diff --git a/README.md b/README.md index 7eab7e415..c6bb8a577 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,6 @@ Depending on board hardware following features are supported: - OLED Display (shows detailed status) - RGB LED (shows colorized status) - Button (short press: flip display page / long press: send alarm message) -- Silicon unique ID - Battery voltage monitoring (analog read / AXP192 / IP5306) - GPS (Generic serial NMEA, or Quectel L76 I2C) - Environmental sensors (Bosch BMP180/BME280/BME680 I2C; SDS011 serial) diff --git a/include/globals.h b/include/globals.h index 42c3257e8..39a42f799 100644 --- a/include/globals.h +++ b/include/globals.h @@ -18,10 +18,6 @@ #include "mallocator.h" #include -// sniffing types -#define MAC_SNIFF_WIFI 0 -#define MAC_SNIFF_BLE 1 - // bits in payloadmask for filtering payload data #define GPS_DATA (0x01) #define ALARM_DATA (0x02) @@ -67,9 +63,9 @@ enum sendprio_t { prio_low, prio_normal, prio_high }; enum timesource_t { _gps, _rtc, _lora, _unsynced }; - +enum snifftype_t { MAC_SNIFF_WIFI, MAC_SNIFF_BLE, MAC_SNIFF_BLE_ENS }; enum runmode_t { - RUNMODE_POWERCYCLE = 0, + RUNMODE_POWERCYCLE, RUNMODE_NORMAL, RUNMODE_WAKEUP, RUNMODE_UPDATE @@ -114,6 +110,13 @@ 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; @@ -145,13 +148,14 @@ extern std::array beacons; extern configData_t cfg; // current device configuration 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 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; +extern TaskHandle_t irqHandlerTask, ClockTask, macProcessTask; extern TimerHandle_t WifiChanTimer; extern Timezone myTZ; extern RTC_DATA_ATTR runmode_t RTC_runmode; diff --git a/include/macsniff.h b/include/macsniff.h index e119d9a34..175cba588 100644 --- a/include/macsniff.h +++ b/include/macsniff.h @@ -14,13 +14,12 @@ #include "corona.h" #endif -#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); -uint16_t mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type); +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 diff --git a/platformio_orig.ini b/platformio_orig.ini index dc5089902..dbaa6046d 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 9a60e456c..b06e78a0f 100644 --- a/src/blecsan.cpp +++ b/src/blecsan.cpp @@ -6,14 +6,10 @@ #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"; +#ifdef VERBOSE const char *bt_addr_t_to_string(esp_ble_addr_type_t type) { switch (type) { case BLE_ADDR_TYPE_PUBLIC: @@ -110,15 +106,24 @@ const char *btsig_gap_type(uint32_t gap_type) { return "Unknown type"; } } // btsig_gap_type +#endif -// using IRAM_:ATTR here to speed up callback function +// 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: @@ -138,42 +143,37 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, 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); - - 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; - } +#endif #if (VENDORFILTER) 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 - // 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); + // add this device mac to processing queue #if (COUNT_ENS) + // check for ens signature if (cfg.enscount) { - // check for ens signature - if (NULL != strstr((const char *)p->scan_rst.ble_adv, ensMagicBytes)) - cwa_mac_add(hashedmac); + 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 vendorfilter if: @@ -186,8 +186,8 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, // 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 vendorfiltering is on, we ... + filter BLE devices using their advertisements to get filter alternative + to vendor OUI if vendorfiltering is on, we ... - want to count: mobile phones and tablets - don't want to count: beacons, peripherals (earphones, headsets, printers), cars and machines see @@ -211,13 +211,13 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, default: break; - } + } // switch } // gap_callback_handler esp_err_t register_ble_callback(void) { ESP_LOGI(TAG, "Register GAP callback"); - // This function is called to occur gap event, such as scan result. + // This function is called when gap event occurs, such as scan result. // register the scan callback function to the gap module ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler)); diff --git a/src/corona.cpp b/src/corona.cpp index caa4d412d..8a2fd979d 100644 --- a/src/corona.cpp +++ b/src/corona.cpp @@ -23,18 +23,13 @@ static std::map 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 ¬ifier : cwaSeenNotifiers) { - ESP_LOGD(TAG, "CWA forget <%X>", notifier.first); - // } - } - #endif - - */ - +#ifdef VERBOSE + ESP_LOGV(TAG, "CWA: forget old notifier: %d", cwaSeenNotifiers.size()); + for (auto const ¬ifier : cwaSeenNotifiers) { + ESP_LOGD(TAG, "CWA forget <%04X>", 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(); diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 55cb4497d..e65eaac2d 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -40,6 +40,9 @@ void doHousekeeping() { ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(irqHandlerTask), eTaskGetState(irqHandlerTask)); + ESP_LOGD(TAG, "MACprocessor %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(macProcessTask), + eTaskGetState(macProcessTask)); #if (HAS_LORA) ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask)); diff --git a/src/display.cpp b/src/display.cpp index 537f71697..7e7e5b384 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -311,6 +311,7 @@ void dp_drawPage(time_t t, bool nextpage) { dp_printf(" "); #endif dp_printf(" ch:%02d", channel); + // dp_printf(" due:%02d", rf_load); dp_println(); // line 5: RSSI limiter + free memory diff --git a/src/hal/generic.h b/src/hal/generic.h index 10db27e97..26d465e3b 100644 --- a/src/hal/generic.h +++ b/src/hal/generic.h @@ -105,8 +105,4 @@ #define LORA_IO1 (33) #define LORA_IO2 LMIC_UNUSED_PIN -// I2C config for Microchip 24AA02E64 DEVEUI unique address -#define MCP_24AA02E64_I2C_ADDRESS 0x50 // I2C address for the 24AA02E64 -#define MCP_24AA02E64_MAC_ADDRESS 0xF8 // Memory adress of unique deveui 64 bits - #endif diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 00f92194f..97865bf67 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -162,51 +162,9 @@ void os_getDevEui(u1_t *buf) { } else { gen_lora_deveui(buf); // generate DEVEUI from device's MAC } - -// Get MCP 24AA02E64 hardware DEVEUI (override default settings if found) -#ifdef MCP_24AA02E64_I2C_ADDRESS - get_hard_deveui(buf); - RevBytes(buf, 8); // swap bytes to LSB format -#endif #endif } -void get_hard_deveui(uint8_t *pdeveui) { - // read DEVEUI from Microchip 24AA02E64 2Kb serial eeprom if present -#ifdef MCP_24AA02E64_I2C_ADDRESS - - uint8_t i2c_ret; - - // Init this just in case, no more to 100KHz - Wire.begin(SDA, SCL, 100000); - Wire.beginTransmission(MCP_24AA02E64_I2C_ADDRESS); - Wire.write(MCP_24AA02E64_MAC_ADDRESS); - i2c_ret = Wire.endTransmission(); - - // check if device was seen on i2c bus - if (i2c_ret == 0) { - char deveui[32] = ""; - uint8_t data; - - Wire.beginTransmission(MCP_24AA02E64_I2C_ADDRESS); - Wire.write(MCP_24AA02E64_MAC_ADDRESS); - Wire.endTransmission(); - - Wire.requestFrom(MCP_24AA02E64_I2C_ADDRESS, 8); - while (Wire.available()) { - data = Wire.read(); - sprintf(deveui + strlen(deveui), "%02X ", data); - *pdeveui++ = data; - } - ESP_LOGI(TAG, "Serial EEPROM found, read DEVEUI %s", deveui); - } else - ESP_LOGI(TAG, "Could not read DEVEUI from serial EEPROM"); - - // Set back to 400KHz to speed up OLED - Wire.setClock(400000); -#endif // MCP 24AA02E64 -} - #if (VERBOSE) // Display OTAA keys diff --git a/src/macsniff.cpp b/src/macsniff.cpp index 90f29a79a..798de95f2 100644 --- a/src/macsniff.cpp +++ b/src/macsniff.cpp @@ -10,6 +10,9 @@ // Local logging tag static const char TAG[] = __FILE__; +QueueHandle_t MacQueue; +TaskHandle_t macProcessTask; + uint16_t salt = 0; uint16_t get_salt(void) { @@ -43,103 +46,170 @@ uint64_t macConvert(uint8_t *paddr) { return (__builtin_bswap64(*mac) >> 16); } -uint16_t mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { +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 + 2048, // 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) { 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 + + // Count only if MAC was not yet seen + if (added) { - // 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 - - 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) { - 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 - } + blink_LED(COLOR_MAGENTA, 50); #endif + break; - // 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 (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, 2000); + blink_LED(COLOR_WHITE, 50); #endif - payload.reset(); - payload.addAlarm(rssi, beaconID); - SendPayload(BEACONPORT, prio_high); - } - }; - - } // added - - // Log scan result - ESP_LOGV(TAG, - "%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d " - "BLTH:%d " + break; + +#endif // COUNT_ENS +#endif // BLECOUNTER + + } // switch + } // added + + // 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/main.cpp b/src/main.cpp index cabfa1e7b..687a926da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,9 +35,10 @@ IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer lmictask 1 2 MCCI LMiC LORAWAN stack clockloop 1 4 generates realtime telegrams for external clock timesync_proc 1 3 processes realtime time sync requests -irqhandler 1 1 cyclic tasks (i.e. displayrefresh) triggered by timers +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 analyzes sniffed MACs IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator Low priority numbers denote low priority tasks. @@ -86,8 +87,9 @@ 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 volatile channel = 0; // channel rotation counter uint8_t batt_level = 0; // display value +uint8_t volatile channel = 0; // channel rotation counter +uint8_t volatile rf_load = 0; // RF traffic indicator uint16_t volatile macs_wifi = 0, macs_ble = 0; // globals for display hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL; @@ -285,6 +287,10 @@ void setup() { start_ota_update(); #endif + // start mac processing task + ESP_LOGI(TAG, "Starting MAC processor..."); + macQueueInit(); + // start BLE scan callback if BLE function is enabled in NVRAM configuration // or switch off bluetooth, if not compiled #if (BLECOUNTER) @@ -344,7 +350,7 @@ void setup() { strcat_P(features, " LORA"); // kick off join, except we come from sleep _ASSERT(lora_stack_init(RTC_runmode == RUNMODE_WAKEUP ? false : true) == - ESP_OK); + ESP_OK); #endif // initialize SPI @@ -490,12 +496,9 @@ void setup() { sendTimer.attach(cfg.sendcycle * 2, setSendIRQ); cyclicTimer.attach(HOMECYCLE, setCyclicIRQ); -#if (TIME_SYNC_INTERVAL) - -#if (!(TIME_SYNC_LORAWAN) && !(TIME_SYNC_LORASERVER) && !defined HAS_GPS && \ - !defined HAS_RTC) -#warning you did not specify a time source, time will not be synched -#endif +// only if we have a timesource we do timesync +#if ((TIME_SYNC_LORAWAN) || (TIME_SYNC_LORASERVER) || (HAS_GPS) || \ + defined HAS_RTC) #if (defined HAS_IF482 || defined HAS_DCF77) ESP_LOGI(TAG, "Starting Clock Controller..."); @@ -508,9 +511,10 @@ void setup() { ESP_LOGI(TAG, "Starting Timekeeper..."); _ASSERT(timepulse_init()); // setup pps timepulse - timepulse_start(); // starts pps and cyclic time sync + timepulse_start(); // starts pps and cyclic time sync + strcat_P(features, " TIME"); -#endif // TIME_SYNC_INTERVAL +#endif // timesync // show compiled features ESP_LOGI(TAG, "Features:%s", features); diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index 06a1e624e..0a7b88d1e 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/sensor.cpp b/src/sensor.cpp index b3f564402..559fd60d0 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -57,7 +57,7 @@ uint8_t *sensor_read(uint8_t sensor) { // note: Sensor1 fields are used for ENS count, if ENS detection enabled #if (COUNT_ENS) if (cfg.enscount) - payload.addCount(cwa_report(), MAC_SNIFF_BLE_CWA); + payload.addCount(cwa_report(), MAC_SNIFF_BLE_ENS); #else buf[0] = length; buf[1] = 0x01; diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index dd8ce4a10..d6325fcdd 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -26,7 +26,7 @@ typedef struct { 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 +// using IRAM_ATTR here to speed up callback function IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type) { @@ -35,16 +35,13 @@ 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 void switchWifiChannel(TimerHandle_t xTimer) { + // static uint8_t channel = 0; // channel rotation counter _ASSERT(xTimer != NULL); channel = (channel % WIFI_CHANNEL_MAX) + 1; // rotate channel 1..WIFI_CHANNEL_MAX