Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 // Server <===> client 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 // Connect to server 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 // Connect to server 00064 if (!fServerPort.ConnectPort(jack_server_entry_name)) { 00065 jack_error("Cannot connect to server Mach port"); 00066 return -1; 00067 } 00068 00069 // Check name in server 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 // Prepare local port using client name 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 To be sure notification thread is started before ClientOpen is called. 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 } // end of namespace 00333 00334