This commit is contained in:
Oliver Brandmueller 2018-04-19 00:45:30 +02:00
commit b6d61b5cd4
12 changed files with 547 additions and 382 deletions

View File

@ -228,13 +228,13 @@ under this Licence:
Most source files in this repository are made available under the Eclipse Public License v1.0. The examples which use a more liberal license. Some of the AES code is available under the LGPL. Refer to each individual source file for more details."
------------------------------------------------------------------------------------------------
blecount.cpp
blescan.cpp
Parts of blecount.cpp were derived or taken from
Parts of blescan.cpp were derived or taken from
nkolban esp32 snippets
BLE Scan
https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils/tests/BLETests/Arduino/BLE_scan
BLE GAP DUMP
https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
under this Licence:

View File

@ -1,6 +1,8 @@
# ESP32-Paxcounter
**Wifi & Bluetooth driven, LoRaWAN enabled, battery powered mini Paxcounter built on cheap ESP32 boards**
---> check branch "development" for latest alpha version <---
<img src="img/Paxcounter-title.jpg">
# Use case
@ -20,13 +22,13 @@ This can all be done with a single small and cheap ESP32 board for less than $20
Currently supported IoT boards:
- Heltec LoRa-32 {1}
- TTGOv1 {1}
- TTGOv2 {1}
- TTGOv2 {1}{4}
- Pycom LoPy {2}
- Pycom LoPy4 {2}
- LoLin32 with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora) {2}{3}
- LoLin32 Lite with [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-Lora) {2}{3}
{1} on board OLED Display supported; {2} on board RGB LED supported; {3} on board Hardware unique DEVEUI supported
{1} on board OLED Display supported; {2} on board RGB LED supported; {3} on board Hardware unique DEVEUI supported; {4} special wiring needed, see instructions in /hal/ttgov2.h
Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).<br>
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory.<br>
@ -36,15 +38,15 @@ Hardware dependent settings (pinout etc.) are stored in board files in /hal dire
<b>Power consumption</b>:
- Heltec ~650mW
- TTGOv1 ~650mW
- TTGOv2 ~670mW
- LoPy with expansion board: ~530mW
- LoPy pure, without expansion board: ~460mW
- Heltec ~720mW
- TTGOv1 TBD
- TTGOv2 ~990mW
- LoPy with expansion board: ~690mW
- LoPy pure, without expansion board: TBD
- LoLin32 with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora): TBD
- LoLin32 Lite with [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-Lora): TBD
These results where metered with software version 1.2.0 during active wifi scan, no LoRa TXing, OLED display off, 5V USB powered.
These results where metered with software version 1.2.97 while continuously scanning wifi and ble, no LoRa TXing, OLED display (if present) on, 5V USB powered.
# Building
@ -62,8 +64,8 @@ If your device has silicon **Unique ID** which is stored in serial EEPROM Microc
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>
The LoPy/LoPy4 board needs to be set manually. See these
<A HREF="https://www.thethingsnetwork.org/labs/story/program-your-lopy-from-the-arduino-ide-using-lmic">instructions</A> how to do it.<p>
For the LoPy/LoPy4 the original Pycom firmware is not needed here, so there is no need to update it before flashing Paxcounter. Just flash the paxcounter code on your LoPy/LoPy4. If you want to go back to the Pycom firmware, no problem. Download the firmware from Pycom and flash it over.
<A HREF="https://www.thethingsnetwork.org/labs/story/program-your-lopy-from-the-arduino-ide-using-lmic">instructions</A> how to do it. Don't forget to press on board reset button after switching between run and bootloader mode.<p>
The original Pycom firmware is not needed, so there is no need to update it before flashing Paxcounter. Just flash the compiled paxcounter binary (.elf file) on your LoPy/LoPy4. If you later want to go back to the Pycom firmware, download the firmware from Pycom and flash it over.
# Legal note
@ -102,10 +104,10 @@ Multiple command/parameter pairs can be concatenated and sent in one single payl
Note: all settings are stored in NVRAM and will be reloaded when device starts. To reset device to factory settings press button (if device has one), or send remote command 09 02 09 00 unconfirmed(!) once.
0x01 set Wifi scan RSSI limit
0x01 set scan RSSI limit
1 ... 255 used for wifi scan radius (greater values increase wifi scan radius, values 50...110 make sense)
0 = Wifi rssi limiter disabled [default]
1 ... 255 used for wifi and bluetooth scan radius (greater values increase scan radius, values 50...110 make sense)
0 = RSSI limiter disabled [default]
0x02 set counter mode
@ -113,7 +115,7 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
1 = cumulative counter, mac counter is never reset
2 = cyclic confirmed, like 0 but data is resent until confirmation by network received
0x03 set screen saver mode
0x03 (NOT YET IMPLEMENTED) set screen saver mode
0 = screen saver off [default]
1 = screen saver on
@ -161,12 +163,12 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
0x0C set BLE scan cycle timer
0 ... 255 duration of a BLE scan cycle in seconds
e.g. 15 -> 1 cycle runs for 15 seconds [default]
e.g. 11 -> 1 cycle runs for 11 seconds [default]
0x0D set BLE scan cycle frequency
0x0D (NOT YET IMPLEMENTED) set BLE and WIFI vendorfilter mode
run BLE scan once after 0 ... 255 full wifi scans
e.g. 2 -> BLE scan runs once after each 2nd wifi scan [default]
0 = disabled (use to count devices, not people)
1 = enabled [default]
0x0E set BLE scan mode
@ -197,9 +199,9 @@ device answers with it's current configuration. The configuration is a C structu
byte 9: Wifi scan cycle duration in seconds/2 (0..255)
byte 10: Wifi channel switch interval in seconds/100 (0..255)
byte 11: BLE scan cycle duration in seconds (0..255)
byte 12: BLE scan frequency, do once after (0..255) full wifi scans
byte 13: BLE scan mode (1=on, 0=0ff)
byte 14: Wifi antenna switch (0=internal, 1=external)
byte 12: BLE scan mode (1=on, 0=0ff)
byte 13: Wifi antenna switch (0=internal, 1=external)
byte 14: Vendorfilter mode (0=disabled, 1=enabled)
byte 15: RGB LED luminosity (0..100 %)
bytes 16-25: Software version (ASCII format)

