summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Miermont <smiermont@semtech.com>2014-01-27 12:04:34 +0100
committerSylvain Miermont <smiermont@semtech.com>2014-01-27 12:04:34 +0100
commitf835eac31780cf7da5b69ae6bd4f57edefa45947 (patch)
treef0c56804db0fb564538d762e1f470d50442da152
parentf9203f1a4a9b635cbe96670ed5a5e5309bb10697 (diff)
downloadlora_gateway-f835eac31780cf7da5b69ae6bd4f57edefa45947.tar.gz
lora_gateway-f835eac31780cf7da5b69ae6bd4f57edefa45947.tar.bz2
lora_gateway-f835eac31780cf7da5b69ae6bd4f57edefa45947.zip
Fixed 'floating point exception' crash when concentrator returned a packet with SF=0 (CRC error on Lora header).v1.2.1
Fixed buggy timezone handling HAL does not return NaN anymore for SNR and RSSI if measurements are not available (return -128).
-rw-r--r--libloragw/VERSION2
-rw-r--r--libloragw/doc/CHANGELOG.TXT6
-rw-r--r--libloragw/src/loragw_gps.c29
-rw-r--r--libloragw/src/loragw_hal.c74
-rw-r--r--loragw_pkt_logger/src/loragw_pkt_logger.c18
5 files changed, 74 insertions, 55 deletions
diff --git a/libloragw/VERSION b/libloragw/VERSION
index b44ab5c..fff109c 100644
--- a/libloragw/VERSION
+++ b/libloragw/VERSION
@@ -1,5 +1,5 @@
/* Software library version: */
-#define VERSION_LIBRARY "1.2.0"
+#define VERSION_LIBRARY "1.2.1"
/* API version */
#define VERSION_API "1"
diff --git a/libloragw/doc/CHANGELOG.TXT b/libloragw/doc/CHANGELOG.TXT
index bdaab2d..9402573 100644
--- a/libloragw/doc/CHANGELOG.TXT
+++ b/libloragw/doc/CHANGELOG.TXT
@@ -1,6 +1,12 @@
Lora Gateway HAL changelog
==========================
+ v1.2.1
+---------------------
+
+ * Fixed 'floating point exception' crash when concentrator returned a packet with SF=0 (CRC error on Lora header)
+ * Fixed buggy timezone handling
+
v1.2.0
---------------------
diff --git a/libloragw/src/loragw_gps.c b/libloragw/src/loragw_gps.c
index 84db3b8..a5f8707 100644
--- a/libloragw/src/loragw_gps.c
+++ b/libloragw/src/loragw_gps.c
@@ -53,6 +53,7 @@ Maintainer: Sylvain Miermont
#define DEBUG_ARRAY(a,b,c) for(a=0;a!=0;){}
#define CHECK_NULL(a) if(a==NULL){return LGW_GPS_ERROR;}
#endif
+#define TRACE() fprintf(stderr, "@ %s %d\n", __FUNCTION__, __LINE__);
/* -------------------------------------------------------------------------- */
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
@@ -306,6 +307,9 @@ int lgw_gps_enable(char *tty_path, char *gps_familly, speed_t target_brate, int
}
tcflush(gps_tty_dev, TCIOFLUSH);
+ /* get timezone info */
+ tzset();
+
/* initialize global variables */
gps_time_ok = false;
gps_pos_ok = false;
@@ -429,7 +433,7 @@ int lgw_gps_get(struct timespec *utc, struct coord_s *loc, struct coord_s *err)
x.tm_hour = gps_hou;
x.tm_min = gps_min;
x.tm_sec = gps_sec;
- y = mktime(&x);
+ y = mktime(&x) - timezone; /* need to substract timezone bc mktime assumes time vector is local time */
if (y == (time_t)(-1)) {
DEBUG_MSG("ERROR: FAILED TO CONVERT BROKEN-DOWN TIME\n");
return LGW_GPS_ERROR;
@@ -470,20 +474,21 @@ int lgw_gps_sync(struct tref *ref, uint32_t count_us, struct timespec utc) {
CHECK_NULL(ref);
/* calculate the slope */
- cnt_diff = (count_us - ref->count_us) / TS_CPS; /* uncorrected by xtal_err */
- utc_diff = (utc.tv_sec - (ref->utc).tv_sec) + 1E-9 * (utc.tv_nsec - (ref->utc).tv_nsec);
- if (utc_diff == 0.0) { // prevent divide by zero
- DEBUG_MSG("ERROR: ATTEMPT TO DIVIDE BY ZERO\n");
- return LGW_GPS_ERROR;
- }
+ 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 */
- slope = cnt_diff/utc_diff;
- if ((slope > PLUS_10PPM) || (slope < MINUS_10PPM)) {
- DEBUG_MSG("Warning: correction range exceeded\n");
- aber_n0 = true;
+ 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;
+ } else {
+ aber_n0 = false;
+ }
} else {
- aber_n0 = false;
+ DEBUG_MSG("Warning: aberrant UTC value for synchronization\n");
+ aber_n0 = true;
}
/* watch if the 3 latest sync point were aberrant or not */
diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c
index 4319d5e..3ab1cb5 100644
--- a/libloragw/src/loragw_hal.c
+++ b/libloragw/src/loragw_hal.c
@@ -20,7 +20,6 @@ Maintainer: Sylvain Miermont
#include <stdint.h> /* C99 types */
#include <stdbool.h> /* bool type */
#include <stdio.h> /* printf fprintf */
-#include <math.h> /* NaN */
#include <string.h> /* memcpy */
#include "loragw_reg.h"
@@ -45,6 +44,7 @@ Maintainer: Sylvain Miermont
#define IF_HZ_TO_REG(f) (f << 5)/15625
#define SET_PPM_ON(bw,dr) (((bw == BW_125KHZ) && ((dr == DR_LORA_SF11) || (dr == DR_LORA_SF12))) || ((bw == BW_250KHZ) && (dr == DR_LORA_SF12)))
+#define TRACE() fprintf(stderr, "@ %s %d\n", __FUNCTION__, __LINE__);
/* -------------------------------------------------------------------------- */
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
@@ -763,13 +763,13 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) {
int nb_pkt_fetch; /* loop variable and return value */
struct lgw_pkt_rx_s *p; /* pointer to the current structure in the struct array */
uint8_t buff[255+RX_METADATA_NB]; /* buffer to store the result of SPI read bursts */
- int sz; /* size of the payload, uses to address metadata */
+ unsigned sz; /* size of the payload, uses to address metadata */
int ifmod; /* type of if_chain/modem a packet was received by */
int stat_fifo; /* the packet status as indicated in the FIFO */
uint32_t raw_timestamp; /* timestamp when internal 'RX finished' was triggered */
+ uint32_t delay_x, delay_y, delay_z; /* temporary variable for timestamp offset calculation */
uint32_t timestamp_correction; /* correction to account for processing delay */
- uint8_t sf, cr, bw; /* used to calculate timestamp correction */
- uint8_t crc_en, ppm; /* used to calculate timestamp correction */
+ uint32_t sf, cr, bw_pow, crc_en, ppm; /* used to calculate timestamp correction */
/* check if the gateway is running */
if (lgw_is_started == false) {
@@ -864,41 +864,51 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) {
default: p->coderate = CR_UNDEFINED;
}
- /* timestamp correction code */
+ /* determine if 'PPM mode' is on, needed for timestamp correction */
+ if (SET_PPM_ON(p->bandwidth,p->datarate)) {
+ ppm = 1;
+ } else {
+ ppm = 0;
+ }
+
+ /* timestamp correction code, base delay */
if (ifmod == IF_LORA_STD) { /* if packet was received on the stand-alone lora modem */
switch (lora_rx_bw) {
case BW_125KHZ:
- timestamp_correction = 64;
- bw = 1;
+ delay_x = 64;
+ bw_pow = 1;
break;
case BW_250KHZ:
- timestamp_correction = 32;
- bw = 2;
+ delay_x = 32;
+ bw_pow = 2;
break;
case BW_500KHZ:
- timestamp_correction = 16;
- bw = 4;
+ delay_x = 16;
+ bw_pow = 4;
break;
default:
DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d IN SWITCH STATEMENT\n", p->bandwidth);
- timestamp_correction = 0;
- bw = 0;
+ delay_x = 0;
+ bw_pow = 0;
}
} else { /* packet was received on one of the sensor channels = 125kHz */
- timestamp_correction = 114;
- bw = 1;
+ delay_x = 114;
+ bw_pow = 1;
}
- if (SET_PPM_ON(p->bandwidth,p->datarate)) {
- ppm = 1;
- } else {
- ppm = 0;
- }
- if ((2*(sz + 2*crc_en) - sf +7) <= 0) { /* payload fits entirely in first 8 symbols */
- timestamp_correction += (((1<<(sf-1)) * (sf+1)) + (3*(1<<(sf-4))))/bw;
- timestamp_correction += 32 * (2*(sz+2*crc_en) + 5)/bw;
+
+ /* timestamp correction code, variable delay */
+ if ((sf >= 6) && (sf <= 12) && (bw_pow > 0)) {
+ if ((2*(sz + 2*crc_en) - (sf-7)) <= 0) { /* payload fits entirely in first 8 symbols */
+ delay_y = ( ((1<<(sf-1)) * (sf+1)) + (3 * (1<<(sf-4))) ) / bw_pow;
+ delay_z = 32 * (2*(sz+2*crc_en) + 5) / bw_pow;
+ } else {
+ delay_y = ( ((1<<(sf-1)) * (sf+1)) + ((4 - ppm) * (1<<(sf-4))) ) / bw_pow;
+ delay_z = (16 + 4*cr) * (((2*(sz+2*crc_en)-sf+6) % (sf - 2*ppm)) + 1) / bw_pow;
+ }
+ timestamp_correction = delay_x + delay_y + delay_z;
} else {
- timestamp_correction += (((1<<(sf-1)) * (sf+1)) + ((4.0-ppm)/4.0*(1<<(sf-2))))/bw;
- timestamp_correction += (16 + 4*cr) * (((2*(sz+2*crc_en)-sf + 6) % (sf-2*ppm) +1) / bw);
+ timestamp_correction = 0;
+ DEBUG_MSG("WARNING: invalid packet, no timestamp correction\n");
}
} else if (ifmod == IF_FSK_STD) {
DEBUG_MSG("Note: FSK packet\n");
@@ -910,9 +920,9 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) {
}
p->modulation = MOD_FSK;
p->rssi = (RSSI_OFFSET_FSK + (float)buff[sz+5])/RSSI_SLOPE_FSK;
- p->snr = NAN;
- p->snr_min = NAN;
- p->snr_max = NAN;
+ p->snr = -128.0;
+ p->snr_min = -128.0;
+ p->snr_max = -128.0;
p->bandwidth = fsk_rx_bw;
p->datarate = fsk_rx_dr;
p->coderate = CR_UNDEFINED;
@@ -921,10 +931,10 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) {
DEBUG_MSG("ERROR: UNEXPECTED PACKET ORIGIN\n");
p->status = STAT_UNDEFINED;
p->modulation = MOD_UNDEFINED;
- p->rssi = NAN;
- p->snr = NAN;
- p->snr_min = NAN;
- p->snr_max = NAN;
+ p->rssi = -128.0;
+ p->snr = -128.0;
+ p->snr_min = -128.0;
+ p->snr_max = -128.0;
p->bandwidth = BW_UNDEFINED;
p->datarate = DR_UNDEFINED;
p->coderate = CR_UNDEFINED;
diff --git a/loragw_pkt_logger/src/loragw_pkt_logger.c b/loragw_pkt_logger/src/loragw_pkt_logger.c
index f5f6b30..c298878 100644
--- a/loragw_pkt_logger/src/loragw_pkt_logger.c
+++ b/loragw_pkt_logger/src/loragw_pkt_logger.c
@@ -234,16 +234,14 @@ int parse_SX1301_configuration(const char * conf_file) {
ifconf.rf_chain = (uint32_t)json_object_dotget_number(conf, "chan_FSK.radio");
ifconf.freq_hz = (int32_t)json_object_dotget_number(conf, "chan_FSK.if");
bw = (uint32_t)json_object_dotget_number(conf, "chan_FSK.bandwidth");
- switch(bw) {
- case 500000: ifconf.bandwidth = BW_500KHZ; break;
- case 250000: ifconf.bandwidth = BW_250KHZ; break;
- case 125000: ifconf.bandwidth = BW_125KHZ; break;
- case 62500: ifconf.bandwidth = BW_62K5HZ; break;
- case 31200: ifconf.bandwidth = BW_31K2HZ; break;
- case 15600: ifconf.bandwidth = BW_15K6HZ; break;
- case 7800: ifconf.bandwidth = BW_7K8HZ; break;
- default: ifconf.bandwidth = BW_UNDEFINED;
- }
+ if (bw <= 7800) ifconf.bandwidth = BW_7K8HZ;
+ else if (bw <= 15600) ifconf.bandwidth = BW_15K6HZ;
+ else if (bw <= 31200) ifconf.bandwidth = BW_31K2HZ;
+ else if (bw <= 62500) ifconf.bandwidth = BW_62K5HZ;
+ else if (bw <= 125000) ifconf.bandwidth = BW_125KHZ;
+ else if (bw <= 250000) ifconf.bandwidth = BW_250KHZ;
+ else if (bw <= 500000) ifconf.bandwidth = BW_500KHZ;
+ else ifconf.bandwidth = BW_UNDEFINED;
ifconf.datarate = (uint32_t)json_object_dotget_number(conf, "chan_FSK.datarate");
MSG("INFO: FSK channel enabled, radio %i selected, IF %i Hz, %u Hz bandwidth, %u bps datarate\n", ifconf.rf_chain, ifconf.freq_hz, bw, ifconf.datarate);
}