1 /*
2 * Copyright 2002-2007, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <DataExchange.h>
8
9 #include <string.h>
10 #include <unistd.h>
11
12 #include <Messenger.h>
13 #include <OS.h>
14
15 #include <MediaDebug.h>
16 #include <MediaMisc.h>
17
18
19 #define TIMEOUT 15000000 // 15 seconds timeout!
20
21
22 namespace BPrivate {
23 namespace media {
24 namespace dataexchange {
25
26
27 static BMessenger sMediaServerMessenger;
28 static BMessenger sMediaRosterMessenger;
29 static port_id sMediaServerPort;
30 static port_id sMediaAddonServerPort;
31
32 static void find_media_server_port();
33 static void find_media_addon_server_port();
34
35
36 static void
find_media_server_port()37 find_media_server_port()
38 {
39 sMediaServerPort = find_port(MEDIA_SERVER_PORT_NAME);
40 if (sMediaServerPort < 0) {
41 TRACE("couldn't find sMediaServerPort\n");
42 sMediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number
43 }
44 }
45
46
47 static void
find_media_addon_server_port()48 find_media_addon_server_port()
49 {
50 sMediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME);
51 if (sMediaAddonServerPort < 0) {
52 TRACE("couldn't find sMediaAddonServerPort\n");
53 sMediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number
54 }
55 }
56
57
58 // #pragma mark -
59
60
61 void
InitServerDataExchange()62 InitServerDataExchange()
63 {
64 sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE);
65 find_media_server_port();
66 find_media_addon_server_port();
67 }
68
69
70 void
InitRosterDataExchange(const BMessenger & rosterMessenger)71 InitRosterDataExchange(const BMessenger& rosterMessenger)
72 {
73 sMediaRosterMessenger = rosterMessenger;
74 }
75
76
77 //! BMessage based data exchange with the local BMediaRoster
78 status_t
SendToRoster(BMessage * msg)79 SendToRoster(BMessage* msg)
80 {
81 status_t status = sMediaRosterMessenger.SendMessage(msg,
82 static_cast<BHandler*>(NULL), TIMEOUT);
83 if (status != B_OK) {
84 ERROR("SendToRoster: SendMessage failed: %s\n", strerror(status));
85 DEBUG_ONLY(msg->PrintToStream());
86 }
87 return status;
88 }
89
90
91 //! BMessage based data exchange with the media_server
92 status_t
SendToServer(BMessage * msg)93 SendToServer(BMessage* msg)
94 {
95 status_t status = sMediaServerMessenger.SendMessage(msg,
96 static_cast<BHandler*>(NULL), TIMEOUT);
97 if (status != B_OK) {
98 ERROR("SendToServer: SendMessage failed: %s\n", strerror(status));
99 DEBUG_ONLY(msg->PrintToStream());
100 }
101 return status;
102 }
103
104
105 status_t
QueryServer(BMessage & request,BMessage & reply)106 QueryServer(BMessage& request, BMessage& reply)
107 {
108 status_t status = sMediaServerMessenger.SendMessage(&request, &reply,
109 TIMEOUT, TIMEOUT);
110 if (status != B_OK) {
111 ERROR("QueryServer: SendMessage failed: %s\n", 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,size_t size)121 SendToServer(int32 msgCode, command_data* msg, size_t size)
122 {
123 return SendToPort(sMediaServerPort, msgCode, msg, size);
124 }
125
126 status_t
QueryServer(int32 msgCode,request_data * request,size_t requestSize,reply_data * reply,size_t replySize)127 QueryServer(int32 msgCode, request_data* request, size_t requestSize,
128 reply_data* reply, size_t replySize)
129 {
130 return QueryPort(sMediaServerPort, msgCode, request, requestSize, reply,
131 replySize);
132 }
133
134
135 //! Raw data based data exchange with the media_addon_server
136 status_t
SendToAddOnServer(int32 msgCode,command_data * msg,size_t size)137 SendToAddOnServer(int32 msgCode, command_data* msg, size_t size)
138 {
139 return SendToPort(sMediaAddonServerPort, msgCode, msg, size);
140 }
141
142
143 status_t
QueryAddOnServer(int32 msgCode,request_data * request,size_t requestSize,reply_data * reply,size_t replySize)144 QueryAddOnServer(int32 msgCode, request_data* request, size_t requestSize,
145 reply_data* reply, size_t replySize)
146 {
147 return QueryPort(sMediaAddonServerPort, msgCode, request, requestSize,
148 reply, replySize);
149 }
150
151
152 //! Raw data based data exchange with the media_server
153 status_t
SendToPort(port_id sendPort,int32 msgCode,command_data * msg,size_t size)154 SendToPort(port_id sendPort, int32 msgCode, command_data* msg, size_t size)
155 {
156 status_t status = write_port_etc(sendPort, msgCode, msg, size,
157 B_RELATIVE_TIMEOUT, TIMEOUT);
158 if (status != B_OK) {
159 ERROR("SendToPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %"
160 B_PRId32 ": %s\n", msgCode, sendPort, strerror(status));
161 if (status == B_BAD_PORT_ID && sendPort == sMediaServerPort) {
162 find_media_server_port();
163 sendPort = sMediaServerPort;
164 } else if (status == B_BAD_PORT_ID
165 && sendPort == sMediaAddonServerPort) {
166 find_media_addon_server_port();
167 sendPort = sMediaAddonServerPort;
168 } else
169 return status;
170
171 status = write_port_etc(sendPort, msgCode, msg, size,
172 B_RELATIVE_TIMEOUT, TIMEOUT);
173 if (status != B_OK) {
174 ERROR("SendToPort: retrying write_port failed, msgCode 0x%" B_PRIx32
175 ", port %" B_PRId32 ": %s\n", msgCode, sendPort,
176 strerror(status));
177 return status;
178 }
179 }
180 return B_OK;
181 }
182
183
184 status_t
QueryPort(port_id requestPort,int32 msgCode,request_data * request,size_t requestSize,reply_data * reply,size_t replySize)185 QueryPort(port_id requestPort, int32 msgCode, request_data* request,
186 size_t requestSize, reply_data* reply, size_t replySize)
187 {
188 status_t status = write_port_etc(requestPort, msgCode, request, requestSize,
189 B_RELATIVE_TIMEOUT, TIMEOUT);
190 if (status != B_OK) {
191 ERROR("QueryPort: write_port failed, msgcode 0x%" B_PRIx32 ", port %"
192 B_PRId32 ": %s\n", msgCode, requestPort, strerror(status));
193
194 if (status == B_BAD_PORT_ID && requestPort == sMediaServerPort) {
195 find_media_server_port();
196 requestPort = sMediaServerPort;
197 } else if (status == B_BAD_PORT_ID
198 && requestPort == sMediaAddonServerPort) {
199 find_media_addon_server_port();
200 requestPort = sMediaAddonServerPort;
201 } else
202 return status;
203
204 status = write_port_etc(requestPort, msgCode, request, requestSize,
205 B_RELATIVE_TIMEOUT, TIMEOUT);
206 if (status != B_OK) {
207 ERROR("QueryPort: retrying write_port failed, msgcode 0x%" B_PRIx32
208 ", port %" B_PRId32 ": %s\n", msgCode, requestPort,
209 strerror(status));
210 return status;
211 }
212 }
213
214 int32 code;
215 status = read_port_etc(request->reply_port, &code, reply, replySize,
216 B_RELATIVE_TIMEOUT, TIMEOUT);
217 if (status < B_OK) {
218 ERROR("QueryPort: read_port failed, msgcode 0x%" B_PRIx32 ", port %"
219 B_PRId32 ": %s\n", msgCode, request->reply_port, strerror(status));
220 }
221
222 return status < B_OK ? status : reply->result;
223 }
224
225
226 } // dataexchange
227 } // media
228 } // BPrivate
229