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.

308 lines
10KB

  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, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
  56. if (result < 0) {
  57. int status1 = *status;
  58. if (status1 & JackVersionError)
  59. jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
  60. else
  61. jack_error("Client name = %s conflits with another running client", name);
  62. return -1;
  63. }
  64. // Prepare local port using client name
  65. char buf[JACK_CLIENT_NAME_SIZE];
  66. snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name_res);
  67. if (!fClientPort.AllocatePort(buf, 16)) {
  68. jack_error("Cannot allocate client Mach port");
  69. return -1;
  70. }
  71. JackLibGlobals::fGlobals->fClientTable[fClientPort.GetPort()] = client;
  72. return 0;
  73. }
  74. void JackMachClientChannel::Close()
  75. {
  76. JackLog("JackMachClientChannel::Close\n");
  77. JackLibGlobals::fGlobals->fClientTable.erase(fClientPort.GetPort());
  78. fServerPort.DisconnectPort();
  79. fClientPort.DestroyPort();
  80. // TO CHECK
  81. kern_return_t res;
  82. if ((res = mach_port_destroy(mach_task_self(), fPrivatePort)) != KERN_SUCCESS) {
  83. jack_error("JackMachClientChannel::Close err = %s", mach_error_string(res));
  84. }
  85. }
  86. int JackMachClientChannel::Start()
  87. {
  88. JackLog("JackMachClientChannel::Start\n");
  89. if (fThread->Start() != 0) {
  90. jack_error("Cannot start Jack client listener");
  91. return -1;
  92. } else {
  93. return 0;
  94. }
  95. }
  96. void JackMachClientChannel::Stop()
  97. {
  98. JackLog("JackMachClientChannel::Stop\n");
  99. fThread->Kill();
  100. }
  101. void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result)
  102. {
  103. kern_return_t res = rpc_jack_client_check(fServerPort.GetPort(), (char*)name, name_res, protocol, options, status, result);
  104. if (res != KERN_SUCCESS) {
  105. *result = -1;
  106. jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res));
  107. }
  108. }
  109. void JackMachClientChannel::ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result)
  110. {
  111. kern_return_t res = rpc_jack_client_open(fServerPort.GetPort(), (char*)name, &fPrivatePort, shared_engine, shared_client, shared_graph, result);
  112. if (res != KERN_SUCCESS) {
  113. *result = -1;
  114. jack_error("JackMachClientChannel::ClientOpen err = %s", mach_error_string(res));
  115. }
  116. }
  117. void JackMachClientChannel::ClientClose(int refnum, int* result)
  118. {
  119. kern_return_t res = rpc_jack_client_close(fPrivatePort, refnum, result);
  120. if (res != KERN_SUCCESS) {
  121. *result = -1;
  122. jack_error("JackMachClientChannel::ClientClose err = %s", mach_error_string(res));
  123. }
  124. }
  125. void JackMachClientChannel::ClientActivate(int refnum, int* result)
  126. {
  127. kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, result);
  128. if (res != KERN_SUCCESS) {
  129. *result = -1;
  130. jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res));
  131. }
  132. }
  133. void JackMachClientChannel::ClientDeactivate(int refnum, int* result)
  134. {
  135. kern_return_t res = rpc_jack_client_deactivate(fPrivatePort, refnum, result);
  136. if (res != KERN_SUCCESS) {
  137. *result = -1;
  138. jack_error("JackMachClientChannel::ClientDeactivate err = %s", mach_error_string(res));
  139. }
  140. }
  141. void JackMachClientChannel::PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
  142. {
  143. kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, flags, buffer_size, port_index, result);
  144. if (res != KERN_SUCCESS) {
  145. *result = -1;
  146. jack_error("JackMachClientChannel::PortRegister err = %s", mach_error_string(res));
  147. }
  148. }
  149. void JackMachClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
  150. {
  151. kern_return_t res = rpc_jack_port_unregister(fPrivatePort, refnum, port_index, result);
  152. if (res != KERN_SUCCESS) {
  153. *result = -1;
  154. jack_error("JackMachClientChannel::PortUnRegister err = %s", mach_error_string(res));
  155. }
  156. }
  157. void JackMachClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
  158. {
  159. kern_return_t res = rpc_jack_port_connect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
  160. if (res != KERN_SUCCESS) {
  161. jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
  162. }
  163. }
  164. void JackMachClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
  165. {
  166. kern_return_t res = rpc_jack_port_disconnect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
  167. if (res != KERN_SUCCESS) {
  168. *result = -1;
  169. jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
  170. }
  171. }
  172. void JackMachClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
  173. {
  174. kern_return_t res = rpc_jack_port_connect(fPrivatePort, refnum, src, dst, result);
  175. if (res != KERN_SUCCESS) {
  176. *result = -1;
  177. jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
  178. }
  179. }
  180. void JackMachClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
  181. {
  182. kern_return_t res = rpc_jack_port_disconnect(fPrivatePort, refnum, src, dst, result);
  183. if (res != KERN_SUCCESS) {
  184. *result = -1;
  185. jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
  186. }
  187. }
  188. void JackMachClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
  189. {
  190. kern_return_t res = rpc_jack_set_buffer_size(fPrivatePort, buffer_size, result);
  191. if (res != KERN_SUCCESS) {
  192. *result = -1;
  193. jack_error("JackMachClientChannel::SetBufferSize err = %s", mach_error_string(res));
  194. }
  195. }
  196. void JackMachClientChannel::SetFreewheel(int onoff, int* result)
  197. {
  198. kern_return_t res = rpc_jack_set_freewheel(fPrivatePort, onoff, result);
  199. if (res != KERN_SUCCESS) {
  200. *result = -1;
  201. jack_error("JackMachClientChannel::SetFreewheel err = %s", mach_error_string(res));
  202. }
  203. }
  204. void JackMachClientChannel::ReleaseTimebase(int refnum, int* result)
  205. {
  206. kern_return_t res = rpc_jack_release_timebase(fPrivatePort, refnum, result);
  207. if (res != KERN_SUCCESS) {
  208. *result = -1;
  209. jack_error("JackMachClientChannel::ReleaseTimebase err = %s", mach_error_string(res));
  210. }
  211. }
  212. void JackMachClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
  213. {
  214. kern_return_t res = rpc_jack_set_timebase_callback(fPrivatePort, refnum, conditional, result);
  215. if (res != KERN_SUCCESS) {
  216. *result = -1;
  217. jack_error("JackMachClientChannel::SetTimebaseCallback err = %s", mach_error_string(res));
  218. }
  219. }
  220. void JackMachClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
  221. {
  222. kern_return_t res = rpc_jack_get_internal_clientname(fPrivatePort, refnum, int_ref, name_res, result);
  223. if (res != KERN_SUCCESS) {
  224. *result = -1;
  225. jack_error("JackMachClientChannel::GetInternalClientName err = %s", mach_error_string(res));
  226. }
  227. }
  228. void JackMachClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
  229. {
  230. kern_return_t res = rpc_jack_internal_clienthandle(fPrivatePort, refnum, (char*)client_name, status, int_ref, result);
  231. if (res != KERN_SUCCESS) {
  232. *result = -1;
  233. jack_error("JackMachClientChannel::InternalClientHandle err = %s", mach_error_string(res));
  234. }
  235. }
  236. void JackMachClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result)
  237. {
  238. kern_return_t res = rpc_jack_internal_clientload(fPrivatePort, refnum, (char*)client_name, (char*)so_name, (char*)objet_data, options, status, int_ref, result);
  239. if (res != KERN_SUCCESS) {
  240. *result = -1;
  241. jack_error("JackMachClientChannel::InternalClientLoad err = %s", mach_error_string(res));
  242. }
  243. }
  244. void JackMachClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
  245. {
  246. kern_return_t res = rpc_jack_internal_clientunload(fPrivatePort, refnum, int_ref, status, result);
  247. if (res != KERN_SUCCESS) {
  248. *result = -1;
  249. jack_error("JackMachClientChannel::InternalClientUnload err = %s", mach_error_string(res));
  250. }
  251. }
  252. bool JackMachClientChannel::Execute()
  253. {
  254. kern_return_t res;
  255. if ((res = mach_msg_server(JackRPCClient_server, 1024, fClientPort.GetPort(), 0)) != KERN_SUCCESS) {
  256. jack_error("JackMachClientChannel::Execute err = %s", mach_error_string(res));
  257. //fClient->ShutDown();
  258. return false;
  259. } else {
  260. return true;
  261. }
  262. }
  263. } // end of namespace