Esempio n. 1
0
int main(int argc, char **argv)
{
	int i; /* temporary variable(s) */
	int32_t reg_val;
	
	/* user chosen parameters */
	double f1 = 0.0;
	double f2 = 0.0;
	double fs = 0.0;
	
	/* frequency scan parameters (default values) */
	uint32_t f_start = rf_rx_lowfreq_[RF_CHAIN]; /* in Hz */
	uint32_t f_stop = rf_rx_upfreq_[RF_CHAIN]; /* in Hz */
	uint32_t f_step = 200000; /* 200 kHz step by default */
	
	/* RSSI measurement results */
	int8_t rssi_max; /* max RSSI during X measurements */
	int high_count; /* nb of measurements above a threshold defined by maximum RSSI */
	
	/* clock, log file and log rotation management */
	FILE * log_file = NULL;
	char log_file_name[64];
	char iso_date[20];
	time_t now_time;
	
	/* variables for PLL register calculation */
	uint32_t f_target; /* loop variable */
	uint32_t freq_hz;
	uint32_t part_int;
	uint32_t part_frac;
	int cpt_attempts = 0;
	
	/* parse command line options */
	while ((i = getopt (argc, argv, "hf:")) != -1) {
		switch (i) {
			case 'h':
				usage();
				return EXIT_SUCCESS;
			
			case 'f':
				sscanf(optarg, "%lf:%lf:%lf", &f1, &f2, &fs);
				/* check configuration sanity */
				if (f2 < f1) {
					MSG("ERROR: stop frequency must be bigger than start frequency\n");
					return EXIT_FAILURE;
				}
				if ((f1 < 30.0) || (f1 > 3000.0)) {
					MSG("ERROR: invalid start frequency %f MHz\n", f1);
					return EXIT_FAILURE;
				}
				if ((f2 < 30.0) || (f2 > 3000.0)) {
					MSG("ERROR: invalid stop frequency %f MHz\n", f2);
					return EXIT_FAILURE;
				}
				f_start = (uint32_t)((f1*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
				f_stop = (uint32_t)((f2*1e6) + 0.5);
				if (fs > 0.01) {
					f_step = (uint32_t)((fs*1e6) + 0.5);
				}
				break;
			
			default:
				MSG("ERROR: argument parsing use -h option for help\n");
				usage();
				return EXIT_FAILURE;
		}
	}
	printf("Scanning from %u Hz to %u Hz with a %u Hz frequency step\n", f_start, f_stop, f_step);
	
	/* configure signal handling */
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigact.sa_handler = sig_handler;
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	
	/* establish connection with concentrator and reset it */
	if (lgw_connect() == LGW_REG_ERROR) {
		MSG("ERROR: fail to connect to concentrator board\n");
		return EXIT_FAILURE;
	}
	lgw_soft_reset();
	
	/* Ungate concentrator clock, switch on the radios and reset them */
	lgw_reg_w(LGW_GLOBAL_EN, 1);
	lgw_reg_w(LGW_RADIO_A_EN,1);
	lgw_reg_w(LGW_RADIO_B_EN,1);
	wait_ms(500);
	lgw_reg_w(LGW_RADIO_RST,1);
	wait_ms(5);
	lgw_reg_w(LGW_RADIO_RST,0);
	wait_ms(5);
	
	/* enter basic parameters for the radio */
	sx125x_write_(RF_CHAIN, 0x10, SX125x_TX_DAC_CLK_SEL + SX125x_CLK_OUT*2);
	sx125x_write_(RF_CHAIN, 0x0C, 0 + SX125x_RX_BB_GAIN*2 + SX125x_RX_LNA_GAIN*32); /* not required, firmware should take care of that */
	sx125x_write_(RF_CHAIN, 0x0D, SX125x_RXBB_BW + SX125x_RX_ADC_TRIM*4 + SX125x_RX_ADC_BW*32);
	
	/* configure the IF and concentrator parameters */
	lgw_reg_w(LGW_IF_FREQ_0, -282); /* default -384 */
	lgw_reg_w(LGW_IF_FREQ_1, -128); /* default -128 */
	
	lgw_reg_w(LGW_RSSI_BB_FILTER_ALPHA,9); /* default 7 */
	lgw_reg_w(LGW_RSSI_DEC_FILTER_ALPHA,7); /* default 5 */
	lgw_reg_w(LGW_RSSI_CHANN_FILTER_ALPHA,3); /* default 8 */
	lgw_reg_w(LGW_RSSI_CHANN_DEFAULT_VALUE,90); /* default 100 */
	lgw_reg_w(LGW_RSSI_DEC_DEFAULT_VALUE,90); /* default 100 */
	
	/* Load firmware */
	load_firmware_(MCU_AGC, rssi_firmware, MCU_AGC_FW_BYTE);
	lgw_reg_w(LGW_FORCE_HOST_FE_CTRL,0);
	lgw_reg_w(LGW_FORCE_DEC_FILTER_GAIN,0);
	
	/* open log file */
	time(&now_time);
	strftime(iso_date,ARRAY_SIZE(iso_date),"%Y%m%dT%H%M%SZ",gmtime(&now_time)); /* format yyyymmddThhmmssZ */
	sprintf(log_file_name, "band_survey_%s.csv", iso_date);
	log_file = fopen(log_file_name, "a"); /* create log file, append if file already exist */
	if (log_file == NULL) {
		MSG("ERROR: impossible to create log file %s\n", log_file_name);
		return EXIT_FAILURE;
	}
	i = fprintf(log_file, "\"Frequency (Hz)\",\"RSSI (dB)\",\"high meas (nb)\"\n");
	if (i < 0) {
		MSG("ERROR: impossible to write to log file %s\n", log_file_name);
		return EXIT_FAILURE;
	}
	
	/* main loop */
	f_target = f_start;
	
	while ((quit_sig != 1) && (exit_sig != 1) && (f_target <= f_stop)) {
		
		/* set PLL to target frequency */
		freq_hz = f_target - MEAS_IF;
		
		#if (CFG_RADIO_1257 == 1)
		part_int = freq_hz / (SX125x_32MHz_FRAC << 8); /* integer part, gives the MSB */
		part_frac = ((freq_hz % (SX125x_32MHz_FRAC << 8)) << 8) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
		#elif (CFG_RADIO_1255 == 1)
		part_int = freq_hz / (SX125x_32MHz_FRAC << 7); /* integer part, gives the MSB */
		part_frac = ((freq_hz % (SX125x_32MHz_FRAC << 7)) << 9) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
		#endif
		
		sx125x_write_(RF_CHAIN, 0x01,0xFF & part_int); /* Most Significant Byte */
		sx125x_write_(RF_CHAIN, 0x02,0xFF & (part_frac >> 8)); /* middle byte */
		sx125x_write_(RF_CHAIN, 0x03,0xFF & part_frac); /* Least Significant Byte */
		
		/* start and PLL lock */
		cpt_attempts = 0;
		do {
			if (cpt_attempts >= PLL_LOCK_MAX_ATTEMPTS) {
				MSG("ERROR: fail to lock PLL\n");
				return -1;
			}
			sx125x_write_(RF_CHAIN, 0x00, 1); /* enable Xtal oscillator */
			sx125x_write_(RF_CHAIN, 0x00, 3); /* Enable RX (PLL+FE) */
			++cpt_attempts;
			wait_ms(1);
		} while((sx125x_read_(RF_CHAIN, 0x11) & 0x02) == 0);
		
		/* give control of the radio to the MCU and get it out of reset */
		lgw_reg_w(LGW_FORCE_HOST_RADIO_CTRL,0);
		lgw_reg_w(LGW_MCU_RST_1, 0);
		
		/* wait for the firmware to finish running and fetch the result */
		do {
			wait_ms(1);
			lgw_reg_r(LGW_MCU_AGC_STATUS, &reg_val);
		} while (reg_val != 1);
		
		lgw_reg_w(LGW_DBG_AGC_MCU_RAM_ADDR,0x20);
		lgw_reg_r(LGW_DBG_AGC_MCU_RAM_DATA, &reg_val);
		rssi_max = (int8_t)reg_val;
		
		lgw_reg_w(LGW_DBG_AGC_MCU_RAM_ADDR,0x21);
		lgw_reg_r(LGW_DBG_AGC_MCU_RAM_DATA, &reg_val);
		high_count = reg_val;
		
		lgw_reg_w(LGW_DBG_AGC_MCU_RAM_ADDR,0x22);
		lgw_reg_r(LGW_DBG_AGC_MCU_RAM_DATA, &reg_val);
		high_count += (reg_val << 8);
		
		/* log the measurement */
		i = fprintf(log_file, "%u, %i, %u\n", f_target, rssi_max, high_count);
		if (i < 0) {
			MSG("ERROR: impossible to write to log file %s\n", log_file_name);
			return EXIT_FAILURE;
		}
		
		/* reset MCU and take back control of radio */
		lgw_reg_w(LGW_MCU_RST_1, 1);
		lgw_reg_w(LGW_FORCE_HOST_RADIO_CTRL,1);
		
		/* iterate loop */
		f_target += f_step;
	}
	
	fclose(log_file);
	lgw_soft_reset();
	lgw_disconnect();
	
	printf("Exiting band survey program\n");
	return EXIT_SUCCESS;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
	int i;
	int xi = 0;
	
	/* application option */
	int test_number = 1;
	int cycle_number = 0;
	int repeats_per_cycle = 1000;
	bool error = false;
	
	/* in/out variables */
	int32_t test_value;
	int32_t read_value;
	int32_t rb1, rb2, rb3; /* interstitial readbacks, to flush buffers if needed */
	
	/* data buffer */
	int32_t test_addr;
	uint8_t test_buff[BUFF_SIZE];
	uint8_t read_buff[BUFF_SIZE];
	
	/* parse command line options */
	while ((i = getopt (argc, argv, "ht:")) != -1) {
		switch (i) {
			case 'h':
				usage();
				return EXIT_FAILURE;
				break;
			
			case 't':
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 1) || (xi > 4)) {
					MSG("ERROR: invalid test number\n");
					return EXIT_FAILURE;
				} else {
					test_number = xi;
				}
				break;
			
			default:
				MSG("ERROR: argument parsing use -h option for help\n");
				usage();
				return EXIT_FAILURE;
		}
	}
	MSG("INFO: Starting LoRa concentrator SPI stress-test number %i\n", test_number);
	
	/* configure signal handling */
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigact.sa_handler = sig_handler;
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	
	/* start SPI link */
	i = lgw_connect();
	if (i != LGW_REG_SUCCESS) {
		MSG("ERROR: lgw_connect() did not return SUCCESS");
		return EXIT_FAILURE;
	}
	
	if (test_number == 1) {
		/* single 8b register R/W stress test */
		while ((quit_sig != 1) && (exit_sig != 1)) {
			printf("Cycle %i > ", cycle_number);
			for (i=0; i<repeats_per_cycle; ++i) {
				test_value = (rand() % 256);
				lgw_reg_w(LGW_IMPLICIT_PAYLOAD_LENGHT, test_value);
				lgw_reg_r(LGW_IMPLICIT_PAYLOAD_LENGHT, &read_value);
				if (read_value != test_value) {
					error = true;
					break;
				}
			}
			if (error) {
				printf("error during the %ith iteration: write 0x%02X, read 0x%02X\n", i+1, test_value, read_value);
				printf("Repeat read of target register:");
				for (i=0; i<READS_WHEN_ERROR; ++i) {
					lgw_reg_r(LGW_IMPLICIT_PAYLOAD_LENGHT, &read_value);
					printf(" 0x%02X", read_value);
				}
				printf("\n");
				return EXIT_FAILURE;
			} else {
				printf("did %i R/W on an 8 bits reg with no error\n", repeats_per_cycle);
				++cycle_number;
			}
		}
	} else if (test_number == 2) {
		/* single 8b register R/W with interstitial VERSION check stress test */
		while ((quit_sig != 1) && (exit_sig != 1)) {
			printf("Cycle %i > ", cycle_number);
			for (i=0; i<repeats_per_cycle; ++i) {
				test_value = (rand() % 256);
				lgw_reg_r(LGW_VERSION, &rb1);
				lgw_reg_w(LGW_IMPLICIT_PAYLOAD_LENGHT, test_value);
				lgw_reg_r(LGW_VERSION, &rb2);
				lgw_reg_r(LGW_IMPLICIT_PAYLOAD_LENGHT, &read_value);
				lgw_reg_r(LGW_VERSION, &rb3);
				if ((rb1 != VERS) || (rb2 != VERS) || (rb3 != VERS) || (read_value != test_value)) {
					error = true;
					break;
				}
			}
			if (error) {
				printf("error during the %ith iteration: write %02X, read %02X, version (%i, %i, %i)\n", i+1, test_value, read_value, rb1, rb2, rb3);
				printf("Repeat read of target register:");
				for (i=0; i<READS_WHEN_ERROR; ++i) {
					lgw_reg_r(LGW_IMPLICIT_PAYLOAD_LENGHT, &read_value);
					printf(" 0x%02X", read_value);
				}
				printf("\n");
				return EXIT_FAILURE;
			} else {
				printf("did %i R/W on an 8 bits reg with no error\n", repeats_per_cycle);
				++cycle_number;
			}
		}
	} else if (test_number == 3) {
		/* 32b register R/W stress test */
		while ((quit_sig != 1) && (exit_sig != 1)) {
			printf("Cycle %i > ", cycle_number);
			for (i=0; i<repeats_per_cycle; ++i) {
				test_value = (rand() & 0x0000FFFF);
				test_value += (int32_t)(rand() & 0x0000FFFF) << 16;
				lgw_reg_w(LGW_FSK_REF_PATTERN_LSB, test_value);
				lgw_reg_r(LGW_FSK_REF_PATTERN_LSB, &read_value);
				if (read_value != test_value) {
					error = true;
					break;
				}
			}
			if (error) {
				printf("error during the %ith iteration: write 0x%08X, read 0x%08X\n", i+1, test_value, read_value);
				printf("Repeat read of target register:");
				for (i=0; i<READS_WHEN_ERROR; ++i) {
					lgw_reg_r(LGW_FSK_REF_PATTERN_LSB, &read_value);
					printf(" 0x%08X", read_value);
				}
				printf("\n");
				return EXIT_FAILURE;
			} else {
				printf("did %i R/W on a 32 bits reg with no error\n", repeats_per_cycle);
				++cycle_number;
			}
		}
	} else if (test_number == 4) {
		/* databuffer R/W stress test */
		while ((quit_sig != 1) && (exit_sig != 1)) {
			for (i=0; i<BUFF_SIZE; ++i) {
				test_buff[i] = rand() & 0xFF;
			}
			printf("Cycle %i > ", cycle_number);
			test_addr = rand() & 0xFFFF;
			lgw_reg_w(LGW_RX_DATA_BUF_ADDR, test_addr); /* write at random offset in memory */
			lgw_reg_wb(LGW_RX_DATA_BUF_DATA, test_buff, BUFF_SIZE);
			lgw_reg_w(LGW_RX_DATA_BUF_ADDR, test_addr); /* go back to start of segment */
			lgw_reg_rb(LGW_RX_DATA_BUF_DATA, read_buff, BUFF_SIZE);
			for (i=0; ((i<BUFF_SIZE) && (test_buff[i] == read_buff[i])); ++i);
			if (i != BUFF_SIZE) {
				printf("error during the buffer comparison\n");
				printf("Written values:\n");
				for (i=0; i<BUFF_SIZE; ++i) {
					printf(" %02X ", test_buff[i]);
					if (i%16 == 15) printf("\n");
				}
				printf("\n");
				printf("Read values:\n");
				for (i=0; i<BUFF_SIZE; ++i) {
					printf(" %02X ", read_buff[i]);
					if (i%16 == 15) printf("\n");
				}
				printf("\n");
				lgw_reg_w(LGW_RX_DATA_BUF_ADDR, test_addr); /* go back to start of segment */
				lgw_reg_rb(LGW_RX_DATA_BUF_DATA, read_buff, BUFF_SIZE);
				printf("Re-read values:\n");
				for (i=0; i<BUFF_SIZE; ++i) {
					printf(" %02X ", read_buff[i]);
					if (i%16 == 15) printf("\n");
				}
				printf("\n");
				return EXIT_FAILURE;
			} else {
				printf("did a %i-byte R/W on a data buffer with no error\n", BUFF_SIZE);
				++cycle_number;
			}
		}
	} else {
		MSG("ERROR: invalid test number");
		usage();
	}
	
	/* close SPI link */
	i = lgw_disconnect();
	if (i != LGW_REG_SUCCESS) {
		MSG("ERROR: lgw_disconnect() did not return SUCCESS");
		return EXIT_FAILURE;
	}
	
	MSG("INFO: Exiting LoRa concentrator SPI stress-test program\n");
	return EXIT_SUCCESS;
}
Esempio n. 3
0
int main(int argc, char **argv)
{
    int i;
    int xi = 0;

    /* in/out variables */
    double f1 = 0.0;
    uint32_t f_init = 0; /* in Hz */
    uint32_t f_start = 0; /* in Hz */
    uint16_t loop_cnt = 0;
    int8_t rssi_target_dBm = -80;
    uint16_t scan_time_us = 128;
    uint32_t timestamp;
    uint8_t rssi_value;
    int8_t rssi_offset = DEFAULT_SX127X_RSSI_OFFSET;
    int32_t val, val2;
    int channel;
    uint32_t freq_offset;

    /* parse command line options */
    while ((i = getopt (argc, argv, "h:f:s:r:o:")) != -1) {
        switch (i) {
            case 'h':
                usage();
                return EXIT_FAILURE;
                break;

            case 'f':
                i = sscanf(optarg, "%lf", &f1);
                if ((i != 1) || (f1 < 30.0) || (f1 > 3000.0)) {
                    MSG("ERROR: Invalid LBT start frequency\n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    f_start = (uint32_t)((f1*1e6) + 0.5);/* .5 Hz offset to get rounding instead of truncating */
                }
                break;
            case 's':
                i = sscanf(optarg, "%i", &xi);
                if ((i != 1) || ((xi != 128) && (xi != 5000))) {
                    MSG("ERROR: scan_time_us must be 128 or 5000 \n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    scan_time_us = xi;
                }
                break;
            case 'r':
                i = sscanf(optarg, "%i", &xi);
                if ((i != 1) || ((xi < -128) && (xi > 0))) {
                    MSG("ERROR: rssi_target must be b/w -128 & 0 \n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    rssi_target_dBm = xi;
                }
                break;
            case 'o': /* -o <int>  SX127x RSSI offset [-128..127] */
                i = sscanf(optarg, "%i", &xi);
                if((i != 1) || (xi < -128) || (xi > 127)) {
                    MSG("ERROR: rssi_offset must be b/w -128 & 127\n");
                    usage();
                    return EXIT_FAILURE;
                } else {
                    rssi_offset = (int8_t)xi;
                }
                break;
            default:
                MSG("ERROR: argument parsing use -h option for help\n");
                usage();
                return EXIT_FAILURE;
        }
    }

    MSG("INFO: Starting LoRa Gateway v1.5 LBT test\n");

    /* configure signal handling */
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigact.sa_handler = sig_handler;
    sigaction(SIGQUIT, &sigact, NULL);
    sigaction(SIGINT, &sigact, NULL);
    sigaction(SIGTERM, &sigact, NULL);

    /* Connect to concentrator */
    i = lgw_connect(false, LGW_DEFAULT_NOTCH_FREQ);
    if (i != LGW_REG_SUCCESS) {
        MSG("ERROR: lgw_connect() did not return SUCCESS\n");
        return EXIT_FAILURE;
    }

    /* Check if FPGA supports LBT */
    lgw_fpga_reg_r(LGW_FPGA_FEATURE, &val);
    if (TAKE_N_BITS_FROM((uint8_t)val, 2, 1) != true) {
        MSG("ERROR: LBT is not supported (0x%x)\n", (uint8_t)val);
        return EXIT_FAILURE;
    }

    /* Get FPGA lowest frequency for LBT channels */
    lgw_fpga_reg_r(LGW_FPGA_LBT_INITIAL_FREQ, &val);
    switch (val) {
        case 0:
            f_init = 915000000;
            break;
        case 1:
            f_init = 863000000;
            break;
        default:
            MSG("ERROR: LBT start frequency %d is not supported\n", val);
            return EXIT_FAILURE;
    }

    /* Initialize 1st LBT channel freq if not given by user */
    if (f_start == 0) {
        f_start = f_init;
    } else if (f_start < f_init) {
        MSG("ERROR: LBT start frequency %u is not supported (f_init=%u)\n", f_start, f_init);
        return EXIT_FAILURE;
    }
    MSG("FREQ: %u\n", f_start);

    /* Configure SX127x and read few RSSI points */
    lgw_setup_sx127x(f_init, MOD_FSK, LGW_SX127X_RXBW_100K_HZ, rssi_offset); /* 200KHz LBT channels */
    for (i = 0; i < 100; i++) {
        lgw_sx127x_reg_r(0x11, &rssi_value); /* 0x11: RegRssiValue */
        MSG("SX127x RSSI:%i dBm\n", -(rssi_value/2));
        wait_ms(10);
    }

    /* Configure LBT */
    val = -2*(rssi_target_dBm);
    lgw_fpga_reg_w(LGW_FPGA_RSSI_TARGET, val);
    for (i = 0; i < LBT_CHANNEL_FREQ_NB; i++) {
        freq_offset = (f_start - f_init)/100E3 + i*2; /* 200KHz between each channel */
        lgw_fpga_reg_w(LGW_FPGA_LBT_CH0_FREQ_OFFSET+i, (int32_t)freq_offset);
        if (scan_time_us == 5000) { /* configured to 128 by default */
            lgw_fpga_reg_w(LGW_FPGA_LBT_SCAN_TIME_CH0+i, 1);
        }
    }

    lgw_fpga_reg_r(LGW_FPGA_RSSI_TARGET, &val);
    MSG("RSSI_TARGET = %d\n", val);
    if (val != (-2*rssi_target_dBm)) {
        MSG("ERROR: failed to read back RSSI target register value\n");
        return EXIT_FAILURE;
    }
    for (i = 0; i < LBT_CHANNEL_FREQ_NB; i++) {
        lgw_fpga_reg_r(LGW_FPGA_LBT_CH0_FREQ_OFFSET+i, &val);
        lgw_fpga_reg_r(LGW_FPGA_LBT_SCAN_TIME_CH0+i, &val2);
        MSG("CH_%i: freq=%u (offset=%i), scan_time=%u (%i)\n", i, (uint32_t)((val*100E3)+f_init), val, (val2==1)?5000:128, val2);
    }
    lgw_fpga_reg_r(LGW_FPGA_VERSION, &val);
    MSG("FPGA VERSION = %d\n", val);

    /* Enable LBT FSM */
    lgw_fpga_reg_w(LGW_FPGA_CTRL_FEATURE_START, 1);

    /* Start test */
    while ((quit_sig != 1) && (exit_sig != 1)) {
        MSG("~~~~\n");
        for (channel = 0; channel < LBT_CHANNEL_FREQ_NB; channel++) {
            /* Select LBT channel */
            lgw_fpga_reg_w(LGW_FPGA_LBT_TIMESTAMP_SELECT_CH, channel);

            /* Get last instant when the selected channel was free */
            lgw_fpga_reg_r(LGW_FPGA_LBT_TIMESTAMP_CH, &val);
            timestamp = (uint32_t)(val & 0x0000FFFF) * 256; /* 16bits (1LSB = 256µs) */
            MSG(" TIMESTAMP_CH%u = %u\n", channel, timestamp);
        }

        loop_cnt += 1;
        wait_ms(400);
    }

    /* close SPI link */
    i = lgw_disconnect();
    if (i != LGW_REG_SUCCESS) {
        MSG("ERROR: lgw_disconnect() did not return SUCCESS\n");
        return EXIT_FAILURE;
    }

    MSG("INFO: Exiting LoRa Gateway v1.5 LBT test successfully\n");
    return EXIT_SUCCESS;
}