I'm trying to write a generic BLE scanner that will explore the world around it and report back what it finds.
The first step of collecting advertisements works fine using BLEDevice::getScan() followed by start().
I can even connect to specific devices based on their advertised address. Where I'm running into problems is calling getServices() on the client. It ALWAYS hangs without returning. But if I hard code the service UUID and call getService() it works fine and I'm able to drill down into the Characteristics and Descriptors.
I have tried this on an ESP32 WROOM32 and with an ESP32-S3, connecting to a variety of BLE devices.
Is there some other way I can programmatically query what services a device has?
Looking into the source for the BLE library code I suspect that the ESP_GATTC_SEARCH_CMPL_EVT is never firing, but no clue what I can do about that...
sketch:
#include "BLEDevice.h"
#define NEW_LINE "\r\n"
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
while (0 == Serial.available()) {
Serial.print('.');
delay(1000);
}
BLEDevice::init("");
String macAddress = "67:c1:60:d5:63:b9";
BLEAddress *myDevice = new BLEAddress(macAddress);
BLEClient *pClient = BLEDevice::createClient();
pClient->connect(*myDevice);
pClient->setMTU(517);
Serial.print("Before" NEW_LINE);
std::map<std::string, BLERemoteService *> *foundServices = pClient->getServices();
Serial.print("After" NEW_LINE);
if (nullptr == foundServices) {
Serial.print("No services found!" NEW_LINE);
} else {
Serial.printf("%d services found" NEW_LINE, foundServices->size());
}
pClient->disconnect();
}
void loop() {
// put your main code here, to run repeatedly:
}
Log:
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
Model : ESP32-S3
Package : 0
Revision : 0.01
Cores : 2
CPU Frequency : 240 MHz
XTAL Frequency : 40 MHz
Features Bitfield : 0x00000012
Embedded Flash : No
Embedded PSRAM : No
2.4GHz WiFi : Yes
Classic BT : No
BT Low Energy : Yes
IEEE 802.15.4 : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
Total Size : 333716 B ( 325.9 KB)
Free Bytes : 293588 B ( 286.7 KB)
Allocated Bytes : 34856 B ( 34.0 KB)
Minimum Free Bytes: 288516 B ( 281.8 KB)
Largest Free Block: 262132 B ( 256.0 KB)
------------------------------------------
SPIRAM Memory Info:
------------------------------------------
Total Size : 2097152 B (2048.0 KB)
Free Bytes : 2095104 B (2046.0 KB)
Allocated Bytes : 0 B ( 0.0 KB)
Minimum Free Bytes: 2095104 B (2046.0 KB)
Largest Free Block: 2064372 B (2016.0 KB)
Bus Mode : QSPI
------------------------------------------
Flash Info:
------------------------------------------
Chip Size : 4194304 B (4 MB)
Block Size : 65536 B ( 64.0 KB)
Sector Size : 4096 B ( 4.0 KB)
Page Size : 256 B ( 0.2 KB)
Bus Speed : 80 MHz
Bus Mode : QIO
------------------------------------------
Partitions Info:
------------------------------------------
nvs : addr: 0x00009000, size: 20.0 KB, type: DATA, subtype: NVS
otadata : addr: 0x0000E000, size: 8.0 KB, type: DATA, subtype: OTA
ota_0 : addr: 0x00010000, size: 1408.0 KB, type: APP, subtype: OTA_0
ota_1 : addr: 0x00170000, size: 1408.0 KB, type: APP, subtype: OTA_1
uf2 : addr: 0x002D0000, size: 256.0 KB, type: APP, subtype: FACTORY
ffat : addr: 0x00310000, size: 960.0 KB, type: DATA, subtype: FAT
------------------------------------------
Software Info:
------------------------------------------
Compile Date/Time : Dec 12 2024 12:57:32
Compile Host OS : windows
ESP-IDF Version : v5.1.4-972-g632e0c2a9f-dirty
Arduino Version : 3.0.7
------------------------------------------
Board Info:
------------------------------------------
Arduino Board : ADAFRUIT_FEATHER_ESP32S3_REVTFT
Arduino Variant : adafruit_feather_esp32s3_reversetft
Arduino FQBN : esp32:esp32:adafruit_feather_esp32s3_reversetft:UploadSpeed=921600,USBMode=default,CDCOnBoot=cdc,MSCOnBoot=default,DFUOnBoot=default,UploadMode=cdc,CPUFreq=240,FlashMode=qio,FlashSize=4M,PartitionScheme=tinyuf2,DebugLevel=verbose,PSRAM=enabled,LoopCore=1,EventsCore=1,EraseFlash=none,ZigbeeMode=default
============ Before Setup End ============
...........[ 13619][V][BLEDevice.cpp:62] createClient(): >> createClient
[ 13620][V][BLEDevice.cpp:68] createClient(): << createClient
[ 13620][V][BLEClient.cpp:110] connect(): >> connect(67:c1:60:d5:63:b9)
[ 13621][I][BLEDevice.cpp:598] addPeerDevice(): add conn_id: 0, GATT role: client
[ 13622][V][FreeRTOS.cpp:179] take(): Semaphore taking: name: RegEvt (0x3fcb4750), owner: <N/A> for connect
[ 13623][V][FreeRTOS.cpp:188] take(): Semaphore taken: name: RegEvt (0x3fcb4750), owner: connect
[ 13624][V][FreeRTOS.cpp:59] wait(): >> wait: Semaphore [waiting3625][D: name: R][egEvt (0x3fBLEDecb4750), owner: cvonnect for connect
ice.cpp:138] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 3] ... ESP_GATTC_REG_EVT
[ 13627][V][BLEUtils.cpp:1202] dumpGattClientEvent(): GATT Event: ESP_GATTC_REG_EVT
[ 13628][V][BLEUtils.cpp:1357] dumpGattClientEvent(): [status: ESP_GATT_OK, app_id: 0x0]
[ 13629][D][BLEClient.cpp:185] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 3] ... ESP_GATTC_REG_EVT
[ 13630][V][FreeRTOS.cpp:136] give(): Semaphore giving: name: RegEvt (0x3fcb4750), owner: connect
[ 13631][V][FreeRTOS.cpp:73] wait(): << wait: Semaphore released: name: RegEvt (0x3fcb4750), owner: <N/A>
[ 13632][V][FreeRTOS.cpp:179] take(): Semaphore taking: name: OpenEvt (0x3fcb47b4), owner: <N/A> for connect
[ 13633][V][FreeRTOS.cpp:188] take(): Semaphore taken: name: OpenEvt (0x3fcb47b4), owner: connect
[ 13634][V][FreeRTOS.cpp:85] timedWait(): >> wait: Semaphore waiting: name: OpenEvt (0x3fcb47b4), owner: connect for connect
[ 43638][D][BLEDevice.cpp:138] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 3] ... ESP_GATTC_DISCONNECT_EVT
[ 43639][V][BLEUtils.cpp:1202] dumpGattClientEvent(): GATT Event: ESP_GATTC_DISCONNECT_EVT
[ 43640][V][BLEUtils.cpp:1241] dumpGattClientEvent(): [reason: ESP_GATT_CONN_CONN_CANCEL, conn_id: 0, remote_bda: 67:c1:60:d5:63:b9]
[ 43641][D][BLEClient.cpp:185] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 3] ... ESP_GATTC_DISCONNECT_EVT
[ 43643][D][BLEDevice.cpp:138] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 3] ... ESP_GATTC_OPEN_EVT
[ 43644][V][BLEUtils.cpp:1202] dumpGattClientEvent(): GATT Event: ESP_GATTC_OPEN_EVT
[ 43645][V][BLEUtils.cpp:1315] dumpGattClientEvent(): [status: ESP_GATT_ERROR, conn_id: 0, remote_bda: 67:c1:60:d5:63:b9, mtu: 0]
[ 43646][D][BLEClient.cpp:185] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 3] ... ESP_GATTC_OPEN_EVT
[ 43647][E][BLEClient.cpp:249] gattClientEventHandler(): Failed to connect, status=Unknown ESP_ERR error
[ 43649][V][FreeRTOS.cpp:136] give(): Semaphore giving: name: OpenEvt (0x3fcb47b4), owner: connect
[ 43650][V][FreeRTOS.cpp:105] timedWait(): << wait: Semaphore name: OpenEvt (0x3fcb47b4), owner: <N/A> released: 1
[ 43651][I][BLEDevice.cpp:609] removePeerDevice(): remove: 0, GATT role client
[ 43652][V][BLEClient.cpp:162] connect(): << connect(),[ 43652][][rc=0
BLEDevice.cpp:138] gattClientEventHandler[ 43653][V][BLEClient.cpp:570] setMTU(): )<< setLocalMTU
: gaBefore
ttClientEvent[ 43654][V][BLEClient.cpp:456] getSHervices():a >> getSenrvices
dler [es[ 43655][V][BLEClient.cpp:74] clearServices(): >> clearServipcegatt_s
if: 3[ 43656][V][BL] ... ESP_GATTC_UNREG_EVT
EClient.cpp:81] c[ 43657][V][BLEUtilsea.cpp:12rSer0vices(): <2] < clearServices
dumpGattClientEvent[ 43658][V][FreeRTOS.cpp:179] t(ake(): Semaphore t)aking:: name: SearchCmplEvt (0x3fcb4818), owner: <N/A> for getGServices
ATT Event: ESP_GATTC_U[ 43660][V][FreeRTOS.cpp:188] take(): SeNmaphoreR taken: name: SearcEhCmplEvt (0xG3fcb4818), owner: ge_tServices
EVT
[ 43662][V][FreeRTOS.cpp:59] wait(): >> wait: Semaphore waiting: name: SearchCmplEvt (0x3fcb4818), owner: getServices for getServices