Skytraq S1315F-RAW-EVK Logger

Dependencies:   TextLCD mbed

Revision:
0:e0ec137da369
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libT/portable/NMEA_parse.c	Sat Dec 18 11:17:21 2010 +0000
@@ -0,0 +1,594 @@
+
+#include "NMEA_parse.h"
+
+#ifndef NULL
+#   define  NULL    ((void *)0)
+#endif
+
+/*
+                                                    nmealib    GM-316    FV-M11
+    GGA    Global Positioning System Fix Data.            O    O    O
+    GSA    GNSS DOP and Active Satellites                O    O    O
+    GSV    GNSS Satellites in View                        O    O    O
+    RMC    Recommended Minimum Navigation Information    O    O    O
+    VTG    Course Over Ground and Ground Speed            O    O    O
+    GGL    Geographic Position – Latitude / Longitude    X    O    O
+    ZDA    Time & Date                                    X    O(synchronized to PPS)    O
+ */
+
+static unsigned char _libNMEA_atoi(unsigned char c)
+{
+    if((c >= (unsigned char)('0')) && (c <= (unsigned char)('9')))
+        return (c - (unsigned char)('0'));
+    if((c >= (unsigned char)('A')) && (c <= (unsigned char)('F')))
+        return (c - (unsigned char)('A')) + 10;
+    return (c - (unsigned char)('a')) + 10;
+}
+short libNMEA_Parse1Char(unsigned char c,libNMEA_data_t *buffer)
+{
+    register short cnewst = 0;
+
+    /* It does again at the time of beginning after one line is obtained it. */
+    /* It does again after the syntax error at the time of beginning. */
+    /* 1行を得た後ならば,再度初めから */
+    /* パースエラーの後も,再度初めから */
+    if((buffer->cjobst >= LIBNMEA_PARSE_COMPLETE) || (buffer->cjobst < LIBNMEA_PARSE_NONE)){
+        buffer->cjobst = LIBNMEA_PARSE_NONE;
+    }
+
+    if(buffer->cjobst == LIBNMEA_PARSE_NONE){ /* Wait '$' */
+        if((c != (unsigned char)('$')) && (c != (unsigned char)('!'))){
+            return buffer->cjobst;
+        }
+        buffer->rawLength = 0;
+        buffer->sum = 0;
+    }
+
+    /* The size check is previously done because it stores it here in the buffer now. */
+    if(buffer->rawLength >= (sizeof(buffer->raw)-2)){
+        buffer->cjobst = -3;    /* Buffer size overflow */
+        return buffer->cjobst;
+    }
+
+    buffer->raw[buffer->rawLength] = c;
+    buffer->rawLength += 1;
+    buffer->raw[buffer->rawLength] = (unsigned char)('\0');
+
+    cnewst = -1;    /* Syntax error (It initializes it by the default value.) */
+
+    switch(buffer->cjobst){
+        case LIBNMEA_PARSE_NONE:
+            cnewst = 1;
+            break;
+        case 1: /* データ待ち */
+            cnewst = buffer->cjobst;
+            if(c == (unsigned char)('*')){
+                cnewst += 1;    /* チェックサム1文字目を得る */
+            } else {
+                buffer->sum = buffer->sum ^ c;    /* チェックサム計算 */
+            }
+            break;
+        case 2:    /* チェックサム1文字目 */
+            buffer->sumwk = _libNMEA_atoi(c);
+            buffer->sumwk = buffer->sumwk << 4;
+            cnewst = buffer->cjobst + 1;    /* チェックサム2文字目を得る */
+            break;
+        case 3:    /* チェックサム2文字目 */
+            if((buffer->sumwk |= _libNMEA_atoi(c)) == buffer->sum){
+                cnewst = LIBNMEA_PARSE_SUMOK;        /* CR待ち */
+            } else {
+                //printf("SUM:%02x/%02x\n",buffer->sumwk,buffer->sum);
+                cnewst = -2;    /* チェックサムエラー */
+            }
+            break;
+        case LIBNMEA_PARSE_SUMOK:    /* CR 待ち */
+            if(c == (unsigned char)0x0d){
+                cnewst = buffer->cjobst + 1;    /* LF待ち */
+            }
+            break;
+        case LIBNMEA_PARSE_SUMOK+1:    /* LF 待ち */
+            if(c == (unsigned char)0x0a){
+                cnewst = LIBNMEA_PARSE_COMPLETE;    /* センテンス完了 */
+            }
+            break;
+    }
+
+    buffer->cjobst = cnewst;
+    return buffer->cjobst;
+}
+
+/* 10進数固定 */
+short libNMEA_atol(unsigned char *numstr,long *val,long *length,unsigned char **nextptr)
+{
+    long retval = 0;
+    int i = 0;
+    int mi = 0;
+    unsigned char c;
+
+    *length = 1;
+
+    if(*(numstr + i) == (unsigned char)('-')){
+        mi = 1;
+        i++;
+    }
+
+    for(;*(numstr + i) != (unsigned char)('\0');i++){
+        c = *(numstr + i);
+        if((c >= (unsigned char)('0')) && (c <= (unsigned char)('9'))){
+            c = c - (unsigned char)('0');
+            retval = (retval * 10) + c;
+            *length = *length * 10;
+        } else {
+            break;
+        }
+    }
+    if((nextptr != NULL) && (*nextptr != NULL)){
+        *nextptr = numstr + i;
+    }
+    *val = (mi) ? (0-retval) : retval;
+    return 0;
+}
+
+short libNMEA_atod(unsigned char *numstr,libNMEA_realnum_t *val,unsigned char **nextptr)
+{
+    long lval = 0;
+    libNMEA_realnum_t e = 0.0;
+    libNMEA_realnum_t f = 0.0;
+    unsigned char *nptr;
+    long length;
+
+    /* TODO:符号チェックを入れる事 */
+
+    /* 整数部 */
+    libNMEA_atol(numstr,&lval,&length,&nptr);
+    e = (libNMEA_realnum_t)lval;
+
+    /* 小数部 */
+    if(*nptr == (unsigned char)('.')){
+        nptr++;
+        libNMEA_atol(nptr,&lval,&length,&nptr);
+        f = ((libNMEA_realnum_t)lval) / ((libNMEA_realnum_t)length);
+    }
+
+    if((nextptr != NULL) && (*nextptr != NULL)){
+        *nextptr = nptr;
+    }
+    *val = e + f;
+    return 0;
+}
+
+/* GPS の緯度経度 ddmm.mmmm(dddmm.mmmm) 形式の文字列を,
+   dd.dddd の libNMEA_realnum_t 形式に変換する. */
+/* http://www.circuitcellar.com/library/print/1000/Stefan123/4.htm */
+short libNMEA_atodeg(unsigned char *numstr,libNMEA_realnum_t *val)
+{
+    volatile long wk = 0;
+    volatile long deg_l = 0;
+    long length = 0;
+    libNMEA_realnum_t mm_d = 0;
+    unsigned char *nextptr;
+
+    /* ddmm 部を取り出す */
+    libNMEA_atol(numstr,(long *)&wk,&length,&nextptr);
+
+    /* dd を得る */
+    deg_l = wk / 100;
+
+    /* .mmmm 部を取り出す */
+    libNMEA_atod(nextptr,&mm_d,&nextptr);
+
+    /* mm.mmmm にする */
+    mm_d = ((libNMEA_realnum_t)(wk % 100)) + mm_d;
+    /* 0.dddd に変換する */
+    mm_d = (mm_d / 60.0);
+    /* もし,mm_d が 1.0 よりも大きい場合,mm.mmmm は60分を超える値であり,
+       GPS の緯度経度値として適切ではない */
+    if(mm_d > 1.0){
+        return -1;
+    }
+
+    *val = ((libNMEA_realnum_t)deg_l) + mm_d;    /* dd.dddd 形式に変換 */
+
+    return 0;
+}
+
+#if 0
+static short _libNMEA_print_args(libNMEA_data_t *buffer)
+{
+    int i;
+    extern int printf(const char *format, ...);
+
+    printf("ARGC %5d:",buffer->argc);
+    for(i=0;i < buffer->argc;i++){
+        printf("[%s]",buffer->raw + buffer->argv[i]);
+    }
+    printf("\n");
+    return 0;
+}
+#endif
+
+static void _libNMEA_String2Time(unsigned char *numstr,libNMEA_gps_info_t *GPSinfo)
+{
+    long wk;
+    long length;
+    unsigned char *nextptr;
+
+    libNMEA_atol(numstr,&wk,&length,&nextptr);
+    GPSinfo->time.sec = wk % 100;
+    wk = wk/100;
+    GPSinfo->time.min = wk % 100;
+    wk = wk/100;
+    GPSinfo->time.hour = wk % 100;
+    GPSinfo->time.msec = 0;
+    if((nextptr != NULL) && (*nextptr == (unsigned char)('.'))){
+        libNMEA_atol(nextptr+1,&wk,&length,(unsigned char **)NULL);
+        GPSinfo->time.msec = wk;
+    }
+}
+
+static void _libNMEA_setInvalid(libNMEA_gps_info_t *GPSinfo)
+{
+    GPSinfo->valid.status = 0;
+
+    GPSinfo->valid.positioning = 0;
+    GPSinfo->valid.active = 0;
+}
+
+/* Recommended Minimum Course Response Message */
+static short _libNMEA_Parse1Line_GPRMC(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
+{
+    unsigned char *nextptr;
+
+    if(buffer->argc != 13){
+        return -2; /* データの数がおかしい */
+    }
+    //_libNMEA_print_args(buffer);
+
+    /* まず,真っ先に見るのは,GPS データのステータス(妥当性) */
+    if(*(buffer->raw+buffer->argv[2]+0) != (unsigned char)('A')){
+        /* GPS データ妥当性無し */
+        GPSinfo->valid.status = 0;
+        /* 妥当性が無いので,これ以上解析する必要は無いので終わる */
+        return 0;
+    }
+
+    /* 測位状態を得る */
+    switch(*(buffer->raw+buffer->argv[12]+0)){
+        case (unsigned char)('A'):    /* 単独測位 */
+        case (unsigned char)('D'):    /* DGPS */
+            GPSinfo->status.positioning = *(buffer->raw+buffer->argv[12]+0);
+            GPSinfo->valid.positioning = 1;
+            break;
+        default:
+            GPSinfo->status.positioning = (unsigned char)('N');
+            _libNMEA_setInvalid(GPSinfo);
+            return 0;    /* 無効な測位状態なので返る */
+    }
+
+    /* *** 妥当性のあるデータ *** */
+
+    /* 緯度を得る */
+    libNMEA_atodeg( buffer->raw+buffer->argv[3]
+                    ,&(GPSinfo->latlon.latitude) );
+    GPSinfo->latlon.lat_unit = *(buffer->raw+buffer->argv[4]);
+    GPSinfo->valid.latitude = 1;
+
+    /* 経度を得る */
+    libNMEA_atodeg( buffer->raw+buffer->argv[5]
+                    ,&(GPSinfo->latlon.longitude ) );
+    GPSinfo->latlon.lon_unit = *(buffer->raw+buffer->argv[6]);
+    GPSinfo->valid.longitude = 1;
+
+    /* 対地速度(ノット)を得る */
+    libNMEA_atod( buffer->raw+buffer->argv[7],
+                  &(GPSinfo->speed.ground),
+                  &nextptr);
+    GPSinfo->valid.speed = 1;
+
+    /* 進行方向(度,真北)を得る */
+    libNMEA_atod( buffer->raw+buffer->argv[8],
+                  &(GPSinfo->direction.trueNorth.deg),
+                  &nextptr);
+    GPSinfo->valid.direction = 1;
+
+    GPSinfo->valid.timeRMC = 0;
+    if(1){
+        /* 現在時刻/日付を得る.*/
+        long wk;
+        long length;
+
+        _libNMEA_String2Time(buffer->raw+buffer->argv[1],GPSinfo);
+
+        libNMEA_atol(buffer->raw+buffer->argv[9],&wk,&length,&nextptr);
+        /* GPRMC は,西暦は下2桁しかないので,2000を加算する. */
+        GPSinfo->date.year = (wk % 100) + 2000;    /* after year 2000. */
+        wk = wk/100;
+        GPSinfo->date.mon = wk % 100;
+        wk = wk/100;
+        GPSinfo->date.day = wk % 100;
+        GPSinfo->valid.timeRMC = 1;
+    }
+
+    /* ステータスは有効 */
+    GPSinfo->valid.status = 1;
+
+    return 0;
+}
+
+static short _libNMEA_Parse1Line_GPZDA(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
+{
+    long wk;
+    long length;
+    unsigned char *nextptr;
+
+    if(buffer->argc != 7){
+        return -2;
+    }
+
+    GPSinfo->valid.timeZDA = 0;
+
+    _libNMEA_String2Time(buffer->raw+buffer->argv[1],GPSinfo);
+
+    libNMEA_atol(buffer->raw+buffer->argv[2],&wk,&length,&nextptr);
+    GPSinfo->date.day = wk;
+    libNMEA_atol(buffer->raw+buffer->argv[3],&wk,&length,&nextptr);
+    GPSinfo->date.mon = wk;
+    libNMEA_atol(buffer->raw+buffer->argv[4],&wk,&length,&nextptr);
+    GPSinfo->date.year = wk;
+
+    GPSinfo->valid.timeZDA = 1;
+
+    return 0;
+}
+
+/* GPGSA - GNSS DOP and Active Satellites */
+/* 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 */
+static short _libNMEA_Parse1Line_GPGSA(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
+{
+    if(buffer->argc != 18){
+        return -2;
+    }
+
+    switch( *(buffer->raw+buffer->argv[2]) ){
+        case '2':   /* 2D */
+        case '3':   /* 3D */
+            GPSinfo->status.active = *(buffer->raw+buffer->argv[2]);
+            GPSinfo->valid.active = 1;
+            break;
+        default:    /* Fix not available */
+            _libNMEA_setInvalid(GPSinfo);
+            return 0;    /* 無効な測位状態なので返る */
+    }
+
+    GPSinfo->valid.accuracy_pdop = 0;
+    libNMEA_atod( buffer->raw+buffer->argv[15],
+                  &(GPSinfo->accuracy.p.dop),
+                  (unsigned char **)NULL);
+    GPSinfo->valid.accuracy_pdop = 1;
+
+    GPSinfo->valid.accuracy_hdop = 0;
+    libNMEA_atod( buffer->raw+buffer->argv[16],
+                  &(GPSinfo->accuracy.h.dop),
+                  (unsigned char **)NULL);
+    GPSinfo->valid.accuracy_hdop = 1;
+
+    GPSinfo->valid.accuracy_vdop = 0;
+    libNMEA_atod( buffer->raw+buffer->argv[17],
+                  &(GPSinfo->accuracy.v.dop),
+                  (unsigned char **)NULL);
+    GPSinfo->valid.accuracy_vdop = 1;
+
+    return 0;
+}
+
+static short _libNMEA_Parse1Line_GP(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
+{
+    unsigned char *sentenceID = (unsigned char *)0;
+
+    sentenceID = buffer->raw+buffer->argv[0];
+    sentenceID += 3;    /* "$GP" をスキップ */
+
+    if(    (*(sentenceID+0) == (unsigned char)('R'))
+        && (*(sentenceID+1) == (unsigned char)('M'))
+        && (*(sentenceID+2) == (unsigned char)('C'))){
+        return _libNMEA_Parse1Line_GPRMC(buffer,GPSinfo);
+    } else if( (*(sentenceID+0) == (unsigned char)('Z'))
+        &&     (*(sentenceID+1) == (unsigned char)('D'))
+        &&     (*(sentenceID+2) == (unsigned char)('A'))){
+        return _libNMEA_Parse1Line_GPZDA(buffer,GPSinfo);
+    } else if((*(sentenceID+0) == (unsigned char)('G'))
+        &&    (*(sentenceID+1) == (unsigned char)('S'))
+        &&    (*(sentenceID+2) == (unsigned char)('A'))){
+        return _libNMEA_Parse1Line_GPGSA(buffer,GPSinfo);
+    }
+
+    return -2;    /* このセンテンスは処理しませんでした */
+}
+
+#ifdef DEBUG    /* { */
+static short max_argc = 0;
+#endif  /* } */
+
+short libNMEA_Parse1Line(libNMEA_data_t *buffer,libNMEA_gps_info_t *GPSinfo)
+{
+    int i;
+    unsigned char *tokerID = (unsigned char *)0;
+
+    buffer->argc = 0;
+    buffer->argv[buffer->argc+0] = 0;
+    buffer->argv[buffer->argc+1] = -1;
+    buffer->argc++;
+
+    /* まず,NMEA センテンスをトークンで分解する.*/
+    /* 後で変換作業をしやすくするため */
+    for(i = 0;buffer->raw[i] != (unsigned char)('\0');i++){
+        if((buffer->raw[i] == (unsigned char)('*'))
+            || (buffer->raw[i] == (unsigned char)(0x0d))
+            || (buffer->raw[i] == (unsigned char)(0x0a))){
+            buffer->raw[i] = (unsigned char)('\0');
+            buffer->argv[buffer->argc] = -1;
+            break;
+        }
+        if(buffer->raw[i] == (unsigned char)(',')){
+            buffer->raw[i] = (unsigned char)('\0');
+            if(buffer->raw[i+1] != (unsigned char)('\0')){
+                buffer->argv[buffer->argc+0] = i+1;
+                buffer->argv[buffer->argc+1] = -1;
+                buffer->argc++;
+                if(buffer->argc >= LIBNMEA_NUMSOFARRAY(buffer->argv)){
+                    return -1;
+                }
+#ifdef DEBUG
+                if(buffer->argc > max_argc){
+                    max_argc = buffer->argc;
+                }
+#endif
+            }
+        }
+    }
+
+    tokerID = buffer->raw+buffer->argv[0];
+    if(*(tokerID+0) == (unsigned char)('$')){
+        if(*(tokerID+1) == (unsigned char)('P')){
+            /* P センテンスは無視する */
+        } else {
+            if((*(tokerID+1) == (unsigned char)('G'))
+                || (*(tokerID+2) == (unsigned char)('P'))){
+                /* GP for a GPS unit */
+                return _libNMEA_Parse1Line_GP(buffer,GPSinfo);
+            } else {
+                /* 不明なトーカーは無視する */
+            }
+        }
+    } else {
+        /* '$' から始まらないセンテンスは無視する */
+    }
+
+    return -2;    /* このセンテンスは処理しませんでした */
+}
+
+#ifdef __SELFTEST__
+#include <stdio.h>
+
+char *sample[] = {
+    "$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",
+    "$GPGLL,4916.452349,N,12311.123215,W,225444.00,A,A*6A\x0d\x0a",
+    "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39\x0d\x0a",
+    "$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75\x0d\x0a",
+    "$GPRMC,225446.00,A,4916.452653,N,12311.123747,W,000.5,054.7,191194,06.2,W,A*68\x0d\x0a",
+    NULL
+};
+
+int main(int argc,char *argv[])
+{
+    int i,j;
+    libNMEA_data_t sts;
+    int ret;
+    libNMEA_gps_info_t GPSinfo;
+    unsigned char *nextptr;
+    unsigned char *text;
+    libNMEA_realnum_t val;
+
+
+    /* x86 版 Linux だと,sizeof(libNMEA_gps_info_t) = 124 である.*/
+    printf("sizeof(libNMEA_gps_info_t) = %lu\n\n",sizeof(libNMEA_gps_info_t));
+    printf("sizeof(libNMEA_gps_time_t) = %lu\n\n",sizeof(libNMEA_gps_time_t));
+
+    text = "123.4567"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "123.4567ABC"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "9876"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "98765ABC"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "98765.123"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "98765.00123"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "1.0000123DEF"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "1.000987XYZDEF"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = "12."; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    text = ".9876"; libNMEA_atod(text,&val,&nextptr);
+    printf("test=[%-20s]/val=%20.10f/ptr=[%s]\n",text,val,nextptr);
+    if(libNMEA_atodeg(text,&val) == 0){ printf("dd.dddd[%10.7f]\n\n",val); } else {printf("ERROR\n\n"); }
+
+    for(i = 0;sample[i] != NULL;i++){
+        sts.cjobst = 0;
+        for(j = 0;*(sample[i]+j) != (char)('\0');j++){
+            ret = libNMEA_Parse1Char(*(sample[i]+j),&sts);
+            if(ret < 0){
+                printf("ret = %d (char:\'%c\')\n",ret,*(sample[i]+j));
+            }
+            if(ret == LIBNMEA_PARSE_COMPLETE){
+                printf("mes:[%s]\n",sample[i]);
+                printf("get:[%s]\n",sts.raw);
+                libNMEA_Parse1Line(&sts,&GPSinfo);
+            }
+        }
+    }
+    return 0;
+}
+#endif
+
+#ifdef __SELFTEST2__
+#include <stdio.h>
+#include <unistd.h>
+
+int main(int argc,char *argv[])
+{
+    libNMEA_data_t sts;
+    int ret;
+    char buf;
+    libNMEA_gps_info_t GPSinfo;
+
+    sts.cjobst = 0;
+    while(read(fileno(stdin),&buf,sizeof(buf)) == sizeof(buf)){
+        ret = libNMEA_Parse1Char(buf,&sts);
+        if(ret < 0){
+            printf("ret = %d (char:\'%c\')\n",ret,buf);
+            printf("err:[%s]\n",sts.raw);
+            return 1;
+        }
+        if(ret == LIBNMEA_PARSE_SUMOK){
+            //printf("get:[%s]\n",sts.raw);
+GPSinfo.valid.status = 0;
+            libNMEA_Parse1Line(&sts,&GPSinfo);
+            if(GPSinfo.valid.status != 0){
+                printf("lat:%c  %8.5f\nlon:%c %8.5f\n",
+                        GPSinfo.latlon.lat_unit,
+                        GPSinfo.latlon.latitude,
+                        GPSinfo.latlon.lon_unit,
+                        GPSinfo.latlon.longitude );
+            } else {
+                //printf("lat:- ---.-----\nlon:- ---.-----\n");
+            }
+
+            sts.cjobst = 0;
+        }
+    }
+    printf("max_argc = %d\n",max_argc);
+    return 0;
+}
+#endif