Skip to content

Fix ATT descriptor discovery handle range and response parsing - #435

Open
thematrix999 wants to merge 1 commit into
arduino-libraries:masterfrom
thematrix999:fix-att-descriptor-discovery
Open

Fix ATT descriptor discovery handle range and response parsing#435
thematrix999 wants to merge 1 commit into
arduino-libraries:masterfrom
thematrix999:fix-att-descriptor-discovery

Conversation

@thematrix999

Copy link
Copy Markdown

Problem

ATTClass::discoverDescriptors() currently has two issues.

First, the descriptor discovery range ends at the value handle of the next characteristic. This includes the next characteristic declaration and value in the descriptor range of the current characteristic.

Second, byte 1 of an ATT Find Information Response is a Format field, not a length multiplier. Format 0x01 contains 4-byte entries (2-byte handle + 2-byte UUID), while format 0x02 contains 18-byte entries (2-byte handle + 16-byte UUID).

The current implementation calculates an 8-byte entry length for format 0x02 and always parses UUIDs as 16-bit.

This can cause discoverAttributes() to fail or time out when a service contains multiple 128-bit characteristics.

Related to #277.

Changes

  • End descriptor discovery immediately before the next characteristic declaration.
  • Parse both ATT Find Information Response formats correctly.
  • Reject unsupported response format values.

Hardware test

Tested using two Arduino Nano 33 BLE boards, one configured as central and the other as peripheral, with ArduinoBLE 1.5.0.

The peripheral exposes a 128-bit service containing multiple 128-bit characteristics, including a notify characteristic with a CCCD.

Before the change:

  • The BLE connection succeeds.
  • discoverAttributes() does not complete.
  • The central reports HCI receive-buffer overflows.
  • The connection eventually terminates.

After the change:

  • Attribute discovery completes successfully.
  • The expected characteristics are found.
  • CCCD subscription succeeds.
  • The central receives 16-byte notifications correctly.

@CLAassistant

CLAassistant commented Aug 3, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 15.24%. Comparing base (281377b) to head (0aeeb27).

Files with missing lines Patch % Lines
src/utility/ATT.cpp 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #435      +/-   ##
==========================================
- Coverage   15.25%   15.24%   -0.02%     
==========================================
  Files          29       29              
  Lines        3684     3687       +3     
==========================================
  Hits          562      562              
- Misses       3122     3125       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@thematrix999
thematrix999 force-pushed the fix-att-descriptor-discovery branch from 3a5b7a8 to 0aeeb27 Compare August 3, 2026 10:26
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Memory usage change @ 0aeeb27

