00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackMachClientChannel.h"
00021 #include "JackRPCEngine.h"
00022 #include "JackTools.h"
00023 #include "JackRPCClientServer.c"
00024 #include "JackError.h"
00025 #include "JackLibClient.h"
00026 #include "JackLibGlobals.h"
00027 #include "JackMachThread.h"
00028 #include "JackConstants.h"
00029
00030 namespace Jack
00031 {
00032
00033 std::map<mach_port_t, JackClient*> gClientTable;
00034
00035 JackMachClientChannel::JackMachClientChannel():fPrivatePort(0),fThread(this)
00036 {}
00037
00038 JackMachClientChannel::~JackMachClientChannel()
00039 {}
00040
00041
00042
00043 int JackMachClientChannel::ServerCheck(const char* server_name)
00044 {
00045 jack_log("JackMachClientChannel::ServerCheck = %s", server_name);
00046 char jack_server_entry_name[512];
00047 snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name);
00048
00049
00050 if (!fServerPort.ConnectPort(jack_server_entry_name)) {
00051 jack_error("Cannot connect to server Mach port");
00052 return -1;
00053 } else {
00054 return 0;
00055 }
00056 }
00057
00058 int JackMachClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status)
00059 {
00060 jack_log("JackMachClientChannel::Open name = %s", name);
00061 char jack_server_entry_name[512];
00062 snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name);
00063
00064
00065 if (!fServerPort.ConnectPort(jack_server_entry_name)) {
00066 jack_error("Cannot connect to server Mach port");
00067 return -1;
00068 }
00069
00070
00071 int result = 0;
00072 ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
00073 if (result < 0) {
00074 int status1 = *status;
00075 if (status1 & JackVersionError)
00076 jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
00077 else
00078 jack_error("Client name = %s conflits with another running client", name);
00079 return -1;
00080 }
00081
00082
00083 char buf[JACK_CLIENT_NAME_SIZE];
00084 snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name_res);
00085
00086 if (!fClientPort.AllocatePort(buf, 16)) {
00087 jack_error("Cannot allocate client Mach port");
00088 return -1;
00089 }
00090
00091 gClientTable[fClientPort.GetPort()] = client;
00092 return 0;
00093 }
00094
00095 void JackMachClientChannel::Close()
00096 {
00097 jack_log("JackMachClientChannel::Close");
00098 gClientTable.erase(fClientPort.GetPort());
00099 fServerPort.DisconnectPort();
00100 fClientPort.DestroyPort();
00101
00102 if (fPrivatePort != 0) {
00103 kern_return_t res;
00104 if ((res = mach_port_destroy(mach_task_self(), fPrivatePort)) != KERN_SUCCESS) {
00105 jack_error("JackMachClientChannel::Close err = %s", mach_error_string(res));
00106 }
00107 }
00108 }
00109
00110 int JackMachClientChannel::Start()
00111 {
00112 jack_log("JackMachClientChannel::Start");
00113
00114
00115
00116 if (fThread.StartSync() != 0) {
00117 jack_error("Cannot start Jack client listener");
00118 return -1;
00119 } else {
00120 return 0;
00121 }
00122 }
00123
00124 void JackMachClientChannel::Stop()
00125 {
00126 jack_log("JackMachClientChannel::Stop");
00127 fThread.Kill();
00128 }
00129
00130 void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result)
00131 {
00132 kern_return_t res = rpc_jack_client_check(fServerPort.GetPort(), (char*)name, name_res, protocol, options, status, result);
00133 if (res != KERN_SUCCESS) {
00134 *result = -1;
00135 jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res));
00136 }
00137 }
00138
00139 void JackMachClientChannel::ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00140 {
00141 kern_return_t res = rpc_jack_client_open(fServerPort.GetPort(), (char*)name, pid, &fPrivatePort, shared_engine, shared_client, shared_graph, result);
00142 if (res != KERN_SUCCESS) {
00143 *result = -1;
00144 jack_error("JackMachClientChannel::ClientOpen err = %s", mach_error_string(res));
00145 }
00146 }
00147
00148 void JackMachClientChannel::ClientClose(int refnum, int* result)
00149 {
00150 kern_return_t res = rpc_jack_client_close(fPrivatePort, refnum, result);
00151 if (res != KERN_SUCCESS) {
00152 *result = -1;
00153 jack_error("JackMachClientChannel::ClientClose err = %s", mach_error_string(res));
00154 }
00155 }
00156
00157 void JackMachClientChannel::ClientActivate(int refnum, int state, int* result)
00158 {
00159 kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, state, result);
00160 if (res != KERN_SUCCESS) {
00161 *result = -1;
00162 jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res));
00163 }
00164 }
00165
00166 void JackMachClientChannel::ClientDeactivate(int refnum, int* result)
00167 {
00168 kern_return_t res = rpc_jack_client_deactivate(fPrivatePort, refnum, result);
00169 if (res != KERN_SUCCESS) {
00170 *result = -1;
00171 jack_error("JackMachClientChannel::ClientDeactivate err = %s", mach_error_string(res));
00172 }
00173 }
00174
00175 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)
00176 {
00177 kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, (char*)type, flags, buffer_size, port_index, result);
00178 if (res != KERN_SUCCESS) {
00179 *result = -1;
00180 jack_error("JackMachClientChannel::PortRegister err = %s", mach_error_string(res));
00181 }
00182 }
00183
00184 void JackMachClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
00185 {
00186 kern_return_t res = rpc_jack_port_unregister(fPrivatePort, refnum, port_index, result);
00187 if (res != KERN_SUCCESS) {
00188 *result = -1;
00189 jack_error("JackMachClientChannel::PortUnRegister err = %s", mach_error_string(res));
00190 }
00191 }
00192
00193 void JackMachClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
00194 {
00195 kern_return_t res = rpc_jack_port_connect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
00196 if (res != KERN_SUCCESS) {
00197 jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
00198 }
00199 }
00200
00201 void JackMachClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
00202 {
00203 kern_return_t res = rpc_jack_port_disconnect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
00204 if (res != KERN_SUCCESS) {
00205 *result = -1;
00206 jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
00207 }
00208 }
00209
00210 void JackMachClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00211 {
00212 kern_return_t res = rpc_jack_port_connect(fPrivatePort, refnum, src, dst, result);
00213 if (res != KERN_SUCCESS) {
00214 *result = -1;
00215 jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
00216 }
00217 }
00218
00219 void JackMachClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00220 {
00221 kern_return_t res = rpc_jack_port_disconnect(fPrivatePort, refnum, src, dst, result);
00222 if (res != KERN_SUCCESS) {
00223 *result = -1;
00224 jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
00225 }
00226 }
00227
00228 void JackMachClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result)
00229 {
00230 kern_return_t res = rpc_jack_port_rename(fPrivatePort, refnum, port, (char*)name, result);
00231 if (res != KERN_SUCCESS) {
00232 *result = -1;
00233 jack_error("JackMachClientChannel::PortRename err = %s", mach_error_string(res));
00234 }
00235 }
00236
00237 void JackMachClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
00238 {
00239 kern_return_t res = rpc_jack_set_buffer_size(fPrivatePort, buffer_size, result);
00240 if (res != KERN_SUCCESS) {
00241 *result = -1;
00242 jack_error("JackMachClientChannel::SetBufferSize err = %s", mach_error_string(res));
00243 }
00244 }
00245
00246 void JackMachClientChannel::SetFreewheel(int onoff, int* result)
00247 {
00248 kern_return_t res = rpc_jack_set_freewheel(fPrivatePort, onoff, result);
00249 if (res != KERN_SUCCESS) {
00250 *result = -1;
00251 jack_error("JackMachClientChannel::SetFreewheel err = %s", mach_error_string(res));
00252 }
00253 }
00254
00255 void JackMachClientChannel::ReleaseTimebase(int refnum, int* result)
00256 {
00257 kern_return_t res = rpc_jack_release_timebase(fPrivatePort, refnum, result);
00258 if (res != KERN_SUCCESS) {
00259 *result = -1;
00260 jack_error("JackMachClientChannel::ReleaseTimebase err = %s", mach_error_string(res));
00261 }
00262 }
00263
00264 void JackMachClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
00265 {
00266 kern_return_t res = rpc_jack_set_timebase_callback(fPrivatePort, refnum, conditional, result);
00267 if (res != KERN_SUCCESS) {
00268 *result = -1;
00269 jack_error("JackMachClientChannel::SetTimebaseCallback err = %s", mach_error_string(res));
00270 }
00271 }
00272
00273 void JackMachClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
00274 {
00275 kern_return_t res = rpc_jack_get_internal_clientname(fPrivatePort, refnum, int_ref, name_res, result);
00276 if (res != KERN_SUCCESS) {
00277 *result = -1;
00278 jack_error("JackMachClientChannel::GetInternalClientName err = %s", mach_error_string(res));
00279 }
00280 }
00281
00282 void JackMachClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
00283 {
00284 kern_return_t res = rpc_jack_internal_clienthandle(fPrivatePort, refnum, (char*)client_name, status, int_ref, result);
00285 if (res != KERN_SUCCESS) {
00286 *result = -1;
00287 jack_error("JackMachClientChannel::InternalClientHandle err = %s", mach_error_string(res));
00288 }
00289 }
00290
00291 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)
00292 {
00293 const char* int_client_name = (client_name) ? client_name : "";
00294 const char* int_so_name = (so_name) ? so_name : "";
00295 const char* int_objet_data = (objet_data) ? objet_data : "";
00296
00297 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);
00298 if (res != KERN_SUCCESS) {
00299 *result = -1;
00300 jack_error("JackMachClientChannel::InternalClientLoad err = %s", mach_error_string(res));
00301 }
00302 }
00303
00304 void JackMachClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
00305 {
00306 kern_return_t res = rpc_jack_internal_clientunload(fPrivatePort, refnum, int_ref, status, result);
00307 if (res != KERN_SUCCESS) {
00308 *result = -1;
00309 jack_error("JackMachClientChannel::InternalClientUnload err = %s", mach_error_string(res));
00310 }
00311 }
00312
00313 bool JackMachClientChannel::Init()
00314 {
00315 jack_log("JackMachClientChannel::Init");
00316 JackClient* client = gClientTable[fClientPort.GetPort()];
00317 return client->Init();
00318 }
00319
00320 bool JackMachClientChannel::Execute()
00321 {
00322 kern_return_t res;
00323 if ((res = mach_msg_server(JackRPCClient_server, 1024, fClientPort.GetPort(), 0)) != KERN_SUCCESS) {
00324 jack_error("JackMachClientChannel::Execute err = %s", mach_error_string(res));
00325 JackClient* client = gClientTable[fClientPort.GetPort()];
00326 client->ShutDown();
00327 return false;
00328 } else {
00329 return true;
00330 }
00331 }
00332
00333 }
00334
00335