Merge pull request #40 from cyberman54/development

Release v1.3.0
This commit is contained in:
Verkehrsrot 2018-04-16 11:18:00 +02:00 committed by GitHub
commit 01213934ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 515 additions and 352 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." 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 nkolban esp32 snippets
BLE Scan BLE GAP DUMP
https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils/tests/BLETests/Arduino/BLE_scan https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
under this Licence: under this Licence:

View File

@ -1,6 +1,8 @@
# ESP32-Paxcounter # ESP32-Paxcounter
**Wifi & Bluetooth driven, LoRaWAN enabled, battery powered mini Paxcounter built on cheap ESP32 boards** **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"> <img src="img/Paxcounter-title.jpg">
# Use case # 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: Currently supported IoT boards:
- Heltec LoRa-32 {1} - Heltec LoRa-32 {1}
- TTGOv1 {1} - TTGOv1 {1}
- TTGOv2 {1} - TTGOv2 {1}{4}
- Pycom LoPy {2} - Pycom LoPy {2}
- Pycom LoPy4 {2} - Pycom LoPy4 {2}
- LoLin32 with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora) {2}{3} - 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} - 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> 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> 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>: <b>Power consumption</b>:
- Heltec ~650mW - Heltec ~720mW
- TTGOv1 ~650mW - TTGOv1 TBD
- TTGOv2 ~670mW - TTGOv2 ~990mW
- LoPy with expansion board: ~530mW - LoPy with expansion board: ~690mW
- LoPy pure, without expansion board: ~460mW - LoPy pure, without expansion board: TBD
- LoLin32 with [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora): 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 - 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 # 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. 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) 1 ... 255 used for wifi and bluetooth scan radius (greater values increase scan radius, values 50...110 make sense)
0 = Wifi rssi limiter disabled [default] 0 = RSSI limiter disabled [default]
0x02 set counter mode 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 1 = cumulative counter, mac counter is never reset
2 = cyclic confirmed, like 0 but data is resent until confirmation by network received 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] 0 = screen saver off [default]
1 = screen saver on 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 0 ... 255 duration of a BLE scan cycle in seconds
e.g. 15 -> 1 cycle runs for 15 seconds [default] 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 0 = disabled (use to count devices, not people)
e.g. 2 -> BLE scan runs once after each 2nd wifi scan [default] 1 = enabled [default]
0x0E set BLE scan mode 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 9: Wifi scan cycle duration in seconds/2 (0..255)
byte 10: Wifi channel switch interval in seconds/100 (0..255) byte 10: Wifi channel switch interval in seconds/100 (0..255)
byte 11: BLE scan cycle duration in seconds (0..255) byte 11: BLE scan cycle duration in seconds (0..255)
byte 12: BLE scan frequency, do once after (0..255) full wifi scans byte 12: BLE scan mode (1=on, 0=0ff)
byte 13: BLE scan mode (1=on, 0=0ff) byte 13: Wifi antenna switch (0=internal, 1=external)
byte 14: Wifi antenna switch (0=internal, 1=external) byte 14: Vendorfilter mode (0=disabled, 1=enabled)
byte 15: RGB LED luminosity (0..100 %) byte 15: RGB LED luminosity (0..100 %)
bytes 16-25: Software version (ASCII format) bytes 16-25: Software version (ASCII format)

View File

