diff --git a/include/corona.h b/include/corona.h new file mode 100644 index 00000000..fcbf556d --- /dev/null +++ b/include/corona.h @@ -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 + +bool cwa_init(void); +bool cwa_mac_add(uint8_t *); +void cwa_clear(void); +uint16_t cwa_report(void); + +#endif diff --git a/include/macsniff.h b/include/macsniff.h index a04b7cc8..574048b7 100644 --- a/include/macsniff.h +++ b/include/macsniff.h @@ -12,10 +12,11 @@ #define MAC_SNIFF_WIFI 0 #define MAC_SNIFF_BLE 1 +#define MAC_SNIFF_BLE_CWA 2 uint16_t get_salt(void); uint64_t macConvert(uint8_t *paddr); 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); -#endif \ No newline at end of file +#endif diff --git a/include/main.h b/include/main.h index bc63ff4e..3e346af7 100644 --- a/include/main.h +++ b/include/main.h @@ -20,5 +20,6 @@ #include "sensor.h" #include "lorawan.h" #include "timekeeper.h" +#include "corona.h" -#endif \ No newline at end of file +#endif diff --git a/include/sdcard.h b/include/sdcard.h index e6bc62fb..fa358a71 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -5,7 +5,7 @@ #include #include -#ifdef HAS_SDCARD +#if (HAS_SDCARD) #if HAS_SDCARD == 1 #include //#include @@ -15,6 +15,11 @@ #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" @@ -38,9 +43,13 @@ #define SDCARD_FILE_NAME "/paxcount.%02d" #define SDCARD_FILE_HEADER "date, time, wifi, bluet" - -bool sdcard_init(void); -void sdcardWriteData(uint16_t, uint16_t); -static void createFile(void); - +#define SDCARD_FILE_NAME "paxcount.%02d" +#define SDCARD_FILE_HEADER "date, time, wifi, bluet" +#if (COUNT_CWA) +#define SDCARD_FILE_HEADER_CWA ",cwa" #endif + +bool sdcard_init( void ); +void sdcardWriteData( uint16_t, uint16_t, uint16_t = 0); + +#endif // _SDCARD_H diff --git a/include/senddata.h b/include/senddata.h index fd31f884..f1a43867 100644 --- a/include/senddata.h +++ b/include/senddata.h @@ -8,6 +8,7 @@ #include "lorawan.h" #include "display.h" #include "sdcard.h" +#include "corona.h" extern Ticker sendcycler; diff --git a/src/blecsan.cpp b/src/blecsan.cpp index d305680e..0806776c 100644 --- a/src/blecsan.cpp +++ b/src/blecsan.cpp @@ -6,6 +6,9 @@ #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"; + // local Tag for logging 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 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: - - - // you can search for elements in the payload using the // function esp_ble_resolve_adv_data() // diff --git a/src/coona.cpp b/src/coona.cpp new file mode 100644 index 00000000..44020d84 --- /dev/null +++ b/src/coona.cpp @@ -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 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 diff --git a/src/display.cpp b/src/display.cpp index 162fa6b3..579956b9 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -265,7 +265,12 @@ void dp_drawPage(time_t t, bool nextpage) { else dp_printf("WIFI:off"); 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 dp_printf(" BLTH:off"); #elif ((WIFICOUNTER) && (!BLECOUNTER)) @@ -274,9 +279,12 @@ void dp_drawPage(time_t t, bool nextpage) { else dp_printf("WIFI:off"); #elif ((!WIFICOUNTER) && (BLECOUNTER)) - if (cfg.blescan) + if (cfg.blescan) { dp_printf("BLTH:%-5d", macs_ble); - else +#if (COUNT_CWA) + dp_printf("(CWA:%d)", cwa_report()); +#endif + } else dp_printf("BLTH:off"); #else dp_printf("Sniffer disabled"); @@ -736,4 +744,4 @@ void dp_plotCurve(uint16_t count, bool reset) { dp_drawPixel(plotbuf, col, row, 1); } -#endif // HAS_DISPLAY \ No newline at end of file +#endif // HAS_DISPLAY diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index ca2a9cc6..4b08748d 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -12,11 +12,11 @@ // 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 // 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_LED (25) // green on board LED diff --git a/src/macsniff.cpp b/src/macsniff.cpp index a64e49b1..3b6ee5d5 100644 --- a/src/macsniff.cpp +++ b/src/macsniff.cpp @@ -10,7 +10,9 @@ // Local logging tag 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) { 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 bool added = false; 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 // 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); SendPayload(BEACONPORT, prio_high); } - }; + }; } // added // Log scan result ESP_LOGV(TAG, "%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d " - "BLTH:%d -> " - "%d Bytes left", + "BLTH:%d " +#if (COUNT_CWA) + "(CWA:%d)" +#endif + "-> %d Bytes left", added ? "new " : "known", 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) } else { diff --git a/src/main.cpp b/src/main.cpp index ed0bd9ee..ff0fa2cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -312,9 +312,25 @@ void setup() { // initialize 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(); #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 #if (HAS_LORA) @@ -336,7 +352,7 @@ void setup() { assert(mqtt_init() == ESP_OK); #endif -#ifdef HAS_SDCARD +#if (HAS_SDCARD) if (sdcard_init()) strcat_P(features, " SD"); #endif diff --git a/src/paxcounter.conf b/src/paxcounter.conf index c98cc7b9..60bfc361 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -24,6 +24,15 @@ #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 + +// 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 * * |< Scan Window > |< Scan Window > | ... |< Scan Window > | diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 94e14eaa..29f65f3a 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -9,6 +9,8 @@ static const char TAG[] = __FILE__; static bool useSDCard; +static void createFile(void); + File fileSDCard; 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 #if HAS_SDCARD == 1 // use SD SPI host driver - useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK); - //SPI.begin(SDCARD_SCLK, SDCARD_MSO, SDCARD_MOSI, SDCARD_CS); //delay(10); //useSDCard = SD.begin(SDCARD_CS, SPI, 40000000, "/sd"); @@ -38,7 +38,7 @@ bool sdcard_init() { 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; char tempBuffer[12 + 1]; time_t t = now(); @@ -56,6 +56,10 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle) { fileSDCard.print(tempBuffer); sprintf(tempBuffer, "%d,%d", noWifi, noBle); fileSDCard.print(tempBuffer); +#if (COUNT_CWA) + sprintf(tempBuffer, ",%d", noBleCWA); + fileSDCard.print(tempBuffer); +#endif #if (HAS_SDS011) sds011_store(&sds); sprintf(tempBuffer, ",%5.1f,%4.1f", sds.pm10, sds.pm25); @@ -98,6 +102,9 @@ void createFile(void) { if (fileSDCard) { ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename); fileSDCard.print(SDCARD_FILE_HEADER); +#if (COUNT_CWA) + fileSDCard.print(SDCARD_FILE_HEADER_CWA); // for Corona-data (CWA) +#endif #if (HAS_SDS011) fileSDCard.print(SDCARD_FILE_HEADER_SDS011); #endif diff --git a/src/senddata.cpp b/src/senddata.cpp index d6067131..34e9000b 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -55,8 +55,14 @@ void SendPayload(uint8_t port, sendprio_t prio) { #endif // write data to sdcard, if present -#ifdef HAS_SDCARD - sdcardWriteData(macs_wifi, macs_ble); +#if (HAS_SDCARD) + if ( port == COUNTERPORT ) { + sdcardWriteData(macs_wifi, macs_ble +#if (COUNT_CWA) + , cwa_report() +#endif + ); + } #endif } // SendPayload @@ -143,22 +149,31 @@ void sendData() { #endif #if (HAS_SENSORS) +#if (HAS_SENSOR_1) case SENSOR1_DATA: payload.reset(); payload.addSensor(sensor_read(1)); SendPayload(SENSOR1PORT, prio_normal); +#if (COUNT_CWA) + cwa_clear(); +#endif break; +#endif +#if (HAS_SENSOR_2) case SENSOR2_DATA: payload.reset(); payload.addSensor(sensor_read(2)); SendPayload(SENSOR2PORT, prio_normal); break; +#endif +#if (HAS_SENSOR_3) case SENSOR3_DATA: payload.reset(); payload.addSensor(sensor_read(3)); SendPayload(SENSOR3PORT, prio_normal); break; #endif +#endif #if (defined BAT_MEASURE_ADC || defined HAS_PMU) case BATT_DATA: diff --git a/src/sensor.cpp b/src/sensor.cpp index abed9b75..230718ec 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -2,6 +2,14 @@ #include "globals.h" #include "sensor.h" +#if (COUNT_CWA) +#include "payload.h" +#include "corona.h" +#include "macsniff.h" + +extern PayloadConvert payload; +#endif + // Local logging tag static const char TAG[] = __FILE__; @@ -47,10 +55,14 @@ uint8_t *sensor_read(uint8_t sensor) { case 1: // insert user specific sensor data frames here */ +#if (COUNT_CWA) + payload.addCount( cwa_report(), MAC_SNIFF_BLE_CWA); +#else buf[0] = length; buf[1] = 0x01; buf[2] = 0x02; buf[3] = 0x03; +#endif break; case 2: @@ -71,4 +83,4 @@ uint8_t *sensor_read(uint8_t sensor) { } return buf; -} \ No newline at end of file +}