Skytraq S1315F-RAW-EVK Logger

Dependencies:   TextLCD mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NMEA_parse.c Source File

NMEA_parse.c

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