Dependencies:   ChaNFSSD mbed BMP085 SHT2x

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NMEA_parse.c Source File

NMEA_parse.c

00001 /*
00002  * Copyright (c) 2011 Toshihisa T
00003  * Released under the MIT License: http://mbed.org/license/mit
00004  */
00005 
00006 #include "NMEA_parse.h"
00007 
00008 #ifndef NULL
00009 #   define  NULL    ((void *)0)
00010 #endif
00011 
00012 /*
00013                                                     nmealib    GM-316    FV-M11
00014     GGA    Global Positioning System Fix Data.            O    O    O
00015     GSA    GNSS DOP and Active Satellites                O    O    O
00016     GSV    GNSS Satellites in View                        O    O    O
00017     RMC    Recommended Minimum Navigation Information    O    O    O
00018     VTG    Course Over Ground and Ground Speed            O    O    O
00019     GGL    Geographic Position – Latitude / Longitude    X    O    O
00020     ZDA    Time & Date                                    X    O(synchronized to PPS)    O
00021  */
00022 
00023 static unsigned char _libNMEA_atoi(unsigned char c)
00024 {
00025     if((c >= (unsigned char)('0')) && (c <= (unsigned char)('9')))
00026         return (c - (unsigned char)('0'));
00027     if((c >= (unsigned char)('A')) && (c <= (unsigned char)('F')))
00028         return (c - (unsigned char)('A')) + 10;
00029     return (c - (unsigned char)('a')) + 10;
00030 }
00031 short libNMEA_Parse1Char(unsigned char c,libNMEA_data_t *buffer)
00032 {
00033     register short cnewst = 0;
00034 
00035     /* It does again at the time of beginning after one line is obtained it. */
00036     /* It does again after the syntax error at the time of beginning. */
00037     /* 1行を得た後ならば,再度初めから */
00038     /* パースエラーの後も,再度初めから */
00039     if((buffer->cjobst >= LIBNMEA_PARSE_COMPLETE) || (buffer->cjobst < LIBNMEA_PARSE_NONE)){
00040         buffer->cjobst = LIBNMEA_PARSE_NONE;
00041     }
00042 
00043     if(buffer->cjobst == LIBNMEA_PARSE_NONE){ /* Wait '$' */
00044         if((c != (unsigned char)('$')) && (c != (unsigned char)('!'))){
00045             return buffer->cjobst;
00046         }
00047         buffer->rawLength = 0;
00048         buffer->sum = 0;
00049     }
00050 
00051     /* The size check is previously done because it stores it here in the buffer now. */
00052     if(buffer->rawLength >= (sizeof(buffer->raw)-2)){
00053         buffer->cjobst = -3;    /* Buffer size overflow */
00054         return buffer->cjobst;
00055     }
00056 
00057     buffer->raw[buffer->rawLength] = c;
00058     buffer->rawLength += 1;
00059     buffer->raw[buffer->rawLength] = (unsigned char)('\0');
00060 
00061     cnewst = -1;    /* Syntax error (It initializes it by the default value.) */
00062 
00063     switch(buffer->cjobst){
00064         case LIBNMEA_PARSE_NONE:
00065             cnewst = 1;
00066             break;
00067         case 1: /* データ待ち */
00068             cnewst = buffer->cjobst;
00069             if(c == (unsigned char)('*')){
00070                 cnewst += 1;    /* チェックサム1文字目を得る */
00071             } else {
00072                 buffer->sum = buffer->sum ^ c;    /* チェックサム計算 */
00073             }
00074             break;
00075         case 2:    /* チェックサム1文字目 */
00076             buffer->sumwk = _libNMEA_atoi(c);
00077             buffer->sumwk = buffer->sumwk << 4;
00078             cnewst = buffer->cjobst + 1;    /* チェックサム2文字目を得る */
00079             break;
00080         case 3:    /* チェックサム2文字目 */
00081             if((buffer->sumwk |= _libNMEA_atoi(c)) == buffer->sum){
00082                 cnewst = LIBNMEA_PARSE_SUMOK;        /* CR待ち */
00083             } else {
00084                 //printf("SUM:%02x/%02x\n",buffer->sumwk,buffer->sum);
00085                 cnewst = -2;    /* チェックサムエラー */
00086             }
00087             break;
00088         case LIBNMEA_PARSE_SUMOK:    /* CR 待ち */
00089             if(c == (unsigned char)0x0d){
00090                 cnewst = buffer->cjobst + 1;    /* LF待ち */
00091             }
00092             break;
00093         case LIBNMEA_PARSE_SUMOK+1:    /* LF 待ち */
00094             if(c == (unsigned char)0x0a){
00095                 cnewst = LIBNMEA_PARSE_COMPLETE;    /* センテンス完了 */
00096             }
00097             break;
00098     }
00099 
00100     buffer->cjobst = cnewst;
00101     return buffer->cjobst;
00102 }
00103 
00104 /* 10進数固定 */
00105 short libNMEA_atol(unsigned char *numstr,long *val,long *length,unsigned char **nextptr)
00106 {
00107     long retval = 0;
00108     int i = 0;
00109     int mi = 0;
00110     unsigned char c;
00111 
00112     *length = 1;
00113 
00114     if(*(numstr + i) == (unsigned char)('-')){
00115         mi = 1;
00116         i++;
00117     }
00118 
00119     for(;*(numstr + i) != (unsigned char)('\0');i++){
00120         c = *(numstr + i);
00121         if((c >= (unsigned char)('0')) && (c <= (unsigned char)('9'))){
00122             c = c - (unsigned char)('0');
00123             retval = (retval * 10) + c;
00124             *length = *length * 10;
00125         } else {
00126             break;
00127         }
00128     }
00129     if((nextptr != NULL) && (*nextptr != NULL)){
00130         *nextptr = numstr + i;
00131     }
00132     *val = (mi) ? (0-retval) : retval;
00133     return 0;
00134 }
00135 
00136 short libNMEA_atod(unsigned char *numstr,libNMEA_realnum_t *val,unsigned char **nextptr)
00137 {
00138     long lval = 0;
00139     libNMEA_realnum_t e = 0.0;
00140     libNMEA_realnum_t f = 0.0;
00141     unsigned char *nptr;
00142     long length;
00143 
00144     /* TODO:符号チェックを入れる事 */
00145 
00146     /* 整数部 */
00147     libNMEA_atol(numstr,&lval,&length,&nptr);
00148     e = (libNMEA_realnum_t)lval;
00149 
00150     /* 小数部 */
00151     if(*nptr == (unsigned char)('.')){
00152         nptr++;
00153         libNMEA_atol(nptr,&lval,&length,&nptr);
00154         f = ((libNMEA_realnum_t)lval) / ((libNMEA_realnum_t)length);
00155     }
00156 
00157     if((nextptr != NULL) && (*nextptr != NULL)){
00158         *nextptr = nptr;
00159     }
00160     *val = e + f;
00161     return 0;
00162 }
00163 
00164 /* GPS の緯度経度 ddmm.mmmm(dddmm.mmmm) 形式の文字列を,
00165    dd.dddd の libNMEA_realnum_t 形式に変換する. */
00166 /* http://www.circuitcellar.com/library/print/1000/Stefan123/4.htm */
00167 short libNMEA_atodeg(unsigned char *numstr,libNMEA_realnum_t *val)
00168 {
00169     volatile long wk = 0;
00170     volatile long deg_l = 0;
00171     long length = 0;
00172     libNMEA_realnum_t mm_d = 0;
00173     unsigned char *nextptr;
00174 
00175     /* ddmm 部を取り出す */
00176     libNMEA_atol(numstr,(long *)&wk,&length,&nextptr);
00177 
00178     /* dd を得る */
00179     deg_l = wk / 100;
00180 
00181     /* .mmmm 部を取り出す */
00182     libNMEA_atod(nextptr,&mm_d,&nextptr);
00183 
00184     /* mm.mmmm にする */
00185     mm_d = ((libNMEA_realnum_t)(wk % 100)) + mm_d;
00186     /* 0.dddd に変換する */
00187     mm_d = (mm_d / 60.0);
00188     /* もし,mm_d が 1.0 よりも大きい場合,mm.mmmm は60分を超える値であり,
00189        GPS の緯度経度値として適切ではない */
00190     if(mm_d > 1.0){
00191         return -1;
00192     }
00193 
00194     *val = ((libNMEA_realnum_t)deg_l) + mm_d;    /* dd.dddd 形式に変換 */
00195 
00196     return 0;
00197 }
00198 
00199 #if 0
00200 static short _libNMEA_print_args(libNMEA_data_t *buffer)
00201 {
00202     int i;
00203     extern int printf(const char *format, ...);
00204 
00205     printf("ARGC %5d:",buffer->argc);
00206     for(i=0;i < buffer->argc;i++){
00207         printf("[%s]",buffer->raw + buffer->argv[i]);
00208     }
00209     printf("\n");
00210     return 0;
00211 }
00212 #endif
00213 
00214 static void _libNMEA_String2Time(unsigned char *numstr,libNMEA_gps_info_t *GPSinfo)
00215 {
00216     long wk;
00217     long length;
00218     unsigned char *nextptr;
00219 
00220     libNMEA_atol(numstr,&wk,&length,&nextptr);
00221     GPSinfo->time.sec = wk % 100;
00222     wk = wk/100;
00223     GPSinfo->time.min = wk % 100;
00224     wk = wk/100;
00225     GPSinfo->time.hour = wk % 100;
00226     GPSinfo->time.msec = 0;
00227     if((nextptr != NULL) && (*nextptr == (unsigned char)('.'))){
00228         libNMEA_atol(nextptr+1,&wk,&length,(unsigned char **)NULL);
00229         GPSinfo->time.msec = wk;
00230     }
00231 }
00232 
00233 static void _libNMEA_setInvalid(libNMEA_gps_info_t *GPSinfo)
00234 {
00235     GPSinfo->valid.status = 0;
00236 
00237     GPSinfo->valid.positioning = 0;
00238     GPSinfo->valid.active = 0;
00239 }
00240 
00241 /* Recommended Minimum Course Response Message */
00242 static short _libNMEA_Parse1Line_GPRMC(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
00243 {
00244     unsigned char *nextptr;
00245 
00246     if(buffer->argc != 13){
00247         return -2; /* データの数がおかしい */
00248     }
00249     //_libNMEA_print_args(buffer);
00250 
00251     /* まず,真っ先に見るのは,GPS データのステータス(妥当性) */
00252     if(*(buffer->raw+buffer->argv[2]+0) != (unsigned char)('A')){
00253         /* GPS データ妥当性無し */
00254         GPSinfo->valid.status = 0;
00255         /* 妥当性が無いので,これ以上解析する必要は無いので終わる */
00256         return 0;
00257     }
00258 
00259     /* 測位状態を得る */
00260     switch(*(buffer->raw+buffer->argv[12]+0)){
00261         case (unsigned char)('A'):    /* 単独測位 */
00262         case (unsigned char)('D'):    /* DGPS */
00263             GPSinfo->status.positioning = *(buffer->raw+buffer->argv[12]+0);
00264             GPSinfo->valid.positioning = 1;
00265             break;
00266         default:
00267             GPSinfo->status.positioning = (unsigned char)('N');
00268             _libNMEA_setInvalid(GPSinfo);
00269             return 0;    /* 無効な測位状態なので返る */
00270     }
00271 
00272     /* *** 妥当性のあるデータ *** */
00273 
00274     /* 緯度を得る */
00275     libNMEA_atodeg( buffer->raw+buffer->argv[3]
00276                     ,&(GPSinfo->latlon.latitude) );
00277     GPSinfo->latlon.lat_unit = *(buffer->raw+buffer->argv[4]);
00278     GPSinfo->valid.latitude = 1;
00279 
00280     /* 経度を得る */
00281     libNMEA_atodeg( buffer->raw+buffer->argv[5]
00282                     ,&(GPSinfo->latlon.longitude ) );
00283     GPSinfo->latlon.lon_unit = *(buffer->raw+buffer->argv[6]);
00284     GPSinfo->valid.longitude = 1;
00285 
00286     /* 対地速度(ノット)を得る */
00287     libNMEA_atod( buffer->raw+buffer->argv[7],
00288                   &(GPSinfo->speed.ground),
00289                   &nextptr);
00290     GPSinfo->valid.speed = 1;
00291 
00292     /* 進行方向(度,真北)を得る */
00293     libNMEA_atod( buffer->raw+buffer->argv[8],
00294                   &(GPSinfo->direction.trueNorth.deg),
00295                   &nextptr);
00296     GPSinfo->valid.direction = 1;
00297 
00298     GPSinfo->valid.timeRMC = 0;
00299     if(1){
00300         /* 現在時刻/日付を得る.*/
00301         long wk;
00302         long length;
00303 
00304         _libNMEA_String2Time(buffer->raw+buffer->argv[1],GPSinfo);
00305 
00306         libNMEA_atol(buffer->raw+buffer->argv[9],&wk,&length,&nextptr);
00307         /* GPRMC は,西暦は下2桁しかないので,2000を加算する. */
00308         GPSinfo->date.year = (wk % 100) + 2000;    /* after year 2000. */
00309         wk = wk/100;
00310         GPSinfo->date.mon = wk % 100;
00311         wk = wk/100;
00312         GPSinfo->date.day = wk % 100;
00313         GPSinfo->valid.timeRMC = 1;
00314     }
00315 
00316     /* ステータスは有効 */
00317     GPSinfo->valid.status = 1;
00318 
00319     return 0;
00320 }
00321 
00322 static short _libNMEA_Parse1Line_GPZDA(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
00323 {
00324     long wk;
00325     long length;
00326     unsigned char *nextptr;
00327 
00328     if(buffer->argc != 7){
00329         return -2;
00330     }
00331 
00332     GPSinfo->valid.timeZDA = 0;
00333 
00334     _libNMEA_String2Time(buffer->raw+buffer->argv[1],GPSinfo);
00335 
00336     libNMEA_atol(buffer->raw+buffer->argv[2],&wk,&length,&nextptr);
00337     GPSinfo->date.day = wk;
00338     libNMEA_atol(buffer->raw+buffer->argv[3],&wk,&length,&nextptr);
00339     GPSinfo->date.mon = wk;
00340     libNMEA_atol(buffer->raw+buffer->argv[4],&wk,&length,&nextptr);
00341     GPSinfo->date.year = wk;
00342 
00343     GPSinfo->valid.timeZDA = 1;
00344 
00345     return 0;
00346 }
00347 
00348 /* GPGSA - GNSS DOP and Active Satellites */
00349 /* 0:[$GPGSA],1:[A],2:[3],3:[05],4:[02],5:[26],6:[27],7:[09],8:[04],9:[15],10:[],11:[],12:[],13:[],14:[],15:[1.8],16:[1.0],17:[1.5]*11 */
00350 static short _libNMEA_Parse1Line_GPGSA(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
00351 {
00352     if(buffer->argc != 18){
00353         return -2;
00354     }
00355 
00356     switch( *(buffer->raw+buffer->argv[2]) ){
00357         case '2':   /* 2D */
00358         case '3':   /* 3D */
00359             GPSinfo->status.active = *(buffer->raw+buffer->argv[2]);
00360             GPSinfo->valid.active = 1;
00361             break;
00362         default:    /* Fix not available */
00363             _libNMEA_setInvalid(GPSinfo);
00364             return 0;    /* 無効な測位状態なので返る */
00365     }
00366 
00367     GPSinfo->valid.accuracy_pdop = 0;
00368     libNMEA_atod( buffer->raw+buffer->argv[15],
00369                   &(GPSinfo->accuracy.p.dop),
00370                   (unsigned char **)NULL);
00371     GPSinfo->valid.accuracy_pdop = 1;
00372 
00373     GPSinfo->valid.accuracy_hdop = 0;
00374     libNMEA_atod( buffer->raw+buffer->argv[16],
00375                   &(GPSinfo->accuracy.h.dop),
00376                   (unsigned char **)NULL);
00377     GPSinfo->valid.accuracy_hdop = 1;
00378 
00379     GPSinfo->valid.accuracy_vdop = 0;
00380     libNMEA_atod( buffer->raw+buffer->argv[17],
00381                   &(GPSinfo->accuracy.v.dop),
00382                   (unsigned char **)NULL);
00383     GPSinfo->valid.accuracy_vdop = 1;
00384 
00385     return 0;
00386 }
00387 
00388 static short _libNMEA_Parse1Line_GP(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
00389 {
00390     unsigned char *sentenceID = (unsigned char *)0;
00391 
00392     sentenceID = buffer->raw+buffer->argv[0];
00393     sentenceID += 3;    /* "$GP" をスキップ */
00394 
00395     if(    (*(sentenceID+0) == (unsigned char)('R'))
00396         && (*(sentenceID+1) == (unsigned char)('M'))
00397         && (*(sentenceID+2) == (unsigned char)('C'))){
00398         return _libNMEA_Parse1Line_GPRMC(buffer,GPSinfo);
00399     } else if( (*(sentenceID+0) == (unsigned char)('Z'))
00400         &&     (*(sentenceID+1) == (unsigned char)('D'))
00401         &&     (*(sentenceID+2) == (unsigned char)('A'))){
00402         return _libNMEA_Parse1Line_GPZDA(buffer,GPSinfo);
00403     } else if((*(sentenceID+0) == (unsigned char)('G'))
00404         &&    (*(sentenceID+1) == (unsigned char)('S'))
00405         &&    (*(sentenceID+2) == (unsigned char)('A'))){
00406         return _libNMEA_Parse1Line_GPGSA(buffer,GPSinfo);
00407     }
00408 
00409     return -2;    /* このセンテンスは処理しませんでした */
00410 }
00411 
00412 #ifdef DEBUG    /* { */
00413 static short max_argc = 0;
00414 #endif  /* } */
00415 
00416 short libNMEA_Parse1Line(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
00417 {
00418     int i;
00419     unsigned char *tokerID = (unsigned char *)0;
00420 
00421     buffer->argc = 0;
00422     buffer->argv[buffer->argc+0] = 0;
00423     buffer->argv[buffer->argc+1] = -1;
00424     buffer->argc++;
00425 
00426     /* まず,NMEA センテンスをトークンで分解する.*/
00427     /* 後で変換作業をしやすくするため */
00428     for(i = 0;buffer->raw[i] != (unsigned char)('\0');i++){
00429         if((buffer->raw[i] == (unsigned char)('*'))
00430             || (buffer->raw[i] == (unsigned char)(0x0d))
00431             || (buffer->raw[i] == (unsigned char)(0x0a))){
00432             buffer->raw[i] = (unsigned char)('\0');
00433             buffer->argv[buffer->argc] = -1;
00434             break;
00435         }
00436         if(buffer->raw[i] == (unsigned char)(',')){
00437             buffer->raw[i] = (unsigned char)('\0');
00438             if(buffer->raw[i+1] != (unsigned char)('\0')){
00439                 buffer->argv[buffer->argc+0] = i+1;
00440                 buffer->argv[buffer->argc+1] = -1;
00441                 buffer->argc++;
00442                 if(buffer->argc >= LIBNMEA_NUMSOFARRAY(buffer->argv)){
00443                     return -1;
00444                 }
00445 #ifdef DEBUG
00446                 if(buffer->argc > max_argc){
00447                     max_argc = buffer->argc;
00448                 }
00449 #endif
00450             }
00451         }
00452     }
00453 
00454     tokerID = buffer->raw+buffer->argv[0];
00455     if(*(tokerID+0) == (unsigned char)('$')){
00456         if(*(tokerID+1) == (unsigned char)('P')){
00457             /* P センテンスは無視する */
00458         } else {
00459             if((*(tokerID+1) == (unsigned char)('G'))
00460                 || (*(tokerID+2) == (unsigned char)('P'))){
00461                 /* GP for a GPS unit */
00462                 return _libNMEA_Parse1Line_GP(buffer,GPSinfo);
00463             } else {
00464                 /* 不明なトーカーは無視する */
00465             }
00466         }
00467     } else {
00468         /* '$' から始まらないセンテンスは無視する */
00469     }
00470 
00471     return -2;    /* このセンテンスは処理しませんでした */
00472 }
00473 
00474 #ifdef __SELFTEST__
00475 #include <stdio.h>
00476 
00477 char *sample[] = {
00478     "$GPGGA,123519.00,4807.038247,N,01131.324523,E,1,08,0.9,545.42,M,46.93,M,5.0,1012*42\x0d\x0a",
00479     "$GPGLL,4916.452349,N,12311.123215,W,225444.00,A,A*6A\x0d\x0a",
00480     "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39\x0d\x0a",
00481     "$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75\x0d\x0a",
00482     "$GPRMC,225446.00,A,4916.452653,N,12311.123747,W,000.5,054.7,191194,06.2,W,A*68\x0d\x0a",
00483     NULL
00484 };
00485 
00486 int main(int argc,char *argv[])
00487 {
00488     int i,j;
00489     libNMEA_data_t sts;
00490     int ret;
00491     libNMEA_gps_info_t GPSinfo;
00492     unsigned char *nextptr;
00493     unsigned char *text;
00494     libNMEA_realnum_t val;
00495 
00496 
00497     /* x86 版 Linux だと,sizeof(libNMEA_gps_info_t) = 124 である.*/
00498     printf("sizeof(libNMEA_gps_info_t) = %lu\n\n",sizeof(libNMEA_gps_info_t));
00499     printf("sizeof(libNMEA_gps_time_t) = %lu\n\n",sizeof(libNMEA_gps_time_t));
00500 
00501     text = "123.4567"; libNMEA_atod(text,&val,&nextptr);
00502     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00503     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00504 
00505     text = "123.4567ABC"; libNMEA_atod(text,&val,&nextptr);
00506     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00507     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00508 
00509     text = "9876"; libNMEA_atod(text,&val,&nextptr);
00510     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00511     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00512 
00513     text = "98765ABC"; libNMEA_atod(text,&val,&nextptr);
00514     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00515     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00516 
00517     text = "98765.123"; libNMEA_atod(text,&val,&nextptr);
00518     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00519     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00520 
00521     text = "98765.00123"; libNMEA_atod(text,&val,&nextptr);
00522     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00523     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00524 
00525     text = "1.0000123DEF"; libNMEA_atod(text,&val,&nextptr);
00526     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00527     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00528 
00529     text = "1.000987XYZDEF"; libNMEA_atod(text,&val,&nextptr);
00530     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00531     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00532 
00533     text = "12."; libNMEA_atod(text,&val,&nextptr);
00534     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00535     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00536 
00537     text = ".9876"; libNMEA_atod(text,&val,&nextptr);
00538     printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
00539     if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
00540 
00541     for(i = 0;sample[i] != NULL;i++){
00542         sts.cjobst = 0;
00543         for(j = 0;*(sample[i]+j) != (char)('\0');j++){
00544             ret = libNMEA_Parse1Char(*(sample[i]+j),&sts);
00545             if(ret < 0){
00546                 printf("ret = %d (char:\'%c\')\n",ret,*(sample[i]+j));
00547             }
00548             if(ret == LIBNMEA_PARSE_COMPLETE){
00549                 printf("mes:[%s]\n",sample[i]);
00550                 printf("get:[%s]\n",sts.raw);
00551                 libNMEA_Parse1Line(&sts,&GPSinfo);
00552             }
00553         }
00554     }
00555     return 0;
00556 }
00557 #endif
00558 
00559 #ifdef __SELFTEST2__
00560 #include <stdio.h>
00561 #include <unistd.h>
00562 
00563 int main(int argc,char *argv[])
00564 {
00565     libNMEA_data_t sts;
00566     int ret;
00567     char buf;
00568     libNMEA_gps_info_t GPSinfo;
00569 
00570     sts.cjobst = 0;
00571     while(read(fileno(stdin),&buf,sizeof(buf)) == sizeof(buf)){
00572         ret = libNMEA_Parse1Char(buf,&sts);
00573         if(ret < 0){
00574             printf("ret = %d (char:\'%c\')\n",ret,buf);
00575             printf("err:[%s]\n",sts.raw);
00576             return 1;
00577         }
00578         if(ret == LIBNMEA_PARSE_SUMOK){
00579             //printf("get:[%s]\n",sts.raw);
00580 GPSinfo.valid.status = 0;
00581             libNMEA_Parse1Line(&sts,&GPSinfo);
00582             if(GPSinfo.valid.status != 0){
00583                 printf("lat:%c  %8.5f\nlon:%c %8.5f\n",
00584                         GPSinfo.latlon.lat_unit,
00585                         GPSinfo.latlon.latitude,
00586                         GPSinfo.latlon.lon_unit,
00587                         GPSinfo.latlon.longitude );
00588             } else {
00589                 //printf("lat:- ---.-----\nlon:- ---.-----\n");
00590             }
00591 
00592             sts.cjobst = 0;
00593         }
00594     }
00595     printf("max_argc = %d\n",max_argc);
00596     return 0;
00597 }
00598 #endif