summaryrefslogtreecommitdiff
path: root/recipes-connectivity/lora/lora-gateway
diff options
context:
space:
mode:
authorJason Reiss <jreiss@multitech.com>2019-06-04 14:16:52 -0500
committerJason Reiss <jreiss@multitech.com>2019-06-04 14:16:52 -0500
commit1db3228526ff0a380a0170e21320fd8d0d345cbe (patch)
tree48a029daaeb581a8adc8436665c45ebb84010e6d /recipes-connectivity/lora/lora-gateway
parentb5a2ca08e91475eeaee33166d018f532e1c069f5 (diff)
downloadmeta-mlinux-1db3228526ff0a380a0170e21320fd8d0d345cbe.tar.gz
meta-mlinux-1db3228526ff0a380a0170e21320fd8d0d345cbe.tar.bz2
meta-mlinux-1db3228526ff0a380a0170e21320fd8d0d345cbe.zip
lora: fix gps time stamping and synchronization, add patch for PKF deduplication to be incorporated into recipe later
Diffstat (limited to 'recipes-connectivity/lora/lora-gateway')
-rw-r--r--recipes-connectivity/lora/lora-gateway/lora-gateway-gpsd.patch219
1 files changed, 192 insertions, 27 deletions
diff --git a/recipes-connectivity/lora/lora-gateway/lora-gateway-gpsd.patch b/recipes-connectivity/lora/lora-gateway/lora-gateway-gpsd.patch
index 471cd82..08d566c 100644
--- a/recipes-connectivity/lora/lora-gateway/lora-gateway-gpsd.patch
+++ b/recipes-connectivity/lora/lora-gateway/lora-gateway-gpsd.patch
@@ -73,10 +73,18 @@ index 6dbd30b..59b2d37 100644
/**
@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 c0e0ded..d3d1ca1 100644
+index c0e0ded..f4774be 100644
--- a/libloragw/src/loragw_gps.c
+++ b/libloragw/src/loragw_gps.c
-@@ -251,109 +251,22 @@ int str_chop(char *s, int buff_size, char separator, int *idx_ary, int max_idx)
+@@ -84,6 +84,7 @@ static double gps_mlo = 0.0; /* minutes of longitude */
+ static char gps_olo = 0; /* orientation (E-W) of longitude */
+ static short gps_alt = 0; /* altitude */
+ static bool gps_pos_ok = false;
++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 */
+@@ -251,109 +252,22 @@ int str_chop(char *s, int buff_size, char separator, int *idx_ary, int max_idx)
/* -------------------------------------------------------------------------- */
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
@@ -91,17 +99,27 @@ index c0e0ded..d3d1ca1 100644
- 0x01, 0x20, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, /* Enable NAV-TIMEGPS output on serial */
- 0x32, 0x94 }; /* Checksum */
- ssize_t num_written;
--
++int lgw_gps_enable(struct gps_data_t *gpsdata, struct fixsource_t *source) {
+
- /* check input parameters */
- CHECK_NULL(tty_path);
- CHECK_NULL(fd_ptr);
--
++ unsigned int flags;
++ fd_set fds;
++ flags = WATCH_ENABLE;
++ flags |= WATCH_RAW;
++ flags |= WATCH_NMEA;
++ gpsd_source_spec(NULL, source);
+
- /* open TTY device */
- gps_tty_dev = open(tty_path, O_RDWR | O_NOCTTY);
- if (gps_tty_dev <= 0) {
- DEBUG_MSG("ERROR: TTY PORT FAIL TO OPEN, CHECK PATH AND ACCESS RIGHTS\n");
-- return LGW_GPS_ERROR;
-- }
++ 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);
+ return LGW_GPS_ERROR;
+ }
- *fd_ptr = gps_tty_dev;
-
- /* manage the different GPS modules families */
@@ -115,7 +133,7 @@ index c0e0ded..d3d1ca1 100644
- /* see lgw_parse_ubx() function for details */
- DEBUG_MSG("WARNING: this version of GPS module may not be supported\n");
- }
--
+
- /* manage the target bitrate */
- if (target_brate != 0) {
- DEBUG_MSG("WARNING: target_brate parameter ignored for now\n"); // TODO
@@ -173,22 +191,10 @@ index c0e0ded..d3d1ca1 100644
- i = tcsetattr(gps_tty_dev, TCSANOW, &ttyopt);
- if (i != 0){
- DEBUG_MSG("ERROR: IMPOSSIBLE TO UPDATE TTY PORT CONFIGURATION\n");
-+int lgw_gps_enable(struct gps_data_t *gpsdata, struct fixsource_t *source) {
-+
-+ unsigned int flags;
-+ fd_set fds;
-+ flags = WATCH_ENABLE;
-+ flags |= WATCH_RAW;
-+ flags |= WATCH_NMEA;
-+ gpsd_source_spec(NULL, source);
-+
-+ 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);
- return LGW_GPS_ERROR;
- }
+- return LGW_GPS_ERROR;
+- }
- tcflush(gps_tty_dev, TCIOFLUSH);
-
+-
- /* Send UBX CFG NAV-TIMEGPS message to tell GPS module to output native GPS time */
- /* This is a binary message, serial port has to be properly configured to handle this */
- num_written = write (gps_tty_dev, ubx_cmd_timegps, UBX_MSG_NAVTIMEGPS_LEN);
@@ -199,7 +205,7 @@ index c0e0ded..d3d1ca1 100644
/* get timezone info */
tzset();
-@@ -368,20 +281,13 @@ int lgw_gps_enable(char *tty_path, char *gps_family, speed_t target_brate, int *
+@@ -368,20 +282,13 @@ int lgw_gps_enable(char *tty_path, char *gps_family, speed_t target_brate, int *
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -225,7 +231,44 @@ index c0e0ded..d3d1ca1 100644
return LGW_GPS_ERROR;
}
-@@ -526,7 +432,7 @@ enum gps_msg lgw_parse_nmea(const char *serial_buff, int buff_size) {
+@@ -457,7 +364,8 @@ enum gps_msg lgw_parse_ubx(const char *serial_buff, size_t buff_size, size_t *ms
+ gps_week = (uint8_t)serial_buff[14];
+ gps_week |= (uint8_t)serial_buff[15] << 8; /* GPS week number */
+
+- gps_time_ok = true;
++
++
+ #if 0
+ /* For debug */
+ {
+@@ -472,11 +380,24 @@ enum gps_msg lgw_parse_ubx(const char *serial_buff, size_t buff_size, size_t *ms
+ printf(" GPS time = %02d:%02d:%02d\n", ubx_gps_hou, ubx_gps_min, ubx_gps_sec);
+ }
+ #endif
+- } else { /* valid */
++ if (gps_lock_ok)
++ gps_time_ok = true;
++
++ return UBX_NAV_TIMEGPS;
++ } else {
+ gps_time_ok = false;
++ return INVALID;
++ }
++ } else if ((serial_buff[2] == 0x01) && (serial_buff[3] == 0x04)) {
++ if (serial_buff[10] == 0x0F && serial_buff[11] == 0x27
++ && serial_buff[10] == 0x0F && serial_buff[11] == 0x27
++ && serial_buff[10] == 0x0F && serial_buff[11] == 0x27
++ && serial_buff[10] == 0x0F && serial_buff[11] == 0x27) {
++ gps_time_ok = false;
++ gps_lock_ok = false;
+ }
+
+- return UBX_NAV_TIMEGPS;
++ return UBX_NAV_TIMEUTC;
+ } else if ((serial_buff[2] == 0x05) && (serial_buff[3] == 0x00)) {
+ DEBUG_MSG("NOTE: UBX ACK-NAK received\n");
+ return IGNORED;
+@@ -526,7 +447,7 @@ enum gps_msg lgw_parse_nmea(const char *serial_buff, int buff_size) {
} else if (!validate_nmea_checksum(serial_buff, buff_size)) {
DEBUG_MSG("Warning: invalid NMEA sentence (bad checksum)\n");
return INVALID;
@@ -234,7 +277,7 @@ index c0e0ded..d3d1ca1 100644
/*
NMEA sentence format: $xxRMC,time,status,lat,NS,long,EW,spd,cog,date,mv,mvEW,posMode*cs<CR><LF>
Valid fix: $GPRMC,083559.34,A,4717.11437,N,00833.91522,E,0.004,77.52,091202,,,A*00
-@@ -535,19 +441,19 @@ enum gps_msg lgw_parse_nmea(const char *serial_buff, int buff_size) {
+@@ -535,33 +456,32 @@ enum gps_msg lgw_parse_nmea(const char *serial_buff, int buff_size) {
memcpy(parser_buf, serial_buff, buff_size);
parser_buf[buff_size] = '\0';
nb_fields = str_chop(parser_buf, buff_size, ',', str_index, ARRAY_SIZE(str_index));
@@ -255,9 +298,17 @@ index c0e0ded..d3d1ca1 100644
- if ((i == 4) && (j == 3)) {
+ if ((i == 3) && (j == 3)) {
if ((gps_mod == 'A') || (gps_mod == 'D')) {
- gps_time_ok = true;
+- gps_time_ok = true;
++ gps_lock_ok = true;
DEBUG_MSG("Note: Valid RMC sentence, GPS locked, date: 20%02d-%02d-%02dT%02d:%02d:%06.3fZ\n", gps_yea, gps_mon, gps_day, gps_hou, gps_min, gps_fra + (float)gps_sec);
-@@ -561,7 +467,7 @@ enum gps_msg lgw_parse_nmea(const char *serial_buff, int buff_size) {
+ } else {
+- gps_time_ok = false;
++ gps_lock_ok = false;
+ DEBUG_MSG("Note: Valid RMC sentence, no satellite fix, estimated date: 20%02d-%02d-%02dT%02d:%02d:%06.3fZ\n", gps_yea, gps_mon, gps_day, gps_hou, gps_min, gps_fra + (float)gps_sec);
+ }
+ } else {
+ /* could not get a valid hour AND date */
+- gps_time_ok = false;
DEBUG_MSG("Note: Valid RMC sentence, mode %c, no date\n", gps_mod);
}
return NMEA_RMC;
@@ -266,6 +317,120 @@ index c0e0ded..d3d1ca1 100644
/*
NMEA sentence format: $xxGGA,time,lat,NS,long,EW,quality,numSV,HDOP,alt,M,sep,M,diffAge,diffStation*cs<CR><LF>
Valid fix: $GPGGA,092725.00,4717.11399,N,00833.91590,E,1,08,1.01,499.6,M,48.0,M,,*5B
+@@ -587,6 +507,8 @@ enum gps_msg lgw_parse_nmea(const char *serial_buff, int buff_size) {
+ } else {
+ /* could not get a valid latitude, longitude AND altitude */
+ gps_pos_ok = false;
++ gps_time_ok = false;
++ gps_lock_ok = false;
+ DEBUG_MSG("Note: Valid GGA sentence, %d sat, no coordinates\n", gps_sat);
+ }
+ return NMEA_GGA;
+@@ -662,72 +580,60 @@ int lgw_gps_get(struct timespec *utc, struct timespec *gps_time, struct coord_s
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+ int lgw_gps_sync(struct tref *ref, uint32_t count_us, struct timespec utc, struct timespec gps_time) {
++ bool update = false;
+ double cnt_diff; /* internal concentrator time difference (in seconds) */
+ double utc_diff; /* UTC time difference (in seconds) */
+- double slope; /* time slope between new reference and old reference (for sanity check) */
+-
+- bool aber_n0; /* is the update value for synchronization aberrant or not ? */
+- static bool aber_min1 = false; /* keep track of whether value at sync N-1 was aberrant or not */
+- static bool aber_min2 = false; /* keep track of whether value at sync N-2 was aberrant or not */
++ double slope = 1.0; /* time slope between new reference and old reference (for sanity check) */
++ static bool calibrating = true;
+
+ CHECK_NULL(ref);
+
+ /* calculate the slope */
+
+- cnt_diff = (double)(count_us - ref->count_us) / (double)(TS_CPS); /* uncorrected by xtal_err */
+- utc_diff = (double)(utc.tv_sec - (ref->utc).tv_sec) + (1E-9 * (double)(utc.tv_nsec - (ref->utc).tv_nsec));
++ if (ref->systime != 0) {
++
++ cnt_diff = (double)(count_us - ref->count_us) / (double)(TS_CPS); /* uncorrected by xtal_err */
++ utc_diff = (double)(utc.tv_sec - (ref->utc).tv_sec) + (1E-9 * (double)(utc.tv_nsec - (ref->utc).tv_nsec));
+
+- /* detect aberrant points by measuring if slope limits are exceeded */
+- if (utc_diff != 0) { // prevent divide by zero
+- slope = cnt_diff/utc_diff;
+- if ((slope > PLUS_10PPM) || (slope < MINUS_10PPM)) {
+- DEBUG_MSG("Warning: correction range exceeded\n");
+- aber_n0 = true;
++ if (cnt_diff != 0 && utc_diff != 0) { // prevent divide by zero
++ slope = cnt_diff/utc_diff;
+ } else {
+- aber_n0 = false;
++ slope = 0.0;
++ }
++
++ if (gps_lock_ok && gps_time_ok && cnt_diff > 1.5) {
++ update = true;
++ }
++
++ update = (slope >= MINUS_10PPM && slope <= PLUS_10PPM);
++
++ if (!calibrating && utc_diff < 10.0) {
++ return LGW_GPS_ERROR;
+ }
++
++ if (calibrating && !update && utc_diff > 1.5) {
++ update = true;
++ } else if (update) {
++ calibrating = false;
++ }
++
+ } else {
+- DEBUG_MSG("Warning: aberrant UTC value for synchronization\n");
+- aber_n0 = true;
++ update = true;
++ slope = 0.0;
+ }
+
+- /* watch if the 3 latest sync point were aberrant or not */
+- if (aber_n0 == false) {
+- /* value no aberrant -> sync with smoothed slope */
+- ref->systime = time(NULL);
++ if (update || calibrating) {
++ ref->systime = time(NULL);
+ ref->count_us = count_us;
+ ref->utc.tv_sec = utc.tv_sec;
+ ref->utc.tv_nsec = utc.tv_nsec;
+ ref->gps.tv_sec = gps_time.tv_sec;
+ ref->gps.tv_nsec = gps_time.tv_nsec;
+ ref->xtal_err = slope;
+- aber_min2 = aber_min1;
+- aber_min1 = aber_n0;
+ return LGW_GPS_SUCCESS;
+- } else if (aber_n0 && aber_min1 && aber_min2) {
+- /* 3 successive aberrant values -> sync reset (keep xtal_err) */
+- ref->systime = time(NULL);
+- ref->count_us = count_us;
+- ref->utc.tv_sec = utc.tv_sec;
+- ref->utc.tv_nsec = utc.tv_nsec;
+- ref->gps.tv_sec = gps_time.tv_sec;
+- ref->gps.tv_nsec = gps_time.tv_nsec;
+- /* reset xtal_err only if the present value is out of range */
+- if ((ref->xtal_err > PLUS_10PPM) || (ref->xtal_err < MINUS_10PPM)) {
+- ref->xtal_err = 1.0;
+- }
+- DEBUG_MSG("Warning: 3 successive aberrant sync attempts, sync reset\n");
+- aber_min2 = aber_min1;
+- aber_min1 = aber_n0;
+- return LGW_GPS_SUCCESS;
+- } else {
+- /* only 1 or 2 successive aberrant values -> ignore and return an error */
+- aber_min2 = aber_min1;
+- aber_min1 = aber_n0;
+- return LGW_GPS_ERROR;
+ }
+
+- return LGW_GPS_SUCCESS;
++ return LGW_GPS_ERROR;
+ }
+
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
diff --git a/libloragw/tst/test_loragw_gps.c b/libloragw/tst/test_loragw_gps.c
index a4164a3..e4b1546 100644
--- a/libloragw/tst/test_loragw_gps.c