commit
01213934ce
8
LICENSE
8
LICENSE
@ -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:
|
||||
|
||||
|
38
README.md
38
README.md
@ -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 TX’ing, OLED display off, 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
|
||||
|
||||
@ -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
|
||||
@ -163,10 +165,10 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
||||
0 ... 255 duration of a BLE scan cycle in seconds
|
||||
e.g. 15 -> 1 cycle runs for 15 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)
|
||||
|
||||
|
144
platformio.ini
144
platformio.ini
@ -17,59 +17,53 @@ 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]
|
||||
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_INFO
|
||||
; -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
|
||||
; -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"
|
||||
;
|
||||
lib_deps_builtin =
|
||||
U8g2@2.22.10
|
||||
|
||||
|
||||
[env:heltec_wifi_lora_32]
|
||||
platform = espressif32
|
||||
board = heltec_wifi_lora_32
|
||||
framework = arduino
|
||||
monitor_baud = 115200
|
||||
upload_speed = 921600
|
||||
upload_speed = 115200
|
||||
lib_deps =
|
||||
U8g2
|
||||
ESP32 BLE Arduino@>=0.4.9
|
||||
${common_env_data.lib_deps_builtin}
|
||||
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
|
||||
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_builtin}
|
||||
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
|
||||
@ -78,23 +72,11 @@ framework = arduino
|
||||
monitor_baud = 115200
|
||||
upload_speed = 921600
|
||||
lib_deps =
|
||||
U8g2
|
||||
ESP32 BLE Arduino@>=0.4.9
|
||||
${common_env_data.lib_deps_builtin}
|
||||
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
|
||||
@ -103,24 +85,12 @@ framework = arduino
|
||||
monitor_baud = 115200
|
||||
upload_speed = 921600
|
||||
lib_deps =
|
||||
U8g2@>2.21.7
|
||||
ESP32 BLE Arduino@>=0.4.9
|
||||
${common_env_data.lib_deps_builtin}
|
||||
SmartLeds
|
||||
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
|
||||
@ -129,24 +99,12 @@ framework = arduino
|
||||
monitor_baud = 115200
|
||||
upload_speed = 921600
|
||||
lib_deps =
|
||||
U8g2@>2.21.7
|
||||
ESP32 BLE Arduino@>=0.4.9
|
||||
SmartLeds
|
||||
${common_env_data.lib_deps_builtin}
|
||||
SmartLeds
|
||||
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
|
||||
@ -155,24 +113,12 @@ framework = arduino
|
||||
monitor_baud = 115200
|
||||
upload_speed = 256000
|
||||
lib_deps =
|
||||
U8g2
|
||||
ESP32 BLE Arduino@>=0.4.9
|
||||
${common_env_data.lib_deps_builtin}
|
||||
SmartLeds
|
||||
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
|
||||
@ -181,21 +127,9 @@ framework = arduino
|
||||
monitor_baud = 115200
|
||||
upload_speed = 921600
|
||||
lib_deps =
|
||||
U8g2
|
||||
ESP32 BLE Arduino@>=0.4.9
|
||||
${common_env_data.lib_deps_builtin}
|
||||
SmartLeds
|
||||
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
|
||||
-include "src/hal/lolin32_lora.h"
|
292
src/blecsan.cpp
Normal file
292
src/blecsan.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
#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
|
||||
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
|
@ -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
|
||||
|
@ -33,9 +33,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 +44,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;
|
||||
@ -57,5 +58,5 @@ extern std::set<uint16_t> macs;
|
||||
|
||||
#ifdef BLECOUNTER
|
||||
extern int scanTime;
|
||||
extern std::set<uint16_t> bles;
|
||||
extern std::set<uint16_t> bles;
|
||||
#endif
|
||||
|
@ -65,7 +65,7 @@ void get_hard_deveui(uint8_t *pdeveui) {
|
||||
Wire.requestFrom(MCP_24AA02E64_I2C_ADDRESS, 8);
|
||||
while (Wire.available()) {
|
||||
data = Wire.read();
|
||||
sprintf(deveui+strlen(deveui), "%02X ", data) ;
|
||||
sprintf(deveui+strlen(deveui), "%02X ", data);
|
||||
*pdeveui++ = data;
|
||||
}
|
||||
i2c_ret = Wire.endTransmission();
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
124
src/macsniff.cpp
124
src/macsniff.cpp
@ -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,38 +34,40 @@ 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
|
||||
|
||||
// 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
|
||||
// salt and hash MAC, and if new unique one, store identifier in container and increment counter on display
|
||||
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
|
||||
|
||||
addr2int += (uint32_t) salt; // add 16-bit salt to pseudo MAC
|
||||
snprintf(buff, sizeof(buff), "%08X", addr2int); // convert unsigned 32-bit salted MAC to 8 digit hex string
|
||||
hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars to fit hash in uint16_t container
|
||||
auto newmac = macs.insert(hashedmac); // add hashed MAC to total container if new unique
|
||||
added = newmac.second ? true:false; // true if hashed MAC is unique in container
|
||||
addr2int += (uint32_t) salt; // add 16-bit salt to pseudo MAC
|
||||
snprintf(buff, sizeof(buff), "%08X", addr2int); // convert unsigned 32-bit salted MAC to 8 digit hex string
|
||||
hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars to fit hash in uint16_t container
|
||||
auto newmac = macs.insert(hashedmac); // add hashed MAC to total container if new unique
|
||||
added = newmac.second ? true:false; // true if hashed MAC is unique in container
|
||||
|
||||
// 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
|
||||
}
|
||||
#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
|
||||
// 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
|
||||
}
|
||||
#ifdef BLECOUNTER
|
||||
else if (sniff_type == MAC_SNIFF_BLE ) {
|
||||
rgb_set_color(COLOR_MAGENTA);
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "%s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLE:%d %s",
|
||||
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLE ",
|
||||
// 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",
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
153
src/main.cpp
153
src/main.cpp
@ -45,6 +45,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;
|
||||
@ -215,9 +217,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 +253,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 +272,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 +289,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 +305,20 @@ void sniffer_loop(void * pvParameters) {
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
yield();
|
||||
}
|
||||
|
||||
u8x8.clearLine(6);
|
||||
|
||||
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
|
||||
|
||||
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 ------------------------------------------------------------ */
|
||||
@ -490,9 +464,16 @@ void setup() {
|
||||
// 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");
|
||||
|
||||
// output LoRaWAN keys to console
|
||||
#ifdef VERBOSE
|
||||
@ -507,18 +488,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
|
||||
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);
|
||||
// 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", 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 +513,56 @@ 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
|
||||
if (ButtonTriggered) {
|
||||
ButtonTriggered = false;
|
||||
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults");
|
||||
eraseConfig();
|
||||
esp_restart();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#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
|
||||
if (cfg.blescan) {
|
||||
u8x8.setCursor(0,3);
|
||||
u8x8.printf("BLTH: %-4d", (int) bles.size());
|
||||
}
|
||||
#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 ------------------------------------------------------------ */
|
||||
|
@ -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.0" // 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
|
||||
|
@ -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) {
|
||||
@ -171,7 +154,6 @@ void set_blescan(int val) {
|
||||
default:
|
||||
cfg.blescan = 0;
|
||||
btStop();
|
||||
u8x8.clearLine(3); // clear BLE results from display
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -187,6 +169,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 +231,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},
|
||||
|
Loading…
Reference in New Issue
Block a user