nkolban/esp32-snippets

Writing >20 Bytes to Characteristic causes all registered Write Callbacks to fire

vicatcu opened this issue ยท 4 comments

Using ESP32_BLE_Arduino on firmware side and using nRF Connect phone app to send TEXT to a characteristic works great, but if I send more than 20 characters in the string, I can observe all of my write characteristic callbacks fire in response. I don't think it's harmful as they just get executed with the previously written values, but it's a bit concerning. Anyone else seen this behavior?

@chegewara Here is a minimal example that demonstrates it, derived from the BLE_server example. All you have to do to demonstrate the result I describe in the OP is write a 21 character string to either characteristic. Anything 20 bytes or less does not result in this behavior. I'm just not sure if it's the library inspiring this or if it's the mobile app (nRF Connect). FWIW, I'm using v1.0.1 of the arduino-esp32 boards manager package.

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLECharacteristic.h>
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID         "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC1_UUID "aeb5483e-36e1-4688-b7f5-ea07361b26a8"
#define CHARACTERISTIC2_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class Characteristic1_Callbacks: public BLECharacteristicCallbacks {
  void onRead(BLECharacteristic *pCharacteristic){
    Serial.println("Characteristic1 Read");
  }
  void onWrite(BLECharacteristic *pCharacteristic){
    Serial.print("Characteristic1 Written: ");
    Serial.println((char *) pCharacteristic->getData());
  }
};

class Characteristic2_Callbacks: public BLECharacteristicCallbacks {
  void onRead(BLECharacteristic *pCharacteristic){
    Serial.println("Characteristic2 Read");
  }
  void onWrite(BLECharacteristic *pCharacteristic){
    Serial.print("Characteristic2 Written: ");
    Serial.println((char *) pCharacteristic->getData());
  }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  BLEDevice::init("Long name works now");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC1_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setCallbacks(new Characteristic1_Callbacks());
  pCharacteristic->setValue("I am Characteristic #1");


  pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC2_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setCallbacks(new Characteristic2_Callbacks());
  pCharacteristic->setValue("I am Characteristic #2");

  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Characteristic defined! Now you can read it in your phone!");
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
}

Will be fixed soon. Thanks.

@chegewara cool well done! How does this back-ported into the https://github.com/nkolban/ESP32_BLE_Arduino repo now?

Easiest and fastest method IMO is to download this repo zip and replace all files in arduino BLE library or you can follow this instruction:
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/ArduinoBLE.md#replacing-the-version-that-comes-with-arduino-esp32