Merge pull request #17 from cyberman54/hallard-master
v1.2.8 - thanks to Charles Hallard for contribution!
This commit is contained in:
		
						commit
						2a23f66050
					
				
							
								
								
									
										12
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								README.md
									
									
									
									
									
								
							| @ -126,8 +126,8 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. | |||||||
| 0x07 set LoRa Adaptive Data Rate mode | 0x07 set LoRa Adaptive Data Rate mode | ||||||
| 
 | 
 | ||||||
| 	0 = ADR off | 	0 = ADR off | ||||||
| 	1 = ADR on [default]  | 	1 = ADR on [default] | ||||||
| 	 | 
 | ||||||
| 	note: set ADR to off, if device is moving, set to on, if not. | 	note: set ADR to off, if device is moving, set to on, if not. | ||||||
| 
 | 
 | ||||||
| 0x08 do nothing | 0x08 do nothing | ||||||
| @ -165,6 +165,11 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. | |||||||
| 	0 = internal antenna [default] | 	0 = internal antenna [default] | ||||||
| 	1 = external antenna | 	1 = external antenna | ||||||
| 
 | 
 | ||||||
|  | 0x0F set RGB led luminosity (works on LoPy/LoPy4 and LoRaNode32 shield only) | ||||||
|  | 
 | ||||||
|  | 		0 ... 100 percentage of luminosity (100% = full light) | ||||||
|  | 		e.g. 40 -> 40% of luminosity | ||||||
|  | 
 | ||||||
| 0x80 get device configuration | 0x80 get device configuration | ||||||
| 
 | 
 | ||||||
| 	device answers with it's current configuration: | 	device answers with it's current configuration: | ||||||
| @ -181,7 +186,8 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. | |||||||
| 	byte 11:		BLE scan cycle duration in seconds (0..255) | 	byte 11:		BLE scan cycle duration in seconds (0..255) | ||||||
| 	byte 12:		BLE scan mode (1=on, 0=0ff) | 	byte 12:		BLE scan mode (1=on, 0=0ff) | ||||||
| 	byte 13:		Wifi antenna switch (0=internal, 1=external) | 	byte 13:		Wifi antenna switch (0=internal, 1=external) | ||||||
| 	bytes 14-23:		Software version (ASCII format) | 	byte 14:		RGB LED luminosity (0..100 %) | ||||||
|  | 	bytes 15-24:		Software version (ASCII format) | ||||||
| 
 | 
 | ||||||
| 0x81 get device uptime | 0x81 get device uptime | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -95,7 +95,7 @@ monitor_baud = 115200 | |||||||
| lib_deps =  | lib_deps =  | ||||||
|     U8g2@>2.21.7 |     U8g2@>2.21.7 | ||||||
|     ESP32 BLE Arduino@>=0.4.9 |     ESP32 BLE Arduino@>=0.4.9 | ||||||
|     ;  NeoPixelBus |     SmartLeds | ||||||
| build_flags =  | build_flags =  | ||||||
| ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ||||||
|    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE |    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE | ||||||
| @ -118,8 +118,8 @@ monitor_baud = 115200 | |||||||
| lib_deps = | lib_deps = | ||||||
|      U8g2@>2.21.7 |      U8g2@>2.21.7 | ||||||
|      ESP32 BLE Arduino@>=0.4.9 |      ESP32 BLE Arduino@>=0.4.9 | ||||||
|      ;  NeoPixelBus |      SmartLeds | ||||||
| build_flags =  | build_flags = | ||||||
| ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ||||||
|    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE |    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE | ||||||
| ;    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE | ;    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE | ||||||
| @ -142,8 +142,8 @@ upload_speed = 256000 | |||||||
| lib_deps =  | lib_deps =  | ||||||
|     U8g2 |     U8g2 | ||||||
|     ESP32 BLE Arduino@>=0.4.9 |     ESP32 BLE Arduino@>=0.4.9 | ||||||
| ;  NeoPixelBus |     SmartLeds | ||||||
| build_flags =  | build_flags = | ||||||
| ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ||||||
|     -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE |     -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE | ||||||
| ;    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE | ;    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE | ||||||
| @ -166,8 +166,8 @@ upload_speed = 921600 | |||||||
| lib_deps =  | lib_deps =  | ||||||
|     U8g2 |     U8g2 | ||||||
|     ESP32 BLE Arduino@>=0.4.9 |     ESP32 BLE Arduino@>=0.4.9 | ||||||
| ;  NeoPixelBus |     SmartLeds | ||||||
| build_flags =  | build_flags = | ||||||
| ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework | ||||||
|     -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE |     -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE | ||||||
| ;    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE | ;    -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE | ||||||
| @ -180,4 +180,3 @@ build_flags = | |||||||
|     -include "src/hal/lolin32_lora.h" |     -include "src/hal/lolin32_lora.h" | ||||||
| ;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp) | ;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp) | ||||||
| ;   -DCONFIG_FREERTOS_UNICORE | ;   -DCONFIG_FREERTOS_UNICORE | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -1,32 +0,0 @@ | |||||||
| 
 |  | ||||||
| // Basic Config
 |  | ||||||
| #include "globals.h" |  | ||||||
| 
 |  | ||||||
| #ifdef BLECOUNTER |  | ||||||
| #include <BLEDevice.h> |  | ||||||
| #include <BLEUtils.h> |  | ||||||
| #include <BLEScan.h> |  | ||||||
| #include <BLEAdvertisedDevice.h> |  | ||||||
| 
 |  | ||||||
| // Local logging tag
 |  | ||||||
| static const char *TAG = "blecount"; |  | ||||||
| 
 |  | ||||||
