diff --git a/platformio.ini b/platformio.ini index dc173f25..7f05eab7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,9 +10,9 @@ ; ---> SELECT TARGET PLATFORM HERE! <--- [platformio] -env_default = heltec_wifi_lora_32 +;env_default = heltec_wifi_lora_32 ;env_default = ttgov1 -;env_default = ttgov2 +env_default = ttgov2 ;env_default = lopy ;env_default = lopy4 ;env_default = lolin32lite_lora diff --git a/src/blecsan.cpp b/src/blecsan.cpp new file mode 100644 index 00000000..29924507 --- /dev/null +++ b/src/blecsan.cpp @@ -0,0 +1,313 @@ +/* code snippets taken from +https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner +*/ + +// Basic Config +#include "globals.h" + +// Bluetooth specific includes +#include +#include +#include + +#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] + +// Prototypes +static const char *bt_event_type_to_string(uint32_t eventType); +static const char *bt_gap_search_event_type_to_string(uint32_t searchEvt); +static const char *bt_addr_t_to_string(esp_ble_addr_type_t type); +static const char *bt_dev_type_to_string(esp_bt_dev_type_t type); +static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); + +// local Tag for logging +static const char *TAG = "paxcnt"; + +static void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + ESP_LOGD(TAG, "Received a GAP event: %s", bt_event_type_to_string(event)); + esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param; + + esp_err_t status; + + + switch (event) + { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + { + ESP_LOGD(TAG, "status: %d", p->scan_param_cmpl.status); + + // This procedure keep the device scanning the peer device which advertising on the air. + status = esp_ble_gap_start_scanning(BLESCANTIME); + if (status != ESP_OK) + { + ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status); + } + } + break; + + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + { + //scan start complete event to indicate scan start successfully or failed + if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(TAG, "Scan start failed"); + } + } + break; + + case ESP_GAP_BLE_SCAN_RESULT_EVT: + { + + ESP_LOGI(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", BT_BD_ADDR_HEX(p->scan_rst.bda)); + ESP_LOGI(TAG, "Device type : %s", bt_dev_type_to_string(p->scan_rst.dev_type)); + ESP_LOGI(TAG, "Search_evt : %s", bt_gap_search_event_type_to_string(p->scan_rst.search_evt)); + ESP_LOGI(TAG, "Addr_type : %s", bt_addr_t_to_string(p->scan_rst.ble_addr_type)); + ESP_LOGI(TAG, "RSSI : %d", p->scan_rst.rssi); + ESP_LOGI(TAG, "Flag : %d", p->scan_rst.flag); + + //bit 0 (OFF) LE Limited Discoverable Mode + //bit 1 (OFF) LE General Discoverable Mode + //bit 2 (ON) BR/EDR Not Supported + //bit 3 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (controller) + //bit 4 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (Host) + + ESP_LOGI(TAG, "num_resps : %d", p->scan_rst.num_resps); + + if ( p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) + { + // Scan is done. + + // The next 5 codelines automatically restarts the scan. + status = esp_ble_gap_start_scanning (BLESCANTIME); + if (status != ESP_OK) + { + ESP_LOGE(TAG, "esp_ble_gap_start_scanning: rc=%d", status); + } + + return; + } + + + if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) + { + + // 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); + ESP_LOGD(TAG, "len: %d, %.*s", len, len, data); + + } + ESP_LOGI(TAG, ""); + + } + break; + + case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: + { + if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(TAG, "Scan stop failed"); + } + else + { + ESP_LOGI(TAG, "Stop scan successfully"); + } + } + + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + { + if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(TAG, "Adv stop failed"); + } + else + { + ESP_LOGI(TAG, "Stop adv successfully"); + } + } + break; + + + default: + break; + } +} // gap_callback_handler + +static const char *bt_dev_type_to_string(esp_bt_dev_type_t type) { + switch(type) { + case ESP_BT_DEVICE_TYPE_BREDR: + return "ESP_BT_DEVICE_TYPE_BREDR"; + case ESP_BT_DEVICE_TYPE_BLE: + return "ESP_BT_DEVICE_TYPE_BLE"; + case ESP_BT_DEVICE_TYPE_DUMO: + return "ESP_BT_DEVICE_TYPE_DUMO"; + default: + return "Unknown"; + } +} // bt_dev_type_to_string + +static const char *bt_addr_t_to_string(esp_ble_addr_type_t type) { + 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"; + } +} // bt_addr_t_to_string + +static const char *bt_gap_search_event_type_to_string(uint32_t searchEvt) { + switch(searchEvt) { + case ESP_GAP_SEARCH_INQ_RES_EVT: + return "ESP_GAP_SEARCH_INQ_RES_EVT"; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + return "ESP_GAP_SEARCH_INQ_CMPL_EVT"; + case ESP_GAP_SEARCH_DISC_RES_EVT: + return "ESP_GAP_SEARCH_DISC_RES_EVT"; + case ESP_GAP_SEARCH_DISC_BLE_RES_EVT: + return "ESP_GAP_SEARCH_DISC_BLE_RES_EVT"; + case ESP_GAP_SEARCH_DISC_CMPL_EVT: + return "ESP_GAP_SEARCH_DISC_CMPL_EVT"; + case ESP_GAP_SEARCH_DI_DISC_CMPL_EVT: + return "ESP_GAP_SEARCH_DI_DISC_CMPL_EVT"; + case ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT: + return "ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT"; + default: + return "Unknown event type"; + } +} // bt_gap_search_event_type_to_string + +/* + * Convert a BT GAP event type to a string representation. + */ +static const char *bt_event_type_to_string(uint32_t eventType) { + switch(eventType) { + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + return "ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT"; + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + return "ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT"; + case ESP_GAP_BLE_SCAN_RESULT_EVT: + return "ESP_GAP_BLE_SCAN_RESULT_EVT"; + case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: + return "ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT"; + default: + return "Unknown event type"; + } +} // bt_event_type_to_string + + + +esp_err_t register_ble_functionality(void) +{ + esp_err_t status; + + ESP_LOGI(TAG, "Register GAP callback"); + + // This function is called to occur gap event, such as scan result. + //register the scan callback function to the gap module + status = esp_ble_gap_register_callback(gap_callback_handler); + if (status != ESP_OK) + { + ESP_LOGE(TAG, "esp_ble_gap_register_callback: rc=%d", status); + return ESP_FAIL; + } + + static esp_ble_scan_params_t ble_scan_params = + { + .scan_type = BLE_SCAN_TYPE_PASSIVE, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = (uint16_t) (BLESCANINTERVAL / 0.625), // Time = N * 0.625 msec + .scan_window = (uint16_t) (BLESCANWINDOW / 0.625) // Time = N * 0.625 msec + }; + + ESP_LOGI(TAG, "Set GAP scan parameters"); + + // This function is called to set scan parameters. + status = esp_ble_gap_set_scan_params(&ble_scan_params); + if (status != ESP_OK) + { + ESP_LOGE(TAG, "esp_ble_gap_set_scan_params: rc=%d", status); + return ESP_FAIL; + } + + + ESP_LOGD(TAG, "We have registered what we need!"); + + return ESP_OK ; +} + + +// Main start code running in its own Xtask +void bt_loop(void *ignore) +{ + esp_err_t status; + + ESP_LOGI(TAG, "Enabling Bluetooth Controller"); + + // Initialize BT controller to allocate task and other resource. + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + if (esp_bt_controller_init(&bt_cfg) != ESP_OK) + { + ESP_LOGE(TAG, "Bluetooth controller initialize failed"); + goto end; + } + + // Enable BT controller + if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) + { + ESP_LOGE(TAG, "Bluetooth controller enable failed"); + goto end; + } + + ESP_LOGI(TAG, "Bluetooth Controller Enabled"); + + ESP_LOGI(TAG, "Init Bluetooth stack"); + + // Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff + status = esp_bluedroid_init(); + if (status != ESP_OK) + { + ESP_LOGE(TAG, "%s init bluetooth failed\n", __func__); + goto end; + } + + // Enable bluetooth, must after esp_bluedroid_init() + status = esp_bluedroid_enable(); + if (status != ESP_OK) + { + ESP_LOGE(TAG, "%s enable bluetooth failed\n", __func__); + goto end; + } + + ESP_LOGI(TAG, "Bluetooth stack initialized"); + + ESP_LOGI(TAG, "Register BLE functionality"); + status = register_ble_functionality(); + if (status != ESP_OK) + { + ESP_LOGE(TAG, "Register BLE functionality failed"); + goto end; + } + + while(1) + { + vTaskDelay(1000); + yield(); + } + +end: + ESP_LOGI(TAG, "Terminating BT logging task"); + vTaskDelete(NULL); + +} // bt_loop \ No newline at end of file diff --git a/src/globals.h b/src/globals.h index 396f7fa9..25b8d333 100644 --- a/src/globals.h +++ b/src/globals.h @@ -57,5 +57,5 @@ extern std::set macs; #ifdef BLECOUNTER extern int scanTime; - extern std::set bles; + extern std::set bles; #endif diff --git a/src/main.cpp b/src/main.cpp index 518e81ad..8728dbc9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -253,6 +253,9 @@ void wifi_sniffer_init(void); void wifi_sniffer_set_channel(uint8_t channel); void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); +// defined in blescan.cpp +void bt_loop(void *ignore); + // Sniffer Task void sniffer_loop(void * pvParameters) { @@ -513,12 +516,16 @@ salt_reset(); // get new 16bit for salting hashes xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 0); ESP_LOGI(TAG, "Starting Wifi task on core 0"); xTaskCreatePinnedToCore(wifi_sniffer_loop, "wifisniffer", 4096, ( void * ) 1, 1, NULL, 0); + ESP_LOGI(TAG, "Starting Bluetooth task on core 0"); + xTaskCreatePinnedToCore(bt_loop, "btscan", 2048, NULL, 5, NULL, 0); // to come here: code for switching off core 1 -#else // run wifi task on core 0 and lora task on core 1 +#else // run wifi task on core 0 and lora task on core 1 and bt task on core 1 ESP_LOGI(TAG, "Starting Lora task on core 1"); xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, ( void * ) 1, ( 5 | portPRIVILEGE_BIT ), NULL, 1); ESP_LOGI(TAG, "Starting Wifi task on core 0"); xTaskCreatePinnedToCore(sniffer_loop, "wifisniffer", 4096, ( void * ) 1, 1, NULL, 0); + ESP_LOGI(TAG, "Starting Bluetooth task on core 1"); + xTaskCreatePinnedToCore(bt_loop, "btscan", 2048, NULL, 5, NULL, 1); #endif // Finally: kickoff first sendjob and join, then send initial payload "0000" diff --git a/src/main.h b/src/main.h index 305bd81a..a532af16 100644 --- a/src/main.h +++ b/src/main.h @@ -9,7 +9,7 @@ // set this to include BLE counting and vendor filter functions #define VENDORFILTER 1 // comment out if you want to count things, not people -#define BLECOUNTER 1 // comment out if you don't want BLE count +//#define BLECOUNTER 1 // comment out if you don't want BLE count // BLE scan parameters #define BLESCANCYCLE 2 // BLE scan once after each wifi scans