arduino-esp32
arduino-esp32 copied to clipboard
ESP32 BLE dual role: Callback error when connecting to Client
Board
ESP32 Dev Module
Device Description
KIT ESP32 Dev Module
Hardware Configuration
[env:esp32dev] platform = espressif32 @ 6.4.0 board = esp32dev framework = arduino upload_port = COM19 monitor_port = COM19 monitor_speed = 115200
Version
latest master (checkout manually)
IDE Name
Platform IO
Operating System
Windows 11
Flash frequency
40MHz
PSRAM enabled
no
Upload speed
default
Description
I am developing a project using ESP32's BLE with 2 roles at the same time:
-
Server: connects to the phone to send information
-
Client: connects to another BLE device Problem:
-
When connecting and disconnecting from the phone:
- Callback function: only onConnectServer & onDisconnectServer
-
When connecting and disconnecting from a BLE device:
- Callback functions: onConnectServer & onDisconnectServer and onConnectClient & onDisconnecrClient (see message log)
This affects the connection between the ESP32 and the phone when the ESP32 connects or disconnects with another BLE device. How can the ESP32 recall the correct device being connected and not cause confusion?
Sketch
#include <Arduino.h>
#include "BLEDevice.h"
//#include "BLEScan.h"
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
#define SERVICE_UUID "390950ed-51ff-445f-a6c6-f6a95a6a465f"
#define CHARACTERISTIC_UUID "f2c513b7-6b51-4363-b6aa-1ef8bd08c56a"
static BLEUUID advServiceUUID("db1df223-4020-4c5a-930c-1989ea04991f");
// The remote service we wish to connect to.
static BLEUUID serviceUUID("efedd9eb-24a9-492a-b66a-ed8543ee096e");
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("22e5bbd9-62d8-45eb-9ffd-4a2b88cd6c3a");
bool deviceConnected = false;
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
static void eventHandler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) {
if (event == ESP_GAP_BLE_SCAN_RESULT_EVT ||
event == ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT ||
event == ESP_GAP_BLE_SCAN_START_COMPLETE_EVT
) return;
Serial.printf("BLE event: %d\n", event);
}
static void eventClientHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* param) {
Serial.printf("BLE Client event: %d\n", event);
}
static void eventServerHandler(esp_gatts_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gatts_cb_param_t* param) {
Serial.printf("BLE Server event: %d\n", event);
}
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
}
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
Serial.println("on Connect Server");
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
Serial.println("on DisConnect Server");
BLEDevice::startAdvertising();
}
};
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
Serial.println("on Connect Client");
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("on Disconnect Client");
}
};
bool connectToServer() {
// Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
// Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
// Serial.println(" - Connected to server");
pClient->setMTU(517); //set client to request maximum MTU from server (default is 23 otherwise)
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
if(pRemoteCharacteristic->canNotify())
pRemoteCharacteristic->registerForNotify(notifyCallback);
connected = true;
return true;
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(advServiceUUID)) {
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
BLEDevice::init("ESP32 dual role");
// BLEDevice::setCustomGapHandler(eventHandler);
// BLEDevice::setCustomGattcHandler(eventClientHandler);
// BLEDevice::setCustomGattsHandler(eventServerHandler);
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
pCharacteristic->addDescriptor(new BLE2902());
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter
BLEDevice::startAdvertising();
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, true);
Serial.println("START");
} // End of setup.
// This is the Arduino main loop function.
void loop() {
if (doConnect == true) {
if (connectToServer()) {
// Serial.println("Connected to the BLE Server");
} else {
// Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
doConnect = false;
}
if (connected) {
}else if(doScan){
BLEDevice::getScan()->start(5); // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
}
delay(1000); // Delay a second between loops.
} // End of loop
Debug Message
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 271414342, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4
START
ac:0b:fb:67:fd:6a
on Connect Server
on Connect Client
[ 5940][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
[ 5941][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
[ 5950][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
on DisConnect Server
on Disconnect Client
ac:0b:fb:67:fd:6a
on Connect Server
on Connect Client
[1062633][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
[1062633][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
[1062642][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
on DisConnect Server
on Disconnect Client
ac:0b:fb:67:fd:6a
on Connect Server
on Connect Client
[1376076][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
[1376077][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
[1376086][E][BLERemoteCharacteristic.cpp:289] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.