Main Page   Compound List   File List   Header Files   Sources   Compound Members   File Members  

pcomm.cpp

00001 /*
00002    Copyright (C) 1999 PolyWog and Javaman for Ghetto.Org
00003    This file is part of the PCR-1000 API Library.
00004 
00005    The PCR-1000 API Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public License as
00007    published by the Free Software Foundation; either version 2 of the
00008    License, or (at your option) any later version.
00009 
00010    The PCR-1000 API Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with the PCR-1000 API Library; see the file LICENSE.  If not,
00017    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019  */
00020 
00021 #if defined (SunOS) || defined (Irix)
00022 #include <strings.h>
00023 #else if defined (BSD) || defined (Linux)
00024 #include <string.h>     /* bzero(), strcpy(), strcpy() etc... */
00025 #endif
00026 #include <assert.h> /* assert() */
00027 #include "pcomm.h"
00028 
00029 PComm :: PComm (char *pcrDev, tcflag_t baudRate, const char *name)
00030 {
00031     if (name==NULL) {
00032         strcpy(int_name, "PComm_Obj");
00033     } else {
00034         strcpy(int_name, name);
00035     }
00036 
00037     callCount=0;
00038     bzero(pcrDevice, sizeof(pcrDevice));
00039     strncpy(pcrDevice, pcrDev, sizeof(pcrDevice)-1);
00040     pcrSpeed = baudRate;
00041 
00042     if (!PCOpen(pcrDev, baudRate))
00043         { exit(-1); }
00044 
00045 }
00062 PComm :: ~PComm ()
00063 {
00064         PCClose();
00065 
00066 #ifdef DEBUG_VER_
00067     fprintf(stderr, "%s: Destroyed\n", int_name);
00068 #endif // DEBUG_VER_ //
00069 }
00079 bool PComm :: PCOpen(const char *pcrDev, tcflag_t baudRate)
00080 {
00081 
00082     /* Open modem device for reading and writing and not as controlling tty
00083        because we don't want to get killed if linenoise sends CTRL-C.  */
00084     fd = open(pcrDev, O_RDWR | O_NOCTTY );
00085     if (fd <0) {
00086                 perror(pcrDev); 
00087                 return false; 
00088 #ifdef DEBUG_VER_
00089         } else {
00090                 fprintf(stderr, "PCOMM: PCOpen(%s, %ld): Success at %d\n", 
00091                         pcrDev, baudRate, fd);
00092 #endif // DEBUG_VER_
00093         }       
00094         
00095 
00096     oldtio      = new termios;
00097     newtio      = new termios;
00098 
00099 
00100         // functions necessary to initialise socket sets for
00101         // use with the select() function(s).
00102         timeOut = new timeval;
00103         FDSet   = new fd_set;
00104         // clear out that memory.
00105         bzero(timeOut, sizeof(struct timeval));
00106         bzero(FDSet, sizeof(fd_set));
00107         // remove any socket descriptors if necessary
00108         // and add socket 'fd' to the FDSet
00109         FD_ZERO(FDSet);
00110         FD_SET(fd, FDSet);
00111         // set default timeout values to five seconds
00112         timeOut->tv_sec  = 5;
00113         timeOut->tv_usec = 0;
00114         // now we should be ready to use the select() statement.
00115         // just make sure that if the socket `fd' is closed
00116         // to repopulate the fd_set and to call select with
00117         // fd+1 as the first arg
00118 
00119     tcgetattr(fd,oldtio); /* save current serial port settings */
00120     bzero(newtio, sizeof(struct termios));
00121 
00122     /*
00123        BAUDRATE: Set bps rate. use cfsetispeed and cfsetospeed.
00124        CLOCAL  : local connection, no modem contol
00125        CREAD   : enable receiving characters
00126        ~HUPCL  : dont reset DTR to low when program finishes
00127        ~PARENB : dont enable parity bits
00128        ~CSTOPB : no stop bits
00129        ~CSIZE  :
00130        CS8     : 8n1 (8bit,no parity,1 stopbit)
00131      */
00132     cfsetispeed( newtio, baudRate );
00133     cfsetospeed( newtio, baudRate );
00134     newtio->c_cflag |=  (CLOCAL | CREAD);
00135     newtio->c_cflag &= ~HUPCL ;
00136     newtio->c_cflag &= ~PARENB ;
00137     newtio->c_cflag &= ~CSTOPB ;
00138     newtio->c_cflag &= ~CSIZE;
00139     newtio->c_cflag |= CS8;
00140 
00141     /* ICANON  : enable canonical input disable all echo functionality,
00142                  and don't send signals to calling program */
00143     newtio->c_lflag |= ICANON;
00144     newtio->c_lflag &= ~(ECHO | ECHOCTL);
00145 
00146     /* Raw output.  */
00147     newtio->c_oflag &= ~OPOST;
00148 
00149     /* now clean the modem line and activate the settings for the port */
00150     /* tcflush(fd, TCIFLUSH); */
00151     tcsetattr(fd,TCSANOW,newtio);
00152 
00153     return true;
00154 }
00173 void PComm :: PCClose()
00174 {
00175     close(fd);
00176 
00177     /* restore the old port settings */
00178     tcsetattr(fd,TCSANOW,oldtio);
00179     delete oldtio;
00180     delete newtio;
00181 
00182     FD_ZERO(FDSet);
00183     delete FDSet;
00184     delete timeOut;   
00185 
00186 }
00194 size_pc PComm :: PCTell(char *mesg)
00195 {
00196     #ifdef DEBUG_VER_
00197     fprintf(stderr, "Tell: %s\n", mesg);
00198     #endif /* DEBUG_VER_ */
00199 
00200     return (Write(mesg));
00201 }
00217 size_pc PComm :: PCAsk(char *mesg)
00218 {
00219     #ifdef DEBUG_VER_2
00220     fprintf(stderr, "Ask: %s\n", mesg);
00221     assert(mesg!=0);
00222     assert(strlen(mesg)==2);
00223     #endif /* DEBUG_VER_ */
00224 
00225     bzero(askBuf, sizeof(askBuf));
00226     strcpy(askBuf, mesg);
00227     strcat(askBuf, PCRQST);
00228 
00229     return (Write(askBuf)-1);
00230 }
00251 size_pc PComm :: PCHear(char *mesg)
00252 {
00253     char *cut;
00254 
00255     #ifdef DEBUG_VER_2
00256     assert(mesg != 0);
00257     fprintf(stderr, "PComm: PCHEAR \n");
00258     #endif /* DEBUG_VER_ */
00259 
00260     hearCtr=0;
00261     bzero(hearBuf, sizeof(hearBuf));
00262     bzero(mesg, sizeof(mesg));
00263 
00264     hearCtr = Read(hearBuf);
00265     cut=strpbrk(hearBuf, PCRECMD);
00266     if (cut!=NULL) { 
00267         *cut=0; 
00268         hearCtr -= 2;
00269     }
00270         
00271     strcpy(mesg, hearBuf); 
00272     
00273     #ifdef DEBUG_VER_2
00274     fprintf(stderr, "Hear: %s\n", mesg);
00275     #endif /* DEBUG_VER_ */
00276 
00277         if (errRead) {
00278                 return (-1);
00279         } else { 
00280                 return (hearCtr);
00281         }
00282 
00283 }
00304 size_pc PComm :: PCRawWrite(char *mesg)
00305 {
00306 
00307     bzero(writeBuf, sizeof(writeBuf));
00308     strcpy(writeBuf, mesg);
00309 
00310     if (select(fd+1, NULL, FDSet, NULL, timeOut)) {
00311         writeCtr = write(fd, writeBuf, strlen(writeBuf));
00312     } else {
00313 #ifdef DEBUG_VER_
00314             fprintf(stderr, "PCRawWrite Time Out on socket %d\n", fd);
00315 #endif // DEBUG_VER_ 
00316         writeCtr = 0;
00317     }
00318 
00319     if ((unsigned)writeCtr!=strlen(writeBuf)) {
00320         return (-1);
00321     }
00322 
00323     return writeCtr;
00324    
00325 }
00337 size_pc PComm :: PCRawRead(char *mesg)
00338 {
00339     readCtr = 1;
00340 
00341     bzero(readBuf, sizeof(readBuf));
00342     bzero(readBuf, sizeof(mesg));
00343 
00344     while(readCtr==1) {
00345         if (select(fd+1, FDSet, NULL, NULL, timeOut)) {
00346                 readCtr= read(fd, readBuf, sizeof(readBuf));
00347                 strcpy(mesg, readBuf);
00348         } else {
00349                 readCtr=(-1);
00350 #ifdef DEBUG_VER_
00351             fprintf(stderr, "PCRawRead Time Out on socket %d\n", fd);
00352 #endif // DEBUG_VER_ 
00353 
00354         }
00355     }
00356 
00357     return readCtr;
00358 }
00370 size_pc PComm :: Write(char *submesg)
00371 {
00372     int __writeCtr;
00373 
00374     bzero(writeBuf, sizeof(writeBuf));
00375     strcpy(writeBuf, submesg);
00376     strcat(writeBuf, PCRECMD);
00377 
00378     #ifdef DEBUG_VER_2
00379     fprintf(stderr, "Write Attempt: %s\n", writeBuf);
00380     #endif /* DEBUG_VER_ */
00381 
00382     if (select(fd+1, NULL, FDSet, NULL, timeOut)) {
00383                 __writeCtr=write(fd, writeBuf, strlen(writeBuf));
00384     } else {
00385 #ifdef DEBUG_VER_
00386             fprintf(stderr, "Write() Time Out on socket %d\n", fd);
00387 #endif // DEBUG_VER_ 
00388             __writeCtr=0;
00389     }
00390 
00391     return (__writeCtr-2);
00392 }
00416 size_pc PComm :: Read(char *submesg)
00417 {
00418     readCtr=1;
00419     int loopBreaker=0;
00420 
00421 #ifdef DEBUG_VER_2
00422     assert(submesg!=0);
00423     fprintf(stderr, "PComm: READ");
00424 #endif /* DEBUG_VER_ */
00425 
00426     bzero(readBuf, sizeof(readBuf));
00427     bzero(submesg, sizeof(submesg));
00428 
00429     while((readCtr==1) && (loopBreaker<10)) {
00430         if (select(fd+1, FDSet, NULL, NULL, timeOut)) {
00431                 readCtr=read(fd, readBuf, sizeof(readBuf));
00432                 // call Count keeps track of the number of
00433                 // read()/writes() to the serial object
00434                     countCall();
00435                 loopBreaker++;
00436         } else {
00437 #ifdef DEBUG_VER_
00438                 fprintf(stderr, "Read() Time Out on socket %d\n", fd);
00439 #endif // DEBUG_VER_ //
00440                     readCtr=1;
00441                 errRead=true;
00442                 loopBreaker++;
00443         }
00444     }
00445 
00446     /* 
00447        Was there an error reading? ie: after five
00448        loops, did we still read in new lines (in other
00449        words, did the radio have nothing to tell us?)
00450        Then we should have never been called, and set
00451        errRead appropriately.
00452      */
00453     (readCtr==1)?(errRead=true):(errRead=false);
00454 
00455     strcpy(submesg, readBuf);
00456 
00457     #ifdef DEBUG_VER_2
00458     fprintf(stderr, "\nRead: %i -  %s\n", readCtr, submesg);
00459     #endif /* DEBUG_VER_ */
00460 
00461     return readCtr;
00462 
00463 }
00496 void PComm :: resetCall()
00497 {
00498 #ifdef DEBUG_VER_2
00499         fprintf(stderr, "PCOMM: resetCall() @ %d \n", callCount);
00500 #endif DEBUG_VER_2
00501         callCount=0;
00502         int __readCounter=0;
00503         int __loopbreaker=0;
00504         
00505         PCClose();
00506         PCOpen(pcrDevice, pcrSpeed);
00507         bzero(callBuf, sizeof(callBuf));
00508         strncpy(callBuf, PCRPWRON, sizeof(callBuf)-1);
00509         strncat(callBuf, PCRECMD,  ((sizeof(callBuf))-(strlen(callBuf))-1));
00510         if (select(fd+1, NULL, FDSet, NULL, timeOut)) {
00511         write(fd, callBuf, strlen(callBuf));
00512             if (select(fd+1, NULL, FDSet, NULL, timeOut)) {
00513                 bzero(callBuf, sizeof(callBuf));
00514                 while ((__readCounter==1) && (__loopbreaker<10)) {
00515                     __readCounter = read(fd, callBuf, sizeof(callBuf));
00516                     __loopbreaker++;
00517                 }
00518 #ifdef DEBUG_VER_
00519             } else {
00520                // we should never have gotten here, if so, we are fubar'd
00521                // and should abort the program
00522                 fprintf(stderr, "Read failed in PCOMM: resetCall()");
00523                 fprintf(stderr, "***UNRECOVERABLE ERROR***");
00524                 abort();
00525 #endif // DEBUG_VER_
00526             }
00527 #ifdef DEBUG_VER_
00528         } else {
00529             // we should never have gotten here, if so, we are fubar'd
00530             // and should abort the program
00531                 fprintf(stderr, "Write failed in PCOMM: resetCall()");
00532         fprintf(stderr, "***UNRECOVERABLE ERROR***");
00533         abort();
00534 #endif // DEBUG_VER_
00535         }
00536 }
00564 void PComm :: countCall()
00565 {
00566         if (callCount<200) {
00567                 callCount++;
00568         } else {
00569                 resetCall();
00570         }
00571 
00572 #ifdef DEBUG_VER_2
00573         fprintf(stderr, "PCOMM: countCall() %d\n", callCount);
00574 #endif // DEBUG_VER_
00575 }       

Generated at Mon Jan 17 00:45:27 2000 for Icom PCR-1000 Library by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999