Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLE - no callback if client enables notifications (CCCD callbacks) #3721

Closed
beegee-tokyo opened this issue Feb 7, 2020 · 4 comments
Closed
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@beegee-tokyo
Copy link
Contributor

Hardware:

Board: ESP32 dev board
Core Installation version: 1.0.4
IDE name: Platform.io
Flash Frequency: 40Mhz
PSRAM enabled: no
Upload Speed: 460800
Computer OS: Windows 7

Description:

@chegewara
I am working on a BLE UART connection between Android and ESP32.
After connection established, it takes some time before the Android app is enabling notification on the UartTX characteristic. On the ESP32 I found no way to get informed if and when the BLE client enabled notifications. If the ESP32 notifies data immediately after a connection is established, the data is lost, because the Android app is not notified about it.
What I would need is a callback (or flag to test) that tells me that the Android app has enabled notifications on the characteristic. On nRF52 Arduino is a callback for the CCCD requests from the client.
Maybe I am blind, but I went through the BLE library up and down, but I cannot find anything that would give me this information.

Sketch: BLE Uart example

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLEServer *pServer = NULL;
BLECharacteristic *pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t txValue = 0;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

class MyServerCallbacks : public BLEServerCallbacks
{
	void onConnect(BLEServer *pServer)
	{
		deviceConnected = true;
	};

	void onDisconnect(BLEServer *pServer)
	{
		deviceConnected = false;
	}
};

class MyCallbacks : public BLECharacteristicCallbacks
{
	void onWrite(BLECharacteristic *pCharacteristic)
	{
		std::string rxValue = pCharacteristic->getValue();

		if (rxValue.length() > 0)
		{
			Serial.println("*********");
			Serial.print("Received Value: ");
			for (int i = 0; i < rxValue.length(); i++)
				Serial.print(rxValue[i]);

			Serial.println();
			Serial.println("*********");
		}
	}
};

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

	// Create the BLE Device
	BLEDevice::init("UART Service");

	// 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
	pTxCharacteristic = pService->createCharacteristic(
		CHARACTERISTIC_UUID_TX,
		BLECharacteristic::PROPERTY_NOTIFY);

	pTxCharacteristic->addDescriptor(new BLE2902());

	BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
		CHARACTERISTIC_UUID_RX,
		BLECharacteristic::PROPERTY_WRITE);

	pRxCharacteristic->setCallbacks(new MyCallbacks());

	// Start the service
	pService->start();

	// Start advertising
	pServer->getAdvertising()->start();
	Serial.println("Waiting a client connection to notify...");
}

void loop()
{

	if (deviceConnected)
	{
                // ============================================
                // First write might fail because client has not yet enabled notifications
                // ============================================
		pTxCharacteristic->setValue(&txValue, 1);
		pTxCharacteristic->notify();
		txValue++;
		delay(10); // bluetooth stack will go into congestion, if too many packets are sent
	}

	// disconnecting
	if (!deviceConnected && oldDeviceConnected)
	{
		delay(500);					 // give the bluetooth stack the chance to get things ready
		pServer->startAdvertising(); // restart advertising
		Serial.println("start advertising");
		oldDeviceConnected = deviceConnected;
	}
	// connecting
	if (deviceConnected && !oldDeviceConnected)
	{
		// do stuff here on connecting
		oldDeviceConnected = deviceConnected;
	}
}```

### Debug Messages:

No crash, just missing a callback

@stale
Copy link

stale bot commented Apr 7, 2020

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Apr 7, 2020
@stale
Copy link

stale bot commented Apr 22, 2020

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

@stale stale bot closed this as completed Apr 22, 2020
@GianCann
Copy link

@beegee-tokyo have you find a solution?

@adabru
Copy link

adabru commented Oct 14, 2020

Don't know since when, but now you can use descriptor callbacks, see https://github.com/espressif/arduino-esp32/blob/master/libraries/BLE/src/BLEDescriptor.h :

class SubscribeCallbacks: public BLEDescriptorCallbacks {
  public:
    void onWrite(BLEDescriptor* pDescriptor)"
} subscribeCallback;

...

BLEDescriptor* pCCCD = new BLE2902();
pCCCD->setCallbacks(&subscribeCallback);
pCharacteristic->addDescriptor(pCCCD);

...

void SubscribeCallbacks::onWrite(BLEDescriptor* pDescriptor) {
  // do what you want
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests

3 participants