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