Every app shipped with the Bluetooth-rune icon. Draw a battery icon for
Battery Health and a signal/antenna icon for the two sub-GHz tools; the BLE
apps keep the Bluetooth icon, which is correct for them.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEaD4ZeAfvWLBUxXp8G11r
The three data rows were far wider than 128 px. Rework the layout into a
"Battery Health" title plus three compact rows that fit the width (percent +
voltage + charge state; current + temperature + VBUS; capacity + health +
wear), and nudge the voltage graph up to suit.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEaD4ZeAfvWLBUxXp8G11r
On device, scanning failed (BT Inspector showed the scan as stopped and found
nothing). The firmware's GAP layer is initialised by the bt service, and ST's
stack disallows raw hci_le_set_scan_* / hci_le_create_connection in that state.
Switch the shared central layer to the GAP procedures: aci_gap_start_
observation_proc / aci_gap_terminate_gap_proc(GAP_OBSERVATION_PROC) for
scanning, and aci_gap_create_connection (+ terminate the direct-connection proc
to cancel) for connecting, with a short settle after stopping observation.
Also surface the raw BLE status code on BT Inspector's scan screen ("err 0xNN")
so any remaining failure is diagnosable on device. Needs the gap command group
exported (BLE_API default is all).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEaD4ZeAfvWLBUxXp8G11r
The updater's option-byte validation (stage 8) compares the device OBs to the
manifest reference generated from scripts/ob.data, which is tuned for the LIGHT
stack (SFSA 0x080D7000, SBRV 0x0D7000>>2, and the SRAM2 secure boundaries).
Installing the FULL stack makes CPU2 move those boundaries (SFSA 0xCE, SBRV
0x0CE000>>2, ...), so validation fails right after the radio installs with
"Uncorr. value mismatch #[8-93]". These bytes are read-only (only CPU2 sets
them) and are correct once the radio install has succeeded, so comment the
CPU2-controlled secure-region OBs (SFSA, FSD, DDS, C2OPT, NBRSD, SNBRSA, BRSD,
SBRSA, SBRV) out of ob.data before the build. The user-controllable OBs (RDP,
BOR, boot config, watchdogs, PCROP, WRP) are still validated. Verified: the
regenerated manifest zeroes the SFSA/SBRV reference and compare mask; the full
suite still builds.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEaD4ZeAfvWLBUxXp8G11r
License Flipper Blue++ under GPL-3.0-or-later, matching the Flipper Zero
firmware it builds on and links against. Add the verbatim GPLv3 text as
LICENSE, an SPDX + copyright header to every original source file and
build.sh, and a License section to the README noting the app sources are
(C) 2026 Andy Dixon while the upstream firmware/SDK remain (C) Flipper
Devices Inc., both GPLv3. Headers are comment-only; the full suite still
builds and all faps link.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEaD4ZeAfvWLBUxXp8G11r
Export the full ST gap/gatt/hci/hal/l2cap command set by default instead of
just hci,gatt, so apps built against this SDK get the whole BLE API without
a rebuild. Costs ~9 KB more firmware flash: 788 KB, still 13 free pages to
the full stack. Update the build.sh comments and README (env-var table and
flash-budget table) to mark `all` as the default. Builds clean; all faps
link and resolve.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEaD4ZeAfvWLBUxXp8G11r
Recentre the README on Flipper Blue++ as a custom full-stack Bluetooth
firmware plus its app suite, rather than a single BT Inspector app that grew
extra sections. New structure: intro, build/install (with the env-var table),
a detailed per-app section for all ten apps (what each does, controls, logs),
then the firmware internals (full stack, exported API + flash table, extra
exports, sub-GHz unlock), how the BLE apps work, limitations, troubleshooting
and repo layout.
Point every app's fap_weburl at the renamed repo
(github.com/andydixon/flipper-bluepp) and recenter the build.sh header on the
full-stack BLE firmware and the app suite rather than a single app. GitHub
repo renamed from flipper-bt-inspector; the slug drops "++" since GitHub repo
names cannot contain "+".
In the all-bands sweep the CC1101 band gaps are skipped, but their bins kept
whatever a previous pass left there, drawing phantom bars. Set skipped bins
to the -127 dBm floor.
Teardown freed the view port before unhooking the serial and status
callbacks, which run on the BLE/BT thread and call view_port_update. A late
notification or status change during exit could touch freed memory. Unhook
both callbacks and restore the default profile first, then free the view port.
The iBeacon branch guarded on `l >= 20` but reads p[20] (the Tx-power byte),
so a payload clamped to exactly 20 bytes read one byte past the advertising
data. Require the full 21 bytes (16 UUID + 2 major + 2 minor + 1 Tx).
Add per-app limitation blocks for BLE Sensor Dashboard, Tracker Detector,
GATT Fuzzer, Beacon Toolkit, GATT Server, the Sub-GHz Scanner/Spectrum pair,
and Battery Health, and generalise the shared BLE notes from two apps to the
whole suite (no pairing, one app owns the radio at a time).
Live fuel-gauge readings (voltage, current, temperature, remaining/full/design capacity, health, wear) with a rolling voltage graph. Read-only; the only app that also runs on stock firmware.
Sweeps RSSI across the CC1101 bands in fixed steps, shows a spectrum, and logs frequencies above a threshold. Uses the region-unlocked firmware and an exported CC1101 preset.
Brings up the Flipper as a connectable serial GATT peripheral via the bt service profile API and echoes what a central writes. Restores the default profile on exit.
Connects, walks every service/characteristic, reads all readable values, and (on OK) writes boundary payloads to writable characteristics, logging every response. For authorised testing. Reuses libble.
Passively scans and flags item trackers by advertising signature (Apple Find My/AirTag, Tile, Samsung SmartTag), with a following-you warning for a tracker seen persistently. Read-only; reuses libble.
Connects to a selected peripheral, finds readable/notifying characteristics with known SIG meanings, and shows them decoded and updating live. Reuses libble (central + value decoders).
Only stage libble/ into apps that include ble_central.h (so non-BLE apps
don't compile the central layer). Rewrite the README overview to list the
full app suite and note that everything except Battery Health needs the
custom firmware.
Restructure the Limitations section into shared/hardware, BT Inspector, BLE
HID Host, and exported-API (unlock) groups. Document the HID host's
heuristic report decoding and keyboard-usage coverage, the flash/option-byte
brick risk, that RPC/loader exposes only internal types, and that the sub-GHz
unlock removes the region check only (PLL bands and the law still apply).
Patch furi_hal_region.c so furi_hal_region_is_frequency_allowed and
furi_hal_region_is_provisioned always return true, allowing transmit on any
frequency the CC1101 can tune regardless of provisioned region. The hardware
PLL bands (~300-348 / 387-464 / 779-928 MHz) remain since they are physical.
Guarded by SUBGHZ_UNLOCK (default 1); build SUBGHZ_UNLOCK=0 to keep limits.
README documents that transmitting outside your local allocation may be
illegal and this is for research/authorised testing only.
The RPC/loader commit added internal headers and relied on the "?" fallback
that enabled every newly-discovered symbol. That exported internal loader
helpers (loader_queue_*, loader_menu_alloc, ...) which are not in the
firmware API-table link, breaking the full firmware build; the earlier
per-app `fap` check did not link the table so it went unnoticed.
Change the api_symbols.csv editor so newly-discovered Headers stay enabled
(their declarations must reach the API table) but new Functions/Variables
default to disabled unless explicitly listed in EXPORT_ENABLE. Drop the
over-broad ^rpc_/^loader_ patterns (the public APIs are already exported by
stock firmware). Result: internal loader types are available to apps, the
internal helper functions stay unexported, and the full firmware links.
Extract the reusable BLE central/GATT client and name/value decoders into
libble/ (moved out of bt_inspector). build.sh now stages libble/*.{c,h}
into each app dir at build time and builds every app in APPS=(...).
New app ble_hid_host: connects to a BLE keyboard or mouse, discovers the
HID service (0x1812), sets protocol mode (boot when offered, else report),
subscribes to the input-report characteristics, and decodes keyboard
(modifiers + key names) and mouse (buttons + dx/dy/wheel) reports live.
Events scroll on screen and are logged with raw bytes to
apps_data/ble_hid_host/. No pairing, so encryption-gated keyboards stay
silent; open devices and most mice work. Both faps build and pass APPCHK.
The public rpc_* and loader_* APIs are already exported by stock firmware
(RPC sessions, app data exchange, launch/enqueue/lock/menu); enable them
explicitly via EXPORT_ENABLE so they stay on. Add the internal loader
header set (loader_i.h, loader_menu.h, loader_queue.h, loader_applications.h)
to the SDK so the internal Loader handle and the menu/queue helpers are
reachable from apps. rpc_i.h is skipped: it depends on the protobuf headers
which are not part of the app SDK. API version -> 87.3; firmware links.
Enable all furi_hal_flash_* functions: geometry, free-page info, raw
program/erase/dword-write, and option-byte read/set/apply. Lets an app
read and modify internal flash directly (research use). Guarded by
EXPORT_FLASH (default 1); build with EXPORT_FLASH=0 to leave disabled.
17 symbols exported; firmware links and the app builds.
The gas-gauge readings (voltage, current, temperature, capacity, health,
charge state) are already exported by stock firmware; add the one remaining
safe reader, furi_hal_power_insomnia_level. furi_hal_power_init stays
disabled because re-initialising the power HAL from an app is unsafe.
Add a data-driven firmware-symbol export mechanism (EXPORT_ENABLE list in
build.sh, applied by the api_symbols.csv editor) and use it to enable all
gap_* functions, the safe ble_glue_* status/lifecycle calls, and
furi_hal_bt_init. Apps can now drive GAP directly, run a custom GATT
server, set the advertised name / extra-beacon config, and read radio-stack
status. The coprocessor FUS stack delete/install calls stay disabled to
avoid erasing the radio firmware. 19 symbols newly exported; firmware links.
build.sh now adds ST's aci_*/hci_* headers to the SDK (with extern "C"
guards, the API table is C++), lets fbt regenerate api_symbols.csv and
enables the selected functions (BLE_API=hci,gatt default; min; all).
The app builds as a normal .fap shipped inside the update package and
loadable from SD, saving ~12 KB of firmware flash versus the built-in
(min mode: ~22 KB). qsort replaced with an insertion sort since libc's
qsort is not exported to apps. README documents modes and flash budget.
Built-in firmware app (needs the full ST BLE stack) with live RSSI-sorted
scan list, advertisement decoding (Apple Continuity, Microsoft CDP, Fast
Pair, Eddystone), connect/discover/read/write/notify, device-info summary,
value history and a timestamped session log. build.sh produces a firmware
update package with COPRO_STACK_TYPE=ble_full and the app compiled in.