BLE: add central role and GATT client support - #4436
Open
palmdalian wants to merge 2 commits into
Open
Conversation
palmdalian
requested review from
DrZlo13,
Skorpionm,
gornekich,
gsurkov,
hedger,
nminaylov and
turbospok
as code owners
August 9, 2026 20:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
👋 Hi, I wanted to use my Flipper to do some peripheral exploration and saw the BLE Central role was not supported. I know there are constraints with memory sizes with the official firmware, but I hopefully directed the LLM to a reasonable solution so that BLE central is an optional feature if a power user really needs it. I'm also happy to send over the validation FAP code that uses the new apis.
Note: I'm not a firmware/C developer. I scanned through the code and verified that it worked with real hardware, but I inevitably missed obvious LLM mistakes since this isn't my usual domain. Hopefully this code is still generally helpful!
What's new
This adds an optional BLE central role and GATT client API to the existing STM32WB BLE glue. The firmware previously exposed only the peripheral role even though the Full BLE radio stack supports both roles.
Related: #2906. That scanner request was closed because the Full BLE stack could not be used as the default Core2 firmware within the available memory. This PR does not change the default Light stack; it exposes central functionality only when a user has explicitly installed the supported Full stack.
furi_ble/central.hwith APIs for scanning, connecting, disconnecting, ATT MTU exchange, service and characteristic discovery/enumeration, CCCD discovery, reads, writes with or without response, and notification subscription.No user application is installed by this PR. The BLE Inspector and the hardware validation applications used during development are external FAPs and are intentionally not included here.
Bug Fixes Included:
While implementing the Central role, the LLM identified and fixed two existing issues in the BLE event_dispatcher:
Important constraints
furi_hal_bt_is_central_supported()and fail gracefully when it returns false.Verification
Builds
./fbt firmware_all./fbt FIRMWARE_APP_SET=unit_tests firmware_all./fbt COMPACT=1 DEBUG=0 updater_package./fbt lintThe normal firmware, unit-test firmware/plugin configuration, and release updater package build successfully from the current branch. The repository-wide source-format and filename lint also passes.
Automated parser coverage
The
test_ble_centralminunit plugin covers:Hardware regression peripheral
Tested on a Flipper Zero running this firmware and the STM32WB Full BLE stack against a Heltec Mesh Node T114 / nRF52840 acting as a deterministic GATT peripheral.
The unattended regression test passed the following operations:
Recorded result:
PASSED.Repeated lifecycle stress test
A separate unattended test repeatedly exercised initialization, scanning, connecting, service and characteristic enumeration, 16-bit and 128-bit discovery, CCCD presence/absence, 255-byte and truncated reads, empty reads, notifications, both write modes, local and peer-initiated disconnects, and deinitialization.
Recorded result:
The four retries were transient link-establishment failures from the deliberately fast-restarting test peripheral. Feature, value, state, and memory-lifetime failures were not retried.
Real peripheral validation
The same API was exercised against a commercial BLE peripheral using two external applications: a focused reader and a generic BLE Inspector. Scanning, connection, GATT enumeration, characteristic reads, CCCD subscription, and button/sensor notification delivery were verified without a device-specific handshake.
The unattended focused-reader result was:
The generic Inspector was also used manually to enumerate standard Device Information and Battery services and to receive notifications from both the real peripheral and the nRF52840 emulator.
Suggested reviewer verification
Build and install a complete update package containing the Full BLE stack:
./fbt flash_usb_full COMPACT=1 DEBUG=0 \ COPRO_OB_DATA=scripts/ob_custradio.data \ COPRO_STACK_BIN=stm32wb5x_BLE_Stack_full_fw.bin \ COPRO_STACK_TYPE=ble_fullUse a central-role FAP to scan for a known GATT peripheral.
Connect, enumerate its services and characteristics, and read a standard value such as Device Name (
0x2A00) or Battery Level (0x2A19).Subscribe to a notifying characteristic and confirm that notifications arrive with the expected handle and payload.
Disconnect and repeat the sequence to exercise cleanup and reinitialization.
With the Light BLE stack installed, confirm that
furi_hal_bt_is_central_supported()returns false and that the application reports the unsupported stack rather than starting a central procedure.Author checklist (Fill this out)
AI usage disclosure (Fill this out)
The tracked implementation and tests in this PR were generated with AI under human direction. AI was used to inspect the existing BLE architecture and STM32WB/BlueNRG interfaces; implement central-role initialization, event routing, GATT procedures, synchronization, callback-lifetime handling, error recovery, HAL capability checks, public API exports, and parser tests; and revise the implementation in response to multiple focused code-review passes.
The generated code was not accepted based on generation alone. It was built in normal and unit-test configurations, reviewed specifically for bounds safety, controller/host state consistency, connection-handle routing, timeout behavior, callback ownership, and teardown races, and exercised on physical hardware using both a deterministic nRF52840 peripheral and a real BLE device. The external validation FAPs and peripheral emulator were also AI-generated for testing but are not part of this PR.
Reviewer checklist (Don't fill this out!)