@ -17,59 +17,53 @@ env_default = heltec_wifi_lora_32
;env_default = lopy4 ;env_default = lopy4
;env_default = lolin32lite_lora ;env_default = lolin32lite_lora
;env_default = lolin32_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] [env:heltec_wifi_lora_32]
platform = espressif32 platform = espressif32
board = heltec_wifi_lora_32 board = heltec_wifi_lora_32
framework = arduino framework = arduino
monitor_baud = 115200 monitor_baud = 115200
upload_speed = 921600 upload_speed = 115200
lib_deps = lib_deps =
U8g2 ${common_env_data.lib_deps_builtin}
ESP32 BLE Arduino@>=0.4.9
build_flags = build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework ${common_env_data.build_flags}
-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_
-Dheltec_wifi_lora_32 -Dheltec_wifi_lora_32
-include "src/main.h"
-include "src/hal/heltec.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] [env:ttgov1]
platform = espressif32 platform = espressif32
board = esp32dev board = esp32dev
framework = arduino framework = arduino
monitor_baud = 115200 monitor_baud = 115200
; On my V1, upload does not works over default 115200 upload_speed = 115200
upload_speed = 921600
;upload_port = COM15
lib_deps = lib_deps =
U8g2 ${common_env_data.lib_deps_builtin}
ESP32 BLE Arduino@>=0.4.9
build_flags = build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework ${common_env_data.build_flags}
-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
-Dttgov1 -Dttgov1
-D_lmic_config_h_
-include "src/main.h"
-include "src/hal/ttgov1.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] [env:ttgov2]
platform = espressif32 platform = espressif32
@ -78,23 +72,11 @@ framework = arduino
monitor_baud = 115200 monitor_baud = 115200
upload_speed = 921600 upload_speed = 921600
lib_deps = lib_deps =
U8g2 ${common_env_data.lib_deps_builtin}
ESP32 BLE Arduino@>=0.4.9
build_flags = build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework ${common_env_data.build_flags}
-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_
-Dttgov2 -Dttgov2
-include "src/main.h"
-include "src/hal/ttgov2.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] [env:lopy]
platform = espressif32 platform = espressif32
@ -103,24 +85,12 @@ framework = arduino
monitor_baud = 115200 monitor_baud = 115200
upload_speed = 921600 upload_speed = 921600
lib_deps = lib_deps =
U8g2@>2.21.7 ${common_env_data.lib_deps_builtin}
ESP32 BLE Arduino@>=0.4.9
SmartLeds SmartLeds
build_flags = build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework ${common_env_data.build_flags}
-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
-Dlopy -Dlopy
-D_lmic_config_h_
-include "src/main.h"
-include "src/hal/lopy.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] [env:lopy4]
platform = espressif32 platform = espressif32
@ -129,24 +99,12 @@ framework = arduino
monitor_baud = 115200 monitor_baud = 115200
upload_speed = 921600 upload_speed = 921600
lib_deps = lib_deps =
U8g2@>2.21.7 ${common_env_data.lib_deps_builtin}
ESP32 BLE Arduino@>=0.4.9 SmartLeds
SmartLeds
build_flags = build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework ${common_env_data.build_flags}
-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_
-Dlopy4 -Dlopy4
-include "src/main.h"
-include "src/hal/lopy4.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] [env:lolin32lite_lora]
platform = espressif32 platform = espressif32
@ -155,24 +113,12 @@ framework = arduino
monitor_baud = 115200 monitor_baud = 115200
upload_speed = 256000 upload_speed = 256000
lib_deps = lib_deps =
U8g2 ${common_env_data.lib_deps_builtin}
ESP32 BLE Arduino@>=0.4.9
SmartLeds SmartLeds
build_flags = build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework ${common_env_data.build_flags}
-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_
-Dlolin32lite_lora -Dlolin32lite_lora
-include "src/main.h"
-include "src/hal/lolin32lite_lora.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] [env:lolin32_lora]
platform = espressif32 platform = espressif32
@ -181,21 +127,9 @@ framework = arduino
monitor_baud = 115200 monitor_baud = 115200
upload_speed = 921600 upload_speed = 921600
lib_deps = lib_deps =
U8g2 ${common_env_data.lib_deps_builtin}
ESP32 BLE Arduino@>=0.4.9
SmartLeds SmartLeds
build_flags = build_flags =
;set log level, we need build_flag for this, otherwise we can't use ESP_LOGx in arduino framework ${common_env_data.build_flags}
-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_
-Dlolin32_lora -Dlolin32_lora
-include "src/main.h"
-include "src/hal/lolin32_lora.h" -include "src/hal/lolin32_lora.h"
;FreeRTOS single core operation, switches off core 1 (see arduino-esp32/cores/esp32/main.cpp)
; -DCONFIG_FREERTOS_UNICORE

292
src/blecsan.cpp Normal file
View 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

View File

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

View File

@ -33,9 +33,9 @@ typedef struct {
int8_t wifiscancycle; // wifi scan cycle [seconds/2] int8_t wifiscancycle; // wifi scan cycle [seconds/2]
int8_t wifichancycle; // wifi channel switch cycle [seconds/100] int8_t wifichancycle; // wifi channel switch cycle [seconds/100]
int8_t blescantime; // BLE scan cycle duration [seconds] 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 blescan; // 0=disabled, 1=enabled
int8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4) int8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
int8_t vendorfilter; // 0=disabled, 1=enabled
int8_t rgblum; // RGB Led luminosity (0..100%) int8_t rgblum; // RGB Led luminosity (0..100%)
char version[10]; // Firmware version char version[10]; // Firmware version
} configData_t; } configData_t;
@ -44,6 +44,7 @@ extern configData_t cfg;
extern uint8_t mydata[]; extern uint8_t mydata[];
extern uint64_t uptimecounter; extern uint64_t uptimecounter;
extern osjob_t sendjob; extern osjob_t sendjob;
extern char display_lora[], display_lmic[];
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;
extern bool joinstate; extern bool joinstate;
extern std::set<uint16_t> wifis; extern std::set<uint16_t> wifis;

