CommManager.cpp
Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <string.h>
00003 #include <errno.h>
00004 
00005 #include "canon_vbc50i/libCanon/XString.h"
00006 #include "canon_vbc50i/libCanon/CommManager.h"
00007 #include "canon_vbc50i/libCanon/login.h"
00008 
00009 
00010 CommManager::CommManager(const char * initseq_filename)
00011 {
00012         sock = NULL;
00013         verbose = 1;
00014         in_thread = 0;
00015         terminate = false;
00016         pthread_mutex_init(&sockmtx,NULL);
00017         Q.setVerboseLevel(1);
00018 
00019         Datagram dgm;
00020         bool loginFromFile = false;
00021         FILE * fp = NULL;
00022         if (initseq_filename) {
00023                 fp = fopen(initseq_filename,"r");
00024                 if (fp == NULL) {
00025                         fprintf(stderr,"CommManager: Could not open '%s'\n",initseq_filename);
00026                 } else {
00027                         loginFromFile = true;
00028                 }
00029         }
00030         if (loginFromFile) {
00031                 while (1) {
00032                         if (!dgm.read(fp)) break;
00033                         //printf("F Telegram %d: id %d\n",init_seq.size(),dgm.getId());
00034                         init_seq.push_back(dgm);
00035                 }
00036                 fclose(fp);
00037         } else {
00038                 printf("Using builtin login sequence\n");
00039                 RawBinDatagram * bdgm = raw_bin_login;
00040                 while (bdgm->len != 0) {
00041                         if (!dgm.read(bdgm->data,bdgm->len)) break;
00042                         //printf("M Telegram %d: id %d\n",init_seq.size(),dgm.getId());
00043                         init_seq.push_back(dgm);
00044                         bdgm ++;
00045                 }
00046         }
00047 #ifdef CM_CARE_FOR_REPLY
00048         init_reply.resize(init_seq.size());
00049 #endif
00050 }       
00051 
00052 CommManager::~CommManager()
00053 {
00054         close();
00055 }
00056 
00057 void * commmanager_inthread(void * arg) 
00058 {
00059         CommManager * cm = (CommManager*)arg;
00060         cm->run();
00061         return NULL;
00062 }
00063 
00064 bool CommManager::sendInitSeq()
00065 {
00066         unsigned int i;
00067         Datagram dgm;
00068         for (i=0;i<init_seq.size();i++) {
00069                 if (!send(init_seq[i])) {
00070                         printf("%s: Can't send datagram %d:",__FUNCTION__,i);
00071                         init_seq[i].write(stdout);
00072                         printf("\n");
00073                         goto cleanup;
00074                 }
00075                 if (!sock->WaitData((i==0)?1000:100)) {
00076                         printf("No answer for datagram %d\n",i);
00077                         goto cleanup;
00078                 }
00079                 if (!dgm.receive(sock)) {
00080                         printf("Error receiving answer for datagram %d\n",i);
00081                         goto cleanup;
00082                 }
00083                 if (verbose > 1) {
00084                         printf("Received: ");dgm.print(stdout);
00085                 }
00086 #ifdef CM_CARE_FOR_REPLY
00087                 init_reply[i] = dgm;
00088 #endif
00089         }
00090 
00091         printf("CM: Initialization completed\n");
00092         return true;
00093 cleanup:
00094         printf("CM: Initialization failed\n");
00095         return false;
00096 }
00097 
00098 
00099 bool CommManager::open(const char * hostname, unsigned int port)
00100 {
00101         int r;
00102         if (sock != NULL) delete sock;
00103         sock = new Socket(hostname,port);
00104         if (verbose) 
00105                 sock->showErrors(); 
00106         else 
00107                 sock->hideErrors();
00108         if (!sock->Open()) goto clean_exit;
00109         if (!sendInitSeq()) goto clean_exit;
00110         
00111         terminate = false;
00112         r = pthread_create(&in_thread,NULL,commmanager_inthread,this);
00113         if (r != 0) throw XString("Failed to start CommManager thread: ") + strerror(errno);
00114 
00115         return true;
00116 
00117 
00118 clean_exit:
00119         delete sock;
00120         sock = NULL;
00121         return false;
00122 } 
00123 
00124 void CommManager::setVerboseLevel(unsigned int v) {
00125         verbose=v;
00126         if (sock != NULL) {
00127                 if (verbose) 
00128                         sock->showErrors(); 
00129                 else 
00130                         sock->hideErrors();
00131         }
00132         Q.setVerboseLevel(verbose);
00133         if (verbose > 1)
00134                 printf("CommManager: Setting verbose level to %d\n",verbose);
00135 }
00136 
00137 bool CommManager::reconnect()
00138 {
00139         if (sock == NULL) {
00140                 return false;
00141         }
00142         // setVerboseLevel(2);
00143         if (verbose > 0)
00144                 printf("CM: reconnecting\n");
00145         sock->Close();
00146         bool ret = sock->Open();;
00147         
00148         if (ret) ret = sendInitSeq();
00149         return ret;
00150 }
00151 
00152 bool CommManager::close()
00153 {
00154         terminate = true;
00155         if (in_thread != 0) {
00156                 pthread_join(in_thread,NULL);
00157                 in_thread = 0;
00158         }
00159         if (sock != NULL) {
00160                 sock->Close();
00161                 delete sock;
00162         }
00163         sock = NULL;
00164         return true;
00165 }
00166 
00167 void CommManager::run()
00168 {
00169         if (verbose>1) 
00170                 printf("T %08X CommManager::run()\n",(int)pthread_self());
00171         Datagram dgm;
00172         if (sock == NULL) return;
00173         if (!sock->IsOpen()) return;
00174         while (!terminate) {
00175                 if (!sock->IsOpen()) {
00176                         usleep(10000);
00177                         continue;
00178                 }
00179                 if (sock->IsBroken()) {
00180                         reconnect();
00181                 }
00182 #if 0
00183                 printf("T %08X CommManager::run()\n",(int)pthread_self());
00184                 struct timespec ts;
00185                 clock_gettime(CLOCK_REALTIME, &ts);
00186                 printf("Current time is %d.%d\n",(int)ts.tv_sec,(int)ts.tv_nsec);
00187 #endif
00188                 if (!sock->WaitData(100)) {
00189                         usleep(10000);
00190                         continue;
00191                 }
00192                 if (!dgm.receive(sock,100,(verbose>1))) {
00193                         usleep(10000);
00194                         continue;
00195                 }
00196                 if (verbose > 1) {
00197                         printf("Received: ");dgm.print(stdout);
00198                 }
00199                 Q.storeDgm(dgm);
00200         }
00201         if (verbose>1) 
00202                 printf("CommManager::run exiting\n");
00203 }
00204 
00205 bool CommManager::send(Datagram & dgm)
00206 {
00207         if (sock == NULL) return false;
00208         if (!sock->IsOpen()) return false;
00209         if (sock->IsBroken()) { /* run will take care of that */return false; }
00210         //printf("Locking sock mtx\n");
00211         pthread_mutex_lock(&sockmtx);
00212         //printf("-- Locked sock mtx\n");
00213         bool res = dgm.send(sock);
00214         if (verbose > 1) {
00215                 printf("Sent    : ");dgm.print(stdout);
00216         }
00217         pthread_mutex_unlock(&sockmtx);
00218         return res;
00219 }
00220 
00221 bool CommManager::addToReceptionField(unsigned char id)
00222 {
00223         Q.addInteresting(id);
00224         return true;
00225 }
00226 
00227 bool CommManager::removeFromReceptionField(unsigned char id)
00228 {
00229         Q.remInteresting(id);
00230         return true;
00231 }
00232 
00233 bool CommManager::resetReceptionField()
00234 {
00235         Q.resetInteresting();
00236         return true;
00237 }
00238 
00239 bool CommManager::wait(unsigned char id, Datagram & dgm, double timeout)
00240 {
00241         return Q.waitDgm(id,dgm,timeout);
00242         //return Q.waitDgm(id,dgm,-1);
00243 }
00244 
00245 
00246 
00247 
00248 


canon_vbc50i
Author(s): Cedric Pradalier
autogenerated on Mon Jan 6 2014 11:18:27