Changeset 842
- Timestamp:
- 09/15/07 08:10:48 (14 months ago)
- Files:
-
- 1 modified
-
trunk/plugin_gps.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/plugin_gps.c
r841 r842 40 40 * -added support for gps device with 9600 baud (env. variable) 41 41 * -added the option that the widget graps data from the buffer and not from the gps device (usefull for multible widgets) 42 * v0.3 -improved nmea parsing 43 * -improved gps-emulator 44 * -time is now updated with rmc and gga sentence 42 45 * 43 46 * TODO: … … 71 74 * each widget will get updates and cause some ugly side effects, specially when you display the time 72 75 * by enabling this option, the widget will not read any nmea data from the serial port. 73 * KEEP IN MIND that there must be ONE widget which does NOT get buffered data (means read data from the port) 76 * KEEP IN MIND that there must be ONE widget which get buffered data (means read data from the port) 77 * 78 * #define SHOW_NMEA_STATUS 0x010000000 OK:0033/Error:0002/Incomplete:0002 79 * 74 80 * 75 81 * Examples: … … 109 115 110 116 #define EMULATE //remove comment to enable gps data emulation... 111 #define EMU_BUFFER_READ_SIZE 32 //how many bytes are read each loop aka emulation speed 117 #define EMU_BUFFER_READ_SIZE 128 //how many bytes are read each loop aka emulation speed 118 #define BUFFER_SIZE 256 112 119 113 120 #define SHOW_ALTITUDE 0x000000001 … … 128 135 //KEEP IN MIND that there must be ONE widget which does not get buffered data (means read data from the port) 129 136 #define OPTION_DEBUG 0x000010000 130 137 #define SHOW_NMEA_STATUS 0x010000000 131 138 132 139 static float course = 0.f; //degrees … … 139 146 static unsigned long gpsDate = 0; //Date in ddmmyy format 140 147 141 static int msgCounter = 0; //debug counter 148 static int msgCounter = 0; //parsed nmea-sentence 149 static int errCounter = 0; //parsed error nmea-sentence 150 static int incomplCounter = 0; //incomplete parsed nmea-sentence 142 151 /* ---------------------------------------------------------------------------------------*/ 143 152 /* STEP 1 : allocate the data structures. be careful if you put them on the stack because */ … … 154 163 155 164 static char Name[] = "plugin_gps.c"; 165 166 static int fndStr = 0; //how many bytes were saved from the last read 167 static char backBuffer[BUFFER_SIZE]; //the buffer to save incomplete nmea strings 168 156 169 157 170 #ifdef EMULATE … … 177 190 "$GPRMC,165117.000,A,5601.0318,N,01211.3505,E,0.08,45.32,190706,,*3F\r\n" 178 191 "$GPGGA,165118.000,5601.0318,N,01211.3505,E,1,07,1.2,23.0,M,41.6,M,,0000*68\r\n" 179 "$GPRMC,165118.000,A,5601.0318,N,01211.3505,E,0.10,37.49,190706,,*30\r\n" 180 "$GPGGA,165119.000,5601.0318,N,01211.3504,E,1,06,1.2,23.0,M,41.6,M,,0000*69\r\n"192 "$GPRMC,165118.000,A,5601.0318,N,01211.3505,E,0.10,37.49,190706,,*30\r\n"*/ 193 "$GPGGA,165119.000,5601.0318,N,01211.3504,E,1,06,1.2,23.0,M,41.6,M,,0000*69\r\n" 181 194 "$GPRMC,165119.000,A,5601.0318,N,01211.3504,E,0.08,27.23,190706,,*34\r\n" 182 195 "$GPGGA,165120.000,5601.0318,N,01211.3504,E,1,07,1.2,23.0,M,41.6,M,,0000*62\r\n" … … 211 224 "$GPRMC,094059.000,A,5409.998934,N,00859.370505,E,0.576,0.00,301206,,,A*53\r\n" 212 225 "$GPGGA,094100.000,5409.999097,N,00859.370542,E,1,12,0.82,-5.177,M,45.414,M,,*4C\r\n" 213 "$GPRMC,094100.000,A,5409.999097,N,00859.370542,E,0.705,0.00,301206,,,A\r\n" */226 "$GPRMC,094100.000,A,5409.999097,N,00859.370542,E,0.705,0.00,301206,,,A\r\n" 214 227 "$GPGGA,004037.851,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A\r\n" 215 228 "$GPGGA,175218.255,4657.3391,N,00726.2666,E,1,04,9.0,568.6,M,48.0,M,0.0,0000*7B\r\n" … … 342 355 satellites = gga->satellites; 343 356 quality = gga->quality; 344 msgCounter++; 345 346 if (debug==1) 347 debug("gps:debug: get gga callout, msg nr: %d\n",msgCounter); 348 349 } 357 gpsTime = gga->time; 358 359 if (debug == 1) 360 debug("gps:debug: get gga callout\n"); 361 362 } 363 364 365 //search a buffer for a string (forwards) 366 int strLastOcc(char *theBuffer, char searchChar, int size) 367 { 368 int i, ret; 369 370 ret = -1; 371 for (i = size; i >= 0; i--) { 372 if (theBuffer[i] == searchChar) { 373 ret = i; 374 break; 375 } 376 } 377 return ret; 378 } 379 380 //search a buffer for a string (backwards) 381 int strFirstOcc(char *theBuffer, char searchChar, int size) 382 { 383 int i, ret; 384 ret = -1; 385 for (i = 0; i < size; i++) { 386 if (theBuffer[i] == searchChar) { 387 ret = i; 388 break; 389 } 390 } 391 return ret; 392 } 393 394 350 395 351 396 /** called when a gprmc message is received and parsed */ … … 359 404 gpsTime = rmc->time; 360 405 gpsDate = rmc->date; 361 msgCounter++; 362 363 if (debug==1) 364 debug("gps:debug: get rmc callout, msg nr: %d\n",msgCounter); 365 406 407 if (debug == 1) 408 debug("gps:debug: get rmc callout\n"); 409 366 410 } 367 411 … … 441 485 long options; 442 486 long dispOptions; 443 #define BUFFER_SIZE 128 487 444 488 char buffer[BUFFER_SIZE]; 489 char bufferTmp[BUFFER_SIZE]; 490 491 int validStart, validEnd; 445 492 446 493 options = R2N(theOptions); 447 494 dispOptions = R2N(displayOptions); 448 495 //error("options: %x\n",options); 449 496 450 497 if (dispOptions & OPTION_DEBUG) 451 debug =1;452 498 debug = 1; 499 453 500 if ((dispOptions & OPTION_GET_BUFFERDATA) == 0) { 454 501 … … 456 503 /* STEP 6 : get a buffer of input */ 457 504 /* --------------------------------------- */ 505 506 memset(buffer, 0, BUFFER_SIZE); 507 if (fndStr > BUFFER_SIZE) 508 fndStr = 0; 509 //copy unfinished nmea strings back 510 if (fndStr > 0) { 511 memcpy(buffer, backBuffer, fndStr); 512 } 458 513 #ifdef EMULATE 514 memcpy(&buffer[fndStr], &test_vector[emu_read_ofs], BUFFER_SIZE - fndStr); 515 459 516 len = rem = EMU_BUFFER_READ_SIZE; 460 517 emu_read_ofs += EMU_BUFFER_READ_SIZE; 461 if (emu_read_ofs > (sizeof(test_vector) -BUFFER_SIZE))518 if (emu_read_ofs > (sizeof(test_vector) - BUFFER_SIZE)) { 462 519 emu_read_ofs = 0; 463 memcpy(buffer, &test_vector[emu_read_ofs], BUFFER_SIZE); 520 memset(buffer, 0, BUFFER_SIZE); 521 } 464 522 #else 465 memset(buffer, 0, sizeof(buffer)); 466 len = rem = read(fd_g, buffer, sizeof(buffer));523 524 len = rem = read(fd_g, buffer, BUFFER_SIZE - fndStr); 467 525 if (len <= 0) { 468 526 error("GPS Plugin, Error read from port, try using the GPS_PORT env variable (export GPS_PORT=/dev/mydev)"); 469 527 //break; 470 528 } 471 if (debug ==1)472 debug("gps:debug: read %d bytes\n", len);473 529 if (debug == 1) 530 debug("gps:debug: read %d bytes\n", len); 531 474 532 #endif 475 533 if (dispOptions & OPTION_RAW_NMEA) … … 479 537 /* STEP 7 : process input until buffer is used up */ 480 538 /* ---------------------------------------------- */ 481 //#ifdef EMULATE 482 // offset = emu_read_ofs; 483 //#else 539 validStart = strFirstOcc(buffer, '$', len); 540 validEnd = strLastOcc(buffer, '\n', len); 541 542 if (validStart >= 0 && validEnd > 0 && validStart < validEnd) { 543 //valid string found 544 memcpy(bufferTmp, buffer, sizeof(buffer)); //save buffer 545 memset(backBuffer, 0, sizeof(backBuffer)); //clear backup buffer 546 memcpy(backBuffer, buffer + validEnd, len - validEnd); // save incomplete nmea string 547 memset(buffer, 0, sizeof(buffer)); //clean buffer 548 memcpy(buffer, bufferTmp + validStart, validEnd - validStart + 1); //copy valid name string 549 fndStr = len - validEnd + validStart; //save the size of the buffer 550 } else { 551 //no valid nmea string found 552 fndStr = 0; 553 memset(buffer, 0, sizeof(buffer)); 554 memset(backBuffer, 0, sizeof(backBuffer)); 555 } 556 484 557 offset = 0; 485 //#endif 486 487 while (rem > 0) { 488 //#ifdef EMULATE 489 // status = nmeap_parseBuffer(&nmea, &test_vector[offset], &rem); 490 //#else 558 if (debug == 1) 559 debug("backBuffer: %s\n", backBuffer); 560 561 //the nmeap_parseBuffer function needs whole nmea strings, combined string will NOT work! 562 validStart = strFirstOcc(buffer, '$', len); 563 validEnd = strFirstOcc(buffer, '\n', len); 564 while (validStart >= 0 && validEnd > 0 && validStart < validEnd) { 565 memset(bufferTmp, 0, sizeof(bufferTmp)); //empty temp buffer 566 memcpy(bufferTmp, buffer + offset + validStart, validEnd - validStart + 1); //fill temp buffer 567 568 if (debug == 1) 569 debug("submit: %s\n", bufferTmp); 570 571 rem = len - offset; 572 status = nmeap_parseBuffer(&nmea, (const char *) &bufferTmp, &rem); //parse it 573 if (status == -1) { 574 errCounter++; 575 error("parser error occured! (cnt: %i)\n", errCounter); 576 } else if (status == 0) { 577 incomplCounter++; 578 } else if (status > 0) 579 msgCounter++; 580 581 offset += validEnd - validStart + 1; //update offset 582 validStart = strFirstOcc(buffer + offset, '$', len - offset); //find next sentence 583 validEnd = strFirstOcc(buffer + offset, '\n', len - offset); 584 } 585 586 587 /* while (rem > 0) { 491 588 status = nmeap_parseBuffer(&nmea, &buffer[offset], &rem); 492 589 debug("\nGPS::debug: remaining: %d bytes\n",rem); 493 //error("loop, remaining=%d, read bytes=%d\n",rem,offset);494 //#endif495 590 offset += (len - rem); 496 } 591 }*/ 497 592 } // end of OPTION get bufferdata 498 593 … … 587 682 } 588 683 589 if (options == 0) { //error, no parameter defined! 684 685 if (dispOptions & SHOW_NMEA_STATUS) { 686 if (dispOptions & OPTION_NO_PREFIX) 687 sprintf(outputStr, "%s%04d/%04d/%04d ", outputStr, msgCounter, errCounter, incomplCounter); 688 else 689 sprintf(outputStr, "%sOK:%03d/Er:%03d/In:%03d ", outputStr, msgCounter, errCounter, incomplCounter); 690 } 691 692 if (options == 0 && dispOptions == 0) { //error, no parameter defined! 590 693 error("gps::parse() ERROR, no parameter specified!"); 591 694 value = strdup("GPS ARG ERR");
