From 48dfa609049df40313262de0c0c3bdb321927789 Mon Sep 17 00:00:00 2001 From: Jason Reiss Date: Thu, 19 Sep 2019 08:07:19 -0500 Subject: Add patches for best packet filter, beacon fix for AU, and log rotate --- lora_pkt_fwd/src/jitqueue.c | 7 +- lora_pkt_fwd/src/lora_pkt_fwd.c | 147 ++++++++++++++++++++++++++++++++++++++-- 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 #include #include +#include #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++; } -- cgit v1.2.3