/* * Debug output function. Spit out message to stderr only if * the current debug output level is >= the given level. */ void gps_printf(gps_handle gps, int level, const char *fmt, ...) { if (gps_debug(gps) >= level) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } }
/* * Send a buffer containing layer 3 data using garmin layer 2 framing * to the device indicated by the gps_handle. The first byte of the data * is assumed to be the garmin record type. * * returns 1 if data sent and acknowledged, -1 if any errors occured. */ int gps_send(gps_handle gps, const u_char *buf, int cnt) { int ok = -1; size_t len = (size_t) cnt; u_char *data = gps_frame(buf, &len); if (data) { if (gps_debug(gps) >= 4) gps_display('}', buf, cnt); ok = gps_write(gps, data, len); free(data); } return ok; }
/* * send a frame and wait for an ack/nak. If nak'd re-send the frame. * Return 1 if all ok, -1 if frame can not be sent/is not acknowledged, * or 0 if frame is always nak'd. */ int gps_send_wait(gps_handle gps, const u_char *buf, int cnt, int timeout) { int retries = 3; int ok = -1; size_t len = (size_t) cnt; u_char *data = gps_frame(buf, &len); if (data) { if (gps_debug(gps) >= 4) gps_display('}', buf, cnt); do { if (gps_write(gps, data, len) == 1) ok = gps_wait(gps, *buf, timeout); } while (ok == 0 && retries--); } if (data) free(data); return ok; }
int gps_recv(gps_handle gps, int to, u_char *buf, int * cnt) { int dle_seen; int etx_seen; int sum; int len; int rlen = -1; u_char *ptr; int stat; /* sync to the first DLE to come down the pike. */ while (1) { do { stat = gps_read(gps, buf, to); } while ((stat == 1) && (*buf != dle)); /* We have a timeout or a frame (or possibly the middle or end of a packet). If a timeout return a -1, otherwise prepare to receive the rest of the frame */ switch (stat) { case -1: gps_printf(gps, 2, "%s: sync error\n", __func__); return -1; case 0: gps_printf(gps, 2, "%s: timeout\n", __func__); return 0; case 1: break; } /* start receiving characters into buf. An end of buffer or a DLE ETX sequence will terminate the reception. Each read is given a READ_TO second timeout -- if we time out assume the gps died and return an error. */ ptr = buf; dle_seen = 0; etx_seen = 0; sum = 0; len = 0; do { stat = gps_read(gps, ptr, READ_TO); if (stat != 1) { gps_printf(gps, 2, "%s: frame error\n", __func__); return -1; } if (dle_seen) { if (*ptr == etx) { etx_seen = 1; break; } dle_seen = 0; } else { if (*ptr == dle) { dle_seen = 1; continue; } } if ((rlen == -1) && (len == 1)) { /* this is the length byte, add it to the checksum and save it, but do not keep it in the buffer */ sum += *ptr; rlen = *ptr; } else { sum += *ptr++; len += 1; } } while (len < *cnt); if (etx_seen) { /* subtract one from the length as we don't count the checksum. */ len -= 1; /* warn if the length is not the expected value. Add in the packet type to the expected length. */ rlen += 1; if (rlen != len) gps_printf(gps, 1, "%s: bad frame len, " "%d expected, %d received\n", __func__, rlen, len); if ((sum & 0xff) == 0) { /* good checksum, update len rcvd and return */ *cnt = len; if (gps_debug(gps) >= 4) gps_display('{', buf, len); return 1; } else { /* bad checksum -- try again */ if (gps_debug(gps) >= 4) gps_display('!', buf, len); return -1; } } else { /* frame too large, return error */ gps_printf(gps, 1, "%s: frame too large for %d byte buffer\n", __func__, *cnt); return -1; } } }
int main(int argc, char *argv[]) { int opt, intval = 15; char temp_str[STR_SIZE] = {0}; int fd, nread, i = 0, j = 0, status = 0; char buf[RD_SIZE]; char buf1[RD_SIZE] = {0}; char *dev_path = "/dev/ttyAMA2"; char *dev_data = "/tmp/.gps.log"; char *logfile = (char*)0; struct timeval tv_begin, tv_end; int tv_intval; while ((opt = getopt(argc,argv,"t:d:l:p:h")) != -1) { switch (opt) { case 'h': printf("rgps [-d /dev/ttyAMA2] [-t interval] [-l logpath]\n"); printf(" -h (get help)\n"); printf(" -d [gps_device or gps_log] (tty device or nmea file)\n"); printf(" -t 15 (report interval 5~300 sec)\n"); printf(" -l /tmp/gps.log (log file for gps)\n"); printf(" -p /tmp/.gps/ (log path for gps)\n"); return 0; case 'd': dev_path = optarg; break; case 'l': logfile = optarg; break; case 'p': if (optarg != NULL) logpath = optarg; break; case 't': intval = strtoul(optarg, NULL, 10); if ((intval < 5)||(intval > 300)) { printf(" -t 15 (report interval 5~300 sec)\n"); intval = 15; } break; default: break; } } /* Log file. */ if (logfile != (char*)0) { logfp = fopen(logfile, "a"); if (logfp == (FILE*)0) { syslog(LOG_CRIT, "%s - %m", logfile); perror(logfile); exit(1); } if (logfile[0] != '/') { syslog( LOG_WARNING, "logfile is not an absolute path, you may not be able to re-open it" ); (void) fprintf( stderr, "%s: logfile is not an absolute path, you may not be able to re-open it\n", argv[0] ); } } sprintf(temp_str, "mkdir -p %s", logpath); system(temp_str); printf("\n GPS positioning ...\n"); memset(temp_str, 0, sizeof(temp_str)); sprintf(temp_str, "head -n 30 %s > %s ; cp %s %s", dev_path, dev_data, dev_data, logpath); while(1) { printf("\n GPS waiting ...\n"); flag_GPGGA = 0; flag_GPRMC = 0; gettimeofday(&tv_begin, NULL); do { printf("\n GPS reading ...\n"); system(temp_str); fd = open(dev_data, O_RDONLY); if (fd == -1) { printf("open dev %s fail !!\n", dev_data); exit(1); } memset(buf, 0, RD_SIZE); memset(buf1, 0, RD_SIZE); nread = read(fd, buf, RD_SIZE-1); close(fd); if (nread > 0) { printf("\n GPS DATALen=%d\n", nread); buf[nread] = '\0'; i = 0; j = 0; //printf("%s %d\n\n", buf, nread); while (nread > 1) { buf1[j] = buf[i]; i++; j++; if ('\n' == buf[i]) { buf1[j] = '\0'; //printf( "\n\n\n-----%d----------buf1 %s\n", nread, buf1); print_gpsinfo(buf1); memset(buf1, 0, RD_SIZE); j = 0; i ++; } nread --; } if ((1 == flag_GPGGA)&&(1 == flag_GPRMC)) { status = gps_report(1); gps_debug(status); break; } } else printf("\n read fail %d\n", nread); gettimeofday(&tv_end, NULL); tv_intval = tv_end.tv_sec - tv_begin.tv_sec; printf("begin:%d, end:%d, interval:%d\n", tv_begin.tv_sec, tv_end.tv_sec, tv_intval); if (tv_intval > 3) { status = gps_report(0); gps_debug(status); break; } } while ((1 != flag_GPGGA)||(1 != flag_GPRMC)); printf("\n GPS closeing ...\n"); sleep(intval); } if (logfp != (FILE*)0) fclose(logfp); return 0; }