commit
7f20c198b9
@ -55,7 +55,6 @@ Depending on board hardware following features are supported:
|
|||||||
- OLED Display (shows detailed status)
|
- OLED Display (shows detailed status)
|
||||||
- RGB LED (shows colorized status)
|
- RGB LED (shows colorized status)
|
||||||
- Button (short press: flip display page / long press: send alarm message)
|
- Button (short press: flip display page / long press: send alarm message)
|
||||||
- Silicon unique ID
|
|
||||||
- Battery voltage monitoring (analog read / AXP192 / IP5306)
|
- Battery voltage monitoring (analog read / AXP192 / IP5306)
|
||||||
- GPS (Generic serial NMEA, or Quectel L76 I2C)
|
- GPS (Generic serial NMEA, or Quectel L76 I2C)
|
||||||
- Environmental sensors (Bosch BMP180/BME280/BME680 I2C; SDS011 serial)
|
- Environmental sensors (Bosch BMP180/BME280/BME680 I2C; SDS011 serial)
|
||||||
|
@ -18,10 +18,6 @@
|
|||||||
#include "mallocator.h"
|
#include "mallocator.h"
|
||||||
#include <bsec.h>
|
#include <bsec.h>
|
||||||
|
|
||||||
// sniffing types
|
|
||||||
#define MAC_SNIFF_WIFI 0
|
|
||||||
#define MAC_SNIFF_BLE 1
|
|
||||||
|
|
||||||
// bits in payloadmask for filtering payload data
|
// bits in payloadmask for filtering payload data
|
||||||
#define GPS_DATA (0x01)
|
#define GPS_DATA (0x01)
|
||||||
#define ALARM_DATA (0x02)
|
#define ALARM_DATA (0x02)
|
||||||
@ -67,9 +63,9 @@
|
|||||||
|
|
||||||
enum sendprio_t { prio_low, prio_normal, prio_high };
|
enum sendprio_t { prio_low, prio_normal, prio_high };
|
||||||
enum timesource_t { _gps, _rtc, _lora, _unsynced };
|
enum timesource_t { _gps, _rtc, _lora, _unsynced };
|
||||||
|
enum snifftype_t { MAC_SNIFF_WIFI, MAC_SNIFF_BLE, MAC_SNIFF_BLE_ENS };
|
||||||
enum runmode_t {
|
enum runmode_t {
|
||||||
RUNMODE_POWERCYCLE = 0,
|
RUNMODE_POWERCYCLE,
|
||||||
RUNMODE_NORMAL,
|
RUNMODE_NORMAL,
|
||||||
RUNMODE_WAKEUP,
|
RUNMODE_WAKEUP,
|
||||||
RUNMODE_UPDATE
|
RUNMODE_UPDATE
|
||||||
@ -114,6 +110,13 @@ typedef struct {
|
|||||||
uint8_t Message[PAYLOAD_BUFFER_SIZE];
|
uint8_t Message[PAYLOAD_BUFFER_SIZE];
|
||||||
} MessageBuffer_t;
|
} MessageBuffer_t;
|
||||||
|
|
||||||
|
// Struct for MAC processing queue
|
||||||
|
typedef struct {
|
||||||
|
uint8_t mac[6];
|
||||||
|
int8_t rssi;
|
||||||
|
snifftype_t sniff_type;
|
||||||
|
} MacBuffer_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t latitude;
|
int32_t latitude;
|
||||||
int32_t longitude;
|
int32_t longitude;
|
||||||
@ -145,13 +148,14 @@ extern std::array<uint64_t, 0xff> beacons;
|
|||||||
extern configData_t cfg; // current device configuration
|
extern configData_t cfg; // current device configuration
|
||||||
extern char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer
|
extern char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer
|
||||||
extern uint8_t volatile channel; // wifi channel rotation counter
|
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 uint8_t batt_level; // display value
|
||||||
extern uint16_t volatile macs_wifi, macs_ble; // display values
|
extern uint16_t volatile macs_wifi, macs_ble; // display values
|
||||||
extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC
|
extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC
|
||||||
extern timesource_t timeSource;
|
extern timesource_t timeSource;
|
||||||
extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ;
|
extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ;
|
||||||
extern SemaphoreHandle_t I2Caccess;
|
extern SemaphoreHandle_t I2Caccess;
|
||||||
extern TaskHandle_t irqHandlerTask, ClockTask;
|
extern TaskHandle_t irqHandlerTask, ClockTask, macProcessTask;
|
||||||
extern TimerHandle_t WifiChanTimer;
|
extern TimerHandle_t WifiChanTimer;
|
||||||
extern Timezone myTZ;
|
extern Timezone myTZ;
|
||||||
extern RTC_DATA_ATTR runmode_t RTC_runmode;
|
extern RTC_DATA_ATTR runmode_t RTC_runmode;
|
||||||
|
@ -14,13 +14,12 @@
|
|||||||
#include "corona.h"
|
#include "corona.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAC_SNIFF_WIFI 0
|
|
||||||
#define MAC_SNIFF_BLE 1
|
|
||||||
#define MAC_SNIFF_BLE_CWA 2
|
|
||||||
|
|
||||||
uint16_t get_salt(void);
|
uint16_t get_salt(void);
|
||||||
uint64_t macConvert(uint8_t *paddr);
|
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);
|
void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
||||||
|
@ -6,14 +6,10 @@
|
|||||||
#define BT_BD_ADDR_HEX(addr) \
|
#define BT_BD_ADDR_HEX(addr) \
|
||||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
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
|
// local Tag for logging
|
||||||
static const char TAG[] = "bluetooth";
|
static const char TAG[] = "bluetooth";
|
||||||
|
|
||||||
|
#ifdef VERBOSE
|
||||||
const char *bt_addr_t_to_string(esp_ble_addr_type_t type) {
|
const char *bt_addr_t_to_string(esp_ble_addr_type_t type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BLE_ADDR_TYPE_PUBLIC:
|
case BLE_ADDR_TYPE_PUBLIC:
|
||||||
@ -110,15 +106,24 @@ const char *btsig_gap_type(uint32_t gap_type) {
|
|||||||
return "Unknown type";
|
return "Unknown type";
|
||||||
}
|
}
|
||||||
} // btsig_gap_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,
|
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 *param) {
|
||||||
|
|
||||||
esp_ble_gap_cb_param_t *p = (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,
|
ESP_LOGV(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv,
|
||||||
btsig_gap_type(*p->scan_rst.ble_adv));
|
btsig_gap_type(*p->scan_rst.ble_adv));
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
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 ==
|
if (p->scan_rst.search_evt ==
|
||||||
ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
|
ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
|
||||||
{ // evaluate sniffed packet
|
{ // evaluate sniffed packet
|
||||||
|
#ifdef VERBOSE
|
||||||
ESP_LOGV(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x",
|
ESP_LOGV(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
BT_BD_ADDR_HEX(p->scan_rst.bda));
|
BT_BD_ADDR_HEX(p->scan_rst.bda));
|
||||||
ESP_LOGV(TAG, "Addr_type : %s",
|
ESP_LOGV(TAG, "Addr_type : %s",
|
||||||
bt_addr_t_to_string(p->scan_rst.ble_addr_type));
|
bt_addr_t_to_string(p->scan_rst.ble_addr_type));
|
||||||
ESP_LOGV(TAG, "RSSI : %d", p->scan_rst.rssi);
|
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 (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)) {
|
||||||
|
#ifdef VERBOSE
|
||||||
ESP_LOGV(TAG, "BT device filtered");
|
ESP_LOGV(TAG, "BT device filtered");
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// hash and add this device and show new count total if it was not
|
// add this device mac to processing queue
|
||||||
// previously added
|
|
||||||
|
|
||||||
#if (COUNT_ENS)
|
#if (COUNT_ENS)
|
||||||
uint16_t hashedmac =
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
|
|
||||||
|
|
||||||
#if (COUNT_ENS)
|
|
||||||
if (cfg.enscount) {
|
|
||||||
// check for ens signature
|
// check for ens signature
|
||||||
if (NULL != strstr((const char *)p->scan_rst.ble_adv, ensMagicBytes))
|
if (cfg.enscount) {
|
||||||
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
|
#endif
|
||||||
|
|
||||||
/* to be improved in vendorfilter if:
|
/* 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,
|
// uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv,
|
||||||
ESP_BLE_AD_TYPE_NAME_CMPL, &len);
|
ESP_BLE_AD_TYPE_NAME_CMPL, &len);
|
||||||
|
|
||||||
filter BLE devices using their advertisements to get filter alternative to
|
filter BLE devices using their advertisements to get filter alternative
|
||||||
vendor OUI if vendorfiltering is on, we ...
|
to vendor OUI if vendorfiltering is on, we ...
|
||||||
- want to count: mobile phones and tablets
|
- want to count: mobile phones and tablets
|
||||||
- don't want to count: beacons, peripherals (earphones, headsets,
|
- don't want to count: beacons, peripherals (earphones, headsets,
|
||||||
printers), cars and machines see
|
printers), cars and machines see
|
||||||
@ -211,13 +211,13 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
} // switch
|
||||||
} // gap_callback_handler
|
} // gap_callback_handler
|
||||||
|
|
||||||
esp_err_t register_ble_callback(void) {
|
esp_err_t register_ble_callback(void) {
|
||||||
ESP_LOGI(TAG, "Register GAP callback");
|
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
|
// register the scan callback function to the gap module
|
||||||
ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler));
|
ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler));
|
||||||
|
|
||||||
|
@ -23,18 +23,13 @@ static std::map<uint16_t, unsigned long> cwaSeenNotifiers;
|
|||||||
|
|
||||||
// Remove notifiers last seen over FORGET_AFTER_MINUTES ago.
|
// Remove notifiers last seen over FORGET_AFTER_MINUTES ago.
|
||||||
void cwa_clear() {
|
void cwa_clear() {
|
||||||
/*
|
#ifdef VERBOSE
|
||||||
|
ESP_LOGV(TAG, "CWA: forget old notifier: %d", cwaSeenNotifiers.size());
|
||||||
#ifdef SOME_FORM_OF_DEBUG
|
|
||||||
ESP_LOGD(TAG, "CWA: forget old notifier: %d", cwaSeenNotifiers.size());
|
|
||||||
for (auto const ¬ifier : cwaSeenNotifiers) {
|
for (auto const ¬ifier : cwaSeenNotifiers) {
|
||||||
ESP_LOGD(TAG, "CWA forget <%X>", notifier.first);
|
ESP_LOGD(TAG, "CWA forget <%04X>", notifier.first);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// clear everything, otherwise we would count the same device again, as in the
|
// clear everything, otherwise we would count the same device again, as in the
|
||||||
// next cycle it likely will advertise with a different hash-value
|
// next cycle it likely will advertise with a different hash-value
|
||||||
cwaSeenNotifiers.clear();
|
cwaSeenNotifiers.clear();
|
||||||
|
@ -40,6 +40,9 @@ void doHousekeeping() {
|
|||||||
ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d",
|
||||||
uxTaskGetStackHighWaterMark(irqHandlerTask),
|
uxTaskGetStackHighWaterMark(irqHandlerTask),
|
||||||
eTaskGetState(irqHandlerTask));
|
eTaskGetState(irqHandlerTask));
|
||||||
|
ESP_LOGD(TAG, "MACprocessor %d bytes left | Taskstate = %d",
|
||||||
|
uxTaskGetStackHighWaterMark(macProcessTask),
|
||||||
|
eTaskGetState(macProcessTask));
|
||||||
#if (HAS_LORA)
|
#if (HAS_LORA)
|
||||||
ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d",
|
||||||
uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask));
|
uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask));
|
||||||
|
@ -311,6 +311,7 @@ void dp_drawPage(time_t t, bool nextpage) {
|
|||||||
dp_printf(" ");
|
dp_printf(" ");
|
||||||
#endif
|
#endif
|
||||||
dp_printf(" ch:%02d", channel);
|
dp_printf(" ch:%02d", channel);
|
||||||
|
// dp_printf(" due:%02d", rf_load);
|
||||||
dp_println();
|
dp_println();
|
||||||
|
|
||||||
// line 5: RSSI limiter + free memory
|
// line 5: RSSI limiter + free memory
|
||||||
|
@ -105,8 +105,4 @@
|
|||||||
#define LORA_IO1 (33)
|
#define LORA_IO1 (33)
|
||||||
#define LORA_IO2 LMIC_UNUSED_PIN
|
#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
|
#endif
|
||||||
|
@ -162,49 +162,7 @@ void os_getDevEui(u1_t *buf) {
|
|||||||
} else {
|
} else {
|
||||||
gen_lora_deveui(buf); // generate DEVEUI from device's MAC
|
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
|
||||||
#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)
|
#if (VERBOSE)
|
||||||
|
166
src/macsniff.cpp
166
src/macsniff.cpp
@ -10,6 +10,9 @@
|
|||||||
// Local logging tag
|
// Local logging tag
|
||||||
static const char TAG[] = __FILE__;
|
static const char TAG[] = __FILE__;
|
||||||
|
|
||||||
|
QueueHandle_t MacQueue;
|
||||||
|
TaskHandle_t macProcessTask;
|
||||||
|
|
||||||
uint16_t salt = 0;
|
uint16_t salt = 0;
|
||||||
|
|
||||||
uint16_t get_salt(void) {
|
uint16_t get_salt(void) {
|
||||||
@ -43,31 +46,106 @@ uint64_t macConvert(uint8_t *paddr) {
|
|||||||
return (__builtin_bswap64(*mac) >> 16);
|
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)
|
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
|
||||||
@ -76,43 +154,44 @@ uint16_t mac_add(uint8_t *paddr, int8_t rssi, bool 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) {
|
switch (MacBuffer.sniff_type) {
|
||||||
|
|
||||||
|
case MAC_SNIFF_WIFI:
|
||||||
macs_wifi++; // increment Wifi MACs counter
|
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:
|
||||||
macs_ble++; // increment BLE Macs counter
|
macs_ble++; // increment BLE 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_MAGENTA, 50);
|
blink_LED(COLOR_MAGENTA, 50);
|
||||||
#endif
|
#endif
|
||||||
}
|
break;
|
||||||
#endif
|
|
||||||
|
|
||||||
// in beacon monitor mode check if seen MAC is a known beacon
|
#if (COUNT_ENS)
|
||||||
if (cfg.monitormode) {
|
case MAC_SNIFF_BLE_ENS:
|
||||||
beaconID = isBeacon(macConvert(paddr));
|
macs_ble++; // increment BLE Macs counter
|
||||||
if (beaconID >= 0) {
|
cwa_mac_add(hashedmac); // process ENS beacon
|
||||||
ESP_LOGI(TAG, "Beacon ID#%d detected", beaconID);
|
|
||||||
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
||||||
blink_LED(COLOR_WHITE, 2000);
|
blink_LED(COLOR_WHITE, 50);
|
||||||
#endif
|
#endif
|
||||||
payload.reset();
|
break;
|
||||||
payload.addAlarm(rssi, beaconID);
|
|
||||||
SendPayload(BEACONPORT, prio_high);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
#endif // COUNT_ENS
|
||||||
|
#endif // BLECOUNTER
|
||||||
|
|
||||||
|
} // switch
|
||||||
} // added
|
} // added
|
||||||
|
|
||||||
// Log scan result
|
// Log scan result
|
||||||
@ -124,22 +203,13 @@ uint16_t mac_add(uint8_t *paddr, int8_t rssi, bool 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;
|
|
||||||
}
|
}
|
22
src/main.cpp
22
src/main.cpp
@ -35,9 +35,10 @@ IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
|||||||
lmictask 1 2 MCCI LMiC LORAWAN stack
|
lmictask 1 2 MCCI LMiC LORAWAN stack
|
||||||
clockloop 1 4 generates realtime telegrams for external clock
|
clockloop 1 4 generates realtime telegrams for external clock
|
||||||
timesync_proc 1 3 processes realtime time sync requests
|
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
|
gpsloop 1 1 reads data from GPS via serial or i2c
|
||||||
lorasendtask 1 1 feeds data from lora sendqueue to lmcic
|
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
|
IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator
|
||||||
|
|
||||||
Low priority numbers denote low priority tasks.
|
Low priority numbers denote low priority tasks.
|
||||||
@ -86,8 +87,9 @@ triggers pps 1 sec impulse
|
|||||||
|
|
||||||
configData_t cfg; // struct holds current device configuration
|
configData_t cfg; // struct holds current device configuration
|
||||||
char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer for LMIC event message
|
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 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
|
uint16_t volatile macs_wifi = 0, macs_ble = 0; // globals for display
|
||||||
|
|
||||||
hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL;
|
hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL;
|
||||||
@ -285,6 +287,10 @@ void setup() {
|
|||||||
start_ota_update();
|
start_ota_update();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// start mac processing task
|
||||||
|
ESP_LOGI(TAG, "Starting MAC processor...");
|
||||||
|
macQueueInit();
|
||||||
|
|
||||||
// start BLE scan callback if BLE function is enabled in NVRAM configuration
|
// start BLE scan callback if BLE function is enabled in NVRAM configuration
|
||||||
// or switch off bluetooth, if not compiled
|
// or switch off bluetooth, if not compiled
|
||||||
#if (BLECOUNTER)
|
#if (BLECOUNTER)
|
||||||
@ -490,12 +496,9 @@ void setup() {
|
|||||||
sendTimer.attach(cfg.sendcycle * 2, setSendIRQ);
|
sendTimer.attach(cfg.sendcycle * 2, setSendIRQ);
|
||||||
cyclicTimer.attach(HOMECYCLE, setCyclicIRQ);
|
cyclicTimer.attach(HOMECYCLE, setCyclicIRQ);
|
||||||
|
|
||||||
#if (TIME_SYNC_INTERVAL)
|
// only if we have a timesource we do timesync
|
||||||
|
#if ((TIME_SYNC_LORAWAN) || (TIME_SYNC_LORASERVER) || (HAS_GPS) || \
|
||||||
#if (!(TIME_SYNC_LORAWAN) && !(TIME_SYNC_LORASERVER) && !defined HAS_GPS && \
|
defined HAS_RTC)
|
||||||
!defined HAS_RTC)
|
|
||||||
#warning you did not specify a time source, time will not be synched
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined HAS_IF482 || defined HAS_DCF77)
|
#if (defined HAS_IF482 || defined HAS_DCF77)
|
||||||
ESP_LOGI(TAG, "Starting Clock Controller...");
|
ESP_LOGI(TAG, "Starting Clock Controller...");
|
||||||
@ -509,8 +512,9 @@ void setup() {
|
|||||||
ESP_LOGI(TAG, "Starting Timekeeper...");
|
ESP_LOGI(TAG, "Starting Timekeeper...");
|
||||||
_ASSERT(timepulse_init()); // setup pps timepulse
|
_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
|
// show compiled features
|
||||||
ESP_LOGI(TAG, "Features:%s", features);
|
ESP_LOGI(TAG, "Features:%s", features);
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -57,7 +57,7 @@ uint8_t *sensor_read(uint8_t sensor) {
|
|||||||
// note: Sensor1 fields are used for ENS count, if ENS detection enabled
|
// note: Sensor1 fields are used for ENS count, if ENS detection enabled
|
||||||
#if (COUNT_ENS)
|
#if (COUNT_ENS)
|
||||||
if (cfg.enscount)
|
if (cfg.enscount)
|
||||||
payload.addCount(cwa_report(), MAC_SNIFF_BLE_CWA);
|
payload.addCount(cwa_report(), MAC_SNIFF_BLE_ENS);
|
||||||
#else
|
#else
|
||||||
buf[0] = length;
|
buf[0] = length;
|
||||||
buf[1] = 0x01;
|
buf[1] = 0x01;
|
||||||
|
@ -26,7 +26,7 @@ typedef struct {
|
|||||||
uint8_t payload[0]; // network data ended with 4 bytes csum (CRC32)
|
uint8_t payload[0]; // network data ended with 4 bytes csum (CRC32)
|
||||||
} wifi_ieee80211_packet_t;
|
} 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,
|
IRAM_ATTR void wifi_sniffer_packet_handler(void *buff,
|
||||||
wifi_promiscuous_pkt_type_t type) {
|
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;
|
(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Software-timer driven Wifi channel rotation callback function
|
// Software-timer driven Wifi channel rotation callback function
|
||||||
void switchWifiChannel(TimerHandle_t xTimer) {
|
void switchWifiChannel(TimerHandle_t xTimer) {
|
||||||
|
// static uint8_t channel = 0; // channel rotation counter
|
||||||
_ASSERT(xTimer != NULL);
|
_ASSERT(xTimer != NULL);
|
||||||
channel =
|
channel =
|
||||||
(channel % WIFI_CHANNEL_MAX) + 1; // rotate channel 1..WIFI_CHANNEL_MAX
|
(channel % WIFI_CHANNEL_MAX) + 1; // rotate channel 1..WIFI_CHANNEL_MAX
|
||||||
|
Loading…
Reference in New Issue
Block a user