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.

1420 lines
36KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Copyright (C) 2004-2008 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.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #ifndef __JackRequest__
  17. #define __JackRequest__
  18. #include "JackConstants.h"
  19. #include "JackError.h"
  20. #include "JackPlatformPlug.h"
  21. #include "JackChannel.h"
  22. #include "JackTime.h"
  23. #include "types.h"
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <list>
  28. namespace Jack
  29. {
  30. #define CheckRes(exp) { if ((exp) < 0) { jack_error("CheckRes error"); return -1; } }
  31. #define CheckSize() { CheckRes(trans->Read(&fSize, sizeof(int))); if (fSize != Size()) { jack_error("CheckSize error size = %d Size() = %d", fSize, Size()); return -1; } }
  32. /*!
  33. \brief Session API constants.
  34. */
  35. enum JackSessionReply {
  36. kImmediateSessionReply = 1,
  37. kPendingSessionReply = 2
  38. };
  39. /*!
  40. \brief Request from client to server.
  41. */
  42. struct JackRequest
  43. {
  44. enum RequestType {
  45. kRegisterPort = 1,
  46. kUnRegisterPort = 2,
  47. kConnectPorts = 3,
  48. kDisconnectPorts = 4,
  49. kSetTimeBaseClient = 5,
  50. kActivateClient = 6,
  51. kDeactivateClient = 7,
  52. kDisconnectPort = 8,
  53. kSetClientCapabilities = 9,
  54. kGetPortConnections = 10,
  55. kGetPortNConnections = 11,
  56. kReleaseTimebase = 12,
  57. kSetTimebaseCallback = 13,
  58. kSetBufferSize = 20,
  59. kSetFreeWheel = 21,
  60. kClientCheck = 22,
  61. kClientOpen = 23,
  62. kClientClose = 24,
  63. kConnectNamePorts = 25,
  64. kDisconnectNamePorts = 26,
  65. kGetInternalClientName = 27,
  66. kInternalClientHandle = 28,
  67. kInternalClientLoad = 29,
  68. kInternalClientUnload = 30,
  69. kPortRename = 31,
  70. kNotification = 32,
  71. kSessionNotify = 33,
  72. kSessionReply = 34,
  73. kGetClientByUUID = 35,
  74. kReserveClientName = 36,
  75. kGetUUIDByClient = 37,
  76. kClientHasSessionCallback = 38,
  77. kComputeTotalLatencies = 39,
  78. kPropertyChangeNotify = 40
  79. };
  80. static const int StartMarker = 'R' | ('e' << 8) | ('q' << 16) | ('S' << 24);
  81. static const int EndMarker = 'R' | ('e' << 8) | ('q' << 16) | ('E' << 24);
  82. static int ReadType(detail::JackChannelTransactionInterface* trans, RequestType& type)
  83. {
  84. type = (RequestType)0;
  85. do {
  86. PRE_PACKED_STRUCTURE_ALWAYS
  87. union {
  88. int i;
  89. uint8_t b[sizeof(i)];
  90. } POST_PACKED_STRUCTURE_ALWAYS start;
  91. CheckRes(trans->Read(&start.i, sizeof(StartMarker)));
  92. if (start.i != StartMarker) {
  93. jack_error("Request start marker not found. Ignoring %02x %02x %02x %02x ",
  94. start.b[0], start.b[1], start.b[2], start.b[3]);
  95. continue;
  96. }
  97. } while (false);
  98. CheckRes(trans->Read(&type, sizeof(RequestType)));
  99. return 0;
  100. }
  101. virtual int Read(detail::JackChannelTransactionInterface* trans) = 0;
  102. virtual int Write(detail::JackChannelTransactionInterface* trans) = 0;
  103. virtual RequestType getType() = 0;
  104. };
  105. PRE_PACKED_STRUCTURE_ALWAYS
  106. template<class DATA>
  107. struct JackRequestMessage
  108. {
  109. protected:
  110. const int fStart = JackRequest::StartMarker;
  111. const JackRequest::RequestType fType;
  112. const int fSize;
  113. public:
  114. DATA d;
  115. protected:
  116. const int fEnd = JackRequest::EndMarker;
  117. template<typename... Args>
  118. JackRequestMessage(Args&... args) : fType(DATA::Type()),
  119. fSize(sizeof(JackRequestMessage<DATA>) - sizeof(fStart) - sizeof(fType) - sizeof(fSize)),
  120. d(args...)
  121. {}
  122. int ReadMessage(detail::JackChannelTransactionInterface* trans)
  123. {
  124. int size = 0;
  125. CheckRes(trans->Read(&size, sizeof(fSize)));
  126. if (size != fSize) {
  127. jack_error("CheckSize error expected %d actual %d", fSize, size);
  128. return -1;
  129. }
  130. /* Size also contains fEnd */
  131. CheckRes(trans->Read(&d, fSize));
  132. if (fEnd != JackRequest::EndMarker) {
  133. jack_error("Request end marker not found (exp %08x act %08x). Request of type %d will be ignored!",
  134. JackRequest::EndMarker, fEnd, fType);
  135. /* no need to sync here. Will be done by JackRequest::ReadType() */
  136. return -1;
  137. }
  138. return 0;
  139. }
  140. int WriteMessage(detail::JackChannelTransactionInterface* trans)
  141. {
  142. CheckRes(trans->Write(this, sizeof(JackRequestMessage<DATA>)));
  143. return 0;
  144. }
  145. } POST_PACKED_STRUCTURE_ALWAYS;
  146. template<class DATA>
  147. struct JackRequestTemplate : public JackRequest, public JackRequestMessage<DATA>
  148. {
  149. template<typename... Args>
  150. JackRequestTemplate(Args&... args) : JackRequestMessage<DATA>(args...)
  151. {}
  152. int Read(detail::JackChannelTransactionInterface* trans)
  153. {
  154. return JackRequestMessage<DATA>::ReadMessage(trans);
  155. }
  156. int Write(detail::JackChannelTransactionInterface* trans)
  157. {
  158. return JackRequestMessage<DATA>::WriteMessage(trans);
  159. }
  160. JackRequest::RequestType getType()
  161. {
  162. return JackRequestMessage<DATA>::fType;
  163. }
  164. };
  165. /*!
  166. \brief Result from the server.
  167. */
  168. struct JackResult
  169. {
  170. int fResult;
  171. JackResult(): fResult( -1)
  172. {}
  173. JackResult(int result): fResult(result)
  174. {}
  175. virtual ~JackResult()
  176. {}
  177. virtual int Read(detail::JackChannelTransactionInterface* trans)
  178. {
  179. return trans->Read(&fResult, sizeof(int));
  180. }
  181. virtual int Write(detail::JackChannelTransactionInterface* trans)
  182. {
  183. return trans->Write(&fResult, sizeof(int));
  184. }
  185. };
  186. /*!
  187. \brief CheckClient request.
  188. */
  189. PRE_PACKED_STRUCTURE_ALWAYS
  190. struct JackClientCheckRequestData
  191. {
  192. char fName[JACK_CLIENT_NAME_SIZE+1];
  193. int fProtocol;
  194. int fOptions;
  195. int fOpen;
  196. jack_uuid_t fUUID;
  197. JackClientCheckRequestData(const char* name="", int protocol=0, int options=0, jack_uuid_t uuid=JACK_UUID_EMPTY_INITIALIZER, int open = false)
  198. : fProtocol(protocol), fOptions(options), fOpen(open), fUUID(uuid)
  199. {
  200. memset(fName, 0, sizeof(fName));
  201. snprintf(fName, sizeof(fName), "%s", name);
  202. }
  203. static JackRequest::RequestType Type()
  204. {
  205. return JackRequest::RequestType::kClientCheck;
  206. }
  207. } POST_PACKED_STRUCTURE_ALWAYS;
  208. typedef JackRequestTemplate<JackClientCheckRequestData> JackClientCheckRequest;
  209. /*!
  210. \brief CheckClient result.
  211. */
  212. struct JackClientCheckResult : public JackResult
  213. {
  214. char fName[JACK_CLIENT_NAME_SIZE+1];
  215. int fStatus;
  216. JackClientCheckResult(): JackResult(), fStatus(0)
  217. {
  218. memset(fName, 0, sizeof(fName));
  219. }
  220. JackClientCheckResult(int32_t result, const char* name, int status)
  221. : JackResult(result), fStatus(status)
  222. {
  223. memset(fName, 0, sizeof(fName));
  224. snprintf(fName, sizeof(fName), "%s", name);
  225. }
  226. int Read(detail::JackChannelTransactionInterface* trans)
  227. {
  228. CheckRes(JackResult::Read(trans));
  229. CheckRes(trans->Read(&fName, sizeof(fName)));
  230. CheckRes(trans->Read(&fStatus, sizeof(int)));
  231. return 0;
  232. }
  233. int Write(detail::JackChannelTransactionInterface* trans)
  234. {
  235. CheckRes(JackResult::Write(trans));
  236. CheckRes(trans->Write(&fName, sizeof(fName)));
  237. CheckRes(trans->Write(&fStatus, sizeof(int)));
  238. return 0;
  239. }
  240. };
  241. /*!
  242. \brief NewClient request.
  243. */
  244. PRE_PACKED_STRUCTURE_ALWAYS
  245. struct JackClientOpenRequestData
  246. {
  247. int fPID;
  248. jack_uuid_t fUUID;
  249. char fName[JACK_CLIENT_NAME_SIZE+1];
  250. JackClientOpenRequestData(const char* name="", int pid=0, jack_uuid_t uuid=JACK_UUID_EMPTY_INITIALIZER)
  251. {
  252. memset(fName, 0, sizeof(fName));
  253. snprintf(fName, sizeof(fName), "%s", name);
  254. fPID = pid;
  255. fUUID = uuid;
  256. }
  257. static JackRequest::RequestType Type()
  258. {
  259. return JackRequest::RequestType::kClientOpen;
  260. }
  261. } POST_PACKED_STRUCTURE_ALWAYS;
  262. typedef JackRequestTemplate<JackClientOpenRequestData> JackClientOpenRequest;
  263. /*!
  264. \brief NewClient result.
  265. */
  266. struct JackClientOpenResult : public JackResult
  267. {
  268. int fSharedEngine;
  269. int fSharedClient;
  270. int fSharedGraph;
  271. JackClientOpenResult()
  272. : JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1)
  273. {}
  274. JackClientOpenResult(int32_t result, int index1, int index2, int index3)
  275. : JackResult(result), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3)
  276. {}
  277. int Read(detail::JackChannelTransactionInterface* trans)
  278. {
  279. CheckRes(JackResult::Read(trans));
  280. CheckRes(trans->Read(&fSharedEngine, sizeof(int)));
  281. CheckRes(trans->Read(&fSharedClient, sizeof(int)));
  282. CheckRes(trans->Read(&fSharedGraph, sizeof(int)));
  283. return 0;
  284. }
  285. int Write(detail::JackChannelTransactionInterface* trans)
  286. {
  287. CheckRes(JackResult::Write(trans));
  288. CheckRes(trans->Write(&fSharedEngine, sizeof(int)));
  289. CheckRes(trans->Write(&fSharedClient, sizeof(int)));
  290. CheckRes(trans->Write(&fSharedGraph, sizeof(int)));
  291. return 0;
  292. }
  293. };
  294. /*!
  295. \brief CloseClient request.
  296. */
  297. PRE_PACKED_STRUCTURE_ALWAYS
  298. struct JackClientCloseRequestData
  299. {
  300. int fRefNum;
  301. JackClientCloseRequestData(int refnum=0): fRefNum(refnum)
  302. {}
  303. static JackRequest::RequestType Type()
  304. {
  305. return JackRequest::RequestType::kClientClose;
  306. }
  307. } POST_PACKED_STRUCTURE_ALWAYS;
  308. typedef JackRequestTemplate<JackClientCloseRequestData> JackClientCloseRequest;
  309. /*!
  310. \brief Activate request.
  311. */
  312. PRE_PACKED_STRUCTURE_ALWAYS
  313. struct JackActivateRequestData
  314. {
  315. int fRefNum;
  316. int fIsRealTime;
  317. JackActivateRequestData(int refnum=0, int is_real_time=0)
  318. : fRefNum(refnum), fIsRealTime(is_real_time)
  319. {}
  320. static JackRequest::RequestType Type()
  321. {
  322. return JackRequest::RequestType::kActivateClient;
  323. }
  324. } POST_PACKED_STRUCTURE_ALWAYS;
  325. typedef JackRequestTemplate<JackActivateRequestData> JackActivateRequest;
  326. /*!
  327. \brief Deactivate request.
  328. */
  329. PRE_PACKED_STRUCTURE_ALWAYS
  330. struct JackDeactivateRequestData
  331. {
  332. int fRefNum;
  333. JackDeactivateRequestData(int refnum=0) : fRefNum(refnum)
  334. {}
  335. static JackRequest::RequestType Type()
  336. {
  337. return JackRequest::RequestType::kDeactivateClient;
  338. }
  339. } POST_PACKED_STRUCTURE_ALWAYS;
  340. typedef JackRequestTemplate<JackDeactivateRequestData> JackDeactivateRequest;
  341. /*!
  342. \brief PortRegister request.
  343. */
  344. PRE_PACKED_STRUCTURE_ALWAYS
  345. struct JackPortRegisterRequestData
  346. {
  347. int fRefNum;
  348. char fName[JACK_PORT_NAME_SIZE + 1]; // port short name
  349. char fPortType[JACK_PORT_TYPE_SIZE + 1];
  350. unsigned int fFlags;
  351. unsigned int fBufferSize;
  352. JackPortRegisterRequestData(int refnum=0, const char* name="", const char* port_type="", unsigned int flags=0, unsigned int buffer_size=0)
  353. : fRefNum(refnum), fFlags(flags), fBufferSize(buffer_size)
  354. {
  355. memset(fName, 0, sizeof(fName));
  356. memset(fPortType, 0, sizeof(fPortType));
  357. strncpy(fName, name, sizeof(fName)-1);
  358. strncpy(fPortType, port_type, sizeof(fPortType)-1);
  359. }
  360. static JackRequest::RequestType Type()
  361. {
  362. return JackRequest::RequestType::kRegisterPort;
  363. }
  364. } POST_PACKED_STRUCTURE_ALWAYS;
  365. typedef JackRequestTemplate<JackPortRegisterRequestData> JackPortRegisterRequest;
  366. /*!
  367. \brief PortRegister result.
  368. */
  369. struct JackPortRegisterResult : public JackResult
  370. {
  371. jack_port_id_t fPortIndex;
  372. JackPortRegisterResult(): JackResult(), fPortIndex(NO_PORT)
  373. {}
  374. int Read(detail::JackChannelTransactionInterface* trans)
  375. {
  376. CheckRes(JackResult::Read(trans));
  377. return trans->Read(&fPortIndex, sizeof(jack_port_id_t));
  378. }
  379. int Write(detail::JackChannelTransactionInterface* trans)
  380. {
  381. CheckRes(JackResult::Write(trans));
  382. return trans->Write(&fPortIndex, sizeof(jack_port_id_t));
  383. }
  384. };
  385. /*!
  386. \brief PortUnregister request.
  387. */
  388. PRE_PACKED_STRUCTURE_ALWAYS
  389. struct JackPortUnRegisterRequestData
  390. {
  391. int fRefNum;
  392. jack_port_id_t fPortIndex;
  393. JackPortUnRegisterRequestData(int refnum=0, jack_port_id_t index=0)
  394. : fRefNum(refnum), fPortIndex(index)
  395. {}
  396. static JackRequest::RequestType Type()
  397. {
  398. return JackRequest::RequestType::kUnRegisterPort;
  399. }
  400. } POST_PACKED_STRUCTURE_ALWAYS;
  401. typedef JackRequestTemplate<JackPortUnRegisterRequestData> JackPortUnRegisterRequest;
  402. /*!
  403. \brief PortConnectName request.
  404. */
  405. PRE_PACKED_STRUCTURE_ALWAYS
  406. struct JackPortConnectNameRequestData
  407. {
  408. int fRefNum;
  409. char fSrc[REAL_JACK_PORT_NAME_SIZE+1]; // port full name
  410. char fDst[REAL_JACK_PORT_NAME_SIZE+1]; // port full name
  411. JackPortConnectNameRequestData(int refnum=0, const char* src_name="", const char* dst_name="")
  412. : fRefNum(refnum)
  413. {
  414. memset(fSrc, 0, sizeof(fSrc));
  415. memset(fDst, 0, sizeof(fDst));
  416. strncpy(fSrc, src_name, sizeof(fSrc)-1);
  417. strncpy(fDst, dst_name, sizeof(fDst)-1);
  418. }
  419. static JackRequest::RequestType Type()
  420. {
  421. return JackRequest::RequestType::kConnectNamePorts;
  422. }
  423. } POST_PACKED_STRUCTURE_ALWAYS;
  424. typedef JackRequestTemplate<JackPortConnectNameRequestData> JackPortConnectNameRequest;
  425. /*!
  426. \brief PortDisconnectName request.
  427. */
  428. PRE_PACKED_STRUCTURE_ALWAYS
  429. struct JackPortDisconnectNameRequestData
  430. {
  431. int fRefNum;
  432. char fSrc[REAL_JACK_PORT_NAME_SIZE+1]; // port full name
  433. char fDst[REAL_JACK_PORT_NAME_SIZE+1]; // port full name
  434. JackPortDisconnectNameRequestData(int refnum=0, const char* src_name="", const char* dst_name="")
  435. : fRefNum(refnum)
  436. {
  437. memset(fSrc, 0, sizeof(fSrc));
  438. memset(fDst, 0, sizeof(fDst));
  439. strncpy(fSrc, src_name, sizeof(fSrc)-1);
  440. strncpy(fDst, dst_name, sizeof(fDst)-1);
  441. }
  442. static JackRequest::RequestType Type()
  443. {
  444. return JackRequest::RequestType::kDisconnectNamePorts;
  445. }
  446. } POST_PACKED_STRUCTURE_ALWAYS;
  447. typedef JackRequestTemplate<JackPortDisconnectNameRequestData> JackPortDisconnectNameRequest;
  448. /*!
  449. \brief PortConnect request.
  450. */
  451. PRE_PACKED_STRUCTURE_ALWAYS
  452. struct JackPortConnectRequestData
  453. {
  454. int fRefNum;
  455. jack_port_id_t fSrc;
  456. jack_port_id_t fDst;
  457. JackPortConnectRequestData(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
  458. : fRefNum(refnum), fSrc(src), fDst(dst)
  459. {}
  460. static JackRequest::RequestType Type()
  461. {
  462. return JackRequest::RequestType::kConnectPorts;
  463. }
  464. } POST_PACKED_STRUCTURE_ALWAYS;
  465. typedef JackRequestTemplate<JackPortConnectRequestData> JackPortConnectRequest;
  466. /*!
  467. \brief PortDisconnect request.
  468. */
  469. PRE_PACKED_STRUCTURE_ALWAYS
  470. struct JackPortDisconnectRequestData
  471. {
  472. int fRefNum;
  473. jack_port_id_t fSrc;
  474. jack_port_id_t fDst;
  475. JackPortDisconnectRequestData(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
  476. : fRefNum(refnum), fSrc(src), fDst(dst)
  477. {}
  478. static JackRequest::RequestType Type()
  479. {
  480. return JackRequest::RequestType::kDisconnectPorts;
  481. }
  482. } POST_PACKED_STRUCTURE_ALWAYS;
  483. typedef JackRequestTemplate<JackPortDisconnectRequestData> JackPortDisconnectRequest;
  484. /*!
  485. \brief PortRename request.
  486. */
  487. PRE_PACKED_STRUCTURE_ALWAYS
  488. struct JackPortRenameRequestData
  489. {
  490. int fRefNum;
  491. jack_port_id_t fPort;
  492. char fName[JACK_PORT_NAME_SIZE + 1]; // port short name
  493. JackPortRenameRequestData(int refnum=0, jack_port_id_t port=0, const char* name="")
  494. : fRefNum(refnum), fPort(port)
  495. {
  496. memset(fName, 0, sizeof(fName));
  497. strncpy(fName, name, sizeof(fName)-1);
  498. }
  499. static JackRequest::RequestType Type()
  500. {
  501. return JackRequest::RequestType::kPortRename;
  502. }
  503. } POST_PACKED_STRUCTURE_ALWAYS;
  504. typedef JackRequestTemplate<JackPortRenameRequestData> JackPortRenameRequest;
  505. /*!
  506. \brief SetBufferSize request.
  507. */
  508. PRE_PACKED_STRUCTURE_ALWAYS
  509. struct JackSetBufferSizeRequestData
  510. {
  511. jack_nframes_t fBufferSize;
  512. JackSetBufferSizeRequestData(jack_nframes_t buffer_size=0)
  513. : fBufferSize(buffer_size)
  514. {}
  515. static JackRequest::RequestType Type()
  516. {
  517. return JackRequest::RequestType::kSetBufferSize;
  518. }
  519. } POST_PACKED_STRUCTURE_ALWAYS;
  520. typedef JackRequestTemplate<JackSetBufferSizeRequestData> JackSetBufferSizeRequest;
  521. /*!
  522. \brief SetFreeWheel request.
  523. */
  524. PRE_PACKED_STRUCTURE_ALWAYS
  525. struct JackSetFreeWheelRequestData
  526. {
  527. int fOnOff;
  528. JackSetFreeWheelRequestData(int onoff=0)
  529. : fOnOff(onoff)
  530. {}
  531. static JackRequest::RequestType Type()
  532. {
  533. return JackRequest::RequestType::kSetFreeWheel;
  534. }
  535. } POST_PACKED_STRUCTURE_ALWAYS;
  536. typedef JackRequestTemplate<JackSetFreeWheelRequestData> JackSetFreeWheelRequest;
  537. /*!
  538. \brief ComputeTotalLatencies request.
  539. */
  540. PRE_PACKED_STRUCTURE_ALWAYS
  541. struct JackComputeTotalLatenciesRequestData
  542. {
  543. static JackRequest::RequestType Type()
  544. {
  545. return JackRequest::RequestType::kComputeTotalLatencies;
  546. }
  547. } POST_PACKED_STRUCTURE_ALWAYS;
  548. typedef JackRequestTemplate<JackComputeTotalLatenciesRequestData> JackComputeTotalLatenciesRequest;
  549. /*!
  550. \brief ReleaseTimebase request.
  551. */
  552. PRE_PACKED_STRUCTURE_ALWAYS
  553. struct JackReleaseTimebaseRequestData
  554. {
  555. int fRefNum;
  556. JackReleaseTimebaseRequestData(int refnum=0)
  557. : fRefNum(refnum)
  558. {}
  559. static JackRequest::RequestType Type()
  560. {
  561. return JackRequest::RequestType::kReleaseTimebase;
  562. }
  563. } POST_PACKED_STRUCTURE_ALWAYS;
  564. typedef JackRequestTemplate<JackReleaseTimebaseRequestData> JackReleaseTimebaseRequest;
  565. /*!
  566. \brief SetTimebaseCallback request.
  567. */
  568. PRE_PACKED_STRUCTURE_ALWAYS
  569. struct JackSetTimebaseCallbackRequestData
  570. {
  571. int fRefNum;
  572. int fConditionnal;
  573. JackSetTimebaseCallbackRequestData(int refnum=0, int conditional=0)
  574. : fRefNum(refnum), fConditionnal(conditional)
  575. {}
  576. static JackRequest::RequestType Type()
  577. {
  578. return JackRequest::RequestType::kSetTimebaseCallback;
  579. }
  580. } POST_PACKED_STRUCTURE_ALWAYS;
  581. typedef JackRequestTemplate<JackSetTimebaseCallbackRequestData> JackSetTimebaseCallbackRequest;
  582. /*!
  583. \brief GetInternalClientName request.
  584. */
  585. PRE_PACKED_STRUCTURE_ALWAYS
  586. struct JackGetInternalClientNameRequestData
  587. {
  588. int fRefNum;
  589. int fIntRefNum;
  590. JackGetInternalClientNameRequestData(int refnum=0, int int_ref=0)
  591. : fRefNum(refnum), fIntRefNum(int_ref)
  592. {}
  593. static JackRequest::RequestType Type()
  594. {
  595. return JackRequest::RequestType::kGetInternalClientName;
  596. }
  597. } POST_PACKED_STRUCTURE_ALWAYS;
  598. typedef JackRequestTemplate<JackGetInternalClientNameRequestData> JackGetInternalClientNameRequest;
  599. /*!
  600. \brief GetInternalClient result.
  601. */
  602. struct JackGetInternalClientNameResult : public JackResult
  603. {
  604. char fName[JACK_CLIENT_NAME_SIZE+1];
  605. JackGetInternalClientNameResult(): JackResult()
  606. {
  607. memset(fName, 0, sizeof(fName));
  608. }
  609. JackGetInternalClientNameResult(int32_t result, const char* name)
  610. : JackResult(result)
  611. {
  612. memset(fName, 0, sizeof(fName));
  613. snprintf(fName, sizeof(fName), "%s", name);
  614. }
  615. int Read(detail::JackChannelTransactionInterface* trans)
  616. {
  617. CheckRes(JackResult::Read(trans));
  618. CheckRes(trans->Read(&fName, sizeof(fName)));
  619. return 0;
  620. }
  621. int Write(detail::JackChannelTransactionInterface* trans)
  622. {
  623. CheckRes(JackResult::Write(trans));
  624. CheckRes(trans->Write(&fName, sizeof(fName)));
  625. return 0;
  626. }
  627. int Size() { return sizeof(fName); }
  628. };
  629. /*!
  630. \brief InternalClientHandle request.
  631. */
  632. PRE_PACKED_STRUCTURE_ALWAYS
  633. struct JackInternalClientHandleRequestData
  634. {
  635. int fRefNum;
  636. char fName[JACK_CLIENT_NAME_SIZE+1];
  637. JackInternalClientHandleRequestData(int refnum=0, const char* client_name="")
  638. : fRefNum(refnum)
  639. {
  640. memset(fName, 0, sizeof(fName));
  641. snprintf(fName, sizeof(fName), "%s", client_name);
  642. }
  643. static JackRequest::RequestType Type()
  644. {
  645. return JackRequest::RequestType::kInternalClientHandle;
  646. }
  647. } POST_PACKED_STRUCTURE_ALWAYS;
  648. typedef JackRequestTemplate<JackInternalClientHandleRequestData> JackInternalClientHandleRequest;
  649. /*!
  650. \brief InternalClientHandle result.
  651. */
  652. struct JackInternalClientHandleResult : public JackResult
  653. {
  654. int fStatus;
  655. int fIntRefNum;
  656. JackInternalClientHandleResult(): JackResult(), fStatus(0), fIntRefNum(0)
  657. {}
  658. JackInternalClientHandleResult(int32_t result, int status, int int_ref)
  659. : JackResult(result), fStatus(status), fIntRefNum(int_ref)
  660. {}
  661. int Read(detail::JackChannelTransactionInterface* trans)
  662. {
  663. CheckRes(JackResult::Read(trans));
  664. CheckRes(trans->Read(&fStatus, sizeof(int)));
  665. CheckRes(trans->Read(&fIntRefNum, sizeof(int)));
  666. return 0;
  667. }
  668. int Write(detail::JackChannelTransactionInterface* trans)
  669. {
  670. CheckRes(JackResult::Write(trans));
  671. CheckRes(trans->Write(&fStatus, sizeof(int)));
  672. CheckRes(trans->Write(&fIntRefNum, sizeof(int)));
  673. return 0;
  674. }
  675. int Size() { return sizeof(int) + sizeof(int); }
  676. };
  677. /*!
  678. \brief InternalClientLoad request.
  679. */
  680. PRE_PACKED_STRUCTURE_ALWAYS
  681. struct JackInternalClientLoadRequestData
  682. {
  683. #ifndef MAX_PATH
  684. #define MAX_PATH 256
  685. #endif
  686. int fRefNum;
  687. char fName[JACK_CLIENT_NAME_SIZE+1];
  688. char fDllName[MAX_PATH+1];
  689. char fLoadInitName[JACK_LOAD_INIT_LIMIT+1];
  690. int fOptions;
  691. jack_uuid_t fUUID;
  692. JackInternalClientLoadRequestData(int refnum=0, const char* client_name="", const char* so_name="", const char* objet_data="", int options=0, jack_uuid_t uuid=JACK_UUID_EMPTY_INITIALIZER)
  693. : fRefNum(refnum), fOptions(options), fUUID(uuid)
  694. {
  695. memset(fName, 0, sizeof(fName));
  696. memset(fDllName, 0, sizeof(fDllName));
  697. memset(fLoadInitName, 0, sizeof(fLoadInitName));
  698. strncpy(fName, client_name, sizeof(fName)-1);
  699. if (so_name) {
  700. strncpy(fDllName, so_name, sizeof(fDllName)-1);
  701. }
  702. if (objet_data) {
  703. strncpy(fLoadInitName, objet_data, sizeof(fLoadInitName)-1);
  704. }
  705. }
  706. static JackRequest::RequestType Type()
  707. {
  708. return JackRequest::RequestType::kInternalClientLoad;
  709. }
  710. } POST_PACKED_STRUCTURE_ALWAYS;
  711. typedef JackRequestTemplate<JackInternalClientLoadRequestData> JackInternalClientLoadRequest;
  712. /*!
  713. \brief InternalClientLoad result.
  714. */
  715. struct JackInternalClientLoadResult : public JackResult
  716. {
  717. int fStatus;
  718. int fIntRefNum;
  719. JackInternalClientLoadResult(): JackResult(), fStatus(0), fIntRefNum(0)
  720. {}
  721. JackInternalClientLoadResult(int32_t result, int status, int int_ref)
  722. : JackResult(result), fStatus(status), fIntRefNum(int_ref)
  723. {}
  724. int Read(detail::JackChannelTransactionInterface* trans)
  725. {
  726. CheckRes(JackResult::Read(trans));
  727. CheckRes(trans->Read(&fStatus, sizeof(int)));
  728. CheckRes(trans->Read(&fIntRefNum, sizeof(int)));
  729. return 0;
  730. }
  731. int Write(detail::JackChannelTransactionInterface* trans)
  732. {
  733. CheckRes(JackResult::Write(trans));
  734. CheckRes(trans->Write(&fStatus, sizeof(int)));
  735. CheckRes(trans->Write(&fIntRefNum, sizeof(int)));
  736. return 0;
  737. }
  738. int Size() { return sizeof(int) + sizeof(int); }
  739. };
  740. /*!
  741. \brief InternalClientUnload request.
  742. */
  743. PRE_PACKED_STRUCTURE_ALWAYS
  744. struct JackInternalClientUnloadRequestData
  745. {
  746. int fRefNum;
  747. int fIntRefNum;
  748. JackInternalClientUnloadRequestData(int refnum=0, int int_ref=0)
  749. : fRefNum(refnum), fIntRefNum(int_ref)
  750. {}
  751. static JackRequest::RequestType Type()
  752. {
  753. return JackRequest::RequestType::kInternalClientUnload;
  754. }
  755. } POST_PACKED_STRUCTURE_ALWAYS;
  756. typedef JackRequestTemplate<JackInternalClientUnloadRequestData> JackInternalClientUnloadRequest;
  757. /*!
  758. \brief InternalClientLoad result.
  759. */
  760. struct JackInternalClientUnloadResult : public JackResult
  761. {
  762. int fStatus;
  763. JackInternalClientUnloadResult(): JackResult(), fStatus(0)
  764. {}
  765. JackInternalClientUnloadResult(int32_t result, int status)
  766. : JackResult(result), fStatus(status)
  767. {}
  768. int Read(detail::JackChannelTransactionInterface* trans)
  769. {
  770. CheckRes(JackResult::Read(trans));
  771. CheckRes(trans->Read(&fStatus, sizeof(int)));
  772. return 0;
  773. }
  774. int Write(detail::JackChannelTransactionInterface* trans)
  775. {
  776. CheckRes(JackResult::Write(trans));
  777. CheckRes(trans->Write(&fStatus, sizeof(int)));
  778. return 0;
  779. }
  780. int Size() { return sizeof(int); }
  781. };
  782. /*!
  783. \brief ClientNotification request.
  784. */
  785. PRE_PACKED_STRUCTURE_ALWAYS
  786. struct JackClientNotificationRequestData
  787. {
  788. int fRefNum;
  789. int fNotify;
  790. int fValue;
  791. JackClientNotificationRequestData(int refnum=0, int notify=0, int value=0)
  792. : fRefNum(refnum), fNotify(notify), fValue(value)
  793. {}
  794. static JackRequest::RequestType Type()
  795. {
  796. return JackRequest::RequestType::kNotification;
  797. }
  798. } POST_PACKED_STRUCTURE_ALWAYS;
  799. typedef JackRequestTemplate<JackClientNotificationRequestData> JackClientNotificationRequest;
  800. struct JackSessionCommand
  801. {
  802. char fUUID[JACK_UUID_STRING_SIZE];
  803. char fClientName[JACK_CLIENT_NAME_SIZE+1];
  804. char fCommand[JACK_SESSION_COMMAND_SIZE+1];
  805. jack_session_flags_t fFlags;
  806. JackSessionCommand() : fFlags(JackSessionSaveError)
  807. {
  808. memset(fUUID, 0, sizeof(fUUID));
  809. memset(fClientName, 0, sizeof(fClientName));
  810. memset(fCommand, 0, sizeof(fCommand));
  811. }
  812. JackSessionCommand(const char *uuid, const char *clientname, const char *command, jack_session_flags_t flags)
  813. {
  814. memset(fUUID, 0, sizeof(fUUID));
  815. memset(fClientName, 0, sizeof(fClientName));
  816. memset(fCommand, 0, sizeof(fCommand));
  817. strncpy(fUUID, uuid, sizeof(fUUID)-1);
  818. strncpy(fClientName, clientname, sizeof(fClientName)-1);
  819. strncpy(fCommand, command, sizeof(fCommand)-1);
  820. fFlags = flags;
  821. }
  822. };
  823. struct JackSessionNotifyResult : public JackResult
  824. {
  825. std::list<JackSessionCommand> fCommandList;
  826. bool fDone;
  827. JackSessionNotifyResult(): JackResult(), fDone(false)
  828. {}
  829. JackSessionNotifyResult(int32_t result)
  830. : JackResult(result), fDone(false)
  831. {}
  832. int Read(detail::JackChannelTransactionInterface* trans)
  833. {
  834. if (trans == NULL)
  835. {
  836. return 0;
  837. }
  838. CheckRes(JackResult::Read(trans));
  839. while (true) {
  840. JackSessionCommand buffer;
  841. CheckRes(trans->Read(buffer.fUUID, sizeof(buffer.fUUID)));
  842. if (buffer.fUUID[0] == '\0')
  843. break;
  844. CheckRes(trans->Read(buffer.fClientName, sizeof(buffer.fClientName)));
  845. CheckRes(trans->Read(buffer.fCommand, sizeof(buffer.fCommand)));
  846. CheckRes(trans->Read(&(buffer.fFlags), sizeof(buffer.fFlags)));
  847. fCommandList.push_back(buffer);
  848. }
  849. fDone = true;
  850. return 0;
  851. }
  852. int Write(detail::JackChannelTransactionInterface* trans)
  853. {
  854. if (trans == NULL)
  855. {
  856. fDone = true;
  857. return 0;
  858. }
  859. char terminator[JACK_UUID_STRING_SIZE];
  860. memset(terminator, 0, sizeof(terminator));
  861. CheckRes(JackResult::Write(trans));
  862. for (std::list<JackSessionCommand>::iterator i = fCommandList.begin(); i != fCommandList.end(); i++) {
  863. CheckRes(trans->Write(i->fUUID, sizeof(i->fUUID)));
  864. CheckRes(trans->Write(i->fClientName, sizeof(i->fClientName)));
  865. CheckRes(trans->Write(i->fCommand, sizeof(i->fCommand)));
  866. CheckRes(trans->Write(&(i->fFlags), sizeof(i->fFlags)));
  867. }
  868. CheckRes(trans->Write(terminator, sizeof(terminator)));
  869. return 0;
  870. }
  871. jack_session_command_t* GetCommands()
  872. {
  873. /* TODO: some kind of signal should be used instead */
  874. while (!fDone)
  875. {
  876. JackSleep(50000); /* 50 ms */
  877. }
  878. jack_session_command_t* session_command = (jack_session_command_t *)malloc(sizeof(jack_session_command_t) * (fCommandList.size() + 1));
  879. int i = 0;
  880. for (std::list<JackSessionCommand>::iterator ci = fCommandList.begin(); ci != fCommandList.end(); ci++) {
  881. session_command[i].uuid = strdup(ci->fUUID);
  882. session_command[i].client_name = strdup(ci->fClientName);
  883. session_command[i].command = strdup(ci->fCommand);
  884. session_command[i].flags = ci->fFlags;
  885. i += 1;
  886. }
  887. session_command[i].uuid = NULL;
  888. session_command[i].client_name = NULL;
  889. session_command[i].command = NULL;
  890. session_command[i].flags = (jack_session_flags_t)0;
  891. return session_command;
  892. }
  893. };
  894. /*!
  895. \brief SessionNotify request.
  896. */
  897. PRE_PACKED_STRUCTURE_ALWAYS
  898. struct JackSessionNotifyRequestData
  899. {
  900. char fPath[JACK_MESSAGE_SIZE+1];
  901. char fDst[JACK_CLIENT_NAME_SIZE+1];
  902. jack_session_event_type_t fEventType;
  903. int fRefNum;
  904. JackSessionNotifyRequestData(int refnum=0, const char* path="", jack_session_event_type_t type=JackSessionSave, const char* dst=NULL)
  905. : fEventType(type), fRefNum(refnum)
  906. {
  907. memset(fPath, 0, sizeof(fPath));
  908. memset(fDst, 0, sizeof(fDst));
  909. strncpy(fPath, path, sizeof(fPath)-1);
  910. if (dst) {
  911. strncpy(fDst, dst, sizeof(fDst)-1);
  912. }
  913. }
  914. static JackRequest::RequestType Type()
  915. {
  916. return JackRequest::RequestType::kSessionNotify;
  917. }
  918. } POST_PACKED_STRUCTURE_ALWAYS;
  919. typedef JackRequestTemplate<JackSessionNotifyRequestData> JackSessionNotifyRequest;
  920. PRE_PACKED_STRUCTURE_ALWAYS
  921. struct JackSessionReplyRequestData
  922. {
  923. int fRefNum;
  924. JackSessionReplyRequestData(int refnum=0)
  925. : fRefNum(refnum)
  926. {}
  927. static JackRequest::RequestType Type()
  928. {
  929. return JackRequest::RequestType::kSessionReply;
  930. }
  931. } POST_PACKED_STRUCTURE_ALWAYS;
  932. typedef JackRequestTemplate<JackSessionReplyRequestData> JackSessionReplyRequest;
  933. struct JackClientNameResult : public JackResult
  934. {
  935. char fName[JACK_CLIENT_NAME_SIZE+1];
  936. JackClientNameResult(): JackResult()
  937. {
  938. memset(fName, 0, sizeof(fName));
  939. }
  940. JackClientNameResult(int32_t result, const char* name)
  941. : JackResult(result)
  942. {
  943. memset(fName, 0, sizeof(fName));
  944. strncpy(fName, name, sizeof(fName)-1);
  945. }
  946. int Read(detail::JackChannelTransactionInterface* trans)
  947. {
  948. CheckRes(JackResult::Read(trans));
  949. CheckRes(trans->Read(&fName, sizeof(fName)));
  950. return 0;
  951. }
  952. int Write(detail::JackChannelTransactionInterface* trans)
  953. {
  954. CheckRes(JackResult::Write(trans));
  955. CheckRes(trans->Write(&fName, sizeof(fName)));
  956. return 0;
  957. }
  958. };
  959. struct JackUUIDResult : public JackResult
  960. {
  961. char fUUID[JACK_UUID_STRING_SIZE];
  962. JackUUIDResult(): JackResult()
  963. {
  964. memset(fUUID, 0, sizeof(fUUID));
  965. }
  966. JackUUIDResult(int32_t result, const char* uuid)
  967. : JackResult(result)
  968. {
  969. memset(fUUID, 0, sizeof(fUUID));
  970. strncpy(fUUID, uuid, sizeof(fUUID)-1);
  971. }
  972. int Read(detail::JackChannelTransactionInterface* trans)
  973. {
  974. CheckRes(JackResult::Read(trans));
  975. CheckRes(trans->Read(&fUUID, sizeof(fUUID)));
  976. return 0;
  977. }
  978. int Write(detail::JackChannelTransactionInterface* trans)
  979. {
  980. CheckRes(JackResult::Write(trans));
  981. CheckRes(trans->Write(&fUUID, sizeof(fUUID)));
  982. return 0;
  983. }
  984. };
  985. PRE_PACKED_STRUCTURE_ALWAYS
  986. struct JackGetUUIDRequestData
  987. {
  988. char fName[JACK_CLIENT_NAME_SIZE+1];
  989. JackGetUUIDRequestData(const char* client_name="")
  990. {
  991. memset(fName, 0, sizeof(fName));
  992. strncpy(fName, client_name, sizeof(fName)-1);
  993. }
  994. static JackRequest::RequestType Type()
  995. {
  996. return JackRequest::RequestType::kGetUUIDByClient;
  997. }
  998. } POST_PACKED_STRUCTURE_ALWAYS;
  999. typedef JackRequestTemplate<JackGetUUIDRequestData> JackGetUUIDRequest;
  1000. PRE_PACKED_STRUCTURE_ALWAYS
  1001. struct JackGetClientNameRequestData
  1002. {
  1003. char fUUID[JACK_UUID_STRING_SIZE];
  1004. JackGetClientNameRequestData(const char* uuid="")
  1005. {
  1006. memset(fUUID, 0, sizeof(fUUID));
  1007. strncpy(fUUID, uuid, sizeof(fUUID)-1);
  1008. }
  1009. static JackRequest::RequestType Type()
  1010. {
  1011. return JackRequest::RequestType::kGetClientByUUID;
  1012. }
  1013. } POST_PACKED_STRUCTURE_ALWAYS;
  1014. typedef JackRequestTemplate<JackGetClientNameRequestData> JackGetClientNameRequest;
  1015. PRE_PACKED_STRUCTURE_ALWAYS
  1016. struct JackReserveNameRequestData
  1017. {
  1018. int fRefNum;
  1019. char fName[JACK_CLIENT_NAME_SIZE+1];
  1020. char fUUID[JACK_UUID_STRING_SIZE];
  1021. JackReserveNameRequestData(int refnum=0, const char *name="", const char* uuid="")
  1022. : fRefNum(refnum)
  1023. {
  1024. memset(fName, 0, sizeof(fName));
  1025. memset(fUUID, 0, sizeof(fUUID));
  1026. strncpy(fName, name, sizeof(fName)-1);
  1027. strncpy(fUUID, uuid, sizeof(fUUID)-1);
  1028. }
  1029. static JackRequest::RequestType Type()
  1030. {
  1031. return JackRequest::RequestType::kReserveClientName;
  1032. }
  1033. } POST_PACKED_STRUCTURE_ALWAYS;
  1034. typedef JackRequestTemplate<JackReserveNameRequestData> JackReserveNameRequest;
  1035. PRE_PACKED_STRUCTURE_ALWAYS
  1036. struct JackClientHasSessionCallbackRequestData
  1037. {
  1038. char fName[JACK_CLIENT_NAME_SIZE+1];
  1039. JackClientHasSessionCallbackRequestData(const char *name="")
  1040. {
  1041. memset(fName, 0, sizeof(fName));
  1042. strncpy(fName, name, sizeof(fName)-1);
  1043. }
  1044. static JackRequest::RequestType Type()
  1045. {
  1046. return JackRequest::RequestType::kClientHasSessionCallback;
  1047. }
  1048. } POST_PACKED_STRUCTURE_ALWAYS;
  1049. typedef JackRequestTemplate<JackClientHasSessionCallbackRequestData> JackClientHasSessionCallbackRequest;
  1050. PRE_PACKED_STRUCTURE_ALWAYS
  1051. struct JackPropertyChangeNotifyRequestData
  1052. {
  1053. jack_uuid_t fSubject;
  1054. char fKey[MAX_PATH+1];
  1055. jack_property_change_t fChange;
  1056. JackPropertyChangeNotifyRequestData(jack_uuid_t subject=0, const char* key="", jack_property_change_t change=(jack_property_change_t)0)
  1057. : fChange(change)
  1058. {
  1059. jack_uuid_copy(&fSubject, subject);
  1060. memset(fKey, 0, sizeof(fKey));
  1061. if (key)
  1062. strncpy(fKey, key, sizeof(fKey)-1);
  1063. }
  1064. static JackRequest::RequestType Type()
  1065. {
  1066. return JackRequest::RequestType::kPropertyChangeNotify;
  1067. }
  1068. } POST_PACKED_STRUCTURE_ALWAYS;
  1069. typedef JackRequestTemplate<JackPropertyChangeNotifyRequestData> JackPropertyChangeNotifyRequest;
  1070. /*!
  1071. \brief ClientNotification.
  1072. */
  1073. struct JackClientNotification
  1074. {
  1075. int fSize;
  1076. char fName[JACK_CLIENT_NAME_SIZE+1];
  1077. int fRefNum;
  1078. int fNotify;
  1079. int fValue1;
  1080. int fValue2;
  1081. int fSync;
  1082. char fMessage[JACK_MESSAGE_SIZE+1];
  1083. JackClientNotification(): fSize(0), fRefNum(0), fNotify(-1), fValue1(-1), fValue2(-1), fSync(0)
  1084. {
  1085. memset(fName, 0, sizeof(fName));
  1086. memset(fMessage, 0, sizeof(fMessage));
  1087. }
  1088. JackClientNotification(const char* name, int refnum, int notify, int sync, const char* message, int value1, int value2)
  1089. : fRefNum(refnum), fNotify(notify), fValue1(value1), fValue2(value2), fSync(sync)
  1090. {
  1091. memset(fName, 0, sizeof(fName));
  1092. memset(fMessage, 0, sizeof(fMessage));
  1093. strncpy(fName, name, sizeof(fName)-1);
  1094. if (message) {
  1095. strncpy(fMessage, message, sizeof(fMessage)-1);
  1096. }
  1097. fSize = Size();
  1098. }
  1099. int Read(detail::JackChannelTransactionInterface* trans)
  1100. {
  1101. CheckSize();
  1102. CheckRes(trans->Read(&fName, sizeof(fName)));
  1103. CheckRes(trans->Read(&fRefNum, sizeof(int)));
  1104. CheckRes(trans->Read(&fNotify, sizeof(int)));
  1105. CheckRes(trans->Read(&fValue1, sizeof(int)));
  1106. CheckRes(trans->Read(&fValue2, sizeof(int)));
  1107. CheckRes(trans->Read(&fSync, sizeof(int)));
  1108. CheckRes(trans->Read(&fMessage, sizeof(fMessage)));
  1109. return 0;
  1110. }
  1111. int Write(detail::JackChannelTransactionInterface* trans)
  1112. {
  1113. CheckRes(trans->Write(&fSize, sizeof(int)));
  1114. CheckRes(trans->Write(&fName, sizeof(fName)));
  1115. CheckRes(trans->Write(&fRefNum, sizeof(int)));
  1116. CheckRes(trans->Write(&fNotify, sizeof(int)));
  1117. CheckRes(trans->Write(&fValue1, sizeof(int)));
  1118. CheckRes(trans->Write(&fValue2, sizeof(int)));
  1119. CheckRes(trans->Write(&fSync, sizeof(int)));
  1120. CheckRes(trans->Write(&fMessage, sizeof(fMessage)));
  1121. return 0;
  1122. }
  1123. int Size() { return sizeof(int) + sizeof(fName) + 5 * sizeof(int) + sizeof(fMessage); }
  1124. };
  1125. } // end of namespace
  1126. #endif