commit
						442326385b
					
				| @ -11,11 +11,11 @@ | ||||
| 
 | ||||
| ; ---> SELECT TARGET PLATFORM HERE! <--- | ||||
| [platformio] | ||||
| ;env_default = heltec | ||||
| env_default = heltec | ||||
| ;env_default = ttgov1 | ||||
| ;env_default = ttgov2 | ||||
| ;env_default = ttgov21 | ||||
| env_default = ttgobeam | ||||
| ;env_default = ttgobeam | ||||
| ;env_default = lopy | ||||
| ;env_default = lopy4 | ||||
| ;env_default = fipy | ||||
|  | ||||
| @ -5,25 +5,25 @@ | ||||
| #include <driver/adc.h> | ||||
| #include <esp_adc_cal.h> | ||||
| 
 | ||||
| #define DEFAULT_VREF    1100    // to be done: use adc2_vref_to_gpio() to obtain a better estimate
 | ||||
| #define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
 | ||||
| #define NO_OF_SAMPLES 64  // we do multisampling
 | ||||
| 
 | ||||
| // Local logging tag
 | ||||
| static const char TAG[] = "main"; | ||||
| 
 | ||||
| static void print_char_val_type(esp_adc_cal_value_t val_type) | ||||
| { | ||||
| static void print_char_val_type(esp_adc_cal_value_t val_type) { | ||||
|   if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { | ||||
|         ESP_LOGI(TAG,"ADC characterization based on Two Point values stored in eFuse"); | ||||
|     ESP_LOGI(TAG, | ||||
|              "ADC characterization based on Two Point values stored in eFuse"); | ||||
|   } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { | ||||
|         ESP_LOGI(TAG,"ADC characterization based on reference voltage stored in eFuse"); | ||||
|     ESP_LOGI(TAG, | ||||
|              "ADC characterization based on reference voltage stored in eFuse"); | ||||
|   } else { | ||||
|     ESP_LOGI(TAG, "ADC characterization based on default reference voltage"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| uint16_t read_voltage(void) | ||||
| { | ||||
| uint16_t read_voltage(void) { | ||||
|   static const adc1_channel_t channel = HAS_BATTERY_PROBE; | ||||
|   static const adc_atten_t atten = ADC_ATTEN_DB_11; | ||||
|   static const adc_unit_t unit = ADC_UNIT_1; | ||||
| @ -33,8 +33,11 @@ uint16_t read_voltage(void) | ||||
|   ESP_ERROR_CHECK(adc1_config_channel_atten(channel, atten)); | ||||
| 
 | ||||
|   // calibrate ADC1
 | ||||
|     esp_adc_cal_characteristics_t *adc_chars = (esp_adc_cal_characteristics_t *) calloc(1, sizeof(esp_adc_cal_characteristics_t)); | ||||
|     esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); | ||||
|   esp_adc_cal_characteristics_t *adc_chars = | ||||
|       (esp_adc_cal_characteristics_t *)calloc( | ||||
|           1, sizeof(esp_adc_cal_characteristics_t)); | ||||
|   esp_adc_cal_value_t val_type = esp_adc_cal_characterize( | ||||
|       unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); | ||||
|   print_char_val_type(val_type); | ||||
| 
 | ||||
|   // multisample ADC1
 | ||||
| @ -46,7 +49,8 @@ uint16_t read_voltage(void) | ||||
|   adc_reading /= NO_OF_SAMPLES; | ||||
| 
 | ||||
|   // Convert adc_reading to voltage in mV
 | ||||
|     uint16_t voltage = (uint16_t) esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); | ||||
|   uint16_t voltage = | ||||
|       (uint16_t)esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); | ||||
| #ifdef BATT_FACTOR | ||||
|   voltage *= BATT_FACTOR; | ||||
| #endif | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* switches wifi antenna, if board has switch to select internal and external antenna */ | ||||
| /* switches wifi antenna, if board has switch  internal / external antenna */ | ||||
| 
 | ||||
| #ifdef HAS_ANTENNA_SWITCH | ||||
| 
 | ||||
| @ -7,10 +7,7 @@ | ||||
| // Local logging tag
 | ||||
| static const char TAG[] = "wifi"; | ||||
| 
 | ||||
| typedef enum { | ||||
|     ANTENNA_INT = 0, | ||||
|     ANTENNA_EXT | ||||
| } antenna_type_t; | ||||
| typedef enum { ANTENNA_INT = 0, ANTENNA_EXT } antenna_type_t; | ||||
| 
 | ||||
| void antenna_init(void) { | ||||
|   gpio_config_t gpioconf = {.pin_bit_mask = 1ull << HAS_ANTENNA_SWITCH, | ||||
|  | ||||
							
								
								
									
										186
									
								
								src/blecsan.cpp
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								src/blecsan.cpp
									
									
									
									
									
								
							| @ -14,7 +14,8 @@ https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner | ||||
| #include <esp_blufi_api.h> // needed for BLE_ADDR types, do not remove
 | ||||
| #include <bt_types.h> | ||||
| 
 | ||||
| #define BT_BD_ADDR_HEX(addr)   addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] | ||||
| #define BT_BD_ADDR_HEX(addr)                                                   \ | ||||
|   addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] | ||||
| 
 | ||||
| // local Tag for logging
 | ||||
| static const char TAG[] = "bluetooth"; | ||||
| @ -38,45 +39,81 @@ const char *bt_addr_t_to_string(esp_ble_addr_type_t type) { | ||||
| } // bt_addr_t_to_string
 | ||||
| 
 | ||||
| const char *btsig_gap_type(uint32_t gap_type) { | ||||
| 	switch (gap_type) | ||||
| 	{ | ||||
| 		case 0x01: return "Flags"; | ||||
| 		case 0x02: return "Incomplete List of 16-bit Service Class UUIDs"; | ||||
| 		case 0x03: return "Complete List of 16-bit Service Class UUIDs"; | ||||
| 		case 0x04: return "Incomplete List of 32-bit Service Class UUIDs"; | ||||
| 		case 0x05: return "Complete List of 32-bit Service Class UUIDs"; | ||||
| 		case 0x06: return "Incomplete List of 128-bit Service Class UUIDs"; | ||||
| 		case 0x07: return "Complete List of 128-bit Service Class UUIDs"; | ||||
| 		case 0x08: return "Shortened Local Name"; | ||||
| 		case 0x09: return "Complete Local Name"; | ||||
| 		case 0x0A: return "Tx Power Level"; | ||||
| 		case 0x0D: return "Class of Device"; | ||||
| 		case 0x0E: return "Simple Pairing Hash C/C-192"; | ||||
| 		case 0x0F: return "Simple Pairing Randomizer R/R-192"; | ||||
| 		case 0x10: return "Device ID/Security Manager TK Value"; | ||||
| 		case 0x11: return "Security Manager Out of Band Flags"; | ||||
| 		case 0x12: return "Slave Connection Interval Range"; | ||||
| 		case 0x14: return "List of 16-bit Service Solicitation UUIDs"; | ||||
| 		case 0x1F: return "List of 32-bit Service Solicitation UUIDs"; | ||||
| 		case 0x15: return "List of 128-bit Service Solicitation UUIDs"; | ||||
| 		case 0x16: return "Service Data - 16-bit UUID"; | ||||
| 		case 0x20: return "Service Data - 32-bit UUID"; | ||||
| 		case 0x21: return "Service Data - 128-bit UUID"; | ||||
| 		case 0x22: return "LE Secure Connections Confirmation Value"; | ||||
| 		case 0x23: return "LE Secure Connections Random Value"; | ||||
| 		case 0x24: return "URI"; | ||||
| 		case 0x25: return "Indoor Positioning"; | ||||
| 		case 0x26: return "Transport Discovery Data"; | ||||
| 		case 0x17: return "Public Target Address"; | ||||
| 		case 0x18: return "Random Target Address"; | ||||
| 		case 0x19: return "Appearance"; | ||||
| 		case 0x1A: return "Advertising Interval"; | ||||
| 		case 0x1B: return "LE Bluetooth Device Address"; | ||||
| 		case 0x1C: return "LE Role"; | ||||
| 		case 0x1D: return "Simple Pairing Hash C-256"; | ||||
| 		case 0x1E: return "Simple Pairing Randomizer R-256"; | ||||
| 		case 0x3D: return "3D Information Data"; | ||||
| 		case 0xFF: return "Manufacturer Specific Data"; | ||||
|   switch (gap_type) { | ||||
|   case 0x01: | ||||
|     return "Flags"; | ||||
|   case 0x02: | ||||
|     return "Incomplete List of 16-bit Service Class UUIDs"; | ||||
|   case 0x03: | ||||
|     return "Complete List of 16-bit Service Class UUIDs"; | ||||
|   case 0x04: | ||||
|     return "Incomplete List of 32-bit Service Class UUIDs"; | ||||
|   case 0x05: | ||||
|     return "Complete List of 32-bit Service Class UUIDs"; | ||||
|   case 0x06: | ||||
|     return "Incomplete List of 128-bit Service Class UUIDs"; | ||||
|   case 0x07: | ||||
|     return "Complete List of 128-bit Service Class UUIDs"; | ||||
|   case 0x08: | ||||
|     return "Shortened Local Name"; | ||||
|   case 0x09: | ||||
|     return "Complete Local Name"; | ||||
|   case 0x0A: | ||||
|     return "Tx Power Level"; | ||||
|   case 0x0D: | ||||
|     return "Class of Device"; | ||||
|   case 0x0E: | ||||
|     return "Simple Pairing Hash C/C-192"; | ||||
|   case 0x0F: | ||||
|     return "Simple Pairing Randomizer R/R-192"; | ||||
|   case 0x10: | ||||
|     return "Device ID/Security Manager TK Value"; | ||||
|   case 0x11: | ||||
|     return "Security Manager Out of Band Flags"; | ||||
|   case 0x12: | ||||
|     return "Slave Connection Interval Range"; | ||||
|   case 0x14: | ||||
|     return "List of 16-bit Service Solicitation UUIDs"; | ||||
|   case 0x1F: | ||||
|     return "List of 32-bit Service Solicitation UUIDs"; | ||||
|   case 0x15: | ||||
|     return "List of 128-bit Service Solicitation UUIDs"; | ||||
|   case 0x16: | ||||
|     return "Service Data - 16-bit UUID"; | ||||
|   case 0x20: | ||||
|     return "Service Data - 32-bit UUID"; | ||||
|   case 0x21: | ||||
|     return "Service Data - 128-bit UUID"; | ||||
|   case 0x22: | ||||
|     return "LE Secure Connections Confirmation Value"; | ||||
|   case 0x23: | ||||
|     return "LE Secure Connections Random Value"; | ||||
|   case 0x24: | ||||
|     return "URI"; | ||||
|   case 0x25: | ||||
|     return "Indoor Positioning"; | ||||
|   case 0x26: | ||||
|     return "Transport Discovery Data"; | ||||
|   case 0x17: | ||||
|     return "Public Target Address"; | ||||
|   case 0x18: | ||||
|     return "Random Target Address"; | ||||
|   case 0x19: | ||||
|     return "Appearance"; | ||||
|   case 0x1A: | ||||
|     return "Advertising Interval"; | ||||
|   case 0x1B: | ||||
|     return "LE Bluetooth Device Address"; | ||||
|   case 0x1C: | ||||
|     return "LE Role"; | ||||
|   case 0x1D: | ||||
|     return "Simple Pairing Hash C-256"; | ||||
|   case 0x1E: | ||||
|     return "Simple Pairing Randomizer R-256"; | ||||
|   case 0x3D: | ||||
|     return "3D Information Data"; | ||||
|   case 0xFF: | ||||
|     return "Manufacturer Specific Data"; | ||||
| 
 | ||||
|   default: | ||||
|     return "Unknown type"; | ||||
| @ -84,14 +121,14 @@ const char *btsig_gap_type(uint32_t gap_type) { | ||||
| } // btsig_gap_type
 | ||||
| 
 | ||||
| // using IRAM_:ATTR here to speed up callback function
 | ||||
| IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) | ||||
| { | ||||
| IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, | ||||
|                                     esp_ble_gap_cb_param_t *param) { | ||||
|   esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param; | ||||
| 
 | ||||
| 	ESP_LOGD(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv, btsig_gap_type(*p->scan_rst.ble_adv));		 | ||||
|   ESP_LOGD(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv, | ||||
|            btsig_gap_type(*p->scan_rst.ble_adv)); | ||||
| 
 | ||||
| 	switch (event)  | ||||
| 	{ | ||||
|   switch (event) { | ||||
|   case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: | ||||
|     // restart scan
 | ||||
|     ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME)); | ||||
| @ -99,26 +136,33 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb | ||||
| 
 | ||||
|   case ESP_GAP_BLE_SCAN_RESULT_EVT: | ||||
|     // evaluate scan results
 | ||||
| 			if ( p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
 | ||||
|     if (p->scan_rst.search_evt == | ||||
|         ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
 | ||||
|     {                                // restart scan
 | ||||
|       ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME)); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
| 			if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
 | ||||
|     if (p->scan_rst.search_evt == | ||||
|         ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
 | ||||
|     {                               // evaluate sniffed packet
 | ||||
| 				ESP_LOGD(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", BT_BD_ADDR_HEX(p->scan_rst.bda)); | ||||
| 				ESP_LOGD(TAG, "Addr_type           : %s", bt_addr_t_to_string(p->scan_rst.ble_addr_type)); | ||||
|       ESP_LOGD(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", | ||||
|                BT_BD_ADDR_HEX(p->scan_rst.bda)); | ||||
|       ESP_LOGD(TAG, "Addr_type           : %s", | ||||
|                bt_addr_t_to_string(p->scan_rst.ble_addr_type)); | ||||
|       ESP_LOGD(TAG, "RSSI                : %d", p->scan_rst.rssi); | ||||
| 
 | ||||
| 				if ((cfg.rssilimit) && (p->scan_rst.rssi < cfg.rssilimit )) { // rssi is negative value
 | ||||
|      				ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi, cfg.rssilimit); | ||||
|       if ((cfg.rssilimit) && | ||||
|           (p->scan_rst.rssi < cfg.rssilimit)) { // rssi is negative value
 | ||||
|         ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi, | ||||
|                  cfg.rssilimit); | ||||
|         break; | ||||
|       } | ||||
| 
 | ||||
| #ifdef VENDORFILTER | ||||
| 
 | ||||
| 					if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) || (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) { | ||||
|       if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) || | ||||
|           (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) { | ||||
|         ESP_LOGD(TAG, "BT device filtered"); | ||||
|         break; | ||||
|       } | ||||
| @ -130,18 +174,21 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb | ||||
| 
 | ||||
|       /* to be improved in vendorfilter if:
 | ||||
|        | ||||
| 
 | ||||
|       // you can search for elements in the payload using the
 | ||||
|       // function esp_ble_resolve_adv_data()
 | ||||
|       //
 | ||||
| 				// Like this, that scans for the "Complete name" (looking inside the payload buffer)
 | ||||
|       // Like this, that scans for the "Complete name" (looking inside the
 | ||||
|       payload buffer) | ||||
|       // uint8_t len;
 | ||||
| 				// uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &len);
 | ||||
|       // uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv,
 | ||||
|       ESP_BLE_AD_TYPE_NAME_CMPL, &len); | ||||
| 
 | ||||
| 				filter BLE devices using their advertisements to get filter alternative to vendor OUI | ||||
| 				if vendorfiltering is on, we ... | ||||
|       filter BLE devices using their advertisements to get filter alternative to | ||||
|       vendor OUI if vendorfiltering is on, we ... | ||||
|       - want to count: mobile phones and tablets | ||||
| 				- don't want to count: beacons, peripherals (earphones, headsets, printers), cars and machines | ||||
| 				see | ||||
|       - don't want to count: beacons, peripherals (earphones, headsets, | ||||
|       printers), cars and machines see | ||||
|       https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp
 | ||||
| 
 | ||||
|       http://www.libelium.com/products/meshlium/smartphone-detection/
 | ||||
| @ -150,9 +197,10 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb | ||||
| 
 | ||||
|       https://www.bluetooth.com/specifications/assigned-numbers/baseband
 | ||||
| 
 | ||||
| 				"The Class of Device (CoD) in case of Bluetooth which allows us to differentiate the type of  | ||||
| 				device (smartphone, handsfree, computer, LAN/network AP). With this parameter we can  | ||||
| 				differentiate among pedestrians and vehicles." | ||||
|       "The Class of Device (CoD) in case of Bluetooth which allows us to | ||||
|       differentiate the type of device (smartphone, handsfree, computer, | ||||
|       LAN/network AP). With this parameter we can differentiate among | ||||
|       pedestrians and vehicles." | ||||
| 
 | ||||
|       */ | ||||
| 
 | ||||
| @ -164,7 +212,6 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb | ||||
|   } | ||||
| } // gap_callback_handler
 | ||||
| 
 | ||||
| 
 | ||||
| esp_err_t register_ble_callback(void) { | ||||
|   ESP_LOGI(TAG, "Register GAP callback"); | ||||
| 
 | ||||
| @ -172,20 +219,21 @@ esp_err_t register_ble_callback(void) { | ||||
|   // register the scan callback function to the gap module
 | ||||
|   ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler)); | ||||
| 
 | ||||
| 	static esp_ble_scan_params_t ble_scan_params =  | ||||
| 	{	 | ||||
|   static esp_ble_scan_params_t ble_scan_params = { | ||||
|       .scan_type = BLE_SCAN_TYPE_PASSIVE, | ||||
|       .own_addr_type = BLE_ADDR_TYPE_RANDOM, | ||||
| 
 | ||||
| #ifdef VENDORFILTER | ||||
|       .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR, | ||||
|   // ADV_IND, ADV_NONCONN_IND, ADV_SCAN_IND packets are used for broadcasting
 | ||||
| 			// data in broadcast applications (e.g., Beacons), so we don't want them in vendorfilter mode
 | ||||
|   // data in broadcast applications (e.g., Beacons), so we don't want them in
 | ||||
|   // vendorfilter mode
 | ||||
| #else | ||||
|       .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, | ||||
| #endif | ||||
| 
 | ||||
| 		.scan_interval          = (uint16_t) (cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec
 | ||||
|       .scan_interval = | ||||
|           (uint16_t)(cfg.blescantime * 10 / 0.625),    // Time = N * 0.625 msec
 | ||||
|       .scan_window = (uint16_t)(BLESCANWINDOW / 0.625) // Time = N * 0.625 msec
 | ||||
|   }; | ||||
| 
 | ||||
| @ -203,11 +251,13 @@ void start_BLEscan(void){ | ||||
| 
 | ||||
|   // Initialize BT controller to allocate task and other resource.
 | ||||
|   esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); | ||||
| 	bt_cfg.controller_task_stack_size = BLESTACKSIZE; // set BT stack size to value configured in paxcounter.conf
 | ||||
|   bt_cfg.controller_task_stack_size = | ||||
|       BLESTACKSIZE; // set BT stack size to value configured in paxcounter.conf
 | ||||
|   ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg)); | ||||
|   ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BTDM)); | ||||
| 
 | ||||
| 	// Init and alloc the resource for bluetooth stack, must be done prior to every bluetooth stuff
 | ||||
|   // Init and alloc the resource for bluetooth stack, must be done prior to
 | ||||
|   // every bluetooth stuff
 | ||||
|   ESP_ERROR_CHECK(esp_bluedroid_init()); | ||||
|   ESP_ERROR_CHECK(esp_bluedroid_enable()); | ||||
| 
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ esp_err_t err; | ||||
| 
 | ||||
| // populate cfg vars with factory settings
 | ||||
| void defaultConfig() { | ||||
|     cfg.lorasf        = LORASFDEFAULT;  // 7-12, initial lora spreadfactor defined in paxcounter.conf
 | ||||
|   cfg.lorasf = LORASFDEFAULT; // 7-12, initial lora sf, see pacounter.conf
 | ||||
|   cfg.txpower = 15;           // 2-15, lora tx power
 | ||||
|   cfg.adrmode = 1;            // 0=disabled, 1=enabled
 | ||||
|   cfg.screensaver = 0;        // 0=disabled, 1=enabled
 | ||||
| @ -26,8 +26,11 @@ void defaultConfig() { | ||||
|   cfg.countermode = 0;        // 0=cyclic, 1=cumulative, 2=cyclic confirmed
 | ||||
|   cfg.rssilimit = 0;          // threshold for rssilimiter, negative value!
 | ||||
|   cfg.sendcycle = SEND_SECS;  // payload send cycle [seconds/2]
 | ||||
|     cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
 | ||||
|     cfg.blescantime   = BLESCANINTERVAL / 10;         // BT channel scan cycle duration [seconds/100], default 1 (= 10ms)
 | ||||
|   cfg.wifichancycle = | ||||
|       WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
 | ||||
|   cfg.blescantime = | ||||
|       BLESCANINTERVAL / | ||||
|       10;          // BT channel scan cycle [seconds/100], default 1 (= 10ms)
 | ||||
|   cfg.blescan = 1; // 0=disabled, 1=enabled
 | ||||
|   cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
 | ||||
|   cfg.vendorfilter = 1;       // 0=disabled, 1=enabled
 | ||||
| @ -64,9 +67,10 @@ void eraseConfig() { | ||||
|     nvs_erase_all(my_handle); | ||||
|     nvs_commit(my_handle); | ||||
|     nvs_close(my_handle); | ||||
|       ESP_LOGI(TAG, "Done");} | ||||
|     else { | ||||
|       ESP_LOGW(TAG, "NVS erase failed"); } | ||||
|     ESP_LOGI(TAG, "Done"); | ||||
|   } else { | ||||
|     ESP_LOGW(TAG, "NVS erase failed"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // save current configuration from RAM to NVRAM
 | ||||
| @ -79,52 +83,69 @@ void saveConfig() { | ||||
|     size_t required_size; | ||||
|     char storedversion[10]; | ||||
| 
 | ||||
|       if( nvs_get_str(my_handle, "version", storedversion, &required_size) != ESP_OK || strcmp(storedversion, cfg.version) != 0 ) | ||||
|     if (nvs_get_str(my_handle, "version", storedversion, &required_size) != | ||||
|             ESP_OK || | ||||
|         strcmp(storedversion, cfg.version) != 0) | ||||
|       nvs_set_str(my_handle, "version", cfg.version); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "lorasf", &flash8) != ESP_OK || flash8 != cfg.lorasf ) | ||||
|     if (nvs_get_i8(my_handle, "lorasf", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.lorasf) | ||||
|       nvs_set_i8(my_handle, "lorasf", cfg.lorasf); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "txpower", &flash8) != ESP_OK || flash8 != cfg.txpower ) | ||||
|     if (nvs_get_i8(my_handle, "txpower", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.txpower) | ||||
|       nvs_set_i8(my_handle, "txpower", cfg.txpower); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "adrmode", &flash8) != ESP_OK || flash8 != cfg.adrmode ) | ||||
|     if (nvs_get_i8(my_handle, "adrmode", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.adrmode) | ||||
|       nvs_set_i8(my_handle, "adrmode", cfg.adrmode); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "screensaver", &flash8) != ESP_OK || flash8 != cfg.screensaver ) | ||||
|     if (nvs_get_i8(my_handle, "screensaver", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.screensaver) | ||||
|       nvs_set_i8(my_handle, "screensaver", cfg.screensaver); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "screenon", &flash8) != ESP_OK || flash8 != cfg.screenon ) | ||||
|     if (nvs_get_i8(my_handle, "screenon", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.screenon) | ||||
|       nvs_set_i8(my_handle, "screenon", cfg.screenon); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK || flash8 != cfg.countermode ) | ||||
|     if (nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.countermode) | ||||
|       nvs_set_i8(my_handle, "countermode", cfg.countermode); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK || flash8 != cfg.sendcycle ) | ||||
|     if (nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.sendcycle) | ||||
|       nvs_set_i8(my_handle, "sendcycle", cfg.sendcycle); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK || flash8 != cfg.wifichancycle ) | ||||
|     if (nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.wifichancycle) | ||||
|       nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "blescantime", &flash8) != ESP_OK || flash8 != cfg.blescantime ) | ||||
|     if (nvs_get_i8(my_handle, "blescantime", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.blescantime) | ||||
|       nvs_set_i8(my_handle, "blescantime", cfg.blescantime); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "blescanmode", &flash8) != ESP_OK || flash8 != cfg.blescan ) | ||||
|     if (nvs_get_i8(my_handle, "blescanmode", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.blescan) | ||||
|       nvs_set_i8(my_handle, "blescanmode", cfg.blescan); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK || flash8 != cfg.wifiant ) | ||||
|     if (nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.wifiant) | ||||
|       nvs_set_i8(my_handle, "wifiant", cfg.wifiant); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "vendorfilter", &flash8) != ESP_OK || flash8 != cfg.vendorfilter ) | ||||
|     if (nvs_get_i8(my_handle, "vendorfilter", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.vendorfilter) | ||||
|       nvs_set_i8(my_handle, "vendorfilter", cfg.vendorfilter); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || flash8 != cfg.rgblum ) | ||||
|     if (nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.rgblum) | ||||
|       nvs_set_i8(my_handle, "rgblum", cfg.rgblum); | ||||
| 
 | ||||
