Пример #1
0
static int
join_bad(Conn_t *conn)
{
  Debug_unit(&conn_unit, "Join_bad called");
  dump_conn(conn);

  if (proper_request()==0) {
    send_join_response(conn->sfd, control_packet, conn->lecid,
		       (unsigned short)LE_STATUS_BAD_REQ);
  }
  return 1;
}
int main(int argc, char **argv)
{
	int i, j; /* loop and temporary variables */
	struct timespec sleep_time = {0, 3000000}; /* 3 ms */
	
	float average_snr=0;
	int packet_counter=0;
	
	/* 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];
			
			if (compare_id(p)==0) {
				if(packet_counter!=0){
					write_results(average_snr,packet_counter,p);
				}
				send_join_response(p);
				packet_counter=0;
				average_snr=0;
			}
		
			/* 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
static int
join_ok(Conn_t *conn)
{
  Reg_t *rtmp = NULL;   /* silence gcc 2.7.2.1 */
  Lecdb_t *ltmp; 
  const char *elanname;

  Debug_unit(&conn_unit, "Join_ok called");  
  dump_conn(conn);

  if (control_packet != NULL &&
      proper_request() == 1) {
/*    dump_control(control_packet);*/

    /* Do not accept control packets with lecid set to unknown value*/
    if (control_packet->lecid != 0) {
      Debug_unit(&conn_unit,"Lecid set");
      ltmp = leciddb_find(control_packet->lecid);
      if (!ltmp || memcmp(&ltmp->address, &control_packet->source_addr,
			  sizeof(AtmAddr_t)) != 0) {
	send_join_response(conn->fd, control_packet, conn->lecid,
			   (unsigned int)LE_STATUS_BAD_LECID);
	return 0;
      }
    }

    /* Is lan destination address present? */
    if (control_packet->source.tag != htons(LANE_DEST_NP)) {
      rtmp = regdb_find_mac(control_packet->source);

      /* Do not accept lan multicast address */
      if (is_multicast(&control_packet->source)) {
	Debug_unit(&conn_unit,"Destination lan address is multicast");
	send_join_response(conn->fd, control_packet, conn->lecid,
			   ((unsigned int)LE_STATUS_BAD_DEST));
	return 0;
      }

      /* Duplicate registered Lan-destination, duplicate mac-address */
      if (rtmp && memcmp(&rtmp->atm_address,&control_packet->source_addr, 
			 sizeof(AtmAddr_t)) != 0) {
	Debug_unit(&conn_unit,"Duplicate Destination lan, duplicate mac");
	send_join_response(conn->fd, control_packet, conn->lecid,
			   ((unsigned int)LE_STATUS_DUPLICATE_REG));
	return 0;
      }
    }

    /* Duplicate atm-address */
    if ((ltmp =leciddb_find_atm(control_packet->source_addr)) != NULL &&
	ltmp->lecid != conn->lecid) {
      Debug_unit(&conn_unit,"Duplicate atmaddress");
      send_join_response(conn->fd, control_packet, conn->lecid,
			 ((unsigned int)LE_STATUS_DUPLICATE_ADDR));
      return 0;
    }
    /* If we have elan-name, check it agaist the one in join request */
    elanname = get_var_str(&conn_unit, "ELANNAME");
    if (elanname) {
      Debug_unit(&conn_unit, "Compare %s with %s",elanname, 
		 control_packet->elan_name);
      if ((strlen(elanname) != control_packet->elan_name_size) ||
	  strncmp(elanname, control_packet->elan_name, 
		  control_packet->elan_name_size)) {
	/* Don't match */
	Debug_unit(&conn_unit, "Invalid elan-name set");
	send_join_response(conn->fd, control_packet, conn->lecid,
			   ((unsigned int)LE_STATUS_NO_CONFIG));
	return 0;
      }
    }
    Debug_unit(&conn_unit,"Control_packet OK.");
    /* Control_packet OK. */
    if (leciddb_find(conn->lecid) == NULL) {
      leciddb_add(conn->lecid,
		  control_packet->source_addr, conn->fd);
    }
    if (control_packet->source.tag != htons(LANE_DEST_NP) && !rtmp) {
/*      dump_addr(&control_packet->source); */
      regdb_add(control_packet->source_addr, 
		control_packet->source);
    }
    /* Send join response */
    if ((conn->proxy == BL_TRUE || is_proxy() == BL_TRUE) &&
	proxydb_find(conn->lecid) == NULL) {
      proxydb_add((const Conn_t *)conn, conn->fd);
    }
    timer_ack(&conn_unit, conn->timer);
    send_join_response(conn->fd, control_packet, conn->lecid,
		       (unsigned short)LE_STATUS_SUCCESS);
    return 1;
  } 

  return 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;
}