Board flash % RAM for global variables %
arduino:esp32:nano_nora 🔺 +36 - +36 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:mbed_giga:giga 🔺 0 - +64 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:mbed_nano:nano33ble 🔺 0 - +64 0.0 - +0.01 0 - 0 0.0 - 0.0
arduino:mbed_nano:nanorp2040connect 🔺 +26 - +26 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:mbed_nicla:nicla_vision 🔺 0 - +64 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:mbed_opta:opta 🔺 0 - +64 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:mbed_portenta:envie_m7 N/A N/A N/A N/A
arduino:renesas_portenta:portenta_c33 🔺 +32 - +32 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:renesas_uno:unor4wifi 🔺 +32 - +32 +0.01 - +0.01 0 - 0 0.0 - 0.0
arduino:samd:mkrwifi1010 🔺 +24 - +24 +0.01 - +0.01 0 - 0 0.0 - 0.0
arduino:samd:nano_33_iot 🔺 +24 - +24 +0.01 - +0.01 0 - 0 0.0 - 0.0
arduino:zephyr:unoq 🔺 +116 - +128 +0.01 - +0.02 🔺 +36 - +36 +0.01 - +0.01
arduino:zephyr_main:giga 🔺 +120 - +124 +0.01 - +0.01 🔺 +36 - +36 +0.01 - +0.01
arduino:zephyr_main:nano33ble 🔺 +120 - +124 +0.02 - +0.02 🔺 +36 - +36 +0.03 - +0.03
arduino:zephyr_main:opta 🔺 +120 - +124 +0.01 - +0.01 🔺 +36 - +36 +0.01 - +0.01
arduino:zephyr_main:portentac33 🔺 +120 - +124 +0.01 - +0.01 🔺 +36 - +36 +0.03 - +0.03
arduino:zephyr_main:portentah7 🔺 +120 - +124 +0.01 - +0.01 🔺 +36 - +36 +0.01 - +0.01
Click for full report table
Board examples/Central/LedControl
flash
% examples/Central/LedControl
RAM for global variables
% examples/Central/PeripheralExplorer
flash
% examples/Central/PeripheralExplorer
RAM for global variables
% examples/Central/Scan
flash
% examples/Central/Scan
RAM for global variables
% examples/Central/ScanCallback
flash
% examples/Central/ScanCallback
RAM for global variables
% examples/Central/SensorTagButton
flash
% examples/Central/SensorTagButton
RAM for global variables
% examples/Peripheral/Advertising/EnhancedAdvertising
flash
% examples/Peripheral/Advertising/EnhancedAdvertising
RAM for global variables
% examples/Peripheral/Advertising/RawDataAdvertising
flash
% examples/Peripheral/Advertising/RawDataAdvertising
RAM for global variables
% examples/Peripheral/BatteryMonitor
flash
% examples/Peripheral/BatteryMonitor
RAM for global variables
% examples/Peripheral/ButtonLED
flash
% examples/Peripheral/ButtonLED
RAM for global variables
% examples/Peripheral/CallbackLED
flash
% examples/Peripheral/CallbackLED
RAM for global variables
% examples/Peripheral/EncryptedBatteryMonitor
flash
% examples/Peripheral/EncryptedBatteryMonitor
RAM for global variables
% examples/Peripheral/LED
flash
% examples/Peripheral/LED
RAM for global variables
%
arduino:esp32:nano_nora 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0 36 0.0 0 0.0
arduino:mbed_giga:giga 0 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 0 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 0 0.0 0 0.0
arduino:mbed_nano:nano33ble 64 0.01 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 64 0.01 0 0.0 64 0.01 0 0.0 0 0.0 0 0.0 64 0.01 0 0.0 64 0.01 0 0.0 64 0.01 0 0.0 64 0.01 0 0.0 64 0.01 0 0.0
arduino:mbed_nano:nanorp2040connect 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0 26 0.0 0 0.0
arduino:mbed_nicla:nicla_vision 0 0.0 0 0.0 0 0.0 0 0.0 64 0.0 0 0.0 0 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 0 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0
arduino:mbed_opta:opta 0 0.0 0 0.0 0 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 0 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0 64 0.0 0 0.0
arduino:mbed_portenta:envie_m7 N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A
arduino:renesas_portenta:portenta_c33 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0 32 0.0 0 0.0
arduino:renesas_uno:unor4wifi 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0 32 0.01 0 0.0
arduino:samd:mkrwifi1010 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0
arduino:samd:nano_33_iot 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0 24 0.01 0 0.0
arduino:zephyr:unoq 116 0.01 36 0.01 124 0.02 36 0.01 124 0.02 36 0.01 124 0.02 36 0.01 128 0.02 36 0.01 124 0.02 36 0.01 124 0.02 36 0.01 120 0.02 36 0.01 124 0.02 36 0.01 128 0.02 36 0.01 116 0.01 36 0.01 116 0.01 36 0.01
arduino:zephyr_main:giga 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 124 0.01 36 0.01 120 0.01 36 0.01 124 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 124 0.01 36 0.01
arduino:zephyr_main:nano33ble 120 0.02 36 0.03 120 0.02 36 0.03 124 0.02 36 0.03 124 0.02 36 0.03 120 0.02 36 0.03 124 0.02 36 0.03 120 0.02 36 0.03 124 0.02 36 0.03 124 0.02 36 0.03 120 0.02 36 0.03 124 0.02 36 0.03 120 0.02 36 0.03
arduino:zephyr_main:opta 124 0.01 36 0.01 124 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 124 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01
arduino:zephyr_main:portentac33 120 0.01 36 0.03 120 0.01 36 0.03 120 0.01 36 0.03 120 0.01 36 0.03 124 0.01 36 0.03 120 0.01 36 0.03 124 0.01 36 0.03 120 0.01 36 0.03 120 0.01 36 0.03 120 0.01 36 0.03 120 0.01 36 0.03 124 0.01 36 0.03
arduino:zephyr_main:portentah7 120 0.01 36 0.01 120 0.01 36 0.01 124 0.01 36 0.01 124 0.01 36 0.01 120 0.01 36 0.01 124 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 124 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01 120 0.01 36 0.01
Click for full report CSV
Board,examples/Central/LedControl<br>flash,%,examples/Central/LedControl<br>RAM for global variables,%,examples/Central/PeripheralExplorer<br>flash,%,examples/Central/PeripheralExplorer<br>RAM for global variables,%,examples/Central/Scan<br>flash,%,examples/Central/Scan<br>RAM for global variables,%,examples/Central/ScanCallback<br>flash,%,examples/Central/ScanCallback<br>RAM for global variables,%,examples/Central/SensorTagButton<br>flash,%,examples/Central/SensorTagButton<br>RAM for global variables,%,examples/Peripheral/Advertising/EnhancedAdvertising<br>flash,%,examples/Peripheral/Advertising/EnhancedAdvertising<br>RAM for global variables,%,examples/Peripheral/Advertising/RawDataAdvertising<br>flash,%,examples/Peripheral/Advertising/RawDataAdvertising<br>RAM for global variables,%,examples/Peripheral/BatteryMonitor<br>flash,%,examples/Peripheral/BatteryMonitor<br>RAM for global variables,%,examples/Peripheral/ButtonLED<br>flash,%,examples/Peripheral/ButtonLED<br>RAM for global variables,%,examples/Peripheral/CallbackLED<br>flash,%,examples/Peripheral/CallbackLED<br>RAM for global variables,%,examples/Peripheral/EncryptedBatteryMonitor<br>flash,%,examples/Peripheral/EncryptedBatteryMonitor<br>RAM for global variables,%,examples/Peripheral/LED<br>flash,%,examples/Peripheral/LED<br>RAM for global variables,%
arduino:esp32:nano_nora,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0,36,0.0,0,0.0
arduino:mbed_giga:giga,0,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,0,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,0,0.0,0,0.0
arduino:mbed_nano:nano33ble,64,0.01,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,64,0.01,0,0.0,64,0.01,0,0.0,0,0.0,0,0.0,64,0.01,0,0.0,64,0.01,0,0.0,64,0.01,0,0.0,64,0.01,0,0.0,64,0.01,0,0.0
arduino:mbed_nano:nanorp2040connect,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0,26,0.0,0,0.0
arduino:mbed_nicla:nicla_vision,0,0.0,0,0.0,0,0.0,0,0.0,64,0.0,0,0.0,0,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,0,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0
arduino:mbed_opta:opta,0,0.0,0,0.0,0,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,0,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0,64,0.0,0,0.0
arduino:mbed_portenta:envie_m7,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A
arduino:renesas_portenta:portenta_c33,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0,32,0.0,0,0.0
arduino:renesas_uno:unor4wifi,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0,32,0.01,0,0.0
arduino:samd:mkrwifi1010,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0
arduino:samd:nano_33_iot,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0,24,0.01,0,0.0
arduino:zephyr:unoq,116,0.01,36,0.01,124,0.02,36,0.01,124,0.02,36,0.01,124,0.02,36,0.01,128,0.02,36,0.01,124,0.02,36,0.01,124,0.02,36,0.01,120,0.02,36,0.01,124,0.02,36,0.01,128,0.02,36,0.01,116,0.01,36,0.01,116,0.01,36,0.01
arduino:zephyr_main:giga,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,124,0.01,36,0.01,120,0.01,36,0.01,124,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,124,0.01,36,0.01
arduino:zephyr_main:nano33ble,120,0.02,36,0.03,120,0.02,36,0.03,124,0.02,36,0.03,124,0.02,36,0.03,120,0.02,36,0.03,124,0.02,36,0.03,120,0.02,36,0.03,124,0.02,36,0.03,124,0.02,36,0.03,120,0.02,36,0.03,124,0.02,36,0.03,120,0.02,36,0.03
arduino:zephyr_main:opta,124,0.01,36,0.01,124,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,124,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01
arduino:zephyr_main:portentac33,120,0.01,36,0.03,120,0.01,36,0.03,120,0.01,36,0.03,120,0.01,36,0.03,124,0.01,36,0.03,120,0.01,36,0.03,124,0.01,36,0.03,120,0.01,36,0.03,120,0.01,36,0.03,120,0.01,36,0.03,120,0.01,36,0.03,124,0.01,36,0.03
arduino:zephyr_main:portentah7,120,0.01,36,0.01,120,0.01,36,0.01,124,0.01,36,0.01,124,0.01,36,0.01,120,0.01,36,0.01,124,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,124,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01,120,0.01,36,0.01

@thematrix999

Copy link
Copy Markdown
Author

For context, the four failing compile jobs also fail on the latest scheduled workflow run from the current master branch:

https://github.com/arduino-libraries/ArduinoBLE/actions/runs/30351039055

The failing targets are the same:

  • arduino:megaavr:uno2018:mode=on
  • arduino:zephyr_main:nicla_sense
  • esp32:esp32:esp32c6
  • esp32:esp32:esp32h2

The Nano 33 BLE compilation, unit tests, and spell check pass.

Codecov reports no patch coverage because the existing unit test suite does not currently exercise ATTClass::discoverDescriptors(). The change has been tested on hardware using two Nano 33 BLE boards, as
described in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants