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 static void check(int code) 78 { 79 static int rep = 0; 80 if(code == 0x204 && rep++ == 200) 81 debugger("scheisse!"); 82 } 83 84 status_t 85 request_data::SendReply(status_t result, reply_data *reply, int replysize) const 86 { 87 reply->result = result; 88 // we cheat and use the (command_data *) version of SendToPort 89 return SendToPort(reply_port, 0, reinterpret_cast<command_data *>(reply), replysize); 90 } 91 92 93 // BMessage based data exchange with the media_server 94 status_t SendToServer(BMessage *msg) 95 { 96 status_t rv; 97 rv = GetMediaServerMessenger()->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT); 98 if (rv != B_OK) { 99 ERROR("SendToServer: SendMessage failed, error 0x%08lx (%s)\n", rv, strerror(rv)); 100 DEBUG_ONLY(msg->PrintToStream()); 101 } 102 return rv; 103 } 104 105 106 status_t 107 QueryServer(BMessage &request, BMessage &reply) 108 { 109 status_t status = GetMediaServerMessenger()->SendMessage(&request, &reply, TIMEOUT, TIMEOUT); 110 if (status != B_OK) { 111 ERROR("QueryServer: SendMessage failed, error 0x%08lx (%s)\n", status, 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 SendToServer(int32 msgcode, command_data *msg, int size) 121 { 122 return SendToPort(MediaServerPort, msgcode, msg, size); 123 } 124 125 status_t QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 126 { 127 return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize); 128 } 129 130 131 // Raw data based data exchange with the media_addon_server 132 status_t SendToAddonServer(int32 msgcode, command_data *msg, int size) 133 { 134 return SendToPort(MediaAddonServerPort, msgcode, msg, size); 135 } 136 137 138 status_t QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 139 { 140 return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize); 141 } 142 143 144 // Raw data based data exchange with the media_server 145 status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size) 146 { 147 status_t rv; 148 check(msgcode); 149 rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); 150 if (rv != B_OK) { 151 ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); 152 if (rv == B_BAD_PORT_ID && sendport == MediaServerPort) { 153 find_media_server_port(); 154 sendport = MediaServerPort; 155 } else if (rv == B_BAD_PORT_ID && sendport == MediaAddonServerPort) { 156 find_media_addon_server_port(); 157 sendport = MediaAddonServerPort; 158 } else { 159 return rv; 160 } 161 check(msgcode); 162 rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); 163 if (rv != B_OK) { 164 ERROR("SendToPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); 165 return rv; 166 } 167 } 168 return B_OK; 169 } 170 171 172 status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 173 { 174 status_t rv; 175 int32 code; 176 177 request->reply_port = _PortPool->GetPort(); 178 179 check(msgcode); 180 rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); 181 182 if (rv != B_OK) { 183 ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); 184 if (rv == B_BAD_PORT_ID && requestport == MediaServerPort) { 185 find_media_server_port(); 186 requestport = MediaServerPort; 187 } else if (rv == B_BAD_PORT_ID && requestport == MediaAddonServerPort) { 188 find_media_addon_server_port(); 189 requestport = MediaAddonServerPort; 190 } else { 191 _PortPool->PutPort(request->reply_port); 192 return rv; 193 } 194 check(msgcode); 195 rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); 196 if (rv != B_OK) { 197 ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); 198 _PortPool->PutPort(request->reply_port); 199 return rv; 200 } 201 } 202 203 rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT); 204 _PortPool->PutPort(request->reply_port); 205 206 if (rv < B_OK) { 207 ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv)); 208 } 209 210 return (rv < B_OK) ? rv : reply->result; 211 } 212 213 }; // dataexchange 214 }; // media 215 }; // BPrivate 216 217