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