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" // NEW_MEDIA_SERVER_SIGNATURE 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 class initit 33 { 34 public: 35 initit() 36 { 37 MediaServerMessenger = new BMessenger(NEW_MEDIA_SERVER_SIGNATURE); 38 find_media_server_port(); 39 find_media_addon_server_port(); 40 41 thread_info info; 42 get_thread_info(find_thread(NULL), &info); 43 team = info.team; 44 } 45 ~initit() 46 { 47 delete MediaServerMessenger; 48 } 49 }; 50 initit _initit; 51 52 53 void find_media_server_port() 54 { 55 MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME); 56 if (MediaServerPort < 0) { 57 ERROR("couldn't find MediaServerPort\n"); 58 MediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number 59 } 60 } 61 62 void find_media_addon_server_port() 63 { 64 MediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME); 65 if (MediaAddonServerPort < 0) { 66 ERROR("couldn't find MediaAddonServerPort\n"); 67 MediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number 68 } 69 } 70 71 72 status_t 73 request_data::SendReply(status_t result, reply_data *reply, int replysize) const 74 { 75 reply->result = result; 76 // we cheat and use the (command_data *) version of SendToPort 77 return SendToPort(reply_port, 0, reinterpret_cast<command_data *>(reply), replysize); 78 } 79 80 81 // BMessage based data exchange with the media_server 82 status_t SendToServer(BMessage *msg) 83 { 84 status_t rv; 85 rv = MediaServerMessenger->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT); 86 if (rv != B_OK) { 87 ERROR("SendToServer: SendMessage failed, error 0x%08lx (%s)\n", rv, strerror(rv)); 88 DEBUG_ONLY(msg->PrintToStream()); 89 } 90 return rv; 91 } 92 93 // Raw data based data exchange with the media_server 94 status_t SendToServer(int32 msgcode, command_data *msg, int size) 95 { 96 return SendToPort(MediaServerPort, msgcode, msg, size); 97 } 98 99 status_t QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 100 { 101 return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize); 102 } 103 104 105 // Raw data based data exchange with the media_addon_server 106 status_t SendToAddonServer(int32 msgcode, command_data *msg, int size) 107 { 108 return SendToPort(MediaAddonServerPort, msgcode, msg, size); 109 } 110 111 112 status_t QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 113 { 114 return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize); 115 } 116 117 118 // Raw data based data exchange with the media_server 119 status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size) 120 { 121 status_t rv; 122 rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); 123 if (rv != B_OK) { 124 ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); 125 if (rv == B_BAD_PORT_ID && sendport == MediaServerPort) { 126 find_media_server_port(); 127 sendport = MediaServerPort; 128 } else if (rv == B_BAD_PORT_ID && sendport == MediaAddonServerPort) { 129 find_media_addon_server_port(); 130 sendport = MediaAddonServerPort; 131 } else { 132 return rv; 133 } 134 rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); 135 if (rv != B_OK) { 136 ERROR("SendToPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); 137 return rv; 138 } 139 } 140 return B_OK; 141 } 142 143 144 status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) 145 { 146 status_t rv; 147 int32 code; 148 149 request->reply_port = _PortPool->GetPort(); 150 151 rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); 152 153 if (rv != B_OK) { 154 ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); 155 if (rv == B_BAD_PORT_ID && requestport == MediaServerPort) { 156 find_media_server_port(); 157 requestport = MediaServerPort; 158 } else if (rv == B_BAD_PORT_ID && requestport == MediaAddonServerPort) { 159 find_media_addon_server_port(); 160 requestport = MediaAddonServerPort; 161 } else { 162 _PortPool->PutPort(request->reply_port); 163 return rv; 164 } 165 rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); 166 if (rv != B_OK) { 167 ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); 168 _PortPool->PutPort(request->reply_port); 169 return rv; 170 } 171 } 172 173 rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT); 174 _PortPool->PutPort(request->reply_port); 175 176 if (rv < B_OK) { 177 ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv)); 178 } 179 180 return (rv < B_OK) ? rv : reply->result; 181 } 182 183 }; // dataexchange 184 }; // media 185 }; // BPrivate 186 187