Jack2  1.9.9
JackRequestDecoder.cpp
1 /*
2 Copyright (C) 2012 Grame
3 
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.
8 
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.
13 
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.
17 
18 */
19 
20 #include "JackRequestDecoder.h"
21 #include "JackServer.h"
22 #include "JackLockedEngine.h"
23 #include "JackChannel.h"
24 
25 #include <assert.h>
26 #include <signal.h>
27 
28 using namespace std;
29 
30 namespace Jack
31 {
32 
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); } }
37 
38 JackRequestDecoder::JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler)
39  :fServer(server), fHandler(handler)
40 {}
41 
42 JackRequestDecoder::~JackRequestDecoder()
43 {}
44 
45 int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* socket, int type_aux)
46 {
47  JackRequest::RequestType type = (JackRequest::RequestType)type_aux;
48 
49  // Read data
50  switch (type) {
51 
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);
64  }
65  break;
66  }
67 
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;
76  }
77 
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;
88  }
89 
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;
98  }
99 
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;
108  }
109 
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;
118  }
119 
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;
128  }
129 
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;
138  }
139 
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;
148  }
149 
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;
158  }
159 
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;
168  }
169 
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;
178  }
179 
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;
188  }
189 
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;
198  }
199 
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;
208  }
209 
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;
218  }
219 
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;
228  }
229 
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;
238  }
239 
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;
248  }
249 
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;
258  }
259 
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;
268  }
269 
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);
279  }
280  break;
281  }
282 
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;
289  }
290 
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;
299  }
300 
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;
309  }
310 
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;
319  }
320 
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;
329  }
330 
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;
339  }
340 
341  default:
342  jack_error("Unknown request %ld", type);
343  return -1;
344  }
345 
346  return 0;
347 }
348 
349 } // end of namespace
350 
351 
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:91
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:107