libpax-only initial push

This commit is contained in:
cyberman54 2021-03-25 10:30:38 +01:00
parent 2854f2dd13
commit cc7508aa41
22 changed files with 106 additions and 1000 deletions

View File

@ -1,17 +0,0 @@
#ifndef _BLESCAN_H
#define _BLESCAN_H
#include "globals.h"
#include "macsniff.h"
// Bluetooth specific includes
#include <esp_bt.h>
#include <esp_bt_main.h>
#include <esp_gap_ble_api.h>
#include <esp_blufi_api.h> // needed for BLE_ADDR types, do not remove
#include <esp_coexist.h>
void start_BLEscan(void);
void stop_BLEscan(void);
#endif

View File

@ -1,6 +1,7 @@
#ifndef _CYCLIC_H
#define _CYCLIC_H
#include <libpax_api.h>
#include "globals.h"
#include "senddata.h"
#include "rcommand.h"
@ -10,11 +11,8 @@
#include "display.h"
#include "sds011read.h"
#include "sdcard.h"
#include "macsniff.h"
#include "reset.h"
#if LIBPAX
#include <libpax_api.h>
#endif
#include "led.h"
extern Ticker cyclicTimer;

View File

@ -15,7 +15,6 @@
#include <set>
#include <array>
#include <algorithm>
#include "mallocator.h"
#include <bsec.h>
#define _bit(b) (1U << (b))
@ -100,13 +99,6 @@ typedef struct {
uint8_t Message[PAYLOAD_BUFFER_SIZE];
} MessageBuffer_t;
// Struct for MAC processing queue
typedef struct {
uint8_t mac[6];
int8_t rssi;
snifftype_t sniff_type;
} MacBuffer_t;
typedef struct {
int32_t latitude;
int32_t longitude;
@ -131,7 +123,6 @@ typedef struct {
float pm25;
} sdsStatus_t;
extern std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
extern std::array<uint64_t, 0xff>::iterator it;
extern std::array<uint64_t, 0xff> beacons;
@ -140,15 +131,12 @@ extern char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer
extern uint8_t volatile channel; // wifi channel rotation counter
extern uint8_t volatile rf_load; // RF traffic indicator
extern uint8_t batt_level; // display value
extern uint16_t volatile macs_wifi, macs_ble; // display values
#if LIBPAX
extern uint16_t volatile libpax_macs_ble, libpax_macs_wifi; // libpax values
#endif
extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC
extern timesource_t timeSource;
extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ;
extern SemaphoreHandle_t I2Caccess;
extern TaskHandle_t irqHandlerTask, ClockTask, macProcessTask;
extern TaskHandle_t irqHandlerTask, ClockTask;
extern TimerHandle_t WifiChanTimer;
extern Timezone myTZ;

View File

@ -1,25 +0,0 @@
#ifndef _MACSNIFF_H
#define _MACSNIFF_H
// ESP32 Functions
#include <esp_wifi.h>
// Hash function for scrambling MAC addresses
#include "hash.h"
#include "senddata.h"
#include "cyclic.h"
#include "led.h"
#if (COUNT_ENS)
#include "corona.h"
#endif
uint32_t renew_salt(void);
uint64_t macConvert(uint8_t *paddr);
esp_err_t macQueueInit(void);
void mac_process(void *pvParameters);
void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type);
uint16_t mac_analyze(MacBuffer_t MacBuffer);
void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb);
#endif

View File

@ -8,8 +8,6 @@
#include "globals.h"
#include "reset.h"
#include "i2c.h"
#include "blescan.h"
#include "wifiscan.h"
#include "configmanager.h"
#include "cyclic.h"
#include "beacon_array.h"

View File

@ -1,54 +0,0 @@
/*
This Mallocator code was taken from:
CppCon2014 Presentations
STL Features And Implementation Techniques
Stephan T. Lavavej
https://github.com/CppCon/CppCon2014
*/
#ifndef _MALLOCATOR_H
#define _MALLOCATOR_H
#include <stdlib.h> // size_t, malloc, free
#include <new> // bad_alloc, bad_array_new_length
#include "esp32-hal-psram.h" // ps_malloc
template <class T> struct Mallocator {
typedef T value_type;
Mallocator() noexcept {} // default ctor not required
template <class U> Mallocator(const Mallocator<U> &) noexcept {}
template <class U> bool operator==(const Mallocator<U> &) const noexcept {
return true;
}
template <class U> bool operator!=(const Mallocator<U> &) const noexcept {
return false;
}
T *allocate(const size_t n) const {
if (n == 0) {
return nullptr;
}
if (n > static_cast<size_t>(-1) / sizeof(T)) {
throw std::bad_array_new_length();
}
#ifndef BOARD_HAS_PSRAM
void *const pv = malloc(n * sizeof(T));
#else
void *const pv = ps_malloc(n * sizeof(T));
#endif
if (!pv) {
throw std::bad_alloc();
}
return static_cast<T *>(pv);
}
void deallocate(T *const p, size_t) const noexcept { free(p); }
};
#endif

View File

@ -8,12 +8,9 @@
#include "configmanager.h"
#include "lorawan.h"
#include "sensor.h"
#include "macsniff.h"
#include "wifiscan.h"
#include "cyclic.h"
#include "timekeeper.h"
#include "timesync.h"
#include "blescan.h"
// maximum number of elements in rcommand interpreter queue
#define RCMD_QUEUE_SIZE 5

View File

@ -1,6 +1,7 @@
#ifndef _SENDDATA_H
#define _SENDDATA_H
#include <libpax_api.h>
#include "spislave.h"
#include "mqttclient.h"
#include "cyclic.h"
@ -9,18 +10,11 @@
#include "display.h"
#include "sdcard.h"
#if (COUNT_ENS)
#include "corona.h"
#endif
#if LIBPAX
#include <libpax_api.h>
extern struct count_payload_t count_from_libpax;
#endif
extern Ticker sendTimer;
void SendPayload(uint8_t port);

