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 <debug.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 port_id sMediaServerPort; 29 static port_id sMediaAddonServerPort; 30 31 static void find_media_server_port(); 32 static void find_media_addon_server_port(); 33 34 35 static void 36 find_media_server_port() 37 { 38 sMediaServerPort = find_port(MEDIA_SERVER_PORT_NAME); 39 if (sMediaServerPort < 0) { 40 TRACE("couldn't find sMediaServerPort\n"); 41 sMediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number 42 } 43 } 44 45 46 static void 47 find_media_addon_server_port() 48 { 49 sMediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME); 50 if (sMediaAddonServerPort < 0) { 51 TRACE("couldn't find sMediaAddonServerPort\n"); 52 sMediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number 53 } 54 } 55 56 57 // #pragma mark - 58 59 60 void 61 InitDataExchange() 62 { 63 sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE); 64 find_media_server_port(); 65 find_media_addon_server_port(); 66 } 67 68 69 //! BMessage based data exchange with the media_server 70 status_t 71 SendToServer(BMessage* msg) 72 { 73 status_t status = sMediaServerMessenger.SendMessage(msg, 74 static_cast<BHandler*>(NULL), TIMEOUT); 75 if (status != B_OK) { 76 ERROR("SendToServer: SendMessage failed: %s\n", strerror(status)); 77 DEBUG_ONLY(msg->PrintToStream()); 78 } 79 return status; 80 } 81 82 83 status_t 84 QueryServer(BMessage& request, BMessage& reply) 85 { 86 status_t status = sMediaServerMessenger.SendMessage(&request, &reply, 87 TIMEOUT, TIMEOUT); 88 if (status != B_OK) { 89 ERROR("QueryServer: SendMessage failed: %s\n", strerror(status)); 90 DEBUG_ONLY(request.PrintToStream()); 91 DEBUG_ONLY(reply.PrintToStream()); 92 } 93 return status; 94 } 95 96 97 //! Raw data based data exchange with the media_server 98 status_t 99 SendToServer(int32 msgCode, command_data* msg, size_t size) 100 { 101 return SendToPort(sMediaServerPort, msgCode, msg, size); 102 } 103 104 status_t 105 QueryServer(int32 msgCode, request_data* request, size_t requestSize, 106 reply_data* reply, size_t replySize) 107 { 108 return QueryPort(sMediaServerPort, msgCode, request, requestSize, reply, 109 replySize); 110 } 111 112 113 //! Raw data based data exchange with the media_addon_server 114 status_t 115 SendToAddOnServer(int32 msgCode, command_data* msg, size_t size) 116 { 117 return SendToPort(sMediaAddonServerPort, msgCode, msg, size); 118 } 119 120 121 status_t 122 QueryAddOnServer(int32 msgCode, request_data* request, size_t requestSize, 123 reply_data* reply, size_t replySize) 124 { 125 return QueryPort(sMediaAddonServerPort, msgCode, request, requestSize, 126 reply, replySize); 127 } 128 129 130 //! Raw data based data exchange with the media_server 131 status_t 132 SendToPort(port_id sendPort, int32 msgCode, command_data* msg, size_t size) 133 { 134 status_t status = write_port_etc(sendPort, msgCode, msg, size, 135 B_RELATIVE_TIMEOUT, TIMEOUT); 136 if (status != B_OK) { 137 ERROR("SendToPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %" 138 B_PRId32 ": %s\n", msgCode, sendPort, strerror(status)); 139 if (status == B_BAD_PORT_ID && sendPort == sMediaServerPort) { 140 find_media_server_port(); 141 sendPort = sMediaServerPort; 142 } else if (status == B_BAD_PORT_ID 143 && sendPort == sMediaAddonServerPort) { 144 find_media_addon_server_port(); 145 sendPort = sMediaAddonServerPort; 146 } else 147 return status; 148 149 status = write_port_etc(sendPort, msgCode, msg, size, 150 B_RELATIVE_TIMEOUT, TIMEOUT); 151 if (status != B_OK) { 152 ERROR("SendToPort: retrying write_port failed, msgCode 0x%" B_PRIx32 153 ", port %" B_PRId32 ": %s\n", msgCode, sendPort, 154 strerror(status)); 155 return status; 156 } 157 } 158 return B_OK; 159 } 160 161 162 status_t 163 QueryPort(port_id requestPort, int32 msgCode, request_data* request, 164 size_t requestSize, reply_data* reply, size_t replySize) 165 { 166 status_t status = write_port_etc(requestPort, msgCode, request, requestSize, 167 B_RELATIVE_TIMEOUT, TIMEOUT); 168 if (status != B_OK) { 169 ERROR("QueryPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %" 170 B_PRId32 ": %s\n", msgCode, requestPort, strerror(status)); 171 172 if (status == B_BAD_PORT_ID && requestPort == sMediaServerPort) { 173 find_media_server_port(); 174 requestPort = sMediaServerPort; 175 } else if (status == B_BAD_PORT_ID 176 && requestPort == sMediaAddonServerPort) { 177 find_media_addon_server_port(); 178 requestPort = sMediaAddonServerPort; 179 } else 180 return status; 181 182 status = write_port_etc(requestPort, msgCode, request, requestSize, 183 B_RELATIVE_TIMEOUT, TIMEOUT); 184 if (status != B_OK) { 185 ERROR("QueryPort: retrying write_port failed, msgcode 0x%" B_PRIx32 186 ", port %" B_PRId32 ": %s\n", msgCode, requestPort, 187 strerror(status)); 188 return status; 189 } 190 } 191 192 int32 code; 193 status = read_port_etc(request->reply_port, &code, reply, replySize, 194 B_RELATIVE_TIMEOUT, TIMEOUT); 195 if (status < B_OK) { 196 ERROR("QueryPort: read_port failed, msgcode 0x%" B_PRIx32 ", port %" 197 B_PRId32 ": %s\n", msgCode, request->reply_port, strerror(status)); 198 } 199 200 return status < B_OK ? status : reply->result; 201 } 202 203 204 } // dataexchange 205 } // media 206 } // BPrivate 207