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 {
00030     fThread = JackGlobals::MakeThread(this);
00031     fNotificationSocket = NULL;
00032     fClient = NULL;
00033 }
00034 
00035 JackSocketClientChannel::~JackSocketClientChannel()
00036 {
00037     delete fThread;
00038     delete fNotificationSocket;
00039 }
00040 
00041 int JackSocketClientChannel::ServerCheck(const char* server_name)
00042 {
00043         JackLog("JackSocketClientChannel::ServerCheck = %s\n", server_name);
00044                 
00045     // Connect to server
00046     if (fRequestSocket.Connect(jack_server_dir, server_name, 0) < 0) {
00047                 jack_error("Cannot connect to server socket");
00048                 fRequestSocket.Close();
00049         return -1;
00050     } else {
00051                 return 0;
00052         }
00053 }
00054 
00055 int JackSocketClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
00056 {
00057         int result = 0;
00058     JackLog("JackSocketClientChannel::Open name = %s\n", name);
00059 
00060     if (fRequestSocket.Connect(jack_server_dir, server_name, 0) < 0) {
00061         jack_error("Cannot connect to server socket");
00062         goto error;
00063     }
00064         
00065         // Check name in server
00066         ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
00067     if (result < 0) {
00068         int status1 = *status;
00069         if (status1 & JackVersionError)
00070                         jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
00071         else
00072                         jack_error("Client name = %s conflits with another running client", name);
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     JackLog("JackSocketClientChannel::Start\n");
00101     if (fThread->Start() != 0) {
00102         jack_error("Cannot start Jack client listener");
00103         return -1;
00104     } else {
00105         return 0;
00106     }
00107 }
00108 
00109 void JackSocketClientChannel::Stop()
00110 {
00111     JackLog("JackSocketClientChannel::Stop\n");
00112     fThread->Kill();
00113 }
00114 
00115 void JackSocketClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, int* result)
00116 {
00117     if (req->Write(&fRequestSocket) < 0) {
00118         jack_error("Could not write request type = %ld", req->fType);
00119         *result = -1;
00120         return ;
00121     }
00122 
00123     if (res->Read(&fRequestSocket) < 0) {
00124         jack_error("Could not read result type = %ld", req->fType);
00125         *result = -1;
00126         return ;
00127     }
00128 
00129     *result = res->fResult;
00130 }
00131 
00132 void JackSocketClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result)
00133 {
00134     if (req->Write(&fRequestSocket) < 0) {
00135         jack_error("Could not write request type = %ld", req->fType);
00136         *result = -1;
00137     } else {
00138         *result = 0;
00139     }
00140 }
00141 
00142 void JackSocketClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result)
00143 {
00144         JackClientCheckRequest req(name, protocol, options);
00145     JackClientCheckResult res;
00146     ServerSyncCall(&req, &res, result);
00147         *status = res.fStatus;
00148         strcpy(name_res, res.fName);
00149 }
00150 
00151 void JackSocketClientChannel::ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00152 {
00153     JackClientOpenRequest req(name);
00154     JackClientOpenResult res;
00155     ServerSyncCall(&req, &res, result);
00156     *shared_engine = res.fSharedEngine;
00157     *shared_client = res.fSharedClient;
00158     *shared_graph = res.fSharedGraph;
00159 }
00160 
00161 void JackSocketClientChannel::ClientClose(int refnum, int* result)
00162 {
00163     JackClientCloseRequest req(refnum);
00164     JackResult res;
00165     ServerAsyncCall(&req, &res, result);
00166 }
00167 
00168 void JackSocketClientChannel::ClientActivate(int refnum, int* result)
00169 {
00170     JackActivateRequest req(refnum);
00171     JackResult res;
00172     ServerSyncCall(&req, &res, result);
00173 }
00174 
00175 void JackSocketClientChannel::ClientDeactivate(int refnum, int* result)
00176 {
00177     JackDeactivateRequest req(refnum);
00178     JackResult res;
00179     ServerSyncCall(&req, &res, result);
00180 }
00181 
00182 void JackSocketClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, unsigned int* port_index, int* result)
00183 {
00184     JackPortRegisterRequest req(refnum, name, type, flags, buffer_size);
00185     JackPortRegisterResult res;
00186     ServerSyncCall(&req, &res, result);
00187     *port_index = res.fPortIndex;
00188 }
00189 
00190 void JackSocketClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
00191 {
00192     JackPortUnRegisterRequest req(refnum, port_index);
00193     JackResult res;
00194     ServerSyncCall(&req, &res, result);
00195 }
00196 
00197 void JackSocketClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
00198 {
00199     JackPortConnectNameRequest req(refnum, src, dst);
00200     JackResult res;
00201     ServerSyncCall(&req, &res, result);
00202 }
00203 
00204 void JackSocketClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
00205 {
00206     JackPortDisconnectNameRequest req(refnum, src, dst);
00207     JackResult res;
00208     ServerSyncCall(&req, &res, result);
00209 }
00210 
00211 void JackSocketClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00212 {
00213     JackPortConnectRequest req(refnum, src, dst);
00214     JackResult res;
00215     ServerSyncCall(&req, &res, result);
00216 }
00217 
00218 void JackSocketClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00219 {
00220     JackPortDisconnectRequest req(refnum, src, dst);
00221     JackResult res;
00222     ServerSyncCall(&req, &res, result);
00223 }
00224 
00225 void JackSocketClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
00226 {
00227     JackSetBufferSizeRequest req(buffer_size);
00228     JackResult res;
00229     ServerSyncCall(&req, &res, result);
00230 }
00231 
00232 void JackSocketClientChannel::SetFreewheel(int onoff, int* result)
00233 {
00234     JackSetFreeWheelRequest req(onoff);
00235     JackResult res;
00236     ServerSyncCall(&req, &res, result);
00237 }
00238 
00239 void JackSocketClientChannel::ReleaseTimebase(int refnum, int* result)
00240 {
00241     JackReleaseTimebaseRequest req(refnum);
00242     JackResult res;
00243     ServerSyncCall(&req, &res, result);
00244 }
00245 
00246 void JackSocketClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
00247 {
00248     JackSetTimebaseCallbackRequest req(refnum, conditional);
00249     JackResult res;
00250     ServerSyncCall(&req, &res, result);
00251 }
00252 
00253 void JackSocketClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
00254 {
00255     JackGetInternalClientNameRequest req(refnum, int_ref);
00256     JackGetInternalClientNameResult res;
00257     ServerSyncCall(&req, &res, result);
00258         strcpy(name_res, res.fName);
00259 }
00260 
00261 void JackSocketClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
00262 {
00263     JackInternalClientHandleRequest req(refnum, client_name);
00264     JackInternalClientHandleResult res;
00265     ServerSyncCall(&req, &res, result);
00266         *int_ref = res.fIntRefNum;
00267         *status = res.fStatus;
00268 }
00269 
00270 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)
00271 {
00272     JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options);
00273     JackInternalClientLoadResult res;
00274     ServerSyncCall(&req, &res, result);
00275         *int_ref = res.fIntRefNum;
00276         *status = res.fStatus;
00277 }
00278 
00279 void JackSocketClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
00280 {
00281     JackInternalClientUnloadRequest req(refnum, int_ref);
00282     JackInternalClientUnloadResult res;
00283     ServerSyncCall(&req, &res, result);
00284         *status = res.fStatus;
00285 }
00286 
00287 bool JackSocketClientChannel::Init()
00288 {
00289     JackLog("JackSocketClientChannel::Init \n");
00290     fNotificationSocket = fNotificationListenSocket.Accept();
00291     // No more needed
00292     fNotificationListenSocket.Close();
00293 
00294     if (!fNotificationSocket) {
00295         jack_error("JackSocketClientChannel: cannot establish notication socket");
00296         return false;
00297     } else {
00298         return true;
00299     }
00300 }
00301 
00302 bool JackSocketClientChannel::Execute()
00303 {
00304     JackClientNotification event;
00305     JackResult res;
00306 
00307     if (event.Read(fNotificationSocket) < 0) {
00308         fNotificationSocket->Close();
00309         jack_error("JackSocketClientChannel read fail");
00310         goto error;
00311     }
00312 
00313     res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fValue1, event.fValue2);
00314 
00315     if (event.fSync) {
00316         if (res.Write(fNotificationSocket) < 0) {
00317             fNotificationSocket->Close();
00318             jack_error("JackSocketClientChannel write fail");
00319             goto error;
00320         }
00321     }
00322     return true;
00323 
00324 error:
00325     fClient->ShutDown();
00326     return false;
00327 }
00328 
00329 } // end of namespace
00330 
00331 
00332 
00333 
00334 

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1