/* * Copyright 2002-2007, Marcus Overhagen. All rights reserved. * Distributed under the terms of the MIT License. */ #include #include #include #include #include #include #include #define TIMEOUT 15000000 // 15 seconds timeout! namespace BPrivate { namespace media { namespace dataexchange { static BMessenger sMediaServerMessenger; static BMessenger sMediaRosterMessenger; static port_id sMediaServerPort; static port_id sMediaAddonServerPort; static void find_media_server_port(); static void find_media_addon_server_port(); static void find_media_server_port() { sMediaServerPort = find_port(MEDIA_SERVER_PORT_NAME); if (sMediaServerPort < 0) { TRACE("couldn't find sMediaServerPort\n"); sMediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number } } static void find_media_addon_server_port() { sMediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME); if (sMediaAddonServerPort < 0) { TRACE("couldn't find sMediaAddonServerPort\n"); sMediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number } } // #pragma mark - void InitServerDataExchange() { sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE); find_media_server_port(); find_media_addon_server_port(); } void InitRosterDataExchange(const BMessenger& rosterMessenger) { sMediaRosterMessenger = rosterMessenger; } //! BMessage based data exchange with the local BMediaRoster status_t SendToRoster(BMessage* msg) { status_t status = sMediaRosterMessenger.SendMessage(msg, static_cast(NULL), TIMEOUT); if (status != B_OK) { ERROR("SendToRoster: SendMessage failed: %s\n", strerror(status)); DEBUG_ONLY(msg->PrintToStream()); } return status; } //! BMessage based data exchange with the media_server status_t SendToServer(BMessage* msg) { status_t status = sMediaServerMessenger.SendMessage(msg, static_cast(NULL), TIMEOUT); if (status != B_OK) { ERROR("SendToServer: SendMessage failed: %s\n", strerror(status)); DEBUG_ONLY(msg->PrintToStream()); } return status; } status_t QueryServer(BMessage& request, BMessage& reply) { status_t status = sMediaServerMessenger.SendMessage(&request, &reply, TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("QueryServer: SendMessage failed: %s\n", 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, size_t size) { return SendToPort(sMediaServerPort, msgCode, msg, size); } status_t QueryServer(int32 msgCode, request_data* request, size_t requestSize, reply_data* reply, size_t replySize) { return QueryPort(sMediaServerPort, msgCode, request, requestSize, reply, replySize); } //! Raw data based data exchange with the media_addon_server status_t SendToAddOnServer(int32 msgCode, command_data* msg, size_t size) { return SendToPort(sMediaAddonServerPort, msgCode, msg, size); } status_t QueryAddOnServer(int32 msgCode, request_data* request, size_t requestSize, reply_data* reply, size_t replySize) { return QueryPort(sMediaAddonServerPort, 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, size_t size) { status_t status = write_port_etc(sendPort, msgCode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("SendToPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %" B_PRId32 ": %s\n", msgCode, sendPort, strerror(status)); if (status == B_BAD_PORT_ID && sendPort == sMediaServerPort) { find_media_server_port(); sendPort = sMediaServerPort; } else if (status == B_BAD_PORT_ID && sendPort == sMediaAddonServerPort) { find_media_addon_server_port(); sendPort = sMediaAddonServerPort; } else return status; status = write_port_etc(sendPort, msgCode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("SendToPort: retrying write_port failed, msgCode 0x%" B_PRIx32 ", port %" B_PRId32 ": %s\n", msgCode, sendPort, strerror(status)); return status; } } return B_OK; } status_t QueryPort(port_id requestPort, int32 msgCode, request_data* request, size_t requestSize, reply_data* reply, size_t replySize) { status_t status = write_port_etc(requestPort, msgCode, request, requestSize, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("QueryPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %" B_PRId32 ": %s\n", msgCode, requestPort, strerror(status)); if (status == B_BAD_PORT_ID && requestPort == sMediaServerPort) { find_media_server_port(); requestPort = sMediaServerPort; } else if (status == B_BAD_PORT_ID && requestPort == sMediaAddonServerPort) { find_media_addon_server_port(); requestPort = sMediaAddonServerPort; } else return status; status = write_port_etc(requestPort, msgCode, request, requestSize, B_RELATIVE_TIMEOUT, TIMEOUT); if (status != B_OK) { ERROR("QueryPort: retrying write_port failed, msgcode 0x%" B_PRIx32 ", port %" B_PRId32 ": %s\n", msgCode, requestPort, strerror(status)); return status; } } int32 code; status = read_port_etc(request->reply_port, &code, reply, replySize, B_RELATIVE_TIMEOUT, TIMEOUT); if (status < B_OK) { ERROR("QueryPort: read_port failed, msgcode 0x%" B_PRIx32 ", port %" B_PRId32 ": %s\n", msgCode, request->reply_port, strerror(status)); } return status < B_OK ? status : reply->result; } } // dataexchange } // media } // BPrivate