xref: /haiku/src/kits/media/DataExchange.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
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" // NEW_MEDIA_SERVER_SIGNATURE
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 class initit
33 {
34 public:
35 	initit()
36 	{
37 		MediaServerMessenger = new BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
38 		find_media_server_port();
39 		find_media_addon_server_port();
40 
41 		thread_info info;
42 		get_thread_info(find_thread(NULL), &info);
43 		team = info.team;
44 	}
45 	~initit()
46 	{
47 		delete MediaServerMessenger;
48 	}
49 };
50 initit _initit;
51 
52 
53 void find_media_server_port()
54 {
55 	MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME);
56 	if (MediaServerPort < 0) {
57 		ERROR("couldn't find MediaServerPort\n");
58 		MediaServerPort = BAD_MEDIA_SERVER_PORT; // make this a unique number
59 	}
60 }
61 
62 void find_media_addon_server_port()
63 {
64 	MediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME);
65 	if (MediaAddonServerPort < 0) {
66 		ERROR("couldn't find MediaAddonServerPort\n");
67 		MediaAddonServerPort = BAD_MEDIA_ADDON_SERVER_PORT; // make this a unique number
68 	}
69 }
70 
71 
72 status_t
73 request_data::SendReply(status_t result, reply_data *reply, int replysize) const
74 {
75 	reply->result = result;
76 	// we cheat and use the (command_data *) version of SendToPort
77 	return SendToPort(reply_port, 0, reinterpret_cast<command_data *>(reply), replysize);
78 }
79 
80 
81 // BMessage based data exchange with the media_server
82 status_t SendToServer(BMessage *msg)
83 {
84 	status_t rv;
85 	rv = MediaServerMessenger->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT);
86 	if (rv != B_OK) {
87 		ERROR("SendToServer: SendMessage failed, error 0x%08lx (%s)\n", rv, strerror(rv));
88 		DEBUG_ONLY(msg->PrintToStream());
89 	}
90 	return rv;
91 }
92 
93 // Raw data based data exchange with the media_server
94 status_t SendToServer(int32 msgcode, command_data *msg, int size)
95 {
96 	return SendToPort(MediaServerPort, msgcode, msg, size);
97 }
98 
99 status_t QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
100 {
101 	return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize);
102 }
103 
104 
105 // Raw data based data exchange with the media_addon_server
106 status_t SendToAddonServer(int32 msgcode, command_data *msg, int size)
107 {
108 	return SendToPort(MediaAddonServerPort, msgcode, msg, size);
109 }
110 
111 
112 status_t QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
113 {
114 	return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize);
115 }
116 
117 
118 // Raw data based data exchange with the media_server
119 status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size)
120 {
121 	status_t rv;
122 	rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT);
123 	if (rv != B_OK) {
124 		ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv));
125 		if (rv == B_BAD_PORT_ID && sendport == MediaServerPort) {
126 			find_media_server_port();
127 			sendport = MediaServerPort;
128 		} else if (rv == B_BAD_PORT_ID && sendport == MediaAddonServerPort) {
129 			find_media_addon_server_port();
130 			sendport = MediaAddonServerPort;
131 		} else {
132 			return rv;
133 		}
134 		rv = write_port_etc(sendport, msgcode, msg, size, B_RELATIVE_TIMEOUT, TIMEOUT);
135 		if (rv != B_OK) {
136 			ERROR("SendToPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, sendport, rv, strerror(rv));
137 			return rv;
138 		}
139 	}
140 	return B_OK;
141 }
142 
143 
144 status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
145 {
146 	status_t rv;
147 	int32 code;
148 
149 	request->reply_port = _PortPool->GetPort();
150 
151 	rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT);
152 
153 	if (rv != B_OK) {
154 		ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv));
155 		if (rv == B_BAD_PORT_ID && requestport == MediaServerPort) {
156 			find_media_server_port();
157 			requestport = MediaServerPort;
158 		} else if (rv == B_BAD_PORT_ID && requestport == MediaAddonServerPort) {
159 			find_media_addon_server_port();
160 			requestport = MediaAddonServerPort;
161 		} else {
162 			_PortPool->PutPort(request->reply_port);
163 			return rv;
164 		}
165 		rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT);
166 		if (rv != B_OK) {
167 			ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv));
168 			_PortPool->PutPort(request->reply_port);
169 			return rv;
170 		}
171 	}
172 
173 	rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT);
174 	_PortPool->PutPort(request->reply_port);
175 
176 	if (rv < B_OK) {
177 		ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv));
178 	}
179 
180 	return (rv < B_OK) ? rv : reply->result;
181 }
182 
183 }; // dataexchange
184 }; // media
185 }; // BPrivate
186 
187