summaryrefslogtreecommitdiff
path: root/lora_pkt_fwd
diff options
context:
space:
mode:
authorJason Reiss <jreiss@multitech.com>2019-09-19 08:07:19 -0500
committerJason Reiss <jreiss@multitech.com>2019-09-19 08:07:19 -0500
commit48dfa609049df40313262de0c0c3bdb321927789 (patch)
tree5245f277c3af9bea1b6eebb59c96dd710c8e2d7c /lora_pkt_fwd
parent86d30c1f498543a18a585fd726931131a6853af7 (diff)
downloadpacket_forwarder_mtac_full-48dfa609049df40313262de0c0c3bdb321927789.tar.gz
packet_forwarder_mtac_full-48dfa609049df40313262de0c0c3bdb321927789.tar.bz2
packet_forwarder_mtac_full-48dfa609049df40313262de0c0c3bdb321927789.zip
Add patches for best packet filter, beacon fix for AU, and log rotate
Diffstat (limited to 'lora_pkt_fwd')
-rw-r--r--lora_pkt_fwd/src/jitqueue.c7
-rw-r--r--lora_pkt_fwd/src/lora_pkt_fwd.c147
2 files changed, 144 insertions, 10 deletions
diff --git a/lora_pkt_fwd/src/jitqueue.c b/lora_pkt_fwd/src/jitqueue.c
index dbde8d2..f1b547b 100644
--- a/lora_pkt_fwd/src/jitqueue.c
+++ b/lora_pkt_fwd/src/jitqueue.c
@@ -37,6 +37,7 @@ Maintainer: Michael Coracin
#define TX_MARGIN_DELAY 1000 /* Packet overlap margin in microseconds */
/* TODO: How much margin should we take? */
#define TX_JIT_DELAY 30000 /* Pre-delay to program packet for TX in microseconds */
+#define TX_PEEK_DELAY 60000 /* Look ahead time for TX in microseconds */
#define TX_MAX_ADVANCE_DELAY ((JIT_NUM_BEACON_IN_QUEUE + 1) * 128 * 1E6) /* Maximum advance delay accepted for a TX packet, compared to current time */
#define BEACON_GUARD 3000000 /* Interval where no ping slot can be placed,
@@ -352,12 +353,12 @@ enum jit_error_e jit_dequeue(struct jit_queue_s *queue, int index, struct lgw_pk
memset(&(queue->nodes[queue->num_pkt]), 0, sizeof(struct jit_node_s));
/* Sort queue in ascending order of packet timestamp */
- jit_sort_queue(queue);
+ // jit_sort_queue(queue);
/* Done */
pthread_mutex_unlock(&mx_jit_queue);
- jit_print_queue(queue, false, DEBUG_JIT);
+ // jit_print_queue(queue, false, DEBUG_JIT);
MSG_DEBUG(DEBUG_JIT, "dequeued packet with count_us=%u from index %d\n", packet->count_us, index);
@@ -427,7 +428,7 @@ enum jit_error_e jit_peek(struct jit_queue_s *queue, struct timeval *time, int *
* Warning: unsigned arithmetic (handle roll-over)
* t_packet < t_current + TX_JIT_DELAY
*/
- if ((queue->nodes[idx_highest_priority].pkt.count_us - time_us) < TX_JIT_DELAY) {
+ if ((queue->nodes[idx_highest_priority].pkt.count_us - time_us) < TX_PEEK_DELAY) {
*pkt_idx = idx_highest_priority;
MSG_DEBUG(DEBUG_JIT, "peek packet with count_us=%u at index %d\n",
queue->nodes[idx_highest_priority].pkt.count_us, idx_highest_priority);
diff --git a/lora_pkt_fwd/src/lora_pkt_fwd.c b/lora_pkt_fwd/src/lora_pkt_fwd.c
index 40b3098..7d0fa30 100644
--- a/lora_pkt_fwd/src/lora_pkt_fwd.c
+++ b/lora_pkt_fwd/src/lora_pkt_fwd.c
@@ -48,6 +48,7 @@ Maintainer: Michael Coracin
#include <spawn.h>
#include <sys/wait.h>
#include <pthread.h>
+#include <getopt.h>
#include "trace.h"
#include "jitqueue.h"
@@ -154,6 +155,7 @@ volatile bool quit_sig = false; /* 1 -> application terminates without shutting
static bool fwd_valid_pkt = true; /* packets with PAYLOAD CRC OK are forwarded */
static bool fwd_error_pkt = false; /* packets with PAYLOAD CRC ERROR are NOT forwarded */
static bool fwd_nocrc_pkt = false; /* packets with NO PAYLOAD CRC are NOT forwarded */
+static bool fwd_best_pkt = true; /* duplicate packets with low SNR are NOT forwarded */
/* network configuration variables */
static uint64_t lgwm = 0; /* Lora gateway MAC address */
@@ -281,6 +283,8 @@ static struct lgw_tx_gain_lut_s txlut; /* TX gain table */
static uint32_t tx_freq_min[LGW_RF_CHAIN_NB]; /* lowest frequency supported by TX chain */
static uint32_t tx_freq_max[LGW_RF_CHAIN_NB]; /* highest frequency supported by TX chain */
+static uint32_t rx_rf_freq[LGW_RF_CHAIN_NB]; /* center frequency of the radio in Hz */
+
/* -------------------------------------------------------------------------- */
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
@@ -672,7 +676,7 @@ static int parse_SX1301_configuration(const char * conf_file) {
}
// } else { /* radio enabled, will parse the other parameters */
snprintf(param_name, sizeof param_name, "radio_%i.freq", i);
- rfconf.freq_hz = (uint32_t)json_object_dotget_number(conf_obj, param_name);
+ rfconf.freq_hz = rx_rf_freq[i] = (uint32_t)json_object_dotget_number(conf_obj, param_name);
snprintf(param_name, sizeof param_name, "radio_%i.rssi_offset", i);
rfconf.rssi_offset = (float)json_object_dotget_number(conf_obj, param_name);
snprintf(param_name, sizeof param_name, "radio_%i.type", i);
@@ -916,6 +920,12 @@ static int parse_gateway_configuration(const char * conf_file) {
}
/* packet filtering parameters */
+ val = json_object_get_value(conf_obj, "best_packet_filter");
+ if (json_value_get_type(val) == JSONBoolean) {
+ fwd_best_pkt = (bool)json_value_get_boolean(val);
+ }
+ MSG("INFO: duplicate packets received with low SNR will%s be forwarded\n", (!fwd_best_pkt ? "" : " NOT"));
+
val = json_object_get_value(conf_obj, "forward_crc_valid");
if (json_value_get_type(val) == JSONBoolean) {
fwd_valid_pkt = (bool)json_value_get_boolean(val);
@@ -1155,12 +1165,51 @@ static int send_tx_ack(uint8_t token_h, uint8_t token_l, enum jit_error_e error)
return send(sock_down, (void *)buff_ack, buff_index, 0);
}
+
+
+void usage(char *proc_name) {
+ fprintf(stderr, "Usage: %s [-l logfile]\n", proc_name);
+ exit(1);
+}
+
+static char *short_options = "l:h";
+static struct option long_options[] = {
+ {"logfile", 1, 0, 'l'},
+ {"help", 0, 0, 'h'},
+ {0, 0, 0, 0},
+};
+
+/* path to logfile */
+char *logfile_path = NULL;
+
+void sighup_handler() {
+ int logfile_fd;
+ int old_logfile_fd = -1;
+
+ FILE *logfile = NULL;
+ if (logfile_path) {
+ logfile = fopen(logfile_path, "a");
+
+ if (logfile) {
+ dup2(STDOUT_FILENO, old_logfile_fd);
+ logfile_fd = fileno(logfile);
+ dup2(logfile_fd, STDOUT_FILENO);
+ dup2(logfile_fd, STDERR_FILENO);
+ close(old_logfile_fd);
+ } else {
+ printf("Error opening log file %s\n", logfile_path);
+ exit(1);
+ }
+ }
+}
+
/* -------------------------------------------------------------------------- */
/* --- MAIN FUNCTION -------------------------------------------------------- */
-int main(void)
+int main(int argc, char** argv)
{
struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
+ struct sigaction sighupact; /* SIGHUP signal handling */
int i; /* loop variable and temporary variable for return value */
int x;
@@ -1168,6 +1217,9 @@ int main(void)
char *global_cfg_path= "global_conf.json"; /* contain global (typ. network-wide) configuration */
char *local_cfg_path = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
char *debug_cfg_path = "debug_conf.json"; /* if present, all other configuration files are ignored */
+ char *proc_name = argv[0];
+ int opt_ind = 0;
+
/* threads */
pthread_t thrid_up;
pthread_t thrid_down;
@@ -1177,6 +1229,41 @@ int main(void)
pthread_t thrid_timersync;
pthread_t thrid_spectralscan;
+
+ while((i = getopt_long(argc, argv, short_options, long_options, &opt_ind)) >= 0) {
+ switch(i) {
+ case 0:
+ break;
+ case 'l':
+ logfile_path = strdup(optarg);
+ if (logfile_path == NULL) {
+ printf("Error: can't save logfile name\n");
+ exit(1);
+ }
+ break;
+ default:
+ usage(proc_name);
+ break;
+ }
+ }
+
+ /* redirect stdout, stderr to logfile if specified */
+ int logfile_fd;
+ FILE *logfile = NULL;
+ if (logfile_path) {
+ logfile = fopen(logfile_path, "a");
+ if (logfile) {
+ logfile_fd = fileno(logfile);
+ dup2(logfile_fd, STDOUT_FILENO);
+ dup2(logfile_fd, STDERR_FILENO);
+ } else {
+ printf("Error opening log file %s\n", logfile_path);
+ exit(1);
+ }
+ }
+
+
+
/* network socket creation */
struct addrinfo hints;
struct addrinfo *result; /* store result of getaddrinfo */
@@ -1440,6 +1527,13 @@ int main(void)
sigaction(SIGINT, &sigact, NULL); /* Ctrl-C */
sigaction(SIGTERM, &sigact, NULL); /* default "kill" command */
+ sigemptyset(&sighupact.sa_mask);
+ sighupact.sa_flags = 0;
+ sighupact.sa_handler = sighup_handler;
+ sigaction(SIGHUP, &sighupact, NULL); /* rotate logfile on HUP */
+ signal(SIGPIPE, SIG_IGN); /* ignore writes after closing socket */
+
+
/* main loop task : statistics collection */
while (!exit_sig && !quit_sig) {
/* wait for next reporting interval */
@@ -1741,6 +1835,38 @@ void thread_up(void) {
memcpy((void *)(buff_up + buff_index), (void *)"{\"rxpk\":[", 9);
buff_index += 9;
+ if (fwd_best_pkt && nb_pkt > 1) {
+ uint32_t check_addr = 0;
+ uint32_t check_mic = 0;
+ uint16_t check_fcnt = 0;
+ float check_snr = -30.0;
+
+ for (i=0; i < nb_pkt; ++i) {
+ p = &rxpkt[i];
+ if (p->size < 12)
+ continue;
+
+ memcpy(&check_addr, p->payload + 1, 4);
+ memcpy(&check_fcnt, p->payload + 6, 2);
+ memcpy(&check_mic, p->payload + p->size - 4, 4);
+
+ check_snr = p->snr;
+
+ for (j=0; j < nb_pkt; ++j) {
+ p = &rxpkt[j];
+
+ if (p->size >= 12
+ && memcmp(&check_addr, p->payload + 1, 4) == 0
+ && memcmp(&check_fcnt, p->payload + 6, 2) == 0
+ && memcmp(&check_mic, p->payload + p->size - 4, 4) == 0
+ && p->snr < check_snr) {
+ // set status of duplicate packets rx'd on wrong channel
+ p->status = 1;
+ }
+ }
+ }
+ }
+
/* serialize Lora packets metadata and payload */
pkt_in_dgram = 0;
for (i=0; i < nb_pkt; ++i) {
@@ -2215,8 +2341,15 @@ void thread_down(void) {
break;
case 12:
beacon_pkt.datarate = DR_LORA_SF12;
- beacon_RFU1_size = 5;
- beacon_RFU2_size = 3;
+
+ /* Check radio 0 center frequency to determine if US or AU region */
+ if (rx_rf_freq[0] > 914900000U ) {
+ beacon_RFU1_size = 3;
+ beacon_RFU2_size = 1;
+ } else {
+ beacon_RFU1_size = 5;
+ beacon_RFU2_size = 3;
+ }
break;
default:
/* should not happen */
@@ -3286,7 +3419,7 @@ void thread_spectralscan(void) {
x = lgw_setup_sx127x(freq, MOD_FSK, map_bandwidth(scan_config.bandwidth), 0);
if( x != 0 ) {
printf( "ERROR: SX127x setup failed\n" );
- return EXIT_FAILURE;
+ exit(EXIT_FAILURE);
}
lgw_fpga_reg_w(LGW_FPGA_CTRL_FEATURE_START, 1);
}
@@ -3380,7 +3513,7 @@ void thread_spectralscan(void) {
JSON_Value *scan_value = json_value_init_object();
JSON_Object *scan_object = json_value_get_object(scan_value);
char scan_string[1024] = "";
- snprintf(scan_string, sizeof scan_string, "%d, %d", freq, scan_time);
+ snprintf(scan_string, sizeof scan_string, "%d, %d", freq, scan_time);
float rssi_thresh[] = {0.1,0.3,0.5,0.8,1};
for (i = 0; i < RSSI_RANGE; i++) {
@@ -3391,7 +3524,7 @@ void thread_spectralscan(void) {
rssi_cumu = scan_config.samples;
}
if (rssi_cumu > rssi_thresh[k]*scan_config.samples) {
- snprintf(param_name, sizeof param_name, "rssi_%d", (uint16_t)(rssi_thresh[k]*100));
+ snprintf(param_name, sizeof param_name, "rssi_%d", (uint16_t)(rssi_thresh[k]*100));
json_object_set_number(scan_object, param_name, -i/2.0);
k++;
}