Merge branch 'master' into develop
[jack2.git] / common / JackRequestDecoder.cpp
blob46bbd1f3c9221b77a87c3049ca888653cf087b62
1 /*
2 Copyright (C) 2012 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "JackRequestDecoder.h"
21 #include "JackServer.h"
22 #include "JackLockedEngine.h"
23 #include "JackChannel.h"
25 #include <assert.h>
26 #include <signal.h>
28 using namespace std;
30 namespace Jack
33 #define CheckRead(req, socket) { if (req.Read(socket) < 0) { jack_error("CheckRead error"); return -1; } }
34 #define CheckWriteName(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error name = %s", error, req.fName); } }
35 #define CheckWriteRefNum(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error ref = %d", error, req.fRefNum); } }
36 #define CheckWrite(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error", error); } }
38 JackRequestDecoder::JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler)
39 :fServer(server), fHandler(handler)
42 JackRequestDecoder::~JackRequestDecoder()
45 int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* socket, int type_aux)
47 JackRequest::RequestType type = (JackRequest::RequestType)type_aux;
49 // Read data
50 switch (type) {
52 case JackRequest::kClientCheck: {
53 jack_log("JackRequest::ClientCheck");
54 JackClientCheckRequest req;
55 JackClientCheckResult res;
56 CheckRead(req, socket);
57 res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
58 CheckWriteName("JackRequest::ClientCheck", socket);
59 // Atomic ClientCheck followed by ClientOpen on same socket
60 if (req.fOpen) {
61 JackRequest header;
62 header.Read(socket);
63 return HandleRequest(socket, header.fType);
65 break;
68 case JackRequest::kClientOpen: {
69 jack_log("JackRequest::ClientOpen");
70 JackClientOpenRequest req;
71 JackClientOpenResult res;
72 CheckRead(req, socket);
73 fHandler->ClientAdd(socket, &req, &res);
74 CheckWriteName("JackRequest::ClientOpen", socket);
75 break;
78 case JackRequest::kClientClose: {
79 jack_log("JackRequest::ClientClose");
80 JackClientCloseRequest req;
81 JackResult res;
82 CheckRead(req, socket);
83 res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
84 CheckWriteRefNum("JackRequest::ClientClose", socket);
85 fHandler->ClientRemove(socket, req.fRefNum);
86 // Will cause the wrapping thread to stop
87 return -1;
90 case JackRequest::kActivateClient: {
91 JackActivateRequest req;
92 JackResult res;
93 jack_log("JackRequest::ActivateClient");
94 CheckRead(req, socket);
95 res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
96 CheckWriteRefNum("JackRequest::ActivateClient", socket);
97 break;
100 case JackRequest::kDeactivateClient: {
101 jack_log("JackRequest::DeactivateClient");
102 JackDeactivateRequest req;
103 JackResult res;
104 CheckRead(req, socket);
105 res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
106 CheckWriteRefNum("JackRequest::DeactivateClient", socket);
107 break;
110 case JackRequest::kRegisterPort: {
111 jack_log("JackRequest::RegisterPort");
112 JackPortRegisterRequest req;
113 JackPortRegisterResult res;
114 CheckRead(req, socket);
115 res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
116 CheckWriteRefNum("JackRequest::RegisterPort", socket);
117 break;
120 case JackRequest::kUnRegisterPort: {
121 jack_log("JackRequest::UnRegisterPort");
122 JackPortUnRegisterRequest req;
123 JackResult res;
124 CheckRead(req, socket);
125 res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
126 CheckWriteRefNum("JackRequest::UnRegisterPort", socket);
127 break;
130 case JackRequest::kConnectNamePorts: {
131 jack_log("JackRequest::ConnectNamePorts");
132 JackPortConnectNameRequest req;
133 JackResult res;
134 CheckRead(req, socket);
135 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
136 CheckWriteRefNum("JackRequest::ConnectNamePorts", socket);
137 break;
140 case JackRequest::kDisconnectNamePorts: {
141 jack_log("JackRequest::DisconnectNamePorts");
142 JackPortDisconnectNameRequest req;
143 JackResult res;
144 CheckRead(req, socket);
145 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
146 CheckWriteRefNum("JackRequest::DisconnectNamePorts", socket);
147 break;
150 case JackRequest::kConnectPorts: {
151 jack_log("JackRequest::ConnectPorts");
152 JackPortConnectRequest req;
153 JackResult res;
154 CheckRead(req, socket);
155 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
156 CheckWriteRefNum("JackRequest::ConnectPorts", socket);
157 break;
160 case JackRequest::kDisconnectPorts: {
161 jack_log("JackRequest::DisconnectPorts");
162 JackPortDisconnectRequest req;
163 JackResult res;
164 CheckRead(req, socket);
165 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
166 CheckWriteRefNum("JackRequest::DisconnectPorts", socket);
167 break;
170 case JackRequest::kPortRename: {
171 jack_log("JackRequest::PortRename");
172 JackPortRenameRequest req;
173 JackResult res;
174 CheckRead(req, socket);
175 res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
176 CheckWriteRefNum("JackRequest::PortRename", socket);
177 break;
180 case JackRequest::kSetBufferSize: {
181 jack_log("JackRequest::SetBufferSize");
182 JackSetBufferSizeRequest req;
183 JackResult res;
184 CheckRead(req, socket);
185 res.fResult = fServer->SetBufferSize(req.fBufferSize);
186 CheckWrite("JackRequest::SetBufferSize", socket);
187 break;
190 case JackRequest::kSetFreeWheel: {
191 jack_log("JackRequest::SetFreeWheel");
192 JackSetFreeWheelRequest req;
193 JackResult res;
194 CheckRead(req, socket);
195 res.fResult = fServer->SetFreewheel(req.fOnOff);
196 CheckWrite("JackRequest::SetFreeWheel", socket);
197 break;
200 case JackRequest::kComputeTotalLatencies: {
201 jack_log("JackRequest::ComputeTotalLatencies");
202 JackComputeTotalLatenciesRequest req;
203 JackResult res;
204 CheckRead(req, socket);
205 res.fResult = fServer->GetEngine()->ComputeTotalLatencies();
206 CheckWrite("JackRequest::ComputeTotalLatencies", socket);
207 break;
210 case JackRequest::kReleaseTimebase: {
211 jack_log("JackRequest::ReleaseTimebase");
212 JackReleaseTimebaseRequest req;
213 JackResult res;
214 CheckRead(req, socket);
215 res.fResult = fServer->ReleaseTimebase(req.fRefNum);
216 CheckWriteRefNum("JackRequest::ReleaseTimebase", socket);
217 break;
220 case JackRequest::kSetTimebaseCallback: {
221 jack_log("JackRequest::SetTimebaseCallback");
222 JackSetTimebaseCallbackRequest req;
223 JackResult res;
224 CheckRead(req, socket);
225 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
226 CheckWriteRefNum("JackRequest::SetTimebaseCallback", socket);
227 break;
230 case JackRequest::kGetInternalClientName: {
231 jack_log("JackRequest::GetInternalClientName");
232 JackGetInternalClientNameRequest req;
233 JackGetInternalClientNameResult res;
234 CheckRead(req, socket);
235 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
236 CheckWriteRefNum("JackRequest::GetInternalClientName", socket);
237 break;
240 case JackRequest::kInternalClientHandle: {
241 jack_log("JackRequest::InternalClientHandle");
242 JackInternalClientHandleRequest req;
243 JackInternalClientHandleResult res;
244 CheckRead(req, socket);
245 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
246 CheckWriteRefNum("JackRequest::InternalClientHandle", socket);
247 break;
250 case JackRequest::kInternalClientLoad: {
251 jack_log("JackRequest::InternalClientLoad");
252 JackInternalClientLoadRequest req;
253 JackInternalClientLoadResult res;
254 CheckRead(req, socket);
255 res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus);
256 CheckWriteName("JackRequest::InternalClientLoad", socket);
257 break;
260 case JackRequest::kInternalClientUnload: {
261 jack_log("JackRequest::InternalClientUnload");
262 JackInternalClientUnloadRequest req;
263 JackInternalClientUnloadResult res;
264 CheckRead(req, socket);
265 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
266 CheckWriteRefNum("JackRequest::InternalClientUnload", socket);
267 break;
270 case JackRequest::kNotification: {
271 jack_log("JackRequest::Notification");
272 JackClientNotificationRequest req;
273 CheckRead(req, socket);
274 if (req.fNotify == kQUIT) {
275 jack_log("JackRequest::Notification kQUIT");
276 throw JackQuitException();
277 } else {
278 fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
280 break;
283 case JackRequest::kSessionNotify: {
284 jack_log("JackRequest::SessionNotify");
285 JackSessionNotifyRequest req;
286 CheckRead(req, socket);
287 fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL);
288 break;
291 case JackRequest::kSessionReply: {
292 jack_log("JackRequest::SessionReply");
293 JackSessionReplyRequest req;
294 JackResult res;
295 CheckRead(req, socket);
296 res.fResult = fServer->GetEngine()->SessionReply(req.fRefNum);
297 CheckWrite("JackRequest::SessionReply", socket);
298 break;
301 case JackRequest::kGetClientByUUID: {
302 jack_log("JackRequest::GetClientByUUID");
303 JackGetClientNameRequest req;
304 JackClientNameResult res;
305 CheckRead(req, socket);
306 res.fResult = fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName);
307 CheckWrite("JackRequest::GetClientByUUID", socket);
308 break;
311 case JackRequest::kGetUUIDByClient: {
312 jack_log("JackRequest::GetUUIDByClient");
313 JackGetUUIDRequest req;
314 JackUUIDResult res;
315 CheckRead(req, socket);
316 res.fResult = fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID);
317 CheckWrite("JackRequest::GetUUIDByClient", socket);
318 break;
321 case JackRequest::kReserveClientName: {
322 jack_log("JackRequest::ReserveClientName");
323 JackReserveNameRequest req;
324 JackResult res;
325 CheckRead(req, socket);
326 res.fResult = fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID);
327 CheckWrite("JackRequest::ReserveClientName", socket);
328 break;
331 case JackRequest::kClientHasSessionCallback: {
332 jack_log("JackRequest::ClientHasSessionCallback");
333 JackClientHasSessionCallbackRequest req;
334 JackResult res;
335 CheckRead(req, socket);
336 res.fResult = fServer->GetEngine()->ClientHasSessionCallback(req.fName);
337 CheckWrite("JackRequest::ClientHasSessionCallback", socket);
338 break;
341 case JackRequest::kPropertyChangeNotify: {
342 jack_log("JackRequest::PropertyChangeNotify");
343 JackPropertyChangeNotifyRequest req;
344 CheckRead(req, socket);
345 fServer->GetEngine()->PropertyChangeNotify(req.fSubject, req.fKey, req.fChange);
346 break;
349 default:
350 jack_error("Unknown request %ld", type);
351 return -1;
354 return 0;
357 } // end of namespace