2
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.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU Lesser General Public License for more details.
14
You should have received a copy of the GNU Lesser General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
#include "JackMachClientChannel.h"
21
#include "JackRPCEngine.h"
22
#include "JackTools.h"
23
#include "JackRPCClientServer.c"
24
#include "JackError.h"
25
#include "JackLibClient.h"
26
#include "JackMachThread.h"
27
#include "JackConstants.h"
32
std::map<mach_port_t, JackClient*> gClientTable;
34
JackMachClientChannel::JackMachClientChannel():fPrivatePort(0),fThread(this)
37
JackMachClientChannel::~JackMachClientChannel()
40
// Server <===> client
42
int JackMachClientChannel::ServerCheck(const char* server_name)
44
jack_log("JackMachClientChannel::ServerCheck = %s", server_name);
45
char jack_server_entry_name[512];
46
snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name);
49
if (!fServerPort.ConnectPort(jack_server_entry_name)) {
50
jack_error("Cannot connect to server Mach port");
57
int JackMachClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status)
59
jack_log("JackMachClientChannel::Open name = %s", name);
60
char jack_server_entry_name[512];
61
snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name);
64
if (!fServerPort.ConnectPort(jack_server_entry_name)) {
65
jack_error("Cannot connect to server Mach port");
69
// Check name in server
71
ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
73
int status1 = *status;
74
if (status1 & JackVersionError)
75
jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
77
jack_error("Client name = %s conflits with another running client", name);
81
// Prepare local port using client name
82
char buf[JACK_CLIENT_NAME_SIZE + 1];
83
snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name_res);
85
if (!fClientPort.AllocatePort(buf, 16)) {
86
jack_error("Cannot allocate client Mach port");
90
gClientTable[fClientPort.GetPort()] = client;
94
void JackMachClientChannel::Close()
96
jack_log("JackMachClientChannel::Close");
97
gClientTable.erase(fClientPort.GetPort());
98
fServerPort.DisconnectPort();
99
fClientPort.DestroyPort();
101
if (fPrivatePort != 0) {
103
if ((res = mach_port_destroy(mach_task_self(), fPrivatePort)) != KERN_SUCCESS) {
104
jack_error("JackMachClientChannel::Close err = %s", mach_error_string(res));
109
int JackMachClientChannel::Start()
111
jack_log("JackMachClientChannel::Start");
113
To be sure notification thread is started before ClientOpen is called.
115
if (fThread.StartSync() != 0) {
116
jack_error("Cannot start Jack client listener");
123
void JackMachClientChannel::Stop()
125
jack_log("JackMachClientChannel::Stop");
129
void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result)
131
kern_return_t res = rpc_jack_client_check(fServerPort.GetPort(), (char*)name, name_res, protocol, options, status, result);
132
if (res != KERN_SUCCESS) {
134
jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res));
138
void JackMachClientChannel::ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
140
kern_return_t res = rpc_jack_client_open(fServerPort.GetPort(), (char*)name, pid, &fPrivatePort, shared_engine, shared_client, shared_graph, result);
141
if (res != KERN_SUCCESS) {
143
jack_error("JackMachClientChannel::ClientOpen err = %s", mach_error_string(res));
147
void JackMachClientChannel::ClientClose(int refnum, int* result)
149
kern_return_t res = rpc_jack_client_close(fPrivatePort, refnum, result);
150
if (res != KERN_SUCCESS) {
152
jack_error("JackMachClientChannel::ClientClose err = %s", mach_error_string(res));
156
void JackMachClientChannel::ClientActivate(int refnum, int is_real_time, int* result)
158
kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, is_real_time, result);
159
if (res != KERN_SUCCESS) {
161
jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res));
165
void JackMachClientChannel::ClientDeactivate(int refnum, int* result)
167
kern_return_t res = rpc_jack_client_deactivate(fPrivatePort, refnum, result);
168
if (res != KERN_SUCCESS) {
170
jack_error("JackMachClientChannel::ClientDeactivate err = %s", mach_error_string(res));
174
void JackMachClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
176
kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, (char*)type, flags, buffer_size, port_index, result);
177
if (res != KERN_SUCCESS) {
179
jack_error("JackMachClientChannel::PortRegister err = %s", mach_error_string(res));
183
void JackMachClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
185
kern_return_t res = rpc_jack_port_unregister(fPrivatePort, refnum, port_index, result);
186
if (res != KERN_SUCCESS) {
188
jack_error("JackMachClientChannel::PortUnRegister err = %s", mach_error_string(res));
192
void JackMachClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
194
kern_return_t res = rpc_jack_port_connect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
195
if (res != KERN_SUCCESS) {
196
jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
200
void JackMachClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
202
kern_return_t res = rpc_jack_port_disconnect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
203
if (res != KERN_SUCCESS) {
205
jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
209
void JackMachClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
211
kern_return_t res = rpc_jack_port_connect(fPrivatePort, refnum, src, dst, result);
212
if (res != KERN_SUCCESS) {
214
jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
218
void JackMachClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
220
kern_return_t res = rpc_jack_port_disconnect(fPrivatePort, refnum, src, dst, result);
221
if (res != KERN_SUCCESS) {
223
jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
227
void JackMachClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result)
229
kern_return_t res = rpc_jack_port_rename(fPrivatePort, refnum, port, (char*)name, result);
230
if (res != KERN_SUCCESS) {
232
jack_error("JackMachClientChannel::PortRename err = %s", mach_error_string(res));
236
void JackMachClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
238
kern_return_t res = rpc_jack_set_buffer_size(fPrivatePort, buffer_size, result);
239
if (res != KERN_SUCCESS) {
241
jack_error("JackMachClientChannel::SetBufferSize err = %s", mach_error_string(res));
245
void JackMachClientChannel::SetFreewheel(int onoff, int* result)
247
kern_return_t res = rpc_jack_set_freewheel(fPrivatePort, onoff, result);
248
if (res != KERN_SUCCESS) {
250
jack_error("JackMachClientChannel::SetFreewheel err = %s", mach_error_string(res));
254
void JackMachClientChannel::ReleaseTimebase(int refnum, int* result)
256
kern_return_t res = rpc_jack_release_timebase(fPrivatePort, refnum, result);
257
if (res != KERN_SUCCESS) {
259
jack_error("JackMachClientChannel::ReleaseTimebase err = %s", mach_error_string(res));
263
void JackMachClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
265
kern_return_t res = rpc_jack_set_timebase_callback(fPrivatePort, refnum, conditional, result);
266
if (res != KERN_SUCCESS) {
268
jack_error("JackMachClientChannel::SetTimebaseCallback err = %s", mach_error_string(res));
272
void JackMachClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
274
kern_return_t res = rpc_jack_get_internal_clientname(fPrivatePort, refnum, int_ref, name_res, result);
275
if (res != KERN_SUCCESS) {
277
jack_error("JackMachClientChannel::GetInternalClientName err = %s", mach_error_string(res));
281
void JackMachClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
283
kern_return_t res = rpc_jack_internal_clienthandle(fPrivatePort, refnum, (char*)client_name, status, int_ref, result);
284
if (res != KERN_SUCCESS) {
286
jack_error("JackMachClientChannel::InternalClientHandle err = %s", mach_error_string(res));
290
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)
292
const char* int_client_name = (client_name) ? client_name : "";
293
const char* int_so_name = (so_name) ? so_name : "";
294
const char* int_objet_data = (objet_data) ? objet_data : "";
296
kern_return_t res = rpc_jack_internal_clientload(fPrivatePort, refnum, (char*)int_client_name, (char*)int_so_name, (char*)int_objet_data, options, status, int_ref, result);
297
if (res != KERN_SUCCESS) {
299
jack_error("JackMachClientChannel::InternalClientLoad err = %s", mach_error_string(res));
303
void JackMachClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
305
kern_return_t res = rpc_jack_internal_clientunload(fPrivatePort, refnum, int_ref, status, result);
306
if (res != KERN_SUCCESS) {
308
jack_error("JackMachClientChannel::InternalClientUnload err = %s", mach_error_string(res));
312
bool JackMachClientChannel::Init()
314
jack_log("JackMachClientChannel::Init");
315
JackClient* client = gClientTable[fClientPort.GetPort()];
316
return client->Init();
319
bool JackMachClientChannel::Execute()
322
if ((res = mach_msg_server(JackRPCClient_server, 1024, fClientPort.GetPort(), 0)) != KERN_SUCCESS) {
323
jack_error("JackMachClientChannel::Execute err = %s", mach_error_string(res));
324
JackClient* client = gClientTable[fClientPort.GetPort()];
332
} // end of namespace