View File

@ -1,19 +0,0 @@
#ifndef _WIFISCAN_H
#define _WIFISCAN_H
// ESP32 Functions
#include <esp_wifi.h>
#include "hash.h" // Hash function for scrambling MAC addresses
#include "antenna.h" // code for switching wifi antennas
#include "macsniff.h"
extern TimerHandle_t WifiChanTimer;
void wifi_sniffer_init(void);
void switch_wifi_sniffer(uint8_t state);
void IRAM_ATTR wifi_sniffer_packet_handler(void *buff,
wifi_promiscuous_pkt_type_t type);
void switchWifiChannel(TimerHandle_t xTimer);
#endif

View File

@ -1,304 +0,0 @@
#if !(LIBPAX)
// some code snippets taken from
// https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
#include "blescan.h"
#define BT_BD_ADDR_HEX(addr) \
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
// local Tag for logging
static const char TAG[] = "bluetooth";
#ifdef VERBOSE
const char *bt_addr_t_to_string(esp_ble_addr_type_t type) {
switch (type) {
case BLE_ADDR_TYPE_PUBLIC:
return "BLE_ADDR_TYPE_PUBLIC";
case BLE_ADDR_TYPE_RANDOM:
return "BLE_ADDR_TYPE_RANDOM";
case BLE_ADDR_TYPE_RPA_PUBLIC:
return "BLE_ADDR_TYPE_RPA_PUBLIC";
case BLE_ADDR_TYPE_RPA_RANDOM:
return "BLE_ADDR_TYPE_RPA_RANDOM";
default:
return "Unknown addr_t";
}
} // bt_addr_t_to_string
const char *btsig_gap_type(uint32_t gap_type) {
switch (gap_type) {
case 0x01:
return "Flags";
case 0x02:
return "Incomplete List of 16-bit Service Class UUIDs";
case 0x03:
return "Complete List of 16-bit Service Class UUIDs";
case 0x04:
return "Incomplete List of 32-bit Service Class UUIDs";
case 0x05:
return "Complete List of 32-bit Service Class UUIDs";
case 0x06:
return "Incomplete List of 128-bit Service Class UUIDs";
case 0x07:
return "Complete List of 128-bit Service Class UUIDs";
case 0x08:
return "Shortened Local Name";
case 0x09:
return "Complete Local Name";
case 0x0A:
return "Tx Power Level";
case 0x0D:
return "Class of Device";
case 0x0E:
return "Simple Pairing Hash C/C-192";
case 0x0F:
return "Simple Pairing Randomizer R/R-192";
case 0x10:
return "Device ID/Security Manager TK Value";
case 0x11:
return "Security Manager Out of Band Flags";
case 0x12:
return "Slave Connection Interval Range";
case 0x14:
return "List of 16-bit Service Solicitation UUIDs";
case 0x1F:
return "List of 32-bit Service Solicitation UUIDs";
case 0x15:
return "List of 128-bit Service Solicitation UUIDs";
case 0x16:
return "Service Data - 16-bit UUID";
case 0x20:
return "Service Data - 32-bit UUID";
case 0x21:
return "Service Data - 128-bit UUID";
case 0x22:
return "LE Secure Connections Confirmation Value";
case 0x23:
return "LE Secure Connections Random Value";
case 0x24:
return "URI";
case 0x25:
return "Indoor Positioning";
case 0x26:
return "Transport Discovery Data";
case 0x17:
return "Public Target Address";
case 0x18:
return "Random Target Address";
case 0x19:
return "Appearance";
case 0x1A:
return "Advertising Interval";
case 0x1B:
return "LE Bluetooth Device Address";
case 0x1C:
return "LE Role";
case 0x1D:
return "Simple Pairing Hash C-256";
case 0x1E:
return "Simple Pairing Randomizer R-256";
case 0x3D:
return "3D Information Data";
case 0xFF:
return "Manufacturer Specific Data";
default:
return "Unknown type";
}
} // btsig_gap_type
#endif
// 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;
#if (COUNT_ENS)
// UUID of Exposure Notification Service (ENS)
// https://blog.google/documents/70/Exposure_Notification_-_Bluetooth_Specification_v1.2.2.pdf
static const char ensMagicBytes[] = "\x16\x6f\xfd";
#endif
#ifdef VERBOSE
ESP_LOGV(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv,
btsig_gap_type(*p->scan_rst.ble_adv));
#endif
switch (event) {
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
// restart scan
esp_ble_gap_start_scanning(BLESCANTIME);
break;
case ESP_GAP_BLE_SCAN_RESULT_EVT:
// evaluate scan results
if (p->scan_rst.search_evt ==
ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
{ // restart scan
esp_ble_gap_start_scanning(BLESCANTIME);
return;
}
if (p->scan_rst.search_evt ==
ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
{ // evaluate sniffed packet
#ifdef VERBOSE
ESP_LOGV(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x",
BT_BD_ADDR_HEX(p->scan_rst.bda));
ESP_LOGV(TAG, "Addr_type : %s",
bt_addr_t_to_string(p->scan_rst.ble_addr_type));
ESP_LOGV(TAG, "RSSI : %d", p->scan_rst.rssi);
#endif
#if (MACFILTER)
if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) ||
(p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) {
#ifdef VERBOSE
ESP_LOGV(TAG, "BT device filtered");
#endif
break;
}
#endif
// add this device mac to processing queue
#if (COUNT_ENS)
// check for ens signature
if (cfg.enscount) {
if (strstr((const char *)p->scan_rst.ble_adv, ensMagicBytes) != NULL)
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi,
MAC_SNIFF_BLE_ENS);
else
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
}
#else
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
#endif
/* to be improved in macfilter:
// you can search for elements in the payload using the
// function esp_ble_resolve_adv_data()
//
// Like this, that scans for the "Complete name" (looking inside the
payload buffer)
// uint8_t len;
// uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv,
ESP_BLE_AD_TYPE_NAME_CMPL, &len);
filter BLE devices using their advertisements to get filter alternative
to vendor OUI if macfiltering is on, we ...
- want to count: mobile phones and tablets
- don't want to count: beacons, peripherals (earphones, headsets,
printers), cars and machines see
https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp
http://www.libelium.com/products/meshlium/smartphone-detection/
https://www.question-defense.com/2013/01/12/bluetooth-cod-bluetooth-class-of-deviceclass-of-service-explained
https://www.bluetooth.com/specifications/assigned-numbers/baseband
"The Class of Device (CoD) in case of Bluetooth which allows us to
differentiate the type of device (smartphone, handsfree, computer,
LAN/network AP). With this parameter we can differentiate among
pedestrians and vehicles."
*/
} // evaluate sniffed packet
break;
default:
break;
} // switch
} // gap_callback_handler
esp_err_t register_ble_callback(bool unregister = false) {
if (unregister) {
ESP_LOGI(TAG, "Unregister GAP callback...");
esp_ble_gap_stop_scanning();
esp_ble_gap_register_callback(NULL);
}
else {
ESP_LOGI(TAG, "Register GAP callback...");
// This function is called when gap event occurs, such as scan result.
// register the scan callback function to the gap module
esp_ble_gap_register_callback(&gap_callback_handler);
static esp_ble_scan_params_t ble_scan_params = {
.scan_type = BLE_SCAN_TYPE_PASSIVE,
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
/*
#if (MACFILTER)
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR,
// ADV_IND, ADV_NONCONN_IND, ADV_SCAN_IND packets are used
for broadcasting
// data in broadcast applications (e.g., Beacons), so we
don't want them in
// macfilter mode
#else
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
#endif
*/
.scan_interval =
(uint16_t)(cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec
.scan_window =
(uint16_t)(BLESCANWINDOW / 0.625), // Time = N * 0.625 msec
.scan_duplicate = BLE_SCAN_DUPLICATE_ENABLE};
ESP_LOGI(TAG, "Set GAP scan parameters");
// This function is called to set scan parameters.
esp_ble_gap_set_scan_params(&ble_scan_params);
}
return ESP_OK;
} // register_ble_callback
void start_BLEscan(void) {
#if (BLECOUNTER)
ESP_LOGI(TAG, "Initializing bluetooth scanner ...");
// Initialize BT controller to allocate task and other resource.
if (btStart()) { // enable bt_controller
esp_coex_preference_set(ESP_COEX_PREFER_BT);
esp_bluedroid_init();
esp_bluedroid_enable();
// Register callback function for capturing bluetooth packets
register_ble_callback(false);
ESP_LOGI(TAG, "Bluetooth scanner started");
} else {
ESP_LOGE(TAG, "Bluetooth controller start failed. Resetting device");
do_reset(true);
}
#endif // BLECOUNTER
} // start_BLEscan
void stop_BLEscan(void) {
#if (BLECOUNTER)
ESP_LOGI(TAG, "Shutting down bluetooth scanner ...");
register_ble_callback(true); // unregister capture function
ESP_LOGD(TAG, "bluedroid disable...");
esp_bluedroid_disable();
ESP_LOGD(TAG, "bluedroid deinit...");
esp_bluedroid_deinit();
if (!btStop()) { // disable bt_controller
ESP_LOGE(TAG, "Bluetooth controller stop failed. Resetting device");
do_reset(true);
}
esp_coex_preference_set(ESP_COEX_PREFER_WIFI);
ESP_LOGI(TAG, "Bluetooth scanner stopped");
#endif // BLECOUNTER
} // stop_BLEscan
#endif

View File

@ -29,11 +29,6 @@ void doHousekeeping() {
ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d",
uxTaskGetStackHighWaterMark(irqHandlerTask),
eTaskGetState(irqHandlerTask));
#if !(LIBPAX)
ESP_LOGD(TAG, "MACprocessor %d bytes left | Taskstate = %d",
uxTaskGetStackHighWaterMark(macProcessTask),
eTaskGetState(macProcessTask));
#endif
ESP_LOGD(TAG, "Rcommand interpreter %d bytes left | Taskstate = %d",
uxTaskGetStackHighWaterMark(rcmdTask), eTaskGetState(rcmdTask));
#if (HAS_LORA)
@ -138,12 +133,6 @@ uint32_t getFreeRAM() {
void reset_counters() {
#if ((WIFICOUNTER) || (BLECOUNTER))
#if !(LIBPAX)
macs.clear(); // clear all macs container
macs_wifi = 0;
macs_ble = 0;
renew_salt(); // get new salt
#endif
#ifdef HAS_DISPLAY
dp_plotCurve(0, true);
#endif

View File

@ -262,11 +262,7 @@ void dp_drawPage(time_t t, bool nextpage) {
#if ((WIFICOUNTER) && (BLECOUNTER))
if (cfg.wifiscan)
#if !(LIBPAX)
dp_printf("WIFI:%-5d", macs_wifi);
#else
dp_printf("WIFI:%-5d", libpax_macs_wifi);
#endif
else
dp_printf("WIFI:off");
if (cfg.blescan)
@ -275,29 +271,17 @@ void dp_drawPage(time_t t, bool nextpage) {
dp_printf(" CWA:%-5d", cwa_report());
else
#endif
#if !(LIBPAX)
dp_printf("BLTH:%-5d", macs_ble);
#else
dp_printf("BLTH:%-5d", libpax_macs_ble);
#endif
else
dp_printf(" BLTH:off");
#elif ((WIFICOUNTER) && (!BLECOUNTER))
if (cfg.wifiscan)
#if !(LIBPAX)
dp_printf("WIFI:%-5d", macs_wifi);
#else
dp_printf("WIFI:%-5d", libpax_macs_wifi);
#endif
else
dp_printf("WIFI:off");
#elif ((!WIFICOUNTER) && (BLECOUNTER))
if (cfg.blescan)
#if !(LIBPAX)
dp_printf("BLTH:%-5d", macs_ble);
#else
dp_printf("BLTH:%-5d", libpax_macs_ble);
#endif
#if (COUNT_ENS)
if (cfg.enscount)
dp_printf("(CWA:%d)", cwa_report());

View File

@ -1,18 +1,17 @@
#include "libpax_helpers.h"
// libpax payload
#if LIBPAX
struct count_payload_t count_from_libpax;
uint16_t volatile libpax_macs_ble, libpax_macs_wifi;
void process_count(void) {
printf("pax: %d; %d; %d;\n", count_from_libpax.pax, count_from_libpax.wifi_count, count_from_libpax.ble_count);
printf("pax: %d; %d; %d;\n", count_from_libpax.pax,
count_from_libpax.wifi_count, count_from_libpax.ble_count);
libpax_macs_ble = count_from_libpax.ble_count;
libpax_macs_wifi = count_from_libpax.wifi_count;
}
void init_libpax() {
libpax_counter_init(process_count, &count_from_libpax, 60*1000, 1);
libpax_counter_start();
}
#endif
libpax_counter_init(process_count, &count_from_libpax, 60 * 1000, 1);
libpax_counter_start();
}

View File

@ -163,6 +163,18 @@ void os_getDevEui(u1_t *buf) {
#if (VERBOSE)
// Display a key
void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb) {
const uint8_t *p;
char keystring[len + 1] = "", keybyte[3];
for (uint8_t i = 0; i < len; i++) {
p = lsb ? key + len - i - 1 : key + i;
snprintf(keybyte, 3, "%02X", *p);
strncat(keystring, keybyte, 2);
}
ESP_LOGI(TAG, "%s: %s", name, keystring);
}
// Display OTAA keys
void showLoraKeys(void) {
// LMIC may not have used callback to fill

View File

@ -1,198 +0,0 @@
// Basic Config
#include "globals.h"
#include "macsniff.h"
// Local logging tag
static const char TAG[] = __FILE__;
static QueueHandle_t MacQueue;
TaskHandle_t macProcessTask;
static uint32_t salt = renew_salt();
uint32_t renew_salt(void) {
salt = esp_random();
ESP_LOGV(TAG, "new salt = %04X", salt);
return salt;
}
int8_t isBeacon(uint64_t mac) {
it = std::find(beacons.begin(), beacons.end(), mac);
if (it != beacons.end())
return std::distance(beacons.begin(), it);
else
return -1;
}
// Display a key
void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb) {
const uint8_t *p;
char keystring[len + 1] = "", keybyte[3];
for (uint8_t i = 0; i < len; i++) {
p = lsb ? key + len - i - 1 : key + i;
snprintf(keybyte, 3, "%02X", *p);
strncat(keystring, keybyte, 2);
}
ESP_LOGI(TAG, "%s: %s", name, keystring);
}
uint64_t macConvert(uint8_t *paddr) {
uint64_t *mac;
mac = (uint64_t *)paddr;
return (__builtin_bswap64(*mac) >> 16);
}
esp_err_t macQueueInit() {
_ASSERT(MAC_QUEUE_SIZE > 0);
MacQueue = xQueueCreate(MAC_QUEUE_SIZE, sizeof(MacBuffer_t));
if (MacQueue == 0) {
ESP_LOGE(TAG, "Could not create MAC processing queue. Aborting.");
return ESP_FAIL;
}
ESP_LOGI(TAG, "MAC processing queue created, size %d Bytes",
MAC_QUEUE_SIZE * sizeof(MacBuffer_t));
xTaskCreatePinnedToCore(mac_process, // task function
"mac_process", // name of task
3072, // stack size of task
(void *)1, // parameter of the task
1, // priority of the task
&macProcessTask, // task handle
1); // CPU core
return ESP_OK;
}
// sniffed MAC processing task
void mac_process(void *pvParameters) {
_ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check
MacBuffer_t MacBuffer;
while (1) {
// fetch next or wait for incoming MAC from sniffing queue
if (xQueueReceive(MacQueue, &MacBuffer, portMAX_DELAY) != pdTRUE) {
ESP_LOGE(TAG, "Premature return from xQueueReceive() with no data!");
continue;
}
// update traffic indicator
rf_load = uxQueueMessagesWaiting(MacQueue);
// process fetched mac
mac_analyze(MacBuffer);
}
delay(2); // yield to CPU
}
// enqueue message in MAC processing queue
void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) {
MacBuffer_t MacBuffer;
MacBuffer.rssi = rssi;
MacBuffer.sniff_type = sniff_type;
memcpy(MacBuffer.mac, paddr, 6);
if (xQueueSendToBackFromISR(MacQueue, (void *)&MacBuffer, (TickType_t)0) !=
pdPASS)
ESP_LOGW(TAG, "Dense radio traffic, packet lost!");
}
uint16_t mac_analyze(MacBuffer_t MacBuffer) {
uint32_t *mac; // pointer to shortened 4 byte MAC
uint32_t saltedmac;
uint16_t hashedmac;
if ((cfg.rssilimit) &&
(MacBuffer.rssi < cfg.rssilimit)) { // rssi is negative value
ESP_LOGI(TAG, "%s RSSI %d -> ignoring (limit: %d)",
(MacBuffer.sniff_type == MAC_SNIFF_WIFI) ? "WIFI" : "BLTH",
MacBuffer.rssi, cfg.rssilimit);
return 0;
}
// in beacon monitor mode check if seen MAC is a known beacon
if (cfg.monitormode) {
int8_t beaconID = isBeacon(macConvert(MacBuffer.mac));
if (beaconID >= 0) {
ESP_LOGI(TAG, "Beacon ID#%d detected", beaconID);
blink_LED(COLOR_WHITE, 2000);
payload.reset();
payload.addAlarm(MacBuffer.rssi, beaconID);
SendPayload(BEACONPORT);
}
};
// only last 3 MAC Address bytes are used for MAC address anonymization
// but since it's uint32 we take 4 bytes to avoid 1st value to be 0.
// this gets MAC in msb (= reverse) order, but doesn't matter for hashing it.
mac = (uint32_t *)(MacBuffer.mac + 2);
// salt and hash MAC, and if new unique one, store identifier in container
// and increment counter on display
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
// reversed 4 byte MAC added to current salt
saltedmac = *mac + salt;
// hashed 4 byte MAC
// to save RAM, we use only lower 2 bytes of hash, since collisions don't
// matter in our use case
hashedmac = myhash((const char *)&saltedmac, 4);
auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique
bool added =
newmac.second ? true : false; // true if hashed MAC is unique in container
// Count only if MAC was not yet seen
if (added) {
switch (MacBuffer.sniff_type) {
case MAC_SNIFF_WIFI:
macs_wifi++; // increment Wifi MACs counter
blink_LED(COLOR_GREEN, 50);
break;
case MAC_SNIFF_BLE:
macs_ble++; // increment BLE Macs counter
blink_LED(COLOR_MAGENTA, 50);
break;
#if (COUNT_ENS)
case MAC_SNIFF_BLE_ENS:
macs_ble++; // increment BLE Macs counter
cwa_mac_add(hashedmac); // process ENS beacon
blink_LED(COLOR_WHITE, 50);
break;
#endif
default:
break;
} // switch
} // added
// Log scan result
ESP_LOGV(TAG,
"%s %s RSSI %ddBi -> MAC %0x:%0x:%0x:%0x:%0x:%0x -> salted %04X"
" -> hashed %04X -> WiFi:%d "
"BLTH:%d "
#if (COUNT_ENS)
"(CWA:%d)"
#endif
"-> %d Bytes left",
added ? "new " : "known",
MacBuffer.sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH",
MacBuffer.rssi, MacBuffer.mac[0], MacBuffer.mac[1], MacBuffer.mac[2],
MacBuffer.mac[3], MacBuffer.mac[4], MacBuffer.mac[5], saltedmac,
hashedmac, macs_wifi, macs_ble,
#if (COUNT_ENS)
cwa_report(),
#endif
getFreeRAM());
// if an unknown Wifi or BLE mac was counted, return hash of this mac, else 0
return (added ? hashedmac : 0);
}

View File

@ -38,7 +38,6 @@ timesync_proc 1 3 processes realtime time sync requests
irqhandler 1 2 cyclic tasks (i.e. displayrefresh) triggered by timers
gpsloop 1 1 reads data from GPS via serial or i2c
lorasendtask 1 1 feeds data from lora sendqueue to lmcic
macprocess 1 1 MAC analyzer loop
rmcd_process 1 1 Remote command interpreter loop
IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator
@ -91,13 +90,7 @@ triggers pps 1 sec impulse
configData_t cfg; // struct holds current device configuration
char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer for LMIC event message
uint8_t batt_level = 0; // display value
#if !(LIBPAX)
uint8_t volatile channel = WIFI_CHANNEL_MIN; // channel rotation counter
#endif
uint8_t volatile rf_load = 0; // RF traffic indicator
#if !(LIBPAX)
uint16_t volatile macs_wifi = 0, macs_ble = 0; // globals for display
#endif
uint8_t volatile rf_load = 0; // RF traffic indicator
hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL;
@ -106,10 +99,6 @@ SemaphoreHandle_t I2Caccess;
bool volatile TimePulseTick = false;
timesource_t timeSource = _unsynced;
// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
// if present
DRAM_ATTR std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
// initialize payload encoder
PayloadConvert payload(PAYLOAD_BUFFER_SIZE);
@ -118,7 +107,6 @@ TimeChangeRule myDST = DAYLIGHT_TIME;
TimeChangeRule mySTD = STANDARD_TIME;
Timezone myTZ(myDST, mySTD);
// local Tag for logging
static const char TAG[] = __FILE__;
@ -304,13 +292,8 @@ void setup() {
if (RTC_runmode == RUNMODE_MAINTENANCE)
start_boot_menu();
#if !(LIBPAX)
// start mac processing task
ESP_LOGI(TAG, "Starting MAC processor...");
macQueueInit();
#else
ESP_LOGI(TAG, "Starting libpax...");
#if (defined WIFICOUNTER || defined BLECOUNTER)
#if (defined WIFICOUNTER || defined BLECOUNTER)
struct libpax_config_t configuration;
libpax_default_config(&configuration);
ESP_LOGI(TAG, "BLESCAN: %d", cfg.blescan);
@ -325,40 +308,21 @@ void setup() {
configuration.blescantime = cfg.blescantime;
int config_update = libpax_update_config(&configuration);
if(config_update != 0) {
if (config_update != 0) {
ESP_LOGE(TAG, "Error in libpax configuration.");
} else {
init_libpax();
}
#endif
#if (BLECOUNTER)
strcat_P(features, " BLE");
#endif
// start rcommand processing task
ESP_LOGI(TAG, "Starting rcommand interpreter...");
rcmd_init();
// start BLE scan callback if BLE function is enabled in NVRAM configuration
// or remove bluetooth stack from RAM, if option bluetooth is not compiled
#if (BLECOUNTER)
strcat_P(features, " BLE");
#if !(LIBPAX)
if (cfg.blescan) {
ESP_LOGI(TAG, "Starting Bluetooth...");
start_BLEscan();
} else
btStop();
#endif
#else
// remove bluetooth stack to gain more free memory
#if !(LIBPAX)
btStop();
esp_bt_mem_release(ESP_BT_MODE_BTDM);
esp_coex_preference_set(
ESP_COEX_PREFER_WIFI); // configure Wifi/BT coexist lib
#endif
#endif
// initialize gps
#if (HAS_GPS)
strcat_P(features, " GPS");
@ -463,29 +427,11 @@ void setup() {
#if (WIFICOUNTER)
strcat_P(features, " WIFI");
#if !(LIBPAX)
// install wifi driver in RAM and start channel hopping
wifi_sniffer_init();
// start wifi sniffing, if enabled
if (cfg.wifiscan) {
ESP_LOGI(TAG, "Starting Wifi...");
switch_wifi_sniffer(1);
} else
switch_wifi_sniffer(0);
#endif
#else
// remove wifi driver from RAM, if option wifi not compiled
esp_wifi_deinit();
#endif
// initialize salt value using esp_random() called by random() in
// arduino-esp32 core. Note: do this *after* wifi has started, since
// function gets it's seed from RF noise
#if !(LIBPAX)
reset_counters();
#endif
// start state machine
ESP_LOGI(TAG, "Starting Interrupt Handler...");
xTaskCreatePinnedToCore(irqHandler, // task function

View File

@ -29,9 +29,6 @@
#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
// Use libpax instead of default counting algorithms
#define LIBPAX 0
// Corona Exposure Notification Service(ENS) counter
#define COUNT_ENS 1 // count found number of devices which advertise Exposure Notification Service
// set to 1 if you want to enable this function [default=0]

View File

@ -21,7 +21,8 @@ void set_reset(uint8_t val[]) {
reset_counters(); // clear macs
break;
case 2: // reset device to factory settings
ESP_LOGI(TAG, "Remote command: reset device to factory settings and restart");
ESP_LOGI(TAG,
"Remote command: reset device to factory settings and restart");
eraseConfig();
do_reset(false);
break;
@ -74,41 +75,12 @@ void set_sleepcycle(uint8_t val[]) {
void set_wifichancycle(uint8_t val[]) {
cfg.wifichancycle = val[0];
#ifndef LIBAPX
// update Wifi channel rotation timer period
if (cfg.wifichancycle > 0) {
if (xTimerIsTimerActive(WifiChanTimer) == pdFALSE)
xTimerStart(WifiChanTimer, (TickType_t)0);
xTimerChangePeriod(WifiChanTimer, pdMS_TO_TICKS(cfg.wifichancycle * 10),
100);
ESP_LOGI(
TAG,
"Remote command: set Wifi channel hopping interval to %.1f seconds",
cfg.wifichancycle / float(100));
} else {
xTimerStop(WifiChanTimer, (TickType_t)0);
esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE);
channel = WIFI_CHANNEL_MIN;
ESP_LOGI(TAG, "Remote command: set Wifi channel hopping to off");
}
#else
// TODO update libpax configuration
#endif
}
void set_blescantime(uint8_t val[]) {
cfg.blescantime = val[0];
#if !(LIBPAX)
ESP_LOGI(TAG, "Remote command: set BLE scan time to %.1f seconds",
cfg.blescantime / float(100));
// stop & restart BLE scan task to apply new parameter
if (cfg.blescan) {
stop_BLEscan();
start_BLEscan();
}
#else
// TODO update libpax configuration
#endif
// TODO update libpax configuration
}
void set_countmode(uint8_t val[]) {
@ -202,12 +174,18 @@ void set_sensor(uint8_t val[]) {
#endif
}
uint64_t macConvert(uint8_t *paddr) {
uint64_t *mac;
mac = (uint64_t *)paddr;
return (__builtin_bswap64(*mac) >> 16);
}
void set_beacon(uint8_t val[]) {
uint8_t id = val[0]; // use first parameter as beacon storage id
memmove(val, val + 1, 6); // strip off storage id
beacons[id] = macConvert(val); // store beacon MAC in array
ESP_LOGI(TAG, "Remote command: set beacon ID#%d", id);
printKey("MAC", val, 6, false); // show beacon MAC
//printKey("MAC", val, 6, false); // show beacon MAC
}
void set_monitor(uint8_t val[]) {
@ -251,37 +229,24 @@ void set_loraadr(uint8_t val[]) {
void set_blescan(uint8_t val[]) {
ESP_LOGI(TAG, "Remote command: set BLE scanner to %s", val[0] ? "on" : "off");
cfg.blescan = val[0] ? 1 : 0;
#if !(LIBPAX)
macs_ble = 0; // clear BLE counter
if (cfg.blescan)
start_BLEscan();
else
stop_BLEscan();
#else
libpax_counter_stop();
libpax_config_t current_config;
libpax_get_current_config(&current_config);
current_config.blecounter = cfg.blescan;
libpax_update_config(&current_config);
init_libpax();
#endif
}
void set_wifiscan(uint8_t val[]) {
ESP_LOGI(TAG, "Remote command: set WIFI scanner to %s",
val[0] ? "on" : "off");
cfg.wifiscan = val[0] ? 1 : 0;
#if !(LIBPAX)
macs_wifi = 0; // clear WIFI counter
switch_wifi_sniffer(cfg.wifiscan);
#else
libpax_counter_stop();
libpax_config_t current_config;
libpax_get_current_config(&current_config);
current_config.wificounter = cfg.wifiscan;
libpax_update_config(&current_config);
init_libpax();
#endif
}
void set_wifiant(uint8_t val[]) {

View File

@ -107,24 +107,10 @@ void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) {
sendTimer.detach();
// switch off radio and other power consuming hardware
#if !(LIBPAX)
#if (WIFICOUNTER)
switch_wifi_sniffer(0);
#endif
#if (BLECOUNTER)
stop_BLEscan();
btStop();
#endif
#endif
#if (HAS_SDS011)
sds011_sleep(void);
#endif
#if !(LIBPAX)
// stop MAC processing
vTaskDelete(macProcessTask);
#endif
// halt interrupts accessing i2c bus
mask_user_IRQ();

View File

@ -3,9 +3,7 @@
Ticker sendTimer;
void setSendIRQ() {
xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits);
}
void setSendIRQ() { xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits); }
// put data to send in RTos Queues used for transmit over channels Lora and SPI
void SendPayload(uint8_t port) {
@ -57,11 +55,7 @@ void SendPayload(uint8_t port) {
// write data to sdcard, if present
#if (HAS_SDCARD)
if (port == COUNTERPORT) {
#if !(LIBPAX)
sdcardWriteData(macs_wifi, macs_ble
#else
sdcardWriteData(libpax_macs_wifi, libpax_macs_ble
#endif
#if (COUNT_ENS)
,
cwa_report()
@ -91,19 +85,11 @@ void sendData() {
case COUNT_DATA:
payload.reset();
#if !(PAYLOAD_OPENSENSEBOX)
#if !(LIBPAX)
payload.addCount(macs_wifi, MAC_SNIFF_WIFI);
#else
ESP_LOGI(TAG, "Sending libpax wifi count: %d", libpax_macs_wifi);
payload.addCount(libpax_macs_wifi, MAC_SNIFF_WIFI);
#endif
if (cfg.blescan) {
#if !(LIBPAX)
payload.addCount(macs_ble, MAC_SNIFF_BLE);
#else
ESP_LOGI(TAG, "Sending libpax ble count: %d", libpax_macs_ble);
payload.addCount(libpax_macs_ble, MAC_SNIFF_BLE);
#endif
}
#endif
#if (HAS_GPS)
@ -117,125 +103,117 @@ void sendData() {
}
#endif
#if (PAYLOAD_OPENSENSEBOX)
#if !(LIBPAX)
payload.addCount(macs_wifi, MAC_SNIFF_WIFI);
#else
ESP_LOGI(TAG, "Sending libpax wifi count: %d", libpax_macs_wifi);
payload.addCount(libpax_macs_wifi, MAC_SNIFF_WIFI);
#endif
if (cfg.blescan) {
#if !(LIBPAX)
payload.addCount(macs_ble, MAC_SNIFF_BLE);
#else
ESP_LOGI(TAG, "Sending libpax ble count: %d", libpax_macs_ble);
payload.addCount(libpax_macs_ble, MAC_SNIFF_BLE);
#endif
#endif
#if (HAS_SDS011)
sds011_store(&sds_status);
payload.addSDS(sds_status);
sds011_store(&sds_status);
payload.addSDS(sds_status);
#endif
SendPayload(COUNTERPORT);
// clear counter if not in cumulative counter mode
if (cfg.countermode != 1) {
reset_counters(); // clear macs container and reset all counters
ESP_LOGI(TAG, "Counter cleared");
}
SendPayload(COUNTERPORT);
// clear counter if not in cumulative counter mode
if (cfg.countermode != 1) {
reset_counters(); // clear macs container and reset all counters
ESP_LOGI(TAG, "Counter cleared");
}
#ifdef HAS_DISPLAY
else
dp_plotCurve(macs.size(), true);
else
dp_plotCurve(macs.size(), true);
#endif
break;
break;
#endif
#if (HAS_BME)
case MEMS_DATA:
payload.reset();
payload.addBME(bme_status);
SendPayload(BMEPORT);
break;
case MEMS_DATA:
payload.reset();
payload.addBME(bme_status);
SendPayload(BMEPORT);
break;
#endif
#if (HAS_GPS)
case GPS_DATA:
if (GPSPORT != COUNTERPORT) {
// send GPS position only if we have a fix
if (gps_hasfix()) {
gps_storelocation(&gps_status);
payload.reset();
payload.addGPS(gps_status);
SendPayload(GPSPORT);
} else
ESP_LOGD(TAG, "No valid GPS position");
}
break;
case GPS_DATA:
if (GPSPORT != COUNTERPORT) {
// send GPS position only if we have a fix
if (gps_hasfix()) {
gps_storelocation(&gps_status);
payload.reset();
payload.addGPS(gps_status);
SendPayload(GPSPORT);
} else
ESP_LOGD(TAG, "No valid GPS position");
}
break;
#endif
#if (HAS_SENSORS)
#if (HAS_SENSOR_1)
case SENSOR1_DATA:
payload.reset();
payload.addSensor(sensor_read(1));
SendPayload(SENSOR1PORT);
case SENSOR1_DATA:
payload.reset();
payload.addSensor(sensor_read(1));
SendPayload(SENSOR1PORT);
#if (COUNT_ENS)
if (cfg.countermode != 1)
cwa_clear();
if (cfg.countermode != 1)
cwa_clear();
#endif
break;
break;
#endif
#if (HAS_SENSOR_2)
case SENSOR2_DATA:
payload.reset();
payload.addSensor(sensor_read(2));
SendPayload(SENSOR2PORT);
break;
case SENSOR2_DATA:
payload.reset();
payload.addSensor(sensor_read(2));
SendPayload(SENSOR2PORT);
break;
#endif
#if (HAS_SENSOR_3)
case SENSOR3_DATA:
payload.reset();
payload.addSensor(sensor_read(3));
SendPayload(SENSOR3PORT);
break;
case SENSOR3_DATA:
payload.reset();
payload.addSensor(sensor_read(3));
SendPayload(SENSOR3PORT);
break;
#endif
#endif
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
case BATT_DATA:
payload.reset();
payload.addVoltage(read_voltage());
SendPayload(BATTPORT);
break;
case BATT_DATA:
payload.reset();
payload.addVoltage(read_voltage());
SendPayload(BATTPORT);
break;
#endif
} // switch
bitmask &= ~mask;
mask <<= 1;
} // while (bitmask)
} // sendData()
} // switch
bitmask &= ~mask;
mask <<= 1;
} // while (bitmask)
} // sendData()
void flushQueues(void) {
rcmd_queuereset();
void flushQueues(void) {
rcmd_queuereset();
#if (HAS_LORA)
lora_queuereset();
lora_queuereset();
#endif
#ifdef HAS_SPI
spi_queuereset();
spi_queuereset();
#endif
#ifdef HAS_MQTT
mqtt_queuereset();
mqtt_queuereset();
#endif
}
}
bool allQueuesEmtpy(void) {
uint32_t rc = rcmd_queuewaiting();
bool allQueuesEmtpy(void) {
uint32_t rc = rcmd_queuewaiting();
#if (HAS_LORA)
rc += lora_queuewaiting();
rc += lora_queuewaiting();
#endif
#ifdef HAS_SPI
rc += spi_queuewaiting();
rc += spi_queuewaiting();
#endif
#ifdef HAS_MQTT
rc += mqtt_queuewaiting();
rc += mqtt_queuewaiting();
#endif
return (rc == 0) ? true : false;
}
return (rc == 0) ? true : false;
}

View File

@ -5,7 +5,6 @@
#if (COUNT_ENS)
#include "payload.h"
#include "corona.h"
#include "macsniff.h"
extern PayloadConvert payload;
#endif

View File

@ -1,107 +0,0 @@
#if !(LIBPAX)
// Basic Config
#include "globals.h"
#include "wifiscan.h"
// Local logging tag
static const char TAG[] = "wifi";
TimerHandle_t WifiChanTimer;
typedef struct {
unsigned frame_ctrl : 16;
unsigned duration_id : 16;
uint8_t addr1[6]; // receiver address
uint8_t addr2[6]; // sender address
uint8_t addr3[6]; // filtering address
unsigned sequence_ctrl : 16;
uint8_t addr4[6]; // optional
} wifi_ieee80211_mac_hdr_t;
typedef struct {
wifi_ieee80211_mac_hdr_t hdr;
uint8_t payload[0]; // network data ended with 4 bytes csum (CRC32)
} wifi_ieee80211_packet_t;
// using IRAM_ATTR here to speed up callback function
IRAM_ATTR void wifi_sniffer_packet_handler(void *buff,
wifi_promiscuous_pkt_type_t type) {
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
const wifi_ieee80211_packet_t *ipkt =
(wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
// process seen MAC
#if MACFILTER
// we guess it's a smartphone, if U/L bit #2 of MAC is set
// bit #2 = 1 -> local mac (randomized) / bit #2 = 0 -> universal mac
if ((hdr->addr2[0] & 0b10) == 0)
return;
else
#endif
mac_add((uint8_t *)hdr->addr2, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI);
}
// Software-timer driven Wifi channel rotation callback function
void switchWifiChannel(TimerHandle_t xTimer) {
channel =
(channel % WIFI_CHANNEL_MAX) + 1; // rotate channel 1..WIFI_CHANNEL_MAX
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
}
void wifi_sniffer_init(void) {
wifi_country_t wifi_country = {WIFI_MY_COUNTRY, WIFI_CHANNEL_MIN,
WIFI_CHANNEL_MAX, 100,
WIFI_COUNTRY_POLICY_MANUAL};
wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();
wifi_cfg.event_handler = NULL; // we don't need a wifi event handler
wifi_cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM
wifi_cfg.wifi_task_core_id = 0; // we want wifi task running on core 0
wifi_promiscuous_filter_t wifi_filter = {.filter_mask =
WIFI_PROMIS_FILTER_MASK_MGMT |
WIFI_PROMIS_FILTER_MASK_DATA};
esp_wifi_init(&wifi_cfg); // start Wifi task
esp_wifi_set_country(&wifi_country); // set locales for RF and channels
esp_wifi_set_storage(WIFI_STORAGE_RAM);
esp_wifi_set_mode(WIFI_MODE_NULL);
esp_wifi_set_ps(WIFI_PS_NONE); // no modem power saving
esp_wifi_set_promiscuous_filter(&wifi_filter); // set frame filter
esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler);
// setup wifi channel hopping timer
WifiChanTimer = xTimerCreate("WifiChannelTimer",
(cfg.wifichancycle > 0)
? pdMS_TO_TICKS(cfg.wifichancycle * 10)
: pdMS_TO_TICKS(50),
pdTRUE, (void *)0, switchWifiChannel);
}
void switch_wifi_sniffer(uint8_t state) {
if (state) {
// start sniffer
#if (BLECOUNTER)
// workaround needed for ESP-IDF v3.3
// see https://github.com/espressif/esp-idf/issues/5427
esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
#endif
esp_wifi_start();
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE);
// start channel hopping timer
if (cfg.wifichancycle > 0)
xTimerStart(WifiChanTimer, (TickType_t)0);
} else {
// start channel hopping timer
if (xTimerIsTimerActive(WifiChanTimer) != pdFALSE)
xTimerStop(WifiChanTimer, (TickType_t)0);
// stop sniffer
esp_wifi_set_promiscuous(false);
esp_wifi_stop();
}
}
#endif // !(LIBPAX)