xref: /haiku/src/kits/media/DataExchange.cpp (revision 2069f565e8ed3556b30cf2f5e3aa54450128b8c2)
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 <debug.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 port_id sMediaServerPort;
29 static port_id sMediaAddonServerPort;
30 
31 static void find_media_server_port();
32 static void find_media_addon_server_port();
33 
34 
35 static void
36 find_media_server_port()
37 {
38 	sMediaServerPort = find_port(MEDIA_SERVER_PORT_NAME);
39 	if (sMediaServerPort < 0) {
40 		ERROR("couldn't find sMediaServerPort\n");
41 		sMediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number
42 	}
43 }
44 
45 
46 static void
47 find_media_addon_server_port()
48 {
49 	sMediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME);
50 	if (sMediaAddonServerPort < 0) {
51 		ERROR("couldn't find sMediaAddonServerPort\n");
52 		sMediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number
53 	}
54 }
55 
56 
57 // #pragma mark -
58 
59 
60 void
61 InitDataExchange()
62 {
63 	sMediaServerMessenger = BMessenger(B_MEDIA_SERVER_SIGNATURE);
64 	find_media_server_port();
65 	find_media_addon_server_port();
66 }
67 
68 
69 //! BMessage based data exchange with the media_server
70 status_t
71 SendToServer(BMessage* msg)
72 {
73 	status_t status = sMediaServerMessenger.SendMessage(msg,
74 		static_cast<BHandler*>(NULL), TIMEOUT);
75 	if (status != B_OK) {
76 		ERROR("SendToServer: SendMessage failed: %s\n", strerror(status));
77 		DEBUG_ONLY(msg->PrintToStream());
78 	}
79 	return status;
80 }
81 
82 
83 status_t
84 QueryServer(BMessage& request, BMessage& reply)
85 {
86 	status_t status = sMediaServerMessenger.SendMessage(&request, &reply,
87 		TIMEOUT, TIMEOUT);
88 	if (status != B_OK) {
89 		ERROR("QueryServer: SendMessage failed: %s\n", strerror(status));
90 		DEBUG_ONLY(request.PrintToStream());
91 		DEBUG_ONLY(reply.PrintToStream());
92 	}
93 	return status;
94 }
95 
96 
97 //! Raw data based data exchange with the media_server
98 status_t
99 SendToServer(int32 msgCode, command_data* msg, size_t size)
100 {
101 	return SendToPort(sMediaServerPort, msgCode, msg, size);
102 }
103 
104 status_t
105 QueryServer(int32 msgCode, request_data* request, size_t requestSize,
106 	reply_data* reply, size_t replySize)
107 {
108 	return QueryPort(sMediaServerPort, msgCode, request, requestSize, reply,
109 		replySize);
110 }
111 
112 
113 //! Raw data based data exchange with the media_addon_server
114 status_t
115 SendToAddOnServer(int32 msgCode, command_data* msg, size_t size)
116 {
117 	return SendToPort(sMediaAddonServerPort, msgCode, msg, size);
118 }
119 
120 
121 status_t
122 QueryAddOnServer(int32 msgCode, request_data* request, size_t requestSize,
123 	reply_data* reply, size_t replySize)
124 {
125 	return QueryPort(sMediaAddonServerPort, msgCode, request, requestSize,
126 		reply, replySize);
127 }
128 
129 
130 //! Raw data based data exchange with the media_server
131 status_t
132 SendToPort(port_id sendPort, int32 msgCode, command_data* msg, size_t size)
133 {
134 	status_t status = write_port_etc(sendPort, msgCode, msg, size,
135 		B_RELATIVE_TIMEOUT, TIMEOUT);
136 	if (status != B_OK) {
137 		ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld: %s\n",
138 			msgCode, sendPort, strerror(status));
139 		if (status == B_BAD_PORT_ID && sendPort == sMediaServerPort) {
140 			find_media_server_port();
141 			sendPort = sMediaServerPort;
142 		} else if (status == B_BAD_PORT_ID
143 			&& sendPort == sMediaAddonServerPort) {
144 			find_media_addon_server_port();
145 			sendPort = sMediaAddonServerPort;
146 		} else
147 			return status;
148 
149 		status = write_port_etc(sendPort, msgCode, msg, size,
150 			B_RELATIVE_TIMEOUT, TIMEOUT);
151 		if (status != B_OK) {
152 			ERROR("SendToPort: retrying write_port failed, msgCode 0x%lx, "
153 				"port %ld: %s\n", msgCode, sendPort, strerror(status));
154 			return status;
155 		}
156 	}
157 	return B_OK;
158 }
159 
160 
161 status_t
162 QueryPort(port_id requestPort, int32 msgCode, request_data* request,
163 	size_t requestSize, reply_data* reply, size_t replySize)
164 {
165 	status_t status = write_port_etc(requestPort, msgCode, request, requestSize,
166 		B_RELATIVE_TIMEOUT, TIMEOUT);
167 	if (status != B_OK) {
168 		ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld: %s\n",
169 			msgCode, requestPort, strerror(status));
170 
171 		if (status == B_BAD_PORT_ID && requestPort == sMediaServerPort) {
172 			find_media_server_port();
173 			requestPort = sMediaServerPort;
174 		} else if (status == B_BAD_PORT_ID
175 			&& requestPort == sMediaAddonServerPort) {
176 			find_media_addon_server_port();
177 			requestPort = sMediaAddonServerPort;
178 		} else
179 			return status;
180 
181 		status = write_port_etc(requestPort, msgCode, request, requestSize,
182 			B_RELATIVE_TIMEOUT, TIMEOUT);
183 		if (status != B_OK) {
184 			ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port "
185 				"%ld: %s\n", msgCode, requestPort, strerror(status));
186 			return status;
187 		}
188 	}
189 
190 	int32 code;
191 	status = read_port_etc(request->reply_port, &code, reply, replySize,
192 		B_RELATIVE_TIMEOUT, TIMEOUT);
193 	if (status < B_OK) {
194 		ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld: %s\n",
195 			msgCode, request->reply_port, strerror(status));
196 	}
197 
198 	return status < B_OK ? status : reply->result;
199 }
200 
201 
202 }	// dataexchange
203 }	// media
204 }	// BPrivate
205