View File

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

View File

@ -2,13 +2,6 @@
// Basic Config // Basic Config
#include "globals.h" #include "globals.h"
#ifdef BLECOUNTER
#include <BLEDevice.h>
//#include <BLEUtils.h>
//#include <BLEScan.h>
//#include <BLEAdvertisedDevice.h>
#endif
#ifdef VENDORFILTER #ifdef VENDORFILTER
#include <array> #include <array>
#include <algorithm> #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}; 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;
uint16_t salt_reset(void) { uint16_t salt_reset(void) {
@ -42,38 +34,40 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
#ifdef VENDORFILTER #ifdef VENDORFILTER
vendor2int = ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[1] << 8 ) | ( (uint32_t)paddr[0] << 16 ); vendor2int = ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[1] << 8 ) | ( (uint32_t)paddr[0] << 16 );
// 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() ) { if ( (sniff_type==MAC_SNIFF_BLE) || std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end() ) {
#endif #endif
// salt and hash MAC, and if new unique one, store identifier in container and increment counter on display // salt and hash MAC, and if new unique one, store identifier in container and increment counter on display
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization // https://en.wikipedia.org/wiki/MAC_Address_Anonymization
addr2int += (uint32_t) salt; // add 16-bit salt to pseudo MAC addr2int += (uint32_t) salt; // add 16-bit salt to pseudo MAC
snprintf(buff, sizeof(buff), "%08X", addr2int); // convert unsigned 32-bit salted MAC to 8 digit hex string snprintf(buff, sizeof(buff), "%08X", addr2int); // convert unsigned 32-bit salted MAC to 8 digit hex string
hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars to fit hash in uint16_t container hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars to fit hash in uint16_t container
auto newmac = macs.insert(hashedmac); // add hashed MAC to total container if new unique auto newmac = macs.insert(hashedmac); // add hashed MAC to total container if new unique
added = newmac.second ? true:false; // true if hashed MAC is unique in container added = newmac.second ? true:false; // true if hashed MAC is unique in container
// Insert only if it was not found on global count // Insert only if it was not found on global count
if (added) { if (added) {
if (sniff_type == MAC_SNIFF_WIFI ) {
rgb_set_color(COLOR_GREEN); if (sniff_type == MAC_SNIFF_WIFI ) {
wifis.insert(hashedmac); // add hashed MAC to wifi container if new unique rgb_set_color(COLOR_GREEN);
wifis.insert(hashedmac); // add hashed MAC to wifi container
} }
#ifdef BLECOUNTER #ifdef BLECOUNTER
else if (sniff_type == MAC_SNIFF_BLE ) { else if (sniff_type == MAC_SNIFF_BLE ) {
rgb_set_color(COLOR_MAGENTA); 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 #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", // Not sure user will have time to see the LED
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLE ", // 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, rssi, buff, hashedmac,
(int) wifis.size(), (int) wifis.size(),
#ifdef BLECOUNTER #ifdef BLECOUNTER
@ -81,12 +75,12 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
#else #else
0, 0,
#endif #endif
added ? "New" : "Already seen"); added ? "new" : "known");
#ifdef VENDORFILTER #ifdef VENDORFILTER
} else { } else {
// Very noisy // 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 #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) 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) { void wifi_sniffer_init(void) {
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM 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 { } else {
ESP_LOGI(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi, cfg.rssilimit); 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) */ uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
} wifi_ieee80211_packet_t; } wifi_ieee80211_packet_t;
extern uint16_t currentScanDevice;
uint16_t salt_reset(void); uint16_t salt_reset(void);
void BLECount();
void wifi_sniffer_init(void); void wifi_sniffer_init(void);
void wifi_sniffer_set_channel(uint8_t channel); void wifi_sniffer_set_channel(uint8_t channel);
void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);

View File

