How to "discover" BLE services using ESP32?

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

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.