X-Git-Url: http://git.openwrt.org/?p=project%2Fugps.git;a=blobdiff_plain;f=nmea.c;h=42be71eec1d0829d8d660cf554acb38e12589d7b;hp=fecdef8d55185c5f3791d6fb9012db14e15ac25b;hb=07528d43f9bccf22dfb16ee03083bb46dd53dfcf;hpb=6924497ce8fcf3b4b3ecac067bf7c503a628077b diff --git a/nmea.c b/nmea.c index fecdef8..42be71e 100644 --- a/nmea.c +++ b/nmea.c @@ -16,8 +16,9 @@ * Copyright (C) 2014 John Crispin */ -#define _BSD_SOURCE +#define _DEFAULT_SOURCE #define _XOPEN_SOURCE +#define _BSD_SOURCE #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include #include @@ -41,7 +43,7 @@ #include "nmea.h" #define MAX_NMEA_PARAM 20 -#define MAX_TIME_OFFSET 2 +#define MAX_TIME_OFFSET 5 #define MAX_BAD_TIME 3 struct nmea_param { @@ -50,7 +52,7 @@ struct nmea_param { } nmea_params[MAX_NMEA_PARAM]; static int nmea_bad_time; -char longitude[32] = { 0 }, latitude[32] = { 0 }, course[16] = { 0 }, speed[16] = { 0 }, elivation[16] = { 0 }; +char longitude[33] = { 0 }, latitude[33] = { 0 }, course[17] = { 0 }, speed[17] = { 0 }, elevation[17] = { 0 }; int gps_valid = 0; static void @@ -80,31 +82,38 @@ nmea_rmc_cb(void) memset(&tm, 0, sizeof(tm)); tm.tm_isdst = 1; - if (!strptime(nmea_params[1].str, "%H%M%S", &tm)) - ERROR("failed to parse time\n"); - else if (!strptime(nmea_params[9].str, "%d%m%y", &tm)) - ERROR("failed to parse date\n"); + if (sscanf(nmea_params[1].str, "%02d%02d%02d", + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 3) { + ERROR("failed to parse time '%s'\n", nmea_params[1].str); + } + else if (sscanf(nmea_params[9].str, "%02d%02d%02d", + &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 3) { + ERROR("failed to parse date '%s'\n", nmea_params[9].str); + } else { - /* is there a libc api for the tz adjustment ? */ - struct timeval tv = { mktime(&tm), 0 }; - struct timeval cur; + tm.tm_year += 100; /* year starts with 1900 */ + tm.tm_mon -= 1; /* month starts with 0 */ - strftime(tmp, 256, "%D %02H:%02M:%02S", &tm); + strftime(tmp, 256, "%Y-%m-%dT%H:%M:%S", &tm); DEBUG(3, "date: %s UTC\n", tmp); - tv.tv_sec -= timezone; - if (daylight) - tv.tv_sec += 3600; - - gettimeofday(&cur, NULL); - - if (abs(cur.tv_sec - tv.tv_sec) > MAX_TIME_OFFSET) { - if (++nmea_bad_time > MAX_BAD_TIME) { - LOG("system time differs from GPS time by more than %d seconds. Using %s UTC as the new time\n", MAX_TIME_OFFSET, tmp); - settimeofday(&tv, NULL); + if (adjust_clock) { + time_t sec = timegm(&tm); + struct timeval tv = { 0 }; + struct timeval cur; + + gettimeofday(&cur, NULL); + + if ((sec < 0) || (abs(cur.tv_sec - tv.tv_sec) > MAX_TIME_OFFSET)) { + tv.tv_sec = sec; + if (++nmea_bad_time > MAX_BAD_TIME) { + LOG("system time differs from GPS time by more than %d seconds. Using %s UTC as the new time\n", MAX_TIME_OFFSET, tmp); + /* only set datetime if specified by command line argument! */ + settimeofday(&tv, NULL); + } + } else { + nmea_bad_time = 0; } - } else { - nmea_bad_time = 0; } } @@ -112,42 +121,27 @@ nmea_rmc_cb(void) ERROR("lat/lng have invalid string length %d<9, %d<10\n", strlen(nmea_params[3].str), strlen(nmea_params[5].str)); } else { - int latd, latm, lats; - int lngd, lngm, lngs; - float flats, flngs; - DEBUG(4, "position: %s, %s\n", - nmea_params[3].str, nmea_params[5].str); - latm = atoi(&nmea_params[3].str[2]); - nmea_params[3].str[2] = '\0'; - latd = atoi(nmea_params[3].str); - lats = atoi(&nmea_params[3].str[5]); - if (*nmea_params[4].str != 'N') - latm *= -1; - - lngm = atoi(&nmea_params[5].str[3]); - nmea_params[5].str[3] = '\0'; - lngd = atoi(nmea_params[5].str); - lngs = atoi(&nmea_params[5].str[6]); - if (*nmea_params[6].str != 'E') - lngm *= -1; - - flats = lats; - flats *= 60; - flats /= 10000; - - flngs = lngs; - flngs *= 60; - flngs /= 10000; - -#define ms_to_deg(x, y) (((x * 10000) + y) / 60) - - DEBUG(4, "position: %d°%d.%04d, %d°%d.%04d\n", - latd, latm, lats, lngd, lngm, lngs); - DEBUG(4, "position: %d°%d'%.1f\" %d°%d'%.1f\"\n", - latd, latm, flats, lngd, lngm, flngs); - - snprintf(latitude, sizeof(latitude), "%d.%04d", latd, ms_to_deg(latm, lats)); - snprintf(longitude, sizeof(longitude), "%d.%04d", lngd, ms_to_deg(lngm, lngs)); + float minutes; + float degrees; + float lat = strtof(nmea_params[3].str, NULL); + float lon = strtof(nmea_params[5].str, NULL); + + degrees = floor(lat / 100.0); + minutes = lat - (degrees * 100.0); + lat = degrees + minutes / 60.0; + + degrees = floor(lon / 100.0); + minutes = lon - (degrees * 100.0); + lon = degrees + minutes / 60.0; + + if (*nmea_params[4].str == 'S') + lat *= -1.0; + if (*nmea_params[6].str == 'W') + lon *= -1.0; + + snprintf(latitude, sizeof(latitude), "%f", lat); + snprintf(longitude, sizeof(longitude), "%f", lon); + DEBUG(3, "position: %s %s\n", latitude, longitude); gps_timestamp(); } @@ -158,8 +152,8 @@ nmea_gga_cb(void) { if (!gps_valid) return; - strncpy(elivation, nmea_params[9].str, sizeof(elivation)); - DEBUG(4, "height: %s\n", elivation); + strncpy(elevation, nmea_params[9].str, sizeof(elevation)); + DEBUG(4, "height: %s\n", elevation); } static void @@ -168,7 +162,7 @@ nmea_vtg_cb(void) if (!gps_valid) return; strncpy(course, nmea_params[1].str, sizeof(course)); - strncpy(speed, nmea_params[6].str, sizeof(speed)); + strncpy(speed, nmea_params[7].str, sizeof(speed)); DEBUG(4, "course: %s\n", course); DEBUG(4, "speed: %s\n", speed); }