/* / _____) _ | | ( (____ _____ ____ _| |_ _____ ____| |__ \____ \| ___ | (_ _) ___ |/ ___) _ \ _____) ) ____| | | || |_| ____( (___| | | | (______/|_____)_|_|_| \__)_____)\____)_| |_| (C)2020 Semtech Description: Utility to compute Time on Air of a LoRa packet License: Revised BSD License, see LICENSE.TXT file include in the project */ /* -------------------------------------------------------------------------- */ /* --- DEPENDANCIES --------------------------------------------------------- */ /* fix an issue between POSIX and C99 */ #if __STDC_VERSION__ >= 199901L #define _XOPEN_SOURCE 600 #else #define _XOPEN_SOURCE 500 #endif #include /* C99 types */ #include /* bool type */ #include /* printf fprintf */ #include /* EXIT_FAILURE */ #include /* getopt_long */ #include /* strcmp */ #include "loragw_hal.h" /* -------------------------------------------------------------------------- */ /* --- PRIVATE MACROS ------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* --- PRIVATE CONSTANTS ---------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* --- PRIVATE VARIABLES ---------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */ /* -------------------------------------------------------------------------- */ /* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */ /* describe command line options */ void usage(void) { printf("Library version information: %s\n", lgw_version_info()); printf("Available options:\n"); printf(" -h print this help\n"); printf(" -s LoRa datarate [5..12]\n"); printf(" -b LoRa bandwidth in khz [125, 250, 500]\n"); printf(" -l LoRa preamble length, [6..65535]\n"); printf(" -c LoRa coding rate [1=4/5 2=4/6 3=4/7 4=4/8]\n"); printf(" -z Payload length [0..255]\n"); printf(" -i Implicit header (no header)\n"); printf(" -r CRC enabled\n"); } /* -------------------------------------------------------------------------- */ /* --- MAIN FUNCTION -------------------------------------------------------- */ int main(int argc, char **argv) { int i; unsigned int arg_u; struct lgw_pkt_tx_s pkt; uint32_t toa_u; /* mandatory params to be set by user */ bool sf = false; bool bw = false; bool preamb = false; bool cr = false; bool sz = false; /* Parameter parsing */ int option_index = 0; static struct option long_options[] = { {0, 0, 0, 0} }; memset(&pkt, 0, sizeof pkt); pkt.no_crc = true; pkt.modulation = MOD_LORA; /* parse command line options */ while ((i = getopt_long (argc, argv, "hirs:b:z:l:c:", long_options, &option_index)) != -1) { switch (i) { case 'h': usage(); return -1; break; case 'i': pkt.no_header = true; break; case 'r': pkt.no_crc = false; break; case 'l': preamb = true; /* param set */ i = sscanf(optarg, "%u", &arg_u); if ((i != 1) || (arg_u > 65535)) { printf("ERROR: argument parsing of -l argument. Use -h to print help\n"); return EXIT_FAILURE; } else { pkt.preamble = (uint16_t)arg_u; } break; case 's': sf = true; /* param set */ i = sscanf(optarg, "%u", &arg_u); if ((i != 1) || (arg_u < 5) || (arg_u > 12)) { printf("ERROR: argument parsing of -s argument. Use -h to print help\n"); return EXIT_FAILURE; } else { pkt.datarate = arg_u; } break; case 'b': bw = true; /* param set */ i = sscanf(optarg, "%u", &arg_u); if (i != 1) { printf("ERROR: argument parsing of -b argument. Use -h to print help\n"); return EXIT_FAILURE; } else { switch (arg_u) { case 125: pkt.bandwidth = BW_125KHZ; break; case 250: pkt.bandwidth = BW_250KHZ; break; case 500: pkt.bandwidth = BW_500KHZ; break; default: printf("ERROR: argument parsing of -b argument. Use -h to print help\n"); return EXIT_FAILURE; } } break; case 'c': cr = true; /* param set */ i = sscanf(optarg, "%u", &arg_u); if (i != 1) { printf("ERROR: argument parsing of -b argument. Use -h to print help\n"); return EXIT_FAILURE; } else { switch (arg_u) { case 1: pkt.coderate = CR_LORA_4_5; break; case 2: pkt.coderate = CR_LORA_4_6; break; case 3: pkt.coderate = CR_LORA_4_7; break; case 4: pkt.coderate = CR_LORA_4_8; break; default: printf("ERROR: argument parsing of -b argument. Use -h to print help\n"); return EXIT_FAILURE; } } break; case 'z': sz = true; /* param set */ i = sscanf(optarg, "%u", &arg_u); if ((i != 1) || (arg_u > 255)) { printf("ERROR: argument parsing of -z argument. Use -h to print help\n"); return EXIT_FAILURE; } else { pkt.size = (uint8_t)arg_u; } break; default: printf("ERROR: argument parsing\n"); usage(); return EXIT_FAILURE; } } printf("### LoRa - Time On Air Calculator ###\n"); if (sf == false || bw == false || preamb == false || cr == false || sz == false) { printf("ERROR: missing mandatory packet description parameter\n"); usage(); return EXIT_FAILURE; } toa_u = lgw_time_on_air(&pkt); printf("=> %u ms\n", toa_u); return 0; }