arduino-libraries/ArduinoBLE

22-byte Name descriptor (0x2901) throws GATT error 7 (offset error) - shorter or longer names are fine

Opened this issue · 1 comments

Both LightBlue and Nordic RF Connect show the same behaviour:

ESP32-S3, ArduinoBLE 1.3.7

A name characteristic that is exactly 22 bytes long cannot be read by the BLE peripheral, showing GATT error 7.

BLEDescriptor ECM1PWMName("2901", "ECM1 PWM Speed Control");

Adding a single space to the end makes the descriptor work perfectly.

BLEDescriptor ECM1PWMName("2901", "ECM1 PWM Speed Control ");

Name descriptors both shorter than or longer than 22 bytes work well.

Test case:

#include <Arduino.h>
#include <ArduinoBLE.h>

BLEDevice BLEcentral;

#define SERVICE_UUID "11c80020-83a8-4114-b8a3-41766e616e00"
#define TWENTYONE_CHAR_CHARACTERISTIC "11c80021-83a8-4114-b8a3-41766e616e00"
#define TWENTYTWO_CHAR_CHARACTERISTIC "11c80022-83a8-4114-b8a3-41766e616e00"
#define TWENTYTHREE_CHAR_CHARACTERISTIC "11c80023-83a8-4114-b8a3-41766e616e00"

const uint8_t floatNoUnitsCPF[7] = {
  0x14,        // IEEE-754 32-bit float
  0x00,        // exponent (0)
  0x00, 0x27,  // unit (no unit) - little endian
  0x01,        // namespace (Bluetooth SIG namespace)
  0x00, 0x00   // description (not used) - little-endian
};

BLEService myService(SERVICE_UUID);

BLEFloatCharacteristic twentyOneCharCharacteristic(TWENTYONE_CHAR_CHARACTERISTIC, BLERead | BLENotify);
BLEDescriptor twentyOneCharCharacteristicName("2901", "123456789012345678901");

BLEFloatCharacteristic twentyTwoCharCharacteristic(TWENTYTWO_CHAR_CHARACTERISTIC, BLERead | BLENotify);
BLEDescriptor twentyTwoCharCharacteristicName("2901", "1234567890123456789012");

BLEFloatCharacteristic twentyThreeCharCharacteristic(TWENTYTHREE_CHAR_CHARACTERISTIC, BLERead | BLENotify);
BLEDescriptor twentyThreeCharCharacteristicName("2901", "12345678901234567890123");

BLEDescriptor floatNoUnitsCPFDesc("2904", floatNoUnitsCPF, 7);

// put function declarations here:
int myFunction(int, int);

void setup() {

  BLE.begin();

  BLE.setLocalName("Test Case");
  BLE.setDeviceName("Test Case");
  BLE.setAdvertisedService(myService);

  twentyOneCharCharacteristic.addDescriptor(twentyOneCharCharacteristicName);
  twentyOneCharCharacteristic.addDescriptor(floatNoUnitsCPFDesc);

  twentyTwoCharCharacteristic.addDescriptor(twentyTwoCharCharacteristicName);
  twentyTwoCharCharacteristic.addDescriptor(floatNoUnitsCPFDesc);

  twentyThreeCharCharacteristic.addDescriptor(twentyThreeCharCharacteristicName);
  twentyThreeCharCharacteristic.addDescriptor(floatNoUnitsCPFDesc);

  myService.addCharacteristic(twentyOneCharCharacteristic);
  myService.addCharacteristic(twentyTwoCharCharacteristic);
  myService.addCharacteristic(twentyThreeCharCharacteristic);

  BLE.addService(myService);

  twentyOneCharCharacteristic.setValue(0.0);
  twentyTwoCharCharacteristic.setValue(0.0);
  twentyThreeCharCharacteristic.setValue(0.0);

  BLE.advertise();

  BLEcentral = BLE.central();
}

void loop() {
  if (BLEcentral.connected()) {
    ;
  }

  delay(100);
}

Verify with LightBlue or nRF Connect. The 22-character name descriptor will show error 7, but the 21- and 23-character names will be read successfully.