From 3816992ad8285d40eb1f8ab1338c84fcc1e911b6 Mon Sep 17 00:00:00 2001 From: Harsh Sharma Date: Mon, 29 Nov 2021 15:21:41 -0600 Subject: Fixed gps not updating on internal concentrator time difference being larger than 1.5. Added getting leap seconds from gpspipe --- libloragw/inc/loragw_gps.h | 7 ++++++ libloragw/src/loragw_gps.c | 53 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/libloragw/inc/loragw_gps.h b/libloragw/inc/loragw_gps.h index 94d1d2a..0714974 100644 --- a/libloragw/inc/loragw_gps.h +++ b/libloragw/inc/loragw_gps.h @@ -116,6 +116,13 @@ int lgw_gps_enable(struct gps_data_t *gpsdata, struct fixsource_t *source); */ int lgw_gps_disable(struct gps_data_t *gpsdata); +/** +@brief Get updated leap seconds + +@return success if the function was able to get the new leap seconds +*/ +int lgw_get_leap_seconds(); + /** @brief Parse messages coming from the GPS system (or other GNSS) diff --git a/libloragw/src/loragw_gps.c b/libloragw/src/loragw_gps.c index 329827e..68a65ac 100644 --- a/libloragw/src/loragw_gps.c +++ b/libloragw/src/loragw_gps.c @@ -89,6 +89,9 @@ static bool gps_lock_ok = false; static char gps_mod = 'N'; /* GPS mode (N no fix, A autonomous, D differential) */ static short gps_sat = 0; /* number of satellites used for fix */ +static uint32_t leap_seconds = 18; /* Adjustment that is applied to Coordinated Universal Time, + to accommodate the difference between precise time and imprecise observed solar time */ + /* -------------------------------------------------------------------------- */ /* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */ @@ -255,6 +258,14 @@ int lgw_gps_enable(struct gps_data_t *gpsdata, struct fixsource_t *source) { unsigned int flags = WATCH_ENABLE| WATCH_JSON; gpsd_source_spec(NULL, source); + /* Update leap seconds from gpspipe */ + if (lgw_get_leap_seconds() != LGW_GPS_SUCCESS) { + DEBUG_MSG("WARNING: Could not update leap seconds, using default value: %d\n", leap_seconds); + } else { + DEBUG_MSG("Updated leap seconds to: %d\n", leap_seconds); + } + + if (gps_open(source->server, source->port, gpsdata) != 0) { DEBUG_MSG("gpspipe: could not connect to gpsd %s:%s, %s(%d)\n", source->server, source->port, gps_errstr(errno), errno); @@ -293,6 +304,40 @@ int lgw_gps_disable(struct gps_data_t *gpsdata) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +int lgw_get_leap_seconds() { + + FILE *fp; + char path[1035]; + uint32_t result = 0; + /* Open the command for reading. */ + fp = popen("/usr/bin/gpspipe -w -n 4 | grep leapsec | jsparser --path leapseconds", "r"); + if (fp == NULL) { + DEBUG_MSG("ERROR: Failed to run command\n" ); + return LGW_GPS_ERROR; + } + + + if (fgets(path, sizeof(path), fp) == NULL) { + DEBUG_MSG("ERROR: Unable to get leap seconds\n"); + pclose(fp); + return LGW_GPS_ERROR; + } + + pclose(fp); + + result = atoi(path); + + if (result == 0) { + DEBUG_MSG("ERROR: Invalid leap second value\n"); + return LGW_GPS_ERROR; + } else { + leap_seconds = result; + return LGW_GPS_SUCCESS; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + enum gps_msg lgw_parse_ubx(const char *serial_buff, size_t buff_size, size_t *msg_size) { bool valid = 0; /* iTOW, fTOW and week validity */ unsigned int payload_length; @@ -599,11 +644,7 @@ int lgw_gps_sync(struct tref *ref, uint32_t count_us, struct timespec gps_time) slope = 0.0; } - if (cnt_diff > 1.5) { - update = true; - } - - update = (slope >= MINUS_10PPM && slope <= PLUS_10PPM); + update = ((slope >= MINUS_10PPM && slope <= PLUS_10PPM) || cnt_diff > 1.5); if (!calibrating && utc_diff < 10.0) { return LGW_GPS_ERROR; @@ -626,7 +667,7 @@ int lgw_gps_sync(struct tref *ref, uint32_t count_us, struct timespec gps_time) ref->utc.tv_sec = gps_time.tv_sec - timezone; ref->utc.tv_nsec = gps_time.tv_nsec; // ref->gps.tv_sec = gps_time.tv_sec; - ref->gps.tv_sec = gps_time.tv_sec + 18 - 315964800; + ref->gps.tv_sec = gps_time.tv_sec + leap_seconds - 315964800; ref->gps.tv_nsec = gps_time.tv_nsec; ref->xtal_err = slope; return LGW_GPS_SUCCESS; -- cgit v1.2.3