CWA detection (experimental)
This commit is contained in:
parent
2c15b29255
commit
c014824667
@ -15,11 +15,6 @@
|
||||
#error HAS_SDCARD unknown card reader value, must be either 1 or 2
|
||||
#endif
|
||||
#endif
|
||||
// Pins for SD-card
|
||||
#define SDCARD_CS (13)
|
||||
#define SDCARD_MOSI (15)
|
||||
#define SDCARD_MISO (2)
|
||||
#define SDCARD_SCLK (14)
|
||||
|
||||
#ifdef HAS_SDS011
|
||||
#include "sds011read.h"
|
||||
@ -45,7 +40,7 @@
|
||||
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"
|
||||
#define SDCARD_FILE_NAME "paxcount.%02d"
|
||||
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
#define SDCARD_FILE_HEADER_CWA ",cwa"
|
||||
#endif
|
||||
|
||||
|
@ -37,16 +37,16 @@ halfile = generic.h
|
||||
|
||||
[platformio]
|
||||
; upload firmware to board with usb cable
|
||||
;default_envs = usb
|
||||
default_envs = usb
|
||||
; upload firmware to a jfrog bintray repository
|
||||
;default_envs = ota
|
||||
; use latest versions of libraries
|
||||
default_envs = dev
|
||||
;default_envs = dev
|
||||
description = Paxcounter is a device for metering passenger flows in realtime. It counts how many mobile devices are around.
|
||||
|
||||
[common]
|
||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
||||
release_version = 1.9.996
|
||||
release_version = 2.0.1
|
||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
||||
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||
debug_level = 4
|
||||
@ -61,19 +61,19 @@ display_library = ; set by build.py and taken from hal file
|
||||
lib_deps_lora =
|
||||
MCCI LoRaWAN LMIC library@3.2.0 ; MCCI LMIC by Terrill Moore
|
||||
lib_deps_display =
|
||||
OneBitDisplay@1.5.0
|
||||
OneBitDisplay@1.7.1
|
||||
QRCode@0.0.1
|
||||
BitBang_I2C@2.1.1
|
||||
TFT_eSPI@>=2.2.8
|
||||
TFT_eSPI@>=2.2.18
|
||||
lib_deps_ledmatrix =
|
||||
Ultrathin_LED_Matrix@>=1.0.0
|
||||
lib_deps_rgbled =
|
||||
SmartLeds@>=1.2.0
|
||||
SmartLeds@>=1.2.1
|
||||
lib_deps_gps =
|
||||
1655@>=1.0.2 ; #1655 TinyGPSPlus by Mikal Hart
|
||||
lib_deps_sensors =
|
||||
Adafruit Unified Sensor@>=1.1.4
|
||||
Adafruit BME280 Library@>=2.0.2
|
||||
Adafruit BME280 Library@>=2.1.0
|
||||
Adafruit BMP085 Library@>=1.1.0
|
||||
BSEC Software Library@1.5.1474
|
||||
https://github.com/ricki-z/SDS011.git
|
||||
|
@ -6,8 +6,10 @@
|
||||
#define BT_BD_ADDR_HEX(addr) \
|
||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
// checking for CWAs we need this magic bytes:
|
||||
static const char cwaMagicBytes[] = "\x03\x03\x6F\xfd";
|
||||
// UUID of Exposure Notification Service (ENS)
|
||||
// see
|
||||
// https://blog.google/documents/70/Exposure_Notification_-_Bluetooth_Specification_v1.2.2.pdf
|
||||
static const char ensMagicBytes[] = "\x03\x03\x6F\xfd";
|
||||
|
||||
// local Tag for logging
|
||||
static const char TAG[] = "bluetooth";
|
||||
@ -161,18 +163,15 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
|
||||
// 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);
|
||||
|
||||
#if (COUNT_CWA)
|
||||
// we can call the cwa-functions now
|
||||
// because we use the hashed max-value
|
||||
// done in mac_add()
|
||||
#if (COUNT_ENS)
|
||||
// we can call the ens functions now using hashed max-value in mac_add()
|
||||
|
||||
// check for CWA-signature
|
||||
if ( 0 == strncmp( (const char*)p->scan_rst.ble_adv, cwaMagicBytes , 4) ) {
|
||||
cwa_mac_add( p->scan_rst.bda);
|
||||
}
|
||||
// check for ens signature
|
||||
if (0 == strncmp((const char *)p->scan_rst.ble_adv, ensMagicBytes, 4)) {
|
||||
cwa_mac_add(p->scan_rst.bda);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* to be improved in vendorfilter if:
|
||||
// you can search for elements in the payload using the
|
||||
// function esp_ble_resolve_adv_data()
|
||||
|
@ -1,85 +0,0 @@
|
||||
// routines for counting the number of available Corona Warn Apps (CWA)
|
||||
|
||||
// copied from https://github.com/kmetz/BLEExposureNotificationBeeper
|
||||
// (c) by Kaspar Metz
|
||||
// modified for use in the Paxcounter by AQ
|
||||
|
||||
#if (COUNT_CWA)
|
||||
|
||||
// Local logging tag
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
#define BT_BD_ADDR_HEX(addr) \
|
||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
#include "corona.h"
|
||||
|
||||
// taken from macsniff.cpp
|
||||
extern uint16_t salt;
|
||||
extern uint16_t hashedmac;
|
||||
|
||||
// When to forget old senders.
|
||||
#define FORGET_AFTER_MINUTES 2
|
||||
|
||||
static std::map<uint16_t, unsigned long> cwaSeenNotifiers;
|
||||
|
||||
|
||||
/**
|
||||
* Remove notifiers last seen over FORGET_AFTER_MINUTES ago.
|
||||
*/
|
||||
void cwa_clear() {
|
||||
ESP_LOGD(TAG, "CWA: forget old notifier: %d", cwaSeenNotifiers.size());
|
||||
|
||||
//#ifdef SOME_FORM_OF_DEBUG
|
||||
for (auto const ¬ifier : cwaSeenNotifiers) {
|
||||
ESP_LOGI(TAG, "CWA forget <%X>", notifier.first);
|
||||
// }
|
||||
}
|
||||
//#endif
|
||||
/* clear everything,
|
||||
* otherwise we will count the same device again
|
||||
* as in the next cycle it will get a differetn hash-value
|
||||
*/
|
||||
cwaSeenNotifiers.clear();
|
||||
}
|
||||
|
||||
/* return the numbers of active CWAs found
|
||||
*/
|
||||
uint16_t cwa_report(void) {
|
||||
return cwaSeenNotifiers.size();
|
||||
}
|
||||
|
||||
bool cwa_init(void)
|
||||
{
|
||||
ESP_LOGD(TAG, "init of BLE-scanner for CWA");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// similar to mac_add(), found in macsniff.cpp
|
||||
// for comments pls. look into this function
|
||||
bool cwa_mac_add(uint8_t* paddr) {
|
||||
|
||||
// are we too early?
|
||||
if ( hashedmac <= 0 )
|
||||
return false; // YES -> return
|
||||
|
||||
bool added = false;
|
||||
ESP_LOGD(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
BT_BD_ADDR_HEX(paddr));
|
||||
|
||||
ESP_LOGD(TAG, "hasehd mac = %X, count = %d (total=%d)", hashedmac, cwaSeenNotifiers.count(hashedmac), cwaSeenNotifiers.size());
|
||||
added = !(cwaSeenNotifiers.count(hashedmac) > 0);
|
||||
|
||||
// Count only if MAC was not yet seen
|
||||
if (added) {
|
||||
ESP_LOGD(TAG, "added device with active CWA");
|
||||
}
|
||||
|
||||
cwaSeenNotifiers[hashedmac] = millis(); // last seen at ....
|
||||
|
||||
// True if MAC WiFi/BLE was new
|
||||
return added;
|
||||
}
|
||||
|
||||
#endif
|
81
src/corona.cpp
Normal file
81
src/corona.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
// routines for counting the number of devices which advertise Exposure
|
||||
// Notification Service e.g. "Corona Warn App" in Germany
|
||||
|
||||
// copied from https://github.com/kmetz/BLEExposureNotificationBeeper
|
||||
// (c) by Kaspar Metz
|
||||
// modified for use in the Paxcounter by AQ
|
||||
|
||||
#if (COUNT_ENS)
|
||||
|
||||
// Local logging tag
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
#define BT_BD_ADDR_HEX(addr) \
|
||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
#include "corona.h"
|
||||
|
||||
// taken from macsniff.cpp
|
||||
extern uint16_t salt;
|
||||
extern uint16_t hashedmac;
|
||||
|
||||
// When to forget old senders.
|
||||
#define FORGET_AFTER_MINUTES 2
|
||||
|
||||
// array of timestamps for seen notifiers
|
||||
static std::map<uint16_t, unsigned long> cwaSeenNotifiers;
|
||||
|
||||
// Remove notifiers last seen over FORGET_AFTER_MINUTES ago.
|
||||
void cwa_clear() {
|
||||
ESP_LOGD(TAG, "CWA: forget old notifier: %d", cwaSeenNotifiers.size());
|
||||
|
||||
/*
|
||||
#ifdef SOME_FORM_OF_DEBUG
|
||||
for (auto const ¬ifier : cwaSeenNotifiers) {
|
||||
ESP_LOGD(TAG, "CWA forget <%X>", notifier.first);
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
// clear everything, otherwise we would count the same device again, as in the
|
||||
// next cycle it likely will advertise with a different hash-value
|
||||
cwaSeenNotifiers.clear();
|
||||
}
|
||||
|
||||
// return the total number of devices seen advertising ENS
|
||||
uint16_t cwa_report(void) { return cwaSeenNotifiers.size(); }
|
||||
|
||||
bool cwa_init(void) {
|
||||
ESP_LOGD(TAG, "init BLE-scanner for ENS");
|
||||
return true;
|
||||
}
|
||||
|
||||
// similar to mac_add(), found in macsniff.cpp
|
||||
// for comments pls. look into this function
|
||||
bool cwa_mac_add(uint8_t *paddr) {
|
||||
|
||||
// are we too early?
|
||||
if (!hashedmac)
|
||||
return false; // YES -> return
|
||||
|
||||
bool added = false;
|
||||
ESP_LOGD(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
BT_BD_ADDR_HEX(paddr));
|
||||
|
||||
ESP_LOGD(TAG, "hashed ENS mac = %X, ENS count = %d (total=%d)", hashedmac,
|
||||
cwaSeenNotifiers.count(hashedmac), cwaSeenNotifiers.size());
|
||||
added = !(cwaSeenNotifiers.count(hashedmac) > 0);
|
||||
|
||||
// Count only if this ENS MAC was not yet seen
|
||||
if (added) {
|
||||
ESP_LOGD(TAG, "added device with active ENS");
|
||||
}
|
||||
|
||||
cwaSeenNotifiers[hashedmac] = millis(); // last seen at ....
|
||||
|
||||
// True if MAC WiFi/BLE was new
|
||||
return added;
|
||||
}
|
||||
|
||||
#endif
|
@ -265,11 +265,10 @@ void dp_drawPage(time_t t, bool nextpage) {
|
||||
else
|
||||
dp_printf("WIFI:off");
|
||||
if (cfg.blescan)
|
||||
#if !(COUNT_CWA)
|
||||
#if (!COUNT_ENS)
|
||||
dp_printf("BLTH:%-5d", macs_ble);
|
||||
#else
|
||||
dp_printf("BLTH:%-5d", macs_ble);
|
||||
dp_printf("(CWA:%d)", cwa_report());
|
||||
dp_printf(" CWA:%-5d", cwa_report());
|
||||
#endif
|
||||
else
|
||||
dp_printf(" BLTH:off");
|
||||
@ -281,10 +280,10 @@ void dp_drawPage(time_t t, bool nextpage) {
|
||||
#elif ((!WIFICOUNTER) && (BLECOUNTER))
|
||||
if (cfg.blescan) {
|
||||
dp_printf("BLTH:%-5d", macs_ble);
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
dp_printf("(CWA:%d)", cwa_report());
|
||||
#endif
|
||||
} else
|
||||
} else
|
||||
dp_printf("BLTH:off");
|
||||
#else
|
||||
dp_printf("Sniffer disabled");
|
||||
@ -357,7 +356,7 @@ void dp_drawPage(time_t t, bool nextpage) {
|
||||
|
||||
#if (HAS_LORA)
|
||||
|
||||
// 3|NtwkID:000000 TXpw:aa
|
||||
// 3|NetID:000000 PWR:aa
|
||||
// 4|DevAdd:00000000 DR:0
|
||||
// 5|CHMsk:0000 Nonce:0000
|
||||
// 6|CUp:000000 CDn:000000
|
||||
@ -365,8 +364,7 @@ void dp_drawPage(time_t t, bool nextpage) {
|
||||
|
||||
dp_setFont(MY_FONT_SMALL);
|
||||
dp_setTextCursor(0, 3);
|
||||
dp_printf("NetwID:%06X TXpw:%-2d", LMIC.netid & 0x001FFFFF,
|
||||
LMIC.radio_txpow);
|
||||
dp_printf("NetID:%06X PWR:%-2d", LMIC.netid & 0x001FFFFF, LMIC.radio_txpow);
|
||||
dp_println();
|
||||
dp_printf("DevAdd:%08X DR:%1d", LMIC.devaddr, LMIC.datarate);
|
||||
dp_println();
|
||||
|
@ -11,8 +11,8 @@
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
// used here and in corona.cpp
|
||||
uint16_t salt = -1;
|
||||
uint16_t hashedmac = -1; // temporary buffer for generated hash value
|
||||
uint16_t salt = 0;
|
||||
uint16_t hashedmac = 0; // temporary buffer for generated hash value
|
||||
|
||||
uint16_t get_salt(void) {
|
||||
salt = (uint16_t)random(65536); // get new 16bit random for salting hashes
|
||||
@ -52,8 +52,8 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
||||
|
||||
char buff[10]; // temporary buffer for printf
|
||||
bool added = false;
|
||||
int8_t beaconID; // beacon number in test monitor mode
|
||||
uint32_t *mac; // temporary buffer for shortened MAC
|
||||
int8_t beaconID; // beacon number in test monitor mode
|
||||
uint32_t *mac; // temporary buffer for shortened MAC
|
||||
|
||||
// only last 3 MAC Address bytes are used for MAC address anonymization
|
||||
// but since it's uint32 we take 4 bytes to avoid 1st value to be 0.
|
||||
@ -117,17 +117,17 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
||||
} // added
|
||||
|
||||
// Log scan result
|
||||
ESP_LOGV(TAG,
|
||||
ESP_LOGD(TAG,
|
||||
"%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d "
|
||||
"BLTH:%d "
|
||||
#if (COUNT_CWA)
|
||||
"(CWA:%d)"
|
||||
#if (COUNT_ENS)
|
||||
"(CWA:%d)"
|
||||
#endif
|
||||
"-> %d Bytes left",
|
||||
added ? "new " : "known",
|
||||
sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff,
|
||||
hashedmac, macs_wifi, macs_ble,
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
cwa_report(),
|
||||
#endif
|
||||
getFreeRAM());
|
||||
|
@ -313,7 +313,7 @@ void setup() {
|
||||
// initialize sensors
|
||||
#if (HAS_SENSORS)
|
||||
#if (HAS_SENSOR_1)
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
ESP_LOGI(TAG, "init CWA-counter");
|
||||
if ( cwa_init() )
|
||||
strcat_P(features, " CWA");
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
// Set this to include BLE counting and vendor filter functions, or to switch off WIFI counting
|
||||
#define VENDORFILTER 1 // set to 0 if you want to count things, not people
|
||||
#define BLECOUNTER 0 // set it to 1 if you want to use BLE count, at expense of power & memory
|
||||
#define BLECOUNTER 1 // set it to 1 if you want to use BLE count, at expense of power & memory
|
||||
#define WIFICOUNTER 1 // set it to 0 if you want to switch off WIFI count
|
||||
|
||||
// BLE scan parameters
|
||||
@ -24,11 +24,12 @@
|
||||
#define BLESCANWINDOW 80 // [milliseconds] scan window, see below, 3 .. 10240, default 80ms
|
||||
#define BLESCANINTERVAL 80 // [illiseconds] scan interval, see below, 3 .. 10240, default 80ms = 100% duty cycle
|
||||
|
||||
#define COUNT_CWA 0 // count found copies of the Corona Warn App (CWA)
|
||||
// set to 0 if you do not want to count these apps
|
||||
// Corona Exposure Notification Service(ENS) counter
|
||||
#define COUNT_ENS 1 // count found number of devices which advertise Exposure Notification Service
|
||||
// set to 0 if you do not want to count these devices
|
||||
|
||||
// for additional sensors (added by some user)
|
||||
#define HAS_SENSOR_1 0 // set to 1 if you want to count CWAs
|
||||
#define HAS_SENSOR_1 1 // set to 1 if you want to count CWAs
|
||||
#define HAS_SENSOR_2 0 // not used
|
||||
#define HAS_SENSOR_3 0 // not used
|
||||
#define HAS_SENSORS (HAS_SENSOR_1 || HAS_SENSOR_2 || HAS_SENSOR_3) // to simplify things
|
||||
@ -82,8 +83,8 @@
|
||||
#define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds]
|
||||
|
||||
// settings for syncing time of node with a time source (network / gps / rtc / timeserver)
|
||||
#define TIME_SYNC_LORAWAN 1 // set to 1 to use LORA network as time source, 0 means off [default = 1]
|
||||
#define TIME_SYNC_LORASERVER 0 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0]
|
||||
#define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 1]
|
||||
#define TIME_SYNC_LORASERVER 1 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0]
|
||||
#define TIME_SYNC_INTERVAL 60 // sync time attempt each .. minutes from time source [default = 60], 0 means off
|
||||
#define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off
|
||||
#define TIME_SYNC_SAMPLES 1 // number of time requests for averaging, max. 255
|
||||
|
@ -56,7 +56,7 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle, __attribute__((unused)) ui
|
||||
fileSDCard.print(tempBuffer);
|
||||
sprintf(tempBuffer, "%d,%d", noWifi, noBle);
|
||||
fileSDCard.print(tempBuffer);
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
sprintf(tempBuffer, ",%d", noBleCWA);
|
||||
fileSDCard.print(tempBuffer);
|
||||
#endif
|
||||
@ -102,7 +102,7 @@ void createFile(void) {
|
||||
if (fileSDCard) {
|
||||
ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename);
|
||||
fileSDCard.print(SDCARD_FILE_HEADER);
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
fileSDCard.print(SDCARD_FILE_HEADER_CWA); // for Corona-data (CWA)
|
||||
#endif
|
||||
#if (HAS_SDS011)
|
||||
|
@ -58,7 +58,7 @@ void SendPayload(uint8_t port, sendprio_t prio) {
|
||||
#if (HAS_SDCARD)
|
||||
if ( port == COUNTERPORT ) {
|
||||
sdcardWriteData(macs_wifi, macs_ble
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
, cwa_report()
|
||||
#endif
|
||||
);
|
||||
@ -154,7 +154,7 @@ void sendData() {
|
||||
payload.reset();
|
||||
payload.addSensor(sensor_read(1));
|
||||
SendPayload(SENSOR1PORT, prio_normal);
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
cwa_clear();
|
||||
#endif
|
||||
break;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "globals.h"
|
||||
#include "sensor.h"
|
||||
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
#include "payload.h"
|
||||
#include "corona.h"
|
||||
#include "macsniff.h"
|
||||
@ -55,7 +55,7 @@ uint8_t *sensor_read(uint8_t sensor) {
|
||||
case 1:
|
||||
|
||||
// insert user specific sensor data frames here */
|
||||
#if (COUNT_CWA)
|
||||
#if (COUNT_ENS)
|
||||
payload.addCount( cwa_report(), MAC_SNIFF_BLE_CWA);
|
||||
#else
|
||||
buf[0] = length;
|
||||
|
Loading…
Reference in New Issue
Block a user