From 30731f5c0ce5396fdbcc0d5147481a5c69e15bff Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 8 Nov 2020 22:14:28 +0100 Subject: [PATCH] MAC processing reworked --- include/macsniff.h | 2 +- platformio_orig.ini | 2 +- src/blecsan.cpp | 7 -- src/macsniff.cpp | 163 ++++++++++++++++++++------------------- src/paxcounter_orig.conf | 10 +-- src/platformio_orig.ini | 135 -------------------------------- src/wifiscan.cpp | 8 +- 7 files changed, 91 insertions(+), 236 deletions(-) delete mode 100644 src/platformio_orig.ini diff --git a/include/macsniff.h b/include/macsniff.h index 5e99656b..175cba58 100644 --- a/include/macsniff.h +++ b/include/macsniff.h @@ -19,7 +19,7 @@ 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(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 diff --git a/platformio_orig.ini b/platformio_orig.ini index dc508990..dbaa6046 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -46,7 +46,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I [common] ; 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! ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose debug_level = 3 diff --git a/src/blecsan.cpp b/src/blecsan.cpp index 108b4941..b06e78a0 100644 --- a/src/blecsan.cpp +++ b/src/blecsan.cpp @@ -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); #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 ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) || (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) { diff --git a/src/macsniff.cpp b/src/macsniff.cpp index e747e373..ddebbecb 100644 --- a/src/macsniff.cpp +++ b/src/macsniff.cpp @@ -80,7 +80,7 @@ void mac_process(void *pvParameters) { ESP_LOGE(TAG, "Premature return from xQueueReceive() with no data!"); continue; } else - mac_analyze(MacBuffer.mac, MacBuffer.rssi, MacBuffer.sniff_type); + mac_analyze(MacBuffer); } delay(2); // yield to CPU } @@ -95,116 +95,117 @@ void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) { memcpy(MacBuffer.mac, paddr, 6); if (xQueueSendToBackFromISR(MacQueue, (void *)&MacBuffer, (TickType_t)0) != - pdTRUE) + pdPASS) 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) 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 - uint32_t *mac; // temporary buffer for shortened MAC + 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 + uint32_t *mac; // temporary buffer for shortened MAC // 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 *)(paddr + 2); + mac = (uint32_t *)(MacBuffer.mac + 2); -#if (VENDORFILTER) - uint32_t *oui; // temporary buffer for vendor OUI - oui = (uint32_t *)paddr; + // 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 - // 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 + snprintf(buff, sizeof(buff), "%08X", + *mac + (uint32_t)salt); // convert unsigned 32-bit salted MAC + // to 8 digit hex string + uint16_t hashedmac = rokkit(&buff[3], 5); // hash MAC 8 digit -> 5 digit + 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 - // 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 + // Count only if MAC was not yet seen + if (added) { - snprintf(buff, sizeof(buff), "%08X", - *mac + (uint32_t)salt); // convert unsigned 32-bit salted MAC - // to 8 digit hex string - hashedmac = rokkit(&buff[3], 5); // hash MAC 8 digit -> 5 digit - auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique - added = newmac.second ? true - : false; // true if hashed MAC is unique in container - - // Count only if MAC was not yet seen - 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) - blink_LED(COLOR_GREEN, 50); + blink_LED(COLOR_GREEN, 50); #endif - } + break; + #if (BLECOUNTER) - else if ((sniff_type == MAC_SNIFF_BLE) || - (sniff_type = MAC_SNIFF_BLE_ENS)) { - macs_ble++; // increment BLE Macs counter + case MAC_SNIFF_BLE: + macs_ble++; // increment BLE Macs counter +#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) + blink_LED(COLOR_MAGENTA, 50); +#endif + break; #if (COUNT_ENS) - if (sniff_type == MAC_SNIFF_BLE_ENS) - cwa_mac_add(hashedmac); -#endif - + 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_MAGENTA, 50); + blink_LED(COLOR_WHITE, 50); #endif - } + break; +#endif // COUNT_ENS #endif // BLECOUNTER - // in beacon monitor mode check if seen MAC is a known beacon - 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); - } - }; + } // switch + } // added - } // added - - // Log scan result - ESP_LOGV(TAG, - "%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d " - "BLTH:%d " + // Log scan result + ESP_LOGV(TAG, + "%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d " + "BLTH:%d " #if (COUNT_ENS) - "(CWA:%d)" + "(CWA:%d)" #endif - "-> %d Bytes left", - added ? "new " : "known", - sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff, - hashedmac, macs_wifi, macs_ble, + "-> %d Bytes left", + added ? "new " : "known", + MacBuffer.sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", + MacBuffer.rssi, buff, hashedmac, macs_wifi, macs_ble, #if (COUNT_ENS) - cwa_report(), + cwa_report(), #endif - getFreeRAM()); + getFreeRAM()); -#if (VENDORFILTER) - } else { - // 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; + // if an unknown Wifi or BLE mac was counted, return hash of this mac, else 0 + return (added ? hashedmac : 0); } \ No newline at end of file diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index 06a1e624..0a7b88d1 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -14,10 +14,11 @@ #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 -// 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 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 MAC_QUEUE_SIZE 50 // size of MAC processing buffer (number of MACs) [default = 50] // BLE scan parameters #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 // 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 +#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 // set to 1 to enable data transfer of user sensor #2 [default=0] +#define HAS_SENSOR_3 0 // set to 1 to enable data transfer of user sensor #3 [default=0] /* Note: guide for setting bluetooth parameters * diff --git a/src/platformio_orig.ini b/src/platformio_orig.ini deleted file mode 100644 index 80087854..00000000 --- a/src/platformio_orig.ini +++ /dev/null @@ -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 diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index dd8ce4a1..d62e6ae3 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -35,12 +35,8 @@ IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, (wifi_ieee80211_packet_t *)ppkt->payload; const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr; - if ((cfg.rssilimit) && - (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); + // process seen MAC + mac_add((uint8_t *)hdr->addr2, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI); } // Software-timer driven Wifi channel rotation callback function