Merge pull request #641 from cyberman54/master

sync dev to master
This commit is contained in:
Verkehrsrot 2020-09-27 11:59:27 +02:00 committed by GitHub
commit 4d2bde6cbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 285 additions and 186 deletions

View File

@ -79,7 +79,7 @@ Some <b>3D printable cases</b> can be found (and, if wanted so, ordered) on Thin
for example.<br>
<b>Power consumption</b> was metered at around 450 - 1000mW, depending on board and user settings in paxcounter.conf.
By default bluetooth sniffing is disabled (#define *BLECOUNTER* 0 in paxcounter.conf). Enabling bluetooth costs 30% more power + 30% flash storage for the software stack. Proof of concept showed that for passenger flow metering wifi sniffing shows better results than bluetooth sniffing. If you enable bluetooth be aware that this goes on expense of wifi sniffing results, because then wifi and bt stack must share the 2,4 GHz RF ressources of ESP32. If you need to sniff wifi and bt in parallel and need best possible results, use two boards - one for wifi only and one for bt only - and add counted results.
By default bluetooth sniffing not installed (#define *BLECOUNTER* 0 in paxcounter.conf). Installing and enabling bluetooth costs 30% more power + 30% flash storage for the software stack. If you enable bluetooth be aware that this goes on expense of wifi sniffing results, because then wifi and bt stack must share the 2,4 GHz RF ressources of ESP32. If you need to sniff wifi and bt in parallel and need best possible results, use two boards - one for wifi only and one for bt only - and add counted results.
# Preparing
@ -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.
# mobile PaxCounter via https://opensensemap.org/
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
[{"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
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
@ -348,6 +360,9 @@ The device listenes for remote control commands on LoRaWAN Port 2. Multiple comm
Note: all settings are stored in NVRAM and will be reloaded when device starts.
Send for example `8386` as Downlink on Port 2 to get battery status and time/date from the device.
<img src="img/paxcounter_downlink_example.png">
0x01 set scan RSSI limit
1 ... 255 used for wifi and bluetooth scan radius (greater values increase scan radius, values 50...110 make sense)
@ -527,9 +542,9 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
# License
Copyright 2018 Oliver Brandmueller <ob@sysadm.in>
Copyright 2018-2020 Oliver Brandmueller <ob@sysadm.in>
Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de>
Copyright 2018-2020 Klaus Wilting <verkehrsrot@arcor.de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -556,4 +571,4 @@ Thanks to
- [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
- [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

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,77 +0,0 @@
// Copyright 2018-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __COEXIST_INTERNAL_H__
#define __COEXIST_INTERNAL_H__
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
COEX_PREFER_WIFI = 0,
COEX_PREFER_BT,
COEX_PREFER_BALANCE,
COEX_PREFER_NUM,
} coex_prefer_t;
/**
* @brief Init software coexist
* extern function for internal use.
*
* @return Init ok or failed.
*/
esp_err_t coex_init(void);
/**
* @brief De-init software coexist
* extern function for internal use.
*/
void coex_deinit(void);
/**
* @brief Pause software coexist
* extern function for internal use.
*/
void coex_pause(void);
/**
* @brief Resume software coexist
* extern function for internal use.
*/
void coex_resume(void);
/**
* @brief Get software coexist version string
* extern function for internal use.
* @return : version string
*/
const char *coex_version_get(void);
/**
* @brief Coexist performance preference set from libbt.a
* extern function for internal use.
*
* @param prefer : the prefer enumeration value
* @return : ESP_OK - success, other - failed
*/
esp_err_t coex_preference_set(coex_prefer_t prefer);
#ifdef __cplusplus
}
#endif
#endif /* __COEXIST_INTERNAL_H__ */

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);
void cwa_mac_add(uint16_t hashedmac);
void cwa_clear(void);
uint16_t cwa_report(void);
#endif

View File

@ -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);
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);
#endif

View File

@ -4,7 +4,6 @@
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
#include <esp_event_loop.h> // needed for Wifi event handler
#include <esp32-hal-timer.h> // needed for timers
#include <esp_coexist.h> // needed for showing coex sw version
#include "globals.h"
#include "reset.h"
@ -20,5 +19,6 @@
#include "sensor.h"
#include "lorawan.h"
#include "timekeeper.h"
#include "corona.h"
#endif

View File

@ -5,10 +5,9 @@
#include <stdio.h>
#include <SPI.h>
#ifdef HAS_SDCARD
#if (HAS_SDCARD)
#if HAS_SDCARD == 1
#include <mySD.h>
//#include <SD.h>
#elif HAS_SDCARD == 2
#include <SD_MMC.h>
#else
@ -39,8 +38,11 @@
#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);
#if (COUNT_ENS)
#define SDCARD_FILE_HEADER_CWA ",cwa"
#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 "display.h"
#include "sdcard.h"
#include "corona.h"
extern Ticker sendcycler;

View File

@ -3,8 +3,6 @@
// ESP32 Functions
#include <esp_wifi.h>
#include <esp_coexist.h>
#include "coexist_internal.h"
#include "hash.h" // Hash function for scrambling MAC addresses
#include "antenna.h" // code for switching wifi antennas

View File

@ -37,54 +37,53 @@ 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.12
; 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
debug_level = 3
extra_scripts = pre:build.py
otakeyfile = ota.conf
lorakeyfile = loraconf.h
lmicconfigfile = lmic_config.h
platform_espressif32 = espressif32@1.12.4
platform_espressif32 = espressif32@2.0.0
monitor_speed = 115200
upload_speed = 115200 ; set by build.py and taken from hal file
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
mcci-catena/MCCI LoRaWAN LMIC library @ ^3.2.0
lib_deps_display =
OneBitDisplay@1.5.0
QRCode@0.0.1
BitBang_I2C@2.1.1
TFT_eSPI@>=2.2.8
bitbank2/OneBitDisplay @ 1.5.0
ricmoo/QRCode @ ^0.0.1
bodmer/TFT_eSPI @ ^2.2.20
lib_deps_ledmatrix =
Ultrathin_LED_Matrix@>=1.0.0
seeed-studio/Ultrathin_LED_Matrix @ ^1.0.0
lib_deps_rgbled =
SmartLeds@>=1.2.0
roboticsbrno/SmartLeds @ ^1.2.1
lib_deps_gps =
1655@>=1.0.2 ; #1655 TinyGPSPlus by Mikal Hart
mikalhart/TinyGPSPlus @ ^1.0.2
lib_deps_sensors =
Adafruit Unified Sensor@>=1.1.4
Adafruit BME280 Library@>=2.0.2
Adafruit BMP085 Library@>=1.1.0
BSEC Software Library@1.5.1474
adafruit/Adafruit Unified Sensor @ ^1.1.4
adafruit/Adafruit BME280 Library @ ^2.1.0
adafruit/Adafruit BMP085 Library @ ^1.1.0
boschsensortec/BSEC Software Library @ 1.5.1474
https://github.com/ricki-z/SDS011.git
lib_deps_basic =
ArduinoJson@<6
76@>=1.2.4 ; #76 Timezone by Jack Christensen
274@>=2.3.5 ; #274 RTC by Michael Miller
SimpleButton
AXP202X_Library@>=1.1.2 ; AXP202 PMU lib by Lewis He
esp32-micro-sdcard
MQTT@>=2.4.7 ; MQTT client maintained by Joel Gaehwiler
bblanchon/ArduinoJson @ <6
jchristensen/Timezone @ ^1.2.4
makuna/RTC @ ^2.3.5
spacehuhn/SimpleButton
lewisxhe/AXP202X_Library @ ^1.1.2
geeksville/esp32-micro-sdcard @ ^0.1.1
256dpi/MQTT @ ^2.4.7
lib_deps_all =
${common.lib_deps_basic}
${common.lib_deps_lora}
@ -109,17 +108,19 @@ build_flags_all =
-mfix-esp32-psram-cache-issue
[env]
lib_ldf_mode = deep ; #632 Fixes compiler error with OneBitDisplay library
framework = arduino
board = esp32dev
board_build.partitions = min_spiffs.csv
upload_speed = ${common.upload_speed}
;upload_port = COM7
;upload_port = COM8
platform = ${common.platform_espressif32}
lib_deps = ${common.lib_deps_all}
build_flags = ${common.build_flags_all}
upload_protocol = ${common.upload_protocol}
extra_scripts = ${common.extra_scripts}
monitor_speed = ${common.monitor_speed}
monitor_filters = time, esp32_exception_decoder, default
[env:ota]
upload_protocol = custom

View File

@ -6,6 +6,11 @@
#define BT_BD_ADDR_HEX(addr) \
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[] = "\x16\x6f\xfd";
// local Tag for logging
static const char TAG[] = "bluetooth";
@ -109,6 +114,7 @@ const char *btsig_gap_type(uint32_t gap_type) {
// using IRAM_:ATTR here to speed up callback function
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 *p = (esp_ble_gap_cb_param_t *)param;
ESP_LOGV(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv,
@ -146,22 +152,29 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
}
#if (VENDORFILTER)
if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) ||
(p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) {
ESP_LOGV(TAG, "BT device filtered");
break;
}
#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
#if (COUNT_ENS)
uint16_t hashedmac =
#endif
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
#if (COUNT_ENS)
// check for ens signature
if (NULL != strstr((const char *)p->scan_rst.ble_adv, ensMagicBytes))
cwa_mac_add(hashedmac);
#endif
/* to be improved in vendorfilter if:
// you can search for elements in the payload using the
// function esp_ble_resolve_adv_data()
//
@ -237,10 +250,9 @@ void start_BLEscan(void) {
#if (BLECOUNTER)
ESP_LOGI(TAG, "Initializing bluetooth scanner ...");
ESP_ERROR_CHECK(esp_coex_preference_set(
ESP_COEX_PREFER_BALANCE)); // configure Wifi/BT coexist lib
// Initialize BT controller to allocate task and other resource.
ESP_ERROR_CHECK(esp_coex_preference_set(ESP_COEX_PREFER_BT));
btStart();
ESP_ERROR_CHECK(esp_bluedroid_init());
ESP_ERROR_CHECK(esp_bluedroid_enable());
@ -259,8 +271,7 @@ void stop_BLEscan(void) {
ESP_ERROR_CHECK(esp_bluedroid_disable());
ESP_ERROR_CHECK(esp_bluedroid_deinit());
btStop(); // disable bt_controller
ESP_ERROR_CHECK(esp_coex_preference_set(
ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib
ESP_ERROR_CHECK(esp_coex_preference_set(ESP_COEX_PREFER_WIFI));
ESP_LOGI(TAG, "Bluetooth scanner stopped");
#endif // BLECOUNTER
} // stop_BLEscan

View File

@ -29,8 +29,8 @@ void defaultConfig() {
cfg.blescantime =
BLESCANINTERVAL /
10; // BT channel scan cycle [seconds/100], default 1 (= 10ms)
cfg.blescan = BLECOUNTER; // 0=disabled, 1=enabled
cfg.wifiscan = WIFICOUNTER; // 0=disabled, 1=enabled
cfg.blescan = 1; // 0=disabled, 1=enabled
cfg.wifiscan = 1; // 0=disabled, 1=enabled
cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
cfg.vendorfilter = VENDORFILTER; // 0=disabled, 1=enabled
cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%)

55
src/corona.cpp Normal file
View 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 &notifier : 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

View File

@ -237,7 +237,7 @@ void dp_drawPage(time_t t, bool nextpage) {
// display number of unique macs total Wifi + BLE
if (DisplayPage < 5) {
dp_setFont(MY_FONT_STRETCHED);
dp_printf("PAX:%-4d", macs.size());
dp_printf("%-5d", macs.size());
}
switch (DisplayPage) {
@ -265,7 +265,11 @@ void dp_drawPage(time_t t, bool nextpage) {
else
dp_printf("WIFI:off");
if (cfg.blescan)
#if (!COUNT_ENS)
dp_printf("BLTH:%-5d", macs_ble);
#else
dp_printf(" CWA:%-5d", cwa_report());
#endif
else
dp_printf(" BLTH:off");
#elif ((WIFICOUNTER) && (!BLECOUNTER))
@ -274,9 +278,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_ENS)
dp_printf("(CWA:%d)", cwa_report());
#endif
} else
dp_printf("BLTH:off");
#else
dp_printf("Sniffer disabled");
@ -349,18 +356,17 @@ void dp_drawPage(time_t t, bool nextpage) {
#if (HAS_LORA)
// 3|NtwkID:000000 TXpw:aa
// 4|DevAdd:00000000 DR:0
// 3|Net:000000 Pwr:aa
// 4|Dev:00000000 DR:0
// 5|CHMsk:0000 Nonce:0000
// 6|CUp:000000 CDn:000000
// 6|fUp:000000 fDn:000000
// 7|SNR:-0000 RSSI:-0000
dp_setFont(MY_FONT_SMALL);
dp_setTextCursor(0, 3);
dp_printf("NetwID:%06X TXpw:%-2d", LMIC.netid & 0x001FFFFF,
LMIC.radio_txpow);
dp_printf("Net:%06X Pwr:%-2d", LMIC.netid & 0x001FFFFF, LMIC.radio_txpow);
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_printf("ChMsk:%04X Nonce:%04X", LMIC.channelMap, LMIC.devNonce);
dp_println();

View File

@ -16,7 +16,7 @@
#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

View File

@ -495,10 +495,9 @@ uint8_t myBattLevelCb(void *pUserData) {
#elif defined HAS_IP5306
if (IP5306_GetPowerSource())
return MCMD_DEVS_EXT_POWER;
#else
return (batt_percent / 100.0 *
(MCMD_DEVS_BATT_MAX - MCMD_DEVS_BATT_MIN + 1));
#endif // HAS_PMU
return (batt_percent / 100.0 * (MCMD_DEVS_BATT_MAX - MCMD_DEVS_BATT_MIN + 1));
}
// event EV_RXCOMPLETE message handler
@ -582,7 +581,8 @@ const char *getCrName(rps_t rps) {
#if (VERBOSE)
// decode LORAWAN MAC message
// see https://github.com/mcci-catena/arduino-lmic/blob/master/doc/LoRaWAN-at-a-glance.pdf
// see
// https://github.com/mcci-catena/arduino-lmic/blob/master/doc/LoRaWAN-at-a-glance.pdf
void mac_decode(const uint8_t cmd[], const uint8_t cmdlen, bool is_down) {
if (!cmdlen)

View File

@ -10,7 +10,7 @@
// Local logging tag
static const char TAG[] = __FILE__;
uint16_t salt;
uint16_t salt = 0;
uint16_t get_salt(void) {
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);
}
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)
return false;
if (salt == 0) // ensure we have salt (appears after radio is turned on)
return 0;
uint16_t hashedmac = 0; // temporary buffer for generated hash value
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
@ -116,13 +116,20 @@ 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 -> "
"%d Bytes left",
"BLTH:%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, getFreeRAM());
hashedmac, macs_wifi, macs_ble,
#if (COUNT_ENS)
cwa_report(),
#endif
getFreeRAM());
#if (VENDORFILTER)
} else {
@ -132,7 +139,7 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
}
#endif
// True if MAC WiFi/BLE was new
return added; // function returns bool if a new and unique Wifi or BLE mac was
// counted (true) or not (false)
// if a new and unique Wifi or BLE mac was counted, returs hash of this mac,
// else 0
return hashedmac;
}

View File

@ -2,8 +2,8 @@
//////////////////////// ESP32-Paxcounter \\\\\\\\\\\\\\\\\\\\\\\\\\
Copyright 2018 Oliver Brandmueller <ob@sysadm.in>
Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de>
Copyright 2018-2020 Oliver Brandmueller <ob@sysadm.in>
Copyright 2018-2020 Klaus Wilting <verkehrsrot@arcor.de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -312,9 +312,25 @@ void setup() {
// initialize 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();
#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
@ -386,8 +402,13 @@ void setup() {
#if (WIFICOUNTER)
strcat_P(features, " WIFI");
// start wifi in monitor mode and start channel rotation timer
ESP_LOGI(TAG, "Starting Wifi...");
wifi_sniffer_init();
if (cfg.blescan) {
ESP_LOGI(TAG, "Starting Wifi...");
switch_wifi_sniffer(1);
} else
switch_wifi_sniffer(0);
#else
// switch off wifi
esp_wifi_deinit();

View File

@ -7,23 +7,33 @@
// Note: After editing, before "build", use "clean" button in PlatformIO!
// Verbose enables additional serial debug output
#define VERBOSE 0 // set to 0 to silence the device, for mute use build option
#define VERBOSE 1 // set to 0 to silence the device, for mute use build option
// Payload send cycle and encoding
#define SENDCYCLE 30 // payload send cycle [seconds/2], 0 .. 255
#define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed
#define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed
#define COUNTERMODE 1 // 0=cyclic, 1=cumulative, 2=cyclic confirmed
// 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 WIFICOUNTER 1 // set it to 0 if you want to switch off WIFI count
#define VENDORFILTER 0 // set to 0 if you want to scan all devices, not filtering smartphone OUIs
#define BLECOUNTER 0 // set to 0 if you do not want to install the BLE sniffer
#define WIFICOUNTER 1 // set to 0 if you do not want to install the WIFI sniffer
// BLE scan parameters
#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 BLESCANINTERVAL 80 // [illiseconds] scan interval, see below, 3 .. 10240, default 80ms = 100% duty cycle
// Corona Exposure Notification Service(ENS) counter
#define COUNT_ENS 0 // 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 0 // 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
*
* |< Scan Window > |< Scan Window > | ... |< Scan Window > |
@ -92,7 +102,7 @@
#define RCMDPORT 2 // remote commands
#define STATUSPORT 2 // remote command results
#define CONFIGPORT 3 // config query results
#define GPSPORT 1 // gps - set to 1 to send combined GPS+COUNTERPORT payload
#define GPSPORT 4 // gps - NOTE: set to 1 to send combined GPS+COUNTERPORT payload
#define BUTTONPORT 5 // button pressed signal
#define BEACONPORT 6 // beacon alarms
#define BMEPORT 7 // BME680 sensor

View File

@ -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_ENS)
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_ENS)
fileSDCard.print(SDCARD_FILE_HEADER_CWA); // for Corona-data (CWA)
#endif
#if (HAS_SDS011)
fileSDCard.print(SDCARD_FILE_HEADER_SDS011);
#endif

View File

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

View File

@ -2,6 +2,14 @@
#include "globals.h"
#include "sensor.h"
#if (COUNT_ENS)
#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_ENS)
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:

View File

@ -191,7 +191,7 @@ void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) {
// flag: length of buffer
// Store the instant the time request of the node was received on the gateway
timesync_store(osticks2ms(os_getTime(), timesync_rx);
timesync_store(osticks2ms(os_getTime()), timesync_rx);
// parse pUserData:
// p type meaning

View File

@ -73,14 +73,12 @@ void wifi_sniffer_init(void) {
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); // no modem power saving
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filter)); // set frame filter
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler));
ESP_ERROR_CHECK(esp_wifi_start()); // for esp_wifi v3.3
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode
// setup wifi channel rotation timer
WifiChanTimer =
xTimerCreate("WifiChannelTimer", pdMS_TO_TICKS(cfg.wifichancycle * 10),
pdTRUE, (void *)0, switchWifiChannel);
switch_wifi_sniffer(1);
}
void switch_wifi_sniffer(uint8_t state) {