JackDebugClient.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 General Public License as published by
00006 the Free Software Foundation; either version 2 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 General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #include "JackDebugClient.h"
00021 #include "JackError.h"
00022 #include <iostream>
00023 #include <iomanip>
00024 #include <sstream>
00025 #include <fstream>
00026 #include <string>
00027 #include <time.h>
00028 
00029 using namespace std;
00030 
00031 namespace Jack
00032 {
00033 
00034 JackDebugClient::JackDebugClient(JackClient * client)
00035 {
00036     fTotalPortNumber = 1;       // The total number of port opened and maybe closed. Historical view.
00037     fOpenPortNumber = 0;        // The current number of opened port.
00038     fIsActivated = 0;
00039     fIsDeactivated = 0;
00040     fIsClosed = 0;
00041     fClient = client;
00042 }
00043 
00044 JackDebugClient::~JackDebugClient()
00045 {
00046     fTotalPortNumber--; // fTotalPortNumber start at 1
00047     *fStream << endl << endl << "----------------------------------- JackDebugClient summary ------------------------------- " << endl << endl;
00048     *fStream << "Client flags ( 1:yes / 0:no ) :" << endl;
00049     *fStream << setw(5) << "- Client call activated : " << fIsActivated << endl;
00050     *fStream << setw(5) << "- Client call deactivated : " << fIsDeactivated << endl;
00051     *fStream << setw(5) << "- Client call closed : " << fIsClosed << endl;
00052     *fStream << setw(5) << "- Total number of instantiated port : " << fTotalPortNumber << endl;
00053     *fStream << setw(5) << "- Number of port remaining open when exiting client : " << fOpenPortNumber << endl;
00054     if (fOpenPortNumber != 0)
00055         *fStream << "!!! WARNING !!! Some ports have not been unregistrated ! Incorrect exiting !" << endl;
00056     if (fIsDeactivated != fIsActivated)
00057         *fStream << "!!! ERROR !!! Client seem do not perform symetric activation-deactivation ! (not the same number of activate and deactivate)" << endl;
00058     if (fIsClosed == 0)
00059         *fStream << "!!! ERROR !!! Client have not been closed with jack_client_close() !" << endl;
00060 
00061     *fStream << endl << endl << "---------------------------- JackDebugClient detailed port summary ------------------------ " << endl << endl;
00062     //for (int i = 0; i < fTotalPortNumber ; i++) {
00063     for (int i = 1; i <= fTotalPortNumber ; i++) {
00064         *fStream << endl << "Port index (internal debug test value) : " << i << endl;
00065         *fStream << setw(5) << "- Name : " << fPortList[i].name << endl;
00066         *fStream << setw(5) << "- idport : " << fPortList[i].idport << endl;
00067         *fStream << setw(5) << "- IsConnected : " << fPortList[i].IsConnected << endl;
00068         *fStream << setw(5) << "- IsUnregistrated : " << fPortList[i].IsUnregistrated << endl;
00069         if (fPortList[i].IsUnregistrated == 0)
00070             *fStream << "!!! WARNING !!! Port have not been unregistrated ! Incorrect exiting !" << endl;
00071     }
00072     *fStream << "delete object JackDebugClient : end of tracing" << endl;
00073     delete fStream;
00074     delete fClient;
00075 }
00076 
00077 int JackDebugClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00078 {
00079     int res = fClient->Open(server_name, name, options, status);
00080     char provstr[256];
00081     char buffer[256];
00082     time_t curtime;
00083     struct tm *loctime;
00084     /* Get the current time. */
00085     curtime = time (NULL);
00086     /* Convert it to local time representation. */
00087     loctime = localtime (&curtime);
00088     strftime (buffer, 256, "%I-%M", loctime);
00089     sprintf(provstr, "JackClientDebug-%s-%s.log", name, buffer);
00090     fStream = new ofstream(provstr, ios_base::ate);
00091     if (fStream->is_open()) {
00092         if (res == -1) {
00093             *fStream << "Trying to open client with name '" << name << "' with bad result (client not opened)." << res << endl;
00094         } else {
00095             *fStream << "Open client with name '" << name << "'." << endl;
00096         }
00097     } else {
00098         JackLog("JackDebugClient::Open : cannot open log file\n");
00099     }
00100     strcpy(fClientName, name);
00101     return res;
00102 }
00103 
00104 int JackDebugClient::Close()
00105 {
00106     fIsClosed++;
00107     *fStream << "Client '" << fClientName << "' was closed" << endl;
00108     return fClient->Close();
00109 }
00110 
00111 void JackDebugClient::CheckClient() const
00112 {
00113     if (fIsClosed > 0)  {
00114                 *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed !" << endl;
00115                 *fStream << "This is likely to cause crash !'" << endl;
00116         }
00117 }
00118 
00119 pthread_t JackDebugClient::GetThreadID()
00120 {
00121         CheckClient();
00122     return fClient->GetThreadID();
00123 }
00124 
00125 JackGraphManager* JackDebugClient::GetGraphManager() const
00126 {
00127         CheckClient();
00128     return fClient->GetGraphManager();
00129 }
00130 JackEngineControl* JackDebugClient::GetEngineControl() const
00131 {
00132         CheckClient();
00133     return fClient->GetEngineControl();
00134 }
00139 int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2)
00140 {
00141         CheckClient();
00142     return fClient->ClientNotify( refnum, name, notify, sync, value1, value2);
00143 }
00144 
00145 int JackDebugClient::Activate()
00146 {
00147         CheckClient();
00148     int res = fClient->Activate();
00149     fIsActivated++;
00150     if (fIsDeactivated)
00151         *fStream << "Client '" << fClientName << "' call activate a new time (it already call 'activate' previously)." << endl;
00152     *fStream << "Client '" << fClientName << "' Activated" << endl;
00153     if (res != 0)
00154         *fStream << "Client '" << fClientName << "' try to activate but server return " << res << " ." << endl;
00155     return res;
00156 }
00157 
00158 int JackDebugClient::Deactivate()
00159 {
00160         CheckClient();
00161     int res = fClient->Deactivate();
00162     fIsDeactivated++;
00163     if (fIsActivated == 0)
00164         *fStream << "Client '" << fClientName << "' deactivate while it hasn't been previoulsy activated !" << endl;
00165     *fStream << "Client '" << fClientName << "' Deactivated" << endl;
00166     if (res != 0)
00167         *fStream << "Client '" << fClientName << "' try to deactivate but server return " << res << " ." << endl;
00168     return res;
00169 }
00170 
00171 //-----------------
00172 // Port management
00173 //-----------------
00174 
00175 int JackDebugClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
00176 {
00177         CheckClient();
00178     int res = fClient->PortRegister(port_name, port_type, flags, buffer_size);
00179     if (res <= 0) {
00180         *fStream << "Client '" << fClientName << "' try port register ('" << port_name << "') and server return error  " << res << " ." << endl;
00181     } else {
00182         if (fTotalPortNumber < MAX_PORT_HISTORY) {
00183             fPortList[fTotalPortNumber].idport = res;
00184             strcpy(fPortList[fTotalPortNumber].name, port_name);
00185             fPortList[fTotalPortNumber].IsConnected = 0;
00186             fPortList[fTotalPortNumber].IsUnregistrated = 0;
00187         } else {
00188             *fStream << "!!! WARNING !!! History is full : no more port history will be recorded." << endl;
00189         }
00190         fTotalPortNumber++;
00191         fOpenPortNumber++;
00192         *fStream << "Client '" << fClientName << "' port register with portname '" << port_name << " port " << res << "' ." << endl;
00193     }
00194     return res;
00195 }
00196 
00197 int JackDebugClient::PortUnRegister(jack_port_id_t port_index)
00198 {
00199         CheckClient();
00200     int res = fClient->PortUnRegister(port_index);
00201     fOpenPortNumber--;
00202     int i;
00203     for (i = (fTotalPortNumber - 1); i >= 0; i--) {     // We search the record into the history
00204         if (fPortList[i].idport == port_index) {                // We found the last record
00205             if (fPortList[i].IsUnregistrated != 0)
00206                 *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl;
00207             fPortList[i].IsUnregistrated++;
00208             break;
00209         }
00210     }
00211     if (i == 0) // Port is not found
00212         *fStream << "JackClientDebug : PortUnregister : port " << port_index << " was not previously registered !" << endl;
00213     if (res != 0)
00214         *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << " )." << endl;
00215     *fStream << "Client '" << fClientName << "' unregister port '" << port_index << "'." << endl;
00216     return res;
00217 }
00218 
00219 int JackDebugClient::PortConnect(const char* src, const char* dst)
00220 {
00221         CheckClient();
00222     if (!fIsActivated)
00223         *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
00224     int i;
00225     int res = fClient->PortConnect( src, dst);
00226     for (i = (fTotalPortNumber - 1); i >= 0; i--) {     // We search the record into the history
00227         if (strcmp(fPortList[i].name, src) == 0) {      // We found the last record in sources
00228             if (fPortList[i].IsUnregistrated != 0)
00229                 *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl;
00230             fPortList[i].IsConnected++;
00231             *fStream << "Connecting port " << src << " to " << dst << ". ";
00232             break;
00233         } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest
00234             if (fPortList[i].IsUnregistrated != 0)
00235                 *fStream << "!!! ERROR !!! Connecting port  " << dst << " previoulsy unregistered !" << endl;
00236             fPortList[i].IsConnected++;
00237             *fStream << "Connecting port " << src << " to " << dst << ". ";
00238             break;
00239         }
00240     }
00241     if (i == 0) // Port is not found
00242         *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl;
00243     if (res != 0)
00244         *fStream << "Client '" << fClientName << "' try to do PortConnect but server return " << res << " ." << endl;
00245     //*fStream << "Client Port Connect done with names" << endl;
00246     return res;
00247 }
00248 
00249 int JackDebugClient::PortDisconnect(const char* src, const char* dst)
00250 {
00251         CheckClient();
00252     if (!fIsActivated)
00253         *fStream << "!!! ERROR !!! Trying to disconnect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl;
00254     int res = fClient->PortDisconnect( src, dst);
00255     int i;
00256     for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history
00257         if (strcmp(fPortList[i].name, src) == 0) { // We found the record in sources
00258             if (fPortList[i].IsUnregistrated != 0)
00259                 *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl;
00260             fPortList[i].IsConnected--;
00261             *fStream << "disconnecting port " << src << ". ";
00262             break;
00263         } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest
00264             if (fPortList[i].IsUnregistrated != 0)
00265                 *fStream << "!!! ERROR !!! : Disonnecting port  " << dst << " previoulsy unregistered !" << endl;
00266             fPortList[i].IsConnected--;
00267             *fStream << "disconnecting port " << dst << ". ";
00268             break;
00269         }
00270     }
00271     if (i == 0) // Port is not found
00272         *fStream << "JackClientDebug : PortDisConnect : port was not found in debug database !" << endl;
00273     if (res != 0)
00274         *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl;
00275     //*fStream << "Client Port Disconnect done." << endl;
00276     return res;
00277 }
00278 
00279 int JackDebugClient::PortConnect(jack_port_id_t src, jack_port_id_t dst)
00280 {       
00281         CheckClient();
00282     if (!fIsActivated)
00283         *fStream << "!!! ERROR !!! : Trying to connect port  " << src << " to  " << dst << " while the client has not been activated !" << endl;
00284     int res = fClient->PortConnect(src, dst);
00285     int i;
00286     for (i = (fTotalPortNumber - 1); i >= 0; i--) {     // We search the record into the history
00287         if (fPortList[i].idport == src) {               // We found the record in sources
00288             if (fPortList[i].IsUnregistrated != 0)
00289                 *fStream << "!!! ERROR !!! : Connecting port  " << src << " previoulsy unregistered !" << endl;
00290             fPortList[i].IsConnected++;
00291             *fStream << "Connecting port " << src << ". ";
00292             break;
00293         } else if (fPortList[i].idport == dst) { // We found the record in dest
00294             if (fPortList[i].IsUnregistrated != 0)
00295                 *fStream << "!!! ERROR !!! : Connecting port  " << dst << " previoulsy unregistered !" << endl;
00296             fPortList[i].IsConnected++;
00297             *fStream << "Connecting port " << dst << ". ";
00298             break;
00299         }
00300     }
00301     if (i == 0) // Port is not found
00302         *fStream << "JackClientDebug : PortConnect : port was not found in debug database !" << endl;
00303     if (res == -1)
00304         *fStream << "Client '" << fClientName << "' try to do Portconnect but server return " << res << " ." << endl;
00305     //*fStream << "Client Port Connect with ID done." << endl;
00306     return res;
00307 }
00308 
00309 int JackDebugClient::PortDisconnect(jack_port_id_t src)
00310 {
00311         CheckClient();
00312     if (!fIsActivated)
00313         *fStream << "!!! ERROR !!! : Trying to disconnect port  " << src << " while that client has not been activated !" << endl;
00314     int res = fClient->PortDisconnect(src);
00315     int i;
00316     for (i = (fTotalPortNumber - 1); i >= 0; i--) {             // We search the record into the history
00317         if (fPortList[i].idport == src) {                               // We found the record in sources
00318             if (fPortList[i].IsUnregistrated != 0)
00319                 *fStream << "!!! ERROR !!! : Disconnecting port  " << src << " previoulsy unregistered !" << endl;
00320             fPortList[i].IsConnected--;
00321             *fStream << "Disconnecting port " << src << ". " << endl;
00322             break;
00323         }
00324     }
00325     if (i == 0) // Port is not found
00326         *fStream << "JackClientDebug : PortDisconnect : port was not found in debug database !" << endl;
00327     if (res != 0)
00328         *fStream << "Client '" << fClientName << "' try to do PortDisconnect but server return " << res << " ." << endl;
00329     //*fStream << "Client Port Disconnect with ID done." << endl;
00330     return res;
00331 }
00332 
00333 int JackDebugClient::PortIsMine(jack_port_id_t port_index)
00334 {
00335         CheckClient();
00336     return fClient->PortIsMine(port_index);
00337 }
00338 
00339 //--------------------
00340 // Context management
00341 //--------------------
00342 
00343 int JackDebugClient::SetBufferSize(jack_nframes_t buffer_size)
00344 {
00345         CheckClient();
00346     return fClient->SetBufferSize(buffer_size);
00347 }
00348 
00349 int JackDebugClient::SetFreeWheel(int onoff)
00350 {
00351         CheckClient();
00352     return fClient->SetFreeWheel(onoff);
00353 }
00354 
00355 /*
00356 ShutDown is called:
00357 - from the RT thread when Execute method fails
00358 - possibly from a "closed" notification channel
00359 (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown))
00360 */
00361 
00362 void JackDebugClient::ShutDown()
00363 {
00364     fClient->ShutDown();
00365 }
00366 
00367 //---------------------
00368 // Transport management
00369 //---------------------
00370 
00371 int JackDebugClient::ReleaseTimebase()
00372 {
00373         CheckClient();
00374     return fClient->ReleaseTimebase();
00375 }
00376 
00377 int JackDebugClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg)
00378 {
00379         CheckClient();
00380     return fClient->SetSyncCallback(sync_callback, arg);
00381 }
00382 
00383 int JackDebugClient::SetSyncTimeout(jack_time_t timeout)
00384 {
00385         CheckClient();
00386     return fClient->SetSyncTimeout(timeout);
00387 }
00388 
00389 int JackDebugClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg)
00390 {
00391         CheckClient();
00392     return fClient->SetTimebaseCallback( conditional, timebase_callback, arg);
00393 }
00394 
00395 int JackDebugClient::TransportLocate(jack_nframes_t frame)
00396 {
00397         CheckClient();
00398     return fClient->TransportLocate(frame);
00399 }
00400 
00401 jack_transport_state_t JackDebugClient::TransportQuery(jack_position_t* pos)
00402 {
00403         CheckClient();
00404     return fClient->TransportQuery(pos);
00405 }
00406 
00407 jack_nframes_t JackDebugClient::GetCurrentTransportFrame()
00408 {
00409         CheckClient();
00410     return fClient->GetCurrentTransportFrame();
00411 }
00412 
00413 int JackDebugClient::TransportReposition(jack_position_t* pos)
00414 {
00415         CheckClient();
00416     return fClient->TransportReposition(pos);
00417 }
00418 
00419 void JackDebugClient::TransportStart()
00420 {
00421         CheckClient();
00422     fClient->TransportStart();
00423 }
00424 
00425 void JackDebugClient::TransportStop()
00426 {
00427         CheckClient();
00428     fClient->TransportStop();
00429 }
00430 
00431 //---------------------
00432 // Callback management
00433 //---------------------
00434 
00435 void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg)
00436 {
00437         CheckClient();
00438     fClient->OnShutdown(callback, arg);
00439 }
00440 
00441 int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg)
00442 {
00443         CheckClient();
00444     return fClient->SetProcessCallback(callback, arg);
00445 }
00446 
00447 int JackDebugClient::SetXRunCallback(JackXRunCallback callback, void *arg)
00448 {
00449         CheckClient();
00450     return fClient->SetXRunCallback(callback, arg);
00451 }
00452 
00453 int JackDebugClient::SetInitCallback(JackThreadInitCallback callback, void *arg)
00454 {
00455         CheckClient();
00456     return fClient->SetInitCallback(callback, arg);
00457 }
00458 
00459 int JackDebugClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg)
00460 {
00461         CheckClient();
00462     return fClient->SetGraphOrderCallback(callback, arg);
00463 }
00464 
00465 int JackDebugClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg)
00466 {
00467         CheckClient();
00468     return fClient->SetBufferSizeCallback(callback, arg);
00469 }
00470 
00471 int JackDebugClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg)
00472 {
00473         CheckClient();
00474     return fClient->SetClientRegistrationCallback(callback, arg);
00475 }
00476 
00477 int JackDebugClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg)
00478 {
00479         CheckClient();
00480     return fClient->SetFreewheelCallback(callback, arg);
00481 }
00482 
00483 int JackDebugClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg)
00484 {
00485         CheckClient();
00486     return fClient->SetPortRegistrationCallback(callback, arg);
00487 }
00488 
00489 int JackDebugClient::SetPortConnectCallback(JackPortConnectCallback callback, void *arg)
00490 {
00491         CheckClient();
00492     return fClient->SetPortConnectCallback(callback, arg);
00493 }
00494 
00495 JackClientControl* JackDebugClient::GetClientControl() const
00496 {
00497         CheckClient();
00498     return fClient->GetClientControl();
00499 }
00500 
00501 // Internal clients
00502 char* JackDebugClient::GetInternalClientName(int ref)
00503 {
00504         CheckClient();
00505     return fClient->GetInternalClientName(ref);
00506 }
00507 
00508 int JackDebugClient::InternalClientHandle(const char* client_name, jack_status_t* status)
00509 {
00510         CheckClient();
00511     return fClient->InternalClientHandle(client_name, status);
00512 }
00513 
00514 int JackDebugClient::InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va)
00515 {
00516         CheckClient();
00517     return fClient->InternalClientLoad(client_name, options, status, va);
00518 }
00519 
00520 void JackDebugClient::InternalClientUnload(int ref, jack_status_t* status)
00521 {
00522         CheckClient();
00523     fClient->InternalClientUnload(ref, status);
00524 }
00525                 
00526 jack_nframes_t JackDebugClient::Wait(int status)
00527 {
00528         CheckClient();
00529     return fClient->Wait(status);
00530 }
00531 
00532 } // end of namespace
00533 

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