int main() { char bufa[BUFSZ] = {'\0'}, bufb[BUFSZ]; size_t lena = 0, mem = BUFSZ; nmeamsg_t nm; nmeabuf_t nb; nmea_ctor(&nb, bufb, mem); nmea_concat(&nb, ",2*23\n$CAREV,INIT,0.1.2.3.4*45\n$CA", 34); nmea_scan(&nb, &nm); nmea_debug(stderr, &nb); lena = nmea_parse(bufa, mem, &nm); if (0 == lena) return -1; if (0 != strncmp(bufa, "$CAREV,INIT,0.1.2.3.4*45\n", lena)) return -1; bufa[lena-1]='.'; printf("len=%ld msg=\"%s\"\n", lena, bufa); nmea_scan(&nb, &nm); nmea_debug(stderr, &nb); return 0; }
/* Collect NMEA sentences from the tty. */ int nmeainput(int c, struct tty *tp) { struct nmea *np = (struct nmea *)tp->t_sc; struct timespec ts; int64_t gap; long tmin, tmax; switch (c) { case '$': nanotime(&ts); np->pos = np->sync = 0; gap = (ts.tv_sec * 1000000000LL + ts.tv_nsec) - (np->lts.tv_sec * 1000000000LL + np->lts.tv_nsec); np->lts.tv_sec = ts.tv_sec; np->lts.tv_nsec = ts.tv_nsec; if (gap <= np->gap) break; np->ts.tv_sec = ts.tv_sec; np->ts.tv_nsec = ts.tv_nsec; #ifdef NMEA_DEBUG if (nmeadebug > 0) { linesw[TTYDISC].l_rint('[', tp); linesw[TTYDISC].l_rint('0' + np->gapno++, tp); linesw[TTYDISC].l_rint(']', tp); } #endif np->gap = gap; /* * If a tty timestamp is available, make sure its value is * reasonable by comparing against the timestamp just taken. * If they differ by more than 2 seconds, assume no PPS signal * is present, note the fact, and keep using the timestamp * value. When this happens, the sensor state is set to * CRITICAL later when the GPRMC sentence is decoded. */ if (tp->t_flags & (TS_TSTAMPDCDSET | TS_TSTAMPDCDCLR | TS_TSTAMPCTSSET | TS_TSTAMPCTSCLR)) { tmax = lmax(np->ts.tv_sec, tp->t_tv.tv_sec); tmin = lmin(np->ts.tv_sec, tp->t_tv.tv_sec); if (tmax - tmin > 1) np->no_pps = 1; else { np->ts.tv_sec = tp->t_tv.tv_sec; np->ts.tv_nsec = tp->t_tv.tv_usec * 1000L; np->no_pps = 0; } } break; case '\r': case '\n': if (!np->sync) { np->cbuf[np->pos] = '\0'; nmea_scan(np, tp); np->sync = 1; } break; default: if (!np->sync && np->pos < (NMEAMAX - 1)) np->cbuf[np->pos++] = c; break; } /* pass data to termios */ return (linesw[TTYDISC].l_rint(c, tp)); }