xref: /haiku/src/kits/media/DataExchange.cpp (revision 1214ef1b2100f2b3299fc9d8d6142e46f70a4c3f)
1 /*
2  * Copyright 2002, Marcus Overhagen. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include <OS.h>
7 #include <Messenger.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include "debug.h"
11 #include "PortPool.h"
12 #include "MediaMisc.h"
13 #include "DataExchange.h"
14 #include "ServerInterface.h"
15 
16 #define TIMEOUT 15000000 // 15 seconds timeout!
17 
18 namespace BPrivate {
19 namespace media {
20 
21 team_id team;
22 
23 namespace dataexchange {
24 
25 BMessenger *MediaServerMessenger;
26 static port_id MediaServerPort;
27 static port_id MediaAddonServerPort;
28 
29 void find_media_server_port();
30 void find_media_addon_server_port();
31 
32 static BMessenger * GetMediaServerMessenger() {
33 	static BMessenger * messenger = new BMessenger(B_MEDIA_SERVER_SIGNATURE);
34 	return MediaServerMessenger = messenger;
35 }
36 
37 class initit
38 {
39 public:
40 	initit()
41 	{
42 		MediaServerMessenger = 0;
43 		find_media_server_port();
44 		find_media_addon_server_port();
45 
46 		thread_info info;
47 		get_thread_info(find_thread(NULL), &info);
48 		team = info.team;
49 	}
50 	~initit()
51 	{
52 		delete MediaServerMessenger;
53 	}
54 };
55 initit _initit;
56 
57 
58 void find_media_server_port()
59 {
60 	MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME);
61 	if (MediaServerPort < 0) {
62 		ERROR("couldn't find MediaServerPort\n");
63 		MediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number
64 	}
65 }
66 
67 void find_media_addon_server_port()
68 {
69 	MediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME);
70 	if (MediaAddonServerPort < 0) {
71 		ERROR("couldn't find MediaAddonServerPort\n");
72 		MediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number
73 	}
74 }
75 
76 
77 static void check(int code)
78 {
79 	static int rep = 0;
80 	if(code == 0x204 && rep++ == 200)
81 		debugger("scheisse!");
82 }
83 
84 status_t
85 request_data::SendReply(status_t result, reply_data *reply, int replysize) const
86 {
87 	reply->result = result;
88 	// we cheat and use the (command_data *) version of SendToPort
89 	return SendToPort(reply_port, 0, reinterpret_cast<command_data *>(reply), replysize);
90 }
91 
92 
93 // BMessage based data exchange with the media_server
94 status_t SendToServer(BMessage *msg)
95 {
96 	status_t rv;
97 	rv = GetMediaServerMessenger()->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT);
98 	if (rv != B_OK) {
99 		ERROR("SendToServer: SendMessage failed, error 0x%08lx (%s)\n", rv, strerror(rv));
100 		DEBUG_ONLY(msg->PrintToStream());
101 	}
102 	return rv;
103 }
104 
105 
106 status_t
107 QueryServer(BMessage &request, BMessage &reply)
108 {
109 	status_t status = GetMediaServerMessenger()->SendMessage(&request, &reply, TIMEOUT, TIMEOUT);
110 	if (status != B_OK) {
111 		ERROR("QueryServer: SendMessage failed, error 0x%08lx (%s)\n", status, 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, int size)
121 {
122 	return SendToPort(MediaServerPort, msgcode, msg, size);
123 }
124 
125 status_t QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
126 {
127 	return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize);
128 }
129 
130 
131 // Raw data based data exchange with the media_addon_server
132 status_t SendToAddonServer(int32 msgcode, command_data *msg, int size)
133 {
134 	return SendToPort(MediaAddonServerPort, msgcode, msg, size);
135 }
136 
137 
138 status_t QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
139 {
140 	return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize);
141 }
142 
143 
144 // Raw data based data exchange with the media_server
145 status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size)
146 {
147 	status_t rv;
148 	check(msgcode);
149 	rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT);
150 	if (rv != B_OK) {
151 		ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv));
152 		if (rv == B_BAD_PORT_ID && sendport == MediaServerPort) {
153 			find_media_server_port();
154 			sendport = MediaServerPort;
155 		} else if (rv == B_BAD_PORT_ID && sendport == MediaAddonServerPort) {
156 			find_media_addon_server_port();
157 			sendport = MediaAddonServerPort;
158 		} else {
159 			return rv;
160 		}
161 	check(msgcode);
162 		rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT);
163 		if (rv != B_OK) {
164 			ERROR("SendToPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv));
165 			return rv;
166 		}
167 	}
168 	return B_OK;
169 }
170 
171 
172 status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
173 {
174 	status_t rv;
175 	int32 code;
176 
177 	request->reply_port = _PortPool->GetPort();
178 
179 	check(msgcode);
180 	rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT);
181 
182 	if (rv != B_OK) {
183 		ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv));
184 		if (rv == B_BAD_PORT_ID && requestport == MediaServerPort) {
185 			find_media_server_port();
186 			requestport = MediaServerPort;
187 		} else if (rv == B_BAD_PORT_ID && requestport == MediaAddonServerPort) {
188 			find_media_addon_server_port();
189 			requestport = MediaAddonServerPort;
190 		} else {
191 			_PortPool->PutPort(request->reply_port);
192 			return rv;
193 		}
194 	check(msgcode);
195 		rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT);
196 		if (rv != B_OK) {
197 			ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv));
198 			_PortPool->PutPort(request->reply_port);
199 			return rv;
200 		}
201 	}
202 
203 	rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT);
204 	_PortPool->PutPort(request->reply_port);
205 
206 	if (rv < B_OK) {
207 		ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv));
208 	}
209 
210 	return (rv < B_OK) ? rv : reply->result;
211 }
212 
213 }; // dataexchange
214 }; // media
215 }; // BPrivate
216 
217