/* * Copyright 2002, Marcus Overhagen. All rights reserved. * Distributed under the terms of the MIT License. */ #include #include #include #include #include "debug.h" #include "PortPool.h" #include "MediaMisc.h" #include "DataExchange.h" #include "ServerInterface.h" #define TIMEOUT 15000000 // 15 seconds timeout! namespace BPrivate { namespace media { team_id team; namespace dataexchange { BMessenger *MediaServerMessenger; static port_id MediaServerPort; static port_id MediaAddonServerPort; void find_media_server_port(); void find_media_addon_server_port(); static BMessenger * GetMediaServerMessenger() { static BMessenger * messenger = new BMessenger(B_MEDIA_SERVER_SIGNATURE); return MediaServerMessenger = messenger; } class initit { public: initit() { MediaServerMessenger = 0; find_media_server_port(); find_media_addon_server_port(); thread_info info; get_thread_info(find_thread(NULL), &info); team = info.team; } ~initit() { delete MediaServerMessenger; } }; initit _initit; void find_media_server_port() { MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME); if (MediaServerPort < 0) { ERROR("couldn't find MediaServerPort\n"); MediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number } } void find_media_addon_server_port() { MediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME); if (MediaAddonServerPort < 0) { ERROR("couldn't find MediaAddonServerPort\n"); MediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number } } static void check(int code) { static int rep = 0; if(code == 0x204 && rep++ == 200) debugger("scheisse!"); } status_t request_data::SendReply(status_t result, reply_data *reply, int replysize) const { reply->result = result; // we cheat and use the (command_data *) version of SendToPort return SendToPort(reply_port, 0, reinterpret_cast(reply), replysize); } // BMessage based data exchange with the media_server status_t SendToServer(BMessage *msg) { status_t rv; rv = GetMediaServerMessenger()->SendMessage(msg, static_cast(NULL), TIMEOUT); if (rv != B_OK) { ERROR("SendToServer: SendMessage failed, error 0x%08lx (%s)\n", rv, strerror(rv)); DEBUG_ONLY(msg->PrintToStream()); } return rv; } status_t QueryServer(BMessage &request, BMessage &reply) { status_t status = GetMediaServerMessenger()->SendMessage(&request, &reply, TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("QueryServer: SendMessage failed, error 0x%08lx (%s)\n", status, strerror(status)); DEBUG_ONLY(request.PrintToStream()); DEBUG_ONLY(reply.PrintToStream()); } return status; } // Raw data based data exchange with the media_server status_t SendToServer(int32 msgcode, command_data *msg, int size) { return SendToPort(MediaServerPort, msgcode, msg, size); } status_t QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) { return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize); } // Raw data based data exchange with the media_addon_server status_t SendToAddonServer(int32 msgcode, command_data *msg, int size) { return SendToPort(MediaAddonServerPort, msgcode, msg, size); } status_t QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) { return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize); } // Raw data based data exchange with the media_server status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size) { status_t rv; check(msgcode); rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); if (rv != B_OK) { ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); if (rv == B_BAD_PORT_ID && sendport == MediaServerPort) { find_media_server_port(); sendport = MediaServerPort; } else if (rv == B_BAD_PORT_ID && sendport == MediaAddonServerPort) { find_media_addon_server_port(); sendport = MediaAddonServerPort; } else { return rv; } check(msgcode); rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); if (rv != B_OK) { ERROR("SendToPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv)); return rv; } } return B_OK; } status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) { status_t rv; int32 code; request->reply_port = _PortPool->GetPort(); check(msgcode); rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); if (rv != B_OK) { ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); if (rv == B_BAD_PORT_ID && requestport == MediaServerPort) { find_media_server_port(); requestport = MediaServerPort; } else if (rv == B_BAD_PORT_ID && requestport == MediaAddonServerPort) { find_media_addon_server_port(); requestport = MediaAddonServerPort; } else { _PortPool->PutPort(request->reply_port); return rv; } check(msgcode); rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); if (rv != B_OK) { ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); _PortPool->PutPort(request->reply_port); return rv; } } rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT); _PortPool->PutPort(request->reply_port); if (rv < B_OK) { ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv)); } return (rv < B_OK) ? rv : reply->result; } }; // dataexchange }; // media }; // BPrivate