1 /* 2 * Copyright 2002-2007, Marcus Overhagen. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <DataExchange.h> 8 9 #include <string.h> 10 #include <unistd.h> 11 12 #include <Messenger.h> 13 #include <OS.h> 14 15 #include <MediaDebug.h> 16 #include <MediaMisc.h> 17 18 19 #define TIMEOUT 15000000 // 15 seconds timeout! 20 21 22 namespace BPrivate { 23 namespace media { 24 namespace dataexchange { 25 26 27 static BMessenger sMediaServerMessenger; 28 static BMessenger sMediaRosterMessenger; 29 static port_id sMediaServerPort; 30 static port_id sMediaAddonServerPort; 31 32 static void find_media_server_port(); 33 static void find_media_addon_server_port(); 34 35 36 static void 37 find_media_server_port() 38 { 39 sMediaServerPort = find_port(MEDIA_SERVER_PORT_NAME); 40 if (sMediaServerPort < 0) { 41 TRACE("couldn't find sMediaServerPort\n"); 42 sMediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number 43 } 44 } 45 46 47 static void 48 find_media_addon_server_port() 49 { 50 sMediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME); 51 if (sMediaAddonServerPort < 0) { 52 TRACE("couldn't find sMediaAddonServerPort\n"); 53 sMediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number 54 } 55 } 56 57 58 // #pragma mark - 59 60 61 void 62 InitServerDataExchange() 63 { 64 sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE); 65 find_media_server_port(); 66 find_media_addon_server_port(); 67 } 68 69 70 void 71 InitRosterDataExchange(const BMessenger& rosterMessenger) 72 { 73 sMediaRosterMessenger = rosterMessenger; 74 } 75 76 77 //! BMessage based data exchange with the local BMediaRoster 78 status_t 79 SendToRoster(BMessage* msg) 80 { 81 status_t status = sMediaRosterMessenger.SendMessage(msg, 82 static_cast<BHandler*>(NULL), TIMEOUT); 83 if (status != B_OK) { 84 ERROR("SendToRoster: SendMessage failed: %s\n", strerror(status)); 85 DEBUG_ONLY(msg->PrintToStream()); 86 } 87 return status; 88 } 89 90 91 //! BMessage based data exchange with the media_server 92 status_t 93 SendToServer(BMessage* msg) 94 { 95 status_t status = sMediaServerMessenger.SendMessage(msg, 96 static_cast<BHandler*>(NULL), TIMEOUT); 97 if (status != B_OK) { 98 ERROR("SendToServer: SendMessage failed: %s\n", strerror(status)); 99 DEBUG_ONLY(msg->PrintToStream()); 100 } 101 return status; 102 } 103 104 105 status_t 106 QueryServer(BMessage& request, BMessage& reply) 107 { 108 status_t status = sMediaServerMessenger.SendMessage(&request, &reply, 109 TIMEOUT, TIMEOUT); 110 if (status != B_OK) { 111 ERROR("QueryServer: SendMessage failed: %s\n", strerror(status)); 112 DEBUG_ONLY(request.PrintToStream()); 113 DEBUG_ONLY(reply.PrintToStream()); 114 } 115 return status; 116 } 117 118 119 //! Raw data based data exchange with the media_server 120 status_t 121 SendToServer(int32 msgCode, command_data* msg, size_t size) 122 { 123 return SendToPort(sMediaServerPort, msgCode, msg, size); 124 } 125 126 status_t 127 QueryServer(int32 msgCode, request_data* request, size_t requestSize, 128 reply_data* reply, size_t replySize) 129 { 130 return QueryPort(sMediaServerPort, msgCode, request, requestSize, reply, 131 replySize); 132 } 133 134 135 //! Raw data based data exchange with the media_addon_server 136 status_t 137 SendToAddOnServer(int32 msgCode, command_data* msg, size_t size) 138 { 139 return SendToPort(sMediaAddonServerPort, msgCode, msg, size); 140 } 141 142 143 status_t 144 QueryAddOnServer(int32 msgCode, request_data* request, size_t requestSize, 145 reply_data* reply, size_t replySize) 146 { 147 return QueryPort(sMediaAddonServerPort, msgCode, request, requestSize, 148 reply, replySize); 149 } 150 151 152 //! Raw data based data exchange with the media_server 153 status_t 154 SendToPort(port_id sendPort, int32 msgCode, command_data* msg, size_t size) 155 { 156 status_t status = write_port_etc(sendPort, msgCode, msg, size, 157 B_RELATIVE_TIMEOUT, TIMEOUT); 158 if (status != B_OK) { 159 ERROR("SendToPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %" 160 B_PRId32 ": %s\n", msgCode, sendPort, strerror(status)); 161 if (status == B_BAD_PORT_ID && sendPort == sMediaServerPort) { 162 find_media_server_port(); 163 sendPort = sMediaServerPort; 164 } else if (status == B_BAD_PORT_ID 165 && sendPort == sMediaAddonServerPort) { 166 find_media_addon_server_port(); 167 sendPort = sMediaAddonServerPort; 168 } else 169 return status; 170 171 status = write_port_etc(sendPort, msgCode, msg, size, 172 B_RELATIVE_TIMEOUT, TIMEOUT); 173 if (status != B_OK) { 174 ERROR("SendToPort: retrying write_port failed, msgCode 0x%" B_PRIx32 175 ", port %" B_PRId32 ": %s\n", msgCode, sendPort, 176 strerror(status)); 177 return status; 178 } 179 } 180 return B_OK; 181 } 182 183 184 status_t 185 QueryPort(port_id requestPort, int32 msgCode, request_data* request, 186 size_t requestSize, reply_data* reply, size_t replySize) 187 { 188 status_t status = write_port_etc(requestPort, msgCode, request, requestSize, 189 B_RELATIVE_TIMEOUT, TIMEOUT); 190 if (status != B_OK) { 191 ERROR("QueryPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %" 192 B_PRId32 ": %s\n", msgCode, requestPort, strerror(status)); 193 194 if (status == B_BAD_PORT_ID && requestPort == sMediaServerPort) { 195 find_media_server_port(); 196 requestPort = sMediaServerPort; 197 } else if (status == B_BAD_PORT_ID 198 && requestPort == sMediaAddonServerPort) { 199 find_media_addon_server_port(); 200 requestPort = sMediaAddonServerPort; 201 } else 202 return status; 203 204 status = write_port_etc(requestPort, msgCode, request, requestSize, 205 B_RELATIVE_TIMEOUT, TIMEOUT); 206 if (status != B_OK) { 207 ERROR("QueryPort: retrying write_port failed, msgcode 0x%" B_PRIx32 208 ", port %" B_PRId32 ": %s\n", msgCode, requestPort, 209 strerror(status)); 210 return status; 211 } 212 } 213 214 int32 code; 215 status = read_port_etc(request->reply_port, &code, reply, replySize, 216 B_RELATIVE_TIMEOUT, TIMEOUT); 217 if (status < B_OK) { 218 ERROR("QueryPort: read_port failed, msgcode 0x%" B_PRIx32 ", port %" 219 B_PRId32 ": %s\n", msgCode, request->reply_port, strerror(status)); 220 } 221 222 return status < B_OK ? status : reply->result; 223 } 224 225 226 } // dataexchange 227 } // media 228 } // BPrivate 229