コード例 #1
0
ファイル: util_tx_test.c プロジェクト: batulzii/lora_gateway
int main(int argc, char **argv)
{
	int i;
	uint8_t status_var;
	
	/* user entry parameters */
	int xi = 0;
	double xd = 0.0;
	
	/* application parameters */
	uint32_t f_target = 0; /* target frequency - invalid default value, has to be specified by user */
	int sf = 10; /* SF10 by default */
	int cr = 1; /* CR1 aka 4/5 by default */
	int bw = 125; /* 125kHz bandwidth by default */
	int pow = 14; /* 14 dBm by default */
	int preamb = 8; /* 8 symbol preamble by default */
	int pl_size = 16; /* 16 bytes payload by default */
	int delay = 1000; /* 1 second between packets by default */
	int repeat = -1; /* by default, repeat until stopped */
	bool invert = false;
	
	/* RF configuration (TX fail if RF chain is not enabled) */
	enum lgw_radio_type_e radio_type = LGW_RADIO_TYPE_NONE;
	uint8_t clocksource = 1; /* Radio B is source by default */
	struct lgw_conf_board_s boardconf;
	struct lgw_conf_rxrf_s rfconf;
	
	/* allocate memory for packet sending */
	struct lgw_pkt_tx_s txpkt; /* array containing 1 outbound packet + metadata */
	
	/* loop variables (also use as counters in the packet payload) */
	uint16_t cycle_count = 0;
	
	/* parse command line options */
	while ((i = getopt (argc, argv, "hif:b:s:c:p:l:z:t:x:r:k")) != -1) {
		switch (i) {
			case 'h':
				usage();
				return EXIT_FAILURE;
				break;
			
			case 'f': /* -f <float> target frequency in MHz */
				i = sscanf(optarg, "%lf", &xd);
				if ((i != 1) || (xd < 30.0) || (xd > 3000.0)) {
					MSG("ERROR: invalid TX frequency\n");
					usage();
					return EXIT_FAILURE;
				} else {
					f_target = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
				}
				break;
			
			case 'b': /* -b <int> Modulation bandwidth in kHz */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || ((xi != 125)&&(xi != 250)&&(xi != 500))) {
					MSG("ERROR: invalid LoRa bandwidth\n");
					usage();
					return EXIT_FAILURE;
				} else {
					bw = xi;
				}
				break;
			
			case 's': /* -s <int> Spreading Factor */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 7) || (xi > 12)) {
					MSG("ERROR: invalid spreading factor\n");
					usage();
					return EXIT_FAILURE;
				} else {
					sf = xi;
				}
				break;
			
			case 'c': /* -c <int> Coding Rate */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 1) || (xi > 4)) {
					MSG("ERROR: invalid coding rate\n");
					usage();
					return EXIT_FAILURE;
				} else {
					cr = xi;
				}
				break;
			
			case 'p': /* -p <int> RF power */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < -60) || (xi > 60)) {
					MSG("ERROR: invalid RF power\n");
					usage();
					return EXIT_FAILURE;
				} else {
					pow = xi;
				}
				break;
			
			case 'l': /* -r <uint> preamble length (symbols) */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 6)) {
					MSG("ERROR: preamble length must be >6 symbols \n");
					usage();
					return EXIT_FAILURE;
				} else {
					preamb = xi;
				}
				break;
			
			case 'z': /* -z <uint> payload length (bytes) */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi <= 0)) {
					MSG("ERROR: invalid payload size\n");
					usage();
					return EXIT_FAILURE;
				} else {
					pl_size = xi;
				}
				break;
			
			case 't': /* -t <int> pause between packets (ms) */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 0)) {
					MSG("ERROR: invalid time between packets\n");
					usage();
					return EXIT_FAILURE;
				} else {
					delay = xi;
				}
				break;
			
			case 'x': /* -x <int> numbers of times the sequence is repeated */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < -1)) {
					MSG("ERROR: invalid number of repeats\n");
					usage();
					return EXIT_FAILURE;
				} else {
					repeat = xi;
				}
				break;

			case 'r': /* <int> Radio type (1255, 1257) */
				sscanf(optarg, "%i", &xi);
				switch (xi) {
					case 1255:
						radio_type = LGW_RADIO_TYPE_SX1255;
						break;
					case 1257:
						radio_type = LGW_RADIO_TYPE_SX1257;
						break;
					default:
						printf("ERROR: invalid radio type\n");
						usage();
						return EXIT_FAILURE;
				}
				break;

			case 'i': /* -i send packet using inverted modulation polarity */
				invert = true;
				break;

			case 'k': /* <int> Concentrator clock source (Radio A or Radio B) */
				sscanf(optarg, "%i", &xi);
				clocksource = (uint8_t)xi;
				break;

			default:
				MSG("ERROR: argument parsing\n");
				usage();
				return EXIT_FAILURE;
		}
	}
	
	/* check parameter sanity */
	if (f_target == 0) {
		MSG("ERROR: frequency parameter not set, please use -f option to specify it.\n");
		return EXIT_FAILURE;
	}
	if (radio_type == LGW_RADIO_TYPE_NONE) {
		MSG("ERROR: radio type parameter not properly set, please use -r option to specify it.\n");
		return EXIT_FAILURE;
	}
	printf("Sending %i packets on %u Hz (BW %i kHz, SF %i, CR %i, %i bytes payload, %i symbols preamble) at %i dBm, with %i ms between each\n", repeat, f_target, bw, sf, cr, pl_size, preamb, pow, delay);
	
	/* 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);
	
	/* starting the concentrator */
	/* board config */
	memset(&boardconf, 0, sizeof(boardconf));

	boardconf.lorawan_public = true;
	boardconf.clksrc = clocksource;
	lgw_board_setconf(boardconf);

	/* RF config */
	memset(&rfconf, 0, sizeof(rfconf));

	rfconf.enable = true;
	rfconf.freq_hz = f_target;
	rfconf.rssi_offset = DEFAULT_RSSI_OFFSET;
	rfconf.type = radio_type;
	rfconf.tx_enable = true;
	lgw_rxrf_setconf(RF_CHAIN, rfconf);

	i = lgw_start();
	if (i == LGW_HAL_SUCCESS) {
		MSG("INFO: concentrator started, packet can be sent\n");
	} else {
		MSG("ERROR: failed to start the concentrator\n");
		return EXIT_FAILURE;
	}
	
	/* fill-up payload and parameters */
	memset(&txpkt, 0, sizeof(txpkt));
	txpkt.freq_hz = f_target;
	txpkt.tx_mode = IMMEDIATE;
	txpkt.rf_chain = RF_CHAIN;
	txpkt.rf_power = pow;
	txpkt.modulation = MOD_LORA;
	switch (bw) {
		case 125: txpkt.bandwidth = BW_125KHZ; break;
		case 250: txpkt.bandwidth = BW_250KHZ; break;
		case 500: txpkt.bandwidth = BW_500KHZ; break;
		default:
			MSG("ERROR: invalid 'bw' variable\n");
			return EXIT_FAILURE;
	}
	switch (sf) {
		case  7: txpkt.datarate = DR_LORA_SF7;  break;
		case  8: txpkt.datarate = DR_LORA_SF8;  break;
		case  9: txpkt.datarate = DR_LORA_SF9;  break;
		case 10: txpkt.datarate = DR_LORA_SF10; break;
		case 11: txpkt.datarate = DR_LORA_SF11; break;
		case 12: txpkt.datarate = DR_LORA_SF12; break;
		default:
			MSG("ERROR: invalid 'sf' variable\n");
			return EXIT_FAILURE;
	}
	switch (cr) {
		case 1: txpkt.coderate = CR_LORA_4_5; break;
		case 2: txpkt.coderate = CR_LORA_4_6; break;
		case 3: txpkt.coderate = CR_LORA_4_7; break;
		case 4: txpkt.coderate = CR_LORA_4_8; break;
		default:
			MSG("ERROR: invalid 'cr' variable\n");
			return EXIT_FAILURE;
	}
	txpkt.invert_pol = invert;
	txpkt.preamble = preamb;
	txpkt.size = pl_size;
	strcpy((char *)txpkt.payload, "TEST**abcdefghijklmnopqrstuvwxyz#0123456789#ABCDEFGHIJKLMNOPQRSTUVWXYZ#0123456789#abcdefghijklmnopqrstuvwxyz#0123456789#ABCDEFGHIJKLMNOPQRSTUVWXYZ#0123456789#abcdefghijklmnopqrstuvwxyz#0123456789#ABCDEFGHIJKLMNOPQRSTUVWXYZ#0123456789#abcdefghijklmnopqrs#" ); /* abc.. is for padding */
	
	/* main loop */
	cycle_count = 0;
	while ((repeat == -1) || (cycle_count < repeat)) {
		++cycle_count;
		
		/* refresh counters in payload (big endian, for readability) */
		txpkt.payload[4] = (uint8_t)(cycle_count >> 8); /* MSB */
		txpkt.payload[5] = (uint8_t)(cycle_count & 0x00FF); /* LSB */
		
		/* send packet */
		printf("Sending packet number %u ...", cycle_count);
		i = lgw_send(txpkt); /* non-blocking scheduling of TX packet */
		if (i != LGW_HAL_SUCCESS) {
			printf("ERROR\n");
			return EXIT_FAILURE;
		}
		
		/* wait for packet to finish sending */
		do {
			wait_ms(5);
			lgw_status(TX_STATUS, &status_var); /* get TX status */
		} while (status_var != TX_FREE);
		printf("OK\n");
		
		/* wait inter-packet delay */
		wait_ms(delay);
		
		/* exit loop on user signals */
		if ((quit_sig == 1) || (exit_sig == 1)) {
			break;
		}
	}
	
	/* clean up before leaving */
	lgw_stop();
	
	printf("Exiting LoRa concentrator TX test program\n");
	return EXIT_SUCCESS;
}
コード例 #2
0
int main(int argc, char **argv)
{
	int i, j; /* loop and temporary variables */
	struct timespec sleep_time = {0, 3000000}; /* 3 ms */
	
	/* clock and log rotation management */
	int log_rotate_interval = 3600; /* by default, rotation every hour */
	int time_check = 0; /* variable used to limit the number of calls to time() function */
	unsigned long pkt_in_log = 0; /* count the number of packet written in each log file */
	
	/* configuration file related */
	const char global_conf_fname[] = "global_conf.json"; /* contain global (typ. network-wide) configuration */
	const char local_conf_fname[] = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
	const char debug_conf_fname[] = "debug_conf.json"; /* if present, all other configuration files are ignored */
	
	/* allocate memory for packet fetching and processing */
	struct lgw_pkt_rx_s rxpkt[16]; /* array containing up to 16 inbound packets metadata */
	struct lgw_pkt_rx_s *p; /* pointer on a RX packet */
	int nb_pkt;
	
	/* local timestamp variables until we get accurate GPS time */
	struct timespec fetch_time;
	char fetch_timestamp[30];
	struct tm * x;
	
	/* parse command line options */
	while ((i = getopt (argc, argv, "hr:")) != -1) {
		switch (i) {
			case 'h':
				usage();
				return EXIT_FAILURE;
				break;
			
			case 'r':
				log_rotate_interval = atoi(optarg);
				if ((log_rotate_interval == 0) || (log_rotate_interval < -1)) {
					MSG( "ERROR: Invalid argument for -r option\n");
					return EXIT_FAILURE;
				}
				break;
			
			default:
				MSG("ERROR: argument parsing use -h option for help\n");
				usage();
				return EXIT_FAILURE;
		}
	}
	
	/* 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);
	
	/* configuration files management */
	if (access(debug_conf_fname, R_OK) == 0) {
	/* if there is a debug conf, parse only the debug conf */
		MSG("INFO: found debug configuration file %s, other configuration files will be ignored\n", debug_conf_fname);
		parse_SX1301_configuration(debug_conf_fname);
		parse_gateway_configuration(debug_conf_fname);
	} else if (access(global_conf_fname, R_OK) == 0) {
	/* if there is a global conf, parse it and then try to parse local conf  */
		MSG("INFO: found global configuration file %s, trying to parse it\n", global_conf_fname);
		parse_SX1301_configuration(global_conf_fname);
		parse_gateway_configuration(global_conf_fname);
		if (access(local_conf_fname, R_OK) == 0) {
			MSG("INFO: found local configuration file %s, trying to parse it\n", local_conf_fname);
			parse_SX1301_configuration(local_conf_fname);
			parse_gateway_configuration(local_conf_fname);
		}
	} else if (access(local_conf_fname, R_OK) == 0) {
	/* if there is only a local conf, parse it and that's all */
		MSG("INFO: found local configuration file %s, trying to parse it\n", local_conf_fname);
		parse_SX1301_configuration(local_conf_fname);
		parse_gateway_configuration(local_conf_fname);
	} else {
		MSG("ERROR: failed to find any configuration file named %s, %s or %s\n", global_conf_fname, local_conf_fname, debug_conf_fname);
		return EXIT_FAILURE;
	}
	
	/* starting the concentrator */
	i = lgw_start();
	if (i == LGW_HAL_SUCCESS) {
		MSG("INFO: concentrator started, packet can now be received\n");
	} else {
		MSG("ERROR: failed to start the concentrator\n");
		return EXIT_FAILURE;
	}
	
	/* transform the MAC address into a string */
	sprintf(lgwm_str, "%08X%08X", (uint32_t)(lgwm >> 32), (uint32_t)(lgwm & 0xFFFFFFFF));
	
	/* opening log file and writing CSV header*/
	time(&now_time);
	open_log();
	
	/* main loop */
	while ((quit_sig != 1) && (exit_sig != 1)) {
		/* fetch packets */
		nb_pkt = lgw_receive(ARRAY_SIZE(rxpkt), rxpkt);
		if (nb_pkt == LGW_HAL_ERROR) {
			MSG("ERROR: failed packet fetch, exiting\n");
			return EXIT_FAILURE;
		} else if (nb_pkt == 0) {
			clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep_time, NULL); /* wait a short time if no packets */
		} else {
			/* local timestamp generation until we get accurate GPS time */
			clock_gettime(CLOCK_REALTIME, &fetch_time);
			x = gmtime(&(fetch_time.tv_sec));
			sprintf(fetch_timestamp,"%04i-%02i-%02i %02i:%02i:%02i.%03liZ",(x->tm_year)+1900,(x->tm_mon)+1,x->tm_mday,x->tm_hour,x->tm_min,x->tm_sec,(fetch_time.tv_nsec)/1000000); /* ISO 8601 format */
		}
		
		/* log packets */
		for (i=0; i < nb_pkt; ++i) {
			p = &rxpkt[i];
			
			/* writing gateway ID */
			fprintf(log_file, "\"%08X%08X\",", (uint32_t)(lgwm >> 32), (uint32_t)(lgwm & 0xFFFFFFFF));
			
			/* writing node MAC address */
			fputs("\"\",", log_file); // TODO: need to parse payload
			
			/* writing UTC timestamp*/
			fprintf(log_file, "\"%s\",", fetch_timestamp);
			// TODO: replace with GPS time when available
			
			/* writing internal clock */
			fprintf(log_file, "%10u,", p->count_us);
			
			/* writing RX frequency */
			fprintf(log_file, "%10u,", p->freq_hz);
			
			/* writing RF chain */
			fprintf(log_file, "%u,", p->rf_chain);
			
			/* writing RX modem/IF chain */
			fprintf(log_file, "%2d,", p->if_chain);
			
			/* writing status */
			switch(p->status) {
				case STAT_CRC_OK:	fputs("\"CRC_OK\" ,", log_file); break;
				case STAT_CRC_BAD:	fputs("\"CRC_BAD\",", log_file); break;
				case STAT_NO_CRC:	fputs("\"NO_CRC\" ,", log_file); break;
				case STAT_UNDEFINED:fputs("\"UNDEF\"  ,", log_file); break;
				default: fputs("\"ERR\"    ,", log_file);
			}
			
			/* writing payload size */
			fprintf(log_file, "%3u,", p->size);
			
			/* writing modulation */
			switch(p->modulation) {
				case MOD_LORA:	fputs("\"LORA\",", log_file); break;
				case MOD_FSK:	fputs("\"FSK\" ,", log_file); break;
				default: fputs("\"ERR\" ,", log_file);
			}
			
			/* writing bandwidth */
			switch(p->bandwidth) {
				case BW_500KHZ:	fputs("500000,", log_file); break;
				case BW_250KHZ:	fputs("250000,", log_file); break;
				case BW_125KHZ:	fputs("125000,", log_file); break;
				case BW_62K5HZ:	fputs("62500 ,", log_file); break;
				case BW_31K2HZ:	fputs("31200 ,", log_file); break;
				case BW_15K6HZ:	fputs("15600 ,", log_file); break;
				case BW_7K8HZ:	fputs("7800  ,", log_file); break;
				case BW_UNDEFINED: fputs("0     ,", log_file); break;
				default: fputs("-1    ,", log_file);
			}
			
			/* writing datarate */
			if (p->modulation == MOD_LORA) {
				switch (p->datarate) {
					case DR_LORA_SF7:	fputs("\"SF7\"   ,", log_file); break;
					case DR_LORA_SF8:	fputs("\"SF8\"   ,", log_file); break;
					case DR_LORA_SF9:	fputs("\"SF9\"   ,", log_file); break;
					case DR_LORA_SF10:	fputs("\"SF10\"  ,", log_file); break;
					case DR_LORA_SF11:	fputs("\"SF11\"  ,", log_file); break;
					case DR_LORA_SF12:	fputs("\"SF12\"  ,", log_file); break;
					default: fputs("\"ERR\"   ,", log_file);
				}
			} else if (p->modulation == MOD_FSK) {
				fprintf(log_file, "\"%6u\",", p->datarate);
			} else {
				fputs("\"ERR\"   ,", log_file);
			}
			
			/* writing coderate */
			switch (p->coderate) {
				case CR_LORA_4_5:	fputs("\"4/5\",", log_file); break;
				case CR_LORA_4_6:	fputs("\"2/3\",", log_file); break;
				case CR_LORA_4_7:	fputs("\"4/7\",", log_file); break;
				case CR_LORA_4_8:	fputs("\"1/2\",", log_file); break;
				case CR_UNDEFINED:	fputs("\"\"   ,", log_file); break;
				default: fputs("\"ERR\",", log_file);
			}
			
			/* writing packet RSSI */
			fprintf(log_file, "%+.0f,", p->rssi);
			
			/* writing packet average SNR */
			fprintf(log_file, "%+5.1f,", p->snr);
			
			/* writing hex-encoded payload (bundled in 32-bit words) */
			fputs("\"", log_file);
			for (j = 0; j < p->size; ++j) {
				if ((j > 0) && (j%4 == 0)) fputs("-", log_file);
				fprintf(log_file, "%02X", p->payload[j]);
			}
			
			/* end of log file line */
			fputs("\"\n", log_file);
			fflush(log_file);
			++pkt_in_log;
		}
		
		/* check time and rotate log file if necessary */
		++time_check;
		if (time_check >= 8) {
			time_check = 0;
			time(&now_time);
			if (difftime(now_time, log_start_time) > log_rotate_interval) {
				fclose(log_file);
				MSG("INFO: log file %s closed, %lu packet(s) recorded\n", log_file_name, pkt_in_log);
				pkt_in_log = 0;
				open_log();
			}
		}
	}
	
	if (exit_sig == 1) {
		/* clean up before leaving */
		i = lgw_stop();
		if (i == LGW_HAL_SUCCESS) {
			MSG("INFO: concentrator stopped successfully\n");
		} else {
			MSG("WARNING: failed to stop concentrator successfully\n");
		}
		fclose(log_file);
		MSG("INFO: log file %s closed, %lu packet(s) recorded\n", log_file_name, pkt_in_log);
	}
	
	MSG("INFO: Exiting packet logger program\n");
	return EXIT_SUCCESS;
}
コード例 #3
0
int main()
{
	struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
	
	struct lgw_conf_rxrf_s rfconf;
	struct lgw_conf_rxif_s ifconf;
	
	struct lgw_pkt_rx_s rxpkt[4]; /* array containing up to 4 inbound packets metadata */
	struct lgw_pkt_tx_s txpkt; /* configuration and metadata for an outbound packet */
	struct lgw_pkt_rx_s *p; /* pointer on a RX packet */
	
	int i, j;
	int nb_pkt;
	
	uint32_t tx_cnt = 0;
	unsigned long loop_cnt = 0;
	uint8_t status_var = 0;
	
	/* 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);
	
	/* beginning of LoRa concentrator-specific code */
	printf("Beginning of test for loragw_hal.c\n");
	
	printf("*** Library version information ***\n%s\n\n", lgw_version_info());
	
	/* set configuration for RF chains */
	memset(&rfconf, 0, sizeof(rfconf));
	
	rfconf.enable = true;
	rfconf.freq_hz = F_RX_0;
	lgw_rxrf_setconf(0, rfconf); /* radio A, f0 */
	
	rfconf.enable = true;
	rfconf.freq_hz = F_RX_1;
	lgw_rxrf_setconf(1, rfconf); /* radio B, f1 */
	
	/* set configuration for LoRa multi-SF channels (bandwidth cannot be set) */
	memset(&ifconf, 0, sizeof(ifconf));
	
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = -300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(0, ifconf); /* chain 0: LoRa 125kHz, all SF, on f0 - 0.3 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = 300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(1, ifconf); /* chain 1: LoRa 125kHz, all SF, on f0 + 0.3 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = -300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(2, ifconf); /* chain 2: LoRa 125kHz, all SF, on f1 - 0.3 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = 300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(3, ifconf); /* chain 3: LoRa 125kHz, all SF, on f1 + 0.3 MHz */
	
	#if (LGW_MULTI_NB >= 8)
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = -100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(4, ifconf); /* chain 4: LoRa 125kHz, all SF, on f0 - 0.1 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = 100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(5, ifconf); /* chain 5: LoRa 125kHz, all SF, on f0 + 0.1 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = -100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(6, ifconf); /* chain 6: LoRa 125kHz, all SF, on f1 - 0.1 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = 100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(7, ifconf); /* chain 7: LoRa 125kHz, all SF, on f1 + 0.1 MHz */
	#endif
	
	/* set configuration for LoRa 'stand alone' channel */
	memset(&ifconf, 0, sizeof(ifconf));
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = 0;
	ifconf.bandwidth = BW_250KHZ;
	ifconf.datarate = DR_LORA_SF10;
	lgw_rxif_setconf(8, ifconf); /* chain 8: LoRa 250kHz, SF10, on f0 MHz */
	
	/* set configuration for FSK channel */
	memset(&ifconf, 0, sizeof(ifconf));
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = 0;
	ifconf.bandwidth = BW_250KHZ;
	ifconf.datarate = 64000;
	lgw_rxif_setconf(9, ifconf); /* chain 9: FSK 64kbps, on f1 MHz */
	
	/* set configuration for TX packet */
	
	memset(&txpkt, 0, sizeof(txpkt));
	txpkt.freq_hz = F_TX;
	txpkt.tx_mode = IMMEDIATE;
	txpkt.rf_power = 10;
	txpkt.modulation = MOD_LORA;
	txpkt.bandwidth = BW_250KHZ;
	txpkt.datarate = DR_LORA_SF10;
	txpkt.coderate = CR_LORA_4_5;
	strcpy((char *)txpkt.payload, "TX.TEST.LORA.GW.????" );
	txpkt.size = 20;
	txpkt.preamble = 6;
	txpkt.rf_chain = 0;
/*	
	memset(&txpkt, 0, sizeof(txpkt));
	txpkt.freq_hz = F_TX;
	txpkt.tx_mode = IMMEDIATE;
	txpkt.rf_power = 10;
	txpkt.modulation = MOD_FSK;
	txpkt.f_dev = 50;
	txpkt.datarate = 64000;
	strcpy((char *)txpkt.payload, "TX.TEST.LORA.GW.????" );
	txpkt.size = 20;
	txpkt.preamble = 4;
	txpkt.rf_chain = 0;
*/	
	
	/* connect, configure and start the LoRa concentrator */
	i = lgw_start();
	if (i == LGW_HAL_SUCCESS) {
		printf("*** Concentrator started ***\n");
	} else {
		printf("*** Impossible to start concentrator ***\n");
		return -1;
	}
	
	/* once configured, dump content of registers to a file, for reference */
	// FILE * reg_dump = NULL;
	// reg_dump = fopen("reg_dump.log", "w");
	// if (reg_dump != NULL) {
		// lgw_reg_check(reg_dump);
		// fclose(reg_dump);
	// }
	
	while ((quit_sig != 1) && (exit_sig != 1)) {
		loop_cnt++;
		
		/* fetch N packets */
		nb_pkt = lgw_receive(ARRAY_SIZE(rxpkt), rxpkt);
		
		if (nb_pkt == 0) {
			wait_ms(300);
		} else {
			/* display received packets */
			for(i=0; i < nb_pkt; ++i) {
				p = &rxpkt[i];
				printf("---\nRcv pkt #%d >>", i+1);
				if (p->status == STAT_CRC_OK) {
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u", p->size);
					switch (p-> modulation) {
						case MOD_LORA: printf(" LoRa"); break;
						case MOD_FSK: printf(" FSK"); break;
						default: printf(" modulation?");
					}
					switch (p->datarate) {
						case DR_LORA_SF7: printf(" SF7"); break;
						case DR_LORA_SF8: printf(" SF8"); break;
						case DR_LORA_SF9: printf(" SF9"); break;
						case DR_LORA_SF10: printf(" SF10"); break;
						case DR_LORA_SF11: printf(" SF11"); break;
						case DR_LORA_SF12: printf(" SF12"); break;
						default: printf(" datarate?");
					}
					switch (p->coderate) {
						case CR_LORA_4_5: printf(" CR1(4/5)"); break;
						case CR_LORA_4_6: printf(" CR2(2/3)"); break;
						case CR_LORA_4_7: printf(" CR3(4/7)"); break;
						case CR_LORA_4_8: printf(" CR4(1/2)"); break;
						default: printf(" coderate?");
					}
					printf("\n");
					printf(" RSSI:%+6.1f SNR:%+5.1f (min:%+5.1f, max:%+5.1f) payload:\n", p->rssi, p->snr, p->snr_min, p->snr_max);
					
					for (j = 0; j < p->size; ++j) {
						printf(" %02X", p->payload[j]);
					}
					printf(" #\n");
				} else if (p->status == STAT_CRC_BAD) {
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u\n", p->size);
					printf(" CRC error, damaged packet\n\n");
				} else if (p->status == STAT_NO_CRC){
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u\n", p->size);
					printf(" no CRC\n\n");
				} else {
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u\n", p->size);
					printf(" invalid status ?!?\n\n");
				}
			}
		}
		
		/* send a packet every X loop */
		if (loop_cnt%16 == 0) {
			/* 32b counter in the payload, big endian */
			txpkt.payload[16] = 0xff & (tx_cnt >> 24);
			txpkt.payload[17] = 0xff & (tx_cnt >> 16);
			txpkt.payload[18] = 0xff & (tx_cnt >> 8);
			txpkt.payload[19] = 0xff & tx_cnt;
			i = lgw_send(txpkt); /* non-blocking scheduling of TX packet */
			j = 0;
			printf("+++\nSending packet #%d, rf path %d, return %d\nstatus -> ", tx_cnt, txpkt.rf_chain, i);
			do {
				++j;
				wait_ms(100);
				lgw_status(TX_STATUS, &status_var); /* get TX status */
				printf("%d:", status_var);
			} while ((status_var != TX_FREE) && (j < 100));
			++tx_cnt;
			printf("\nTX finished\n");
		}
	}
コード例 #4
0
ファイル: util_tx_test.c プロジェクト: JiapengLi/lora_gateway
int main(int argc, char **argv)
{
	int i;
	uint8_t status_var;
	
	/* user entry parameters */
	int xi = 0;
	double xd = 0.0;
	uint32_t f_min;
	uint32_t f_max;
	
	/* application parameters */
	uint32_t f_target = lowfreq[RF_CHAIN]/2 + upfreq[RF_CHAIN]/2; /* target frequency */
	int sf = 10; /* SF10 by default */
	int bw = 125; /* 125kHz bandwidth by default */
	int pow = 14; /* 14 dBm by default */
	int preamb = 8; /* 8 symbol preamble by default */
	int pl_size = 16; /* 16 bytes payload by default */
	int delay = 1000; /* 1 second between packets by default */
	int repeat = -1; /* by default, repeat until stopped */
	bool invert = false;
	
	/* RF configuration (TX fail if RF chain is not enabled) */
	const struct lgw_conf_rxrf_s rfconf = {true, lowfreq[RF_CHAIN]};
	
	/* allocate memory for packet sending */
	struct lgw_pkt_tx_s txpkt; /* array containing 1 outbound packet + metadata */
	
	/* loop variables (also use as counters in the packet payload) */
	uint16_t cycle_count = 0;
	
	/* parse command line options */
	while ((i = getopt (argc, argv, "hf:s:b:p:r:z:t:x:i")) != -1) {
		switch (i) {
			case 'h':
				usage();
				return EXIT_FAILURE;
				break;
			
			case 'f': /* -f <float> target frequency in MHz */
				i = sscanf(optarg, "%lf", &xd);
				if ((i != 1) || (xd < 30.0) || (xd > 3000.0)) {
					MSG("ERROR: invalid TX frequency\n");
					usage();
					return EXIT_FAILURE;
				} else {
					f_target = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
				}
				break;
			
			case 's': /* -s <int> Spreading Factor */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 7) || (xi > 12)) {
					MSG("ERROR: invalid spreading factor\n");
					usage();
					return EXIT_FAILURE;
				} else {
					sf = xi;
				}
				break;
			
			case 'b': /* -b <int> Modulation bandwidth in kHz */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || ((xi != 125)&&(xi != 250)&&(xi != 500))) {
					MSG("ERROR: invalid LoRa bandwidth\n");
					usage();
					return EXIT_FAILURE;
				} else {
					bw = xi;
				}
				break;
			
			case 'p': /* -p <int> RF power */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < -60) || (xi > 60)) {
					MSG("ERROR: invalid RF power\n");
					usage();
					return EXIT_FAILURE;
				} else {
					pow = xi;
				}
				break;
			
			case 'r': /* -r <uint> preamble length (symbols) */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 6)) {
					MSG("ERROR: preamble length must be >6 symbols \n");
					usage();
					return EXIT_FAILURE;
				} else {
					preamb = xi;
				}
				break;
			
			case 'z': /* -z <uint> payload length (bytes) */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi <= 0)) {
					MSG("ERROR: invalid payload size\n");
					usage();
					return EXIT_FAILURE;
				} else {
					pl_size = xi;
				}
				break;
			
			case 't': /* -t <int> pause between packets (ms) */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < 0)) {
					MSG("ERROR: invalid time between packets\n");
					usage();
					return EXIT_FAILURE;
				} else {
					delay = xi;
				}
				break;
			
			case 'x': /* -x <int> numbers of times the sequence is repeated */
				i = sscanf(optarg, "%i", &xi);
				if ((i != 1) || (xi < -1)) {
					MSG("ERROR: invalid number of repeats\n");
					usage();
					return EXIT_FAILURE;
				} else {
					repeat = xi;
				}
				break;
			
			case 'i': /* -i send packet using inverted modulation polarity */
				invert = true;
				break;
			
			default:
				MSG("ERROR: argument parsing\n");
				usage();
				return EXIT_FAILURE;
		}
	}
	
	/* check parameter sanity */
	f_min = lowfreq[RF_CHAIN] + (500 * bw);
	f_max = upfreq[RF_CHAIN] - (500 * bw);
	if ((f_target < f_min) || (f_target > f_max)) {
		MSG("ERROR: frequency out of authorized band (accounting for modulation bandwidth)\n");
		return EXIT_FAILURE;
	}
	printf("Sending %i packets on %u Hz (BW %i kHz, SF %i, %i bytes payload, %i symbols preamble) at %i dBm, with %i ms between each\n", repeat, f_target, bw, sf, pl_size, preamb, pow, delay);
	
	/* 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);
	
	/* starting the concentrator */
	lgw_rxrf_setconf(RF_CHAIN, rfconf);
	i = lgw_start();
	if (i == LGW_HAL_SUCCESS) {
		MSG("INFO: concentrator started, packet can be sent\n");
	} else {
		MSG("ERROR: failed to start the concentrator\n");
		return EXIT_FAILURE;
	}
	
	/* fill-up payload and parameters */
	memset(&txpkt, 0, sizeof(txpkt));
	txpkt.freq_hz = f_target;
	txpkt.tx_mode = IMMEDIATE;
	txpkt.rf_chain = RF_CHAIN;
	txpkt.rf_power = pow;
	txpkt.modulation = MOD_LORA;
	switch (bw) {
		case 125: txpkt.bandwidth = BW_125KHZ; break;
		case 250: txpkt.bandwidth = BW_250KHZ; break;
		case 500: txpkt.bandwidth = BW_500KHZ; break;
		default:
			MSG("ERROR: invalid 'bw' variable\n");
			return EXIT_FAILURE;
	}
	switch (sf) {
		case  7: txpkt.datarate = DR_LORA_SF7;  break;
		case  8: txpkt.datarate = DR_LORA_SF8;  break;
		case  9: txpkt.datarate = DR_LORA_SF9;  break;
		case 10: txpkt.datarate = DR_LORA_SF10; break;
		case 11: txpkt.datarate = DR_LORA_SF11; break;
		case 12: txpkt.datarate = DR_LORA_SF12; break;
		default:
			MSG("ERROR: invalid 'sf' variable\n");
			return EXIT_FAILURE;
	}
	txpkt.coderate = CR_LORA_4_5;
	txpkt.invert_pol = invert;
	txpkt.preamble = preamb;
	txpkt.size = pl_size;
	strcpy((char *)txpkt.payload, "TEST**abcdefghijklmnopqrstuvwxyz0123456789" ); /* abc.. is for padding */
	
	/* main loop */
	cycle_count = 0;
	while ((repeat == -1) || (cycle_count < repeat)) {
		++cycle_count;
		
		/* refresh counters in payload (big endian, for readability) */
		txpkt.payload[4] = (uint8_t)(cycle_count >> 8); /* MSB */
		txpkt.payload[5] = (uint8_t)(cycle_count & 0x00FF); /* LSB */
		
		/* send packet */
		printf("Sending packet number %u ...", cycle_count);
		i = lgw_send(txpkt); /* non-blocking scheduling of TX packet */
		if (i != LGW_HAL_SUCCESS) {
			printf("ERROR\n");
			return EXIT_FAILURE;
		}
		
		/* wait for packet to finish sending */
		do {
			wait_ms(5);
			lgw_status(TX_STATUS, &status_var); /* get TX status */
		} while (status_var != TX_FREE);
		printf("OK\n");
		
		/* wait inter-packet delay */
		wait_ms(delay);
		
		/* exit loop on user signals */
		if ((quit_sig == 1) || (exit_sig == 1)) {
			break;
		}
	}
	
	/* clean up before leaving */
	lgw_stop();
	
	printf("Exiting LoRa concentrator TX test program\n");
	return EXIT_SUCCESS;
}
コード例 #5
0
int main(int argc, char **argv)
{
	struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
	
	struct lgw_conf_board_s boardconf;
	struct lgw_conf_rxrf_s rfconf;
	struct lgw_conf_rxif_s ifconf;
	
	struct lgw_pkt_rx_s rxpkt[4]; /* array containing up to 4 inbound packets metadata */
	struct lgw_pkt_tx_s txpkt; /* configuration and metadata for an outbound packet */
	struct lgw_pkt_rx_s *p; /* pointer on a RX packet */
	
	int i, j;
	int nb_pkt;
	uint32_t fa = 0, fb = 0, ft = 0;
	enum lgw_radio_type_e radio_type = LGW_RADIO_TYPE_NONE;
	uint8_t clocksource = 0; /* Radio A is source in MTAC-LORA */
	
	uint32_t tx_cnt = 0;
	unsigned long loop_cnt = 0;
	uint8_t status_var = 0;
	double xd = 0.0;
	int xi = 0;

	/* parse command line options */
	while ((i = getopt (argc, argv, "ha:b:t:r:k:")) != -1) {
		switch (i) {
			case 'h':
				usage();
				return -1;
				break;
			case 'a': /* <float> Radio A RX frequency in MHz */
				sscanf(optarg, "%lf", &xd);
				fa = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
				break;
			case 'b': /* <float> Radio B RX frequency in MHz */
				sscanf(optarg, "%lf", &xd);
				fb = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
				break;
			case 't': /* <float> Radio TX frequency in MHz */
				sscanf(optarg, "%lf", &xd);
				ft = (uint32_t)((xd*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
				break;
			case 'r': /* <int> Radio type (1255, 1257) */
				sscanf(optarg, "%i", &xi);
				switch (xi) {
					case 1255:
						radio_type = LGW_RADIO_TYPE_SX1255;
						break;
					case 1257:
						radio_type = LGW_RADIO_TYPE_SX1257;
						break;
					default:
						printf("ERROR: invalid radio type\n");
						usage();
						return -1;
				}
				break;
			case 'k': /* <int> Concentrator clock source (Radio A or Radio B) */
				sscanf(optarg, "%i", &xi);
				clocksource = (uint8_t)xi;
				break;
			default:
				printf("ERROR: argument parsing\n");
				usage();
				return -1;
		}
	}

	/* check input parameters */
	if ((fa == 0) || (fb == 0) || (ft == 0)) {
		printf("ERROR: missing frequency input parameter:\n");
		printf("  Radio A RX: %u\n", fa);
		printf("  Radio B RX: %u\n", fb);
		printf("  Radio TX: %u\n", ft);
		usage();
		return -1;
	}

	if (radio_type == LGW_RADIO_TYPE_NONE) {
		printf("ERROR: missing radio type parameter:\n");
		usage();
		return -1;
	}

	/* 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);

	/* beginning of LoRa concentrator-specific code */
	printf("Beginning of test for loragw_hal.c\n");

	printf("*** Library version information ***\n%s\n\n", lgw_version_info());

	/* set configuration for board */
	memset(&boardconf, 0, sizeof(boardconf));

	boardconf.lorawan_public = true;
	boardconf.clksrc = clocksource;
	lgw_board_setconf(boardconf);

	/* set configuration for RF chains */
	memset(&rfconf, 0, sizeof(rfconf));

	rfconf.enable = true;
	rfconf.freq_hz = fa;
	rfconf.rssi_offset = DEFAULT_RSSI_OFFSET;
	rfconf.type = radio_type;
	rfconf.tx_enable = true;
	lgw_rxrf_setconf(0, rfconf); /* radio A, f0 */

	rfconf.enable = true;
	rfconf.freq_hz = fb;
	rfconf.rssi_offset = DEFAULT_RSSI_OFFSET;
	rfconf.type = radio_type;
	rfconf.tx_enable = false;
	lgw_rxrf_setconf(1, rfconf); /* radio B, f1 */

	/* set configuration for LoRa multi-SF channels (bandwidth cannot be set) */
	memset(&ifconf, 0, sizeof(ifconf));

	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = -300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(0, ifconf); /* chain 0: LoRa 125kHz, all SF, on f0 - 0.3 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = 300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(1, ifconf); /* chain 1: LoRa 125kHz, all SF, on f0 + 0.3 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = -300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(2, ifconf); /* chain 2: LoRa 125kHz, all SF, on f1 - 0.3 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = 300000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(3, ifconf); /* chain 3: LoRa 125kHz, all SF, on f1 + 0.3 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = -100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(4, ifconf); /* chain 4: LoRa 125kHz, all SF, on f0 - 0.1 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = 100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(5, ifconf); /* chain 5: LoRa 125kHz, all SF, on f0 + 0.1 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = -100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(6, ifconf); /* chain 6: LoRa 125kHz, all SF, on f1 - 0.1 MHz */
	
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = 100000;
	ifconf.datarate = DR_LORA_MULTI;
	lgw_rxif_setconf(7, ifconf); /* chain 7: LoRa 125kHz, all SF, on f1 + 0.1 MHz */
	
	/* set configuration for LoRa 'stand alone' channel */
	memset(&ifconf, 0, sizeof(ifconf));
	ifconf.enable = true;
	ifconf.rf_chain = 0;
	ifconf.freq_hz = 0;
	ifconf.bandwidth = BW_250KHZ;
	ifconf.datarate = DR_LORA_SF10;
	lgw_rxif_setconf(8, ifconf); /* chain 8: LoRa 250kHz, SF10, on f0 MHz */
	
	/* set configuration for FSK channel */
	memset(&ifconf, 0, sizeof(ifconf));
	ifconf.enable = true;
	ifconf.rf_chain = 1;
	ifconf.freq_hz = 0;
	ifconf.bandwidth = BW_250KHZ;
	ifconf.datarate = 64000;
	lgw_rxif_setconf(9, ifconf); /* chain 9: FSK 64kbps, on f1 MHz */
	
	/* set configuration for TX packet */
	memset(&txpkt, 0, sizeof(txpkt));
	txpkt.freq_hz = ft;
	txpkt.tx_mode = IMMEDIATE;
	txpkt.rf_power = 10;
	txpkt.modulation = MOD_LORA;
	txpkt.bandwidth = BW_250KHZ;
	txpkt.datarate = DR_LORA_SF10;
	txpkt.coderate = CR_LORA_4_5;
	strcpy((char *)txpkt.payload, "TX.TEST.LORA.GW.????" );
	txpkt.size = 20;
	txpkt.preamble = 6;
	txpkt.rf_chain = 0;
/*	
	memset(&txpkt, 0, sizeof(txpkt));
	txpkt.freq_hz = F_TX;
	txpkt.tx_mode = IMMEDIATE;
	txpkt.rf_power = 10;
	txpkt.modulation = MOD_FSK;
	txpkt.f_dev = 50;
	txpkt.datarate = 64000;
	strcpy((char *)txpkt.payload, "TX.TEST.LORA.GW.????" );
	txpkt.size = 20;
	txpkt.preamble = 4;
	txpkt.rf_chain = 0;
*/	
	
	/* connect, configure and start the LoRa concentrator */
	i = lgw_start();
	if (i == LGW_HAL_SUCCESS) {
		printf("*** Concentrator started ***\n");
	} else {
		printf("*** Impossible to start concentrator ***\n");
		return -1;
	}
	
	/* once configured, dump content of registers to a file, for reference */
	// FILE * reg_dump = NULL;
	// reg_dump = fopen("reg_dump.log", "w");
	// if (reg_dump != NULL) {
		// lgw_reg_check(reg_dump);
		// fclose(reg_dump);
	// }
	
	while ((quit_sig != 1) && (exit_sig != 1)) {
		loop_cnt++;
		
		/* fetch N packets */
		nb_pkt = lgw_receive(ARRAY_SIZE(rxpkt), rxpkt);
		
		if (nb_pkt == 0) {
			wait_ms(300);
		} else {
			/* display received packets */
			for(i=0; i < nb_pkt; ++i) {
				p = &rxpkt[i];
				printf("---\nRcv pkt #%d >>", i+1);
				if (p->status == STAT_CRC_OK) {
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u", p->size);
					switch (p-> modulation) {
						case MOD_LORA: printf(" LoRa"); break;
						case MOD_FSK: printf(" FSK"); break;
						default: printf(" modulation?");
					}
					switch (p->datarate) {
						case DR_LORA_SF7: printf(" SF7"); break;
						case DR_LORA_SF8: printf(" SF8"); break;
						case DR_LORA_SF9: printf(" SF9"); break;
						case DR_LORA_SF10: printf(" SF10"); break;
						case DR_LORA_SF11: printf(" SF11"); break;
						case DR_LORA_SF12: printf(" SF12"); break;
						default: printf(" datarate?");
					}
					switch (p->coderate) {
						case CR_LORA_4_5: printf(" CR1(4/5)"); break;
						case CR_LORA_4_6: printf(" CR2(2/3)"); break;
						case CR_LORA_4_7: printf(" CR3(4/7)"); break;
						case CR_LORA_4_8: printf(" CR4(1/2)"); break;
						default: printf(" coderate?");
					}
					printf("\n");
					printf(" RSSI:%+6.1f SNR:%+5.1f (min:%+5.1f, max:%+5.1f) payload:\n", p->rssi, p->snr, p->snr_min, p->snr_max);
					
					for (j = 0; j < p->size; ++j) {
						printf(" %02X", p->payload[j]);
					}
					printf(" #\n");
				} else if (p->status == STAT_CRC_BAD) {
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u\n", p->size);
					printf(" CRC error, damaged packet\n\n");
				} else if (p->status == STAT_NO_CRC){
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u\n", p->size);
					printf(" no CRC\n\n");
				} else {
					printf(" if_chain:%2d", p->if_chain);
					printf(" tstamp:%010u", p->count_us);
					printf(" size:%3u\n", p->size);
					printf(" invalid status ?!?\n\n");
				}
			}
		}
		
		/* send a packet every X loop */
		if (loop_cnt%16 == 0) {
			/* 32b counter in the payload, big endian */
			txpkt.payload[16] = 0xff & (tx_cnt >> 24);
			txpkt.payload[17] = 0xff & (tx_cnt >> 16);
			txpkt.payload[18] = 0xff & (tx_cnt >> 8);
			txpkt.payload[19] = 0xff & tx_cnt;
			i = lgw_send(txpkt); /* non-blocking scheduling of TX packet */
			j = 0;
			printf("+++\nSending packet #%d, rf path %d, return %d\nstatus -> ", tx_cnt, txpkt.rf_chain, i);
			do {
				++j;
				wait_ms(100);
				lgw_status(TX_STATUS, &status_var); /* get TX status */
				printf("%d:", status_var);
			} while ((status_var != TX_FREE) && (j < 100));
			++tx_cnt;
			printf("\nTX finished\n");
		}
	}
コード例 #6
0
int main(int argc, char **argv)
{
    static struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */

    int i; /* loop and temporary variables */

    /* Parameter parsing */
    int option_index = 0;
    static struct option long_options[] = {
        {"dig", 1, 0, 0},
        {"dac", 1, 0, 0},
        {"mix", 1, 0, 0},
        {"pa", 1, 0, 0},
        {"mod", 1, 0, 0},
        {"sf", 1, 0, 0},
        {"bw", 1, 0, 0},
        {"br", 1, 0, 0},
        {"fdev", 1, 0, 0},
        {"bt", 1, 0, 0},
        {"notch", 1, 0, 0},
        {0, 0, 0, 0}
    };
    unsigned int arg_u;
    float arg_f;
    char arg_s[64];

    /* Application parameters */
    uint32_t freq_hz = DEFAULT_FREQ_HZ;
    uint8_t g_dig = DEFAULT_DIGITAL_GAIN;
    uint8_t g_dac = DEFAULT_DAC_GAIN;
    uint8_t g_mix = DEFAULT_MIXER_GAIN;
    uint8_t g_pa = DEFAULT_PA_GAIN;
    char mod[64] = DEFAULT_MODULATION;
    uint8_t sf = DEFAULT_SF;
    unsigned int bw_khz = DEFAULT_BW_KHZ;
    float br_kbps = DEFAULT_BR_KBPS;
    uint8_t fdev_khz = DEFAULT_FDEV_KHZ;
    uint8_t bt = DEFAULT_BT;
    uint32_t tx_notch_freq = DEFAULT_NOTCH_FREQ;

    int32_t offset_i, offset_q;

    /* RF configuration (TX fail if RF chain is not enabled) */
    enum lgw_radio_type_e radio_type = LGW_RADIO_TYPE_SX1257;
    struct lgw_conf_board_s boardconf;
    struct lgw_conf_rxrf_s rfconf;
    struct lgw_tx_gain_lut_s txlut;
    struct lgw_pkt_tx_s txpkt;


    /* Parse command line options */
    while ((i = getopt_long (argc, argv, "hud::f:r:", long_options, &option_index)) != -1) {
        switch (i) {
            case 'h':
                printf("~~~ Library version string~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
                printf(" %s\n", lgw_version_info());
                printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
                printf(" -f      <float>  Tx RF frequency in MHz [800:1000]\n");
                printf(" -r      <int>    Radio type (SX1255:1255, SX1257:1257)\n");
                printf(" --notch <uint>   Tx notch filter frequency in KhZ [126..250]\n");
                printf(" --dig   <uint>   Digital gain trim, [0:3]\n");
                printf("                   0:1, 1:7/8, 2:3/4, 3:1/2\n");
                printf(" --mix   <uint>   Radio Tx mixer gain trim, [0:15]\n");
                printf("                   15 corresponds to maximum gain, 1 LSB corresponds to 2dB step\n");
                printf(" --pa    <uint>   PA gain trim, [0:3]\n");
                printf(" --mod   <char>   Modulation type ['LORA','FSK','CW']\n");
                printf(" --sf    <uint>   LoRa Spreading Factor, [7:12]\n");
                printf(" --bw    <uint>   LoRa bandwidth in kHz, [125,250,500]\n");
                printf(" --br    <float>  FSK bitrate in kbps, [0.5:250]\n");
                printf(" --fdev  <uint>   FSK frequency deviation in kHz, [1:250]\n");
                printf(" --bt    <uint>   FSK gaussian filter BT trim, [0:3]\n");
                printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
                return EXIT_SUCCESS;
                break;

            case 0:
                if (strcmp(long_options[option_index].name,"dig") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || (arg_u > 3)) {
                        printf("ERROR: argument parsing of --dig argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else
                    {
                        g_dig = (uint8_t)arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"dac") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || (arg_u > 3)) {
                        printf("ERROR: argument parsing of --dac argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        g_dac = (uint8_t)arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"mix") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || (arg_u > 15)) {
                        printf("ERROR: argument parsing of --mix argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        g_mix = (uint8_t)arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"pa") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || (arg_u > 3)) {
                        printf("ERROR: argument parsing of --pa argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        g_pa = arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"mod") == 0) {
                    i = sscanf(optarg, "%s", arg_s);
                    if ((i != 1) || ((strcmp(arg_s,"LORA") != 0) && (strcmp(arg_s,"FSK") != 0)  && (strcmp(arg_s,"CW") != 0))) {
                        printf("ERROR: argument parsing of --mod argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        sprintf(mod, "%s", arg_s);
                    }
                }
                else if (strcmp(long_options[option_index].name,"sf") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || (arg_u < 7) || (arg_u > 12)) {
                        printf("ERROR: argument parsing of --sf argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        sf = (uint8_t)arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"bw") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || ((arg_u != 125) && (arg_u != 250) && (arg_u != 500))) {
                        printf("ERROR: argument parsing of --bw argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        bw_khz = arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"br") == 0) {
                    i = sscanf(optarg, "%f", &arg_f);
                    if ((i != 1) || (arg_f < 0.5) || (arg_f > 250)) {
                        printf("ERROR: argument parsing of --br argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        br_kbps = arg_f;
                    }
                }
                else if (strcmp(long_options[option_index].name,"fdev") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || (arg_u < 1) || (arg_u > 250)) {
                        printf("ERROR: argument parsing of --fdev argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        fdev_khz = (uint8_t)arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"bt") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || (arg_u > 3)) {
                        printf("ERROR: argument parsing of --bt argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        bt = (uint8_t)arg_u;
                    }
                }
                else if (strcmp(long_options[option_index].name,"notch") == 0) {
                    i = sscanf(optarg, "%u", &arg_u);
                    if ((i != 1) || ((arg_u < 126) || (arg_u > 250))) {
                        printf("ERROR: argument parsing of --notch argument. Use -h to print help\n");
                        return EXIT_FAILURE;
                    }
                    else {
                        tx_notch_freq = (uint32_t)arg_u * 1000U;
                    }
                }
                else {
                    printf("ERROR: argument parsing options. Use -h to print help\n");
                    return EXIT_FAILURE;
                }
                break;

        case 'f':
            i = sscanf(optarg, "%f", &arg_f);
            if ((i != 1) || (arg_f < 1)) {
                printf("ERROR: argument parsing of -f argument. Use -h to print help\n");
                return EXIT_FAILURE;
            }
            else {
                freq_hz = (uint32_t)((arg_f * 1e6) + 0.5);
            }
            break;

        case 'r':
            i = sscanf(optarg, "%u", &arg_u);
            switch (arg_u) {
                case 1255:
                    radio_type = LGW_RADIO_TYPE_SX1255;
                    break;
                case 1257:
                    radio_type = LGW_RADIO_TYPE_SX1257;
                    break;
                default:
                    printf("ERROR: argument parsing of -r argument. Use -h to print help\n");
                    return EXIT_FAILURE;
            }
            break;

        default:
            printf("ERROR: argument parsing options. Use -h to print help\n");
            return EXIT_FAILURE;
        }
    }

    /* 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 );

    /* Board config */
    memset(&boardconf, 0, sizeof(boardconf));
    boardconf.lorawan_public = true;
    boardconf.clksrc = 1; /* Radio B is source by default */
    lgw_board_setconf(boardconf);

    /* RF config */
    memset(&rfconf, 0, sizeof(rfconf));
    rfconf.enable = true;
    rfconf.freq_hz = freq_hz;
    rfconf.rssi_offset = DEFAULT_RSSI_OFFSET;
    rfconf.type = radio_type;
    rfconf.tx_enable = true;
    rfconf.tx_notch_freq = tx_notch_freq;
    lgw_rxrf_setconf(TX_RF_CHAIN, rfconf);

    /* Tx gain LUT */
    memset(&txlut, 0, sizeof txlut);
    txlut.size = 1;
    txlut.lut[0].dig_gain = g_dig;
    txlut.lut[0].pa_gain = g_pa;
    txlut.lut[0].dac_gain = g_dac;
    txlut.lut[0].mix_gain = g_mix;
    txlut.lut[0].rf_power = 0;
    lgw_txgain_setconf(&txlut);

    /* Start the concentrator */
    i = lgw_start();
    if (i == LGW_HAL_SUCCESS) {
        MSG("INFO: concentrator started, packet can be sent\n");
    } else {
        MSG("ERROR: failed to start the concentrator\n");
        return EXIT_FAILURE;
    }

    /* fill-up payload and parameters */
    memset(&txpkt, 0, sizeof(txpkt));
    txpkt.freq_hz = freq_hz;
    txpkt.tx_mode = IMMEDIATE;
    txpkt.rf_chain = TX_RF_CHAIN;
    txpkt.rf_power = 0;
    if (strcmp(mod, "FSK") == 0) {
        txpkt.modulation = MOD_FSK;
        txpkt.datarate = br_kbps * 1e3;
    } else {
        txpkt.modulation = MOD_LORA;
        switch (bw_khz) {
            case 125: txpkt.bandwidth = BW_125KHZ; break;
            case 250: txpkt.bandwidth = BW_250KHZ; break;
            case 500: txpkt.bandwidth = BW_500KHZ; break;
            default:
                MSG("ERROR: invalid 'bw' variable\n");
                return EXIT_FAILURE;
        }
        switch (sf) {
            case  7: txpkt.datarate = DR_LORA_SF7;  break;
            case  8: txpkt.datarate = DR_LORA_SF8;  break;
            case  9: txpkt.datarate = DR_LORA_SF9;  break;
            case 10: txpkt.datarate = DR_LORA_SF10; break;
            case 11: txpkt.datarate = DR_LORA_SF11; break;
            case 12: txpkt.datarate = DR_LORA_SF12; break;
            default:
                MSG("ERROR: invalid 'sf' variable\n");
                return EXIT_FAILURE;
        }
    }
    txpkt.coderate = CR_LORA_4_5;
    txpkt.f_dev = fdev_khz;
    txpkt.preamble = 65535;
    txpkt.invert_pol = false;
    txpkt.no_crc = true;
    txpkt.no_header = true;
    txpkt.size = 1;
    txpkt.payload[0] = 0;

    /* Overwrite settings */
    lgw_reg_w(LGW_TX_MODE, 1); /* Tx continuous */
    lgw_reg_w(LGW_FSK_TX_GAUSSIAN_SELECT_BT, bt);
    if (strcmp(mod, "CW") == 0) {
        /* Enable signal generator with DC */
        lgw_reg_w(LGW_SIG_GEN_FREQ, 0);
        lgw_reg_w(LGW_SIG_GEN_EN, 1);
        lgw_reg_w(LGW_TX_OFFSET_I, 0);
        lgw_reg_w(LGW_TX_OFFSET_Q, 0);
    }

    /* Send packet */
    i = lgw_send(txpkt);

    /* Recap all settings */
    printf("SX1301 library version: %s\n", lgw_version_info());
    if (strcmp(mod, "LORA") == 0) {
        printf("Modulation: LORA SF:%d BW:%d kHz\n", sf, bw_khz);
    }
    else if (strcmp(mod, "FSK") == 0) {
        printf("Modulation: FSK BR:%3.3f kbps FDEV:%d kHz BT:%d\n", br_kbps, fdev_khz, bt);
    }
    else if (strcmp(mod, "CW") == 0) {
        printf("Modulation: CW\n");
    }
    switch(rfconf.type) {
        case LGW_RADIO_TYPE_SX1255:
            printf("Radio Type: SX1255\n");
            break;
        case LGW_RADIO_TYPE_SX1257:
            printf("Radio Type: SX1257\n");
            break;
        default:
            printf("ERROR: undefined radio type\n");
            break;
    }
    printf("Frequency: %4.3f MHz\n", freq_hz/1e6);
    printf("TX Gains: Digital:%d DAC:%d Mixer:%d PA:%d\n", g_dig, g_dac, g_mix, g_pa);
    if (strcmp(mod, "CW") != 0) {
        lgw_reg_r(LGW_TX_OFFSET_I, &offset_i);
        lgw_reg_r(LGW_TX_OFFSET_Q, &offset_q);
        printf("Calibrated DC offsets: I:%d Q:%d\n", offset_i, offset_q);
    }

    /* waiting for user input */
    while ((quit_sig != 1) && (exit_sig != 1)) {
        wait_ms(100);
    }

    /* clean up before leaving */
    lgw_stop();

    return 0;
}
コード例 #7
0
int main(int argc, char **argv)
{
	int i; /* loop and temporary variables */
	struct timespec sleep_time = {0, 3000000}; /* 3 ms */
	
	int packet_counter = 0;
	
	/* allocate memory for packet fetching and processing */
	struct lgw_pkt_rx_s rxpkt[16]; /* array containing up to 16 inbound packets metadata */
	struct lgw_pkt_rx_s *p; /* pointer on a RX packet */
	int nb_pkt;

	configure_gateway();

	/* parse command line options */
	while ((i = getopt (argc, argv, "hr:")) != -1) {
		switch (i) {
			case 'h':
				usage();
				return EXIT_FAILURE;
				break;
			case 'r':
				result_file_name = optarg;
				break;
			
			default:
				MSG("ERROR: argument parsing use -h option for help\n");
				usage();
				return EXIT_FAILURE;
		}
	}

	/* 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);

	/* starting the concentrator */
	i = lgw_start();
	if (i == LGW_HAL_SUCCESS) {
		MSG("INFO: concentrator started, packet can now be received\n");
	} else {
		MSG("ERROR: failed to start the concentrator\n");
		return EXIT_FAILURE;
	}

	openResultFile();
	
	/* transform the MAC address into a string */
	sprintf(lgwm_str, "%08X%08X", (uint32_t)(lgwm >> 32), (uint32_t)(lgwm & 0xFFFFFFFF));

	/* main loop */
	while ((quit_sig != 1) && (exit_sig != 1)) {
		/* fetch packets */
		nb_pkt = lgw_receive(ARRAY_SIZE(rxpkt), rxpkt);
		if (nb_pkt == LGW_HAL_ERROR) {
			MSG("ERROR: failed packet fetch, exiting\n");
			return EXIT_FAILURE;
		} else if (nb_pkt == 0) {
			clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep_time, NULL); /* wait a short time if no packets */
		} else {
			/* local timestamp generation until we get accurate GPS time */
		}
		
		/* log packets */
		for (i=0; i < nb_pkt; ++i) {
			p = &rxpkt[i];

			switch(compare_id(p)) {
				case JOIN_REQ_MSG:
					MSG("Sending join response.\n");
					send_join_response(p);
					packet_counter = 0;
					size = 0;
					break;
				case TEST_MSG:
					snr[packet_counter] = p->snr;
					packet_counter++;
					size = p->size;
					break;
				case END_TEST_MSG:
					if (packet_counter != 0) {				
						write_results(packet_counter, p);
						MSG("Ended series: %i packets received.\n", packet_counter);
					}
					packet_counter = 0;
					size = 0;
					break;
				case ALL_TESTS_ENDED_MSG:
					exit_sig = 1; // ending program
					MSG("All tests have been finished.\n");
					break;
				default:
					// message not recognized
					break;
			}
		}
	}
	
	if (exit_sig == 1) {
		/* clean up before leaving */
		i = lgw_stop();
		if (i == LGW_HAL_SUCCESS) {
			MSG("INFO: concentrator stopped successfully\n");
		} else {
			MSG("WARNING: failed to stop concentrator successfully\n");
		}
	}

	fclose(result_file);
	
	MSG("INFO: Exiting uplink concentrator program\n");
	return EXIT_SUCCESS;
}
コード例 #8
0
int main()
{
	struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
	
	int i;
	char tmp_str[80];
	
	/* serial variables */
	char serial_buff[128]; /* buffer to receive GPS data */
	ssize_t nb_char;
	int gps_tty_dev; /* file descriptor to the serial port of the GNSS module */
	
	/* NMEA variables */
	enum gps_msg latest_msg; /* keep track of latest NMEA message parsed */
	
	/* variables for PPM pulse GPS synchronization */
	uint32_t ppm_tstamp;
	struct timespec ppm_utc;
	struct tref ppm_ref;
	
	/* variables for timestamp <-> UTC conversions */
	uint32_t x, z;
	struct timespec y;
	
	/* 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);
	
	/* Intro message and library information */
	printf("Beginning of test for loragw_gps.c\n");
	printf("*** Library version information ***\n%s\n***\n", lgw_version_info());
	
	/* Open and configure GPS */
	i = lgw_gps_enable("/dev/ttyACM0", NULL, 0, &gps_tty_dev);
	if (i != LGW_GPS_SUCCESS) {
		printf("ERROR: IMPOSSIBLE TO ENABLE GPS\n");
		exit(EXIT_FAILURE);
	}
	
	/* start concentrator */
	lgw_start();
	
	/* initialize some variables before loop */
	memset(serial_buff, 0, sizeof serial_buff);
	memset(&ppm_ref, 0, sizeof ppm_ref);
	
	/* loop until user action */
	while ((quit_sig != 1) && (exit_sig != 1)) {
		/* blocking canonical read on serial port */
		nb_char = read(gps_tty_dev, serial_buff, sizeof(serial_buff)-1);
		if (nb_char <= 0) {
			printf("Warning: read() returned value <= 0\n");
			continue;
		} else {
			serial_buff[nb_char] = 0;
		}
		
		/* parse the received NMEA */
		latest_msg = lgw_parse_nmea(serial_buff, sizeof(serial_buff));
		
		if (latest_msg == NMEA_RMC) {
			
			printf("\n~~ RMC NMEA sentence, triggering synchronization attempt ~~\n");
			
			/* get UTC time for synchronization */
			i = lgw_gps_get(&ppm_utc, NULL, NULL);
			if (i != LGW_GPS_SUCCESS) {
				printf("    No valid reference UTC time available, synchronization impossible.\n");
				continue;
			}
			/* get timestamp for synchronization */
			i = lgw_get_trigcnt(&ppm_tstamp);
			if (i != LGW_HAL_SUCCESS) {
				printf("    Failed to read timestamp, synchronization impossible.\n");
				continue;
			}
			/* try to update synchronize time reference with the new UTC & timestamp */
			i = lgw_gps_sync(&ppm_ref, ppm_tstamp, ppm_utc);
			if (i != LGW_GPS_SUCCESS) {
				printf("    Synchronization error.\n");
				continue;
			}
			/* display result */
			printf("    * Synchronization successful *\n");
			strftime(tmp_str, sizeof(tmp_str), "%F %T", gmtime(&(ppm_ref.utc.tv_sec)));
			printf("    UTC reference time: %s.%09ldZ\n", tmp_str, ppm_ref.utc.tv_nsec);
			printf("    Internal counter reference value: %u\n", ppm_ref.count_us);
			printf("    Clock error: %.9f\n", ppm_ref.xtal_err);
			
			x = ppm_tstamp + 500000;
			printf("    * Test of timestamp counter <-> UTC value conversion *\n");
			printf("    Test value: %u\n", x);
			lgw_cnt2utc(ppm_ref, x, &y);
			strftime(tmp_str, sizeof(tmp_str), "%F %T", gmtime(&(y.tv_sec)));
			printf("    Conversion to UTC: %s.%09ldZ\n", tmp_str, y.tv_nsec);
			lgw_utc2cnt(ppm_ref, y, &z);
			printf("    Converted back: %u\n", z);
		}
	}
	
	/* clean up before leaving */
	if (exit_sig == 1) {
		lgw_stop();
	}
	
	printf("\nEnd of test for loragw_gps.c\n");
	exit(EXIT_SUCCESS);
}
コード例 #9
0
ファイル: pktfwd.c プロジェクト: JiapengLi/lorawan-parser
int pktfwd_init(config_lgw_t *lgw)
{
    struct termios newtty;
    struct sigaction sig;
    int i, ret;

    if (lgw_board_setconf(lgw->board.conf) != LGW_HAL_SUCCESS) {
        log_puts(LOG_NORMAL, "WARNING: Failed to configure board");
    }

    if (lgw_lbt_setconf(lgw->lbt.conf) != LGW_HAL_SUCCESS) {
        log_puts(LOG_NORMAL, "WARNING: Failed to configure lbt");
    }

    if (lgw_txgain_setconf(&lgw->txlut.conf) != LGW_HAL_SUCCESS) {
        log_puts(LOG_NORMAL, "WARNING: Failed to configure concentrator TX Gain LUT");
    }

    for (i=0; i<LGW_RF_CHAIN_NB; i++) {
        if (lgw_rxrf_setconf(i, lgw->radio[i].conf) != LGW_HAL_SUCCESS) {
            log_puts(LOG_NORMAL, "WARNING: invalid configuration for radio %i", i);
        }
    }

    for (i = 0; i < LGW_MULTI_NB; ++i) {
        if (lgw_rxif_setconf(i, lgw->chan[i].conf) != LGW_HAL_SUCCESS) {
             log_puts(LOG_NORMAL, "WARNING: invalid configuration for Lora multi-SF channel %i", i);
        }
    }

    if (lgw_rxif_setconf(8, lgw->chan[8].conf) != LGW_HAL_SUCCESS) {
        log_puts(LOG_NORMAL, "WARNING: invalid configuration for Lora multi-SF channel %i", i);
    }

    if (lgw_rxif_setconf(9, lgw->chan[9].conf) != LGW_HAL_SUCCESS) {
        log_puts(LOG_NORMAL, "WARNING: invalid configuration for Lora multi-SF channel %i", i);
    }

    sigemptyset (&sig.sa_mask);
    sig.sa_handler = pktfwd_sig_handler;
    sig.sa_flags = 0;
    sigaction(SIGQUIT, &sig, NULL);
    sigaction(SIGINT, &sig, NULL);
    sigaction(SIGTERM, &sig, NULL);

#ifdef PKTFWD_DISABLE_ECHO
    if(tcgetattr(STDIN_FILENO, &savedtty) != 0){
        log_puts(LOG_FATAL, "Fatal error tcgetattr");
        exit(EXIT_FAILURE);
    }

    newtty = savedtty;
    newtty.c_lflag &= ~ECHO;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &newtty);
#endif

    ret = lgw_start();
    if (ret == LGW_HAL_SUCCESS) {
        log_puts(LOG_NORMAL, "Concentrator started");
    } else {
        log_puts(LOG_NORMAL, "Concentrator failed to start");
        exit(EXIT_FAILURE);
    }

    return 0;
}