View File

@ -8,6 +8,7 @@
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
; ---> SELECT TARGET PLATFORM HERE! <---
[platformio]
env_default = heltec_wifi_lora_32
@ -17,185 +18,115 @@ env_default = heltec_wifi_lora_32
;env_default = lopy4
;env_default = lolin32lite_lora
;env_default = lolin32_lora
;
description = Paxcounter is a proof-of-concept ESP32 device for metering passenger flows in realtime. It counts how many mobile devices are around.
[common_env_data]
lib_deps_display =
U8g2@>=2.22.14
lib_deps_rgbled =
SmartLeds
build_flags =
; we need build_flag for logging, otherwise we can't use ESP_LOGx in arduino framework
; ---> NOTE: For production run set DEBUG_LEVEL level to NONE! <---
; 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_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
;
; override lora settings from LMiC library in lmic/config.h and use main.h instead
-D_lmic_config_h_
-include "src/main.h"
[env:heltec_wifi_lora_32]
platform = espressif32
board = heltec_wifi_lora_32
framework = arduino
board = heltec_wifi_lora_32
monitor_baud = 115200
upload_speed = 921600
upload_speed = 115200
lib_deps =
U8g2
ESP32 BLE Arduino@>=0.4.9
${common_env_data.lib_deps_display}
build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
;needed for ESP32 BLE Ardunio v0.4.9
-fexceptions
-std=c++11
;override lora settings from LMiC library in lmic/config.h and use main.h instead
-D_lmic_config_h_
${common_env_data.build_flags}
-Dheltec_wifi_lora_32
-include "src/main.h"
-include "src/hal/heltec.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE
[env:ttgov1]
platform = espressif32
board = esp32dev
framework = arduino
board = esp32dev
monitor_baud = 115200
; On my V1, upload does not works over default 115200
upload_speed = 921600
;upload_port = COM15
upload_speed = 115200
lib_deps =
U8g2
ESP32 BLE Arduino@>=0.4.9
${common_env_data.lib_deps_display}
build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
;needed for ESP32 BLE Ardunio v0.4.9
-fexceptions
-std=c++11
;override lora settings from LMiC library in lmic/config.h and use main.h instead
${common_env_data.build_flags}
-Dttgov1
-D_lmic_config_h_
-include "src/main.h"
-include "src/hal/ttgov1.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE
[env:ttgov2]
platform = espressif32
board = esp32dev
framework = arduino
board = esp32dev
monitor_baud = 115200
upload_speed = 921600
lib_deps =
U8g2
ESP32 BLE Arduino@>=0.4.9
${common_env_data.lib_deps_display}
build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
;needed for ESP32 BLE Ardunio v0.4.9
-fexceptions
-std=c++11
;override lora settings from LMiC library in lmic/config.h and use main.h instead
-D_lmic_config_h_
${common_env_data.build_flags}
-Dttgov2
-include "src/main.h"
-include "src/hal/ttgov2.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE
[env:lopy]
platform = espressif32
board = esp32dev
framework = arduino
board = esp32dev
monitor_baud = 115200
upload_speed = 921600
lib_deps =
U8g2@>2.21.7
ESP32 BLE Arduino@>=0.4.9
SmartLeds
${common_env_data.lib_deps_rgbled}
build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
;needed for ESP32 BLE Ardunio v0.4.9
-fexceptions
-std=c++11
;override lora settings from LMiC library in lmic/config.h and use main.h instead
${common_env_data.build_flags}
-Dlopy
-D_lmic_config_h_
-include "src/main.h"
-include "src/hal/lopy.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE
[env:lopy4]
platform = espressif32
board = esp32dev
framework = arduino
board = esp32dev
monitor_baud = 115200
upload_speed = 921600
lib_deps =
U8g2@>2.21.7
ESP32 BLE Arduino@>=0.4.9
SmartLeds
${common_env_data.lib_deps_rgbled}
build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
;needed for ESP32 BLE Ardunio v0.4.9
-fexceptions
-std=c++11
;override lora settings from LMiC library in lmic/config.h and use main.h instead
-D_lmic_config_h_
${common_env_data.build_flags}
-Dlopy4
-include "src/main.h"
-include "src/hal/lopy4.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE
[env:lolin32lite_lora]
platform = espressif32
board = lolin32
framework = arduino
board = lolin32
monitor_baud = 115200
upload_speed = 256000
lib_deps =
U8g2
ESP32 BLE Arduino@>=0.4.9
SmartLeds
${common_env_data.lib_deps_rgbled}
build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
;needed for ESP32 BLE Ardunio v0.4.9
-fexceptions
-std=c++11
;override lora settings from LMiC library in lmic/config.h and use main.h instead
-D_lmic_config_h_
${common_env_data.build_flags}
-Dlolin32lite_lora
-include "src/main.h"
-include "src/hal/lolin32lite_lora.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE
[env:lolin32_lora]
platform = espressif32
board = lolin32
framework = arduino
board = lolin32
monitor_baud = 115200
upload_speed = 921600
lib_deps =
U8g2
ESP32 BLE Arduino@>=0.4.9
SmartLeds
${common_env_data.lib_deps_rgbled}
build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
;needed for ESP32 BLE Ardunio v0.4.9
-fexceptions
-std=c++11
;override lora settings from LMiC library in lmic/config.h and use main.h instead
-D_lmic_config_h_
${common_env_data.build_flags}
-Dlolin32_lora
-include "src/main.h"
-include "src/hal/lolin32_lora.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE

