Jack2
1.9.7
|
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 "JackSocketClientChannel.h" 00021 #include "JackRequest.h" 00022 #include "JackClient.h" 00023 #include "JackGlobals.h" 00024 00025 namespace Jack 00026 { 00027 00028 JackSocketClientChannel::JackSocketClientChannel(): 00029 fThread(this) 00030 { 00031 fNotificationSocket = NULL; 00032 fClient = NULL; 00033 } 00034 00035 JackSocketClientChannel::~JackSocketClientChannel() 00036 { 00037 delete fNotificationSocket; 00038 } 00039 00040 int JackSocketClientChannel::ServerCheck(const char* server_name) 00041 { 00042 jack_log("JackSocketClientChannel::ServerCheck = %s", server_name); 00043 00044 // Connect to server 00045 if (fRequestSocket.Connect(jack_server_dir, server_name, 0) < 0) { 00046 jack_error("Cannot connect to server socket"); 00047 fRequestSocket.Close(); 00048 return -1; 00049 } else { 00050 return 0; 00051 } 00052 } 00053 00054 int JackSocketClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) 00055 { 00056 int result = 0; 00057 jack_log("JackSocketClientChannel::Open name = %s", name); 00058 00059 if (fRequestSocket.Connect(jack_server_dir, server_name, 0) < 0) { 00060 jack_error("Cannot connect to server socket"); 00061 goto error; 00062 } 00063 00064 // Check name in server 00065 ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); 00066 if (result < 0) { 00067 int status1 = *status; 00068 if (status1 & JackVersionError) 00069 jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); 00070 else 00071 jack_error("Client name = %s conflits with another running client", name); 00072 goto error; 00073 } 00074 00075 if (fNotificationListenSocket.Bind(jack_client_dir, name_res, 0) < 0) { 00076 jack_error("Cannot bind socket"); 00077 goto error; 00078 } 00079 00080 fClient = obj; 00081 return 0; 00082 00083 error: 00084 fRequestSocket.Close(); 00085 fNotificationListenSocket.Close(); 00086 return -1; 00087 } 00088 00089 void JackSocketClientChannel::Close() 00090 { 00091 fRequestSocket.Close(); 00092 fNotificationListenSocket.Close(); 00093 if (fNotificationSocket) 00094 fNotificationSocket->Close(); 00095 } 00096 00097 int JackSocketClientChannel::Start() 00098 { 00099 jack_log("JackSocketClientChannel::Start"); 00100 /* 00101 To be sure notification thread is started before ClientOpen is called. 00102 */ 00103 if (fThread.StartSync() != 0) { 00104 jack_error("Cannot start Jack client listener"); 00105 return -1; 00106 } else { 00107 return 0; 00108 } 00109 } 00110 00111 void JackSocketClientChannel::Stop() 00112 { 00113 jack_log("JackSocketClientChannel::Stop"); 00114 fThread.Kill(); 00115 } 00116 00117 void JackSocketClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, int* result) 00118 { 00119 if (req->Write(&fRequestSocket) < 0) { 00120 jack_error("Could not write request type = %ld", req->fType); 00121 *result = -1; 00122 return; 00123 } 00124 00125 if (res->Read(&fRequestSocket) < 0) { 00126 jack_error("Could not read result type = %ld", req->fType); 00127 *result = -1; 00128 return; 00129 } 00130 00131 *result = res->fResult; 00132 } 00133 00134 void JackSocketClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result) 00135 { 00136 if (req->Write(&fRequestSocket) < 0) { 00137 jack_error("Could not write request type = %ld", req->fType); 00138 *result = -1; 00139 } else { 00140 *result = 0; 00141 } 00142 } 00143 00144 void JackSocketClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) 00145 { 00146 JackClientCheckRequest req(name, protocol, options, uuid); 00147 JackClientCheckResult res; 00148 ServerSyncCall(&req, &res, result); 00149 *status = res.fStatus; 00150 strcpy(name_res, res.fName); 00151 } 00152 00153 void JackSocketClientChannel::ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) 00154 { 00155 JackClientOpenRequest req(name, pid, uuid); 00156 JackClientOpenResult res; 00157 ServerSyncCall(&req, &res, result); 00158 *shared_engine = res.fSharedEngine; 00159 *shared_client = res.fSharedClient; 00160 *shared_graph = res.fSharedGraph; 00161 } 00162 00163 void JackSocketClientChannel::ClientClose(int refnum, int* result) 00164 { 00165 JackClientCloseRequest req(refnum); 00166 JackResult res; 00167 ServerSyncCall(&req, &res, result); 00168 } 00169 00170 void JackSocketClientChannel::ClientActivate(int refnum, int is_real_time, int* result) 00171 { 00172 JackActivateRequest req(refnum, is_real_time); 00173 JackResult res; 00174 ServerSyncCall(&req, &res, result); 00175 } 00176 00177 void JackSocketClientChannel::ClientDeactivate(int refnum, int* result) 00178 { 00179 JackDeactivateRequest req(refnum); 00180 JackResult res; 00181 ServerSyncCall(&req, &res, result); 00182 } 00183 00184 void JackSocketClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) 00185 { 00186 JackPortRegisterRequest req(refnum, name, type, flags, buffer_size); 00187 JackPortRegisterResult res; 00188 ServerSyncCall(&req, &res, result); 00189 *port_index = res.fPortIndex; 00190 } 00191 00192 void JackSocketClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result) 00193 { 00194 JackPortUnRegisterRequest req(refnum, port_index); 00195 JackResult res; 00196 ServerSyncCall(&req, &res, result); 00197 } 00198 00199 void JackSocketClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result) 00200 { 00201 JackPortConnectNameRequest req(refnum, src, dst); 00202 JackResult res; 00203 ServerSyncCall(&req, &res, result); 00204 } 00205 00206 void JackSocketClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result) 00207 { 00208 JackPortDisconnectNameRequest req(refnum, src, dst); 00209 JackResult res; 00210 ServerSyncCall(&req, &res, result); 00211 } 00212 00213 void JackSocketClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) 00214 { 00215 JackPortConnectRequest req(refnum, src, dst); 00216 JackResult res; 00217 ServerSyncCall(&req, &res, result); 00218 } 00219 00220 void JackSocketClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) 00221 { 00222 JackPortDisconnectRequest req(refnum, src, dst); 00223 JackResult res; 00224 ServerSyncCall(&req, &res, result); 00225 } 00226 00227 void JackSocketClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result) 00228 { 00229 JackPortRenameRequest req(refnum, port, name); 00230 JackResult res; 00231 ServerSyncCall(&req, &res, result); 00232 } 00233 00234 void JackSocketClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result) 00235 { 00236 JackSetBufferSizeRequest req(buffer_size); 00237 JackResult res; 00238 ServerSyncCall(&req, &res, result); 00239 } 00240 00241 void JackSocketClientChannel::SetFreewheel(int onoff, int* result) 00242 { 00243 JackSetFreeWheelRequest req(onoff); 00244 JackResult res; 00245 ServerSyncCall(&req, &res, result); 00246 } 00247 00248 void JackSocketClientChannel::ComputeTotalLatencies(int* result) 00249 { 00250 JackComputeTotalLatenciesRequest req; 00251 JackResult res; 00252 ServerSyncCall(&req, &res, result); 00253 } 00254 00255 void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result) 00256 { 00257 JackSessionNotifyRequest req(refnum, path, type, target); 00258 JackSessionNotifyResult res; 00259 int intresult; 00260 ServerSyncCall(&req, &res, &intresult); 00261 00262 jack_session_command_t* session_command = (jack_session_command_t *)malloc(sizeof(jack_session_command_t) * (res.fCommandList.size() + 1)); 00263 int i = 0; 00264 00265 for (std::list<JackSessionCommand>::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) { 00266 session_command[i].uuid = strdup( ci->fUUID ); 00267 session_command[i].client_name = strdup( ci->fClientName ); 00268 session_command[i].command = strdup( ci->fCommand ); 00269 session_command[i].flags = ci->fFlags; 00270 i += 1; 00271 } 00272 00273 session_command[i].uuid = NULL; 00274 session_command[i].client_name = NULL; 00275 session_command[i].command = NULL; 00276 session_command[i].flags = (jack_session_flags_t)0; 00277 00278 *result = session_command; 00279 } 00280 00281 void JackSocketClientChannel::SessionReply(int refnum, int* result) 00282 { 00283 JackSessionReplyRequest req(refnum); 00284 JackResult res; 00285 ServerSyncCall(&req, &res, result); 00286 } 00287 00288 void JackSocketClientChannel::GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result) 00289 { 00290 JackGetUUIDRequest req(client_name); 00291 JackUUIDResult res; 00292 ServerSyncCall(&req, &res, result); 00293 strncpy(uuid_res, res.fUUID, JACK_UUID_SIZE); 00294 } 00295 00296 void JackSocketClientChannel::GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result) 00297 { 00298 JackGetClientNameRequest req(uuid); 00299 JackClientNameResult res; 00300 ServerSyncCall(&req, &res, result); 00301 strncpy(name_res, res.fName, JACK_CLIENT_NAME_SIZE); 00302 } 00303 00304 void JackSocketClientChannel::ClientHasSessionCallback(const char* client_name, int* result) 00305 { 00306 JackClientHasSessionCallbackRequest req(client_name); 00307 JackResult res; 00308 ServerSyncCall(&req, &res, result); 00309 } 00310 00311 void JackSocketClientChannel::ReserveClientName(int refnum, const char* client_name, const char* uuid, int* result) 00312 { 00313 JackReserveNameRequest req(refnum, client_name, uuid); 00314 JackResult res; 00315 ServerSyncCall(&req, &res, result); 00316 } 00317 00318 void JackSocketClientChannel::ReleaseTimebase(int refnum, int* result) 00319 { 00320 JackReleaseTimebaseRequest req(refnum); 00321 JackResult res; 00322 ServerSyncCall(&req, &res, result); 00323 } 00324 00325 void JackSocketClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result) 00326 { 00327 JackSetTimebaseCallbackRequest req(refnum, conditional); 00328 JackResult res; 00329 ServerSyncCall(&req, &res, result); 00330 } 00331 00332 void JackSocketClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) 00333 { 00334 JackGetInternalClientNameRequest req(refnum, int_ref); 00335 JackGetInternalClientNameResult res; 00336 ServerSyncCall(&req, &res, result); 00337 strcpy(name_res, res.fName); 00338 } 00339 00340 void JackSocketClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) 00341 { 00342 JackInternalClientHandleRequest req(refnum, client_name); 00343 JackInternalClientHandleResult res; 00344 ServerSyncCall(&req, &res, result); 00345 *int_ref = res.fIntRefNum; 00346 *status = res.fStatus; 00347 } 00348 00349 void JackSocketClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) 00350 { 00351 JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options, uuid); 00352 JackInternalClientLoadResult res; 00353 ServerSyncCall(&req, &res, result); 00354 *int_ref = res.fIntRefNum; 00355 *status = res.fStatus; 00356 } 00357 00358 void JackSocketClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result) 00359 { 00360 JackInternalClientUnloadRequest req(refnum, int_ref); 00361 JackInternalClientUnloadResult res; 00362 ServerSyncCall(&req, &res, result); 00363 *status = res.fStatus; 00364 } 00365 00366 bool JackSocketClientChannel::Init() 00367 { 00368 jack_log("JackSocketClientChannel::Init"); 00369 fNotificationSocket = fNotificationListenSocket.Accept(); 00370 // No more needed 00371 fNotificationListenSocket.Close(); 00372 00373 if (!fNotificationSocket) { 00374 jack_error("JackSocketClientChannel: cannot establish notication socket"); 00375 return false; 00376 } else { 00377 return true; 00378 } 00379 } 00380 00381 bool JackSocketClientChannel::Execute() 00382 { 00383 JackClientNotification event; 00384 JackResult res; 00385 00386 if (event.Read(fNotificationSocket) < 0) { 00387 fNotificationSocket->Close(); 00388 jack_error("JackSocketClientChannel read fail"); 00389 goto error; 00390 } 00391 00392 res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); 00393 00394 if (event.fSync) { 00395 if (res.Write(fNotificationSocket) < 0) { 00396 fNotificationSocket->Close(); 00397 jack_error("JackSocketClientChannel write fail"); 00398 goto error; 00399 } 00400 } 00401 return true; 00402 00403 error: 00404 fClient->ShutDown(); 00405 return false; 00406 } 00407 00408 } // end of namespace 00409 00410 00411 00412 00413