Merge branch 'master' of https://github.com/cyberman54/ESP32-Paxcounter
This commit is contained in:
commit
f164e5279b
22
README.md
22
README.md
@ -48,11 +48,13 @@ Hardware dependent settings (pinout etc.) are stored in board files in /hal dire
|
|||||||
|
|
||||||
These results where metered with software version 1.2.97 while continuously scanning wifi and ble, no LoRa TX’ing, OLED display (if present) on, 5V USB powered.
|
These results where metered with software version 1.2.97 while continuously scanning wifi and ble, no LoRa TX’ing, OLED display (if present) on, 5V USB powered.
|
||||||
|
|
||||||
# Building
|
# Preparing
|
||||||
|
|
||||||
Use <A HREF="https://platformio.org/">PlatformIO</A> with your preferred IDE for development and building this code.
|
Before compiling the code,
|
||||||
|
|
||||||
Before compiling the code, **create file loraconf.h in your local /src directory** using the template [loraconf.sample.h](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/loraconf.sample.h) and populate it with your personal APPEUI und APPKEY for the LoRaWAN network. If you're using popular <A HREF="https://thethingsnetwork.org">TheThingsNetwork</A> you can copy&paste the keys from TTN console or output of ttnctl.
|
- **edit paxcounter.conf** and taylor settings in this file according to your needs and use case. Please take care of the duty cycle regulations of the LoRaWAN network you're going to use.
|
||||||
|
|
||||||
|
- **create file loraconf.h in your local /src directory** using the template [loraconf.sample.h](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/loraconf.sample.h) and populate it with your personal APPEUI und APPKEY for the LoRaWAN network. If you're using popular <A HREF="https://thethingsnetwork.org">TheThingsNetwork</A> you can copy&paste the keys from TTN console or output of ttnctl.
|
||||||
|
|
||||||
To join the network only method OTAA is supported, not ABP. The DEVEUI for OTAA will be derived from the device's MAC adress during device startup and is shown as well on the device's display (if it has one) as on the serial console for copying it to your LoRaWAN network server settings.
|
To join the network only method OTAA is supported, not ABP. The DEVEUI for OTAA will be derived from the device's MAC adress during device startup and is shown as well on the device's display (if it has one) as on the serial console for copying it to your LoRaWAN network server settings.
|
||||||
|
|
||||||
@ -60,6 +62,10 @@ If your device has a fixed DEVEUI enter this in your local loraconf.h file. Duri
|
|||||||
|
|
||||||
If your device has silicon **Unique ID** which is stored in serial EEPROM Microchip 24AA02E64 you don't need to change anything. The Unique ID will be read during startup and DEVEUI will be generated from it, overriding settings in loraconf.h.
|
If your device has silicon **Unique ID** which is stored in serial EEPROM Microchip 24AA02E64 you don't need to change anything. The Unique ID will be read during startup and DEVEUI will be generated from it, overriding settings in loraconf.h.
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
Use <A HREF="https://platformio.org/">PlatformIO</A> with your preferred IDE for development and building this code.
|
||||||
|
|
||||||
# Uploading
|
# Uploading
|
||||||
|
|
||||||
To upload the code to your ESP32 board this needs to be switched from run to bootloader mode. Boards with USB bridge like Heltec and TTGO usually have an onboard logic which allows soft switching by the upload tool. In PlatformIO this happenes automatically.<p>
|
To upload the code to your ESP32 board this needs to be switched from run to bootloader mode. Boards with USB bridge like Heltec and TTGO usually have an onboard logic which allows soft switching by the upload tool. In PlatformIO this happenes automatically.<p>
|
||||||
@ -150,10 +156,10 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
|||||||
1 = reset MAC counter to zero
|
1 = reset MAC counter to zero
|
||||||
2 = reset device to factory settings
|
2 = reset device to factory settings
|
||||||
|
|
||||||
0x0A set Wifi scan cycle and payload transmit cycle
|
0x0A set payload send cycle
|
||||||
|
|
||||||
0 ... 255 duration of a wifi scan cycle in seconds/2, after this payload is sent
|
0 ... 255 payload send cycle in seconds/2
|
||||||
e.g. 120 -> 1 cycle runs for 240 seconds [default]
|
e.g. 120 -> payload is transmitted each 240 seconds [default]
|
||||||
|
|
||||||
0x0B set Wifi channel switch interval timer
|
0x0B set Wifi channel switch interval timer
|
||||||
|
|
||||||
@ -187,7 +193,7 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
|||||||
|
|
||||||
0x80 get device configuration
|
0x80 get device configuration
|
||||||
|
|
||||||
device answers with it's current configuration. The configuration is a C structure declared in file [globals.h](src/globals.h#L24-L41) with the following definition:
|
device answers with it's current configuration. The configuration is a C structure declared in file [globals.h](src/globals.h#L27-L44) with the following definition:
|
||||||
|
|
||||||
byte 1: Lora SF (7..12)
|
byte 1: Lora SF (7..12)
|
||||||
byte 2: Lora TXpower (2..15)
|
byte 2: Lora TXpower (2..15)
|
||||||
@ -196,7 +202,7 @@ device answers with it's current configuration. The configuration is a C structu
|
|||||||
byte 5: Display status (1=on, 0=off)
|
byte 5: Display status (1=on, 0=off)
|
||||||
byte 6: Counter mode (0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed)
|
byte 6: Counter mode (0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed)
|
||||||
bytes 7-8: RSSI limiter threshold value (negative)
|
bytes 7-8: RSSI limiter threshold value (negative)
|
||||||
byte 9: Wifi scan cycle duration in seconds/2 (0..255)
|
byte 9: Payload send cycle in seconds/2 (0..255)
|
||||||
byte 10: Wifi channel switch interval in seconds/100 (0..255)
|
byte 10: Wifi channel switch interval in seconds/100 (0..255)
|
||||||
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)
|
||||||
|
@ -31,14 +31,14 @@ build_flags =
|
|||||||
; ---> NOTE: For production run set DEBUG_LEVEL level to NONE! <---
|
; ---> NOTE: For production run set DEBUG_LEVEL level to NONE! <---
|
||||||
; otherwise device may crash in dense environments due to serial buffer overflow
|
; otherwise device may crash in dense environments due to serial buffer overflow
|
||||||
;
|
;
|
||||||
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
|
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
|
||||||
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
|
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
|
||||||
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||||
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||||
;
|
;
|
||||||
; override lora settings from LMiC library in lmic/config.h and use main.h instead
|
; override lora settings from LMiC library in lmic/config.h and use main.h instead
|
||||||
-D_lmic_config_h_
|
-D_lmic_config_h_
|
||||||
-include "src/main.h"
|
-include "src/paxcounter.conf"
|
||||||
|
|
||||||
[env:heltec_wifi_lora_32]
|
[env:heltec_wifi_lora_32]
|
||||||
platform = espressif32
|
platform = espressif32
|
||||||
|
@ -21,7 +21,7 @@ void antenna_init(void) {
|
|||||||
gpio_config(&gpioconf);
|
gpio_config(&gpioconf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void antenna_select (const int8_t _ant) {
|
void antenna_select (const uint8_t _ant) {
|
||||||
if (HAS_ANTENNA_SWITCH < 32) {
|
if (HAS_ANTENNA_SWITCH < 32) {
|
||||||
if (_ant == ANTENNA_EXT) {
|
if (_ant == ANTENNA_EXT) {
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_REG, 1 << HAS_ANTENNA_SWITCH);
|
GPIO_REG_WRITE(GPIO_OUT_W1TS_REG, 1 << HAS_ANTENNA_SWITCH);
|
||||||
|
@ -100,7 +100,7 @@ static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_pa
|
|||||||
{
|
{
|
||||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
||||||
{ // restart scan
|
{ // restart scan
|
||||||
status = esp_ble_gap_start_scanning(BLESCANTIME);
|
status = esp_ble_gap_start_scanning(cfg.blescantime);
|
||||||
if (status != ESP_OK)
|
if (status != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
|
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
|
||||||
@ -112,7 +112,7 @@ static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_pa
|
|||||||
{
|
{
|
||||||
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
|
{ // restart scan
|
||||||
status = esp_ble_gap_start_scanning (BLESCANTIME);
|
status = esp_ble_gap_start_scanning (cfg.blescantime);
|
||||||
if (status != ESP_OK)
|
if (status != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
|
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
|
||||||
@ -233,13 +233,17 @@ esp_err_t register_ble_functionality(void)
|
|||||||
|
|
||||||
|
|
||||||
// Main start code running in its own Xtask
|
// Main start code running in its own Xtask
|
||||||
void bt_loop(void *ignore)
|
void bt_loop(void * pvParameters)
|
||||||
{
|
{
|
||||||
|
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
||||||
|
|
||||||
esp_err_t status;
|
esp_err_t status;
|
||||||
|
|
||||||
// Initialize BT controller to allocate task and other resource.
|
// Initialize BT controller to allocate task and other resource.
|
||||||
ESP_LOGI(TAG, "Enabling Bluetooth Controller");
|
ESP_LOGI(TAG, "Enabling Bluetooth Controller");
|
||||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||||
|
bt_cfg.controller_task_stack_size = 8192; // double BT stack size
|
||||||
|
|
||||||
if (esp_bt_controller_init(&bt_cfg) != ESP_OK)
|
if (esp_bt_controller_init(&bt_cfg) != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "Bluetooth controller initialize failed");
|
ESP_LOGE(TAG, "Bluetooth controller initialize failed");
|
||||||
@ -253,6 +257,8 @@ void bt_loop(void *ignore)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//esp_bt_controller_mem_release(ESP_BT_MODE_BTDM); // gives 30KB more RAM for heap
|
||||||
|
|
||||||
// Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff
|
// Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff
|
||||||
ESP_LOGI(TAG, "Init Bluetooth stack");
|
ESP_LOGI(TAG, "Init Bluetooth stack");
|
||||||
status = esp_bluedroid_init();
|
status = esp_bluedroid_init();
|
||||||
@ -280,8 +286,7 @@ void bt_loop(void *ignore)
|
|||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
vTaskDelay(500/portTICK_PERIOD_MS);
|
vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
|
||||||
yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -13,19 +13,19 @@ esp_err_t err;
|
|||||||
|
|
||||||
// defined in antenna.cpp
|
// defined in antenna.cpp
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
void antenna_select(const int8_t _ant);
|
void antenna_select(const uint8_t _ant);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// populate cfg vars with factory settings
|
// populate cfg vars with factory settings
|
||||||
void defaultConfig() {
|
void defaultConfig() {
|
||||||
cfg.lorasf = LORASFDEFAULT; // 7-12, initial lora spreadfactor defined in main.h
|
cfg.lorasf = LORASFDEFAULT; // 7-12, initial lora spreadfactor defined in paxcounter.conf
|
||||||
cfg.txpower = 15; // 2-15, lora tx power
|
cfg.txpower = 15; // 2-15, lora tx power
|
||||||
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
||||||
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
||||||
cfg.screenon = 1; // 0=disbaled, 1=enabled
|
cfg.screenon = 1; // 0=disbaled, 1=enabled
|
||||||
cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
||||||
cfg.rssilimit = 0; // threshold for rssilimiter, negative value!
|
cfg.rssilimit = 0; // threshold for rssilimiter, negative value!
|
||||||
cfg.wifiscancycle = SEND_SECS; // wifi scan cycle [seconds/2]
|
cfg.sendcycle = SEND_SECS; // payload send 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.blescantime = BLESCANTIME; // BLE scan cycle duration [seconds]
|
cfg.blescantime = BLESCANTIME; // BLE scan cycle duration [seconds]
|
||||||
cfg.blescan = 1; // 0=disabled, 1=enabled
|
cfg.blescan = 1; // 0=disabled, 1=enabled
|
||||||
@ -99,8 +99,8 @@ void saveConfig() {
|
|||||||
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);
|
nvs_set_i8(my_handle, "countermode", cfg.countermode);
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "wifiscancycle", &flash8) != ESP_OK || flash8 != cfg.wifiscancycle )
|
if( nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK || flash8 != cfg.sendcycle )
|
||||||
nvs_set_i8(my_handle, "wifiscancycle", cfg.wifiscancycle);
|
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);
|
nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle);
|
||||||
@ -174,113 +174,113 @@ void loadConfig() {
|
|||||||
// overwrite defaults with valid values from NVRAM
|
// overwrite defaults with valid values from NVRAM
|
||||||
if( nvs_get_i8(my_handle, "lorasf", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "lorasf", &flash8) == ESP_OK ) {
|
||||||
cfg.lorasf = flash8;
|
cfg.lorasf = flash8;
|
||||||
ESP_LOGI(TAG, "lorasf = %i", flash8);
|
ESP_LOGI(TAG, "lorasf = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "lorasf set to default %i", cfg.lorasf);
|
ESP_LOGI(TAG, "lorasf set to default %d", cfg.lorasf);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "txpower", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "txpower", &flash8) == ESP_OK ) {
|
||||||
cfg.txpower = flash8;
|
cfg.txpower = flash8;
|
||||||
ESP_LOGI(TAG, "txpower = %i", flash8);
|
ESP_LOGI(TAG, "txpower = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "txpower set to default %i", cfg.txpower);
|
ESP_LOGI(TAG, "txpower set to default %d", cfg.txpower);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "adrmode", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "adrmode", &flash8) == ESP_OK ) {
|
||||||
cfg.adrmode = flash8;
|
cfg.adrmode = flash8;
|
||||||
ESP_LOGI(TAG, "adrmode = %i", flash8);
|
ESP_LOGI(TAG, "adrmode = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "adrmode set to default %i", cfg.adrmode);
|
ESP_LOGI(TAG, "adrmode set to default %d", cfg.adrmode);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "screensaver", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "screensaver", &flash8) == ESP_OK ) {
|
||||||
cfg.screensaver = flash8;
|
cfg.screensaver = flash8;
|
||||||
ESP_LOGI(TAG, "screensaver = %i", flash8);
|
ESP_LOGI(TAG, "screensaver = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "screensaver set to default %i", cfg.screensaver);
|
ESP_LOGI(TAG, "screensaver set to default %d", cfg.screensaver);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "screenon", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "screenon", &flash8) == ESP_OK ) {
|
||||||
cfg.screenon = flash8;
|
cfg.screenon = flash8;
|
||||||
ESP_LOGI(TAG, "screenon = %i", flash8);
|
ESP_LOGI(TAG, "screenon = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "screenon set to default %i", cfg.screenon);
|
ESP_LOGI(TAG, "screenon set to default %d", cfg.screenon);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "countermode", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "countermode", &flash8) == ESP_OK ) {
|
||||||
cfg.countermode = flash8;
|
cfg.countermode = flash8;
|
||||||
ESP_LOGI(TAG, "countermode = %i", flash8);
|
ESP_LOGI(TAG, "countermode = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "countermode set to default %i", cfg.countermode);
|
ESP_LOGI(TAG, "countermode set to default %d", cfg.countermode);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "wifiscancycle", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "sendcycle", &flash8) == ESP_OK ) {
|
||||||
cfg.wifiscancycle = flash8;
|
cfg.sendcycle = flash8;
|
||||||
ESP_LOGI(TAG, "wifiscancycle = %i", flash8);
|
ESP_LOGI(TAG, "sendcycle = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "WIFI scan cycle set to default %i", cfg.wifiscancycle);
|
ESP_LOGI(TAG, "Payload send cycle set to default %d", cfg.sendcycle);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "wifichancycle", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "wifichancycle", &flash8) == ESP_OK ) {
|
||||||
cfg.wifichancycle = flash8;
|
cfg.wifichancycle = flash8;
|
||||||
ESP_LOGI(TAG, "wifichancycle = %i", flash8);
|
ESP_LOGI(TAG, "wifichancycle = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "WIFI channel cycle set to default %i", cfg.wifichancycle);
|
ESP_LOGI(TAG, "WIFI channel cycle set to default %d", 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 = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "WIFI antenna switch set to default %i", cfg.wifiant);
|
ESP_LOGI(TAG, "WIFI antenna switch set to default %d", cfg.wifiant);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "vendorfilter", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "vendorfilter", &flash8) == ESP_OK ) {
|
||||||
cfg.vendorfilter = flash8;
|
cfg.vendorfilter = flash8;
|
||||||
ESP_LOGI(TAG, "vendorfilter = %i", flash8);
|
ESP_LOGI(TAG, "vendorfilter = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "Vendorfilter mode set to default %i", cfg.vendorfilter);
|
ESP_LOGI(TAG, "Vendorfilter mode set to default %d", cfg.vendorfilter);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK ) {
|
||||||
cfg.rgblum = flash8;
|
cfg.rgblum = flash8;
|
||||||
ESP_LOGI(TAG, "rgbluminosity = %i", flash8);
|
ESP_LOGI(TAG, "rgbluminosity = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "RGB luminosity set to default %i", cfg.rgblum);
|
ESP_LOGI(TAG, "RGB luminosity set to default %d", cfg.rgblum);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "blescantime", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "blescantime", &flash8) == ESP_OK ) {
|
||||||
cfg.blescantime = flash8;
|
cfg.blescantime = flash8;
|
||||||
ESP_LOGI(TAG, "blescantime = %i", flash8);
|
ESP_LOGI(TAG, "blescantime = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "BLEscantime set to default %i", cfg.blescantime);
|
ESP_LOGI(TAG, "BLEscantime set to default %d", cfg.blescantime);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "blescanmode", &flash8) == ESP_OK ) {
|
if( nvs_get_i8(my_handle, "blescanmode", &flash8) == ESP_OK ) {
|
||||||
cfg.blescan = flash8;
|
cfg.blescan = flash8;
|
||||||
ESP_LOGI(TAG, "BLEscanmode = %i", flash8);
|
ESP_LOGI(TAG, "BLEscanmode = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "BLEscanmode set to default %i", cfg.blescan);
|
ESP_LOGI(TAG, "BLEscanmode set to default %d", 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 = %d", flash16);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "rssilimit set to default %i", cfg.rssilimit);
|
ESP_LOGI(TAG, "rssilimit set to default %d", cfg.rssilimit);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
// OLED Display
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
// OLED Display
|
|
||||||
#include <U8x8lib.h>
|
#include <U8x8lib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -22,23 +22,24 @@
|
|||||||
|
|
||||||
#include "rgb_led.h"
|
#include "rgb_led.h"
|
||||||
#include "macsniff.h"
|
#include "macsniff.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
// Struct holding devices's runtime configuration
|
// Struct holding devices's runtime configuration
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t lorasf; // 7-12, lora spreadfactor
|
uint8_t lorasf; // 7-12, lora spreadfactor
|
||||||
int8_t txpower; // 2-15, lora tx power
|
uint8_t txpower; // 2-15, lora tx power
|
||||||
int8_t adrmode; // 0=disabled, 1=enabled
|
uint8_t adrmode; // 0=disabled, 1=enabled
|
||||||
int8_t screensaver; // 0=disabled, 1=enabled
|
uint8_t screensaver; // 0=disabled, 1=enabled
|
||||||
int8_t screenon; // 0=disabled, 1=enabled
|
uint8_t screenon; // 0=disabled, 1=enabled
|
||||||
int8_t countermode; // 0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed
|
uint8_t countermode; // 0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed
|
||||||
int16_t rssilimit; // threshold for rssilimiter, negative value!
|
int16_t rssilimit; // threshold for rssilimiter, negative value!
|
||||||
int8_t wifiscancycle; // wifi scan cycle [seconds/2]
|
uint8_t sendcycle; // payload send cycle [seconds/2]
|
||||||
int8_t wifichancycle; // wifi channel switch cycle [seconds/100]
|
uint8_t wifichancycle; // wifi channel switch cycle [seconds/100]
|
||||||
int8_t blescantime; // BLE scan cycle duration [seconds]
|
uint8_t blescantime; // BLE scan cycle duration [seconds]
|
||||||
int8_t blescan; // 0=disabled, 1=enabled
|
uint8_t blescan; // 0=disabled, 1=enabled
|
||||||
int8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
|
uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
|
||||||
int8_t vendorfilter; // 0=disabled, 1=enabled
|
uint8_t vendorfilter; // 0=disabled, 1=enabled
|
||||||
int8_t rgblum; // RGB Led luminosity (0..100%)
|
uint8_t rgblum; // RGB Led luminosity (0..100%)
|
||||||
char version[10]; // Firmware version
|
char version[10]; // Firmware version
|
||||||
} configData_t;
|
} configData_t;
|
||||||
|
|
||||||
@ -48,15 +49,11 @@ extern uint64_t uptimecounter;
|
|||||||
extern osjob_t sendjob;
|
extern osjob_t sendjob;
|
||||||
extern char display_lora[], display_lmic[];
|
extern char display_lora[], display_lmic[];
|
||||||
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;
|
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;
|
||||||
|
extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters
|
||||||
extern bool joinstate;
|
extern bool joinstate;
|
||||||
extern std::set<uint16_t> wifis;
|
|
||||||
extern std::set<uint16_t> macs;
|
extern std::set<uint16_t> macs;
|
||||||
|
extern hw_timer_t * channelSwitch; // hardware timer used for wifi channel switching
|
||||||
|
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
extern HAS_DISPLAY u8x8;
|
extern HAS_DISPLAY u8x8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BLECOUNTER
|
|
||||||
extern int scanTime;
|
|
||||||
extern std::set<uint16_t> bles;
|
|
||||||
#endif
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
||||||
#define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
#define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
||||||
#define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
#define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
||||||
#define DIO2 32 // ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO2 LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// Hardware pin definitions for Heltec LoRa-32 Board with OLED SSD1306 I2C Display
|
// Hardware pin definitions for Heltec LoRa-32 Board with OLED SSD1306 I2C Display
|
||||||
#define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 RST
|
#define OLED_RST 16 // ESP32 GPIO16 (Pin16) -- SD1306 RST
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
||||||
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
||||||
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
||||||
#define DIO2 4 // ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO2 LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
||||||
#define DIO5 35 // ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO5 LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
||||||
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
||||||
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
||||||
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
||||||
#define DIO2 4 // ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO2 LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
||||||
#define DIO5 35 // ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO5 LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
||||||
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#define RST 18
|
#define RST 18
|
||||||
#define DIO0 23 // LoRa IRQ
|
#define DIO0 23 // LoRa IRQ
|
||||||
#define DIO1 23 // workaround
|
#define DIO1 23 // workaround
|
||||||
#define DIO2 23 // workaround
|
#define DIO2 LMIC_UNUSED_PIN // 23 workaround
|
||||||
|
|
||||||
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
||||||
#define HAS_ANTENNA_SWITCH 16 // pin for switching wifi antenna
|
#define HAS_ANTENNA_SWITCH 16 // pin for switching wifi antenna
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#define RST LMIC_UNUSED_PIN
|
#define RST LMIC_UNUSED_PIN
|
||||||
#define DIO0 23 // LoRa IRQ
|
#define DIO0 23 // LoRa IRQ
|
||||||
#define DIO1 23 // workaround
|
#define DIO1 23 // workaround
|
||||||
#define DIO2 23 // workaround
|
#define DIO2 LMIC_UNUSED_PIN // 23 workaround
|
||||||
|
|
||||||
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
||||||
#define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna
|
#define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST 14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
||||||
#define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
#define DIO0 26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
||||||
#define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
#define DIO1 33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
||||||
#define DIO2 32 // ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO2 LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN
|
#define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN
|
||||||
#define DIO0 26 // ESP32 GPIO26 wired on PCB to HPD13A
|
#define DIO0 26 // ESP32 GPIO26 wired on PCB to HPD13A
|
||||||
#define DIO1 33 // HPDIO1 on pcb, needs to be wired external to GPIO33
|
#define DIO1 33 // HPDIO1 on pcb, needs to be wired external to GPIO33
|
||||||
#define DIO2 32 // HPDIO2 on pcb, needs to be wired external to GPIO32 (not necessary for LoRa, only FSK)
|
#define DIO2 LMIC_UNUSED_PIN // 32 HPDIO2 on pcb, needs to be wired external to GPIO32 (not necessary for LoRa, only FSK)
|
||||||
|
|
||||||
// Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C Display
|
// Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C Display
|
||||||
#define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN
|
#define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN
|
||||||
|
@ -13,12 +13,9 @@
|
|||||||
// Local logging Tag
|
// Local logging Tag
|
||||||
static const char *TAG = "lorawan";
|
static const char *TAG = "lorawan";
|
||||||
|
|
||||||
// function defined in main.cpp
|
|
||||||
void set_onboard_led(int state);
|
|
||||||
|
|
||||||
// functions defined in rcommand.cpp
|
// functions defined in rcommand.cpp
|
||||||
void rcommand(int cmd, int arg);
|
void rcommand(uint8_t cmd, uint8_t arg);
|
||||||
void switch_lora(int sf, int tx);
|
void switch_lora(uint8_t sf, uint8_t tx);
|
||||||
|
|
||||||
// DevEUI generator using devices's MAC address
|
// DevEUI generator using devices's MAC address
|
||||||
void gen_lora_deveui(uint8_t *pdeveui) {
|
void gen_lora_deveui(uint8_t *pdeveui) {
|
||||||
@ -112,28 +109,20 @@ void printKeys(void) {
|
|||||||
|
|
||||||
void do_send(osjob_t* j){
|
void do_send(osjob_t* j){
|
||||||
uint8_t mydata[4];
|
uint8_t mydata[4];
|
||||||
uint16_t data;
|
|
||||||
// Sum of unique WIFI MACs seen
|
// Sum of unique WIFI MACs seen
|
||||||
data = (uint16_t) wifis.size();
|
mydata[0] = (macs_wifi & 0xff00) >> 8;
|
||||||
mydata[0] = (data & 0xff00) >> 8;
|
mydata[1] = macs_wifi & 0xff;
|
||||||
mydata[1] = data & 0xff;
|
|
||||||
|
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
// Sum of unique BLE MACs seen
|
// Sum of unique BLE MACs seen
|
||||||
data = (uint16_t) bles.size();
|
mydata[2] = (macs_ble & 0xff00) >> 8;
|
||||||
mydata[2] = (data & 0xff00) >> 8;
|
mydata[3] = macs_ble & 0xff;
|
||||||
mydata[3] = data & 0xff;
|
|
||||||
#else
|
#else
|
||||||
mydata[2] = 0;
|
mydata[2] = 0;
|
||||||
mydata[3] = 0;
|
mydata[3] = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Total BLE+WIFI unique MACs seen
|
|
||||||
// TBD ?
|
|
||||||
//data = (uint16_t) macs.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) {
|
||||||
ESP_LOGI(TAG, "OP_TXRXPEND, not sending");
|
ESP_LOGI(TAG, "OP_TXRXPEND, not sending");
|
||||||
@ -143,9 +132,17 @@ void do_send(osjob_t* j){
|
|||||||
LMIC_setTxData2(1, mydata, sizeof(mydata), (cfg.countermode & 0x02));
|
LMIC_setTxData2(1, mydata, sizeof(mydata), (cfg.countermode & 0x02));
|
||||||
ESP_LOGI(TAG, "Packet queued");
|
ESP_LOGI(TAG, "Packet queued");
|
||||||
sprintf(display_lmic, "PACKET QUEUED");
|
sprintf(display_lmic, "PACKET QUEUED");
|
||||||
|
// clear counter if not in cumulative counter mode
|
||||||
|
if (cfg.countermode != 1) {
|
||||||
|
reset_counters(); // clear macs container and reset all counters
|
||||||
|
reset_salt(); // get new salt for salting hashes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Next TX is scheduled after TX_COMPLETE event.
|
|
||||||
}
|
// Schedule next transmission
|
||||||
|
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(cfg.sendcycle * 2), do_send);
|
||||||
|
|
||||||
|
} // do_send()
|
||||||
|
|
||||||
void onEvent (ev_t ev) {
|
void onEvent (ev_t ev) {
|
||||||
char buff[24]="";
|
char buff[24]="";
|
||||||
@ -166,8 +163,10 @@ void onEvent (ev_t ev) {
|
|||||||
case EV_REJOIN_FAILED: strcpy_P(buff, PSTR("REJOIN FAILED")); break;
|
case EV_REJOIN_FAILED: strcpy_P(buff, PSTR("REJOIN FAILED")); break;
|
||||||
|
|
||||||
case EV_JOINED:
|
case EV_JOINED:
|
||||||
|
|
||||||
|
joinstate=true;
|
||||||
strcpy_P(buff, PSTR("JOINED"));
|
strcpy_P(buff, PSTR("JOINED"));
|
||||||
sprintf(display_lora, " "); // erase "Join Wait" message from display
|
|
||||||
// Disable link check validation (automatically enabled
|
// Disable link check validation (automatically enabled
|
||||||
// during join, but not supported by TTN at this time).
|
// during join, but not supported by TTN at this time).
|
||||||
LMIC_setLinkCheckMode(0);
|
LMIC_setLinkCheckMode(0);
|
||||||
@ -175,26 +174,21 @@ void onEvent (ev_t ev) {
|
|||||||
LMIC_setAdrMode(cfg.adrmode);
|
LMIC_setAdrMode(cfg.adrmode);
|
||||||
// Set data rate and transmit power (note: txpower seems to be ignored by the library)
|
// Set data rate and transmit power (note: txpower seems to be ignored by the library)
|
||||||
switch_lora(cfg.lorasf,cfg.txpower);
|
switch_lora(cfg.lorasf,cfg.txpower);
|
||||||
joinstate=true;
|
|
||||||
// show effective LoRa parameters after join
|
// show effective LoRa parameters after join
|
||||||
ESP_LOGI(TAG, "ADR=%i, SF=%i, TXPOWER=%i", cfg.adrmode, cfg.lorasf, cfg.txpower);
|
ESP_LOGI(TAG, "ADR=%d, SF=%d, TXPOWER=%d", cfg.adrmode, cfg.lorasf, cfg.txpower);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_TXCOMPLETE:
|
case EV_TXCOMPLETE:
|
||||||
ESP_LOGI(TAG, "EV_TXCOMPLETE (includes waiting for RX windows)");
|
|
||||||
if (LMIC.txrxFlags & TXRX_ACK) {
|
|
||||||
ESP_LOGI(TAG, "Received ack");
|
|
||||||
sprintf(display_lmic, "RECEIVED ACK");
|
|
||||||
|
|
||||||
} else {
|
strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK") : PSTR("TX COMPLETE"));
|
||||||
sprintf(display_lmic, "TX COMPLETE");
|
sprintf(display_lora, ""); // erase previous LoRa message from display
|
||||||
}
|
|
||||||
if (LMIC.dataLen) {
|
if (LMIC.dataLen) {
|
||||||
ESP_LOGI(TAG, "Received %d bytes of payload", LMIC.dataLen);
|
ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d", LMIC.dataLen, LMIC.rssi, (signed char)LMIC.snr / 4);
|
||||||
sprintf(display_lora, "Rcvd %d bytes", LMIC.dataLen);
|
|
||||||
|
|
||||||
// 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)
|
||||||
sprintf(display_lmic, "RSSI %d SNR %d", LMIC.rssi, (signed char)LMIC.snr / 4 );
|
sprintf(display_lora, "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 ) ) {
|
||||||
@ -208,6 +202,7 @@ void onEvent (ev_t ev) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: sprintf_P(buff, PSTR("UNKNOWN EVENT %d"), ev); break;
|
default: sprintf_P(buff, PSTR("UNKNOWN EVENT %d"), ev); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,6 +212,5 @@ void onEvent (ev_t ev) {
|
|||||||
sprintf(display_lmic, buff);
|
sprintf(display_lmic, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // onEvent()
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -13,69 +13,66 @@ 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};
|
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 salt;
|
||||||
|
|
||||||
uint16_t salt_reset(void) {
|
uint16_t reset_salt(void) {
|
||||||
salt = random(65536); // get new 16bit random for salting hashes
|
salt = random(65536); // get new 16bit random for salting hashes and set global salt var
|
||||||
return salt;
|
return salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
||||||
|
|
||||||
char buff[16]; // temporary buffer for printf
|
char buff[16]; // temporary buffer for printf
|
||||||
bool added = false;
|
bool added = false;
|
||||||
uint32_t addr2int;
|
uint32_t addr2int, vendor2int; // temporary buffer for MAC and Vendor OUI
|
||||||
uint32_t vendor2int;
|
uint16_t hashedmac; // temporary buffer for generated hash value
|
||||||
uint16_t hashedmac;
|
|
||||||
|
|
||||||
// only last 3 MAC Address bytes are used for MAC Address Anonymization
|
// 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
|
// 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
|
#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
|
// 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
|
#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
|
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
|
||||||
|
|
||||||
addr2int += (uint32_t) salt; // add 16-bit salt to pseudo MAC
|
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
|
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
|
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
|
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
|
added = newmac.second ? true:false; // true if hashed MAC is unique in container
|
||||||
|
|
||||||
// Insert only if it was not found on global count
|
// Count only if MAC was not yet seen
|
||||||
if (added) {
|
if (added) {
|
||||||
|
// increment counter and one blink led
|
||||||
if (sniff_type == MAC_SNIFF_WIFI ) {
|
if (sniff_type == MAC_SNIFF_WIFI ) {
|
||||||
rgb_set_color(COLOR_GREEN);
|
macs_wifi++; // increment Wifi MACs counter
|
||||||
wifis.insert(hashedmac); // add hashed MAC to wifi container
|
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
|
||||||
}
|
blink_LED(COLOR_GREEN, 50);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
else if (sniff_type == MAC_SNIFF_BLE ) {
|
else if (sniff_type == MAC_SNIFF_BLE ) {
|
||||||
rgb_set_color(COLOR_MAGENTA);
|
macs_ble++; // increment BLE Macs counter
|
||||||
bles.insert(hashedmac); // add hashed MAC to BLE container
|
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
|
||||||
}
|
blink_LED(COLOR_MAGENTA, 50);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Not sure user will have time to see the LED
|
|
||||||
// TBD do light off further in the code
|
|
||||||
rgb_set_color(COLOR_NONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "%s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLTH:%d %s",
|
// Log scan result
|
||||||
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLTH",
|
ESP_LOGI(TAG, "%s %s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLTH:%d -> %d Bytes left",
|
||||||
rssi, buff, hashedmac,
|
added ? "new " : "known",
|
||||||
(int) wifis.size(),
|
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLTH",
|
||||||
#ifdef BLECOUNTER
|
rssi, buff, hashedmac, macs_wifi, macs_ble,
|
||||||
(int) bles.size(),
|
ESP.getFreeHeap());
|
||||||
#else
|
|
||||||
0,
|
|
||||||
#endif
|
|
||||||
added ? "new" : "known");
|
|
||||||
|
|
||||||
#ifdef VENDORFILTER
|
#ifdef VENDORFILTER
|
||||||
} else {
|
} else {
|
||||||
|
@ -19,7 +19,7 @@ typedef struct {
|
|||||||
uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
|
uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
|
||||||
} wifi_ieee80211_packet_t;
|
} wifi_ieee80211_packet_t;
|
||||||
|
|
||||||
uint16_t salt_reset(void);
|
uint16_t reset_salt(void);
|
||||||
void wifi_sniffer_init(void);
|
void wifi_sniffer_init(void);
|
||||||
void wifi_sniffer_set_channel(uint8_t channel);
|
void wifi_sniffer_set_channel(uint8_t channel);
|
||||||
void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
|
void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
|
||||||
|
616
src/main.cpp
616
src/main.cpp
@ -24,9 +24,6 @@ Refer to LICENSE.txt file in repository for more details.
|
|||||||
// Basic Config
|
// Basic Config
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
// std::set for unified array functions
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
// Does nothing and avoid any compilation error with I2C
|
// Does nothing and avoid any compilation error with I2C
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
|
||||||
@ -35,36 +32,41 @@ Refer to LICENSE.txt file in repository for more details.
|
|||||||
#include <lmic.h>
|
#include <lmic.h>
|
||||||
#include <hal/hal.h>
|
#include <hal/hal.h>
|
||||||
|
|
||||||
// ESP32 Functions
|
// ESP32 lib Functions
|
||||||
#include <esp_event_loop.h> // needed for Wifi event handler
|
#include <esp_event_loop.h> // needed for Wifi event handler
|
||||||
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
|
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
|
||||||
#include <esp32-hal-log.h> // needed for ESP_LOGx on arduino framework
|
#include <esp32-hal-log.h> // needed for ESP_LOGx on arduino framework
|
||||||
|
|
||||||
configData_t cfg; // struct holds current device configuration
|
|
||||||
osjob_t sendjob, initjob; // LMIC
|
|
||||||
|
|
||||||
// Initialize global variables
|
// Initialize global variables
|
||||||
char display_lora[16], display_lmic[16];
|
configData_t cfg; // struct holds current device configuration
|
||||||
uint8_t channel = 0;
|
osjob_t sendjob, initjob; // LMIC jobs
|
||||||
int macnum = 0;
|
uint64_t uptimecounter = 0; // timer global for uptime counter
|
||||||
uint64_t uptimecounter = 0;
|
uint8_t DisplayState = 0; // globals for state machine
|
||||||
bool joinstate = false;
|
uint16_t macs_total = 0, macs_wifi = 0, macs_ble = 0; // MAC counters globals for display
|
||||||
|
uint8_t channel = 0; // wifi channel rotation counter global for display
|
||||||
|
char display_lora[16], display_lmic[16]; // display buffers
|
||||||
|
led_states LEDState = LED_OFF; // LED state global for state machine
|
||||||
|
led_states previousLEDState = LED_ON; // This will force LED to be off at boot since State is OFF
|
||||||
|
unsigned long LEDBlinkStarted = 0; // When (in millis() led blink started)
|
||||||
|
uint16_t LEDBlinkDuration = 0; // How long the blink need to be
|
||||||
|
uint16_t LEDColor = COLOR_NONE; // state machine variable to set RGB LED color
|
||||||
|
bool joinstate = false; // LoRa network joined? global flag
|
||||||
|
bool blinkdone = true; // flag for state machine for blinking LED once
|
||||||
|
hw_timer_t * displaytimer = NULL; // configure hardware timer used for cyclic display refresh
|
||||||
|
hw_timer_t * channelSwitch = NULL; // configure hardware timer used for wifi channel switching
|
||||||
|
|
||||||
|
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying shared variable DisplayIRQ
|
||||||
|
|
||||||
std::set<uint16_t> macs; // associative container holds total of unique MAC adress hashes (Wifi + BLE)
|
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
|
// this variables will be changed in the ISR, and read in main loop
|
||||||
std::set<uint16_t> bles; // associative container holds unique BLE MAC adresses hashes
|
static volatile int ButtonPressed = 0, DisplayTimerIRQ = 0, ChannelTimerIRQ = 0;
|
||||||
int scanTime;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// this variable will be changed in the ISR, and read in main loop
|
|
||||||
static volatile bool ButtonTriggered = false;
|
|
||||||
|
|
||||||
// local Tag for logging
|
// local Tag for logging
|
||||||
static const char *TAG = "paxcnt";
|
static const char *TAG = "paxcnt";
|
||||||
// Note: Log level control seems not working during runtime,
|
// Note: Log level control seems not working during runtime,
|
||||||
// so we need to switch loglevel by compiler build option in platformio.ini
|
// so we need to switch loglevel by compiler build option in platformio.ini
|
||||||
|
|
||||||
#ifndef VERBOSE
|
#ifndef VERBOSE
|
||||||
int redirect_log(const char * fmt, va_list args) {
|
int redirect_log(const char * fmt, va_list args) {
|
||||||
//do nothing
|
//do nothing
|
||||||
@ -72,22 +74,15 @@ int redirect_log(const char * fmt, va_list args) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// defined in configmanager.cpp
|
void reset_counters() {
|
||||||
void eraseConfig(void);
|
macs.clear(); // clear all macs container
|
||||||
void saveConfig(void);
|
macs_total = 0; // reset all counters
|
||||||
void loadConfig(void);
|
macs_wifi = 0;
|
||||||
|
macs_ble = 0;
|
||||||
#ifdef HAS_LED
|
}
|
||||||
void set_onboard_led(int st);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* begin LMIC specific parts ------------------------------------------------------------ */
|
/* begin LMIC specific parts ------------------------------------------------------------ */
|
||||||
|
|
||||||
// defined in lorawan.cpp
|
|
||||||
void gen_lora_deveui(uint8_t * pdeveui);
|
|
||||||
void RevBytes(unsigned char* b, size_t c);
|
|
||||||
void get_hard_deveui(uint8_t *pdeveui);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
void printKeys(void);
|
void printKeys(void);
|
||||||
@ -133,10 +128,6 @@ const lmic_pinmap lmic_pins = {
|
|||||||
.dio = {DIO0, DIO1, DIO2}
|
.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
|
||||||
@ -149,52 +140,36 @@ static void lora_init (osjob_t* j) {
|
|||||||
|
|
||||||
// LMIC FreeRTos Task
|
// LMIC FreeRTos 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;
|
static uint16_t lorawait = 0;
|
||||||
bool new_led_state;
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
uint16_t color;
|
|
||||||
|
// execute LMIC jobs
|
||||||
os_runloop_once();
|
os_runloop_once();
|
||||||
|
|
||||||
// All follow is Led management
|
// indicate LMIC state on LEDs if present
|
||||||
// Let join at the begining of if sequence,
|
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
|
||||||
// is prior to send because joining state send data
|
led_loop();
|
||||||
if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) ) {
|
#endif
|
||||||
color = COLOR_YELLOW;
|
/*
|
||||||
// quick blink 20ms on each 1/5 second
|
// check if payload is sent
|
||||||
new_led_state = ((millis() % 200) < 20) ? HIGH : LOW;
|
while(LMIC.opmode & OP_TXRXPEND) {
|
||||||
|
if(!lorawait)
|
||||||
// TX data pending
|
sprintf(display_lora, "LoRa wait");
|
||||||
} else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) {
|
lorawait++;
|
||||||
color = COLOR_BLUE;
|
// in case sending really fails: reset LMIC and rejoin network
|
||||||
// small blink 10ms on each 1/2sec (not when joining)
|
if( (lorawait % MAXLORARETRY ) == 0) {
|
||||||
new_led_state = ((millis() % 500) < 20) ? HIGH : LOW;
|
ESP_LOGI(TAG, "Payload not sent, resetting LMIC and rejoin");
|
||||||
|
lorawait = 0;
|
||||||
// This should not happen so indicate a problem
|
LMIC_reset(); // Reset the MAC state. Session and pending data transfers will be discarded.
|
||||||
} else if ( LMIC.opmode & (OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) {
|
};
|
||||||
color = COLOR_RED;
|
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||||
// heartbeat long blink 200ms on each 2 seconds
|
|
||||||
new_led_state = ((millis() % 2000) < 200) ? HIGH : LOW;
|
|
||||||
} else {
|
|
||||||
// led off
|
|
||||||
rgb_set_color(COLOR_NONE);
|
|
||||||
}
|
}
|
||||||
// led need to change state? avoid digitalWrite() for nothing
|
*/
|
||||||
if (led_state != new_led_state) {
|
vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
|
||||||
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);
|
|
||||||
yield();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,114 +181,61 @@ void lorawan_loop(void * pvParameters) {
|
|||||||
|
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
HAS_DISPLAY u8x8(OLED_RST, OLED_SCL, OLED_SDA);
|
HAS_DISPLAY u8x8(OLED_RST, OLED_SCL, OLED_SDA);
|
||||||
|
// Display Refresh IRQ
|
||||||
|
void IRAM_ATTR DisplayIRQ() {
|
||||||
|
portENTER_CRITICAL_ISR(&timerMux);
|
||||||
|
DisplayTimerIRQ++;
|
||||||
|
portEXIT_CRITICAL_ISR(&timerMux);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
// defined in antenna.cpp
|
// defined in antenna.cpp
|
||||||
void antenna_init();
|
void antenna_init();
|
||||||
void antenna_select(const int8_t _ant);
|
void antenna_select(const uint8_t _ant);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BLECOUNTER
|
#ifndef BLECOUNTER
|
||||||
bool btstop = btStop();
|
bool btstop = btStop();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void set_onboard_led(int st){
|
#ifdef HAS_BUTTON
|
||||||
#ifdef HAS_LED
|
// Button IRQ
|
||||||
switch (st) {
|
// IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855
|
||||||
#ifdef LED_ACTIVE_LOW
|
void IRAM_ATTR ButtonIRQ() {
|
||||||
case 1: digitalWrite(HAS_LED, LOW); break;
|
ButtonPressed++;
|
||||||
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
|
||||||
};
|
|
||||||
|
|
||||||
|
void IRAM_ATTR ChannelSwitchIRQ() {
|
||||||
#ifdef HAS_BUTTON
|
portENTER_CRITICAL(&timerMux);
|
||||||
// Button Handling, board dependent -> perhaps to be moved to hal/<$board.h>
|
ChannelTimerIRQ++;
|
||||||
// IRAM_ATTR necessary here, see https://github.com/espressif/arduino-esp32/issues/855
|
portEXIT_CRITICAL(&timerMux);
|
||||||
void IRAM_ATTR isr_button_pressed(void) {
|
}
|
||||||
ButtonTriggered = true; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* end hardware specific parts -------------------------------------------------------- */
|
/* end hardware specific parts -------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
/* begin wifi specific parts ---------------------------------------------------------- */
|
/* begin wifi specific parts ---------------------------------------------------------- */
|
||||||
|
|
||||||
// defined in wifisniffer.cpp
|
|
||||||
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);
|
|
||||||
|
|
||||||
// defined in blescan.cpp
|
|
||||||
void bt_loop(void *ignore);
|
|
||||||
|
|
||||||
// Sniffer Task
|
// Sniffer Task
|
||||||
void sniffer_loop(void * pvParameters) {
|
void sniffer_loop(void * pvParameters) {
|
||||||
|
|
||||||
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
||||||
channel=0;
|
|
||||||
char buff[16];
|
|
||||||
int nloop=0, lorawait=0;
|
|
||||||
|
|
||||||
while (true) {
|
while (1) {
|
||||||
|
|
||||||
nloop++; // actual number of wifi loops, controls cycle when data is sent
|
if (ChannelTimerIRQ) {
|
||||||
|
portENTER_CRITICAL(&timerMux);
|
||||||
|
ChannelTimerIRQ--;
|
||||||
|
portEXIT_CRITICAL(&timerMux);
|
||||||
|
// rotates variable channel 1..WIFI_CHANNEL_MAX
|
||||||
|
channel = (channel % WIFI_CHANNEL_MAX) + 1;
|
||||||
|
wifi_sniffer_set_channel(channel);
|
||||||
|
ESP_LOGD(TAG, "Wifi set channel %d", channel);
|
||||||
|
|
||||||
vTaskDelay(cfg.wifichancycle*10 / portTICK_PERIOD_MS);
|
vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
|
||||||
yield();
|
}
|
||||||
channel = (channel % WIFI_CHANNEL_MAX) + 1; // rotates variable channel 1..WIFI_CHANNEL_MAX
|
|
||||||
wifi_sniffer_set_channel(channel);
|
|
||||||
ESP_LOGD(TAG, "Wifi set channel %d", channel);
|
|
||||||
|
|
||||||
// duration of one wifi scan loop reached? then send data and begin new scan cycle
|
|
||||||
if ( nloop >= ( (100 / cfg.wifichancycle) * (cfg.wifiscancycle * 2)) +1 ) {
|
|
||||||
nloop=0; channel=0; // reset wifi scan + channel loop counter
|
|
||||||
do_send(&sendjob); // Prepare and execute LoRaWAN data upload
|
|
||||||
vTaskDelay(500/portTICK_PERIOD_MS);
|
|
||||||
yield();
|
|
||||||
|
|
||||||
// clear counter if not in cumulative counter mode
|
|
||||||
if (cfg.countermode != 1) {
|
|
||||||
macs.clear(); // clear all macs container
|
|
||||||
wifis.clear(); // clear Wifi macs couner
|
|
||||||
#ifdef BLECOUNTER
|
|
||||||
bles.clear(); // clear BLE macs counter
|
|
||||||
#endif
|
|
||||||
salt_reset(); // get new salt for salting hashes
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if payload is sent
|
|
||||||
lorawait = 0;
|
|
||||||
while(LMIC.opmode & OP_TXRXPEND) {
|
|
||||||
if(!lorawait)
|
|
||||||
sprintf(display_lora, "LoRa wait");
|
|
||||||
lorawait++;
|
|
||||||
// in case sending really fails: reset and rejoin network
|
|
||||||
if( (lorawait % MAXLORARETRY ) == 0) {
|
|
||||||
ESP_LOGI(TAG, "Payload not sent, trying reset and rejoin");
|
|
||||||
esp_restart();
|
|
||||||
};
|
|
||||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
sprintf(display_lora, " "); // clear LoRa wait message fromd display
|
|
||||||
|
|
||||||
/*
|
|
||||||
// TBD: need to check if long 2000ms pause causes stack problems while scanning continues
|
|
||||||
if (cfg.screenon && cfg.screensaver) {
|
|
||||||
vTaskDelay(2000/portTICK_PERIOD_MS); // pause for displaying results
|
|
||||||
yield();
|
|
||||||
u8x8.setPowerSave(1 && cfg.screensaver); // set display off if screensaver is enabled
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // end of send data cycle
|
|
||||||
|
|
||||||
} // end of infinite wifi channel rotation loop
|
} // end of infinite wifi channel rotation loop
|
||||||
}
|
}
|
||||||
@ -330,71 +252,215 @@ uint64_t uptime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
// Print a key on display
|
|
||||||
void DisplayKey(const uint8_t * key, uint8_t len, bool lsb) {
|
|
||||||
uint8_t start=lsb?len:0;
|
|
||||||
uint8_t end = lsb?0:len;
|
|
||||||
const uint8_t * p ;
|
|
||||||
for (uint8_t i=0; i<len ; i++) {
|
|
||||||
p = lsb ? key+len-i-1 : key+i;
|
|
||||||
u8x8.printf("%02X", *p);
|
|
||||||
}
|
|
||||||
u8x8.printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_display(const char *Productname, const char *Version) {
|
// Print a key on display
|
||||||
uint8_t buf[32];
|
void DisplayKey(const uint8_t * key, uint8_t len, bool lsb) {
|
||||||
u8x8.begin();
|
uint8_t start=lsb?len:0;
|
||||||
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
uint8_t end = lsb?0:len;
|
||||||
u8x8.clear();
|
const uint8_t * p ;
|
||||||
u8x8.setFlipMode(0);
|
for (uint8_t i=0; i<len ; i++) {
|
||||||
u8x8.setInverseFont(1);
|
p = lsb ? key+len-i-1 : key+i;
|
||||||
u8x8.draw2x2String(0, 0, Productname);
|
u8x8.printf("%02X", *p);
|
||||||
u8x8.setInverseFont(0);
|
}
|
||||||
u8x8.draw2x2String(2, 2, Productname);
|
u8x8.printf("\n");
|
||||||
delay(1500);
|
}
|
||||||
u8x8.clear();
|
|
||||||
u8x8.setFlipMode(1);
|
|
||||||
u8x8.setInverseFont(1);
|
|
||||||
u8x8.draw2x2String(0, 0, Productname);
|
|
||||||
u8x8.setInverseFont(0);
|
|
||||||
u8x8.draw2x2String(2, 2, Productname);
|
|
||||||
delay(1500);
|
|
||||||
|
|
||||||
u8x8.setFlipMode(0);
|
void init_display(const char *Productname, const char *Version) {
|
||||||
u8x8.clear();
|
uint8_t buf[32];
|
||||||
|
u8x8.begin();
|
||||||
#ifdef DISPLAY_FLIP
|
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
||||||
|
u8x8.clear();
|
||||||
|
u8x8.setFlipMode(0);
|
||||||
|
u8x8.setInverseFont(1);
|
||||||
|
u8x8.draw2x2String(0, 0, Productname);
|
||||||
|
u8x8.setInverseFont(0);
|
||||||
|
u8x8.draw2x2String(2, 2, Productname);
|
||||||
|
delay(1500);
|
||||||
|
u8x8.clear();
|
||||||
u8x8.setFlipMode(1);
|
u8x8.setFlipMode(1);
|
||||||
#endif
|
u8x8.setInverseFont(1);
|
||||||
|
u8x8.draw2x2String(0, 0, Productname);
|
||||||
|
u8x8.setInverseFont(0);
|
||||||
|
u8x8.draw2x2String(2, 2, Productname);
|
||||||
|
delay(1500);
|
||||||
|
|
||||||
// Display chip information
|
u8x8.setFlipMode(0);
|
||||||
#ifdef VERBOSE
|
u8x8.clear();
|
||||||
esp_chip_info_t chip_info;
|
|
||||||
esp_chip_info(&chip_info);
|
|
||||||
u8x8.printf("ESP32 %d cores\nWiFi%s%s\n",
|
|
||||||
chip_info.cores,
|
|
||||||
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
|
|
||||||
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
|
|
||||||
u8x8.printf("ESP Rev.%d\n", chip_info.revision);
|
|
||||||
u8x8.printf("%dMB %s Flash\n", spi_flash_get_chip_size() / (1024 * 1024),
|
|
||||||
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext.");
|
|
||||||
#endif // VERBOSE
|
|
||||||
|
|
||||||
u8x8.print(Productname);
|
#ifdef DISPLAY_FLIP
|
||||||
u8x8.print(" v");
|
u8x8.setFlipMode(1);
|
||||||
u8x8.println(PROGVERSION);
|
#endif
|
||||||
u8x8.println("DEVEUI:");
|
|
||||||
os_getDevEui((u1_t*) buf);
|
// Display chip information
|
||||||
DisplayKey(buf, 8, true);
|
#ifdef VERBOSE
|
||||||
delay(5000);
|
esp_chip_info_t chip_info;
|
||||||
u8x8.clear();
|
esp_chip_info(&chip_info);
|
||||||
}
|
u8x8.printf("ESP32 %d cores\nWiFi%s%s\n",
|
||||||
|
chip_info.cores,
|
||||||
|
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
|
||||||
|
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
|
||||||
|
u8x8.printf("ESP Rev.%d\n", chip_info.revision);
|
||||||
|
u8x8.printf("%dMB %s Flash\n", spi_flash_get_chip_size() / (1024 * 1024),
|
||||||
|
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext.");
|
||||||
|
#endif // VERBOSE
|
||||||
|
|
||||||
|
u8x8.print(Productname);
|
||||||
|
u8x8.print(" v");
|
||||||
|
u8x8.println(PROGVERSION);
|
||||||
|
u8x8.println("DEVEUI:");
|
||||||
|
os_getDevEui((u1_t*) buf);
|
||||||
|
DisplayKey(buf, 8, true);
|
||||||
|
delay(5000);
|
||||||
|
u8x8.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void refreshDisplay() {
|
||||||
|
// update counter display (lines 0-4)
|
||||||
|
char buff[16];
|
||||||
|
snprintf(buff, sizeof(buff), "PAX:%-4d", (int) macs.size()); // convert 16-bit MAC counter to decimal counter value
|
||||||
|
u8x8.draw2x2String(0, 0, buff); // display number on unique macs total Wifi + BLE
|
||||||
|
u8x8.setCursor(0,4);
|
||||||
|
u8x8.printf("WIFI:%-4d", macs_wifi);
|
||||||
|
|
||||||
|
#ifdef BLECOUNTER
|
||||||
|
u8x8.setCursor(0,3);
|
||||||
|
if (cfg.blescan)
|
||||||
|
u8x8.printf("BLTH:%-4d", macs_ble);
|
||||||
|
else
|
||||||
|
u8x8.printf("%-16s", "BLTH:off");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// update LoRa SF display (line 3)
|
||||||
|
u8x8.setCursor(11,3);
|
||||||
|
u8x8.printf("SF:%c%c", lora_datarate[LMIC.datarate * 2], lora_datarate[LMIC.datarate * 2 + 1]);
|
||||||
|
|
||||||
|
// update wifi channel display (line 4)
|
||||||
|
u8x8.setCursor(11,4);
|
||||||
|
u8x8.printf("ch:%02d", channel);
|
||||||
|
|
||||||
|
// update RSSI limiter status & free memory display (line 5)
|
||||||
|
u8x8.setCursor(0,5);
|
||||||
|
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit);
|
||||||
|
u8x8.setCursor(10,5);
|
||||||
|
u8x8.printf("%4dKB", ESP.getFreeHeap() / 1024);
|
||||||
|
|
||||||
|
// update LoRa status display (line 6)
|
||||||
|
u8x8.setCursor(0,6);
|
||||||
|
u8x8.printf("%-16s", display_lora);
|
||||||
|
|
||||||
|
// update LMiC event display (line 7)
|
||||||
|
u8x8.setCursor(0,7);
|
||||||
|
u8x8.printf("%-16s", display_lmic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateDisplay() {
|
||||||
|
// refresh display according to refresh cycle setting
|
||||||
|
if (DisplayTimerIRQ) {
|
||||||
|
portENTER_CRITICAL(&timerMux);
|
||||||
|
DisplayTimerIRQ--;
|
||||||
|
portEXIT_CRITICAL(&timerMux);
|
||||||
|
|
||||||
|
refreshDisplay();
|
||||||
|
|
||||||
|
// set display on/off according to current device configuration
|
||||||
|
if (DisplayState != cfg.screenon) {
|
||||||
|
DisplayState = cfg.screenon;
|
||||||
|
u8x8.setPowerSave(!cfg.screenon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // updateDisplay()
|
||||||
#endif // HAS_DISPLAY
|
#endif // HAS_DISPLAY
|
||||||
|
|
||||||
|
#ifdef HAS_BUTTON
|
||||||
|
void readButton() {
|
||||||
|
if (ButtonPressed) {
|
||||||
|
ButtonPressed--;
|
||||||
|
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults");
|
||||||
|
eraseConfig();
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
|
||||||
|
void blink_LED(uint16_t set_color, uint16_t set_blinkduration) {
|
||||||
|
LEDColor = set_color; // set color for RGB LED
|
||||||
|
LEDBlinkDuration = set_blinkduration; // duration
|
||||||
|
LEDBlinkStarted = millis(); // Time Start here
|
||||||
|
LEDState = LED_ON; // Let main set LED on
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_loop() {
|
||||||
|
// Custom blink running always have priority other LoRaWAN led management
|
||||||
|
if ( LEDBlinkStarted && LEDBlinkDuration) {
|
||||||
|
|
||||||
|
//ESP_LOGI(TAG, "Start=%ld for %g",LEDBlinkStarted, LEDBlinkDuration );
|
||||||
|
|
||||||
|
// Custom blink is finished, let this order, avoid millis() overflow
|
||||||
|
if ( (millis() - LEDBlinkStarted) >= LEDBlinkDuration) {
|
||||||
|
// Led becomes off, and stop blink
|
||||||
|
LEDState = LED_OFF;
|
||||||
|
LEDBlinkStarted = 0;
|
||||||
|
LEDBlinkDuration = 0;
|
||||||
|
LEDColor = COLOR_NONE ;
|
||||||
|
} else {
|
||||||
|
// In case of LoRaWAN led management blinked off
|
||||||
|
LEDState = LED_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No custom blink, check LoRaWAN state
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// LED indicators for viusalizing LoRaWAN state
|
||||||
|
if ( LMIC.opmode & (OP_JOINING | OP_REJOIN) ) {
|
||||||
|
LEDColor = COLOR_YELLOW;
|
||||||
|
// quick blink 20ms on each 1/5 second
|
||||||
|
LEDState = ((millis() % 200) < 20) ? LED_ON : LED_OFF; // TX data pending
|
||||||
|
} else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) {
|
||||||
|
LEDColor = COLOR_BLUE;
|
||||||
|
// small blink 10ms on each 1/2sec (not when joining)
|
||||||
|
LEDState = ((millis() % 500) < 20) ? LED_ON : LED_OFF;
|
||||||
|
// This should not happen so indicate a problem
|
||||||
|
} else if ( LMIC.opmode & (OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0 ) {
|
||||||
|
LEDColor = COLOR_RED;
|
||||||
|
// heartbeat long blink 200ms on each 2 seconds
|
||||||
|
LEDState = ((millis() % 2000) < 200) ? LED_ON : LED_OFF;
|
||||||
|
} else {
|
||||||
|
// led off
|
||||||
|
LEDColor = COLOR_NONE;
|
||||||
|
LEDState = LED_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ESP_LOGI(TAG, "state=%d previous=%d Color=%d",LEDState, previousLEDState, LEDColor );
|
||||||
|
// led need to change state? avoid digitalWrite() for nothing
|
||||||
|
if (LEDState != previousLEDState) {
|
||||||
|
if (LEDState == LED_ON) {
|
||||||
|
rgb_set_color(LEDColor);
|
||||||
|
#ifdef LED_ACTIVE_LOW
|
||||||
|
digitalWrite(HAS_LED, LOW);
|
||||||
|
#else
|
||||||
|
digitalWrite(HAS_LED, HIGH);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
rgb_set_color(COLOR_NONE);
|
||||||
|
#ifdef LED_ACTIVE_LOW
|
||||||
|
digitalWrite(HAS_LED, HIGH);
|
||||||
|
#else
|
||||||
|
digitalWrite(HAS_LED, LOW);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
previousLEDState = LEDState;
|
||||||
|
}
|
||||||
|
}; // led_loop()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* begin Aruino SETUP ------------------------------------------------------------ */
|
/* begin Aruino SETUP ------------------------------------------------------------ */
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
char features[64] = "";
|
||||||
|
|
||||||
// disable brownout detection
|
// disable brownout detection
|
||||||
#ifdef DISABLE_BROWNOUT
|
#ifdef DISABLE_BROWNOUT
|
||||||
@ -413,7 +479,6 @@ 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);
|
|
||||||
|
|
||||||
// initialize system event handler for wifi task, needed for wifi_sniffer_init()
|
// initialize system event handler for wifi task, needed for wifi_sniffer_init()
|
||||||
esp_event_loop_init(NULL, NULL);
|
esp_event_loop_init(NULL, NULL);
|
||||||
@ -435,67 +500,100 @@ void setup() {
|
|||||||
loadConfig(); // includes initialize if necessary
|
loadConfig(); // includes initialize if necessary
|
||||||
|
|
||||||
// initialize led if needed
|
// initialize led if needed
|
||||||
#ifdef HAS_LED
|
#if (HAS_LED != NOT_A_PIN)
|
||||||
pinMode(HAS_LED, OUTPUT);
|
pinMode(HAS_LED, OUTPUT);
|
||||||
digitalWrite(HAS_LED, LOW);
|
strcat(features, " LED");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_RGB_LED
|
||||||
|
rgb_set_color(COLOR_PINK);
|
||||||
|
strcat(features, " RGB");
|
||||||
|
delay(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// initialize button handling if needed
|
// initialize button handling if needed
|
||||||
#ifdef HAS_BUTTON
|
#ifdef HAS_BUTTON
|
||||||
|
strcat(features, " BTN_");
|
||||||
#ifdef BUTTON_PULLUP
|
#ifdef BUTTON_PULLUP
|
||||||
|
strcat(features, "PU");
|
||||||
// install button interrupt (pullup mode)
|
// install button interrupt (pullup mode)
|
||||||
pinMode(HAS_BUTTON, INPUT_PULLUP);
|
pinMode(HAS_BUTTON, INPUT_PULLUP);
|
||||||
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), isr_button_pressed, RISING);
|
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, RISING);
|
||||||
#else
|
#else
|
||||||
|
strcat(features, "PD");
|
||||||
// install button interrupt (pulldown mode)
|
// install button interrupt (pulldown mode)
|
||||||
pinMode(HAS_BUTTON, INPUT_PULLDOWN);
|
pinMode(HAS_BUTTON, INPUT_PULLDOWN);
|
||||||
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), isr_button_pressed, FALLING);
|
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, FALLING);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// initialize wifi antenna if needed
|
// initialize wifi antenna if needed
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
|
strcat(features, " ANT");
|
||||||
antenna_init();
|
antenna_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
// initialize display
|
strcat(features, " OLED");
|
||||||
|
// initialize display
|
||||||
init_display(PROGNAME, PROGVERSION);
|
init_display(PROGNAME, PROGVERSION);
|
||||||
|
DisplayState = cfg.screenon;
|
||||||
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
|
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
|
||||||
u8x8.draw2x2String(0, 0, "PAX:0");
|
u8x8.draw2x2String(0, 0, "PAX:0");
|
||||||
u8x8.setCursor(0,4);
|
u8x8.setCursor(0,4);
|
||||||
u8x8.printf("WIFI: 0");
|
u8x8.printf("WIFI:0");
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
u8x8.setCursor(0,3);
|
u8x8.setCursor(0,3);
|
||||||
u8x8.printf("BLTH: 0");
|
u8x8.printf("BLTH:0");
|
||||||
#endif
|
#endif
|
||||||
u8x8.setCursor(0,5);
|
u8x8.setCursor(0,5);
|
||||||
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %d", cfg.rssilimit);
|
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit);
|
||||||
|
|
||||||
sprintf(display_lora, "Join wait");
|
sprintf(display_lora, "Join wait");
|
||||||
|
|
||||||
|
// setup Display IRQ, thanks to https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
|
||||||
|
displaytimer = timerBegin(0, 80, true); // prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 0, count up
|
||||||
|
timerAttachInterrupt(displaytimer, &DisplayIRQ, true); // interrupt handler DisplayIRQ, triggered by edge
|
||||||
|
timerAlarmWrite(displaytimer, DISPLAYREFRESH_MS * 1000, true); // reload interrupt after each trigger of display refresh cycle
|
||||||
|
timerAlarmEnable(displaytimer); // enable display interrupt
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// setup channel rotation IRQ, thanks to https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
|
||||||
|
channelSwitch = timerBegin(1, 80, true); // prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 1, count up
|
||||||
|
timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true); // interrupt handler, triggered by edge
|
||||||
|
timerAlarmWrite(channelSwitch, cfg.wifichancycle * 10000, true); // reload interrupt after each trigger of channel switch cycle
|
||||||
|
timerAlarmEnable(channelSwitch); // enable channel switching interrupt
|
||||||
|
|
||||||
|
// show compiled features
|
||||||
|
ESP_LOGI(TAG, "Features %s", features);
|
||||||
|
|
||||||
// output LoRaWAN keys to console
|
// output LoRaWAN keys to console
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
printKeys();
|
printKeys();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
os_init(); // setup LMIC
|
os_init(); // setup LMIC
|
||||||
|
LMIC_reset(); // Reset the MAC state. Session and pending data transfers will be discarded.
|
||||||
os_setCallback(&initjob, lora_init); // setup initial job & join network
|
os_setCallback(&initjob, lora_init); // setup initial job & join network
|
||||||
|
|
||||||
wifi_sniffer_init(); // setup wifi in monitor mode and start MAC counting
|
wifi_sniffer_init(); // setup wifi in monitor mode and start MAC counting
|
||||||
|
|
||||||
// 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
|
||||||
// note: do this *after* wifi has started, since gets it's seed from RF noise
|
// note: do this *after* wifi has started, since gets it's seed from RF noise
|
||||||
salt_reset(); // get new 16bit for salting hashes
|
reset_salt(); // get new 16bit for salting hashes
|
||||||
|
|
||||||
// run wifi task on core 0 and lora task on core 1 and bt task on core 0
|
// run wifi task on core 0 and lora task on core 1 and bt task on core 0
|
||||||
ESP_LOGI(TAG, "Starting Lora task on core 1");
|
ESP_LOGI(TAG, "Starting Lora task on core 1");
|
||||||
xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 1);
|
xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 1);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Starting Wifi task on core 0");
|
ESP_LOGI(TAG, "Starting Wifi task on core 0");
|
||||||
xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 16384, ( void * ) 1, 1, NULL, 0);
|
xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 2048, ( void * ) 1, 1, NULL, 0);
|
||||||
|
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
if (cfg.blescan) { // start BLE task only if BLE function is enabled in NVRAM configuration
|
if (cfg.blescan) { // start BLE task only if BLE function is enabled in NVRAM configuration
|
||||||
ESP_LOGI(TAG, "Starting Bluetooth task on core 0");
|
ESP_LOGI(TAG, "Starting Bluetooth task on core 0");
|
||||||
xTaskCreatePinnedToCore(bt_loop, "btscan", 16384, NULL, 5, NULL, 0);
|
xTaskCreatePinnedToCore(bt_loop, "btscan", 4096, ( void * ) 1, 1, NULL, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -513,56 +611,30 @@ do_send(&sendjob);
|
|||||||
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
|
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
uptimecounter = uptime() / 1000; // count uptime seconds
|
// simple state machine for controlling display, LED, button, etc.
|
||||||
|
uptimecounter = uptime() / 1000; // counts uptime in seconds (64bit)
|
||||||
|
|
||||||
#ifdef HAS_BUTTON // ...then check if pressed
|
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
|
||||||
if (ButtonTriggered) {
|
led_loop();
|
||||||
ButtonTriggered = false;
|
|
||||||
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults");
|
|
||||||
eraseConfig();
|
|
||||||
esp_restart();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_DISPLAY // ...then update mask
|
#ifdef HAS_BUTTON
|
||||||
|
readButton();
|
||||||
// set display on/off according to current device configuration
|
|
||||||
u8x8.setPowerSave(!cfg.screenon);
|
|
||||||
|
|
||||||
// update counter display (lines 0-4)
|
|
||||||
char buff[16];
|
|
||||||
snprintf(buff, sizeof(buff), "PAX:%-4d", (int) macs.size()); // convert 16-bit MAC counter to decimal counter value
|
|
||||||
u8x8.draw2x2String(0, 0, buff); // display number on unique macs total Wifi + BLE
|
|
||||||
u8x8.setCursor(0,4);
|
|
||||||
u8x8.printf("WIFI: %-4d", (int) wifis.size());
|
|
||||||
#ifdef BLECOUNTER
|
|
||||||
u8x8.setCursor(0,3);
|
|
||||||
if (cfg.blescan)
|
|
||||||
u8x8.printf("BLTH: %-4d", (int) bles.size());
|
|
||||||
else
|
|
||||||
u8x8.printf("%-16s", "BLTH: off");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// update wifi channel display (line 4)
|
|
||||||
u8x8.setCursor(11,4);
|
|
||||||
u8x8.printf("ch:%02i", channel);
|
|
||||||
|
|
||||||
// update RSSI limiter status display (line 5)
|
|
||||||
u8x8.setCursor(0,5);
|
|
||||||
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %-4d", cfg.rssilimit);
|
|
||||||
|
|
||||||
// update LoRa status display (line 6)
|
|
||||||
u8x8.setCursor(0,6);
|
|
||||||
u8x8.printf("%-16s", display_lora);
|
|
||||||
|
|
||||||
// update LMiC event display (line 7)
|
|
||||||
u8x8.setCursor(0,7);
|
|
||||||
u8x8.printf("%-16s", display_lmic);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vTaskDelay(1000/DISPLAYFPS/portTICK_PERIOD_MS);
|
#ifdef HAS_DISPLAY
|
||||||
|
updateDisplay();
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
// check free memory
|
||||||
|
if (ESP.getFreeHeap() <= MEM_LOW) {
|
||||||
|
do_send(&sendjob); // send count
|
||||||
|
reset_counters(); // clear macs container and reset all counters
|
||||||
|
reset_salt(); // get new salt for salting hashes
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(10/portTICK_PERIOD_MS); // reset watchdog
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* end Aruino LOOP ------------------------------------------------------------ */
|
/* end Aruino LOOP ------------------------------------------------------------ */
|
||||||
|
151
src/main.h
151
src/main.h
@ -1,131 +1,44 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// program version - note: increment version after modifications to configData_t struct!!
|
// program version - note: increment version after modifications to configData_t struct!!
|
||||||
#define PROGVERSION "1.3.01" // use max 10 chars here!
|
#define PROGVERSION "1.3.4" // use max 10 chars here!
|
||||||
#define PROGNAME "PAXCNT"
|
#define PROGNAME "PAXCNT"
|
||||||
|
|
||||||
// Verbose enables serial output
|
//--- Declarations ---
|
||||||
#define VERBOSE 1 // comment out to silence the device, for mute use build option
|
|
||||||
|
|
||||||
// set this to include BLE counting and vendor filter functions
|
enum led_states {
|
||||||
#define VENDORFILTER 1 // comment out if you want to count things, not people
|
LED_OFF,
|
||||||
#define BLECOUNTER 1 // comment out if you don't want BLE count
|
LED_ON
|
||||||
|
};
|
||||||
|
|
||||||
// BLE scan parameters
|
#if defined(CFG_eu868)
|
||||||
#define BLESCANTIME 11 // [seconds] scan duration, see note below
|
const char lora_datarate[] = {"1211100908077BFSNA"};
|
||||||
#define BLESCANWINDOW 10 // [milliseconds] scan window, see below, 3 .. 10240, default 10
|
#elif defined(CFG_us915)
|
||||||
#define BLESCANINTERVAL 10 // [milliseconds] how long to wait between scans, 3 .. 10240, default 10
|
const char lora_datarate[] = {"100908078CNA121110090807"};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Note: guide for setting bluetooth parameters
|
//--- Prototypes ---
|
||||||
*
|
|
||||||
* |< Scan Window > |< Scan Window > |< Scan Window > |
|
|
||||||
* |< Scan Interval >|< Scan Interval >|< Scan Interval >|
|
|
||||||
* |< Scan duration >|
|
|
||||||
*
|
|
||||||
* Scan duration sets how long scanning should be going on, interrupting a wifi scan cycle.
|
|
||||||
* Scan window sets how much of the interval should be occupied by scanning.
|
|
||||||
* Scan interval is how long scanning should be done on each channel. BLE uses 3 channels for advertising.
|
|
||||||
* -> Adjust these values with power consumption in mind if power is limited.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// WiFi scan parameters
|
// defined in main.cpp
|
||||||
#define WIFI_CHANNEL_MIN 1 // start channel number where scan begings
|
void reset_counters(void);
|
||||||
#define WIFI_CHANNEL_MAX 13 // total channel number to scan
|
void blink_LED(uint16_t set_color, uint16_t set_blinkduration);
|
||||||
#define WIFI_MY_COUNTRY "EU" // select locale for Wifi RF settings
|
void led_loop(void);
|
||||||
#define WIFI_CHANNEL_SWITCH_INTERVAL 50 // [seconds/100] -> 0,5 sec.
|
|
||||||
|
|
||||||
// LoRa payload send cycle
|
// defined in configmanager.cpp
|
||||||
#define SEND_SECS 120 // [seconds/2] -> 240 sec.
|
void eraseConfig(void);
|
||||||
//#define SEND_SECS 30 // [seconds/2] -> 60 sec.
|
void saveConfig(void);
|
||||||
|
void loadConfig(void);
|
||||||
|
|
||||||
// Default LoRa Spreadfactor
|
// defined in lorawan.cpp
|
||||||
#define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs
|
void onEvent(ev_t ev);
|
||||||
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy
|
void do_send(osjob_t* j);
|
||||||
#define RCMDPORT 2 // LoRaWAN Port on which device listenes for remote commands
|
void gen_lora_deveui(uint8_t * pdeveui);
|
||||||
|
void RevBytes(unsigned char* b, size_t c);
|
||||||
|
void get_hard_deveui(uint8_t *pdeveui);
|
||||||
|
|
||||||
// Default RGB LED luminosity (in %)
|
// defined in wifisniffer.cpp
|
||||||
#define RGBLUMINOSITY 30 // 30%
|
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);
|
||||||
|
|
||||||
// OLED Display refresh cycle (in Milliseconds)
|
// defined in blescan.cpp
|
||||||
#define DISPLAYFPS 5 // [fps] -> 5 Frames per second ps = 200ms refreseh cycle
|
void bt_loop(void *ignore);
|
||||||
|
|
||||||
// LMIC settings
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// Select frequency band here according to national regulations
|
|
||||||
#define CFG_eu868 1
|
|
||||||
//#define CFG_us915 1
|
|
||||||
|
|
||||||
// This is the SX1272/SX1273 radio, which is also used on the HopeRF
|
|
||||||
// RFM92 boards.
|
|
||||||
//#define CFG_sx1272_radio 1
|
|
||||||
// This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on
|
|
||||||
// the HopeRF RFM95 boards.
|
|
||||||
//#define CFG_sx1276_radio 1
|
|
||||||
|
|
||||||
// 16 μs per tick
|
|
||||||
// LMIC requires ticks to be 15.5μs - 100 μs long
|
|
||||||
#define US_PER_OSTICK_EXPONENT 4
|
|
||||||
#define US_PER_OSTICK (1 << US_PER_OSTICK_EXPONENT)
|
|
||||||
#define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK)
|
|
||||||
|
|
||||||
// Set this to 1 to enable some basic debug output (using printf) about
|
|
||||||
// RF settings used during transmission and reception. Set to 2 to
|
|
||||||
// enable more verbose output. Make sure that printf is actually
|
|
||||||
// configured (e.g. on AVR it is not by default), otherwise using it can
|
|
||||||
// cause crashing.
|
|
||||||
//#define LMIC_DEBUG_LEVEL 1
|
|
||||||
|
|
||||||
// Enable this to allow using printf() to print to the given serial port
|
|
||||||
// (or any other Print object). This can be easy for debugging. The
|
|
||||||
// current implementation only works on AVR, though.
|
|
||||||
//#define LMIC_PRINTF_TO Serial
|
|
||||||
|
|
||||||
// Any runtime assertion failures are printed to this serial port (or
|
|
||||||
// any other Print object). If this is unset, any failures just silently
|
|
||||||
// halt execution.
|
|
||||||
#define LMIC_FAILURE_TO Serial
|
|
||||||
|
|
||||||
// Uncomment this to disable all code related to joining
|
|
||||||
//#define DISABLE_JOIN
|
|
||||||
// Uncomment this to disable all code related to ping
|
|
||||||
#define DISABLE_PING
|
|
||||||
// Uncomment this to disable all code related to beacon tracking.
|
|
||||||
// Requires ping to be disabled too
|
|
||||||
#define DISABLE_BEACONS
|
|
||||||
|
|
||||||
// Uncomment these to disable the corresponding MAC commands.
|
|
||||||
// Class A
|
|
||||||
//#define DISABLE_MCMD_DCAP_REQ // duty cycle cap
|
|
||||||
//#define DISABLE_MCMD_DN2P_SET // 2nd DN window param
|
|
||||||
//#define DISABLE_MCMD_SNCH_REQ // set new channel
|
|
||||||
// Class B
|
|
||||||
//#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING
|
|
||||||
//#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatical disabled by DISABLE_BEACON
|
|
||||||
|
|
||||||
// In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the
|
|
||||||
// same on RX. This ensures that gateways can talk to nodes and vice
|
|
||||||
// versa, but gateways will not hear other gateways and nodes will not
|
|
||||||
// hear other nodes. By uncommenting this macro, this inversion is
|
|
||||||
// disabled and this node can hear other nodes. If two nodes both have
|
|
||||||
// this macro set, they can talk to each other (but they can no longer
|
|
||||||
// hear gateways). This should probably only be used when debugging
|
|
||||||
// and/or when talking to the radio directly (e.g. like in the "raw"
|
|
||||||
// example).
|
|
||||||
//#define DISABLE_INVERT_IQ_ON_RX
|
|
||||||
|
|
||||||
// This allows choosing between multiple included AES implementations.
|
|
||||||
// Make sure exactly one of these is uncommented.
|
|
||||||
//
|
|
||||||
// This selects the original AES implementation included LMIC. This
|
|
||||||
// implementation is optimized for speed on 32-bit processors using
|
|
||||||
// fairly big lookup tables, but it takes up big amounts of flash on the
|
|
||||||
// AVR architecture.
|
|
||||||
#define USE_ORIGINAL_AES
|
|
||||||
//
|
|
||||||
// This selects the AES implementation written by Ideetroon for their
|
|
||||||
// own LoRaWAN library. It also uses lookup tables, but smaller
|
|
||||||
// byte-oriented ones, making it use a lot less flash space (but it is
|
|
||||||
// also about twice as slow as the original).
|
|
||||||
// #define USE_IDEETRON_AES
|
|
||||||
|
129
src/paxcounter.conf
Normal file
129
src/paxcounter.conf
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// ----- Paxcounter user config file ------
|
||||||
|
//
|
||||||
|
// --> adapt to your needs and use case <--
|
||||||
|
|
||||||
|
// Verbose enables serial output
|
||||||
|
#define VERBOSE 1 // comment out to silence the device, for mute use build option
|
||||||
|
|
||||||
|
// set this to include BLE counting and vendor filter functions
|
||||||
|
#define VENDORFILTER 1 // comment out if you want to count things, not people
|
||||||
|
#define BLECOUNTER 1 // comment out if you don't want BLE count
|
||||||
|
|
||||||
|
// BLE scan parameters
|
||||||
|
#define BLESCANTIME 11 // [seconds] scan duration, see note below
|
||||||
|
#define BLESCANWINDOW 10 // [milliseconds] scan window, see below, 3 .. 10240, default 10
|
||||||
|
#define BLESCANINTERVAL 10 // [milliseconds] how long to wait between scans, 3 .. 10240, default 10
|
||||||
|
|
||||||
|
/* Note: guide for setting bluetooth parameters
|
||||||
|
*
|
||||||
|
* |< Scan Window > |< Scan Window > |< Scan Window > |
|
||||||
|
* |< Scan Interval >|< Scan Interval >|< Scan Interval >|
|
||||||
|
* |< Scan duration >|
|
||||||
|
*
|
||||||
|
* Scan duration sets how long scanning should be going on, interrupting a wifi scan cycle.
|
||||||
|
* Scan window sets how much of the interval should be occupied by scanning.
|
||||||
|
* Scan interval is how long scanning should be done on each channel. BLE uses 3 channels for advertising.
|
||||||
|
* -> Adjust these values with power consumption in mind if power is limited.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// WiFi scan parameters
|
||||||
|
#define WIFI_CHANNEL_MIN 1 // start channel number where scan begings
|
||||||
|
#define WIFI_CHANNEL_MAX 13 // total channel number to scan
|
||||||
|
#define WIFI_MY_COUNTRY "EU" // select locale for Wifi RF settings
|
||||||
|
#define WIFI_CHANNEL_SWITCH_INTERVAL 50 // [seconds/100] -> 0,5 sec.
|
||||||
|
|
||||||
|
// LoRa payload send cycle --> take care of duty cycle of LoRaWAN network! <--
|
||||||
|
#define SEND_SECS 120 // [seconds/2] -> 240 sec.
|
||||||
|
#define MEM_LOW 2048 // [Bytes] low memory threshold triggering a send cycle
|
||||||
|
|
||||||
|
// Default LoRa Spreadfactor
|
||||||
|
#define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs
|
||||||
|
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy
|
||||||
|
#define RCMDPORT 2 // LoRaWAN Port on which device listenes for remote commands
|
||||||
|
|
||||||
|
// Default RGB LED luminosity (in %)
|
||||||
|
#define RGBLUMINOSITY 30 // 30%
|
||||||
|
|
||||||
|
// OLED Display refresh cycle (in Milliseconds)
|
||||||
|
#define DISPLAYREFRESH_MS 40 // e.g. 40ms -> 1000/40 = 25 frames per second
|
||||||
|
|
||||||
|
// LMIC settings
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Select frequency band here according to national regulations
|
||||||
|
#define CFG_eu868 1
|
||||||
|
//#define CFG_us915 1
|
||||||
|
|
||||||
|
// This is the SX1272/SX1273 radio, which is also used on the HopeRF
|
||||||
|
// RFM92 boards.
|
||||||
|
//#define CFG_sx1272_radio 1
|
||||||
|
// This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on
|
||||||
|
// the HopeRF RFM95 boards.
|
||||||
|
//#define CFG_sx1276_radio 1
|
||||||
|
|
||||||
|
// 16 μs per tick
|
||||||
|
// LMIC requires ticks to be 15.5μs - 100 μs long
|
||||||
|
#define US_PER_OSTICK_EXPONENT 4
|
||||||
|
#define US_PER_OSTICK (1 << US_PER_OSTICK_EXPONENT)
|
||||||
|
#define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK)
|
||||||
|
|
||||||
|
// Set this to 1 to enable some basic debug output (using printf) about
|
||||||
|
// RF settings used during transmission and reception. Set to 2 to
|
||||||
|
// enable more verbose output. Make sure that printf is actually
|
||||||
|
// configured (e.g. on AVR it is not by default), otherwise using it can
|
||||||
|
// cause crashing.
|
||||||
|
//#define LMIC_DEBUG_LEVEL 1
|
||||||
|
|
||||||
|
// Enable this to allow using printf() to print to the given serial port
|
||||||
|
// (or any other Print object). This can be easy for debugging. The
|
||||||
|
// current implementation only works on AVR, though.
|
||||||
|
//#define LMIC_PRINTF_TO Serial
|
||||||
|
|
||||||
|
// Any runtime assertion failures are printed to this serial port (or
|
||||||
|
// any other Print object). If this is unset, any failures just silently
|
||||||
|
// halt execution.
|
||||||
|
#define LMIC_FAILURE_TO Serial
|
||||||
|
|
||||||
|
// Uncomment this to disable all code related to joining
|
||||||
|
//#define DISABLE_JOIN
|
||||||
|
// Uncomment this to disable all code related to ping
|
||||||
|
#define DISABLE_PING
|
||||||
|
// Uncomment this to disable all code related to beacon tracking.
|
||||||
|
// Requires ping to be disabled too
|
||||||
|
#define DISABLE_BEACONS
|
||||||
|
|
||||||
|
// Uncomment these to disable the corresponding MAC commands.
|
||||||
|
// Class A
|
||||||
|
//#define DISABLE_MCMD_DCAP_REQ // duty cycle cap
|
||||||
|
//#define DISABLE_MCMD_DN2P_SET // 2nd DN window param
|
||||||
|
//#define DISABLE_MCMD_SNCH_REQ // set new channel
|
||||||
|
// Class B
|
||||||
|
//#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING
|
||||||
|
//#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatical disabled by DISABLE_BEACON
|
||||||
|
|
||||||
|
// In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the
|
||||||
|
// same on RX. This ensures that gateways can talk to nodes and vice
|
||||||
|
// versa, but gateways will not hear other gateways and nodes will not
|
||||||
|
// hear other nodes. By uncommenting this macro, this inversion is
|
||||||
|
// disabled and this node can hear other nodes. If two nodes both have
|
||||||
|
// this macro set, they can talk to each other (but they can no longer
|
||||||
|
// hear gateways). This should probably only be used when debugging
|
||||||
|
// and/or when talking to the radio directly (e.g. like in the "raw"
|
||||||
|
// example).
|
||||||
|
//#define DISABLE_INVERT_IQ_ON_RX
|
||||||
|
|
||||||
|
// This allows choosing between multiple included AES implementations.
|
||||||
|
// Make sure exactly one of these is uncommented.
|
||||||
|
//
|
||||||
|
// This selects the original AES implementation included LMIC. This
|
||||||
|
// implementation is optimized for speed on 32-bit processors using
|
||||||
|
// fairly big lookup tables, but it takes up big amounts of flash on the
|
||||||
|
// AVR architecture.
|
||||||
|
#define USE_ORIGINAL_AES
|
||||||
|
//
|
||||||
|
// This selects the AES implementation written by Ideetroon for their
|
||||||
|
// own LoRaWAN library. It also uses lookup tables, but smaller
|
||||||
|
// byte-oriented ones, making it use a lot less flash space (but it is
|
||||||
|
// also about twice as slow as the original).
|
||||||
|
// #define USE_IDEETRON_AES
|
@ -14,22 +14,18 @@ static const char *TAG = "rcommand";
|
|||||||
|
|
||||||
// table of remote commands and assigned functions
|
// table of remote commands and assigned functions
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const int nam;
|
const uint8_t nam;
|
||||||
void (*func)(int);
|
void (*func)(uint8_t);
|
||||||
const bool store;
|
const bool store;
|
||||||
} cmd_t;
|
} cmd_t;
|
||||||
|
|
||||||
// functions defined in configmanager.cpp
|
|
||||||
void eraseConfig(void);
|
|
||||||
void saveConfig(void);
|
|
||||||
|
|
||||||
// function defined in antenna.cpp
|
// function defined in antenna.cpp
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
void antenna_select(const int8_t _ant);
|
void antenna_select(const uint8_t _ant);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// help function to assign LoRa datarates to numeric spreadfactor values
|
// help function to assign LoRa datarates to numeric spreadfactor values
|
||||||
void switch_lora (int sf, int tx) {
|
void switch_lora (uint8_t sf, uint8_t tx) {
|
||||||
if ( tx > 20 ) return;
|
if ( tx > 20 ) return;
|
||||||
cfg.txpower = tx;
|
cfg.txpower = tx;
|
||||||
switch (sf) {
|
switch (sf) {
|
||||||
@ -54,7 +50,7 @@ void switch_lora (int sf, int tx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set of functions that can be triggered by remote commands
|
// set of functions that can be triggered by remote commands
|
||||||
void set_reset(int val) {
|
void set_reset(uint8_t val) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 0: // restart device
|
case 0: // restart device
|
||||||
ESP_LOGI(TAG, "Remote command: restart device");
|
ESP_LOGI(TAG, "Remote command: restart device");
|
||||||
@ -64,12 +60,8 @@ 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 all macs container
|
reset_counters(); // clear macs
|
||||||
wifis.clear(); // clear Wifi macs container
|
reset_salt(); // get new salt
|
||||||
#ifdef BLECOUNTER
|
|
||||||
bles.clear(); // clear BLE macs container
|
|
||||||
#endif
|
|
||||||
salt_reset(); // get new 16bit salt
|
|
||||||
sprintf(display_lora, "Reset counter");
|
sprintf(display_lora, "Reset counter");
|
||||||
break;
|
break;
|
||||||
case 2: // reset device to factory settings
|
case 2: // reset device to factory settings
|
||||||
@ -80,27 +72,29 @@ void set_reset(int val) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_rssi(int val) {
|
void set_rssi(uint8_t val) {
|
||||||
cfg.rssilimit = val * -1;
|
cfg.rssilimit = val * -1;
|
||||||
ESP_LOGI(TAG, "Remote command: set RSSI limit to %i", cfg.rssilimit);
|
ESP_LOGI(TAG, "Remote command: set RSSI limit to %d", cfg.rssilimit);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_wifiscancycle(int val) {
|
void set_sendcycle(uint8_t val) {
|
||||||
cfg.wifiscancycle = val;
|
cfg.sendcycle = val;
|
||||||
ESP_LOGI(TAG, "Remote command: set Wifi scan cycle duration to %i seconds", cfg.wifiscancycle*2);
|
ESP_LOGI(TAG, "Remote command: set payload send cycle to %d seconds", cfg.sendcycle*2);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_wifichancycle(int val) {
|
void set_wifichancycle(uint8_t val) {
|
||||||
cfg.wifichancycle = val;
|
cfg.wifichancycle = val;
|
||||||
ESP_LOGI(TAG, "Remote command: set Wifi channel switch interval to %i seconds", cfg.wifichancycle/100);
|
// 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));
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_blescantime(int val) {
|
void set_blescantime(uint8_t val) {
|
||||||
cfg.blescantime = val;
|
cfg.blescantime = val;
|
||||||
ESP_LOGI(TAG, "Remote command: set BLE scan time to %i seconds", cfg.blescantime);
|
ESP_LOGI(TAG, "Remote command: set BLE scan time to %d seconds", cfg.blescantime);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_countmode(int val) {
|
void set_countmode(uint8_t val) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 0: // cyclic unconfirmed
|
case 0: // cyclic unconfirmed
|
||||||
cfg.countermode = 0;
|
cfg.countermode = 0;
|
||||||
@ -117,7 +111,7 @@ void set_countmode(int val) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_screensaver(int val) {
|
void set_screensaver(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set screen saver to %s ", val ? "on" : "off");
|
ESP_LOGI(TAG, "Remote command: set screen saver to %s ", val ? "on" : "off");
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 1: cfg.screensaver = val; break;
|
case 1: cfg.screensaver = val; break;
|
||||||
@ -125,7 +119,7 @@ void set_screensaver(int val) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_display(int val) {
|
void set_display(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set screen to %s", val ? "on" : "off");
|
ESP_LOGI(TAG, "Remote command: set screen to %s", val ? "on" : "off");
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 1: cfg.screenon = val; break;
|
case 1: cfg.screenon = val; break;
|
||||||
@ -133,12 +127,12 @@ void set_display(int val) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_lorasf(int val) {
|
void set_lorasf(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set LoRa SF to %i", val);
|
ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val);
|
||||||
switch_lora(val, cfg.txpower);
|
switch_lora(val, cfg.txpower);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_loraadr(int val) {
|
void set_loraadr(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off");
|
ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off");
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 1: cfg.adrmode = val; break;
|
case 1: cfg.adrmode = val; break;
|
||||||
@ -147,14 +141,12 @@ void set_loraadr(int val) {
|
|||||||
LMIC_setAdrMode(cfg.adrmode);
|
LMIC_setAdrMode(cfg.adrmode);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_blescan(int val) {
|
void set_blescan(uint8_t 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 0:
|
case 0:
|
||||||
cfg.blescan = 0;
|
cfg.blescan = 0;
|
||||||
#ifdef BLECOUNTER
|
macs_ble = 0; // clear BLE counter
|
||||||
bles.clear(); // clear BLE macs container
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cfg.blescan = 1;
|
cfg.blescan = 1;
|
||||||
@ -162,7 +154,7 @@ void set_blescan(int val) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_wifiant(int 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) {
|
switch (val) {
|
||||||
case 1: cfg.wifiant = val; break;
|
case 1: cfg.wifiant = val; break;
|
||||||
@ -173,7 +165,7 @@ void set_wifiant(int val) {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_vendorfilter(int 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) {
|
switch (val) {
|
||||||
case 1: cfg.vendorfilter = val; break;
|
case 1: cfg.vendorfilter = val; break;
|
||||||
@ -181,22 +173,22 @@ void set_vendorfilter(int val) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_rgblum(int val) {
|
void set_rgblum(uint8_t val) {
|
||||||
// Avoid wrong parameters
|
// Avoid wrong parameters
|
||||||
cfg.rgblum = (val>=0 && val<=100) ? (uint8_t) val : RGBLUMINOSITY;
|
cfg.rgblum = (val>=0 && val<=100) ? (uint8_t) val : RGBLUMINOSITY;
|
||||||
ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum);
|
ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_lorapower(int val) {
|
void set_lorapower(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %i", val);
|
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val);
|
||||||
switch_lora(cfg.lorasf, val);
|
switch_lora(cfg.lorasf, val);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_noop (int val) {
|
void set_noop (uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: noop - doing nothing");
|
ESP_LOGI(TAG, "Remote command: noop - doing nothing");
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_config (int val) {
|
void get_config (uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get configuration");
|
ESP_LOGI(TAG, "Remote command: get configuration");
|
||||||
int size = sizeof(configData_t);
|
int size = sizeof(configData_t);
|
||||||
// declare send buffer (char byte array)
|
// declare send buffer (char byte array)
|
||||||
@ -205,20 +197,20 @@ void get_config (int val) {
|
|||||||
memcpy(sendData, &cfg, size);
|
memcpy(sendData, &cfg, size);
|
||||||
LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port
|
LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port
|
||||||
delete sendData; // free memory
|
delete sendData; // free memory
|
||||||
ESP_LOGI(TAG, "%i bytes queued in send queue", size-1);
|
ESP_LOGI(TAG, "%d bytes queued in send queue", size-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_uptime (int val) {
|
void get_uptime (uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get uptime");
|
ESP_LOGI(TAG, "Remote command: get uptime");
|
||||||
int size = sizeof(uptimecounter);
|
int size = sizeof(uptimecounter);
|
||||||
unsigned char *sendData = new unsigned char[size];
|
unsigned char *sendData = new unsigned char[size];
|
||||||
memcpy(sendData, (unsigned char*)&uptimecounter, size);
|
memcpy(sendData, (unsigned char*)&uptimecounter , size);
|
||||||
LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port
|
LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port
|
||||||
delete sendData; // free memory
|
delete sendData; // free memory
|
||||||
ESP_LOGI(TAG, "%i bytes queued in send queue", size-1);
|
ESP_LOGI(TAG, "%d bytes queued in send queue", size-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_cputemp (int val) {
|
void get_cputemp (uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get cpu temperature");
|
ESP_LOGI(TAG, "Remote command: get cpu temperature");
|
||||||
float temp = temperatureRead();
|
float temp = temperatureRead();
|
||||||
int size = sizeof(temp);
|
int size = sizeof(temp);
|
||||||
@ -226,7 +218,7 @@ void get_cputemp (int val) {
|
|||||||
memcpy(sendData, (unsigned char*)&temp, size);
|
memcpy(sendData, (unsigned char*)&temp, size);
|
||||||
LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port
|
LMIC_setTxData2(RCMDPORT, sendData, size-1, 0); // send data unconfirmed on RCMD Port
|
||||||
delete sendData; // free memory
|
delete sendData; // free memory
|
||||||
ESP_LOGI(TAG, "%i bytes queued in send queue", size-1);
|
ESP_LOGI(TAG, "%d bytes queued in send queue", size-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
// assign previously defined functions to set of numeric remote commands
|
// assign previously defined functions to set of numeric remote commands
|
||||||
@ -242,7 +234,7 @@ cmd_t table[] = {
|
|||||||
{0x07, set_loraadr, true},
|
{0x07, set_loraadr, true},
|
||||||
{0x08, set_screensaver, true},
|
{0x08, set_screensaver, true},
|
||||||
{0x09, set_reset, false},
|
{0x09, set_reset, false},
|
||||||
{0x0a, set_wifiscancycle, true},
|
{0x0a, set_sendcycle, true},
|
||||||
{0x0b, set_wifichancycle, true},
|
{0x0b, set_wifichancycle, true},
|
||||||
{0x0c, set_blescantime, true},
|
{0x0c, set_blescantime, true},
|
||||||
{0x0d, set_vendorfilter, false},
|
{0x0d, set_vendorfilter, false},
|
||||||
@ -255,7 +247,7 @@ cmd_t table[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// check and execute remote command
|
// check and execute remote command
|
||||||
void rcommand(int cmd, int arg) {
|
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;
|
bool store_flag = false;
|
||||||
while(i--) {
|
while(i--) {
|
||||||
|
Loading…
Reference in New Issue
Block a user