Jack2 1.9.6
|
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