1 /* 2 * Copyright 2002, Marcus Overhagen. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <OS.h> 7 #include <Messenger.h> 8 #include <string.h> 9 #include <unistd.h> 10 #include "debug.h" 11 #include "PortPool.h" 12 #include "MediaMisc.h" 13 #include "DataExchange.h" 14 #include "ServerInterface.h" 15 16 #define TIMEOUT 15000000 // 15 seconds timeout! 17 18 namespace BPrivate { 19 namespace media { 20 21 team_id team; 22 23 namespace dataexchange { 24 25 BMessenger *MediaServerMessenger; 26 static port_id MediaServerPort; 27 static port_id MediaAddonServerPort; 28 29 void find_media_server_port(); 30 void find_media_addon_server_port(); 31 32 static BMessenger * GetMediaServerMessenger() { 33 static BMessenger * messenger = new BMessenger(B_MEDIA_SERVER_SIGNATURE); 34 return MediaServerMessenger = messenger; 35 } 36 37 class initit 38 { 39 public: 40 initit() 41 { 42 MediaServerMessenger = 0; 43 find_media_server_port(); 44 find_media_addon_server_port(); 45 46 thread_info info; 47 get_thread_info(find_thread(NULL), &info); 48 team = info.team; 49 } 50 ~initit() 51 { 52 delete MediaServerMessenger; 53 } 54 }; 55 initit _initit; 56 57 58 void find_media_server_port() 59 { 60 MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME); 61 if (MediaServerPort < 0) { 62 ERROR("couldn't find MediaServerPort\n"); 63 MediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number 64 } 65 } 66 67 void find_media_addon_server_port() 68 { 69 MediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME); 70 if (MediaAddonServerPort < 0) { 71 ERROR("couldn't find MediaAddonServerPort\n"); 72 MediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number 73 } 74 } 75 76 77 status_t 78 request_data::SendReply(status_t result, reply_data *reply, int replysize) const 79 { 80 reply->result = result; 81 // we cheat and use the (command_data *) version of SendToPort 82 return SendToPort(reply_port, 0, reinterpret_cast<command_data *>(reply), replysize); 83 } 84 85 86 // BMessage based data exchange with the media_server 87 status_t SendToServer(BMessage *msg) 88 { 89 status_t rv; 90 rv = GetMediaServerMessenger()->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT); 91 if (rv != B_OK) { 92 ERROR("SendToServer: SendMessage failed, error 0x%08lx (%s)\n", rv, strerror(rv)); 93 DEBUG_ONLY(msg->PrintToStream()); 94 } 95 return rv; 96 } 97 98 99 status_t 100 QueryServer(BMessage &request, BMessage &reply) 101 { 102 status_t status = GetMediaServerMessenger()->SendMessage(&request, &reply, TIMEOUT, TIMEOUT); 103 if (status != B_OK) { 104 ERROR("QueryServer: SendMessage failed, error 0x%08lx (%s)\n", status, strerror(status)); 105 DEBUG_ONLY(request.PrintToStream()); 106 DEBUG_ONLY(reply.PrintToStream()); 107 } 108 return status; 109 } 110 111 112 // Raw data based data exchange with the media_server 113 status_t SendToServer(int32 msgcode, command_data *msg, int size) 114 { 115 return SendToPort(MediaServerPort, msgcode, msg, size); 116 } 117 118 status_t QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 119 { 120 return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize); 121 } 122 123 124 // Raw data based data exchange with the media_addon_server 125 status_t SendToAddonServer(int32 msgcode, command_data *msg, int size) 126 { 127 return SendToPort(MediaAddonServerPort, msgcode, msg, size); 128 } 129 130 131 status_t QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 132 { 133 return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize); 134 } 135 136 137 // Raw data based data exchange with the media_server 138 status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size) 139 { 140 status_t rv; 141 rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); 142 if (rv != B_OK) { 143 ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); 144 if (rv == B_BAD_PORT_ID && sendport == MediaServerPort) { 145 find_media_server_port(); 146 sendport = MediaServerPort; 147 } else if (rv == B_BAD_PORT_ID && sendport == MediaAddonServerPort) { 148 find_media_addon_server_port(); 149 sendport = MediaAddonServerPort; 150 } else { 151 return rv; 152 } 153 rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); 154 if (rv != B_OK) { 155 ERROR("SendToPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); 156 return rv; 157 } 158 } 159 return B_OK; 160 } 161 162 163 status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 164 { 165 status_t rv; 166 int32 code; 167 168 request->reply_port = _PortPool->GetPort(); 169 170 rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); 171 172 if (rv != B_OK) { 173 ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); 174 if (rv == B_BAD_PORT_ID && requestport == MediaServerPort) { 175 find_media_server_port(); 176 requestport = MediaServerPort; 177 } else if (rv == B_BAD_PORT_ID && requestport == MediaAddonServerPort) { 178 find_media_addon_server_port(); 179 requestport = MediaAddonServerPort; 180 } else { 181 _PortPool->PutPort(request->reply_port); 182 return rv; 183 } 184 rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); 185 if (rv != B_OK) { 186 ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); 187 _PortPool->PutPort(request->reply_port); 188 return rv; 189 } 190 } 191 192 rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT); 193 _PortPool->PutPort(request->reply_port); 194 195 if (rv < B_OK) { 196 ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv)); 197 } 198 199 return (rv < B_OK) ? rv : reply->result; 200 } 201 202 }; // dataexchange 203 }; // media 204 }; // BPrivate 205 206