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.

313 lines
11KB

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