int main(int argc, char *argv[]) { struct gps_data_t collect; struct fixsource_t source; char buf[BUFSIZ]; int option; bool batchmode = false; bool forwardmode = false; char *fmsg = NULL; #ifdef CLIENTDEBUG_ENABLE int debug = 0; #endif (void)signal(SIGSEGV, onsig); (void)signal(SIGBUS, onsig); while ((option = getopt(argc, argv, "bf:hsD:?")) != -1) { switch (option) { case 'b': batchmode = true; break; case 'f': forwardmode = true; fmsg = optarg; break; case 's': (void) printf ("Sizes: fix=%zd gpsdata=%zd rtcm2=%zd rtcm3=%zd ais=%zd compass=%zd raw=%zd devices=%zd policy=%zd version=%zd, noise=%zd\n", sizeof(struct gps_fix_t), sizeof(struct gps_data_t), sizeof(struct rtcm2_t), sizeof(struct rtcm3_t), sizeof(struct ais_t), sizeof(struct attitude_t), sizeof(struct rawdata_t), sizeof(collect.devices), sizeof(struct policy_t), sizeof(struct version_t), sizeof(struct gst_t)); exit(EXIT_SUCCESS); #ifdef CLIENTDEBUG_ENABLE case 'D': debug = atoi(optarg); break; #endif case '?': case 'h': default: (void)fputs("usage: test_libgps [-b] [-f fwdmsg] [-D lvl] [-s] [server[:port:[device]]]\n", stderr); exit(EXIT_FAILURE); } } /* Grok the server, port, and device. */ if (optind < argc) { gpsd_source_spec(argv[optind], &source); } else gpsd_source_spec(NULL, &source); #ifdef CLIENTDEBUG_ENABLE gps_enable_debug(debug, stdout); #endif if (batchmode) { #ifdef SOCKET_EXPORT_ENABLE while (fgets(buf, sizeof(buf), stdin) != NULL) { if (buf[0] == '{' || isalpha(buf[0])) { gps_unpack(buf, &gpsdata); libgps_dump_state(&gpsdata); } } #endif } else if (gps_open(source.server, source.port, &collect) != 0) { (void)fprintf(stderr, "test_libgps: no gpsd running or network error: %d, %s\n", errno, gps_errstr(errno)); exit(EXIT_FAILURE); } else if (forwardmode) { (void)gps_send(&collect, fmsg); (void)gps_read(&collect); #ifdef SOCKET_EXPORT_ENABLE libgps_dump_state(&collect); #endif (void)gps_close(&collect); } else { int tty = isatty(0); if (tty) (void)fputs("This is the gpsd exerciser.\n", stdout); for (;;) { if (tty) (void)fputs("> ", stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) { if (tty) putchar('\n'); break; } collect.set = 0; (void)gps_send(&collect, buf); (void)gps_read(&collect); #ifdef SOCKET_EXPORT_ENABLE libgps_dump_state(&collect); #endif } (void)gps_close(&collect); } return 0; }
int gps_sock_read(struct gps_data_t *gpsdata) /* wait for and read data being streamed from the daemon */ { char *eol; ssize_t response_length; int status = -1; gpsdata->set &= ~PACKET_SET; for (eol = PRIVATE(gpsdata)->buffer; *eol != '\n' && eol < PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting; eol++) continue; if (*eol != '\n') eol = NULL; errno = 0; if (eol == NULL) { #ifndef USE_QT /* read data: return -1 if no data waiting or buffered, 0 otherwise */ status = (int)recv(gpsdata->gps_fd, PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting, sizeof(PRIVATE(gpsdata)->buffer) - PRIVATE(gpsdata)->waiting, 0); #else status = ((QTcpSocket *) (gpsdata->gps_fd))->read(PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting, sizeof(PRIVATE(gpsdata)->buffer) - PRIVATE(gpsdata)->waiting); #endif /* if we just received data from the socket, it's in the buffer */ if (status > -1) PRIVATE(gpsdata)->waiting += status; /* buffer is empty - implies no data was read */ if (PRIVATE(gpsdata)->waiting == 0) { /* * If we received 0 bytes, other side of socket is closing. * Return -1 as end-of-data indication. */ // cppcheck-suppress duplicateBranch if (status == 0) return -1; #ifndef USE_QT /* count transient errors as success, we'll retry later */ else if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) return 0; #endif /* hard error return of -1, pass it along */ else return -1; } /* there's buffered data waiting to be returned */ for (eol = PRIVATE(gpsdata)->buffer; *eol != '\n' && eol < PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting; eol++) continue; if (*eol != '\n') eol = NULL; if (eol == NULL) return 0; } assert(eol != NULL); *eol = '\0'; response_length = eol - PRIVATE(gpsdata)->buffer + 1; gpsdata->online = timestamp(); status = gps_unpack(PRIVATE(gpsdata)->buffer, gpsdata); memmove(PRIVATE(gpsdata)->buffer, PRIVATE(gpsdata)->buffer + response_length, PRIVATE(gpsdata)->waiting - response_length); PRIVATE(gpsdata)->waiting -= response_length; gpsdata->set |= PACKET_SET; return (status == 0) ? (int)response_length : status; }
int main(int argc, char *argv[]) { struct gps_data_t collect; char buf[BUFSIZ]; int option; bool batchmode = false; int debug = 0; (void)signal(SIGSEGV, onsig); (void)signal(SIGBUS, onsig); while ((option = getopt(argc, argv, "bhsD:?")) != -1) { switch (option) { case 'b': batchmode = true; break; case 's': (void) printf ("Sizes: fix=%zd gpsdata=%zd rtcm2=%zd rtcm3=%zd ais=%zd compass=%zd raw=%zd devices=%zd policy=%zd version=%zd, noise=%zd\n", sizeof(struct gps_fix_t), sizeof(struct gps_data_t), sizeof(struct rtcm2_t), sizeof(struct rtcm3_t), sizeof(struct ais_t), sizeof(struct attitude_t), sizeof(struct rawdata_t), sizeof(collect.devices), sizeof(struct policy_t), sizeof(struct version_t), sizeof(struct gst_t)); exit(EXIT_SUCCESS); case 'D': debug = atoi(optarg); break; case '?': case 'h': default: (void)fputs("usage: test_libgps [-b] [-D lvl] [-s]\n", stderr); exit(EXIT_FAILURE); } } gps_enable_debug(debug, stdout); if (batchmode) { while (fgets(buf, sizeof(buf), stdin) != NULL) { if (buf[0] == '{' || isalpha(buf[0])) { gps_unpack(buf, &gpsdata); libgps_dump_state(&gpsdata); } } } else if (gps_open(NULL, 0, &collect) <= 0) { (void)fputs("Daemon is not running.\n", stdout); exit(EXIT_FAILURE); } else if (optind < argc) { (void)strlcpy(buf, argv[optind], BUFSIZ); (void)strlcat(buf, "\n", BUFSIZ); (void)gps_send(&collect, buf); (void)gps_read(&collect); libgps_dump_state(&collect); (void)gps_close(&collect); } else { int tty = isatty(0); if (tty) (void)fputs("This is the gpsd exerciser.\n", stdout); for (;;) { if (tty) (void)fputs("> ", stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) { if (tty) putchar('\n'); break; } collect.set = 0; (void)gps_send(&collect, buf); (void)gps_read(&collect); libgps_dump_state(&collect); } (void)gps_close(&collect); } return 0; }