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