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.

268 lines
8.6KB

  1. /*
  2. Copyright (C) 2004-2006 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 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 General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackMachClientChannel.h"
  16. #include "JackRPCEngine.h"
  17. #include "JackRPCClientServer.c"
  18. #include "JackError.h"
  19. #include "JackLibClient.h"
  20. #include "JackLibGlobals.h"
  21. #include "JackMachThread.h"
  22. #include "JackConstants.h"
  23. namespace Jack
  24. {
  25. JackMachClientChannel::JackMachClientChannel()
  26. {
  27. fThread = new JackMachThread(this);
  28. }
  29. JackMachClientChannel::~JackMachClientChannel()
  30. {
  31. delete fThread;
  32. }
  33. // Server <===> client
  34. int JackMachClientChannel::ServerCheck(const char* server_name)
  35. {
  36. JackLog("JackMachClientChannel::ServerCheck = %s\n", server_name);
  37. // Connect to server
  38. if (!fServerPort.ConnectPort(jack_server_entry)) {
  39. jack_error("Cannot connect to server Mach port");
  40. return -1;
  41. } else {
  42. return 0;
  43. }
  44. }
  45. int JackMachClientChannel::Open(const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status)
  46. {
  47. JackLog("JackMachClientChannel::Open name = %s\n", name);
  48. // Connect to server
  49. if (!fServerPort.ConnectPort(jack_server_entry)) {
  50. jack_error("Cannot connect to server Mach port");
  51. return -1;
  52. }
  53. // Check name in server
  54. int result = 0;
  55. ClientCheck(name, name_res, (int)options, (int*)status, &result);
  56. if (result < 0) {
  57. jack_error("Client name = %s conflits with another running client", name);
  58. return -1;
  59. }
  60. // Prepare local port using client name
  61. char buf[JACK_CLIENT_NAME_SIZE];
  62. snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name_res);
  63. if (!fClientPort.AllocatePort(buf, 16)) {
  64. jack_error("Cannot allocate client Mach port");
  65. return -1;
  66. }
  67. JackLibGlobals::fGlobals->fClientTable[fClientPort.GetPort()] = client;
  68. return 0;
  69. }
  70. void JackMachClientChannel::Close()
  71. {
  72. JackLog("JackMachClientChannel::Close\n");
  73. JackLibGlobals::fGlobals->fClientTable.erase(fClientPort.GetPort());
  74. fServerPort.DisconnectPort();
  75. fClientPort.DestroyPort();
  76. // TO CHECK
  77. kern_return_t res;
  78. if ((res = mach_port_destroy(mach_task_self(), fPrivatePort)) != KERN_SUCCESS) {
  79. jack_error("JackMachClientChannel::Close err = %s", mach_error_string(res));
  80. }
  81. }
  82. int JackMachClientChannel::Start()
  83. {
  84. JackLog("JackMachClientChannel::Start\n");
  85. if (fThread->Start() != 0) {
  86. jack_error("Cannot start Jack client listener");
  87. return -1;
  88. } else {
  89. return 0;
  90. }
  91. }
  92. void JackMachClientChannel::Stop()
  93. {
  94. JackLog("JackMachClientChannel::Stop\n");
  95. fThread->Kill();
  96. }
  97. void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int options, int* status, int* result)
  98. {
  99. kern_return_t res = rpc_jack_client_check(fServerPort.GetPort(), (char*)name, name_res, options, status, result);
  100. if (res != KERN_SUCCESS) {
  101. *result = -1;
  102. jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res));
  103. }
  104. }
  105. void JackMachClientChannel::ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result)
  106. {
  107. kern_return_t res = rpc_jack_client_open(fServerPort.GetPort(), (char*)name, &fPrivatePort, shared_engine, shared_client, shared_graph, result);
  108. if (res != KERN_SUCCESS) {
  109. *result = -1;
  110. jack_error("JackMachClientChannel::ClientOpen err = %s", mach_error_string(res));
  111. }
  112. }
  113. void JackMachClientChannel::ClientClose(int refnum, int* result)
  114. {
  115. kern_return_t res = rpc_jack_client_close(fPrivatePort, refnum, result);
  116. if (res != KERN_SUCCESS) {
  117. *result = -1;
  118. jack_error("JackMachClientChannel::ClientClose err = %s", mach_error_string(res));
  119. }
  120. }
  121. void JackMachClientChannel::ClientActivate(int refnum, int* result)
  122. {
  123. kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, result);
  124. if (res != KERN_SUCCESS) {
  125. *result = -1;
  126. jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res));
  127. }
  128. }
  129. void JackMachClientChannel::ClientDeactivate(int refnum, int* result)
  130. {
  131. kern_return_t res = rpc_jack_client_deactivate(fPrivatePort, refnum, result);
  132. if (res != KERN_SUCCESS) {
  133. *result = -1;
  134. jack_error("JackMachClientChannel::ClientDeactivate err = %s", mach_error_string(res));
  135. }
  136. }
  137. void JackMachClientChannel::PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
  138. {
  139. kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, flags, buffer_size, port_index, result);
  140. if (res != KERN_SUCCESS) {
  141. *result = -1;
  142. jack_error("JackMachClientChannel::PortRegister err = %s", mach_error_string(res));
  143. }
  144. }
  145. void JackMachClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
  146. {
  147. kern_return_t res = rpc_jack_port_unregister(fPrivatePort, refnum, port_index, result);
  148. if (res != KERN_SUCCESS) {
  149. *result = -1;
  150. jack_error("JackMachClientChannel::PortUnRegister err = %s", mach_error_string(res));
  151. }
  152. }
  153. void JackMachClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
  154. {
  155. kern_return_t res = rpc_jack_port_connect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
  156. if (res != KERN_SUCCESS) {
  157. jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
  158. }
  159. }
  160. void JackMachClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
  161. {
  162. kern_return_t res = rpc_jack_port_disconnect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
  163. if (res != KERN_SUCCESS) {
  164. *result = -1;
  165. jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
  166. }
  167. }
  168. void JackMachClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
  169. {
  170. kern_return_t res = rpc_jack_port_connect(fPrivatePort, refnum, src, dst, result);
  171. if (res != KERN_SUCCESS) {
  172. *result = -1;
  173. jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
  174. }
  175. }
  176. void JackMachClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
  177. {
  178. kern_return_t res = rpc_jack_port_disconnect(fPrivatePort, refnum, src, dst, result);
  179. if (res != KERN_SUCCESS) {
  180. *result = -1;
  181. jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
  182. }
  183. }
  184. void JackMachClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
  185. {
  186. kern_return_t res = rpc_jack_set_buffer_size(fPrivatePort, buffer_size, result);
  187. if (res != KERN_SUCCESS) {
  188. *result = -1;
  189. jack_error("JackMachClientChannel::SetBufferSize err = %s", mach_error_string(res));
  190. }
  191. }
  192. void JackMachClientChannel::SetFreewheel(int onoff, int* result)
  193. {
  194. kern_return_t res = rpc_jack_set_freewheel(fPrivatePort, onoff, result);
  195. if (res != KERN_SUCCESS) {
  196. *result = -1;
  197. jack_error("JackMachClientChannel::SetFreewheel err = %s", mach_error_string(res));
  198. }
  199. }
  200. void JackMachClientChannel::ReleaseTimebase(int refnum, int* result)
  201. {
  202. kern_return_t res = rpc_jack_release_timebase(fPrivatePort, refnum, result);
  203. if (res != KERN_SUCCESS) {
  204. *result = -1;
  205. jack_error("JackMachClientChannel::ReleaseTimebase err = %s", mach_error_string(res));
  206. }
  207. }
  208. void JackMachClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
  209. {
  210. kern_return_t res = rpc_jack_set_timebase_callback(fPrivatePort, refnum, conditional, result);
  211. if (res != KERN_SUCCESS) {
  212. *result = -1;
  213. jack_error("JackMachClientChannel::SetTimebaseCallback err = %s", mach_error_string(res));
  214. }
  215. }
  216. bool JackMachClientChannel::Execute()
  217. {
  218. kern_return_t res;
  219. if ((res = mach_msg_server(JackRPCClient_server, 1024, fClientPort.GetPort(), 0)) != KERN_SUCCESS) {
  220. jack_error("JackMachClientChannel::Execute err = %s", mach_error_string(res));
  221. //fClient->ShutDown();
  222. return false;
  223. } else {
  224. return true;
  225. }
  226. }
  227. } // end of namespace