* Copyright 2002-2007, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <DataExchange.h>
#include <string.h>
#include <unistd.h>
#include <Messenger.h>
#include <OS.h>
#include <MediaDebug.h>
#include <MediaMisc.h>
#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;
}
}
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;
}
}
void
InitServerDataExchange()
{
sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE);
find_media_server_port();
find_media_addon_server_port();
}
void
InitRosterDataExchange(const BMessenger& rosterMessenger)
{
sMediaRosterMessenger = rosterMessenger;
}
status_t
SendToRoster(BMessage* msg)
{
status_t status = sMediaRosterMessenger.SendMessage(msg,
static_cast<BHandler*>(NULL), TIMEOUT);
if (status != B_OK) {
ERROR("SendToRoster: SendMessage failed: %s\n", strerror(status));
DEBUG_ONLY(msg->PrintToStream());
}
return status;
}
status_t
SendToServer(BMessage* msg)
{
status_t status = sMediaServerMessenger.SendMessage(msg,
static_cast<BHandler*>(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;
}
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);
}
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);
}
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;
}
}
}
}