293
src/blecsan.cpp Normal file
View File

@ -0,0 +1,293 @@
#ifdef BLECOUNTER
/* code snippets taken from
https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
*/
// Basic Config
#include "globals.h"
// Bluetooth specific includes
#include <esp_bt.h>
#include <esp_bt_main.h>
#include <esp_gap_ble_api.h>
#include <esp_blufi_api.h> // needed for BLE_ADDR types, do not remove
#include <bt_types.h>
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
// local Tag for logging
static const char *TAG = "bt_loop";
// defined in macsniff.cpp
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type);
// Prototypes
static const char *bt_addr_t_to_string(esp_ble_addr_type_t type);
static const char *btsig_gap_type(uint32_t gap_type);
static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
static const char *bt_addr_t_to_string(esp_ble_addr_type_t type) {
switch(type) {
case BLE_ADDR_TYPE_PUBLIC:
return "BLE_ADDR_TYPE_PUBLIC";
case BLE_ADDR_TYPE_RANDOM:
return "BLE_ADDR_TYPE_RANDOM";
case BLE_ADDR_TYPE_RPA_PUBLIC:
return "BLE_ADDR_TYPE_RPA_PUBLIC";
case BLE_ADDR_TYPE_RPA_RANDOM:
return "BLE_ADDR_TYPE_RPA_RANDOM";
default:
return "Unknown addr_t";
}
} // bt_addr_t_to_string
static const char *btsig_gap_type(uint32_t gap_type) {
switch (gap_type)
{
case 0x01: return "Flags";
case 0x02: return "Incomplete List of 16-bit Service Class UUIDs";
case 0x03: return "Complete List of 16-bit Service Class UUIDs";
case 0x04: return "Incomplete List of 32-bit Service Class UUIDs";
case 0x05: return "Complete List of 32-bit Service Class UUIDs";
case 0x06: return "Incomplete List of 128-bit Service Class UUIDs";
case 0x07: return "Complete List of 128-bit Service Class UUIDs";
case 0x08: return "Shortened Local Name";
case 0x09: return "Complete Local Name";
case 0x0A: return "Tx Power Level";
case 0x0D: return "Class of Device";
case 0x0E: return "Simple Pairing Hash C/C-192";
case 0x0F: return "Simple Pairing Randomizer R/R-192";
case 0x10: return "Device ID/Security Manager TK Value";
case 0x11: return "Security Manager Out of Band Flags";
case 0x12: return "Slave Connection Interval Range";
case 0x14: return "List of 16-bit Service Solicitation UUIDs";
case 0x1F: return "List of 32-bit Service Solicitation UUIDs";
case 0x15: return "List of 128-bit Service Solicitation UUIDs";
case 0x16: return "Service Data - 16-bit UUID";
case 0x20: return "Service Data - 32-bit UUID";
case 0x21: return "Service Data - 128-bit UUID";
case 0x22: return "LE Secure Connections Confirmation Value";
case 0x23: return "LE Secure Connections Random Value";
case 0x24: return "URI";
case 0x25: return "Indoor Positioning";
case 0x26: return "Transport Discovery Data";
case 0x17: return "Public Target Address";
case 0x18: return "Random Target Address";
case 0x19: return "Appearance";
case 0x1A: return "Advertising Interval";
case 0x1B: return "LE Bluetooth Device Address";
case 0x1C: return "LE Role";
case 0x1D: return "Simple Pairing Hash C-256";
case 0x1E: return "Simple Pairing Randomizer R-256";
case 0x3D: return "3D Information Data";
case 0xFF: return "Manufacturer Specific Data";
default:
return "Unknown type";
}
} // btsig_gap_type
static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param;
esp_err_t status;
ESP_LOGD(tag, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv, btsig_gap_type(*p->scan_rst.ble_adv));
switch (event)
{
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
{ // restart scan
status = esp_ble_gap_start_scanning(BLESCANTIME);
if (status != ESP_OK)
{
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
}
}
break;
case ESP_GAP_BLE_SCAN_RESULT_EVT:
{
if ( p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
{ // restart scan
status = esp_ble_gap_start_scanning (BLESCANTIME);
if (status != ESP_OK)
{
ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status);
}
return;
}
if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
{ // evaluate sniffed packet
ESP_LOGD(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", BT_BD_ADDR_HEX(p->scan_rst.bda));
ESP_LOGD(TAG, "Addr_type : %s", bt_addr_t_to_string(p->scan_rst.ble_addr_type));
ESP_LOGD(TAG, "RSSI : %d", p->scan_rst.rssi);
if (!( cfg.rssilimit == 0 ) || (p->scan_rst.rssi > cfg.rssilimit )) { // rssi is negative value
ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi, cfg.rssilimit);
break;
}
#ifdef VENDORFILTER
if (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) goto skip;
if (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM) goto skip;
#endif
// add this device and show new count total if it was not previously added
if (cfg.blescan) // count only if BLE scan is enabled
mac_add((uint8_t *) p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
break;
skip:
ESP_LOGD(TAG, "BT device filtered");
break;
/* to be improved in vendorfilter if:
// you can search for elements in the payload using the
// function esp_ble_resolve_adv_data()
//
// Like this, that scans for the "Complete name" (looking inside the payload buffer)
// uint8_t len;
// uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &len);
filter BLE devices using their advertisements to get filter alternative to vendor OUI
if vendorfiltering is on, we ...
- want to count: mobile phones and tablets
- don't want to count: beacons, peripherals (earphones, headsets, printers), cars and machines
see
https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp
http://www.libelium.com/products/meshlium/smartphone-detection/
https://www.question-defense.com/2013/01/12/bluetooth-cod-bluetooth-class-of-deviceclass-of-service-explained
https://www.bluetooth.com/specifications/assigned-numbers/baseband
"The Class of Device (CoD) in case of Bluetooth which allows us to differentiate the type of
device (smartphone, handsfree, computer, LAN/network AP). With this parameter we can
differentiate among pedestrians and vehicles."
*/
}
}
break;
default:
break;
}
} // gap_callback_handler
esp_err_t register_ble_functionality(void)
{
esp_err_t status;
ESP_LOGI(TAG, "Register GAP callback");
// This function is called to occur gap event, such as scan result.
//register the scan callback function to the gap module
status = esp_ble_gap_register_callback(gap_callback_handler);
if (status != ESP_OK)
{
ESP_LOGE(TAG, "esp_ble_gap_register_callback: rc=%d", status);
return ESP_FAIL;
}
static esp_ble_scan_params_t ble_scan_params =
{
.scan_type = BLE_SCAN_TYPE_PASSIVE,
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
#ifdef VENDORFILTER
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR,
// ADV_IND, ADV_NONCONN_IND, ADV_SCAN_IND packets are used for broadcasting
// data in broadcast applications (e.g., Beacons), so we don't want them in vendorfilter mode
#else
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
#endif
.scan_interval = (uint16_t) (BLESCANINTERVAL / 0.625), // Time = N * 0.625 msec
.scan_window = (uint16_t) (BLESCANWINDOW / 0.625) // Time = N * 0.625 msec
};
ESP_LOGI(TAG, "Set GAP scan parameters");
// This function is called to set scan parameters.
status = esp_ble_gap_set_scan_params(&ble_scan_params);
if (status != ESP_OK)
{
ESP_LOGE(TAG, "esp_ble_gap_set_scan_params: rc=%d", status);
return ESP_FAIL;
}
return ESP_OK ;
}
// Main start code running in its own Xtask
void bt_loop(void *ignore)
{
esp_err_t status;
// Initialize BT controller to allocate task and other resource.
ESP_LOGI(TAG, "Enabling Bluetooth Controller");
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK)
{
ESP_LOGE(TAG, "Bluetooth controller initialize failed");
goto end;
}
// Enable BT controller
if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK)
{
ESP_LOGE(TAG, "Bluetooth controller enable failed");
goto end;
}
// Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff
ESP_LOGI(TAG, "Init Bluetooth stack");
status = esp_bluedroid_init();
if (status != ESP_OK)
{
ESP_LOGE(TAG, "%s init bluetooth failed\n", __func__);
goto end;
}
// Enable bluetooth, must after esp_bluedroid_init()
status = esp_bluedroid_enable();
if (status != ESP_OK)
{
ESP_LOGE(TAG, "%s enable bluetooth failed\n", __func__);
goto end;
}
ESP_LOGI(TAG, "Register BLE functionality");
status = register_ble_functionality();
if (status != ESP_OK)
{
ESP_LOGE(TAG, "Register BLE functionality failed");
goto end;
}
while(1)
{
vTaskDelay(500/portTICK_PERIOD_MS);
yield();
}
end:
ESP_LOGI(TAG, "Terminating BT logging task");
vTaskDelete(NULL);
} // bt_loop
#endif // BLECOUNTER

