Skip to content

[Breaking] Update Characteristic and Descriptor callbacks to return status and accept values. - #1203

Merged
h2zero merged 2 commits into
masterfrom
update-callbacks
Oct 27, 2026
Merged

h2zero merged 2 commits into
masterfrom
update-callbacks

Conversation

@h2zero

@h2zero h2zero commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Read and write callbacks can now return GATT status codes, allowing applications to report success or errors for attribute operations.
    • Write callbacks now receive the proposed value directly, and accepted writes update the attribute value only when the callback returns success.
  • Bug Fixes
    • Stream data is buffered only after a write callback succeeds.
    • Failed value-buffer allocations now leave the value in a safe, empty state.

Roberto Anić Banić and others added 2 commits October 27, 2026 14:13
The GATT access handler discarded the outcome of the characteristic
write callback and always returned 0 (success) to the peer, so an
application had no way to reject a write with an ATT error even under
write-with-response.

This replaces the the non-return value callbacks for characteristic and descriptor
read/write callbacks with callbacks that return an enum value from the added
`NimBLEGattStatus` enum. This will allow applications to accept or deny value access
with a standard BLE response code.

A rejection reaches the peer only for write-with-response; a write
command is unacknowledged so the code is dropped by the stack, by spec.

* Removed deprecated `NimBLECharacteristic::onStatus` callback.
…lback

This adds a value parameter to the `onWrite` callbacks for `NimBLECharacteristic` and
`NimBLEDescriptor` classes. This allows the application to reject the write and not have
it's internal value changed.
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 73143f95-2f88-4e21-b1a4-73a82170eb86
Commits

Reviewing files that changed from the base of the PR and between d9ce2fb and a7f71d8.

Files selected for processing: 11
  • examples/NimBLE_Server/NimBLE_Server.ino
  • src/NimBLEAttValue.cpp
  • src/NimBLECharacteristic.cpp
  • src/NimBLECharacteristic.h
  • src/NimBLEDescriptor.cpp
  • src/NimBLEDescriptor.h
  • src/NimBLEDevice.h
  • src/NimBLELocalValueAttribute.h
  • src/NimBLEServer.cpp
  • src/NimBLEStream.cpp
  • src/NimBLEStream.h

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Walkthrough

Arrr, characteristic and descriptor read and write callbacks now return GATT statuses. Write callbacks receive the proposed value, and the server propagates callback results while assembling incoming write data.

Changes: GATT Callback Status Handling

Layer / File(s) Summary
Status and callback contracts
src/NimBLELocalValueAttribute.h, src/NimBLECharacteristic.h, src/NimBLEDescriptor.h, src/NimBLEDevice.h
The local attribute, characteristic, and descriptor event APIs now use NimBLEGattStatus and pass write values as NimBLEAttValue&. The status enum and BLEGattStatus alias are added.
Characteristic and descriptor callback behavior
src/NimBLECharacteristic.cpp, src/NimBLEDescriptor.cpp
Read and write events return callback statuses. Characteristic and descriptor values are updated only when write callbacks return Success.
Server event dispatch
src/NimBLEAttValue.cpp, src/NimBLEServer.cpp
The server builds write values from mbuf segments, handles allocation and length errors, and returns read and write callback statuses. NimBLEAttValue resets its length and capacity fields when allocation fails.
Stream and example callback updates
src/NimBLEStream.cpp, src/NimBLEStream.h, examples/NimBLE_Server/NimBLE_Server.ino
The stream buffers data only after the user callback accepts a write. Example characteristic and descriptor callbacks use the updated signatures and log the supplied values.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant NimBLEServer
  participant NimBLEAttValue
  participant NimBLECharacteristic
  participant CharacteristicCallbacks
  NimBLEServer->>NimBLEAttValue: Build value from mbuf segments
  NimBLEServer->>NimBLECharacteristic: Call writeEvent with value and peer info
  NimBLECharacteristic->>CharacteristicCallbacks: Call onWrite with value and peer info
  CharacteristicCallbacks-->>NimBLECharacteristic: Return GATT status
  NimBLECharacteristic-->>NimBLEServer: Return write status
Loading

Possibly related PRs

  • h2zero/NimBLE-Arduino#1142: This PR changes the same callback API family, including callback registration and characteristic and descriptor callback sites.
Merge Risk: Minimal · up to a7f71

The changed callbacks and write handling have no established issue that needs resolution before merge.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surv… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main breaking API change: characteristic and descriptor callbacks now return status values and receive written values.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 21 functions across 11 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Arrr, a value sails in on the GATT tide
Callbacks judge the payload with status as guide
A write takes root when success comes through
Rejected bytes stay out of the stream’s queue
The server sends the result back true!

Comment @coderabbitai help to get the list of available commands.

@h2zero
h2zero merged commit f2bd8b3 into master Oct 27, 2026
44 checks passed
@h2zero
h2zero deleted the update-callbacks branch October 27, 2026 20:44
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.

1 participant