|       if( nvs_get_i8(my_handle, "gpsmode", &flash8) != ESP_OK || flash8 != cfg.gpsmode ) | ||||
|     if (nvs_get_i8(my_handle, "gpsmode", &flash8) != ESP_OK || | ||||
|         flash8 != cfg.gpsmode) | ||||
|       nvs_set_i8(my_handle, "gpsmode", cfg.gpsmode); | ||||
| 
 | ||||
|       if( nvs_get_i16(my_handle, "rssilimit", &flash16) != ESP_OK || flash16 != cfg.rssilimit ) | ||||
|     if (nvs_get_i16(my_handle, "rssilimit", &flash16) != ESP_OK || | ||||
|         flash16 != cfg.rssilimit) | ||||
|       nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit); | ||||
| 
 | ||||
|     err = nvs_commit(my_handle); | ||||
| @ -153,7 +174,8 @@ void loadConfig() { | ||||
|   open_storage(); | ||||
|   if (err != ESP_OK) { | ||||
|     ESP_LOGW(TAG, "Error (%d) opening NVS handle, storing defaults", err); | ||||
|     saveConfig(); } // saves factory settings to NVRAM
 | ||||
|     saveConfig(); | ||||
|   } // saves factory settings to NVRAM
 | ||||
|   else { | ||||
|     int8_t flash8 = 0; | ||||
|     int16_t flash16 = 0; | ||||
| @ -164,7 +186,8 @@ void loadConfig() { | ||||
|       nvs_get_str(my_handle, "version", cfg.version, &required_size); | ||||
|       ESP_LOGI(TAG, "NVRAM settings version = %s", cfg.version); | ||||
|       if (strcmp(cfg.version, PROGVERSION)) { | ||||
|         ESP_LOGI(TAG, "migrating NVRAM settings to new version %s", PROGVERSION); | ||||
|         ESP_LOGI(TAG, "migrating NVRAM settings to new version %s", | ||||
|                  PROGVERSION); | ||||
|         nvs_close(my_handle); | ||||
|         migrateVersion(); | ||||
|       } | ||||
|  | ||||
| @ -68,6 +68,7 @@ extern char display_lora[], display_lmic[]; | ||||
| extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; | ||||
| extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters
 | ||||
| extern std::set<uint16_t> macs; | ||||
| extern hw_timer_t * channelSwitch; // hardware timer used for wifi channel switching
 | ||||
| extern hw_timer_t | ||||
|     *channelSwitch;         // hardware timer used for wifi channel switching
 | ||||
| extern xref2u1_t rcmd_data; // buffer for rcommand results size
 | ||||
| extern u1_t rcmd_data_size; // buffer for rcommand results size
 | ||||
|  | ||||
| @ -28,8 +28,7 @@ void gps_loop(void * pvParameters) { | ||||
| 
 | ||||
|   while (1) { | ||||
| 
 | ||||
|         if (cfg.gpsmode) | ||||
|         { | ||||
|     if (cfg.gpsmode) { | ||||
| #if defined GPS_SERIAL | ||||
| 
 | ||||
|       // serial connect to GPS device
 | ||||
|  | ||||
| @ -19,6 +19,4 @@ | ||||
| #define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN
 | ||||
| #define DIO0 GPIO_NUM_26    // ESP32 GPIO26 <-> HPD13A IO0
 | ||||
| #define DIO1 GPIO_NUM_32 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !!
 | ||||
| #define DIO2                                                                   \ | ||||
|   LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // needs external wiring, but not
 | ||||
|                   // necessary for LoRa, only FSK
 | ||||
| #define DIO2 LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // not needed for LoRa
 | ||||
|  | ||||
| @ -5,13 +5,15 @@ | ||||
|  * and rename this file to src/loraconf.h | ||||
|  * | ||||
|  * Note that DEVEUI, APPEUI and APPKEY should all be specified in MSB format. | ||||
|  * (This is different from standard LMIC-Arduino which expects DEVEUI and APPEUI in LSB format.) | ||||
|  * (This is different from standard LMIC-Arduino which expects DEVEUI and APPEUI | ||||
|  * in LSB format.) | ||||
| 
 | ||||
|  * Set your DEVEUI here, if you have one. You can leave this untouched, | ||||
|  * then the DEVEUI will be generated during runtime from device's MAC adress | ||||
|  * and will be displayed on device's screen as well as on serial console. | ||||
|  * | ||||
|  * NOTE: Use MSB format (as displayed in TTN console, so you can cut & paste from there) | ||||
|  * NOTE: Use MSB format (as displayed in TTN console, so you can cut & paste | ||||
|  * from there) | ||||
|  * For TTN, APPEUI in MSB format always starts with 0x70, 0xB3, 0xD5 | ||||
|  * | ||||
|  * Note: If using a board with Microchip 24AA02E64 Uinique ID for deveui, | ||||
| @ -25,4 +27,5 @@ static const u1_t DEVEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||||
| 
 | ||||
| static const u1_t APPEUI[8] = {0x70, 0xB3, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||||
| 
 | ||||
| static const u1_t APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||||
| static const u1_t APPKEY[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||||
| @ -211,8 +211,7 @@ void onEvent(ev_t ev) { | ||||
|   case EV_JOINED: | ||||
| 
 | ||||
|     strcpy_P(buff, PSTR("JOINED")); | ||||
|     sprintf(display_lora, | ||||
|             " "); // clear previous lmic status message from display
 | ||||
|     sprintf(display_lora, " "); // clear previous lmic status
 | ||||
| 
 | ||||
|     // set data rate adaptation
 | ||||
|     LMIC_setAdrMode(cfg.adrmode); | ||||
| @ -229,8 +228,7 @@ void onEvent(ev_t ev) { | ||||
| 
 | ||||
|     strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK") | ||||
|                                                : PSTR("TX COMPLETE")); | ||||
|     sprintf(display_lora, | ||||
|             " "); // clear previous lmic status message from display
 | ||||
|     sprintf(display_lora, " "); // clear previous lmic status
 | ||||
| 
 | ||||
|     if (LMIC.dataLen) { | ||||
|       ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d", | ||||
|  | ||||
| @ -9,13 +9,16 @@ | ||||
| // Local logging tag
 | ||||
| static const char TAG[] = "wifi"; | ||||
| 
 | ||||
| static wifi_country_t wifi_country = {.cc=WIFI_MY_COUNTRY, .schan=WIFI_CHANNEL_MIN, .nchan=WIFI_CHANNEL_MAX, .policy=WIFI_COUNTRY_POLICY_MANUAL}; | ||||
| static wifi_country_t wifi_country = {.cc = WIFI_MY_COUNTRY, | ||||
|                                       .schan = WIFI_CHANNEL_MIN, | ||||
|                                       .nchan = WIFI_CHANNEL_MAX, | ||||
|                                       .policy = WIFI_COUNTRY_POLICY_MANUAL}; | ||||
| 
 | ||||
| // globals
 | ||||
| uint16_t salt; | ||||
| 
 | ||||
| uint16_t reset_salt(void) { | ||||
|     salt = random(65536); // get new 16bit random for salting hashes and set global salt var
 | ||||
|   salt = random(65536); // get new 16bit random for salting hashes
 | ||||
|   return salt; | ||||
| } | ||||
| 
 | ||||
| @ -28,23 +31,30 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { | ||||
| 
 | ||||
|   // only last 3 MAC Address bytes are used for MAC address anonymization
 | ||||
|   // but since it's uint32 we take 4 bytes to avoid 1st value to be 0
 | ||||
|     addr2int =  ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[3] << 8 ) | ( (uint32_t)paddr[4] << 16 ) | ( (uint32_t)paddr[5] << 24 ); | ||||
|   addr2int = ((uint32_t)paddr[2]) | ((uint32_t)paddr[3] << 8) | | ||||
|              ((uint32_t)paddr[4] << 16) | ((uint32_t)paddr[5] << 24); | ||||
| 
 | ||||
| #ifdef VENDORFILTER | ||||
|         vendor2int = ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[1] << 8 ) | ( (uint32_t)paddr[0] << 16 ); | ||||
|   vendor2int = ((uint32_t)paddr[2]) | ((uint32_t)paddr[1] << 8) | | ||||
|                ((uint32_t)paddr[0] << 16); | ||||
|   // use OUI vendor filter list only on Wifi, not on BLE
 | ||||
|         if ( (sniff_type==MAC_SNIFF_BLE) || std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end() )  | ||||
|     { | ||||
|   if ((sniff_type == MAC_SNIFF_BLE) || | ||||
|       std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end()) { | ||||
| #endif | ||||
| 
 | ||||
|     // salt and hash MAC, and if new unique one, store identifier in container and increment counter on display
 | ||||
|     // salt and hash MAC, and if new unique one, store identifier in container
 | ||||
|     // and increment counter on display
 | ||||
|     // https://en.wikipedia.org/wiki/MAC_Address_Anonymization
 | ||||
| 
 | ||||
|     addr2int += (uint32_t)salt; // add 16-bit salt to pseudo MAC
 | ||||
| 	snprintf(buff, sizeof(buff), "%08X", addr2int);	// convert unsigned 32-bit salted MAC to 8 digit hex string
 | ||||
| 	hashedmac = rokkit(&buff[3], 5);	    // hash MAC last string value, use 5 chars to fit hash in uint16_t container
 | ||||
| 	auto newmac = macs.insert(hashedmac);	// add hashed MAC to total container if new unique
 | ||||
|     added = newmac.second ? true:false;     // true if hashed MAC is unique in container
 | ||||
|     snprintf( | ||||
|         buff, sizeof(buff), "%08X", | ||||
|         addr2int); // convert unsigned 32-bit salted MAC to 8 digit hex string
 | ||||
|     hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars
 | ||||
|                                      // to fit hash in uint16_t container
 | ||||
|     auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique
 | ||||
|     added = newmac.second ? true | ||||
|                           : false; // true if hashed MAC is unique in container
 | ||||
| 
 | ||||
|     // Count only if MAC was not yet seen
 | ||||
|     if (added) { | ||||
| @ -66,32 +76,39 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { | ||||
|     } | ||||
| 
 | ||||
|     // Log scan result
 | ||||
|     ESP_LOGI(TAG, "%s %s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d  BLTH:%d -> %d Bytes left", | ||||
|     ESP_LOGI(TAG, | ||||
|              "%s %s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d  BLTH:%d -> " | ||||
|              "%d Bytes left", | ||||
|              added ? "new  " : "known", | ||||
|         sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLTH",  | ||||
|         rssi, buff, hashedmac, macs_wifi, macs_ble, | ||||
|         ESP.getFreeHeap()); | ||||
|              sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff, | ||||
|              hashedmac, macs_wifi, macs_ble, ESP.getFreeHeap()); | ||||
| 
 | ||||
| #ifdef VENDORFILTER | ||||
|   } else { | ||||
|     // Very noisy
 | ||||
|         // ESP_LOGD(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X", paddr[0],paddr[1],paddr[2],paddr[3],paddr[5],paddr[5]);
 | ||||
|     // ESP_LOGD(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X",
 | ||||
|     // paddr[0],paddr[1],paddr[2],paddr[3],paddr[5],paddr[5]);
 | ||||
|   } | ||||
| #endif | ||||
| 
 | ||||
|   // True if MAC WiFi/BLE was new
 | ||||
|     return added; // function returns bool if a new and unique Wifi or BLE mac was counted (true) or not (false)
 | ||||
|   return added; // function returns bool if a new and unique Wifi or BLE mac was
 | ||||
|                 // counted (true) or not (false)
 | ||||
| } | ||||
| 
 | ||||
| void wifi_sniffer_init(void) { | ||||
|   wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); | ||||
|   cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM
 | ||||
| 		wifi_promiscuous_filter_t filter = {.filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames
 | ||||
|   wifi_promiscuous_filter_t filter = { | ||||
|       .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames
 | ||||
|   ESP_ERROR_CHECK(esp_wifi_init(&cfg));             // configure Wifi with cfg
 | ||||
|     	ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country));		// set locales for RF and channels
 | ||||
| 		ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));	// we don't need NVRAM
 | ||||
|   ESP_ERROR_CHECK( | ||||
|       esp_wifi_set_country(&wifi_country)); // set locales for RF and channels
 | ||||
|   ESP_ERROR_CHECK( | ||||
|       esp_wifi_set_storage(WIFI_STORAGE_RAM)); // we don't need NVRAM
 | ||||
|   // ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
 | ||||
|     	ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filter));	// set MAC frame filter
 | ||||
|   ESP_ERROR_CHECK( | ||||
|       esp_wifi_set_promiscuous_filter(&filter)); // set MAC frame filter
 | ||||
|   ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler)); | ||||
|   ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode
 | ||||
| } | ||||
| @ -101,16 +118,19 @@ void wifi_sniffer_set_channel(uint8_t channel) { | ||||
| } | ||||
| 
 | ||||
| // using IRAM_:ATTR here to speed up callback function
 | ||||
| IRAM_ATTR void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type) { | ||||
| IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, | ||||
|                                            wifi_promiscuous_pkt_type_t type) { | ||||
|   const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff; | ||||
|     const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload; | ||||
|   const wifi_ieee80211_packet_t *ipkt = | ||||
|       (wifi_ieee80211_packet_t *)ppkt->payload; | ||||
|   const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr; | ||||
| 
 | ||||
|     if ((cfg.rssilimit) && (ppkt->rx_ctrl.rssi < cfg.rssilimit )) { // rssi is negative value
 | ||||
|         ESP_LOGI(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi, cfg.rssilimit); | ||||
|   if ((cfg.rssilimit) && | ||||
|       (ppkt->rx_ctrl.rssi < cfg.rssilimit)) { // rssi is negative value
 | ||||
|     ESP_LOGI(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi, | ||||
|              cfg.rssilimit); | ||||
|   } else { | ||||
|     uint8_t *p = (uint8_t *)hdr->addr2; | ||||
|     mac_add(p, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| /*
 | ||||
|   | ||||
| 
 | ||||
| ESP32-Paxcounter | ||||
| 
 | ||||
| Copyright  2018 Oliver Brandmueller <ob@sysadm.in> | ||||
| Copyright  2018 Klaus Wilting <verkehrsrot@arcor.de> | ||||
|  | ||||
| @ -10,10 +10,7 @@ | ||||
| 
 | ||||
| //--- Declarations ---
 | ||||
| 
 | ||||
| enum led_states {  | ||||
|   LED_OFF, | ||||
|   LED_ON | ||||
| }; | ||||
| enum led_states { LED_OFF, LED_ON }; | ||||
| 
 | ||||
| #if defined(CFG_eu868) | ||||
| const char lora_datarate[] = {"1211100908077BFSNA"}; | ||||
| @ -28,7 +25,6 @@ void reset_counters(void); | ||||
| void blink_LED(uint16_t set_color, uint16_t set_blinkduration); | ||||
| void led_loop(void); | ||||
| 
 | ||||
| 
 | ||||
| // defined in blescan.cpp
 | ||||
| #ifdef BLECOUNTER | ||||
| void start_BLEscan(void); | ||||
|  | ||||
							
								
								
									
										183
									
								
								src/rcommand.cpp
									
									
									
									
									
								
							
							
						
						
									
										183
									
								
								src/rcommand.cpp
									
									
									
									
									
								
							| @ -1,6 +1,7 @@ | ||||
| // remote command interpreter
 | ||||
| // parses multiple number of command / value pairs from LoRaWAN remote command port (RCMDPORT)  
 | ||||
| // checks commands and executes each command with 1 argument per command
 | ||||
| // parses multiple number of command / value pairs from LoRaWAN remote command
 | ||||
| // port (RCMDPORT) checks commands and executes each command with 1 argument per
 | ||||
| // command
 | ||||
| 
 | ||||
| // Basic Config
 | ||||
| #include "globals.h" | ||||
| @ -31,18 +32,22 @@ typedef struct { | ||||
| 
 | ||||
| // function sends result of get commands to LoRaWAN network
 | ||||
| void do_transmit(osjob_t *j) { | ||||
|     // check if there is a pending TX/RX job running, if yes then reschedule transmission
 | ||||
|   // check if there is a pending TX/RX job running, if yes then reschedule
 | ||||
|   // transmission
 | ||||
|   if (LMIC.opmode & OP_TXRXPEND) { | ||||
|     ESP_LOGI(TAG, "LoRa busy, rescheduling"); | ||||
|     sprintf(display_lmic, "LORA BUSY"); | ||||
|         os_setTimedCallback(&rcmdjob, os_getTime()+sec2osticks(RETRANSMIT_RCMD), do_transmit); | ||||
|     os_setTimedCallback(&rcmdjob, os_getTime() + sec2osticks(RETRANSMIT_RCMD), | ||||
|                         do_transmit); | ||||
|   } | ||||
|     LMIC_setTxData2(RCMDPORT, rcmd_data, rcmd_data_size, 0); // send data unconfirmed on RCMD Port
 | ||||
|   LMIC_setTxData2(RCMDPORT, rcmd_data, rcmd_data_size, | ||||
|                   0); // send data unconfirmed on RCMD Port
 | ||||
|   ESP_LOGI(TAG, "%d bytes queued to send", rcmd_data_size); | ||||
|   sprintf(display_lmic, "PACKET QUEUED"); | ||||
| } | ||||
| 
 | ||||
| // help function to transmit result of get commands, since callback function do_transmit() cannot have params
 | ||||
| // help function to transmit result of get commands, since callback function
 | ||||
| // do_transmit() cannot have params
 | ||||
| void transmit(xref2u1_t mydata, u1_t mydata_size) { | ||||
|   rcmd_data = mydata; | ||||
|   rcmd_data_size = mydata_size; | ||||
| @ -51,26 +56,48 @@ void transmit(xref2u1_t mydata, u1_t mydata_size){ | ||||
| 
 | ||||
| // help function to assign LoRa datarates to numeric spreadfactor values
 | ||||
| void switch_lora(uint8_t sf, uint8_t tx) { | ||||
|     if ( tx > 20 ) return; | ||||
|   if (tx > 20) | ||||
|     return; | ||||
|   cfg.txpower = tx; | ||||
|   switch (sf) { | ||||
|         case 7: LMIC_setDrTxpow(DR_SF7,tx); cfg.lorasf=sf; break; | ||||
|         case 8: LMIC_setDrTxpow(DR_SF8,tx); cfg.lorasf=sf; break; | ||||
|         case 9: LMIC_setDrTxpow(DR_SF9,tx); cfg.lorasf=sf; break; | ||||
|         case 10: LMIC_setDrTxpow(DR_SF10,tx); cfg.lorasf=sf; break; | ||||
|   case 7: | ||||
|     LMIC_setDrTxpow(DR_SF7, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
|   case 8: | ||||
|     LMIC_setDrTxpow(DR_SF8, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
|   case 9: | ||||
|     LMIC_setDrTxpow(DR_SF9, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
|   case 10: | ||||
|     LMIC_setDrTxpow(DR_SF10, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
|   case 11: | ||||
| #if defined(CFG_eu868) | ||||
|             LMIC_setDrTxpow(DR_SF11,tx); cfg.lorasf=sf; break; | ||||
|     LMIC_setDrTxpow(DR_SF11, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
| #elif defined(CFG_us915) | ||||
|             LMIC_setDrTxpow(DR_SF11CR,tx); cfg.lorasf=sf; break; | ||||
|     LMIC_setDrTxpow(DR_SF11CR, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
| #endif | ||||
|   case 12: | ||||
| #if defined(CFG_eu868) | ||||
|             LMIC_setDrTxpow(DR_SF12,tx); cfg.lorasf=sf; break; | ||||
|     LMIC_setDrTxpow(DR_SF12, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
| #elif defined(CFG_us915) | ||||
|             LMIC_setDrTxpow(DR_SF12CR,tx); cfg.lorasf=sf; break; | ||||
|     LMIC_setDrTxpow(DR_SF12CR, tx); | ||||
|     cfg.lorasf = sf; | ||||
|     break; | ||||
| #endif | ||||
|         default: break; | ||||
|   default: | ||||
|     break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -80,7 +107,9 @@ void set_reset(uint8_t val) { | ||||
|   case 0: // restart device
 | ||||
|     ESP_LOGI(TAG, "Remote command: restart device"); | ||||
|     sprintf(display_lora, "Reset pending"); | ||||
|             vTaskDelay(10000/portTICK_PERIOD_MS); // wait for LMIC to confirm LoRa downlink to server
 | ||||
|     vTaskDelay( | ||||
|         10000 / | ||||
|         portTICK_PERIOD_MS); // wait for LMIC to confirm LoRa downlink to server
 | ||||
|     esp_restart(); | ||||
|     break; | ||||
|   case 1: // reset MAC counter
 | ||||
| @ -104,23 +133,28 @@ void set_rssi(uint8_t val) { | ||||
| 
 | ||||
| void set_sendcycle(uint8_t val) { | ||||
|   cfg.sendcycle = val; | ||||
|     ESP_LOGI(TAG, "Remote command: set payload send cycle to %d seconds", cfg.sendcycle*2); | ||||
|   ESP_LOGI(TAG, "Remote command: set payload send cycle to %d seconds", | ||||
|            cfg.sendcycle * 2); | ||||
| }; | ||||
| 
 | ||||
| void set_wifichancycle(uint8_t val) { | ||||
|   cfg.wifichancycle = val; | ||||
|   // modify wifi channel rotation IRQ
 | ||||
|     timerAlarmWrite(channelSwitch, cfg.wifichancycle * 10000, true); // reload interrupt after each trigger of channel switch cycle
 | ||||
|     ESP_LOGI(TAG, "Remote command: set Wifi channel switch interval to %.1f seconds", cfg.wifichancycle/float(100)); | ||||
|   timerAlarmWrite( | ||||
|       channelSwitch, cfg.wifichancycle * 10000, | ||||
|       true); // reload interrupt after each trigger of channel switch cycle
 | ||||
|   ESP_LOGI(TAG, | ||||
|            "Remote command: set Wifi channel switch interval to %.1f seconds", | ||||
|            cfg.wifichancycle / float(100)); | ||||
| }; | ||||
| 
 | ||||
| void set_blescantime(uint8_t val) { | ||||
|   cfg.blescantime = val; | ||||
|     ESP_LOGI(TAG, "Remote command: set BLE scan time to %.1f seconds", cfg.blescantime/float(100)); | ||||
|   ESP_LOGI(TAG, "Remote command: set BLE scan time to %.1f seconds", | ||||
|            cfg.blescantime / float(100)); | ||||
| #ifdef BLECOUNTER | ||||
|   // stop & restart BLE scan task to apply new parameter
 | ||||
|         if (cfg.blescan) | ||||
|         { | ||||
|   if (cfg.blescan) { | ||||
|     stop_BLEscan(); | ||||
|     start_BLEscan(); | ||||
|   } | ||||
| @ -147,24 +181,36 @@ void set_countmode(uint8_t val) { | ||||
| void set_screensaver(uint8_t val) { | ||||
|   ESP_LOGI(TAG, "Remote command: set screen saver to %s ", val ? "on" : "off"); | ||||
|   switch (val) { | ||||
|         case 1: cfg.screensaver = val; break; | ||||
|         default: cfg.screensaver = 0; break; | ||||
|   case 1: | ||||
|     cfg.screensaver = val; | ||||
|     break; | ||||
|   default: | ||||
|     cfg.screensaver = 0; | ||||
|     break; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| void set_display(uint8_t val) { | ||||
|   ESP_LOGI(TAG, "Remote command: set screen to %s", val ? "on" : "off"); | ||||
|   switch (val) { | ||||
|         case 1: cfg.screenon = val; break; | ||||
|         default: cfg.screenon = 0; break; | ||||
|   case 1: | ||||
|     cfg.screenon = val; | ||||
|     break; | ||||
|   default: | ||||
|     cfg.screenon = 0; | ||||
|     break; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| void set_gps(uint8_t val) { | ||||
|   ESP_LOGI(TAG, "Remote command: set GPS to %s", val ? "on" : "off"); | ||||
|   switch (val) { | ||||
|         case 1: cfg.gpsmode = val; break; | ||||
|         default: cfg.gpsmode = 0; break; | ||||
|   case 1: | ||||
|     cfg.gpsmode = val; | ||||
|     break; | ||||
|   default: | ||||
|     cfg.gpsmode = 0; | ||||
|     break; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| @ -176,8 +222,12 @@ void set_lorasf(uint8_t val) { | ||||
| void set_loraadr(uint8_t val) { | ||||
|   ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off"); | ||||
|   switch (val) { | ||||
|         case 1: cfg.adrmode = val; break; | ||||
|         default: cfg.adrmode = 0; break; | ||||
|   case 1: | ||||
|     cfg.adrmode = val; | ||||
|     break; | ||||
|   default: | ||||
|     cfg.adrmode = 0; | ||||
|     break; | ||||
|   } | ||||
|   LMIC_setAdrMode(cfg.adrmode); | ||||
| }; | ||||
| @ -202,10 +252,15 @@ void set_blescan(uint8_t val) { | ||||
| }; | ||||
| 
 | ||||
| void set_wifiant(uint8_t val) { | ||||
|     ESP_LOGI(TAG, "Remote command: set Wifi antenna to %s", val ? "external" : "internal"); | ||||
|   ESP_LOGI(TAG, "Remote command: set Wifi antenna to %s", | ||||
|            val ? "external" : "internal"); | ||||
|   switch (val) { | ||||
|         case 1: cfg.wifiant = val; break; | ||||
|         default: cfg.wifiant = 0; break; | ||||
|   case 1: | ||||
|     cfg.wifiant = val; | ||||
|     break; | ||||
|   default: | ||||
|     cfg.wifiant = 0; | ||||
|     break; | ||||
|   } | ||||
| #ifdef HAS_ANTENNA_SWITCH | ||||
|   antenna_select(cfg.wifiant); | ||||
| @ -213,10 +268,15 @@ void set_wifiant(uint8_t val) { | ||||
| }; | ||||
| 
 | ||||
| void set_vendorfilter(uint8_t val) { | ||||
|     ESP_LOGI(TAG, "Remote command: set vendorfilter mode to %s", val ? "on" : "off"); | ||||
|   ESP_LOGI(TAG, "Remote command: set vendorfilter mode to %s", | ||||
|            val ? "on" : "off"); | ||||
|   switch (val) { | ||||
|         case 1: cfg.vendorfilter = val; break; | ||||
|         default: cfg.vendorfilter = 0; break; | ||||
|   case 1: | ||||
|     cfg.vendorfilter = val; | ||||
|     break; | ||||
|   default: | ||||
|     cfg.vendorfilter = 0; | ||||
|     break; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| @ -262,7 +322,9 @@ void get_gps (uint8_t val) { | ||||
| #ifdef HAS_GPS | ||||
|   gps_read(); | ||||
|   transmit((byte *)&gps_status, sizeof(gps_status)); | ||||
|         ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, gps_status.altitude); | ||||
|   ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", | ||||
|            gps_status.latitude / 1000000, gps_status.longitude / 1000000, | ||||
|            gps_status.satellites, gps_status.hdop, gps_status.altitude); | ||||
| #else | ||||
|   ESP_LOGE(TAG, "GPS not present"); | ||||
| #endif | ||||
| @ -271,40 +333,33 @@ void get_gps (uint8_t val) { | ||||
| // assign previously defined functions to set of numeric remote commands
 | ||||
| // format: opcode, function, flag (1 = do make settings persistent / 0 = don't)
 | ||||
| //
 | ||||
| cmd_t table[] = { | ||||
|                 {0x01, set_rssi, true}, | ||||
|                 {0x02, set_countmode, true}, | ||||
|                 {0x03, set_gps, true}, | ||||
|                 {0x04, set_display, true}, | ||||
|                 {0x05, set_lorasf, true}, | ||||
|                 {0x06, set_lorapower, true}, | ||||
|                 {0x07, set_loraadr, true}, | ||||
|                 {0x08, set_screensaver, true}, | ||||
|                 {0x09, set_reset, false}, | ||||
|                 {0x0a, set_sendcycle, true}, | ||||
|                 {0x0b, set_wifichancycle, true}, | ||||
|                 {0x0c, set_blescantime, true}, | ||||
|                 {0x0d, set_vendorfilter, false}, | ||||
|                 {0x0e, set_blescan, true}, | ||||
|                 {0x0f, set_wifiant, true}, | ||||
|                 {0x10, set_rgblum, true}, | ||||
|                 {0x80, get_config, false}, | ||||
|                 {0x81, get_uptime, false}, | ||||
|                 {0x82, get_cputemp, false}, | ||||
|                 {0x83, get_voltage, false}, | ||||
|                 {0x84, get_gps, false} | ||||
|                 }; | ||||
| cmd_t table[] = {{0x01, set_rssi, true},          {0x02, set_countmode, true}, | ||||
|                  {0x03, set_gps, true},           {0x04, set_display, true}, | ||||
|                  {0x05, set_lorasf, true},        {0x06, set_lorapower, true}, | ||||
|                  {0x07, set_loraadr, true},       {0x08, set_screensaver, true}, | ||||
|                  {0x09, set_reset, false},        {0x0a, set_sendcycle, true}, | ||||
|                  {0x0b, set_wifichancycle, true}, {0x0c, set_blescantime, true}, | ||||
|                  {0x0d, set_vendorfilter, false}, {0x0e, set_blescan, true}, | ||||
|                  {0x0f, set_wifiant, true},       {0x10, set_rgblum, true}, | ||||
|                  {0x80, get_config, false},       {0x81, get_uptime, false}, | ||||
|                  {0x82, get_cputemp, false},      {0x83, get_voltage, false}, | ||||
|                  {0x84, get_gps, false}}; | ||||
| 
 | ||||
| // check and execute remote command
 | ||||
| void rcommand(uint8_t cmd, uint8_t arg) { | ||||
|     int i = sizeof(table) / sizeof(table[0]); // number of commands in command table
 | ||||
|   int i = | ||||
|       sizeof(table) / sizeof(table[0]); // number of commands in command table
 | ||||
|   bool store_flag = false; | ||||
|   while (i--) { | ||||
|     if (cmd == table[i].nam) { // check if valid command
 | ||||
|       table[i].func(arg);      // then execute assigned function
 | ||||
|             if ( table[i].store ) store_flag = true; // set save flag if function needs to store configuration
 | ||||
|       if (table[i].store) | ||||
|         store_flag = | ||||
|             true; // set save flag if function needs to store configuration
 | ||||
|       break;      // exit check loop, since command was found
 | ||||
|     } | ||||
|   } | ||||
|     if (store_flag) saveConfig(); // if save flag is set: store new configuration in NVS to make it persistent
 | ||||
|   if (store_flag) | ||||
|     saveConfig(); // if save flag is set: store new configuration in NVS to make
 | ||||
|                   // it persistent
 | ||||
| } | ||||
| @ -6,8 +6,7 @@ | ||||
| // RGB Led instance
 | ||||
| SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED); | ||||
| 
 | ||||
| float rgb_CalcColor(float p, float q, float t) | ||||
| { | ||||
| float rgb_CalcColor(float p, float q, float t) { | ||||
|   if (t < 0.0f) | ||||
|     t += 1.0f; | ||||
|   if (t > 1.0f) | ||||
| @ -30,19 +29,15 @@ float rgb_CalcColor(float p, float q, float t) | ||||
| // HslColor using H, S, L values (0.0 - 1.0)
 | ||||
| // L should be limited to between (0.0 - 0.5)
 | ||||
| // ------------------------------------------------------------------------
 | ||||
| RGBColor rgb_hsl2rgb(float h, float s, float l) | ||||
| { | ||||
| RGBColor rgb_hsl2rgb(float h, float s, float l) { | ||||
|   RGBColor RGB_color; | ||||
|   float r; | ||||
|   float g; | ||||
|   float b; | ||||
| 
 | ||||
|     if (s == 0.0f || l == 0.0f) | ||||
|     { | ||||
|   if (s == 0.0f || l == 0.0f) { | ||||
|     r = g = b = l; // achromatic or black
 | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|   } else { | ||||
|     float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s); | ||||
|     float p = 2.0f * l - q; | ||||
|     r = rgb_CalcColor(p, q, h + 1.0f / 3.0f); | ||||
|  | ||||
| @ -19,8 +19,7 @@ | ||||
| #define COLOR_WHITE 360 | ||||
| #define COLOR_NONE 999 | ||||
| 
 | ||||
| struct RGBColor | ||||
| { | ||||
| struct RGBColor { | ||||
|   uint8_t R; | ||||
|   uint8_t G; | ||||
|   uint8_t B; | ||||
|  | ||||
| @ -40,7 +40,8 @@ uint32_t rokkit(const char * data, int len) { | ||||
|   uint32_t hash, tmp; | ||||
|   int rem; | ||||
| 
 | ||||
|     if (len <= 0 || data == 0) return 0; | ||||
|   if (len <= 0 || data == 0) | ||||
|     return 0; | ||||
|   hash = len; | ||||
|   rem = len & 3; | ||||
|   len >>= 2; | ||||
| @ -57,16 +58,19 @@ uint32_t rokkit(const char * data, int len) { | ||||
| 
 | ||||
|   /* Handle end cases */ | ||||
|   switch (rem) { | ||||
|         case 3: hash += *((uint16_t*)data); | ||||
|   case 3: | ||||
|     hash += *((uint16_t *)data); | ||||
|     hash ^= hash << 16; | ||||
|     hash ^= ((signed char)data[2]) << 18; | ||||
|     hash += hash >> 11; | ||||
|     break; | ||||
|         case 2: hash += *((uint16_t*)data); | ||||
|   case 2: | ||||
|     hash += *((uint16_t *)data); | ||||
|     hash ^= hash << 11; | ||||
|     hash += hash >> 17; | ||||
|     break; | ||||
|         case 1: hash += (signed char)*data; | ||||
|   case 1: | ||||
|     hash += (signed char)*data; | ||||
|     hash ^= hash << 10; | ||||
|     hash += hash >> 1; | ||||
|   } | ||||
|  | ||||
							
								
								
									
										1639
									
								
								src/vendor_array.h
									
									
									
									
									
								
							
							
						
						
									
										1639
									
								
								src/vendor_array.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user