Page 1 of 1

Bonding BLE client to a device

Posted: Wed Jul 30, 2025 11:59 am
by Fardenco
Hi,
I own a Bluetooth PTT (Push To Talk) button that is initially made to be connected to a smartphone for use with voice chat apps.
My goal is to connect it to an ESP32-C3 to trigger actions when the button is pushed.
The device uses BLE 4.2.
I've made this program that connects to the device using its MAC address, and then it subscribes to the notify characteristics I'm interested in.

Code: Select all

#include <BLEDevice.h>

#define outputPin 4

static BLEAddress bleAddress("93:6C:96:76:97:8D");
static const char* SERVICE_UUID = "0000ff00-0000-1000-8000-00805f9b34fb";
static const char* CHARACTERISTIC_UUID = "0000ff01-0000-1000-8000-00805f9b34fb";

BLEClient* pClient;
BLERemoteCharacteristic* pRemoteCharacteristic;

bool connected = false;

class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pClient) {
    Serial.println("Connexion réussie au périphérique BLE");
  }

  void onDisconnect(BLEClient* pClient) {
    Serial.println("Déconnexion du périphérique BLE");
    connected = false;
  }
};

void notifyCallback(BLERemoteCharacteristic* pCharacteristic, uint8_t* data, size_t length, bool isNotify) {
  Serial.print("Notification reçue : ");
  for (size_t i = 0; i < length; i++) {
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.println();

  if (length > 0) {
    if (data[0] == 1) {
      digitalWrite(outputPin, HIGH);
      Serial.println("Bouton pressé");
    }
    else
    {
      digitalWrite(outputPin, LOW);
      Serial.println("Bouton relâché");
    }
  }
}

void setup() {
  Serial.begin(115200);

  pinMode(outputPin, OUTPUT);

  Serial.println("Initialisation du client BLE...");

  BLEDevice::init("");
  pClient = BLEDevice::createClient();
  pClient->setClientCallbacks(new MyClientCallback());

  Serial.print("Connexion à l'adresse : ");
  Serial.println(bleAddress.toString().c_str());

  if (pClient->connect(bleAddress)) {
    connected = true;
    Serial.println("Connecté au périphérique BLE");
  } else {
    Serial.println("Impossible de se connecter.");
    return;
  }

  // Obtenir le service et la caractéristique
  BLERemoteService* pRemoteService = pClient->getService(SERVICE_UUID);
  if (pRemoteService == nullptr) {
    Serial.println("Service non trouvé !");
    return;
  }

  pRemoteCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID);
  if (pRemoteCharacteristic == nullptr) {
    Serial.println("Caractéristique non trouvée !");
    return;
  }

  // Souscrire aux notifications de la caractéristique
  if (pRemoteCharacteristic->canNotify()) {
    pRemoteCharacteristic->registerForNotify(notifyCallback);
    Serial.println("Notifications activées.");
  } else {
    Serial.println("Impossible de s'abonner aux notifications.");
  }
}

void loop() {
  if (!connected) {
    Serial.println("Tentative de reconnexion...");
    pClient->connect(bleAddress);
    delay(2000);
  }
  delay(1000);
}
This program works great, excepts for one thing : the PTT button only updates the characteristic I'm interested in when bonded, and my program only connects to the device, it doesn't bond.
If, before running the program, I bond the device to my smartphone, then the ESP32 will happily get the notifications when pressing the button.
But if the device is not bonded, then it doesn't update.

The PTT button changes behavior when it's bonded. If it's not bonded, then the integrated LED blinks twice per second and a 3s push on the button shuts the device down. When it's bonded, the LED only blinks every 5s and the button can be pressed for as long as we want (which is mandatory for a PTT button). The device will only shut down when unbonded.

My problem is that I can't seem to find how to initiate the bond with the device as a client.
From what I unserstand the BLESecurity library can handle that
I added those lines to try

Code: Select all

BLESecurity* pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);
The program compiles without error but it doesn't seem to make any difference, I wonder if this setting is only for BLE server and not for BLE client.

Could someone help me figure this out ?
Thank you