Jack2 1.9.6

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, 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, 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 
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, char* name_res, int protocol, int options, int* status, int* result)
00146 {
00147     JackClientCheckRequest req(name, protocol, options);
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* shared_engine, int* shared_client, int* shared_graph, int* result)
00155 {
00156     JackClientOpenRequest req(name, pid);
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::ReleaseTimebase(int refnum, int* result)
00250 {
00251     JackReleaseTimebaseRequest req(refnum);
00252     JackResult res;
00253     ServerSyncCall(&req, &res, result);
00254 }
00255 
00256 void JackSocketClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
00257 {
00258     JackSetTimebaseCallbackRequest req(refnum, conditional);
00259     JackResult res;
00260     ServerSyncCall(&req, &res, result);
00261 }
00262 
00263 void JackSocketClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
00264 {
00265     JackGetInternalClientNameRequest req(refnum, int_ref);
00266     JackGetInternalClientNameResult res;
00267     ServerSyncCall(&req, &res, result);
00268     strcpy(name_res, res.fName);
00269 }
00270 
00271 void JackSocketClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
00272 {
00273     JackInternalClientHandleRequest req(refnum, client_name);
00274     JackInternalClientHandleResult res;
00275     ServerSyncCall(&req, &res, result);
00276     *int_ref = res.fIntRefNum;
00277     *status = res.fStatus;
00278 }
00279 
00280 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* result)
00281 {
00282     JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options);
00283     JackInternalClientLoadResult res;
00284     ServerSyncCall(&req, &res, result);
00285     *int_ref = res.fIntRefNum;
00286     *status = res.fStatus;
00287 }
00288 
00289 void JackSocketClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
00290 {
00291     JackInternalClientUnloadRequest req(refnum, int_ref);
00292     JackInternalClientUnloadResult res;
00293     ServerSyncCall(&req, &res, result);
00294     *status = res.fStatus;
00295 }
00296 
00297 bool JackSocketClientChannel::Init()
00298 {
00299     jack_log("JackSocketClientChannel::Init");
00300     fNotificationSocket = fNotificationListenSocket.Accept();
00301     // No more needed
00302     fNotificationListenSocket.Close();
00303 
00304     if (!fNotificationSocket) {
00305         jack_error("JackSocketClientChannel: cannot establish notication socket");
00306         return false;
00307     } else {
00308         return fClient->Init();
00309     }
00310 }
00311 
00312 bool JackSocketClientChannel::Execute()
00313 {
00314     JackClientNotification event;
00315     JackResult res;
00316 
00317     if (event.Read(fNotificationSocket) < 0) {
00318         fNotificationSocket->Close();
00319         jack_error("JackSocketClientChannel read fail");
00320         goto error;
00321     }
00322 
00323     res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2);
00324 
00325     if (event.fSync) {
00326         if (res.Write(fNotificationSocket) < 0) {
00327             fNotificationSocket->Close();
00328             jack_error("JackSocketClientChannel write fail");
00329             goto error;
00330         }
00331     }
00332     return true;
00333 
00334 error:
00335     fClient->ShutDown();
00336     return false;
00337 }
00338 
00339 } // end of namespace
00340 
00341 
00342 
00343 
00344