MAC processing reworked

This commit is contained in:
Klaus K Wilting 2020-11-08 22:14:28 +01:00
parent 1cd9ae16f1
commit 30731f5c0c
7 changed files with 91 additions and 236 deletions

View File

@ -19,7 +19,7 @@ uint64_t macConvert(uint8_t *paddr);
esp_err_t macQueueInit(void); esp_err_t macQueueInit(void);
void mac_process(void *pvParameters); void mac_process(void *pvParameters);
void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type); void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type);
uint16_t mac_analyze(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); void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb);
#endif #endif

View File

@ -46,7 +46,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I
[common] [common]
; for release_version use max. 10 chars total, use any decimal format like "a.b.c" ; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
release_version = 2.0.3 release_version = 2.0.4
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
debug_level = 3 debug_level = 3

View File

@ -151,13 +151,6 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
ESP_LOGV(TAG, "RSSI : %d", p->scan_rst.rssi); ESP_LOGV(TAG, "RSSI : %d", p->scan_rst.rssi);
#endif #endif
if ((cfg.rssilimit) &&
(p->scan_rst.rssi < cfg.rssilimit)) { // rssi is negative value
ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi,
cfg.rssilimit);
break;
}
#if (VENDORFILTER) #if (VENDORFILTER)
if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) || if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) ||
(p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) { (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) {

View File

@ -80,7 +80,7 @@ void mac_process(void *pvParameters) {
ESP_LOGE(TAG, "Premature return from xQueueReceive() with no data!"); ESP_LOGE(TAG, "Premature return from xQueueReceive() with no data!");
continue; continue;
} else } else
mac_analyze(MacBuffer.mac, MacBuffer.rssi, MacBuffer.sniff_type); mac_analyze(MacBuffer);
} }
delay(2); // yield to CPU delay(2); // yield to CPU
} }
@ -95,35 +95,53 @@ void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) {
memcpy(MacBuffer.mac, paddr, 6); memcpy(MacBuffer.mac, paddr, 6);
if (xQueueSendToBackFromISR(MacQueue, (void *)&MacBuffer, (TickType_t)0) != if (xQueueSendToBackFromISR(MacQueue, (void *)&MacBuffer, (TickType_t)0) !=
pdTRUE) pdPASS)
ESP_LOGW(TAG, "Dense radio traffic, packet lost!"); ESP_LOGW(TAG, "Dense radio traffic, packet lost!");
} }
uint16_t mac_analyze(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) { uint16_t mac_analyze(MacBuffer_t MacBuffer) {
if (salt == 0) // ensure we have salt (appears after radio is turned on) if (salt == 0) // ensure we have salt (appears after radio is turned on)
return 0; return 0;
uint16_t hashedmac = 0; // temporary buffer for generated hash value 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);
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
blink_LED(COLOR_WHITE, 2000);
#endif
payload.reset();
payload.addAlarm(MacBuffer.rssi, beaconID);
SendPayload(BEACONPORT, prio_high);
}
};
#if (VENDORFILTER)
uint32_t *oui; // temporary buffer for vendor OUI
oui = (uint32_t *)MacBuffer.mac;
// if we find OUI on vendor filter list we don't analyze and return early
if (std::find(vendors.begin(), vendors.end(), __builtin_bswap32(*oui) >> 8) !=
vendors.end())
return 0;
#endif
char buff[10]; // temporary buffer for printf char buff[10]; // temporary buffer for printf
bool added = false;
int8_t beaconID; // beacon number in test monitor mode
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
// but since it's uint32 we take 4 bytes to avoid 1st value to be 0. // 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. // this gets MAC in msb (= reverse) order, but doesn't matter for hashing it.
mac = (uint32_t *)(paddr + 2); mac = (uint32_t *)(MacBuffer.mac + 2);
#if (VENDORFILTER)
uint32_t *oui; // temporary buffer for vendor OUI
oui = (uint32_t *)paddr;
// use OUI vendor filter list only on Wifi, not on BLE
if ((sniff_type == MAC_SNIFF_BLE) ||
std::find(vendors.begin(), vendors.end(), __builtin_bswap32(*oui) >> 8) !=
vendors.end()) {
#endif
// salt and hash MAC, and if new unique one, store identifier in container // salt and hash MAC, and if new unique one, store identifier in container
// and increment counter on display // and increment counter on display
@ -132,52 +150,44 @@ uint16_t mac_analyze(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) {
snprintf(buff, sizeof(buff), "%08X", snprintf(buff, sizeof(buff), "%08X",
*mac + (uint32_t)salt); // convert unsigned 32-bit salted MAC *mac + (uint32_t)salt); // convert unsigned 32-bit salted MAC
// to 8 digit hex string // to 8 digit hex string
hashedmac = rokkit(&buff[3], 5); // hash MAC 8 digit -> 5 digit uint16_t hashedmac = rokkit(&buff[3], 5); // hash MAC 8 digit -> 5 digit
auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique
added = newmac.second ? true bool added =
: false; // true if hashed MAC is unique in container newmac.second ? true : false; // true if hashed MAC is unique in container
// Count only if MAC was not yet seen // Count only if MAC was not yet seen
if (added) { if (added) {
// increment counter and one blink led
if (sniff_type == MAC_SNIFF_WIFI) {
macs_wifi++; // increment Wifi MACs counter
switch (MacBuffer.sniff_type) {
case MAC_SNIFF_WIFI:
macs_wifi++; // increment Wifi MACs counter
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
blink_LED(COLOR_GREEN, 50); blink_LED(COLOR_GREEN, 50);
#endif #endif
} break;
#if (BLECOUNTER) #if (BLECOUNTER)
else if ((sniff_type == MAC_SNIFF_BLE) || case MAC_SNIFF_BLE:
(sniff_type = MAC_SNIFF_BLE_ENS)) {
macs_ble++; // increment BLE Macs counter macs_ble++; // increment BLE Macs counter
#if (COUNT_ENS)
if (sniff_type == MAC_SNIFF_BLE_ENS)
cwa_mac_add(hashedmac);
#endif
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
blink_LED(COLOR_MAGENTA, 50); blink_LED(COLOR_MAGENTA, 50);
#endif #endif
} break;
#if (COUNT_ENS)
case MAC_SNIFF_BLE_ENS:
macs_ble++; // increment BLE Macs counter
cwa_mac_add(hashedmac); // process ENS beacon
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
blink_LED(COLOR_WHITE, 50);
#endif
break;
#endif // COUNT_ENS
#endif // BLECOUNTER #endif // BLECOUNTER
// in beacon monitor mode check if seen MAC is a known beacon } // switch
if (cfg.monitormode) {
beaconID = isBeacon(macConvert(paddr));
if (beaconID >= 0) {
ESP_LOGI(TAG, "Beacon ID#%d detected", beaconID);
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
blink_LED(COLOR_WHITE, 2000);
#endif
payload.reset();
payload.addAlarm(rssi, beaconID);
SendPayload(BEACONPORT, prio_high);
}
};
} // added } // added
// Log scan result // Log scan result
@ -189,22 +199,13 @@ uint16_t mac_analyze(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) {
#endif #endif
"-> %d Bytes left", "-> %d Bytes left",
added ? "new " : "known", added ? "new " : "known",
sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff, MacBuffer.sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH",
hashedmac, macs_wifi, macs_ble, MacBuffer.rssi, buff, hashedmac, macs_wifi, macs_ble,
#if (COUNT_ENS) #if (COUNT_ENS)
cwa_report(), cwa_report(),
#endif #endif
getFreeRAM()); getFreeRAM());
#if (VENDORFILTER) // if an unknown Wifi or BLE mac was counted, return hash of this mac, else 0
} else { return (added ? hashedmac : 0);
// Very noisy
// ESP_LOGD(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X",
// paddr[0],paddr[1],paddr[2],paddr[3],paddr[5],paddr[5]);
}
#endif
// if a new and unique Wifi or BLE mac was counted, returs hash of this mac,
// else 0
return hashedmac;
} }

View File

@ -14,10 +14,11 @@
#define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed #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 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed
// Set this to include BLE counting and vendor filter functions, or to switch off WIFI counting // MAC sniffing parameters
#define VENDORFILTER 0 // set to 0 if you want to scan all devices, not filtering smartphone OUIs #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 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 #define WIFICOUNTER 1 // set to 0 if you do not want to install the WIFI sniffer
#define MAC_QUEUE_SIZE 50 // size of MAC processing buffer (number of MACs) [default = 50]
// BLE scan parameters // BLE scan parameters
#define BLESCANTIME 0 // [seconds] scan duration, 0 means infinite [default], see note below #define BLESCANTIME 0 // [seconds] scan duration, 0 means infinite [default], see note below
@ -29,10 +30,9 @@
// set to 0 if you do not want to enable this function // set to 0 if you do not want to enable this function
// for additional sensors (added by some user) // 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_1 0 // set to 1 to enable data transfer of user sensor #1 (also used as ENS counter) [default=0]
#define HAS_SENSOR_2 0 // not used #define HAS_SENSOR_2 0 // set to 1 to enable data transfer of user sensor #2 [default=0]
#define HAS_SENSOR_3 0 // not used #define HAS_SENSOR_3 0 // set to 1 to enable data transfer of user sensor #3 [default=0]
#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
* *

View File

@ -1,135 +0,0 @@
; PlatformIO Project Configuration File
; NOTE: PlatformIO v4 is needed!
;
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
; ---> SELECT THE TARGET PLATFORM HERE! <---
[board]
halfile = generic.h
;halfile = ebox.h
;halfile = eboxtube.h
;halfile = ecopower.h
;halfile = heltec.h
;halfile = heltecv2.h
;halfile = ttgov1.h
;halfile = ttgov2.h
;halfile = ttgov21old.h
;halfile = ttgov21new.h
;halfile = ttgofox.h
;halfile = ttgobeam.h
;halfile = ttgobeam10.h
;halfile = fipy.h
;halfile = lopy.h
;halfile = lopy4.h
;halfile = lolin32litelora.h
;halfile = lolin32lora.h
;halfile = lolin32lite.h
;halfile = wemos32oled.h
;halfile = wemos32matrix.h
;halfile = octopus32.h
;halfile = tinypico.h
;halfile = tinypicomatrix.h
;halfile = m5core.h
;halfile = m5fire.h
;halfile = olimexpoeiso.h
[platformio]
; upload firmware to board with usb cable
default_envs = usb
; upload firmware to a jfrog bintray repository
;default_envs = ota
; use latest versions of libraries
;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 = 2.0.16
; 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 = 3
extra_scripts = pre:build.py
otakeyfile = ota.conf
lorakeyfile = loraconf.h
lmicconfigfile = lmic_config.h
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-catena/MCCI LoRaWAN LMIC library @ ^3.2.0
lib_deps_display =
bitbank2/OneBitDisplay @ 1.7.2
ricmoo/QRCode @ ^0.0.1
bodmer/TFT_eSPI @ ^2.2.20
lib_deps_ledmatrix =
seeed-studio/Ultrathin_LED_Matrix @ ^1.0.0
lib_deps_rgbled =
roboticsbrno/SmartLeds @ ^1.2.1
lib_deps_gps =
mikalhart/TinyGPSPlus @ ^1.0.2
lib_deps_sensors =
adafruit/Adafruit Unified Sensor @ ^1.1.4
adafruit/Adafruit BME280 Library @ ^2.1.1
adafruit/Adafruit BMP085 Library @ ^1.1.0
boschsensortec/BSEC Software Library @ 1.5.1474
https://github.com/ricki-z/SDS011.git
lib_deps_basic =
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}
${common.lib_deps_display}
${common.lib_deps_rgbled}
${common.lib_deps_gps}
${common.lib_deps_sensors}
${common.lib_deps_ledmatrix}
build_flags_basic =
-include "src/hal/${board.halfile}"
-include "src/paxcounter.conf"
-w
'-DCORE_DEBUG_LEVEL=${common.debug_level}'
'-DLOG_LOCAL_LEVEL=${common.debug_level}'
'-DPROGVERSION="${common.release_version}"'
build_flags_sensors =
-Llib/Bosch-BSEC/src/esp32/
-lalgobsec
build_flags_all =
${common.build_flags_basic}
${common.build_flags_sensors}
-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 = 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
[env:usb]
upload_protocol = esptool
[env:dev]
upload_protocol = esptool
build_type = debug
platform = https://github.com/platformio/platform-espressif32.git#develop
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git

View File

@ -35,11 +35,7 @@ IRAM_ATTR void wifi_sniffer_packet_handler(void *buff,
(wifi_ieee80211_packet_t *)ppkt->payload; (wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr; const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
if ((cfg.rssilimit) && // process seen MAC
(ppkt->rx_ctrl.rssi < cfg.rssilimit)) // rssi is negative value
ESP_LOGD(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi,
cfg.rssilimit);
else // count seen MAC
mac_add((uint8_t *)hdr->addr2, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI); mac_add((uint8_t *)hdr->addr2, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI);
} }