View File

@ -28,9 +28,9 @@ void defaultConfig() {
cfg.wifiscancycle = SEND_SECS; // wifi scan cycle [seconds/2]
cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
cfg.blescantime = BLESCANTIME; // BLE scan cycle duration [seconds]
cfg.blescancycle = BLESCANCYCLE; // do a BLE scan after [BLESCANCYCLE] full Wifi scan cycles
cfg.blescan = 1; // 0=disabled, 1=enabled
cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
cfg.vendorfilter = 1; // 0=disabled, 1=enabled
cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%)
strncpy( cfg.version, PROGVERSION, sizeof(cfg.version)-1 );
@ -108,15 +108,15 @@ void saveConfig() {
if( nvs_get_i8(my_handle, "blescantime", &flash8) != ESP_OK || flash8 != cfg.blescantime )
nvs_set_i8(my_handle, "blescantime", cfg.blescantime);
if( nvs_get_i8(my_handle, "blescancycle", &flash8) != ESP_OK || flash8 != cfg.blescancycle )
nvs_set_i8(my_handle, "blescancycle", cfg.blescancycle);
if( nvs_get_i8(my_handle, "blescanmode", &flash8) != ESP_OK || flash8 != cfg.blescan )
nvs_set_i8(my_handle, "blescanmode", cfg.blescan);
if( nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK || flash8 != cfg.wifiant )
nvs_set_i8(my_handle, "wifiant", cfg.wifiant);
if( nvs_get_i8(my_handle, "vendorfilter", &flash8) != ESP_OK || flash8 != cfg.vendorfilter )
nvs_set_i8(my_handle, "vendorfilter", cfg.vendorfilter);
if( nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || flash8 != cfg.rgblum )
nvs_set_i8(my_handle, "rgblum", cfg.rgblum);
@ -244,6 +244,14 @@ void loadConfig() {
saveConfig();
}
if( nvs_get_i8(my_handle, "vendorfilter", &flash8) == ESP_OK ) {
cfg.vendorfilter = flash8;
ESP_LOGI(TAG, "vendorfilter = %i", flash8);
} else {
ESP_LOGI(TAG, "Vendorfilter mode set to default %i", cfg.vendorfilter);
saveConfig();
}
if( nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK ) {
cfg.rgblum = flash8;
ESP_LOGI(TAG, "rgbluminosity = %i", flash8);
@ -260,14 +268,6 @@ void loadConfig() {
saveConfig();
}
if( nvs_get_i8(my_handle, "blescancycle", &flash8) == ESP_OK ) {
cfg.blescancycle = flash8;
ESP_LOGI(TAG, "blescancycle = %i", flash8);
} else {
ESP_LOGI(TAG, "BLEscancycle set to default %i", cfg.blescancycle);
saveConfig();
}
if( nvs_get_i8(my_handle, "blescanmode", &flash8) == ESP_OK ) {
cfg.blescan = flash8;
ESP_LOGI(TAG, "BLEscanmode = %i", flash8);
@ -287,8 +287,8 @@ void loadConfig() {
nvs_close(my_handle);
ESP_LOGI(TAG, "Done");
// put actions to be triggered on loaded config here
u8x8.setPowerSave(!cfg.screenon); // set display on/off
// put actions to be triggered after config loaded here
#ifdef HAS_ANTENNA_SWITCH // set antenna type, if device has one
antenna_select(cfg.wifiant);
#endif

View File

@ -6,8 +6,10 @@
#include <array>
#include <algorithm>
#ifdef HAS_DISPLAY
// OLED Display
#include <U8x8lib.h>
#endif
// LMIC-Arduino LoRaWAN Stack
#include <lmic.h>
@ -33,9 +35,9 @@ typedef struct {
int8_t wifiscancycle; // wifi scan cycle [seconds/2]
int8_t wifichancycle; // wifi channel switch cycle [seconds/100]
int8_t blescantime; // BLE scan cycle duration [seconds]
int8_t blescancycle; // BLE scan frequency, once after [blescancycle] full wifi scans
int8_t blescan; // 0=disabled, 1=enabled
int8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
int8_t vendorfilter; // 0=disabled, 1=enabled
int8_t rgblum; // RGB Led luminosity (0..100%)
char version[10]; // Firmware version
} configData_t;
@ -44,6 +46,7 @@ extern configData_t cfg;
extern uint8_t mydata[];
extern uint64_t uptimecounter;
extern osjob_t sendjob;
extern char display_lora[], display_lmic[];
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;
extern bool joinstate;
extern std::set<uint16_t> wifis;
@ -51,8 +54,6 @@ extern std::set<uint16_t> macs;
#ifdef HAS_DISPLAY
extern HAS_DISPLAY u8x8;
#else
extern U8X8_NULL u8x8;
#endif
#ifdef BLECOUNTER

View File

@ -135,15 +135,14 @@ void do_send(osjob_t* j){
//mydata[5] = data & 0xff;
// Check if there is not a current TX/RX job running
u8x8.clearLine(7);
if (LMIC.opmode & OP_TXRXPEND) {
ESP_LOGI(TAG, "OP_TXRXPEND, not sending");
u8x8.drawString(0, 7, "LORA BUSY");
sprintf(display_lmic, "LORA BUSY");
} else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata), (cfg.countermode & 0x02));
ESP_LOGI(TAG, "Packet queued");
u8x8.drawString(0, 7, "PACKET QUEUED");
sprintf(display_lmic, "PACKET QUEUED");
}
// Next TX is scheduled after TX_COMPLETE event.
}
@ -168,7 +167,7 @@ void onEvent (ev_t ev) {
case EV_JOINED:
strcpy_P(buff, PSTR("JOINED"));
u8x8.clearLine(6); // erase "Join Wait" message from display, see main.cpp
sprintf(display_lora, " "); // erase "Join Wait" message from display
// Disable link check validation (automatically enabled
// during join, but not supported by TTN at this time).
LMIC_setLinkCheckMode(0);
@ -182,23 +181,21 @@ void onEvent (ev_t ev) {
break;
case EV_TXCOMPLETE:
ESP_LOGI(TAG, "EV_TXCOMPLETE (includes waiting for RX windows)");
u8x8.clearLine(7);
if (LMIC.txrxFlags & TXRX_ACK) {
ESP_LOGI(TAG, "Received ack");
u8x8.drawString(0, 7, "RECEIVED ACK");
sprintf(display_lmic, "RECEIVED ACK");
} else {
u8x8.drawString(0, 7, "TX COMPLETE");
sprintf(display_lmic, "TX COMPLETE");
}
if (LMIC.dataLen) {
ESP_LOGI(TAG, "Received %d bytes of payload", LMIC.dataLen);
u8x8.clearLine(6);
u8x8.setCursor(0, 6);
u8x8.printf("Rcvd %d bytes", LMIC.dataLen);
u8x8.clearLine(7);
u8x8.setCursor(0, 7);
sprintf(display_lora, "Rcvd %d bytes", LMIC.dataLen);
// LMIC.snr = SNR twos compliment [dB] * 4
// LMIC.rssi = RSSI [dBm] (-196...+63)
u8x8.printf("RSSI %d SNR %d", LMIC.rssi, (signed char)LMIC.snr / 4);
sprintf(display_lmic, "RSSI %d SNR %d", LMIC.rssi, (signed char)LMIC.snr / 4 );
// check if payload received on command port, then call remote command interpreter
if ( (LMIC.txrxFlags & TXRX_PORT) && (LMIC.frame[LMIC.dataBeg-1] == RCMDPORT ) ) {
// caution: buffering LMIC values here because rcommand() can modify LMIC.frame
@ -217,8 +214,7 @@ void onEvent (ev_t ev) {
// Log & Display if asked
if (*buff) {
ESP_LOGI(TAG, "EV_%s", buff);
u8x8.clearLine(7);
u8x8.drawString(0, 7, buff);
sprintf(display_lmic, buff);
}

View File

@ -2,13 +2,6 @@
// Basic Config
#include "globals.h"
#ifdef BLECOUNTER
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#endif
#ifdef VENDORFILTER
#include <array>
#include <algorithm>
@ -20,7 +13,6 @@ static const char *TAG = "macsniff";
static wifi_country_t wifi_country = {.cc=WIFI_MY_COUNTRY, .schan=WIFI_CHANNEL_MIN, .nchan=WIFI_CHANNEL_MAX, .policy=WIFI_COUNTRY_POLICY_MANUAL};
uint16_t currentScanDevice = 0;
uint16_t salt;
uint16_t salt_reset(void) {
@ -42,7 +34,7 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
#ifdef VENDORFILTER
vendor2int = ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[1] << 8 ) | ( (uint32_t)paddr[0] << 16 );
// No vendor filter for 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() ) {
#endif
@ -57,23 +49,25 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
// Insert only if it was not found on global count
if (added) {
if (sniff_type == MAC_SNIFF_WIFI ) {
rgb_set_color(COLOR_GREEN);
wifis.insert(hashedmac); // add hashed MAC to wifi container if new unique
wifis.insert(hashedmac); // add hashed MAC to wifi container
}
#ifdef BLECOUNTER
else if (sniff_type == MAC_SNIFF_BLE ) {
rgb_set_color(COLOR_MAGENTA);
bles.insert(hashedmac); // add hashed MAC to BLE container if new unique
bles.insert(hashedmac); // add hashed MAC to BLE container
}
#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 BLE:%d %s",
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLE ",
ESP_LOGI(TAG, "%s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLTH:%d %s",
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLTH",
rssi, buff, hashedmac,
(int) wifis.size(),
#ifdef BLECOUNTER
@ -81,12 +75,12 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
#else
0,
#endif
added ? "New" : "Already seen");
added ? "new" : "known");
#ifdef VENDORFILTER
} else {
// Very noisy
//ESP_LOGI(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X", paddr[0],paddr[1],paddr[2],paddr[3],paddr[5],paddr[5]);
// ESP_LOGD(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X", paddr[0],paddr[1],paddr[2],paddr[3],paddr[5],paddr[5]);
}
#endif
@ -94,65 +88,6 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
return added; // function returns bool if a new and unique Wifi or BLE mac was counted (true) or not (false)
}
#ifdef BLECOUNTER
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
int lastcount = (int) macs.size();
uint8_t *p = (uint8_t *) advertisedDevice.getAddress().getNative();
/* to be done here:
#ifdef VENDORFILTER
filter BLE devices using their advertisements to get filter alternative to vendor OUI
if vendorfiltering is on, we ...
- want to count: mobile phones and tablets
- don't want to count: beacons, peripherals (earphones, headsets, printers), cars and machines
see
https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp
http://www.libelium.com/products/meshlium/smartphone-detection/
https://www.question-defense.com/2013/01/12/bluetooth-cod-bluetooth-class-of-deviceclass-of-service-explained
https://www.bluetooth.com/specifications/assigned-numbers/baseband
"The Class of Device (CoD) in case of Bluetooth which allows us to differentiate the type of
device (smartphone, handsfree, computer, LAN/network AP). With this parameter we can
differentiate among pedestrians and vehicles."
#endif
*/
// Current devices seen on this scan session
currentScanDevice++;
u8x8.setCursor(11,3);
u8x8.printf("%-4d", currentScanDevice);
// add this device and show new count total if it was not previously added
if ( mac_add(p, advertisedDevice.getRSSI(), MAC_SNIFF_BLE) ) {
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
}
}
};
void BLECount() {
ESP_LOGI(TAG, "BLE scan started");
currentScanDevice = 0; // Set 0 seen device on this scan session
u8x8.drawString(0,3,"Scanning->");
BLEDevice::init(""); // we don't want to be seen by a name
BLEScanResults foundDevices; // instance for getting count
BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(false); // An active scan would mean that we will wish unneeeded scan responses
pBLEScan->setWindow(BLESCANWINDOW);
pBLEScan->setInterval(BLESCANINTERVAL);
pBLEScan->start(cfg.blescantime); // note: this is a blocking call
ESP_LOGI(TAG, "BLE scan done, seen %d device(s)", foundDevices.getCount());
}
#endif
void wifi_sniffer_init(void) {
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM
@ -181,6 +116,5 @@ void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type) {
} else {
ESP_LOGI(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi, cfg.rssilimit);
}
//yield();
}

View File

@ -19,10 +19,7 @@ typedef struct {
uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
} wifi_ieee80211_packet_t;
extern uint16_t currentScanDevice;
uint16_t salt_reset(void);
void BLECount();
void wifi_sniffer_init(void);
void wifi_sniffer_set_channel(uint8_t channel);
void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);

