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 22namespace BPrivate { 23namespace media { 24namespace dataexchange { 25 26 27static BMessenger sMediaServerMessenger; 28static BMessenger sMediaRosterMessenger; 29static port_id sMediaServerPort; 30static port_id sMediaAddonServerPort; 31 32static void find_media_server_port(); 33static void find_media_addon_server_port(); 34 35 36static void 37find_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 47static void 48find_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 61void 62InitServerDataExchange() 63{ 64 sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE); 65 find_media_server_port(); 66 find_media_addon_server_port(); 67} 68 69 70void 71InitRosterDataExchange(const BMessenger& rosterMessenger) 72{ 73 sMediaRosterMessenger = rosterMessenger; 74} 75 76 77//! BMessage based data exchange with the local BMediaRoster 78status_t 79SendToRoster(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 92status_t 93SendToServer(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 105status_t 106QueryServer(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 120status_t 121SendToServer(int32 msgCode, command_data* msg, size_t size) 122{ 123 return SendToPort(sMediaServerPort, msgCode, msg, size); 124} 125 126status_t 127QueryServer(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 136status_t 137SendToAddOnServer(int32 msgCode, command_data* msg, size_t size) 138{ 139 return SendToPort(sMediaAddonServerPort, msgCode, msg, size); 140} 141 142 143status_t 144QueryAddOnServer(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 153status_t 154SendToPort(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 184status_t 185QueryPort(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