00001
00002
00027 #include <stdio.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include "packet.h"
00031 #include <unistd.h>
00032 #include <sys/select.h>
00033 #include <sys/time.h>
00034 #include <stdlib.h>
00035
00036
00037 #include "erratic.h"
00038
00039 void ErraticPacket::Print() {
00040 if (packet) {
00041 printf("\"");
00042 for(int i=0;i<size;i++) {
00043 printf("%u ", packet[i]);
00044 }
00045 puts("\"");
00046 }
00047 }
00048
00049 void ErraticPacket::PrintHex() {
00050 if (packet) {
00051 printf("\"Hex: ");
00052 for(int i=0;i<size;i++) {
00053 printf("%.2x ", packet[i]);
00054 }
00055 puts("\"");
00056 }
00057 }
00058
00059
00060 bool ErraticPacket::Check() {
00061 uint16_t chksum = CalcChkSum();
00062 uint16_t received_chksum = packet[size-2] << 8 | packet[size-1];
00063
00064 if ( chksum == received_chksum )
00065 {
00066 if (debug_mode)
00067 {
00068 printf("Good packet: ");
00069 PrintHex();
00070 }
00071 return(true);
00072 }
00073
00074 if (debug_mode) {
00075 printf("This packet failed checksum control (%i instead of %i): ", received_chksum, chksum);
00076 PrintHex();
00077 }
00078
00079 return(false);
00080 }
00081
00082 uint16_t ErraticPacket::CalcChkSum() {
00083 uint8_t *buffer = &packet[3];
00084 uint16_t n = size - 5;
00085 uint16_t c = 0;
00086
00087 while (n > 1) {
00088 c+= (*(buffer)<<8) | *(buffer+1);
00089 n -= 2;
00090 buffer += 2;
00091 }
00092 if (n > 0) c = c ^ (uint16_t)*buffer;
00093
00094 return(c);
00095 }
00096
00097
00098 int ErraticPacket::Receive( int fd, uint16_t wait ) {
00099 uint8_t prefix[3];
00100 uint32_t skipped;
00101 uint16_t cnt;
00102
00103 if (debug_mode)
00104 printf("Check for packets in Receive()\n");
00105
00106 memset(packet,0,sizeof(packet));
00107 struct pollfd readpoll;
00108 readpoll.fd = fd;
00109 readpoll.events = POLLIN | POLLPRI;
00110 readpoll.revents = 0;
00111
00112 #ifdef USE_SELECT
00113 fd_set read_set, error_set;
00114 struct timeval tv;
00115 FD_ZERO(&read_set);
00116 FD_ZERO(&error_set);
00117 FD_SET(fd, &read_set);
00118 FD_SET(fd, &error_set);
00119 tv.tv_sec = 0;
00120 tv.tv_usec = 0;
00121 if (wait >= 1000)
00122 tv.tv_sec = wait/1000;
00123 else
00124 tv.tv_usec = wait*1000;
00125 #endif
00126
00127
00128 if (wait) {
00129 while (1) {
00130 #ifdef USE_SELECT
00131 int ret = select(fd+1, &read_set, 0, &error_set, &tv);
00132 if (ret)
00133 {
00134 if (debug_mode)
00135 printf("Data waiting\n");
00136 break;
00137 }
00138 else
00139 if (debug_mode)
00140 printf("No data\n");
00141 #endif
00142
00143 int8_t stuff = poll(&readpoll, 1, wait);
00144
00145 if (stuff < 0) {
00146 if (errno == EINTR) {
00147 continue;
00148 }
00149 return 1;
00150 }
00151
00152 if (stuff == 0) {
00153 return (receive_result_e)timeout;
00154 }
00155
00156 if (readpoll.revents & POLLIN)
00157 break;
00158
00159 printf("Serial port error\n");
00160 return (receive_result_e)failure;
00161 }
00162 }
00163
00164 do {
00165 memset(prefix,0,sizeof(prefix));
00166
00167 skipped = 0;
00168 while(1) {
00169 cnt = 0;
00170
00171
00172
00173 while( cnt!=1 ) {
00174 if (wait) {
00175 while (1) {
00176
00177 #ifdef USE_SELECT
00178 FD_ZERO(&read_set);
00179 FD_ZERO(&error_set);
00180 FD_SET(fd, &read_set);
00181 FD_SET(fd, &error_set);
00182 tv.tv_sec = 0;
00183 tv.tv_usec = 100*1000;
00184
00185 int ret = select(fd+1, &read_set, 0, &error_set, &tv);
00186 if (ret)
00187 break;
00188 #endif
00189
00190 int8_t stuff = poll(&readpoll, 1, 100);
00191
00192 if (stuff < 0) {
00193 if (errno == EINTR) {
00194 continue;
00195 }
00196 return 1;
00197 }
00198
00199 if (stuff == 0) {
00200 return (receive_result_e)timeout;
00201 }
00202
00203 if (readpoll.revents & POLLIN)
00204 break;
00205
00206 printf("Serial port error\n");
00207 return (receive_result_e)failure;
00208 }
00209 }
00210
00211
00212 int newcnt = read( fd, &prefix[2], 1 );
00213 if (debug_mode)
00214 printf("Read %d byte: %02x\n", newcnt, prefix[2]);
00215
00216 if (newcnt < 0 && errno == EAGAIN)
00217 continue;
00218 else if (newcnt < 0) {
00219 perror("Erratic::Receive:read:");
00220 return(1);
00221 }
00222
00223 cnt++;
00224 }
00225
00226 if (prefix[0]==0xFA && prefix[1]==0xFB) break;
00227
00228 prefix[0]=prefix[1];
00229 prefix[1]=prefix[2];
00230 skipped++;
00231
00232 if (skipped > 200) return (receive_result_e)timeout;
00233 }
00234 if (skipped>2 && debug_mode) printf("Skipped %d bytes\n", skipped);
00235
00236 size = prefix[2]+3;
00237 memcpy( packet, prefix, 3);
00238
00239 cnt = 0;
00240 while( cnt!=prefix[2] )
00241 {
00242 if (wait) {
00243 while (1) {
00244 #ifdef USE_SELECT
00245 FD_ZERO(&read_set);
00246 FD_ZERO(&error_set);
00247 FD_SET(fd, &read_set);
00248 FD_SET(fd, &error_set);
00249 tv.tv_sec = 0;
00250 tv.tv_usec = 100*1000;
00251
00252 int ret = select(fd+1, &read_set, 0, &error_set, &tv);
00253 if (ret)
00254 break;
00255 #endif
00256
00257 int8_t stuff = poll(&readpoll, 1, 100);
00258
00259 if (stuff < 0) {
00260 if (errno == EINTR) {
00261 continue;
00262 }
00263 return 1;
00264 }
00265
00266 if (stuff == 0) {
00267 return (receive_result_e)timeout;
00268 }
00269
00270 if (readpoll.revents & POLLIN)
00271 break;
00272
00273 printf("Serial port error\n");
00274 return (receive_result_e)failure;
00275 }
00276 }
00277
00278 int newcnt = read( fd, &packet[3+cnt], prefix[2]-cnt );
00279 if (debug_mode)
00280 {
00281 printf("Read %d bytes packet\n", newcnt);
00282 if (newcnt > 0)
00283 {
00284 for (int i=0; i<newcnt; i++)
00285 printf("%02x ", packet[3+i]);
00286 printf("\n");
00287 }
00288 }
00289
00290 if (newcnt < 0 && errno == EAGAIN)
00291 continue;
00292 else if (newcnt < 0) {
00293 perror("Erratic::Receive:read:");
00294 return(1);
00295 }
00296
00297 cnt += newcnt;
00298 }
00299 } while (!Check());
00300 return(0);
00301 }
00302
00303
00304 int ErraticPacket::Build( unsigned char *data, unsigned char datasize ) {
00305 uint16_t chksum;
00306
00307 size = datasize + 5;
00308
00309
00310 packet[0]=0xFA;
00311 packet[1]=0xFB;
00312
00313 if ( size > 198 ) {
00314 printf("Erratic driver error: Packet to robot can't be larger than 200 bytes");
00315 return(1);
00316 }
00317 packet[2] = datasize + 2;
00318
00319 memcpy( &packet[3], data, datasize );
00320
00321 chksum = CalcChkSum();
00322
00323 packet[3+datasize] = chksum >> 8;
00324 packet[3+datasize+1] = chksum;
00325
00326
00327
00328
00329
00330
00331
00332
00333 return(0);
00334 }
00335
00336 int ErraticPacket::Send( int fd) {
00337 int cnt=0;
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 while(cnt!=size)
00348 {
00349 if((cnt += write( fd, packet+cnt, size-cnt )) < 0)
00350 {
00351 perror("Send");
00352 return(1);
00353 }
00354 }
00355 return(0);
00356 }