Jack2 1.9.7
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);
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 

Generated for Jack2 by doxygen 1.7.4