Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ArRobotPacketReceiver.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArDeviceConnection.h"
00029 #include "ArRobotPacketReceiver.h"
00030 #include "ArLogFileConnection.h"
00031 #include "ArLog.h"
00032 #include "ariaUtil.h"
00033 
00034 
00045 AREXPORT ArRobotPacketReceiver::ArRobotPacketReceiver(bool allocatePackets,
00046                               unsigned char sync1,
00047                               unsigned char sync2) : 
00048   myPacket(sync1, sync2)
00049 {
00050   myAllocatePackets = allocatePackets;
00051   myDeviceConn = NULL;
00052   mySync1 = sync1;
00053   mySync2 = sync2;
00054 }
00055 
00067 AREXPORT ArRobotPacketReceiver::ArRobotPacketReceiver(
00068     ArDeviceConnection *deviceConnection, bool allocatePackets,
00069     unsigned char sync1, unsigned char sync2) :
00070   myPacket(sync1, sync2)
00071 {
00072   myDeviceConn = deviceConnection;
00073   myAllocatePackets = allocatePackets;
00074   mySync1 = sync1;
00075   mySync2 = sync2;
00076 }
00077 
00078 AREXPORT ArRobotPacketReceiver::~ArRobotPacketReceiver() 
00079 {
00080   
00081 }
00082 
00083 AREXPORT void ArRobotPacketReceiver::setDeviceConnection(
00084     ArDeviceConnection *deviceConnection)
00085 {
00086   myDeviceConn = deviceConnection;
00087 }
00088 
00089 AREXPORT ArDeviceConnection *ArRobotPacketReceiver::getDeviceConnection(void)
00090 {
00091   return myDeviceConn;
00092 }
00093 
00103 AREXPORT ArRobotPacket *ArRobotPacketReceiver::receivePacket(
00104     unsigned int msWait)
00105 {
00106   ArRobotPacket *packet;
00107   unsigned char c;
00108   char buf[256];
00109   int count = 0;
00110   // state can be one of the STATE_ enums in the class
00111   int state = STATE_SYNC1;
00112   //unsigned int timeDone;
00113   //unsigned int curTime;
00114   long timeToRunFor;
00115   ArTime timeDone;
00116   ArTime lastDataRead;
00117   ArTime packetReceived;
00118   int numRead;
00119 
00120   if (myAllocatePackets)
00121     packet = new ArRobotPacket(mySync1, mySync2);
00122   else
00123     packet = &myPacket;
00124 
00125   if (packet == NULL || myDeviceConn == NULL || 
00126       myDeviceConn->getStatus() != ArDeviceConnection::STATUS_OPEN)
00127   {
00128     if (myAllocatePackets)
00129       delete packet;
00130     return NULL;
00131   }
00132   
00133   timeDone.setToNow();
00134   timeDone.addMSec(msWait);
00135 
00136   // check for log file connection, return assembled packet
00137   if (dynamic_cast<ArLogFileConnection *>(myDeviceConn))
00138   {
00139     packet->empty();
00140     packet->setLength(0);
00141     packetReceived = myDeviceConn->getTimeRead(0);
00142     packet->setTimeReceived(packetReceived);
00143     numRead = myDeviceConn->read(buf, 255, 0);
00144     if (numRead > 0)
00145     {
00146       packet->dataToBuf(buf, numRead);
00147       packet->resetRead();
00148       return packet;
00149     }
00150     else
00151     {
00152       if (myAllocatePackets)
00153     delete packet;
00154       return NULL;
00155     }
00156   }      
00157   
00158 
00159   do
00160     {
00161       timeToRunFor = timeDone.mSecTo();
00162       if (timeToRunFor < 0)
00163         timeToRunFor = 0;
00164 
00165       if (myDeviceConn->read((char *)&c, 1, timeToRunFor) == 0) 
00166         {
00167           if (state == STATE_SYNC1)
00168             {
00169               if (myAllocatePackets)
00170                 delete packet;
00171               return NULL;
00172             }
00173           else
00174             {
00175               //ArUtil::sleep(1);
00176               continue;
00177             }
00178         }
00179 
00180       switch (state) {
00181       case STATE_SYNC1:
00182         if (c == mySync1) // move on, resetting packet
00183           {
00184             state = STATE_SYNC2;
00185             packet->empty();
00186             packet->setLength(0);
00187             packet->uByteToBuf(c);
00188             packetReceived = myDeviceConn->getTimeRead(0);
00189             packet->setTimeReceived(packetReceived);
00190           }
00191         else
00192     {
00193           //printf("Bad sync1 %d\n", c);
00194     }
00195         break;
00196       case STATE_SYNC2:
00197         if (c == mySync2) // move on, adding this byte
00198           {
00199             state = STATE_ACQUIRE_DATA;
00200             packet->uByteToBuf(c);
00201           }
00202         else // go back to beginning, packet hosed
00203           {
00204         //printf("Bad sync2 %d\n", c);
00205             state = STATE_SYNC1;
00206           }
00207         break;
00208       case STATE_ACQUIRE_DATA:
00209         // the character c is the count of the packets remianing at this point
00210         // so we'll just put it into the packet then get the rest of the data
00211         packet->uByteToBuf(c);
00212         // if c > 200 than there is a problem, spec says packet max size is 200
00213         count = 0;
00222         // here we read until we get as much as we want, OR until
00223         // we go 100 ms without data... its arbitrary but it doesn't happen often
00224         // and it'll mean a bad packet anyways
00225         lastDataRead.setToNow();
00226         while (count < c)
00227           {
00228             numRead = myDeviceConn->read(buf + count, c - count, 1);
00229             if (numRead > 0)
00230               lastDataRead.setToNow();
00231             if (lastDataRead.mSecTo() < -100)
00232               {
00233                 if (myAllocatePackets)
00234                   delete packet;
00235         //printf("Bad time taken reading\n");
00236                 return NULL;
00237               }
00238             count += numRead;
00239           }
00240         packet->dataToBuf(buf, c);
00241         if (packet->verifyCheckSum()) 
00242           {
00243             packet->resetRead();
00244         /* put this in if you want to see the packets received
00245            printf("Input ");
00246                packet->printHex();
00247            */
00248         // you can also do this next line if you only care about type
00249         //printf("Input %x\n", packet->getID());
00250             return packet;
00251           }
00252         else 
00253           {
00254         /* put this in if you want to see bad checksum packets 
00255                printf("Bad Input ");
00256                packet->printHex();
00257            */
00258             ArLog::log(ArLog::Normal, 
00259                        "ArRobotPacketReceiver::receivePacket: bad packet, bad checksum");
00260             state = STATE_SYNC1;
00261             break;
00262           }
00263         break;
00264       default:
00265         break;
00266       }
00267     } while (timeDone.mSecTo() >= 0 || state != STATE_SYNC1);
00268 
00269   //printf("finished the loop...\n");
00270   if (myAllocatePackets)
00271     delete packet;
00272   return NULL;
00273 
00274 }
00275 
00276 

Generated on Tue Feb 20 10:51:41 2007 for Aria by  doxygen 1.4.0