packet.cc

00001 /*
00002  *  Player - One Hell of a Robot Server
00003  *  Copyright (C) 2000  
00004  *     Brian Gerkey, Kasper Stoy, Richard Vaughan, & Andrew Howard
00005  *                      
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  */
00022 
00023 /*
00024  * $Id: packet.cc 4356 2008-02-15 08:53:55Z thjc $
00025  *   part of the P2OS parser.  this class has methods for building,
00026  *   printing, sending and receiving P2OS packets.
00027  *
00028  */
00029 
00030 #include <stdio.h>
00031 #include <errno.h>
00032 #include <string.h>
00033 #include <packet.h>
00034 #include <unistd.h>
00035 #include <stdlib.h> /* for exit() */
00036 
00037 void P2OSPacket::Print() {
00038   if (packet) {
00039     printf("\"");
00040     for(int i=0;i<size;i++) {
00041       printf("%u ", packet[i]);
00042     }
00043     puts("\"");
00044   }
00045 }
00046 
00047 void P2OSPacket::PrintHex() {
00048   if (packet) {
00049     printf("\"");
00050     for(int i=0;i<size;i++) {
00051       printf("0x%.2x ", packet[i]);
00052     }
00053     puts("\"");
00054   }
00055 }
00056 
00057 
00058 bool P2OSPacket::Check() {
00059   short chksum;
00060   chksum = CalcChkSum();
00061 
00062   if ( chksum == packet[size-2] << 8 | packet[size-1]) 
00063     return(true);
00064 
00065 
00066   return(false);
00067 }
00068 
00069 int P2OSPacket::CalcChkSum() {
00070   unsigned char *buffer = &packet[3];
00071   int c = 0;
00072   int n;
00073 
00074   n = size - 5;
00075 
00076   while (n > 1) {
00077     c+= (*(buffer)<<8) | *(buffer+1);
00078     c = c & 0xffff;
00079     n -= 2;
00080     buffer += 2;
00081   }
00082   if (n>0) c = c^ (int)*(buffer++);
00083   
00084   return(c);
00085 }
00086 
00087 int P2OSPacket::Receive( int fd ) 
00088 {
00089   unsigned char prefix[3];
00090   //int skipped=0;
00091   int cnt;
00092 
00093   memset(packet,0,sizeof(packet));
00094 
00095   do 
00096   {
00097     memset(prefix,0,sizeof(prefix));
00098     //memset( prefix, 0, 3);
00099 
00100     while(1) 
00101     {
00102       cnt = 0;
00103       while( cnt!=1 ) 
00104       {
00105         if ( (cnt+=read( fd, &prefix[2], 1 )) < 0 ) 
00106         {
00107           perror("Error reading packet header from robot connection: P2OSPacket():Receive():read():");
00108           return(1);
00109         }
00110       }
00111 
00112       if (prefix[0]==0xFA && prefix[1]==0xFB) break;
00113       
00114       GlobalTime->GetTimeDouble(&timestamp);
00115       
00116       prefix[0]=prefix[1];
00117       prefix[1]=prefix[2];
00118       //skipped++;
00119     }
00120     //if (skipped>3) printf("Skipped %d bytes\n", skipped);
00121     
00122     size = prefix[2]+3;
00123     memcpy( packet, prefix, 3);
00124 
00125     cnt = 0;
00126     while( cnt!=prefix[2] ) 
00127     {
00128       if ( (cnt+=read( fd, &packet[3+cnt],  prefix[2]-cnt )) < 0 ) 
00129       {
00130         perror("Error reading packet body from robot connection: P2OSPacket():Receive():read():");
00131         return(1);
00132       }  
00133     }
00134   } while (!Check());  
00135   return(0);
00136 }
00137 
00138 int P2OSPacket::Build( unsigned char *data, unsigned char datasize ) {
00139   short chksum;
00140 
00141   size = datasize + 5;
00142 
00143   /* header */
00144   packet[0]=0xFA;
00145   packet[1]=0xFB;
00146   
00147   if ( size > 198 ) {
00148     puts("Packet to P2OS can't be larger than 200 bytes");
00149     return(1);
00150   }
00151   packet[2] = datasize + 2;
00152 
00153   memcpy( &packet[3], data, datasize );
00154   
00155   chksum = CalcChkSum();
00156   packet[3+datasize] = chksum >> 8;
00157   packet[3+datasize+1] = chksum & 0xFF;
00158 
00159   if (!Check()) {
00160     puts("DAMN");
00161     return(1);
00162   }
00163   return(0);
00164 }
00165 
00166 int P2OSPacket::Send( int fd) 
00167 {
00168   int cnt=0;
00169   
00170   //printf("Send(): ");
00171   //PrintHex();
00172   while(cnt!=size)
00173   {
00174     if((cnt += write( fd, packet, size )) < 0) 
00175     {
00176       perror("Send");
00177       return(1);
00178     }
00179   }
00180   return(0);
00181 }

Last updated 12 September 2005 21:38:45