Jack2 1.9.8

JackSocketClientChannel.cpp

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