Merge pull request #631 from cyberman54/CWA
Covid-19 exposure notifications system scanning function
This commit is contained in:
commit
81879c23f6
16
README.md
16
README.md
@ -200,12 +200,24 @@ Paxcounter can keep it's time-of-day synced with an external time source. Set *#
|
|||||||
Paxcounter can be used to sync a wall clock which has a DCF77 or IF482 time telegram input. Set *#define HAS_IF482* or *#define HAS_DCF77* in board's hal file to setup clock controller. Use case of this function is to integrate paxcounter and clock. Accurary of the synthetic DCF77 signal depends on accuracy of on board's time base, see above.
|
Paxcounter can be used to sync a wall clock which has a DCF77 or IF482 time telegram input. Set *#define HAS_IF482* or *#define HAS_DCF77* in board's hal file to setup clock controller. Use case of this function is to integrate paxcounter and clock. Accurary of the synthetic DCF77 signal depends on accuracy of on board's time base, see above.
|
||||||
|
|
||||||
# mobile PaxCounter via https://opensensemap.org/
|
# mobile PaxCounter via https://opensensemap.org/
|
||||||
|
|
||||||
This describes how to set up a mobile PaxCounter:
|
This describes how to set up a mobile PaxCounter:
|
||||||
Follow all steps so far for preparing the device, use the packed payload format. In paxcounter.conf set PAYLOAD_OPENSENSEBOX to 1. Register a new sensbox on https://opensensemap.org/.
|
Follow all steps so far for preparing the device, use the packed payload format. In [paxcounter.conf](src/paxcounter.conf) set PAYLOAD_OPENSENSEBOX to 1. Register a new sensbox on https://opensensemap.org/.
|
||||||
There in the sensor configuration select "TheThingsNetwork" and set Decoding Profil to "LoRa serialization", enter your TTN Application and Device Id. Decoding option has to be
|
There in the sensor configuration select "TheThingsNetwork" and set Decoding Profil to "LoRa serialization", enter your TTN Application and Device Id. Decoding option has to be
|
||||||
[{"decoder":"latLng"},{"decoder":"uint16","sensor_id":"yoursensorid"}]
|
[{"decoder":"latLng"},{"decoder":"uint16","sensor_id":"yoursensorid"}]
|
||||||
|
|
||||||
|
# Covid-19 Exposure Notification System beacon detection (Germany: "Corona Warn App counter")
|
||||||
|
|
||||||
|
Bluetooth low energy service UUID 0xFD6F, used by Google/Apple COVID-19 Exposure Notification System, can be monitored and counted. By comparing with the total number of observed devices this gives an indication how many people staying in proximity are using Apps for tracing COVID-19 exposures, e.g. in Germany the "Corona Warn App". To achive best resulta withs this funcion, use following settings in [paxcounter.conf](src/paxcounter.conf):
|
||||||
|
|
||||||
|
#define COUNT_ENS 1 // enable ENS monitoring function
|
||||||
|
#define VENDORFILTER 0 // disable OUI filter (scans ALL device MACs)
|
||||||
|
#define BLECOUNTER 1 // enable bluetooth sniffing
|
||||||
|
#define WIFICOUNTER 0 // disable wifi sniffing (improves BLE scan speed)
|
||||||
|
#define HAS_SENSOR_1 1 // optional: transmit ENS counter data to server
|
||||||
|
|
||||||
# SD-card
|
# SD-card
|
||||||
|
|
||||||
Data can be stored on an SD-card if one is availabe. Simply choose the file in src/hal and add the following lines to your hal-file:
|
Data can be stored on an SD-card if one is availabe. Simply choose the file in src/hal and add the following lines to your hal-file:
|
||||||
|
|
||||||
#define HAS_SDCARD 1 // SD-card-reader/writer, using SPI interface
|
#define HAS_SDCARD 1 // SD-card-reader/writer, using SPI interface
|
||||||
@ -559,4 +571,4 @@ Thanks to
|
|||||||
- [terrillmoore](https://github.com/mcci-catena) for maintaining the LMIC for arduino LoRaWAN stack
|
- [terrillmoore](https://github.com/mcci-catena) for maintaining the LMIC for arduino LoRaWAN stack
|
||||||
- [sbamueller](https://github.com/sbamueller) for writing the tutorial in Make Magazine
|
- [sbamueller](https://github.com/sbamueller) for writing the tutorial in Make Magazine
|
||||||
- [Stefan](https://github.com/nerdyscout) for paxcounter opensensebox integration
|
- [Stefan](https://github.com/nerdyscout) for paxcounter opensensebox integration
|
||||||
- [August Quint](https://github.com/AugustQu) for adding SD card data logger and SDS011 support
|
- [August Quint](https://github.com/AugustQu) for adding SD card data logger, SDS011 and ENS support
|
||||||
|
16
include/corona.h
Normal file
16
include/corona.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _CORONA_h
|
||||||
|
#define _CORONA_H
|
||||||
|
|
||||||
|
// inspired by https://github.com/kmetz/BLEExposureNotificationBeeper
|
||||||
|
// (c) by Kaspar Metz
|
||||||
|
// modified for use in the Paxcounter by AQ
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
bool cwa_init(void);
|
||||||
|
void cwa_mac_add(uint16_t hashedmac);
|
||||||
|
void cwa_clear(void);
|
||||||
|
uint16_t cwa_report(void);
|
||||||
|
|
||||||
|
#endif
|
@ -12,10 +12,11 @@
|
|||||||
|
|
||||||
#define MAC_SNIFF_WIFI 0
|
#define MAC_SNIFF_WIFI 0
|
||||||
#define MAC_SNIFF_BLE 1
|
#define MAC_SNIFF_BLE 1
|
||||||
|
#define MAC_SNIFF_BLE_CWA 2
|
||||||
|
|
||||||
uint16_t get_salt(void);
|
uint16_t get_salt(void);
|
||||||
uint64_t macConvert(uint8_t *paddr);
|
uint64_t macConvert(uint8_t *paddr);
|
||||||
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type);
|
uint16_t mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type);
|
||||||
void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb);
|
void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -20,5 +20,6 @@
|
|||||||
#include "sensor.h"
|
#include "sensor.h"
|
||||||
#include "lorawan.h"
|
#include "lorawan.h"
|
||||||
#include "timekeeper.h"
|
#include "timekeeper.h"
|
||||||
|
#include "corona.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -5,7 +5,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
#ifdef HAS_SDCARD
|
#if (HAS_SDCARD)
|
||||||
#if HAS_SDCARD == 1
|
#if HAS_SDCARD == 1
|
||||||
#include <mySD.h>
|
#include <mySD.h>
|
||||||
//#include <SD.h>
|
//#include <SD.h>
|
||||||
@ -38,9 +38,13 @@
|
|||||||
|
|
||||||
#define SDCARD_FILE_NAME "/paxcount.%02d"
|
#define SDCARD_FILE_NAME "/paxcount.%02d"
|
||||||
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"
|
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"
|
||||||
|
#define SDCARD_FILE_NAME "paxcount.%02d"
|
||||||
|
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
#define SDCARD_FILE_HEADER_CWA ",cwa"
|
||||||
|
#endif
|
||||||
|
|
||||||
bool sdcard_init( void );
|
bool sdcard_init( void );
|
||||||
void sdcardWriteData(uint16_t, uint16_t);
|
void sdcardWriteData( uint16_t, uint16_t, uint16_t = 0);
|
||||||
static void createFile(void);
|
|
||||||
|
|
||||||
#endif
|
#endif // _SDCARD_H
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "lorawan.h"
|
#include "lorawan.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "sdcard.h"
|
#include "sdcard.h"
|
||||||
|
#include "corona.h"
|
||||||
|
|
||||||
extern Ticker sendcycler;
|
extern Ticker sendcycler;
|
||||||
|
|
||||||
|
@ -37,19 +37,19 @@ halfile = generic.h
|
|||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
; upload firmware to board with usb cable
|
; upload firmware to board with usb cable
|
||||||
;default_envs = usb
|
default_envs = usb
|
||||||
; upload firmware to a jfrog bintray repository
|
; upload firmware to a jfrog bintray repository
|
||||||
;default_envs = ota
|
;default_envs = ota
|
||||||
; use latest versions of libraries
|
; 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.
|
description = Paxcounter is a device for metering passenger flows in realtime. It counts how many mobile devices are around.
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
; 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!
|
; 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
|
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||||
debug_level = 4
|
debug_level = 3
|
||||||
extra_scripts = pre:build.py
|
extra_scripts = pre:build.py
|
||||||
otakeyfile = ota.conf
|
otakeyfile = ota.conf
|
||||||
lorakeyfile = loraconf.h
|
lorakeyfile = loraconf.h
|
||||||
@ -64,16 +64,16 @@ lib_deps_display =
|
|||||||
OneBitDisplay@1.5.0
|
OneBitDisplay@1.5.0
|
||||||
QRCode@0.0.1
|
QRCode@0.0.1
|
||||||
BitBang_I2C@2.1.1
|
BitBang_I2C@2.1.1
|
||||||
TFT_eSPI@>=2.2.8
|
TFT_eSPI@>=2.2.18
|
||||||
lib_deps_ledmatrix =
|
lib_deps_ledmatrix =
|
||||||
Ultrathin_LED_Matrix@>=1.0.0
|
Ultrathin_LED_Matrix@>=1.0.0
|
||||||
lib_deps_rgbled =
|
lib_deps_rgbled =
|
||||||
SmartLeds@>=1.2.0
|
SmartLeds@>=1.2.1
|
||||||
lib_deps_gps =
|
lib_deps_gps =
|
||||||
1655@>=1.0.2 ; #1655 TinyGPSPlus by Mikal Hart
|
1655@>=1.0.2 ; #1655 TinyGPSPlus by Mikal Hart
|
||||||
lib_deps_sensors =
|
lib_deps_sensors =
|
||||||
Adafruit Unified Sensor@>=1.1.4
|
Adafruit Unified Sensor@>=1.1.4
|
||||||
Adafruit BME280 Library@>=2.0.2
|
Adafruit BME280 Library@>=2.1.0
|
||||||
Adafruit BMP085 Library@>=1.1.0
|
Adafruit BMP085 Library@>=1.1.0
|
||||||
BSEC Software Library@1.5.1474
|
BSEC Software Library@1.5.1474
|
||||||
https://github.com/ricki-z/SDS011.git
|
https://github.com/ricki-z/SDS011.git
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
#define BT_BD_ADDR_HEX(addr) \
|
#define BT_BD_ADDR_HEX(addr) \
|
||||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||||
|
|
||||||
|
// 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
|
// local Tag for logging
|
||||||
static const char TAG[] = "bluetooth";
|
static const char TAG[] = "bluetooth";
|
||||||
|
|
||||||
@ -109,7 +114,9 @@ const char *btsig_gap_type(uint32_t gap_type) {
|
|||||||
// using IRAM_:ATTR here to speed up callback function
|
// using IRAM_:ATTR here to speed up callback function
|
||||||
IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
|
IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
|
||||||
esp_ble_gap_cb_param_t *param) {
|
esp_ble_gap_cb_param_t *param) {
|
||||||
|
|
||||||
esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param;
|
esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param;
|
||||||
|
uint16_t hashedmac = 0;
|
||||||
|
|
||||||
ESP_LOGV(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv,
|
ESP_LOGV(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv,
|
||||||
btsig_gap_type(*p->scan_rst.ble_adv));
|
btsig_gap_type(*p->scan_rst.ble_adv));
|
||||||
@ -146,22 +153,25 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if (VENDORFILTER)
|
#if (VENDORFILTER)
|
||||||
|
|
||||||
if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) ||
|
if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) ||
|
||||||
(p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) {
|
(p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) {
|
||||||
ESP_LOGV(TAG, "BT device filtered");
|
ESP_LOGV(TAG, "BT device filtered");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// add this device and show new count total if it was not previously added
|
// hash and add this device and show new count total if it was not
|
||||||
|
// previously added
|
||||||
|
hashedmac =
|
||||||
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
|
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
|
||||||
|
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
// check for ens signature
|
||||||
|
if (0 == strncmp((const char *)p->scan_rst.ble_adv, ensMagicBytes, 4))
|
||||||
|
cwa_mac_add(hashedmac);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* to be improved in vendorfilter if:
|
/* to be improved in vendorfilter if:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// you can search for elements in the payload using the
|
// you can search for elements in the payload using the
|
||||||
// function esp_ble_resolve_adv_data()
|
// function esp_ble_resolve_adv_data()
|
||||||
//
|
//
|
||||||
|
55
src/corona.cpp
Normal file
55
src/corona.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
// When to forget old senders ** currently not used **
|
||||||
|
#define FORGET_AFTER_MINUTES 2
|
||||||
|
|
||||||
|
// array of timestamps for seen notifiers: hash -> timestamp[ms]
|
||||||
|
static std::map<uint16_t, unsigned long> cwaSeenNotifiers;
|
||||||
|
|
||||||
|
// Remove notifiers last seen over FORGET_AFTER_MINUTES ago.
|
||||||
|
void cwa_clear() {
|
||||||
|
/*
|
||||||
|
|
||||||
|
#ifdef SOME_FORM_OF_DEBUG
|
||||||
|
ESP_LOGD(TAG, "CWA: forget old notifier: %d", cwaSeenNotifiers.size());
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cwa_mac_add(uint16_t hashedmac) {
|
||||||
|
cwaSeenNotifiers[hashedmac] = millis(); // hash last seen at ....
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -265,7 +265,11 @@ void dp_drawPage(time_t t, bool nextpage) {
|
|||||||
else
|
else
|
||||||
dp_printf("WIFI:off");
|
dp_printf("WIFI:off");
|
||||||
if (cfg.blescan)
|
if (cfg.blescan)
|
||||||
|
#if (!COUNT_ENS)
|
||||||
dp_printf("BLTH:%-5d", macs_ble);
|
dp_printf("BLTH:%-5d", macs_ble);
|
||||||
|
#else
|
||||||
|
dp_printf(" CWA:%-5d", cwa_report());
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
dp_printf(" BLTH:off");
|
dp_printf(" BLTH:off");
|
||||||
#elif ((WIFICOUNTER) && (!BLECOUNTER))
|
#elif ((WIFICOUNTER) && (!BLECOUNTER))
|
||||||
@ -274,9 +278,12 @@ void dp_drawPage(time_t t, bool nextpage) {
|
|||||||
else
|
else
|
||||||
dp_printf("WIFI:off");
|
dp_printf("WIFI:off");
|
||||||
#elif ((!WIFICOUNTER) && (BLECOUNTER))
|
#elif ((!WIFICOUNTER) && (BLECOUNTER))
|
||||||
if (cfg.blescan)
|
if (cfg.blescan) {
|
||||||
dp_printf("BLTH:%-5d", macs_ble);
|
dp_printf("BLTH:%-5d", macs_ble);
|
||||||
else
|
#if (COUNT_ENS)
|
||||||
|
dp_printf("(CWA:%d)", cwa_report());
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
dp_printf("BLTH:off");
|
dp_printf("BLTH:off");
|
||||||
#else
|
#else
|
||||||
dp_printf("Sniffer disabled");
|
dp_printf("Sniffer disabled");
|
||||||
@ -349,18 +356,17 @@ void dp_drawPage(time_t t, bool nextpage) {
|
|||||||
|
|
||||||
#if (HAS_LORA)
|
#if (HAS_LORA)
|
||||||
|
|
||||||
// 3|NtwkID:000000 TXpw:aa
|
// 3|Net:000000 Pwr:aa
|
||||||
// 4|DevAdd:00000000 DR:0
|
// 4|Dev:00000000 DR:0
|
||||||
// 5|CHMsk:0000 Nonce:0000
|
// 5|CHMsk:0000 Nonce:0000
|
||||||
// 6|CUp:000000 CDn:000000
|
// 6|fUp:000000 fDn:000000
|
||||||
// 7|SNR:-0000 RSSI:-0000
|
// 7|SNR:-0000 RSSI:-0000
|
||||||
|
|
||||||
dp_setFont(MY_FONT_SMALL);
|
dp_setFont(MY_FONT_SMALL);
|
||||||
dp_setTextCursor(0, 3);
|
dp_setTextCursor(0, 3);
|
||||||
dp_printf("NetwID:%06X TXpw:%-2d", LMIC.netid & 0x001FFFFF,
|
dp_printf("Net:%06X Pwr:%-2d", LMIC.netid & 0x001FFFFF, LMIC.radio_txpow);
|
||||||
LMIC.radio_txpow);
|
|
||||||
dp_println();
|
dp_println();
|
||||||
dp_printf("DevAdd:%08X DR:%1d", LMIC.devaddr, LMIC.datarate);
|
dp_printf("Dev:%08X DR:%1d", LMIC.devaddr, LMIC.datarate);
|
||||||
dp_println();
|
dp_println();
|
||||||
dp_printf("ChMsk:%04X Nonce:%04X", LMIC.channelMap, LMIC.devNonce);
|
dp_printf("ChMsk:%04X Nonce:%04X", LMIC.channelMap, LMIC.devNonce);
|
||||||
dp_println();
|
dp_println();
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
||||||
|
|
||||||
// enable only if you want to store a local paxcount table on the device
|
// enable only if you want to store a local paxcount table on the device
|
||||||
#define HAS_SDCARD 2 // this board has an SD-card-reader/writer
|
#define HAS_SDCARD 1 // this board has an SD-card-reader/writer
|
||||||
|
|
||||||
#define HAS_DISPLAY 1
|
#define HAS_DISPLAY 1
|
||||||
#define HAS_LED (25) // green on board LED
|
#define HAS_LED (25) // green on board LED
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
// Local logging tag
|
// Local logging tag
|
||||||
static const char TAG[] = __FILE__;
|
static const char TAG[] = __FILE__;
|
||||||
|
|
||||||
uint16_t salt;
|
uint16_t salt = 0;
|
||||||
|
|
||||||
uint16_t get_salt(void) {
|
uint16_t get_salt(void) {
|
||||||
salt = (uint16_t)random(65536); // get new 16bit random for salting hashes
|
salt = (uint16_t)random(65536); // get new 16bit random for salting hashes
|
||||||
@ -43,15 +43,15 @@ uint64_t macConvert(uint8_t *paddr) {
|
|||||||
return (__builtin_bswap64(*mac) >> 16);
|
return (__builtin_bswap64(*mac) >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
uint16_t mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
||||||
|
|
||||||
if (!salt) // ensure we have salt (appears after radio is turned on)
|
if (salt == 0) // ensure we have salt (appears after radio is turned on)
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
|
uint16_t hashedmac = 0; // temporary buffer for generated hash value
|
||||||
char buff[10]; // temporary buffer for printf
|
char buff[10]; // temporary buffer for printf
|
||||||
bool added = false;
|
bool added = false;
|
||||||
int8_t beaconID; // beacon number in test monitor mode
|
int8_t beaconID; // beacon number in test monitor mode
|
||||||
uint16_t hashedmac; // temporary buffer for generated hash value
|
|
||||||
uint32_t *mac; // temporary buffer for shortened MAC
|
uint32_t *mac; // temporary buffer for shortened MAC
|
||||||
|
|
||||||
// only last 3 MAC Address bytes are used for MAC address anonymization
|
// only last 3 MAC Address bytes are used for MAC address anonymization
|
||||||
@ -116,13 +116,20 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
|||||||
} // added
|
} // added
|
||||||
|
|
||||||
// Log scan result
|
// Log scan result
|
||||||
ESP_LOGV(TAG,
|
ESP_LOGD(TAG,
|
||||||
"%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d "
|
"%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d "
|
||||||
"BLTH:%d -> "
|
"BLTH:%d "
|
||||||
"%d Bytes left",
|
#if (COUNT_ENS)
|
||||||
|
"(CWA:%d)"
|
||||||
|
#endif
|
||||||
|
"-> %d Bytes left",
|
||||||
added ? "new " : "known",
|
added ? "new " : "known",
|
||||||
sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff,
|
sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff,
|
||||||
hashedmac, macs_wifi, macs_ble, getFreeRAM());
|
hashedmac, macs_wifi, macs_ble,
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
cwa_report(),
|
||||||
|
#endif
|
||||||
|
getFreeRAM());
|
||||||
|
|
||||||
#if (VENDORFILTER)
|
#if (VENDORFILTER)
|
||||||
} else {
|
} else {
|
||||||
@ -132,7 +139,7 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// True if MAC WiFi/BLE was new
|
// if a new and unique Wifi or BLE mac was counted, returs hash of this mac,
|
||||||
return added; // function returns bool if a new and unique Wifi or BLE mac was
|
// else 0
|
||||||
// counted (true) or not (false)
|
return hashedmac;
|
||||||
}
|
}
|
||||||
|
20
src/main.cpp
20
src/main.cpp
@ -312,9 +312,25 @@ void setup() {
|
|||||||
|
|
||||||
// initialize sensors
|
// initialize sensors
|
||||||
#if (HAS_SENSORS)
|
#if (HAS_SENSORS)
|
||||||
strcat_P(features, " SENS");
|
#if (HAS_SENSOR_1)
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
ESP_LOGI(TAG, "init CWA-counter");
|
||||||
|
if ( cwa_init() )
|
||||||
|
strcat_P(features, " CWA");
|
||||||
|
#else
|
||||||
|
strcat_P(features, " SENS(1)");
|
||||||
sensor_init();
|
sensor_init();
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#if (HAS_SENSOR_2)
|
||||||
|
strcat_P(features, " SENS(2)");
|
||||||
|
sensor_init();
|
||||||
|
#endif
|
||||||
|
#if (HAS_SENSOR_3)
|
||||||
|
strcat_P(features, " SENS(3)");
|
||||||
|
sensor_init();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// initialize LoRa
|
// initialize LoRa
|
||||||
#if (HAS_LORA)
|
#if (HAS_LORA)
|
||||||
@ -336,7 +352,7 @@ void setup() {
|
|||||||
assert(mqtt_init() == ESP_OK);
|
assert(mqtt_init() == ESP_OK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_SDCARD
|
#if (HAS_SDCARD)
|
||||||
if (sdcard_init())
|
if (sdcard_init())
|
||||||
strcat_P(features, " SD");
|
strcat_P(features, " SD");
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,15 +15,25 @@
|
|||||||
#define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
#define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
||||||
|
|
||||||
// Set this to include BLE counting and vendor filter functions, or to switch off WIFI counting
|
// 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 VENDORFILTER 0 // set to 0 if you want to all devices, not filtering smartphone OUIs
|
||||||
#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
|
#define WIFICOUNTER 0 // set it to 0 if you want to switch off WIFI count
|
||||||
|
|
||||||
// BLE scan parameters
|
// BLE scan parameters
|
||||||
#define BLESCANTIME 0 // [seconds] scan duration, 0 means infinite [default], see note below
|
#define BLESCANTIME 0 // [seconds] scan duration, 0 means infinite [default], see note below
|
||||||
#define BLESCANWINDOW 80 // [milliseconds] scan window, see below, 3 .. 10240, default 80ms
|
#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 BLESCANINTERVAL 80 // [illiseconds] scan interval, see below, 3 .. 10240, default 80ms = 100% duty cycle
|
||||||
|
|
||||||
|
// 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 enable this function
|
||||||
|
|
||||||
|
// for additional sensors (added by some user)
|
||||||
|
#define HAS_SENSOR_1 1 // set to 1 if you want to transmit CWA counter
|
||||||
|
#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
|
||||||
|
|
||||||
/* Note: guide for setting bluetooth parameters
|
/* Note: guide for setting bluetooth parameters
|
||||||
*
|
*
|
||||||
* |< Scan Window > |< Scan Window > | ... |< Scan Window > |
|
* |< Scan Window > |< Scan Window > | ... |< Scan Window > |
|
||||||
@ -73,8 +83,8 @@
|
|||||||
#define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds]
|
#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)
|
// 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_LORAWAN 0 // 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_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 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_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
|
#define TIME_SYNC_SAMPLES 1 // number of time requests for averaging, max. 255
|
||||||
|
@ -9,6 +9,8 @@ static const char TAG[] = __FILE__;
|
|||||||
|
|
||||||
static bool useSDCard;
|
static bool useSDCard;
|
||||||
|
|
||||||
|
static void createFile(void);
|
||||||
|
|
||||||
File fileSDCard;
|
File fileSDCard;
|
||||||
|
|
||||||
bool sdcard_init() {
|
bool sdcard_init() {
|
||||||
@ -19,9 +21,7 @@ bool sdcard_init() {
|
|||||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html
|
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html
|
||||||
|
|
||||||
#if HAS_SDCARD == 1 // use SD SPI host driver
|
#if HAS_SDCARD == 1 // use SD SPI host driver
|
||||||
|
|
||||||
useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK);
|
useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK);
|
||||||
|
|
||||||
//SPI.begin(SDCARD_SCLK, SDCARD_MSO, SDCARD_MOSI, SDCARD_CS);
|
//SPI.begin(SDCARD_SCLK, SDCARD_MSO, SDCARD_MOSI, SDCARD_CS);
|
||||||
//delay(10);
|
//delay(10);
|
||||||
//useSDCard = SD.begin(SDCARD_CS, SPI, 40000000, "/sd");
|
//useSDCard = SD.begin(SDCARD_CS, SPI, 40000000, "/sd");
|
||||||
@ -38,7 +38,7 @@ bool sdcard_init() {
|
|||||||
return useSDCard;
|
return useSDCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdcardWriteData(uint16_t noWifi, uint16_t noBle) {
|
void sdcardWriteData(uint16_t noWifi, uint16_t noBle, __attribute__((unused)) uint16_t noBleCWA) {
|
||||||
static int counterWrites = 0;
|
static int counterWrites = 0;
|
||||||
char tempBuffer[12 + 1];
|
char tempBuffer[12 + 1];
|
||||||
time_t t = now();
|
time_t t = now();
|
||||||
@ -56,6 +56,10 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle) {
|
|||||||
fileSDCard.print(tempBuffer);
|
fileSDCard.print(tempBuffer);
|
||||||
sprintf(tempBuffer, "%d,%d", noWifi, noBle);
|
sprintf(tempBuffer, "%d,%d", noWifi, noBle);
|
||||||
fileSDCard.print(tempBuffer);
|
fileSDCard.print(tempBuffer);
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
sprintf(tempBuffer, ",%d", noBleCWA);
|
||||||
|
fileSDCard.print(tempBuffer);
|
||||||
|
#endif
|
||||||
#if (HAS_SDS011)
|
#if (HAS_SDS011)
|
||||||
sds011_store(&sds);
|
sds011_store(&sds);
|
||||||
sprintf(tempBuffer, ",%5.1f,%4.1f", sds.pm10, sds.pm25);
|
sprintf(tempBuffer, ",%5.1f,%4.1f", sds.pm10, sds.pm25);
|
||||||
@ -98,6 +102,9 @@ void createFile(void) {
|
|||||||
if (fileSDCard) {
|
if (fileSDCard) {
|
||||||
ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename);
|
ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename);
|
||||||
fileSDCard.print(SDCARD_FILE_HEADER);
|
fileSDCard.print(SDCARD_FILE_HEADER);
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
fileSDCard.print(SDCARD_FILE_HEADER_CWA); // for Corona-data (CWA)
|
||||||
|
#endif
|
||||||
#if (HAS_SDS011)
|
#if (HAS_SDS011)
|
||||||
fileSDCard.print(SDCARD_FILE_HEADER_SDS011);
|
fileSDCard.print(SDCARD_FILE_HEADER_SDS011);
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,8 +55,14 @@ void SendPayload(uint8_t port, sendprio_t prio) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// write data to sdcard, if present
|
// write data to sdcard, if present
|
||||||
#ifdef HAS_SDCARD
|
#if (HAS_SDCARD)
|
||||||
sdcardWriteData(macs_wifi, macs_ble);
|
if ( port == COUNTERPORT ) {
|
||||||
|
sdcardWriteData(macs_wifi, macs_ble
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
, cwa_report()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // SendPayload
|
} // SendPayload
|
||||||
@ -143,22 +149,31 @@ void sendData() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (HAS_SENSORS)
|
#if (HAS_SENSORS)
|
||||||
|
#if (HAS_SENSOR_1)
|
||||||
case SENSOR1_DATA:
|
case SENSOR1_DATA:
|
||||||
payload.reset();
|
payload.reset();
|
||||||
payload.addSensor(sensor_read(1));
|
payload.addSensor(sensor_read(1));
|
||||||
SendPayload(SENSOR1PORT, prio_normal);
|
SendPayload(SENSOR1PORT, prio_normal);
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
cwa_clear();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if (HAS_SENSOR_2)
|
||||||
case SENSOR2_DATA:
|
case SENSOR2_DATA:
|
||||||
payload.reset();
|
payload.reset();
|
||||||
payload.addSensor(sensor_read(2));
|
payload.addSensor(sensor_read(2));
|
||||||
SendPayload(SENSOR2PORT, prio_normal);
|
SendPayload(SENSOR2PORT, prio_normal);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if (HAS_SENSOR_3)
|
||||||
case SENSOR3_DATA:
|
case SENSOR3_DATA:
|
||||||
payload.reset();
|
payload.reset();
|
||||||
payload.addSensor(sensor_read(3));
|
payload.addSensor(sensor_read(3));
|
||||||
SendPayload(SENSOR3PORT, prio_normal);
|
SendPayload(SENSOR3PORT, prio_normal);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
|
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
|
||||||
case BATT_DATA:
|
case BATT_DATA:
|
||||||
|
@ -2,6 +2,14 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "sensor.h"
|
#include "sensor.h"
|
||||||
|
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
#include "payload.h"
|
||||||
|
#include "corona.h"
|
||||||
|
#include "macsniff.h"
|
||||||
|
|
||||||
|
extern PayloadConvert payload;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Local logging tag
|
// Local logging tag
|
||||||
static const char TAG[] = __FILE__;
|
static const char TAG[] = __FILE__;
|
||||||
|
|
||||||
@ -47,10 +55,14 @@ uint8_t *sensor_read(uint8_t sensor) {
|
|||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
// insert user specific sensor data frames here */
|
// insert user specific sensor data frames here */
|
||||||
|
#if (COUNT_ENS)
|
||||||
|
payload.addCount( cwa_report(), MAC_SNIFF_BLE_CWA);
|
||||||
|
#else
|
||||||
buf[0] = length;
|
buf[0] = length;
|
||||||
buf[1] = 0x01;
|
buf[1] = 0x01;
|
||||||
buf[2] = 0x02;
|
buf[2] = 0x02;
|
||||||
buf[3] = 0x03;
|
buf[3] = 0x03;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
Loading…
Reference in New Issue
Block a user