jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

360 lines
14KB

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