@ -45,6 +45,8 @@ configData_t cfg; // struct holds current device configuration
osjob_t sendjob, initjob; // LMIC osjob_t sendjob, initjob; // LMIC
// Initialize global variables // Initialize global variables
char display_lora[16], display_lmic[16];
uint8_t channel = 0;
int macnum = 0; int macnum = 0;
uint64_t uptimecounter = 0; uint64_t uptimecounter = 0;
bool joinstate = false; bool joinstate = false;
@ -215,9 +217,7 @@ void lorawan_loop(void * pvParameters) {
void antenna_select(const int8_t _ant); void antenna_select(const int8_t _ant);
#endif #endif
#ifdef BLECOUNTER #ifndef BLECOUNTER
void BLECount(void);
#else
bool btstop = btStop(); bool btstop = btStop();
#endif #endif
@ -253,11 +253,14 @@ void wifi_sniffer_init(void);
void wifi_sniffer_set_channel(uint8_t channel); void wifi_sniffer_set_channel(uint8_t channel);
void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
// defined in blescan.cpp
void bt_loop(void *ignore);
// Sniffer Task // Sniffer Task
void sniffer_loop(void * pvParameters) { void sniffer_loop(void * pvParameters) {
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
uint8_t channel=0; channel=0;
char buff[16]; char buff[16];
int nloop=0, lorawait=0; int nloop=0, lorawait=0;
@ -269,31 +272,10 @@ void sniffer_loop(void * pvParameters) {
yield(); yield();
channel = (channel % WIFI_CHANNEL_MAX) + 1; // rotates variable channel 1..WIFI_CHANNEL_MAX channel = (channel % WIFI_CHANNEL_MAX) + 1; // rotates variable channel 1..WIFI_CHANNEL_MAX
wifi_sniffer_set_channel(channel); wifi_sniffer_set_channel(channel);
ESP_LOGI(TAG, "Wifi set channel %d", channel); ESP_LOGD(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);
// duration of one wifi scan loop reached? then send data and begin new scan cycle // duration of one wifi scan loop reached? then send data and begin new scan cycle
if ( nloop >= ( (100 / cfg.wifichancycle) * (cfg.wifiscancycle * 2)) +1 ) { 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 nloop=0; channel=0; // reset wifi scan + channel loop counter
do_send(&sendjob); // Prepare and execute LoRaWAN data upload do_send(&sendjob); // Prepare and execute LoRaWAN data upload
vTaskDelay(500/portTICK_PERIOD_MS); vTaskDelay(500/portTICK_PERIOD_MS);
@ -307,15 +289,13 @@ void sniffer_loop(void * pvParameters) {
bles.clear(); // clear BLE macs counter bles.clear(); // clear BLE macs counter
#endif #endif
salt_reset(); // get new salt for salting hashes 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; lorawait = 0;
while(LMIC.opmode & OP_TXRXPEND) { while(LMIC.opmode & OP_TXRXPEND) {
if(!lorawait) if(!lorawait)
u8x8.drawString(0,6,"LoRa wait "); sprintf(display_lora, "LoRa wait");
lorawait++; lorawait++;
// in case sending really fails: reset and rejoin network // in case sending really fails: reset and rejoin network
if( (lorawait % MAXLORARETRY ) == 0) { if( (lorawait % MAXLORARETRY ) == 0) {
@ -325,26 +305,20 @@ void sniffer_loop(void * pvParameters) {
vTaskDelay(1000/portTICK_PERIOD_MS); vTaskDelay(1000/portTICK_PERIOD_MS);
yield(); 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 // TBD: need to check if long 2000ms pause causes stack problems while scanning continues
if (cfg.screenon && cfg.screensaver) { if (cfg.screenon && cfg.screensaver) {
vTaskDelay(2000/portTICK_PERIOD_MS); // pause for displaying results vTaskDelay(2000/portTICK_PERIOD_MS); // pause for displaying results
yield(); yield();
u8x8.setPowerSave(1 && cfg.screensaver); // set display off if screensaver is enabled u8x8.setPowerSave(1 && cfg.screensaver); // set display off if screensaver is enabled
} }
*/
} // end of send data cycle } // end of send data cycle
else { } // end of infinite wifi channel rotation loop
#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 wifi specific parts ------------------------------------------------------------ */ /* end wifi specific parts ------------------------------------------------------------ */
@ -490,9 +464,16 @@ void setup() {
// initialize display // initialize display
init_display(PROGNAME, PROGVERSION); init_display(PROGNAME, PROGVERSION);
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
u8x8.draw2x2String(0, 0, "PAX:0");
u8x8.setCursor(0,4);
u8x8.printf("WIFI: 0");
#ifdef BLECOUNTER
u8x8.setCursor(0,3);
u8x8.printf("BLTH: 0");
#endif
u8x8.setCursor(0,5); u8x8.setCursor(0,5);
u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %d", cfg.rssilimit); u8x8.printf(!cfg.rssilimit ? "RLIM: off" : "RLIM: %d", cfg.rssilimit);
u8x8.drawString(0,6,"Join Wait "); sprintf(display_lora, "Join wait");
// output LoRaWAN keys to console // output LoRaWAN keys to console
#ifdef VERBOSE #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 // note: do this *after* wifi has started, since gets it's seed from RF noise
salt_reset(); // get new 16bit for salting hashes salt_reset(); // get new 16bit for salting hashes
// Start FreeRTOS tasks // run wifi task on core 0 and lora task on core 1 and bt task on core 0
#if CONFIG_FREERTOS_UNICORE // run all tasks on core 0 and switch off core 1 ESP_LOGI(TAG, "Starting Lora task on core 1");
ESP_LOGI(TAG, "Starting Lora task on core 0"); xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 1);
xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 0); ESP_LOGI(TAG, "Starting Wifi task on core 0");
ESP_LOGI(TAG, "Starting Wifi task on core 0"); xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 16384, ( void * ) 1, 1, NULL, 0);
xTaskCreatePinnedToCore(wifi_sniffer_loop, "wifisniffer", 4096, ( void * ) 1, 1, NULL, 0); #ifdef BLECOUNTER
// to come here: code for switching off core 1 if (cfg.blescan) { // start BLE task only if BLE function is enabled in NVRAM configuration
#else // run wifi task on core 0 and lora task on core 1 ESP_LOGI(TAG, "Starting Bluetooth task on core 0");
ESP_LOGI(TAG, "Starting Lora task on core 1"); xTaskCreatePinnedToCore(bt_loop, "btscan", 16384, NULL, 5, NULL, 0);
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);
#endif #endif
// Finally: kickoff first sendjob and join, then send initial payload "0000" // 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 // Arduino main moop, runs on core 1
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/ // https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
void loop() { void loop() {
while(1) {
#ifdef HAS_BUTTON uptimecounter = uptime() / 1000; // count uptime seconds
if (ButtonTriggered) {
ButtonTriggered = false; #ifdef HAS_BUTTON // ...then check if pressed
ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults"); if (ButtonTriggered) {
eraseConfig(); ButtonTriggered = false;
esp_restart(); ESP_LOGI(TAG, "Button pressed, resetting device to factory defaults");
eraseConfig();
esp_restart();
} }
else #endif
#endif
{ vTaskDelay(1000/portTICK_PERIOD_MS); #ifdef HAS_DISPLAY // ...then update mask
uptimecounter = uptime() / 1000; // count uptime seconds
} // 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 ------------------------------------------------------------ */ /* end Aruino LOOP ------------------------------------------------------------ */

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
// program version - note: increment version after modifications to configData_t struct!! // program version - note: increment version after modifications to configData_t struct!!
#define PROGVERSION "1.2.95" // use max 10 chars here! #define PROGVERSION "1.3.0" // use max 10 chars here!
#define PROGNAME "PAXCNT" #define PROGNAME "PAXCNT"
// Verbose enables serial output // Verbose enables serial output
@ -12,7 +12,6 @@
#define BLECOUNTER 1 // comment out if you don't want BLE count #define BLECOUNTER 1 // comment out if you don't want BLE count
// BLE scan parameters // BLE scan parameters
#define BLESCANCYCLE 2 // BLE scan once after each <BLECYCLE> wifi scans
#define BLESCANTIME 11 // [seconds] scan duration, see note below #define BLESCANTIME 11 // [seconds] scan duration, see note below
#define BLESCANWINDOW 10 // [milliseconds] scan window, see below, 3 .. 10240, default 10 #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 #define BLESCANINTERVAL 10 // [milliseconds] how long to wait between scans, 3 .. 10240, default 10
@ -47,6 +46,9 @@
// Default RGB LED luminosity (in %) // Default RGB LED luminosity (in %)
#define RGBLUMINOSITY 30 // 30% #define RGBLUMINOSITY 30 // 30%
// OLED Display refresh cycle (in Milliseconds)
#define DISPLAYFPS 5 // [fps] -> 5 Frames per second ps = 200ms refreseh cycle
// LMIC settings // LMIC settings
// define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored // define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored
// define hardware specifics settings in platformio.ini as build_flag for hardware environment // define hardware specifics settings in platformio.ini as build_flag for hardware environment

View File

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