View File

@ -27,9 +27,8 @@ Refer to LICENSE.txt file in repository for more details.
// std::set for unified array functions
#include <set>
// OLED driver
#include <U8x8lib.h>
#include <Wire.h> // Does nothing and avoid any compilation error with I2C
// Does nothing and avoid any compilation error with I2C
#include <Wire.h>
// LMIC-Arduino LoRaWAN Stack
#include "loraconf.h"
@ -45,6 +44,8 @@ configData_t cfg; // struct holds current device configuration
osjob_t sendjob, initjob; // LMIC
// Initialize global variables
char display_lora[16], display_lmic[16];
uint8_t channel = 0;
int macnum = 0;
uint64_t uptimecounter = 0;
bool joinstate = false;
@ -205,8 +206,6 @@ void lorawan_loop(void * pvParameters) {
#ifdef HAS_DISPLAY
HAS_DISPLAY u8x8(OLED_RST, OLED_SCL, OLED_SDA);
#else
U8X8_NULL u8x8;
#endif
#ifdef HAS_ANTENNA_SWITCH
@ -215,9 +214,7 @@ void lorawan_loop(void * pvParameters) {
void antenna_select(const int8_t _ant);
#endif
#ifdef BLECOUNTER
void BLECount(void);
#else
#ifndef BLECOUNTER
bool btstop = btStop();
#endif
@ -253,11 +250,14 @@ 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
void sniffer_loop(void * pvParameters) {
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
uint8_t channel=0;
channel=0;
char buff[16];
int nloop=0, lorawait=0;
@ -269,31 +269,10 @@ void sniffer_loop(void * pvParameters) {
yield();
channel = (channel % WIFI_CHANNEL_MAX) + 1; // rotates variable channel 1..WIFI_CHANNEL_MAX
wifi_sniffer_set_channel(channel);
ESP_LOGI(TAG, "Wifi set channel %d", channel);
snprintf(buff, sizeof(buff), "PAX:%d", (int) macs.size()); // convert 16-bit MAC counter to decimal counter value
u8x8.draw2x2String(0, 0, buff); // display number on unique macs total
#ifdef BLECOUNTER
// We just state out of BLE scanning
u8x8.setCursor(0,3);
if (currentScanDevice) {
u8x8.printf("BLE: %-4d %-4d", (int) bles.size(), currentScanDevice);
} else {
u8x8.printf("BLE: %-4d", (int) bles.size());
}
#endif
u8x8.setCursor(0,4);
u8x8.printf("WIFI: %-4d", (int) wifis.size());
u8x8.setCursor(11,4);
u8x8.printf("ch:%02i", channel);
u8x8.setCursor(0,5);
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %-3d", cfg.rssilimit);
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 ) {
u8x8.setPowerSave(!cfg.screenon); // set display on if enabled
nloop=0; channel=0; // reset wifi scan + channel loop counter
do_send(&sendjob); // Prepare and execute LoRaWAN data upload
vTaskDelay(500/portTICK_PERIOD_MS);
@ -307,15 +286,13 @@ void sniffer_loop(void * pvParameters) {
bles.clear(); // clear BLE macs counter
#endif
salt_reset(); // get new salt for salting hashes
u8x8.clearLine(0); // clear Display counter
u8x8.clearLine(1);
}
// wait until payload is sent, while wifi scanning and mac counting task continues
// check if payload is sent
lorawait = 0;
while(LMIC.opmode & OP_TXRXPEND) {
if(!lorawait)
u8x8.drawString(0,6,"LoRa wait ");
sprintf(display_lora, "LoRa wait");
lorawait++;
// in case sending really fails: reset and rejoin network
if( (lorawait % MAXLORARETRY ) == 0) {
@ -325,26 +302,20 @@ void sniffer_loop(void * pvParameters) {
vTaskDelay(1000/portTICK_PERIOD_MS);
yield();
}
sprintf(display_lora, " "); // clear LoRa wait message fromd display
u8x8.clearLine(6);
/*
// 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
else {
#ifdef BLECOUNTER
if (nloop % (WIFI_CHANNEL_MAX * cfg.blescancycle) == 0 ) // once after cfg.blescancycle Wifi scans, do a BLE scan
if (cfg.blescan) { // execute BLE count if BLE function is enabled
BLECount(); // start BLE scan, this is a blocking call
}
#endif
} // end of channel rotation loop
} // end of infinite wifi scan loop
} // end of infinite wifi channel rotation loop
}
/* end wifi specific parts ------------------------------------------------------------ */
@ -358,6 +329,7 @@ uint64_t uptime() {
return (uint64_t) high32 << 32 | low32;
}
#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;
@ -371,10 +343,9 @@ void DisplayKey(const uint8_t * key, uint8_t len, bool lsb) {
}
void init_display(const char *Productname, const char *Version) {
uint8_t buf[32];
u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r);
#ifdef HAS_DISPLAY
uint8_t buf[32];
u8x8.clear();
u8x8.setFlipMode(0);
u8x8.setInverseFont(1);
@ -418,8 +389,8 @@ void init_display(const char *Productname, const char *Version) {
DisplayKey(buf, 8, true);
delay(5000);
u8x8.clear();
#endif // HAS_DISPLAY
}
#endif // HAS_DISPLAY
/* begin Aruino SETUP ------------------------------------------------------------ */
@ -487,12 +458,21 @@ void setup() {
antenna_init();
#endif
#ifdef HAS_DISPLAY
// initialize display
init_display(PROGNAME, PROGVERSION);
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
u8x8.draw2x2String(0, 0, "PAX:0");
u8x8.setCursor(0,4);
u8x8.printf("WIFI: 0");
#ifdef BLECOUNTER
u8x8.setCursor(0,3);
u8x8.printf("BLTH: 0");
#endif
u8x8.setCursor(0,5);
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %d", cfg.rssilimit);
u8x8.drawString(0,6,"Join Wait ");
sprintf(display_lora, "Join wait");
#endif
// output LoRaWAN keys to console
#ifdef VERBOSE
@ -507,18 +487,16 @@ wifi_sniffer_init(); // setup wifi in monitor mode and start MAC counting
// note: do this *after* wifi has started, since gets it's seed from RF noise
salt_reset(); // get new 16bit for salting hashes
// Start FreeRTOS tasks
#if CONFIG_FREERTOS_UNICORE // run all tasks on core 0 and switch off core 1
ESP_LOGI(TAG, "Starting Lora task on core 0");
xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 0);
ESP_LOGI(TAG, "Starting Wifi task on core 0");
xTaskCreatePinnedToCore(wifi_sniffer_loop, "wifisniffer", 4096, ( void * ) 1, 1, NULL, 0);
// to come here: code for switching off core 1
#else // run wifi task on core 0 and lora task on core 1
// 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");
xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 1);
ESP_LOGI(TAG, "Starting Wifi task on core 0");
xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 4096, ( void * ) 1, 1, NULL, 0);
xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 16384, ( void * ) 1, 1, NULL, 0);
#ifdef BLECOUNTER
if (cfg.blescan) { // start BLE task only if BLE function is enabled in NVRAM configuration
ESP_LOGI(TAG, "Starting Bluetooth task on core 0");
xTaskCreatePinnedToCore(bt_loop, "btscan", 16384, NULL, 5, NULL, 0);
}
#endif
// Finally: kickoff first sendjob and join, then send initial payload "0000"
@ -534,20 +512,57 @@ do_send(&sendjob);
// Arduino main moop, runs on core 1
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
void loop() {
while(1) {
#ifdef HAS_BUTTON
uptimecounter = uptime() / 1000; // count uptime seconds
#ifdef HAS_BUTTON // ...then check if pressed
if (ButtonTriggered) {
ButtonTriggered = false;
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults");
eraseConfig();
esp_restart();
}
else
#endif
{ vTaskDelay(1000/portTICK_PERIOD_MS);
uptimecounter = uptime() / 1000; // count uptime seconds
}
}
#ifdef HAS_DISPLAY // ...then update mask
// 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
vTaskDelay(1000/DISPLAYFPS/portTICK_PERIOD_MS);
}
/* end Aruino LOOP ------------------------------------------------------------ */

View File

@ -1,7 +1,7 @@
#pragma once
// program version - note: increment version after modifications to configData_t struct!!
#define PROGVERSION "1.2.95" // use max 10 chars here!
#define PROGVERSION "1.3.01" // use max 10 chars here!
#define PROGNAME "PAXCNT"
// Verbose enables serial output
@ -12,7 +12,6 @@
#define BLECOUNTER 1 // comment out if you don't want BLE count
// BLE scan parameters
#define BLESCANCYCLE 2 // BLE scan once after each <BLECYCLE> wifi scans
#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
@ -47,6 +46,9 @@
// Default RGB LED luminosity (in %)
#define RGBLUMINOSITY 30 // 30%
// OLED Display refresh cycle (in Milliseconds)
#define DISPLAYFPS 5 // [fps] -> 5 Frames per second ps = 200ms refreseh cycle
// 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

View File

@ -58,9 +58,7 @@ void set_reset(int val) {
switch (val) {
case 0: // restart device
ESP_LOGI(TAG, "Remote command: restart device");
u8x8.clearLine(5);
u8x8.setCursor(0, 5);
u8x8.printf("Reset pending ");
sprintf(display_lora, "Reset pending");
vTaskDelay(10000/portTICK_PERIOD_MS); // wait for LMIC to confirm LoRa downlink to server
esp_restart();
break;
@ -72,16 +70,11 @@ void set_reset(int val) {
bles.clear(); // clear BLE macs container
#endif
salt_reset(); // get new 16bit salt
u8x8.clearLine(0); u8x8.clearLine(1); // clear Display counter
u8x8.clearLine(5);
u8x8.setCursor(0, 5);
u8x8.printf("Reset counter ");
sprintf(display_lora, "Reset counter");
break;
case 2: // reset device to factory settings
ESP_LOGI(TAG, "Remote command: reset device to factory settings");
u8x8.clearLine(5);
u8x8.setCursor(0, 5);
u8x8.printf("Factory reset ");
sprintf(display_lora, "Factory reset");
eraseConfig();
break;
}
@ -90,9 +83,6 @@ void set_reset(int val) {
void set_rssi(int val) {
cfg.rssilimit = val * -1;
ESP_LOGI(TAG, "Remote command: set RSSI limit to %i", cfg.rssilimit);
u8x8.clearLine(5);
u8x8.setCursor(0, 5);
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: -%4i", cfg.rssilimit);
};
void set_wifiscancycle(int val) {
@ -110,11 +100,6 @@ void set_blescantime(int val) {
ESP_LOGI(TAG, "Remote command: set BLE scan time to %i seconds", cfg.blescantime);
};
void set_blescancycle(int val) {
cfg.blescancycle = val;
ESP_LOGI(TAG, "Remote command: set BLE scan cycle to %i", cfg.blescancycle);
};
void set_countmode(int val) {
switch (val) {
case 0: // cyclic unconfirmed
@ -138,7 +123,6 @@ void set_screensaver(int val) {
case 1: cfg.screensaver = val; break;
default: cfg.screensaver = 0; break;
}
u8x8.setPowerSave(cfg.screensaver); // set display 0=on / 1=off
};
void set_display(int val) {
@ -147,7 +131,6 @@ void set_display(int val) {
case 1: cfg.screenon = val; break;
default: cfg.screenon = 0; break;
}
u8x8.setPowerSave(!cfg.screenon); // set display 0=on / 1=off
};
void set_lorasf(int val) {
@ -167,11 +150,14 @@ void set_loraadr(int val) {
void set_blescan(int val) {
ESP_LOGI(TAG, "Remote command: set BLE scan mode to %s", val ? "on" : "off");
switch (val) {
case 1: cfg.blescan = val; break;
default:
case 0:
cfg.blescan = 0;
btStop();
u8x8.clearLine(3); // clear BLE results from display
#ifdef BLECOUNTER
bles.clear(); // clear BLE macs container
#endif
break;
default:
cfg.blescan = 1;
break;
}
};
@ -187,6 +173,14 @@ void set_wifiant(int val) {
#endif
};
void set_vendorfilter(int val) {
ESP_LOGI(TAG, "Remote command: set vendorfilter mode to %s", val ? "on" : "off");
switch (val) {
case 1: cfg.vendorfilter = val; break;
default: cfg.vendorfilter = 0; break;
}
};
void set_rgblum(int val) {
// Avoid wrong parameters
cfg.rgblum = (val>=0 && val<=100) ? (uint8_t) val : RGBLUMINOSITY;
@ -241,17 +235,17 @@ void get_cputemp (int val) {
cmd_t table[] = {
{0x01, set_rssi, true},
{0x02, set_countmode, true},
{0x03, set_screensaver, true},
{0x03, set_noop, false},
{0x04, set_display, true},
{0x05, set_lorasf, true},
{0x06, set_lorapower, true},
{0x07, set_loraadr, true},
{0x08, set_noop, false},
{0x08, set_screensaver, true},
{0x09, set_reset, false},
{0x0a, set_wifiscancycle, true},
{0x0b, set_wifichancycle, true},
{0x0c, set_blescantime, true},
{0x0d, set_blescancycle, true},
{0x0d, set_vendorfilter, false},
{0x0e, set_blescan, true},
{0x0f, set_wifiant, true},
{0x10, set_rgblum, true},