| class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { |  | ||||||
|     void onResult(BLEAdvertisedDevice advertisedDevice) { |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| void BLECount() { |  | ||||||
|     u8x8.clearLine(3); |  | ||||||
|     u8x8.drawString(0,3,"BLE Scan..."); |  | ||||||
|     BLEDevice::init(PROGNAME); |  | ||||||
|     BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
 |  | ||||||
|     pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); |  | ||||||
|     pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
 |  | ||||||
|     BLEScanResults foundDevices = pBLEScan->start(cfg.blescancycle); |  | ||||||
|     u8x8.clearLine(3); |  | ||||||
|     u8x8.setCursor(0,3); |  | ||||||
|     blenum=foundDevices.getCount(); |  | ||||||
|     u8x8.printf("BLE#: %-5i",blenum); |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| @ -29,8 +29,10 @@ void defaultConfig() { | |||||||
|     cfg.wifiscancycle = SEND_SECS; // wifi scan cycle [seconds/2]
 |     cfg.wifiscancycle = SEND_SECS; // wifi scan cycle [seconds/2]
 | ||||||
|     cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
 |     cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
 | ||||||
|     cfg.blescancycle  = BLESCANTIME; // BLE scan cycle [seconds]
 |     cfg.blescancycle  = BLESCANTIME; // BLE scan cycle [seconds]
 | ||||||
|     cfg.blescan     = 0;  // 0=disabled, 1=enabled
 |     cfg.blescan     = 1;  // 0=disabled, 1=enabled
 | ||||||
|     cfg.wifiant     = 0;  // 0=internal, 1=external (for LoPy/LoPy4)
 |     cfg.wifiant     = 0;  // 0=internal, 1=external (for LoPy/LoPy4)
 | ||||||
|  |     cfg.rgblum      = RGBLUMINOSITY; // RGB Led luminosity (0 100%)
 | ||||||
|  | 
 | ||||||
|     strncpy( cfg.version, PROGVERSION, sizeof(cfg.version)-1 ); |     strncpy( cfg.version, PROGVERSION, sizeof(cfg.version)-1 ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -47,7 +49,7 @@ void open_storage() { | |||||||
|     // Open
 |     // Open
 | ||||||
|     ESP_LOGI(TAG, "Opening NVS"); |     ESP_LOGI(TAG, "Opening NVS"); | ||||||
|     err = nvs_open("config", NVS_READWRITE, &my_handle); |     err = nvs_open("config", NVS_READWRITE, &my_handle); | ||||||
|     if (err != ESP_OK)  |     if (err != ESP_OK) | ||||||
|       ESP_LOGI(TAG, "Error (%d) opening NVS handle", err); |       ESP_LOGI(TAG, "Error (%d) opening NVS handle", err); | ||||||
|     else |     else | ||||||
|       ESP_LOGI(TAG, "Done"); |       ESP_LOGI(TAG, "Done"); | ||||||
| @ -56,14 +58,14 @@ void open_storage() { | |||||||
| // erase all keys and values in NVRAM
 | // erase all keys and values in NVRAM
 | ||||||
| void eraseConfig() { | void eraseConfig() { | ||||||
|     ESP_LOGI(TAG, "Clearing settings in NVS"); |     ESP_LOGI(TAG, "Clearing settings in NVS"); | ||||||
|     open_storage();  |     open_storage(); | ||||||
|     if (err == ESP_OK) { |     if (err == ESP_OK) { | ||||||
|       nvs_erase_all(my_handle); |       nvs_erase_all(my_handle); | ||||||
|       nvs_commit(my_handle); |       nvs_commit(my_handle); | ||||||
|       nvs_close(my_handle); |       nvs_close(my_handle); | ||||||
|       ESP_LOGI(TAG, "Done");}  |       ESP_LOGI(TAG, "Done");} | ||||||
|     else {  |     else { | ||||||
|       ESP_LOGW(TAG, "NVS erase failed"); }  |       ESP_LOGW(TAG, "NVS erase failed"); } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // save current configuration from RAM to NVRAM
 | // save current configuration from RAM to NVRAM
 | ||||||
| @ -75,10 +77,10 @@ void saveConfig() { | |||||||
|       int16_t flash16 = 0; |       int16_t flash16 = 0; | ||||||
|       size_t required_size; |       size_t required_size; | ||||||
|       char storedversion[10]; |       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); |         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); |         nvs_set_i8(my_handle, "lorasf", cfg.lorasf); | ||||||
| 
 | 
 | ||||||
| @ -110,11 +112,14 @@ void saveConfig() { | |||||||
|         nvs_set_i8(my_handle, "blescanmode", 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);         |         nvs_set_i8(my_handle, "wifiant", cfg.wifiant); | ||||||
|  | 
 | ||||||
|  |       if( nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || flash8 != cfg.rgblum ) | ||||||
|  |           nvs_set_i8(my_handle, "rgblum", cfg.rgblum); | ||||||
| 
 | 
 | ||||||
|       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); |         nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit); | ||||||
|        | 
 | ||||||
|       err = nvs_commit(my_handle); |       err = nvs_commit(my_handle); | ||||||
|       nvs_close(my_handle); |       nvs_close(my_handle); | ||||||
|       if ( err == ESP_OK ) { |       if ( err == ESP_OK ) { | ||||||
| @ -146,7 +151,7 @@ void loadConfig() { | |||||||
|     int8_t  flash8  = 0; |     int8_t  flash8  = 0; | ||||||
|     int16_t flash16 = 0; |     int16_t flash16 = 0; | ||||||
|     size_t required_size; |     size_t required_size; | ||||||
|      | 
 | ||||||
|     // check if configuration stored in NVRAM matches PROGVERSION
 |     // check if configuration stored in NVRAM matches PROGVERSION
 | ||||||
|     if( nvs_get_str(my_handle, "version", NULL, &required_size) == ESP_OK ) { |     if( nvs_get_str(my_handle, "version", NULL, &required_size) == ESP_OK ) { | ||||||
|       nvs_get_str(my_handle, "version", cfg.version, &required_size); |       nvs_get_str(my_handle, "version", cfg.version, &required_size); | ||||||
| @ -227,7 +232,7 @@ void loadConfig() { | |||||||
|       ESP_LOGI(TAG, "WIFI channel cycle set to default %i", cfg.wifichancycle); |       ESP_LOGI(TAG, "WIFI channel cycle set to default %i", cfg.wifichancycle); | ||||||
|       saveConfig(); |       saveConfig(); | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|     if( nvs_get_i8(my_handle, "wifiant", &flash8) == ESP_OK ) { |     if( nvs_get_i8(my_handle, "wifiant", &flash8) == ESP_OK ) { | ||||||
|       cfg.wifiant = flash8; |       cfg.wifiant = flash8; | ||||||
|       ESP_LOGI(TAG, "wifiantenna = %i", flash8); |       ESP_LOGI(TAG, "wifiantenna = %i", flash8); | ||||||
| @ -236,6 +241,14 @@ void loadConfig() { | |||||||
|       saveConfig(); |       saveConfig(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if( nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK ) { | ||||||
|  |       cfg.rgblum = flash8; | ||||||
|  |       ESP_LOGI(TAG, "rgbluminosity = %i", flash8); | ||||||
|  |     } else { | ||||||
|  |       ESP_LOGI(TAG, "RGB luminosity set to default %i", cfg.rgblum); | ||||||
|  |       saveConfig(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if( nvs_get_i8(my_handle, "blescancycle", &flash8) == ESP_OK ) { |     if( nvs_get_i8(my_handle, "blescancycle", &flash8) == ESP_OK ) { | ||||||
|       cfg.blescancycle = flash8; |       cfg.blescancycle = flash8; | ||||||
|       ESP_LOGI(TAG, "blescancycle = %i", flash8); |       ESP_LOGI(TAG, "blescancycle = %i", flash8); | ||||||
| @ -251,7 +264,7 @@ void loadConfig() { | |||||||
|       ESP_LOGI(TAG, "BLEscanmode set to default %i", cfg.blescan); |       ESP_LOGI(TAG, "BLEscanmode set to default %i", cfg.blescan); | ||||||
|       saveConfig(); |       saveConfig(); | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|     if( nvs_get_i16(my_handle, "rssilimit", &flash16) == ESP_OK ) { |     if( nvs_get_i16(my_handle, "rssilimit", &flash16) == ESP_OK ) { | ||||||
|       cfg.rssilimit = flash16; |       cfg.rssilimit = flash16; | ||||||
|       ESP_LOGI(TAG, "rssilimit = %i", flash16); |       ESP_LOGI(TAG, "rssilimit = %i", flash16); | ||||||
| @ -259,7 +272,7 @@ void loadConfig() { | |||||||
|       ESP_LOGI(TAG, "rssilimit set to default %i", cfg.rssilimit); |       ESP_LOGI(TAG, "rssilimit set to default %i", cfg.rssilimit); | ||||||
|       saveConfig(); |       saveConfig(); | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|     nvs_close(my_handle); |     nvs_close(my_handle); | ||||||
|     ESP_LOGI(TAG, "Done"); |     ESP_LOGI(TAG, "Done"); | ||||||
| 
 | 
 | ||||||
| @ -268,5 +281,5 @@ void loadConfig() { | |||||||
|     #ifdef HAS_ANTENNA_SWITCH // set antenna type, if device has one
 |     #ifdef HAS_ANTENNA_SWITCH // set antenna type, if device has one
 | ||||||
|       antenna_select(cfg.wifiant); |       antenna_select(cfg.wifiant); | ||||||
|     #endif |     #endif | ||||||
|     }  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ | |||||||
| 
 | 
 | ||||||
| // std::set for unified array functions
 | // std::set for unified array functions
 | ||||||
| #include <set> | #include <set> | ||||||
|  | #include <array> | ||||||
|  | #include <algorithm> | ||||||
| 
 | 
 | ||||||
| // OLED Display
 | // OLED Display
 | ||||||
| #include <U8x8lib.h> | #include <U8x8lib.h> | ||||||
| @ -11,6 +13,12 @@ | |||||||
| #include <lmic.h> | #include <lmic.h> | ||||||
| #include <hal/hal.h> | #include <hal/hal.h> | ||||||
| 
 | 
 | ||||||
|  | #ifdef HAS_RGB_LED | ||||||
|  | #include <SmartLeds.h> | ||||||
|  | #endif | ||||||
|  | #include "rgb_led.h" | ||||||
|  | #include "macsniff.h" | ||||||
|  | 
 | ||||||
| // Struct holding devices's runtime configuration
 | // Struct holding devices's runtime configuration
 | ||||||
| typedef struct { | typedef struct { | ||||||
|   int8_t lorasf;                       // 7-12, lora spreadfactor
 |   int8_t lorasf;                       // 7-12, lora spreadfactor
 | ||||||
| @ -25,6 +33,7 @@ typedef struct { | |||||||
|   int8_t blescancycle;                 // BLE scan cycle [seconds]
 |   int8_t blescancycle;                 // BLE scan cycle [seconds]
 | ||||||
|   int8_t blescan;                      // 0=disabled, 1=enabled
 |   int8_t blescan;                      // 0=disabled, 1=enabled
 | ||||||
|   int8_t wifiant;                      // 0=internal, 1=external (for LoPy/LoPy4)
 |   int8_t wifiant;                      // 0=internal, 1=external (for LoPy/LoPy4)
 | ||||||
|  |   int8_t rgblum;                       // RGB Led luminosity (0 100%)
 | ||||||
|   char version[10];                    // Firmware version
 |   char version[10];                    // Firmware version
 | ||||||
|   } configData_t; |   } configData_t; | ||||||
| 
 | 
 | ||||||
| @ -32,9 +41,9 @@ extern configData_t cfg; | |||||||
| extern uint8_t mydata[]; | extern uint8_t mydata[]; | ||||||
| extern uint64_t uptimecounter; | extern uint64_t uptimecounter; | ||||||
| extern osjob_t sendjob; | extern osjob_t sendjob; | ||||||
| extern uint16_t macnum, blenum, salt; | extern int countermode, screensaver, adrmode, lorasf, txpower, rlim, salt; | ||||||
| extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; |  | ||||||
| extern bool joinstate; | extern bool joinstate; | ||||||
|  | extern std::set<uint16_t> wifis;  | ||||||
| extern std::set<uint16_t> macs;  | extern std::set<uint16_t> macs;  | ||||||
| 
 | 
 | ||||||
| #ifdef HAS_DISPLAY | #ifdef HAS_DISPLAY | ||||||
| @ -45,4 +54,5 @@ extern std::set<uint16_t> macs; | |||||||
| 
 | 
 | ||||||
| #ifdef BLECOUNTER | #ifdef BLECOUNTER | ||||||
|     extern int scanTime; |     extern int scanTime; | ||||||
| #endif |     extern std::set<uint16_t> bles;  | ||||||
|  | #endif | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ | |||||||
| 
 | 
 | ||||||
| #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
 | #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
 | ||||||
| #define HAS_LED NOT_A_PIN // Led os on same pin than Lora SS pin, to avoid pb, we don't use it
 | #define HAS_LED NOT_A_PIN // Led os on same pin than Lora SS pin, to avoid pb, we don't use it
 | ||||||
|  | #define LED_ACTIVE_LOW 1  // Onboard LED is active when pin is LOW
 | ||||||
|                           // Anyway shield is on over the LoLin32 board, so we won't be able to see this LED
 |                           // Anyway shield is on over the LoLin32 board, so we won't be able to see this LED
 | ||||||
| #define HAS_RGB_LED   13  // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
 | #define HAS_RGB_LED   13  // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
 | ||||||
| #define HAS_BUTTON    15  // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
 | #define HAS_BUTTON    15  // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
 | ||||||
| @ -30,4 +31,3 @@ | |||||||
| #define OLED_RST U8X8_PIN_NONE  // Not reset pin
 | #define OLED_RST U8X8_PIN_NONE  // Not reset pin
 | ||||||
| #define OLED_SDA 21             // ESP32 GPIO21 (Pin21) -- OLED SDA
 | #define OLED_SDA 21             // ESP32 GPIO21 (Pin21) -- OLED SDA
 | ||||||
| #define OLED_SCL 22             // ESP32 GPIO22 (Pin22) -- OLED SCL
 | #define OLED_SCL 22             // ESP32 GPIO22 (Pin22) -- OLED SCL
 | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -5,8 +5,8 @@ | |||||||
| #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | ||||||
| 
 | 
 | ||||||
| #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
 | #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
 | ||||||
| #define HAS_LED NOT_A_PIN // Led os on same pin than Lora SS pin, to avoid pb, we don't use it
 | #define HAS_LED       22  // ESP32 GPIO12 (pin22) On Board LED
 | ||||||
|                           // Anyway shield is on over the LoLin32 board, so we won't be able to see this LED
 | #define LED_ACTIVE_LOW 1  // Onboard LED is active when pin is LOW
 | ||||||
| #define HAS_RGB_LED   13  // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
 | #define HAS_RGB_LED   13  // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
 | ||||||
| #define HAS_BUTTON    15  // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
 | #define HAS_BUTTON    15  // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
 | ||||||
| #define BUTTON_PULLUP  1  // Button need pullup instead of default pulldown
 | #define BUTTON_PULLUP  1  // Button need pullup instead of default pulldown
 | ||||||
| @ -30,4 +30,3 @@ | |||||||
| #define OLED_RST U8X8_PIN_NONE  // Not reset pin
 | #define OLED_RST U8X8_PIN_NONE  // Not reset pin
 | ||||||
| #define OLED_SDA 14             // ESP32 GPIO14 (Pin14) -- OLED SDA
 | #define OLED_SDA 14             // ESP32 GPIO14 (Pin14) -- OLED SDA
 | ||||||
| #define OLED_SCL 12             // ESP32 GPIO12 (Pin12) -- OLED SCL
 | #define OLED_SCL 12             // ESP32 GPIO12 (Pin12) -- OLED SCL
 | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
| 
 | 
 | ||||||
| #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
 | #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
 | ||||||
| #define HAS_LED GPIO_NUM_2 // white LED on board
 | #define HAS_LED GPIO_NUM_2 // white LED on board
 | ||||||
|  | #define LED_ACTIVE_LOW 1  // Onboard LED is active when pin is LOW
 | ||||||
| #define HAS_BUTTON GPIO_NUM_0 // button "PRG" on board
 | #define HAS_BUTTON GPIO_NUM_0 // button "PRG" on board
 | ||||||
| 
 | 
 | ||||||
| // re-define pin definitions of pins_arduino.h
 | // re-define pin definitions of pins_arduino.h
 | ||||||
| @ -21,4 +22,4 @@ | |||||||
| // Hardware pin definitions for TTGOv1 Board with OLED SSD1306 I2C Display
 | // Hardware pin definitions for TTGOv1 Board with OLED SSD1306 I2C Display
 | ||||||
| #define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset
 | #define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset
 | ||||||
| #define OLED_SDA 4  // ESP32 GPIO4 (Pin4)   -- SD1306 Data
 | #define OLED_SDA 4  // ESP32 GPIO4 (Pin4)   -- SD1306 Data
 | ||||||
| #define OLED_SCL 15 // ESP32 GPIO15 (Pin15) -- SD1306 Clock
 | #define OLED_SCL 15 // ESP32 GPIO15 (Pin15) -- SD1306 Clock
 | ||||||
|  | |||||||
| @ -79,10 +79,22 @@ void printKeys(void) { | |||||||
| #endif // VERBOSE
 | #endif // VERBOSE
 | ||||||
| 
 | 
 | ||||||
| void do_send(osjob_t* j){ | void do_send(osjob_t* j){ | ||||||
|     mydata[0] = (macnum & 0xff00) >> 8; |     uint16_t data; | ||||||
|     mydata[1] = macnum  & 0x00ff; |     // Total BLE+WIFI unique MACs seen
 | ||||||
|     mydata[2] = (blenum & 0xff00) >> 8; |     data = (uint16_t) macs.size(); | ||||||
|     mydata[3] = blenum  & 0x00ff; |     mydata[0] = (data & 0xff00) >> 8; | ||||||
|  |     mydata[1] = data  & 0xff; | ||||||
|  |      | ||||||
|  |     // Sum of unique BLE MACs seen
 | ||||||
|  |     data = (uint16_t) bles.size(); | ||||||
|  |     mydata[2] = (data & 0xff00) >> 8; | ||||||
|  |     mydata[3] = data  & 0xff; | ||||||
|  | 
 | ||||||
|  |     // Sum of unique WIFI MACs seen
 | ||||||
|  |     // TBD ?
 | ||||||
|  |     //data = (uint16_t) wifis.size();
 | ||||||
|  |     //mydata[4] = (data & 0xff00) >> 8;
 | ||||||
|  |     //mydata[5] = data  & 0xff;
 | ||||||
| 
 | 
 | ||||||
|     // Check if there is not a current TX/RX job running
 |     // Check if there is not a current TX/RX job running
 | ||||||
|     if (LMIC.opmode & OP_TXRXPEND) { |     if (LMIC.opmode & OP_TXRXPEND) { | ||||||
| @ -95,7 +107,6 @@ void do_send(osjob_t* j){ | |||||||
|         ESP_LOGI(TAG, "Packet queued"); |         ESP_LOGI(TAG, "Packet queued"); | ||||||
|         u8x8.clearLine(7); |         u8x8.clearLine(7); | ||||||
|         u8x8.drawString(0, 7, "PACKET QUEUED"); |         u8x8.drawString(0, 7, "PACKET QUEUED"); | ||||||
|         set_onboard_led(1); |  | ||||||
|     } |     } | ||||||
|     // Next TX is scheduled after TX_COMPLETE event.
 |     // Next TX is scheduled after TX_COMPLETE event.
 | ||||||
| } | } | ||||||
| @ -162,7 +173,6 @@ void onEvent (ev_t ev) { | |||||||
|             ESP_LOGI(TAG, "EV_TXCOMPLETE (includes waiting for RX windows)"); |             ESP_LOGI(TAG, "EV_TXCOMPLETE (includes waiting for RX windows)"); | ||||||
|             u8x8.clearLine(7); |             u8x8.clearLine(7); | ||||||
|             u8x8.drawString(0, 7, "TX COMPLETE"); |             u8x8.drawString(0, 7, "TX COMPLETE"); | ||||||
|             set_onboard_led(0); |  | ||||||
|             if (LMIC.txrxFlags & TXRX_ACK) { |             if (LMIC.txrxFlags & TXRX_ACK) { | ||||||
|               ESP_LOGI(TAG, "Received ack"); |               ESP_LOGI(TAG, "Received ack"); | ||||||
|               u8x8.clearLine(7); |               u8x8.clearLine(7); | ||||||
| @ -176,7 +186,7 @@ void onEvent (ev_t ev) { | |||||||
|                 u8x8.clearLine(7); |                 u8x8.clearLine(7); | ||||||
|                 u8x8.setCursor(0, 7); |                 u8x8.setCursor(0, 7); | ||||||
|                 // LMIC.snr = SNR twos compliment [dB] * 4
 |                 // LMIC.snr = SNR twos compliment [dB] * 4
 | ||||||
|                 // LMIC.rssi = RSSI [dBm] (-196...+63)              
 |                 // LMIC.rssi = RSSI [dBm] (-196...+63)
 | ||||||
|                 u8x8.printf("RSSI %d SNR %d", LMIC.rssi, (signed char)LMIC.snr / 4); |                 u8x8.printf("RSSI %d SNR %d", LMIC.rssi, (signed char)LMIC.snr / 4); | ||||||
|                 // check if payload received on command port, then call remote command interpreter
 |                 // check if payload received on command port, then call remote command interpreter
 | ||||||
|                 if ( (LMIC.txrxFlags & TXRX_PORT) && (LMIC.frame[LMIC.dataBeg-1] == RCMDPORT ) ) { |                 if ( (LMIC.txrxFlags & TXRX_PORT) && (LMIC.frame[LMIC.dataBeg-1] == RCMDPORT ) ) { | ||||||
| @ -223,4 +233,5 @@ void onEvent (ev_t ev) { | |||||||
|             u8x8.printf("UNKNOWN EVENT %d", ev); |             u8x8.printf("UNKNOWN EVENT %d", ev); | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										141
									
								
								src/macsniff.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/macsniff.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,141 @@ | |||||||
|  | 
 | ||||||
|  | // Basic Config
 | ||||||
|  | #include "main.h" | ||||||
|  | #include "globals.h" | ||||||
|  | 
 | ||||||
|  | #ifdef BLECOUNTER | ||||||
|  |     #include <BLEDevice.h> | ||||||
|  |     #include <BLEUtils.h> | ||||||
|  |     #include <BLEScan.h> | ||||||
|  |     #include <BLEAdvertisedDevice.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef VENDORFILTER | ||||||
|  |     #include <array> | ||||||
|  |     #include <algorithm> | ||||||
|  |     #include "vendor_array.h" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | // Local logging tag
 | ||||||
|  | static const char *TAG = "macsniff"; | ||||||
|  | 
 | ||||||
|  | static wifi_country_t wifi_country = {.cc=WIFI_MY_COUNTRY, .schan=WIFI_CHANNEL_MIN, .nchan=WIFI_CHANNEL_MAX, .policy=WIFI_COUNTRY_POLICY_MANUAL}; | ||||||
|  | 
 | ||||||
|  | uint16_t currentScanDevice = 0; | ||||||
|  | 
 | ||||||
|  | bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { | ||||||
|  | 
 | ||||||
|  |     char counter [6]; // uint16_t -> 2 byte -> 5 decimals + '0' terminator -> 6 chars
 | ||||||
|  |     char macbuf [21]; // uint64_t -> 8 byte -> 20 decimals + '0' terminator -> 21 chars
 | ||||||
|  |     char typebuff[8]; | ||||||
|  |     uint64_t addr2int; | ||||||
|  | 	uint32_t vendor2int; | ||||||
|  | 	uint16_t hashedmac; | ||||||
|  | 	std::pair<std::set<uint16_t>::iterator, bool> newmac; | ||||||
|  | 
 | ||||||
|  |     addr2int = ( (uint64_t)paddr[0] ) | ( (uint64_t)paddr[1] << 8 ) | ( (uint64_t)paddr[2] << 16 ) | \ | ||||||
|  |     ( (uint64_t)paddr[3] << 24 ) | ( (uint64_t)paddr[4] << 32 ) | ( (uint64_t)paddr[5] << 40 ); | ||||||
|  | 
 | ||||||
|  |     #ifdef VENDORFILTER | ||||||
|  |         vendor2int = ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[1] << 8 ) | ( (uint32_t)paddr[0] << 16 ); | ||||||
|  |         // No vendor filter for BLE
 | ||||||
|  |         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
 | ||||||
|  | 		// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
 | ||||||
|  | 			 | ||||||
|  | 		addr2int |= (uint64_t) salt << 48;		// prepend 16-bit salt to 48-bit MAC
 | ||||||
|  | 		snprintf(macbuf, 21, "%llx", addr2int);	// convert unsigned 64-bit salted MAC to 16 digit hex string
 | ||||||
|  | 		hashedmac = rokkit(macbuf, 5);			// hash MAC string, use 5 chars to fit hash in uint16_t container
 | ||||||
|  | 		newmac = macs.insert(hashedmac);		// add hashed MAC to total container if new unique
 | ||||||
|  | 
 | ||||||
|  |         if (sniff_type == MAC_SNIFF_WIFI ) { | ||||||
|  |             newmac = wifis.insert(hashedmac);   // add hashed MAC to wifi container if new unique
 | ||||||
|  |             strcpy(typebuff, "WiFi"); | ||||||
|  |         } else if (sniff_type == MAC_SNIFF_BLE ) { | ||||||
|  |             newmac = bles.insert(hashedmac);    // add hashed MAC to BLE container if new unique
 | ||||||
|  |             strcpy(typebuff, "BLE "); | ||||||
|  |         } | ||||||
|  |       | ||||||
|  |         if (newmac.second) { // first time seen this WIFI or BLE MAC
 | ||||||
|  |             snprintf(counter, 6, "%i", macs.size());		// convert 16-bit MAC counter to decimal counter value
 | ||||||
|  |             u8x8.draw2x2String(0, 0, counter); | ||||||
|  |             ESP_LOGI(TAG, "%s RSSI %04d -> Hash %04x -> #%05i", typebuff, rssi, hashedmac, macs.size()); | ||||||
|  |         } else { // already seen WIFI or BLE MAC
 | ||||||
|  |             ESP_LOGI(TAG, "%s RSSI %04d -> already seen", typebuff, rssi); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     #ifdef VENDORFILTER | ||||||
|  |     } else { | ||||||
|  |         // Very noisy
 | ||||||
|  |         //ESP_LOGI(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 newmac.second; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef BLECOUNTER | ||||||
|  | 
 | ||||||
|  | class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { | ||||||
|  |     void onResult(BLEAdvertisedDevice advertisedDevice) { | ||||||
|  |         uint8_t *p = (uint8_t *) advertisedDevice.getAddress().getNative(); | ||||||
|  | 
 | ||||||
|  |         // Current devices seen on this scan session
 | ||||||
|  |         currentScanDevice++; | ||||||
|  |         mac_add(p, advertisedDevice.getRSSI(), MAC_SNIFF_BLE); | ||||||
|  |         u8x8.setCursor(12,3); | ||||||
|  |         u8x8.printf("%d", currentScanDevice); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void BLECount() { | ||||||
|  |     int blenum = 0; // Total device seen on this scan session
 | ||||||
|  |     currentScanDevice = 0; // Set 0 seen device on this scan session
 | ||||||
|  |     u8x8.clearLine(3); | ||||||
|  |     u8x8.drawString(0,3,"BLE Scan..."); | ||||||
|  |     BLEDevice::init(PROGNAME); | ||||||
|  |     BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
 | ||||||
|  |     pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); | ||||||
|  |     pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
 | ||||||
|  |     BLEScanResults foundDevices = pBLEScan->start(cfg.blescancycle); | ||||||
|  |     blenum=foundDevices.getCount(); | ||||||
|  |     u8x8.clearLine(3); | ||||||
|  |     u8x8.setCursor(0,3); | ||||||
|  |     u8x8.printf("BLE#: %-5i %-3i",bles.size(), blenum); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 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
 | ||||||
|  |     	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_mode(WIFI_MODE_NULL)); | ||||||
|  |     	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
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void wifi_sniffer_set_channel(uint8_t channel) { | ||||||
|  |     esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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_mac_hdr_t *hdr = &ipkt->hdr; | ||||||
|  |      | ||||||
|  |     if (( cfg.rssilimit == 0 ) || (ppkt->rx_ctrl.rssi > cfg.rssilimit )) { // rssi is negative value
 | ||||||
|  |         uint8_t *p = (uint8_t *) hdr->addr2; | ||||||
|  |         mac_add(p, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI) ; | ||||||
|  |     } else { | ||||||
|  |         ESP_LOGI(TAG, "WiFi RSSI %04d -> ignoring (limit: %i)", ppkt->rx_ctrl.rssi, cfg.rssilimit); | ||||||
|  |     } | ||||||
|  |     yield(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										28
									
								
								src/macsniff.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/macsniff.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | // ESP32 Functions
 | ||||||
|  | #include <esp_wifi.h> | ||||||
|  | 
 | ||||||
|  | #define MAC_SNIFF_WIFI 0 | ||||||
|  | #define MAC_SNIFF_BLE  1 | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     unsigned frame_ctrl:16; | ||||||
|  |     unsigned duration_id:16; | ||||||
|  |     uint8_t addr1[6]; /* receiver address */ | ||||||
|  |     uint8_t addr2[6]; /* sender address */ | ||||||
|  |     uint8_t addr3[6]; /* filtering address */ | ||||||
|  |     unsigned sequence_ctrl:16; | ||||||
|  |     uint8_t addr4[6]; /* optional */ | ||||||
|  | } wifi_ieee80211_mac_hdr_t; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     wifi_ieee80211_mac_hdr_t hdr; | ||||||
|  |     uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */ | ||||||
|  | } wifi_ieee80211_packet_t; | ||||||
|  | 
 | ||||||
|  | void BLECount(); | ||||||
|  | void wifi_sniffer_init(void); | ||||||
|  | void wifi_sniffer_set_channel(uint8_t channel); | ||||||
|  | void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); | ||||||
|  | 
 | ||||||
|  | // function defined in rokkithash.cpp
 | ||||||
|  | uint32_t rokkit(const char * , int ); | ||||||
							
								
								
									
										155
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								src/main.cpp
									
									
									
									
									
								
							| @ -25,6 +25,9 @@ Refer to LICENSE.txt file in repository for more details. | |||||||
| #include "main.h" | #include "main.h" | ||||||
| #include "globals.h" | #include "globals.h" | ||||||
| 
 | 
 | ||||||
|  | // std::set for unified array functions
 | ||||||
|  | #include <set> | ||||||
|  | 
 | ||||||
| // OLED driver
 | // OLED driver
 | ||||||
| #include <U8x8lib.h> | #include <U8x8lib.h> | ||||||
| 
 | 
 | ||||||
| @ -42,11 +45,17 @@ configData_t cfg; // struct holds current device configuration | |||||||
| osjob_t sendjob, initjob; // LMIC
 | osjob_t sendjob, initjob; // LMIC
 | ||||||
| 
 | 
 | ||||||
| // Initialize global variables
 | // Initialize global variables
 | ||||||
| uint16_t macnum = 0, blenum = 0, salt; | int macnum = 0, salt; | ||||||
| uint64_t uptimecounter = 0; | uint64_t uptimecounter = 0; | ||||||
| bool joinstate = false; | bool joinstate = false; | ||||||
| 
 | 
 | ||||||
| std::set<uint16_t> macs; // associative container holds filtered MAC adresses
 | std::set<uint16_t> macs; // associative container holds total of unique MAC adress hashes (Wifi + BLE)
 | ||||||
|  | std::set<uint16_t> wifis; // associative container holds unique Wifi MAC adress hashes
 | ||||||
|  | 
 | ||||||
|  | #ifdef BLECOUNTER | ||||||
|  |     std::set<uint16_t> bles; // associative container holds unique BLE MAC adresses hashes
 | ||||||
|  |     int scanTime; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| // this variable will be changed in the ISR, and read in main loop
 | // this variable will be changed in the ISR, and read in main loop
 | ||||||
| static volatile bool ButtonTriggered = false; | static volatile bool ButtonTriggered = false; | ||||||
| @ -67,29 +76,19 @@ void eraseConfig(void); | |||||||
| void saveConfig(void); | void saveConfig(void); | ||||||
| void loadConfig(void); | void loadConfig(void); | ||||||
| 
 | 
 | ||||||
| /* begin LMIC specific parts ------------------------------------------------------------ */ | #ifdef HAS_LED | ||||||
|  |     void set_onboard_led(int st); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| // LMIC enhanced Pin mapping 
 | /* begin LMIC specific parts ------------------------------------------------------------ */ | ||||||
| const lmic_pinmap lmic_pins = { |  | ||||||
|     .mosi = PIN_SPI_MOSI, |  | ||||||
|     .miso = PIN_SPI_MISO, |  | ||||||
|     .sck = PIN_SPI_SCK, |  | ||||||
|     .nss = PIN_SPI_SS, |  | ||||||
|     .rxtx = LMIC_UNUSED_PIN, |  | ||||||
|     .rst = RST, |  | ||||||
|     .dio = {DIO0, DIO1, DIO2} |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| // defined in lorawan.cpp
 | // defined in lorawan.cpp
 | ||||||
| void gen_lora_deveui(uint8_t * pdeveui); | void gen_lora_deveui(uint8_t * pdeveui); | ||||||
| void RevBytes(unsigned char* b, size_t c); | void RevBytes(unsigned char* b, size_t c); | ||||||
|  | 
 | ||||||
| #ifdef VERBOSE | #ifdef VERBOSE | ||||||
|     void printKeys(void); |     void printKeys(void); | ||||||
| #endif | #endif // VERBOSE
 | ||||||
| 
 |  | ||||||
| // LMIC functions
 |  | ||||||
| void onEvent(ev_t ev); |  | ||||||
| void do_send(osjob_t* j); |  | ||||||
| 
 | 
 | ||||||
| // LMIC callback functions
 | // LMIC callback functions
 | ||||||
| void os_getDevKey (u1_t *buf) {  | void os_getDevKey (u1_t *buf) {  | ||||||
| @ -112,6 +111,21 @@ void os_getDevEui (u1_t* buf) { | |||||||
|         gen_lora_deveui(buf); // generate DEVEUI from device's MAC
 |         gen_lora_deveui(buf); // generate DEVEUI from device's MAC
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // LMIC enhanced Pin mapping
 | ||||||
|  | const lmic_pinmap lmic_pins = { | ||||||
|  |     .mosi = PIN_SPI_MOSI, | ||||||
|  |     .miso = PIN_SPI_MISO, | ||||||
|  |     .sck = PIN_SPI_SCK, | ||||||
|  |     .nss = PIN_SPI_SS, | ||||||
|  |     .rxtx = LMIC_UNUSED_PIN, | ||||||
|  |     .rst = RST, | ||||||
|  |     .dio = {DIO0, DIO1, DIO2} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // LMIC functions
 | ||||||
|  | void onEvent(ev_t ev); | ||||||
|  | void do_send(osjob_t* j); | ||||||
|  | 
 | ||||||
| // LoRaWAN Initjob
 | // LoRaWAN Initjob
 | ||||||
| static void lora_init (osjob_t* j) { | static void lora_init (osjob_t* j) { | ||||||
|     // reset MAC state
 |     // reset MAC state
 | ||||||
| @ -125,8 +139,48 @@ static void lora_init (osjob_t* j) { | |||||||
| // LMIC Task
 | // LMIC Task
 | ||||||
| void lorawan_loop(void * pvParameters) { | void lorawan_loop(void * pvParameters) { | ||||||
|     configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
 |     configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
 | ||||||
|  | 
 | ||||||
|  |     static bool led_state ; | ||||||
|  |     bool new_led_state ; | ||||||
|  | 
 | ||||||
|     while(1) { |     while(1) { | ||||||
|  |         uint16_t color; | ||||||
|         os_runloop_once(); |         os_runloop_once(); | ||||||
|  | 
 | ||||||
|  |         // All follow is Led management
 | ||||||
|  |         // Let join at the begining of if sequence,
 | ||||||
|  |         // is prior to send because joining state send data
 | ||||||
|  |         if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) )  { | ||||||
|  |             color = COLOR_YELLOW; | ||||||
|  |             // Joining Quick blink 20ms on each 1/5 second
 | ||||||
|  |             new_led_state = ((millis() % 200) < 20) ? HIGH : LOW; | ||||||
|  |              | ||||||
|  |         // Small blink 10ms on each 1/2sec (not when joining)
 | ||||||
|  |         } else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) { | ||||||
|  |             color = COLOR_BLUE; | ||||||
|  |             new_led_state = ((millis() % 500) < 20) ? HIGH : LOW; | ||||||
|  |          | ||||||
|  |         // This should not happen so indicate a pb
 | ||||||
|  |         } else  if ( LMIC.opmode & (OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) { | ||||||
|  |             color = COLOR_RED; | ||||||
|  |             // Heartbeat long blink 200ms on each 2 seconds
 | ||||||
|  |             new_led_state = ((millis() % 2000) < 200) ? HIGH : LOW; | ||||||
|  |         } else { | ||||||
|  |           rgb_set_color(COLOR_NONE); | ||||||
|  |         } | ||||||
|  |         // led  need to change state ?
 | ||||||
|  |         // avoid digitalWrite() for nothing
 | ||||||
|  |         if (led_state != new_led_state) { | ||||||
|  |             if (new_led_state == HIGH) { | ||||||
|  |                 set_onboard_led(1); | ||||||
|  |                 rgb_set_color(color); | ||||||
|  |             } else { | ||||||
|  |                 set_onboard_led(0); | ||||||
|  |                 rgb_set_color(COLOR_NONE); | ||||||
|  |             } | ||||||
|  |             led_state = new_led_state; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         vTaskDelay(10/portTICK_PERIOD_MS); |         vTaskDelay(10/portTICK_PERIOD_MS); | ||||||
|         yield(); |         yield(); | ||||||
|     }     |     }     | ||||||
| @ -159,12 +213,18 @@ void lorawan_loop(void * pvParameters) { | |||||||
| void set_onboard_led(int st){ | void set_onboard_led(int st){ | ||||||
| #ifdef HAS_LED | #ifdef HAS_LED | ||||||
|     switch (st) { |     switch (st) { | ||||||
|         case 1: digitalWrite(HAS_LED, HIGH); break; |         #ifdef LED_ACTIVE_LOW | ||||||
|         case 0: digitalWrite(HAS_LED, LOW); break; |           case 1: digitalWrite(HAS_LED, LOW); break; | ||||||
|  |           case 0: digitalWrite(HAS_LED, HIGH); break; | ||||||
|  |         #else | ||||||
|  |           case 1: digitalWrite(HAS_LED, HIGH); break; | ||||||
|  |           case 0: digitalWrite(HAS_LED, LOW); break; | ||||||
|  |         #endif | ||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #ifdef HAS_BUTTON | #ifdef HAS_BUTTON | ||||||
|     // Button Handling, board dependent -> perhaps to be moved to hal/<$board.h>
 |     // Button Handling, board dependent -> perhaps to be moved to hal/<$board.h>
 | ||||||
|     // IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855
 |     // IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855
 | ||||||
| @ -190,35 +250,49 @@ void wifi_sniffer_loop(void * pvParameters) { | |||||||
|     int nloop=0, lorawait=0; |     int nloop=0, lorawait=0; | ||||||
|      |      | ||||||
|   	while (true) { |   	while (true) { | ||||||
|         nloop++; |         nloop++; // acutal number of wifi loops
 | ||||||
| 		vTaskDelay(cfg.wifichancycle*10 / portTICK_PERIOD_MS); | 
 | ||||||
|  |         // execute BLE count if BLE function is enabled
 | ||||||
|  |         #ifdef BLECOUNTER | ||||||
|  |         // Once 2 full Wifi Channels scan, do a BLE scan
 | ||||||
|  |         if (nloop % (WIFI_CHANNEL_MAX*2) == 0 ) { | ||||||
|  |             // execute BLE count if BLE function is enabled
 | ||||||
|  |             if (cfg.blescan) | ||||||
|  |                 BLECount(); | ||||||
|  |         } | ||||||
|  |         #endif | ||||||
|  | 
 | ||||||
|  |         vTaskDelay(cfg.wifichancycle*10 / portTICK_PERIOD_MS); | ||||||
|         yield(); |         yield(); | ||||||
| 		wifi_sniffer_set_channel(channel); |         wifi_sniffer_set_channel(channel); | ||||||
| 		channel = (channel % WIFI_CHANNEL_MAX) + 1; |         channel = (channel % WIFI_CHANNEL_MAX) + 1; | ||||||
|  |         ESP_LOGI(TAG, "Wifi set channel %d", channel); | ||||||
|  |          | ||||||
|  |         u8x8.setCursor(0,5); | ||||||
|  |         u8x8.printf(!cfg.rssilimit ? "RLIM:  off" : "RLIM: %4i", cfg.rssilimit); | ||||||
|  |         u8x8.setCursor(11,5); | ||||||
|  |         u8x8.printf("ch:%02i", channel); | ||||||
|  |         u8x8.setCursor(0,4); | ||||||
|  |         u8x8.printf("MAC#: %-5i", wifis.size()); | ||||||
|          |          | ||||||
|         // duration of one wifi scan loop reached? then send data and begin new scan cycle
 |         // duration of one wifi scan loop reached? then send data and begin new scan cycle
 | ||||||
|         if( nloop >= ((100 / cfg.wifichancycle) * (cfg.wifiscancycle * 2)) ) { |         if( nloop >= ((100 / cfg.wifichancycle) * (cfg.wifiscancycle * 2)) ) { | ||||||
|             u8x8.setPowerSave(!cfg.screenon); // set display on if enabled
 |             u8x8.setPowerSave(!cfg.screenon); // set display on if enabled
 | ||||||
|             nloop = 0; // reset wlan sniffing loop counter
 |             nloop = 0; // reset wlan sniffing loop counter
 | ||||||
|              |              | ||||||
|             // execute BLE count if BLE function is enabled
 |  | ||||||
|             #ifdef BLECOUNTER |  | ||||||
|                 if (cfg.blescan) |  | ||||||
|                     BLECount(); |  | ||||||
|             #endif |  | ||||||
|              |  | ||||||
|             // Prepare and execute LoRaWAN data upload
 |             // Prepare and execute LoRaWAN data upload
 | ||||||
|             u8x8.setCursor(0,4); |  | ||||||
|             u8x8.printf("MAC#: %-5i", macnum); |  | ||||||
|             do_send(&sendjob); // send payload
 |             do_send(&sendjob); // send payload
 | ||||||
|             vTaskDelay(500/portTICK_PERIOD_MS); |             vTaskDelay(500/portTICK_PERIOD_MS); | ||||||
|             yield(); |             yield(); | ||||||
| 
 | 
 | ||||||
|             // clear counter if not in cumulative counter mode
 |             // clear counter if not in cumulative counter mode
 | ||||||
|             if (cfg.countermode != 1) { |             if (cfg.countermode != 1) { | ||||||
|                 macs.clear(); // clear macs container
 |                 macs.clear(); // clear all macs container
 | ||||||
|  |                 wifis.clear(); // clear Wifi macs couner
 | ||||||
|  |                 #ifdef BLECOUNTER | ||||||
|  |                   bles.clear(); // clear BLE macs counter
 | ||||||
|  |                 #endif  | ||||||
|                 salt = random(65536); // get new 16bit random for salting hashes
 |                 salt = random(65536); // get new 16bit random for salting hashes
 | ||||||
|                 macnum = 0; |  | ||||||
|                 u8x8.clearLine(0); u8x8.clearLine(1); // clear Display counter
 |                 u8x8.clearLine(0); u8x8.clearLine(1); // clear Display counter
 | ||||||
|             }       |             }       | ||||||
| 
 | 
 | ||||||
| @ -237,8 +311,10 @@ void wifi_sniffer_loop(void * pvParameters) { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             u8x8.clearLine(6); |             u8x8.clearLine(6); | ||||||
| 	                     | 
 | ||||||
|             if (cfg.screenon && cfg.screensaver) vTaskDelay(2000/portTICK_PERIOD_MS); // pause for displaying results
 |             if (cfg.screenon && cfg.screensaver) { | ||||||
|  |               vTaskDelay(2000/portTICK_PERIOD_MS); // pause for displaying results
 | ||||||
|  |             } | ||||||
|             yield(); |             yield(); | ||||||
|             u8x8.setPowerSave(1 && cfg.screensaver); // set display off if screensaver is enabled
 |             u8x8.setPowerSave(1 && cfg.screensaver); // set display off if screensaver is enabled
 | ||||||
|         } |         } | ||||||
| @ -336,7 +412,8 @@ void setup() { | |||||||
| #endif | #endif | ||||||
|      |      | ||||||
|     ESP_LOGI(TAG, "Starting %s %s", PROGNAME, PROGVERSION); |     ESP_LOGI(TAG, "Starting %s %s", PROGNAME, PROGVERSION); | ||||||
| 
 |     rgb_set_color(COLOR_NONE); | ||||||
|  |                  | ||||||
|     // system event handler for wifi task, needed for wifi_sniffer_init()
 |     // system event handler for wifi task, needed for wifi_sniffer_init()
 | ||||||
|     esp_event_loop_init(NULL, NULL); |     esp_event_loop_init(NULL, NULL); | ||||||
| 
 | 
 | ||||||
| @ -355,7 +432,7 @@ void setup() { | |||||||
| 
 | 
 | ||||||
|     // Read settings from NVRAM
 |     // Read settings from NVRAM
 | ||||||
|     loadConfig(); // includes initialize if necessary
 |     loadConfig(); // includes initialize if necessary
 | ||||||
|        | 
 | ||||||
|     // initialize hardware
 |     // initialize hardware
 | ||||||
| #ifdef HAS_LED | #ifdef HAS_LED | ||||||
|     // initialize LED
 |     // initialize LED
 | ||||||
| @ -380,7 +457,7 @@ void setup() { | |||||||
|     antenna_init(); |     antenna_init(); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     // initialize salt value using esp_random() called by random in arduino-esp32 core
 |     // initialize salt value using esp_random() called by random() in arduino-esp32 core
 | ||||||
|     salt = random(65536); // get new 16bit random for salting hashes
 |     salt = random(65536); // get new 16bit random for salting hashes
 | ||||||
| 
 | 
 | ||||||
|     // initialize display
 |     // initialize display
 | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								src/main.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/main.h
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | |||||||
| // program version
 | // program version
 | ||||||
| #define PROGVERSION                     "1.2.62" // use max 10 chars here!
 | #define PROGVERSION                     "1.2.8" // use max 10 chars here!
 | ||||||
| #define PROGNAME                        "PAXCNT" | #define PROGNAME                        "PAXCNT" | ||||||
| 
 | 
 | ||||||
| // Verbose enables serial output
 | // Verbose enables serial output
 | ||||||
| @ -10,22 +10,26 @@ | |||||||
| #define BLECOUNTER                      1 // comment out if you don't want BLE count
 | #define BLECOUNTER                      1 // comment out if you don't want BLE count
 | ||||||
| 
 | 
 | ||||||
| // BLE scan time
 | // BLE scan time
 | ||||||
| #define BLESCANTIME                     30 // [seconds]
 | #define BLESCANTIME                     15 // [seconds]
 | ||||||
| 
 | 
 | ||||||
| // WiFi Sniffer cycle interval
 | // WiFi Sniffer cycle interval
 | ||||||
| #define SEND_SECS                       120 // [seconds/2] -> 240 sec.
 | #define SEND_SECS                       120 // [seconds/2] -> 240 sec.
 | ||||||
|  | //#define SEND_SECS                       30 // [seconds/2] -> 60 sec.
 | ||||||
| 
 | 
 | ||||||
| // WiFi sniffer config
 | // WiFi sniffer config
 | ||||||
| #define WIFI_CHANNEL_MIN                1   // start channel number where scan begings
 | #define WIFI_CHANNEL_MIN                1   // start channel number where scan begings
 | ||||||
| #define	WIFI_CHANNEL_MAX                13  // total channel number to scan
 | #define	WIFI_CHANNEL_MAX                13  // total channel number to scan
 | ||||||
| #define WIFI_MY_COUNTRY                 "EU"  // for Wifi RF settings
 | #define WIFI_MY_COUNTRY                 "EU"  // for Wifi RF settings
 | ||||||
| #define	WIFI_CHANNEL_SWITCH_INTERVAL    50  // [seconds/100] -> 0,5 sec.     
 | #define	WIFI_CHANNEL_SWITCH_INTERVAL    50  // [seconds/100] -> 0,5 sec.
 | ||||||
| 
 | 
 | ||||||
| // Default LoRa Spreadfactor
 | // Default LoRa Spreadfactor
 | ||||||
| #define LORASFDEFAULT                   9 // 7 ... 12
 | #define LORASFDEFAULT                   9 // 7 ... 12
 | ||||||
| #define MAXLORARETRY                    500 // maximum count of TX retries if LoRa busy
 | #define MAXLORARETRY                    500 // maximum count of TX retries if LoRa busy
 | ||||||
| #define RCMDPORT                        2 // LoRaWAN Port on which device listenes for remote commands
 | #define RCMDPORT                        2 // LoRaWAN Port on which device listenes for remote commands
 | ||||||
| 
 | 
 | ||||||
|  | // Default RGB LED luminosity (in %)
 | ||||||
|  | #define RGBLUMINOSITY                   50 // 50%
 | ||||||
|  | 
 | ||||||
| // LMIC settings
 | // LMIC settings
 | ||||||
| // define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored
 | // define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored
 | ||||||
| // define hardware specifics settings in platformio.ini as build_flag for hardware environment
 | // define hardware specifics settings in platformio.ini as build_flag for hardware environment
 | ||||||
| @ -99,10 +103,10 @@ | |||||||
| // implementation is optimized for speed on 32-bit processors using
 | // implementation is optimized for speed on 32-bit processors using
 | ||||||
| // fairly big lookup tables, but it takes up big amounts of flash on the
 | // fairly big lookup tables, but it takes up big amounts of flash on the
 | ||||||
| // AVR architecture.
 | // AVR architecture.
 | ||||||
| // #define USE_ORIGINAL_AES
 | #define USE_ORIGINAL_AES | ||||||
| //
 | //
 | ||||||
| // This selects the AES implementation written by Ideetroon for their
 | // This selects the AES implementation written by Ideetroon for their
 | ||||||
| // own LoRaWAN library. It also uses lookup tables, but smaller
 | // own LoRaWAN library. It also uses lookup tables, but smaller
 | ||||||
| // byte-oriented ones, making it use a lot less flash space (but it is
 | // byte-oriented ones, making it use a lot less flash space (but it is
 | ||||||
| // also about twice as slow as the original).
 | // also about twice as slow as the original).
 | ||||||
| #define USE_IDEETRON_AES | // #define USE_IDEETRON_AES
 | ||||||
|  | |||||||
| @ -67,8 +67,9 @@ void set_reset(int val) { | |||||||
|             break; |             break; | ||||||
|         case 1: // reset MAC counter
 |         case 1: // reset MAC counter
 | ||||||
|             ESP_LOGI(TAG, "Remote command: reset MAC counter"); |             ESP_LOGI(TAG, "Remote command: reset MAC counter"); | ||||||
|             macs.clear(); // clear macs container
 |             macs.clear(); // clear all macs container
 | ||||||
|             macnum = 0; |             wifis.clear(); // clear Wifi macs container
 | ||||||
|  |             bles.clear(); // clear BLE macs container
 | ||||||
|             salt = random(65536); // get new 16bit random for salting hashes
 |             salt = random(65536); // get new 16bit random for salting hashes
 | ||||||
|             u8x8.clearLine(0); u8x8.clearLine(1); // clear Display counter
 |             u8x8.clearLine(0); u8x8.clearLine(1); // clear Display counter
 | ||||||
|             u8x8.clearLine(5); |             u8x8.clearLine(5); | ||||||
| @ -140,7 +141,7 @@ void set_display(int val) { | |||||||
|         case 1: cfg.screenon = val; break; |         case 1: cfg.screenon = val; break; | ||||||
|         default: cfg.screenon = 0; break; |         default: cfg.screenon = 0; break; | ||||||
|         } |         } | ||||||
|     u8x8.setPowerSave(!cfg.screenon); // set display 0=on / 1=off                          
 |     u8x8.setPowerSave(!cfg.screenon); // set display 0=on / 1=off
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void set_lorasf(int val) { | void set_lorasf(int val) { | ||||||
| @ -161,8 +162,8 @@ void set_blescan(int val) { | |||||||
|     ESP_LOGI(TAG, "Remote command: set BLE scan mode to %s", val ? "on" : "off"); |     ESP_LOGI(TAG, "Remote command: set BLE scan mode to %s", val ? "on" : "off"); | ||||||
|     switch (val) { |     switch (val) { | ||||||
|         case 1: cfg.blescan = val; break; |         case 1: cfg.blescan = val; break; | ||||||
|         default:  |         default: | ||||||
|             cfg.blescan = 0;  |             cfg.blescan = 0; | ||||||
|             btStop(); |             btStop(); | ||||||
|             u8x8.clearLine(3); // clear BLE results from display
 |             u8x8.clearLine(3); // clear BLE results from display
 | ||||||
|             break; |             break; | ||||||
| @ -180,6 +181,12 @@ void set_wifiant(int val) { | |||||||
|     #endif |     #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | void set_rgblum(int val) { | ||||||
|  |     // Avoid wrong parameters
 | ||||||
|  |     cfg.rgblum = (val>=0 && val<=100) ? (uint8_t) val : RGBLUMINOSITY; | ||||||
|  |     ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| void set_lorapower(int val) { | void set_lorapower(int val) { | ||||||
|     ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %i", val); |     ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %i", val); | ||||||
|     switch_lora(cfg.lorasf, val); |     switch_lora(cfg.lorasf, val); | ||||||
| @ -240,13 +247,14 @@ cmd_t table[] = { | |||||||
|                 {0x0c, set_blescancycle, true}, |                 {0x0c, set_blescancycle, true}, | ||||||
|                 {0x0d, set_blescan, true}, |                 {0x0d, set_blescan, true}, | ||||||
|                 {0x0e, set_wifiant, true}, |                 {0x0e, set_wifiant, true}, | ||||||
|  |                 {0x0f, set_rgblum, true}, | ||||||
|                 {0x80, get_config, false}, |                 {0x80, get_config, false}, | ||||||
|                 {0x81, get_uptime, false}, |                 {0x81, get_uptime, false}, | ||||||
|                 {0x82, get_cputemp, false} |                 {0x82, get_cputemp, false} | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
| // check and execute remote command
 | // check and execute remote command
 | ||||||
| void rcommand(int cmd, int arg) {          | void rcommand(int cmd, int 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; |     bool store_flag = false; | ||||||
|     while(i--) {  |     while(i--) {  | ||||||
|  | |||||||
							
								
								
									
										87
									
								
								src/rgb_led.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/rgb_led.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | // Basic Config
 | ||||||
|  | #include "main.h" | ||||||
|  | #include "globals.h" | ||||||
|  | 
 | ||||||
|  | #ifdef HAS_RGB_LED | ||||||
|  | 
 | ||||||
|  | // RGB Led instance
 | ||||||
|  | SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED); | ||||||
|  | 
 | ||||||
|  | // Luminosity from 0 to 100%
 | ||||||
|  | uint8_t rgb_luminosity = 50 ; | ||||||
|  | 
 | ||||||
|  | float rgb_CalcColor(float p, float q, float t) | ||||||
|  | { | ||||||
|  |     if (t < 0.0f) | ||||||
|  |         t += 1.0f; | ||||||
|  |     if (t > 1.0f) | ||||||
|  |         t -= 1.0f; | ||||||
|  | 
 | ||||||
|  |     if (t < 1.0f / 6.0f) | ||||||
|  |         return p + (q - p) * 6.0f * t; | ||||||
|  | 
 | ||||||
|  |     if (t < 0.5f) | ||||||
|  |         return q; | ||||||
|  | 
 | ||||||
|  |     if (t < 2.0f / 3.0f) | ||||||
|  |         return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f); | ||||||
|  | 
 | ||||||
|  |     return p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ------------------------------------------------------------------------
 | ||||||
|  | // Hue, Saturation, Lightness color members
 | ||||||
|  | // 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_color; | ||||||
|  |     float r; | ||||||
|  |     float g; | ||||||
|  |     float b; | ||||||
|  | 
 | ||||||
|  |     if (s == 0.0f || l == 0.0f) | ||||||
|  |     { | ||||||
|  |         r = g = b = l; // achromatic or black
 | ||||||
|  |     } | ||||||
|  |     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); | ||||||
|  |         g = rgb_CalcColor(p, q, h); | ||||||
|  |         b = rgb_CalcColor(p, q, h - 1.0f / 3.0f); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     RGB_color.R = (uint8_t)(r * 255.0f); | ||||||
|  |     RGB_color.G = (uint8_t)(g * 255.0f); | ||||||
|  |     RGB_color.B = (uint8_t)(b * 255.0f); | ||||||
|  | 
 | ||||||
|  |     return RGB_color; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void rgb_set_color(uint16_t hue) { | ||||||
|  |   if (hue == COLOR_NONE) { | ||||||
|  |     // Off
 | ||||||
|  |     rgb_led[0] = Rgb(0,0,0); | ||||||
|  |   } else { | ||||||
|  |     // see http://www.workwithcolor.com/blue-color-hue-range-01.htm
 | ||||||
|  |     // H (is color from 0..360) should be between 0.0 and 1.0
 | ||||||
|  |     // S is saturation keep it to 1
 | ||||||
|  |     // L is brightness should be between 0.0 and 0.5
 | ||||||
|  |     // rgb_luminosity is between 0 and 100 (percent)
 | ||||||
|  |     RGBColor target = rgb_hsl2rgb( hue / 360.0f, 1.0f, 0.005f * cfg.rgblum); | ||||||
|  |     //uint32_t color = target.R<<16 | target.G<<8 | target.B;
 | ||||||
|  |     rgb_led[0] = Rgb(target.R, target.G, target.B); | ||||||
|  |   } | ||||||
|  |   // Show
 | ||||||
|  |   rgb_led.show(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  | 
 | ||||||
|  | // No RGB LED empty functions
 | ||||||
|  | void rgb_set_color(uint16_t hue) {} | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										30
									
								
								src/rgb_led.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/rgb_led.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | // value for HSL color
 | ||||||
|  | // see http://www.workwithcolor.com/blue-color-hue-range-01.htm
 | ||||||
|  | #define COLOR_RED              0 | ||||||
|  | #define COLOR_ORANGE          30 | ||||||
|  | #define COLOR_ORANGE_YELLOW   45 | ||||||
|  | #define COLOR_YELLOW          60 | ||||||
|  | #define COLOR_YELLOW_GREEN    90 | ||||||
|  | #define COLOR_GREEN          120 | ||||||
|  | #define COLOR_GREEN_CYAN     165 | ||||||
|  | #define COLOR_CYAN           180 | ||||||
|  | #define COLOR_CYAN_BLUE      210 | ||||||
|  | #define COLOR_BLUE           240 | ||||||
|  | #define COLOR_BLUE_MAGENTA   275 | ||||||
|  | #define COLOR_MAGENTA        300 | ||||||
|  | #define COLOR_PINK           350 | ||||||
|  | #define COLOR_WHITE          360 | ||||||
|  | #define COLOR_NONE           999 | ||||||
|  | 
 | ||||||
|  | struct RGBColor | ||||||
|  | { | ||||||
|  |     uint8_t R; | ||||||
|  |     uint8_t G; | ||||||
|  |     uint8_t B; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Exported Functions
 | ||||||
|  | void rgb_set_color(uint16_t hue); | ||||||
							
								
								
									
										2870
									
								
								src/vendor_array.h
									
									
									
									
									
								
							
							
						
						
									
										2870
									
								
								src/vendor_array.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,98 +0,0 @@ | |||||||
| // Basic Config
 |  | ||||||
| #include "main.h" |  | ||||||
| #include "globals.h" |  | ||||||
| 
 |  | ||||||
| // ESP32 Functions
 |  | ||||||
| #include <esp_wifi.h> |  | ||||||
| 
 |  | ||||||
| #ifdef VENDORFILTER |  | ||||||
| 	#include <array> |  | ||||||
| 	#include <algorithm> |  | ||||||
| 	#include "vendor_array.h" |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| // Local logging tag
 |  | ||||||
| static const char *TAG = "wifisniffer"; |  | ||||||
| 
 |  | ||||||
| // function defined in rokkithash.cpp
 |  | ||||||
| uint32_t rokkit(const char * , int ); |  | ||||||
| 
 |  | ||||||
| static wifi_country_t wifi_country = {.cc=WIFI_MY_COUNTRY, .schan=WIFI_CHANNEL_MIN, .nchan=WIFI_CHANNEL_MAX, .policy=WIFI_COUNTRY_POLICY_MANUAL}; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
| 	unsigned frame_ctrl:16; |  | ||||||
| 	unsigned duration_id:16; |  | ||||||
| 	uint8_t addr1[6]; /* receiver address */ |  | ||||||
| 	uint8_t addr2[6]; /* sender address */ |  | ||||||
| 	uint8_t addr3[6]; /* filtering address */ |  | ||||||
| 	unsigned sequence_ctrl:16; |  | ||||||
| 	uint8_t addr4[6]; /* optional */ |  | ||||||
| } wifi_ieee80211_mac_hdr_t; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
| 	wifi_ieee80211_mac_hdr_t hdr; |  | ||||||
| 	uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */ |  | ||||||
| } wifi_ieee80211_packet_t; |  | ||||||
| 
 |  | ||||||
| extern void wifi_sniffer_init(void); |  | ||||||
| extern void wifi_sniffer_set_channel(uint8_t channel); |  | ||||||
| extern void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); |  | ||||||
| 
 |  | ||||||
| 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
 |  | ||||||
|     	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_mode(WIFI_MODE_NULL)); |  | ||||||
|     	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
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void wifi_sniffer_set_channel(uint8_t channel) { |  | ||||||
| 	esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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_mac_hdr_t *hdr = &ipkt->hdr; |  | ||||||
| 	char counter [6]; // uint16_t -> 2 byte -> 5 decimals + '0' terminator -> 6 chars
 |  | ||||||
| 	char macbuf [21]; // uint64_t -> 8 byte -> 10 decimals + '0' terminator -> 21 chars
 |  | ||||||
| 	uint64_t addr2int; |  | ||||||
| 	uint32_t vendor2int; |  | ||||||
| 	uint16_t hashedmac; |  | ||||||
| 	std::pair<std::set<uint16_t>::iterator, bool> newmac; |  | ||||||
| 
 |  | ||||||
| 	if (( cfg.rssilimit == 0 ) || (ppkt->rx_ctrl.rssi > cfg.rssilimit )) { // rssi is negative value
 |  | ||||||
| 	    addr2int = ( (uint64_t)hdr->addr2[0] ) | ( (uint64_t)hdr->addr2[1] << 8 ) | ( (uint64_t)hdr->addr2[2] << 16 ) | \ |  | ||||||
| 			( (uint64_t)hdr->addr2[3] << 24 ) | ( (uint64_t)hdr->addr2[4] << 32 ) | ( (uint64_t)hdr->addr2[5] << 40 ); |  | ||||||
| 
 |  | ||||||
| #ifdef VENDORFILTER // uses vendor array with prefiltered OUIs (no local nd no group MACs, bits 0+1 in 1st byte of OUI)
 |  | ||||||
| 		vendor2int = ( (uint32_t)hdr->addr2[2] ) | ( (uint32_t)hdr->addr2[1] << 8 ) | ( (uint32_t)hdr->addr2[0] << 16 ); |  | ||||||
| 		if ( 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
 |  | ||||||
| 			// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
 |  | ||||||
| 			 |  | ||||||
| 			addr2int |= (uint64_t) salt << 48;		// prepend 16-bit salt to 48-bit MAC
 |  | ||||||
| 			snprintf(macbuf, 21, "%llx", addr2int);	// convert unsigned 64-bit salted MAC to 16 digit hex string
 |  | ||||||
| 			hashedmac = rokkit(macbuf, 5);			// hash MAC string, use 5 chars to fit hash in uint16_t container
 |  | ||||||
| 			newmac = macs.insert(hashedmac);		// store hashed MAC only if first time seen
 |  | ||||||
| 			if (newmac.second) {					// if first time seen MAC
 |  | ||||||
| 				macnum++;								// increment MAC counter
 |  | ||||||
| 				snprintf(counter, 6, "%i", macnum);		// convert 16-bit MAC counter to decimal counter value
 |  | ||||||
| 				u8x8.draw2x2String(0, 0, counter);		// display counter
 |  | ||||||
| 				ESP_LOGI(TAG, "#%05i: RSSI %04d -> Hash %04x", macnum, ppkt->rx_ctrl.rssi, hashedmac); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| #ifdef VENDORFILTER |  | ||||||
| 		} |  | ||||||
| #endif |  | ||||||
| 	} else |  | ||||||
| 		ESP_LOGI(TAG, "RSSI %04d -> ignoring (limit: %i)", ppkt->rx_ctrl.rssi, cfg.rssilimit); |  | ||||||
| 
 |  | ||||||
| 	yield(); |  | ||||||
| } |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user