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

ArRobotPacketReceiver.cpp

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

Generated on Wed Oct 19 12:56:36 2005 for Aria by  doxygen 1.4.0