Merge pull request #628 from AugustQu/CWA

CWA
This commit is contained in:
Verkehrsrot 2020-09-01 16:34:31 +02:00 committed by GitHub
commit 368a9205cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 231 additions and 31 deletions

16
include/corona.h Normal file
View 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);
bool cwa_mac_add(uint8_t *);
void cwa_clear(void);
uint16_t cwa_report(void);
#endif

View File

@ -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); bool 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

View File

@ -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

View File

@ -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>
@ -15,6 +15,11 @@
#error HAS_SDCARD unknown card reader value, must be either 1 or 2 #error HAS_SDCARD unknown card reader value, must be either 1 or 2
#endif #endif
#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 #ifdef HAS_SDS011
#include "sds011read.h" #include "sds011read.h"
@ -38,9 +43,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"
bool sdcard_init(void); #define SDCARD_FILE_HEADER "date, time, wifi, bluet"
void sdcardWriteData(uint16_t, uint16_t); #if (COUNT_CWA)
static void createFile(void); #define SDCARD_FILE_HEADER_CWA ",cwa"
#endif #endif
bool sdcard_init( void );
void sdcardWriteData( uint16_t, uint16_t, uint16_t = 0);
#endif // _SDCARD_H

View File

@ -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;

View File

@ -6,6 +6,9 @@
#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]
// checking for CWAs we need this magic bytes:
static const char cwaMagicBytes[] = "\x03\x03\x6F\xfd";
// local Tag for logging // local Tag for logging
static const char TAG[] = "bluetooth"; static const char TAG[] = "bluetooth";
@ -158,10 +161,19 @@ 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 // 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); 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()
// check for CWA-signature
if ( 0 == strncmp( (const char*)p->scan_rst.ble_adv, cwaMagicBytes , 4) ) {
cwa_mac_add( p->scan_rst.bda);
}
#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()
// //

85
src/coona.cpp Normal file
View File

@ -0,0 +1,85 @@
// 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 &notifier : 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

View File

@ -265,7 +265,12 @@ void dp_drawPage(time_t t, bool nextpage) {
else else
dp_printf("WIFI:off"); dp_printf("WIFI:off");
if (cfg.blescan) if (cfg.blescan)
dp_printf(" BLTH:%-5d", macs_ble); #if !(COUNT_CWA)
dp_printf("BLTH:%-5d", macs_ble);
#else
dp_printf("BLTH:%-5d", macs_ble);
dp_printf("(CWA:%d)", cwa_report());
#endif
else else
dp_printf(" BLTH:off"); dp_printf(" BLTH:off");
#elif ((WIFICOUNTER) && (!BLECOUNTER)) #elif ((WIFICOUNTER) && (!BLECOUNTER))
@ -274,9 +279,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_CWA)
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");
@ -736,4 +744,4 @@ void dp_plotCurve(uint16_t count, bool reset) {
dp_drawPixel(plotbuf, col, row, 1); dp_drawPixel(plotbuf, col, row, 1);
} }
#endif // HAS_DISPLAY #endif // HAS_DISPLAY

View File

@ -12,11 +12,11 @@
// This settings are for boards labeled v1.6 on pcb, NOT for v1.5 or older // This settings are for boards labeled v1.6 on pcb, NOT for v1.5 or older
*/ */
#define HAS_LORA 1 // comment out if device shall not send data via LoRa #define HAS_LORA 1 // comment out if device shall not send data via LoRa
#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

View File

@ -10,7 +10,9 @@
// Local logging tag // Local logging tag
static const char TAG[] = __FILE__; static const char TAG[] = __FILE__;
uint16_t salt; // used here and in corona.cpp
uint16_t salt = -1;
uint16_t hashedmac = -1; // temporary buffer for generated hash value
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
@ -51,7 +53,6 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
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
@ -111,18 +112,25 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
payload.addAlarm(rssi, beaconID); payload.addAlarm(rssi, beaconID);
SendPayload(BEACONPORT, prio_high); SendPayload(BEACONPORT, prio_high);
} }
}; };
} // added } // added
// Log scan result // Log scan result
ESP_LOGV(TAG, ESP_LOGV(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_CWA)
"(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_CWA)
cwa_report(),
#endif
getFreeRAM());
#if (VENDORFILTER) #if (VENDORFILTER)
} else { } else {

View File

@ -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_CWA)
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

View File

@ -24,6 +24,15 @@
#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
#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
// for additional sensors (added by some user)
#define HAS_SENSOR_1 0 // 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
/* Note: guide for setting bluetooth parameters /* Note: guide for setting bluetooth parameters
* *
* |< Scan Window > |< Scan Window > | ... |< Scan Window > | * |< Scan Window > |< Scan Window > | ... |< Scan Window > |

View File

@ -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_CWA)
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_CWA)
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

View File

@ -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_CWA)
, 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_CWA)
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:

View File

@ -2,6 +2,14 @@
#include "globals.h" #include "globals.h"
#include "sensor.h" #include "sensor.h"
#if (COUNT_CWA)
#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_CWA)
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:
@ -71,4 +83,4 @@ uint8_t *sensor_read(uint8_t sensor) {
} }
return buf; return buf;
} }