Skip to content

net/bt: Add native Bluetooth host stack - #20686

Open
anchao wants to merge 1 commit into
apache:masterfrom
anchao:nuttx_bluetooth_host_stack
Open

anchao wants to merge 1 commit into
apache:masterfrom
anchao:nuttx_bluetooth_host_stack

Conversation

@anchao

@anchao anchao commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds a native NuttX Bluetooth host stack under net/bt, together with
the public Bluetooth header namespace, net_buf memory support, build
integration, and a broad sim:bt coverage configuration.

The stack is ported from Zephyr Bluetooth host components and adapted to run
inside NuttX without requiring an external RTOS runtime. It keeps the controller
interface separated through the HCI transport and driver abstraction layers,
while exposing Bluetooth APIs through the NuttX public include tree.

This provides the foundation for BLE, BR/EDR Classic, Bluetooth Mesh, LE Audio,
GATT services, and profile-level shell/demo coverage in NuttX.

What is included

Core Bluetooth Host

This PR adds the core host-side Bluetooth protocol machinery, including:

  • Bluetooth address handling
  • Identity management
  • HCI command and event processing
  • HCI driver registration and transport abstraction
  • Buffer ownership and monitor support
  • Settings storage and key management
  • SMP pairing support
  • ATT request processing
  • GATT database handling
  • L2CAP channels
  • ISO channels
  • Advertising and scanning
  • Connection management
  • Direction finding and channel sounding helpers
  • Common data and utility helpers

These pieces provide both the internal host stack logic and the public APIs
needed by applications, services, profiles, and shell commands.

Classic BR/EDR Support

The PR adds Classic Bluetooth support, including:

  • Inquiry and BR/EDR connection management
  • BR/EDR L2CAP
  • RFCOMM
  • SDP
  • SCO plumbing
  • Secure Simple Pairing
  • A2DP
  • AVRCP and AVRCP Cover Art
  • GOEP and OBEX
  • BIP
  • PBAP
  • MAP
  • HFP Audio Gateway
  • HFP Hands-Free
  • HID Device
  • HID Host
  • SPP shell support

Classic shell commands expose profile-level test and operation flows so these
features can be compiled and exercised from the NuttX shell environment.

Bluetooth Mesh Support

This PR adds Bluetooth Mesh host support, including:

  • Provisioning and bearer handling
  • Network, transport, and access layers
  • Subnet and key management
  • Replay protection
  • Beacons
  • Friend and Low Power Node behavior
  • GATT Proxy and Proxy Client/Server
  • Heartbeat
  • Configuration Client/Server
  • Health Client/Server
  • Model message helpers
  • Settings persistence
  • Mesh shell utilities
  • BLOB Transfer
  • Firmware Update and Firmware Distribution
  • Remote Provisioning
  • Large Composition Data
  • Directed Forwarding
  • Bridge Configuration
  • On-Demand Private Proxy
  • Opcode Aggregation
  • Private Beacon
  • SAR Configuration
  • Solicitation PDU RPL
  • Mesh statistics
  • Related client and server models

LE Audio Support

The PR adds LE Audio infrastructure and profiles, including:

  • BAP Unicast Client/Server
  • BAP Broadcast Source/Sink
  • Scan Delegator
  • Broadcast Assistant
  • PACS and ASCS
  • CAP Acceptor, Initiator, and Commander
  • AICS
  • VCP and VOCS
  • MICP
  • CSIP
  • TBS
  • MCS and MCC
  • Media Proxy
  • HAS
  • TMAS and TMAP
  • GMAP
  • PBP
  • CCID and CCP
  • Codec helpers
  • LC3 preset definitions
  • Endpoint and stream management
  • LE Audio shell coverage

These components provide the public headers and implementation structure needed
for both unicast and broadcast audio roles, as well as coordinated and
content-control audio use cases.

GATT Services

This PR adds GATT service support and service implementations, including:

  • GAP
  • BAS
  • DIS
  • TPS
  • HRS
  • CTS
  • ETS
  • IAS
  • ANS
  • NUS
  • OTS
  • Service configuration and callbacks
  • Object Transfer support
  • Nordic UART Service instances
  • Immediate Alert Client/Server helpers
  • Battery Service variants
  • Shell integration where applicable

The sim:bt configuration enables common services such as BAS, DIS, TPS, and
NUS so that GATT server behavior can be exercised from the simulator build.

Common Support and Compatibility Layer

This PR adds the compatibility and support infrastructure required by the host
stack, including:

  • NuttX-backed kernel object wrappers
  • Work queues and timeout helpers
  • Atomics
  • Static iterable section compatibility
  • Logging compatibility
  • Settings compatibility
  • Device stubs
  • Crypto helpers
  • EAD support
  • SBC codec support
  • Host utility code
  • net_buf and net_buf_simple memory support
  • Path-derived public header guards

The compatibility surface is kept local to the Bluetooth subsystem, while public
Bluetooth APIs are exposed through the NuttX include namespace.

Build and Configuration

This PR adds build-system integration for the Bluetooth stack:

  • Make build integration
  • CMake build integration
  • Kconfig coverage for the core host
  • Kconfig coverage for Classic
  • Kconfig coverage for Mesh
  • Kconfig coverage for services
  • Kconfig coverage for LE Audio
  • Kconfig coverage for crypto, common library, and net_buf support
  • sim:bt defconfig for broad compile coverage
  • Private include paths for internal compatibility headers

The build integration keeps Bluetooth implementation details contained within
the Bluetooth subsystem and avoids leaking internal compatibility headers into
unrelated NuttX targets.

Runtime/demo coverage

The sim:bt configuration includes demo-oriented behavior for exercising the
stack in the simulator, including:

  • Automatic Bluetooth enable during system initialization
  • Automatic LE advertising startup
  • LE advertising restart after LE disconnect and connection object recycling
  • Runtime logging from the NUS demo application layer
  • Demo GATT services for simple read/write and notification testing
  • Standard BAS, DIS, and TPS service enablement
  • A2DP sink registration for SBC/AAC endpoints
  • AVRCP CT/TG callback logging
  • A2DP media receive callback logging with payload dump support

The runtime logs are intentionally kept in the NUS demo application layer rather
than being added to the protocol stack internals.

Current limitation

The current Bluetooth host stack supports only flat builds and therefore
CONFIG_BT depends on BUILD_FLAT.

Protected builds and kernel builds are not supported in this initial version.
Support for protected and kernel build modes is planned for 27Q2. As part of
that work, the related Bluetooth profiles will be added to the libc build where
needed so they can work correctly across NuttX protected/kernel build
boundaries.

Impact

N/A

Testing

The current test and validation coverage is limited to the simulator platform.

A simulator-based Bluetooth test framework has been completed and is used to
exercise both Classic Bluetooth and BLE paths. The sim:bt configuration
provides broad build coverage for the host stack, services, profiles, and demo
integration.

Validated coverage includes:

  • Simulator build coverage for the Bluetooth host stack
  • Classic Bluetooth test coverage through the simulator framework
  • BLE test coverage through the simulator framework
  • BR/EDR profile registration and callback-path validation
  • LE advertising startup and restart behavior
  • LE connection and disconnection callback-path validation
  • GATT database discovery path validation
  • Standard GATT service enablement, including BAS, DIS, and TPS
  • NUS demo service registration and runtime callback-path validation
  • A2DP sink endpoint registration for SBC/AAC
  • A2DP media receive callback logging and payload dump path
  • AVRCP CT/TG callback registration and callback logging paths

Build validation was performed with the simulator Bluetooth configuration:

Makefile:

./tools/configure.sh  sim/bt
make -j

CMake:

cmake -B build -DBOARD_CONFIG=sim:bt -GNinja
cmake --build build 

A2DP connection:

archer@archer:~/code/nuttx/n8/nuttx$ sudo ./nuttx 
[sudo] password for archer: 
[    0.360] [ 5] <inf> bt_dev_show_info: HCI transport: nuttx_bt_hci
[    0.360] [ 5] <inf> bt_dev_show_info: Identity: P:00:1A:7D:8D:C8:4B
[    0.360] [ 5] <inf> bt_dev_show_info: HCI: version 4.0 (0x06) revision 0x22bb, manufacturer 0x000a
[    0.360] [ 5] <inf> bt_dev_show_info: LMP: version 4.0 (0x06) subver 0x22bb
[    0.370] [ 5] <inf> bt_nus_update_device_name: Bluetooth device name: NuttX-BT-C84B
[    0.370] [ 5] <inf> bt_nus_auth_register: Bluetooth auth callbacks registered
[    0.410] [ 5] <inf> bt_nus_start_le_adv: LE advertising active after Bluetooth enable
[    0.410] [ 5] <inf> bt_nus_a2dp_sink_register: A2DP SBC sink endpoint registered
[    0.410] [ 5] <inf> bt_nus_a2dp_sink_register: A2DP AAC sink endpoint registered
[    0.410] [ 5] <inf> bt_nus_avrcp_ct_register: AVRCP CT callbacks registered
[    0.410] [ 5] <wrn> bt_avctp_server_register: L2CAP server has been registered
[    0.410] [ 5] <wrn> bt_avctp_server_register: L2CAP server has been registered
[    0.410] [ 5] <inf> bt_nus_avrcp_tg_register: AVRCP TG callbacks registered

NuttShell (NSH) NuttX-10.4.0
nsh> [   22.310] [ 8] <inf> bt_nus_br_conn_req: BR/EDR conn req: addr 98:0D:AF:0E:77:65 cod 0x7a020c
[   22.330] [ 8] <inf> bt_nus_connected: BR/EDR connected: 98:0D:AF:0E:77:65
[   22.470] [ 8] <wrn> l2cap_br_conf_rsp_opt_mtu: Proposed MTU is the same as given value (205 == 205)
[   24.170] [ 8] <inf> bt_nus_disconnected: BR/EDR disconnected: 98:0D:AF:0E:77:65 reason 0x13
[   24.170] [ 2] <inf> bt_nus_le_recycled: LE connection object recycled
[   24.170] [ 2] <inf> bt_nus_start_le_adv: LE advertising active after connection recycled
[   27.410] [ 8] <inf> bt_nus_br_conn_req: BR/EDR conn req: addr 98:0D:AF:0E:77:65 cod 0x7a020c
[   27.430] [ 8] <inf> bt_nus_connected: BR/EDR connected: 98:0D:AF:0E:77:65
[   27.620] [ 8] <wrn> l2cap_br_conf_rsp_opt_mtu: Proposed MTU is the same as given value (205 == 205)
[   28.570] [ 8] <inf> bt_nus_pairing_confirm: Pairing confirmed: 98:0D:AF:0E:77:65
[   29.190] [ 8] <wrn> l2cap_br_conf_rsp_opt_mtu: Proposed MTU is the same as given value (1020 == 1020)
[   29.220] [ 2] <inf> bt_nus_a2dp_connected: A2DP sink connected callback: a2dp 0x401341e8 err 0
[   29.220] [ 2] <inf> bt_nus_a2dp_connected: A2DP sink connected
[   29.230] [ 8] <wrn> l2cap_br_conf_rsp_opt_mtu: Proposed MTU is the same as given value (1020 == 1020)
[   29.260] [ 2] <inf> bt_nus_avrcp_ct_connected: AVRCP CT connected callback: conn 98:0D:AF:0E:77:65 ct 0x40122970
[   29.260] [ 2] <inf> bt_nus_avrcp_tg_connected: AVRCP TG connected callback: conn 98:0D:AF:0E:77:65 tg 0x40122eb8
[   29.270] [ 8] <wrn> l2cap_br_check_chan_config: Unsupported extended window size
[   29.270] [ 8] <wrn> l2cap_br_check_chan_config: Unsupported FCS option, force to enable FCS
[   29.270] [ 8] <inf> bt_nus_avrcp_tg_get_caps: AVRCP TG get_caps callback: tg 0x40122eb8 tid 2 cap_id 0x03
[   29.400] [ 8] <wrn> l2cap_br_conf_rsp_opt_mtu: Proposed MTU is the same as given value (339 == 339)
[   29.460] [ 2] <inf> bt_nus_avrcp_ct_browsing_connected: AVRCP CT browsing_connected callback: conn 98:0D:AF:0E:77:65 ct 0x40122970
[   29.460] [ 2] <inf> bt_nus_avrcp_tg_browsing_connected: AVRCP TG browsing_connected callback: conn 98:0D:AF:0E:77:65 tg 0x40122eb8
[   29.590] [ 8] <inf> bt_nus_a2dp_config_req: A2DP sink config_req callback: a2dp 0x401341e8 ep 0x40105be0 stream 0x40125d40
[   29.590] [ 8] <inf> bt_nus_a2dp_log_codec_cfg: A2DP config_req codec: delay_report 1 codec_ie 0x767cbfe87c2f
[   29.590] [ 8] <inf> bt_nus_dump_buf: A2DP config_req codec: len 6 dump 6
[   29.590] [ 8] <inf> bt_nus_dump_buf: A2DP config_req codec[0]: 80 01 04 83 e8 00 00 00 00 00 00 00 00 00 00 00
[   29.590] [ 8] <inf> bt_nus_a2dp_stream_configured: A2DP sink stream configured callback: stream 0x40125d40
[   29.590] [ 8] <inf> bt_nus_dump_buf: A2DP stream codec config: len 6 dump 6
[   29.590] [ 8] <inf> bt_nus_dump_buf: A2DP stream codec config[0]: 80 01 04 83 e8 00 00 00 00 00 00 00 00 00 00 00
[   29.690] [ 8] <inf> bt_nus_a2dp_accept_req: A2DP sink establish_req callback: stream 0x40125d40
[   29.960] [ 8] <wrn> l2cap_br_conf_rsp_opt_mtu: Proposed MTU is the same as given value (1020 == 1020)
[   30.000] [ 2] <inf> bt_nus_a2dp_stream_established: A2DP sink stream established callback: stream 0x40125d40


@xiaoxiang781216

xiaoxiang781216 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

But this portging should belong userspace, like nimble:
https://github.com/apache/nuttx-apps/tree/master/wireless/bluetooth/nimble
since it doesn't follow other network stack design which exposes the network functionality through socket interface.
BTW, since Zephyr is under the active development, it's better to integrate it through download.

* pass through kernel objects such as FIFOs.
*/

struct net_buf_simple

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use iob?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

netbuf provides interfaces for network byte order operations and bit-level read/write access; furthermore, when used in conjunction with TCP/IP, it ensures that there is no contention for iob resources.

Comment thread boards/sim/sim/sim/configs/bt/defconfig Outdated
############################################################################
# boards/sim/sim/sim/configs/bt/defconfig
#
# Copyright (c) ByteDance Ltd. and/or its affiliates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove ALL company copyright

@jerpelea jerpelea Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it a rewrite or a copy ? We can not remove company information without authors consent!

@xiaoxiang781216 xiaoxiang781216 Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the code is copied from Zephyr and adjusted by @anchao , so should drop Bytedance copyright and keep Zephyr.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, The initial version was ported from Zephyr, but all files have been adapted to support the native NuttX; the entire protocol stack utilizes NuttX kernel APIs and adheres to NuttX coding standards.

@jerpelea jerpelea Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since you are a bytedance contributor is it possible to update the license to match the rest if NuttX under ICLA or SGA for the new implemnetation

is it possible to move it to nuttx-apps

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As Xiaomi's representative, you seem perfectly comfortable with the incremental contribution model that Xiaomi benefits from in the Zephyr community. Yet when it comes to NuttX, you keep raising the bar and imposing additional barriers. Why the double standard?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current Nimble port in nuttx-apps calls a significant number of NuttX kernel APIs directly — APIs like k_thread_create, k_sem_, k_fifo_, various work_queue functions, and other internal kernel primitives.

This is complete nonsense. AI hallucinations, or what? Did you even verify this?

If your AI makes mistakes like these, it’s hard to have confidence in the quality of the code or any claims made about it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k_sem_, k_fifo_ and k_work_* are Zephyr names kept by NimBLE's mesh code, which was ported from Zephyr. It has nothing to do with nuttx porting layer.

@raiden00pl raiden00pl Oct 16, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new stack being proposed takes the opposite approach: it starts in the kernel where it belongs architecturally (just like TCP/IP, CAN, and other in-kernel network stacks), and then we add proper userspace access through the socket layer — the same pattern every other NuttX network subsystem follows. That's not treating Bluetooth "specially" — it's treating it consistently with the rest of the OS.

No it's not. TCP/IP, CAN and other in-kernel networks stacks occupy different OSI layers. This PR puts all OSI layers to kernel which is obviously wrong. Everything above L4-L5 that resides in the kernel is controversial. What you are proposing is equivalent to embedding HTTP, REST or CANopen into the kernel.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me restate my proposal more clearly: the intention is not to keep all Bluetooth profiles in kernel space. The plan is to keep only the lower Bluetooth transport/protocol layers that need to interact closely with the network/device side in the kernel, especially L2CAP. Higher-level profiles and application-facing logic should be moved out of the kernel and maintained in libs/libbt.

So the long-term layering would be:

  • kernel: controller/HCI integration, core host transport, L2CAP, and other lower-layer pieces that need kernel-side integration;
  • libs/libbt: higher-level Bluetooth profiles and reusable host-stack logic;
  • apps: shell commands, tools, demos, and other user-facing code.

This still follows the OSI layering principle. I am not proposing that profiles such as audio, GATT services, mesh models, or other application-level logic should permanently live in the kernel.

For the current first-stage PR, the main goal is to make the stack build and run in FLAT mode first. In FLAT mode the separation is naturally less strict, and keeping the profile code close to the stack can provide better performance and lower overhead. This is also important if we want NuttX Bluetooth to be competitive with mainstream embedded OS implementations such as Zephyr.

However, I agree that this should not become the final layout for Protected and Kernel builds. For the next stage, I plan to move the higher-level profiles into libs/libbt and keep only the necessary lower-layer kernel components in net/bt. The shell code has already been removed from this PR and will be moved to apps, so the current stack no longer contains userspace shell code.

In short, I agree with the concern about not putting all OSI layers into the kernel. My proposal is to keep L2CAP and the required lower layers in the kernel, while moving higher-level profiles to libs/libbt as part of the next-stage Protected/Kernel mode support.

Comment thread net/Kconfig Outdated
@@ -438,6 +390,7 @@ source "net/netlink/Kconfig"
source "net/tcp/Kconfig"
source "net/udp/Kconfig"
source "net/bluetooth/Kconfig"
source "net/bt/Kconfig"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but what's relationship with the original bluetooth stack? it isn't good to contain two Bluetooth stacks with the incompatible public API in the kernel space.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original protocol stack will be removed once we have implemented support in both the kernel and user space.

@xiaoxiang781216 xiaoxiang781216 Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so please finish your work in your internal git and do test before submitting the partial code to community.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't conflict with the existing Bluetooth subsystem at all — the new stack lives under net/bt/ and is guarded by its own CONFIG_BT Kconfig option, completely independent from the legacy stack. The two can coexist and be developed in parallel.

Submitting to the community early has several benefits:

  1. Parallel development: The community can start testing, reviewing, and contributing fixes while we continue working on phase 2 (userspace/kernel space split). There's no need to block the initial framework on downstream work.
  2. Earlier feedback: The Bluetooth stack is a large piece of work — 600+ files. Getting it into the tree sooner means more eyes on the code, earlier bug discovery, and broader testing across different hardware platforms.
  3. Lower upstream maintenance burden: Keeping a large patch set in an internal fork and rebasing against master is painful and error-prone. Every day it stays out of tree, the merge conflict surface grows.

Asking us to fully finish phase 2 and 3 in isolation before submitting phase 1 would actually slow down the overall effort and delay the community from benefiting from a working Bluetooth stack. This is a baseline submission that gives everyone a foundation to build on — not the final product.

@anchao

anchao commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

But this portging should belong userspace, like nimble: https://github.com/apache/nuttx-apps/tree/master/wireless/bluetooth/nimble since it doesn't follow other network stack design which exposes the network functionality through socket interface. BTW, since Zephyr is under the active development, it's better to integrate it through download.

At this stage, the entire Bluetooth stack currently only supports flat build. Protected build and kernel build support are planned for Phase 2.

Our thinking for Phase 1 is to get the full stack running with complete feature support first. I've also added flat build as a dependency under the CONFIG_BT configuration option. Once this is in place, we'll move the upper-layer profile code entirely
into the libc implementation.

Why flat build first?

There are several benefits to this approach:

  1. Performance: The current stack can directly call kernel APIs. Compared to userspace APIs, this yields significantly better performance.
  2. Bypassing VFS overhead: Under flat build, the HOST side of the stack can bypass the VFS layer entirely. Currently, the VFS layer requires two memory copies during data transfer between the controller and the HOST. For IoT devices — especially those
    with CPU frequencies below 100 MHz — this copying becomes very costly. For example, with SPP bandwidth at 200 MB/s, this alone can consume more than 15% CPU load.
  3. Direct callback path: Ideally, Bluetooth callbacks should fire directly from interrupt context or workqueue callbacks (similar to Zephyr's design), without going through unnecessary abstraction layers.

Migration Plan

The overall migration is broken down into several phases:

Phase 1 (current)

Submit the full-featured Bluetooth stack to the mainline so everyone can collaborate on stabilizing it together.

Phase 2

Provide both userspace and kernel space support:

• Bluetooth profile code will move to libc.
• Interaction with the kernel will go through the socket/VFS layer.
• This will only take effect under protected build and kernel build modes.
• Under flat build, we'll directly map the transport layer (the VFS layer) into direct function calls for maximum performance.

Phase 3

Once the new stack fully supports NuttX's Bluetooth capabilities:

  1. Remove compatibility with the old Bluetooth stack.
  2. Make this the standard Bluetooth implementation for NuttX.

Why not do everything in one commit?

A Bluetooth protocol stack is an extremely complex piece of work. It involves different profiles, different L2CAP data link layers (e.g., LE Audio and SCO), each of which may require different implementation approaches within the kernel. Supporting
both kernel space and userspace in a single commit is, frankly, not realistic. We need to proceed step by step and gradually refine the architecture into what we envision.

My initial implementation is focused on getting the full-featured stack running on NuttX with minimal resource consumption. We'll continue to invest in stabilizing and improving the framework and architecture over subsequent iterations.

@github-actions github-actions Bot added Area: Bluetooth Arch: simulator Issues related to the SIMulator Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. Board: simulator labels Oct 15, 2026
@xiaoxiang781216

xiaoxiang781216 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

As AI’s code generation capability improves, ensuring code quality becomes ever more important. Before the code finish:

  1. keep only the transport/driver layer in kernel space
  2. change to the socket model
  3. replace the current bluetooth stack without losing function

I reject to merge this pr. Anyway, you can send email to dev@ and ask other people opinion.

@jerpelea

Copy link
Copy Markdown
Contributor

As AI’s code generation capability improves, ensuring code quality becomes ever more important. Before the code finish:

1. keep only the transport/driver layer in kernel space

2. change to the socket model

3. replace the current bluetooth stack without losing function

I reject to merge this pr. Anyway, you can send email to dev@ and ask other people opinion.

+1

@jerpelea

jerpelea commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

I have concerns on the code quality and compliance

Please split the contribution to small chunks which can be reviewed and discussed

@anchao

anchao commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

As AI’s code generation capability improves, ensuring code quality becomes ever more important. Before the code finish:

  1. keep only the transport/driver layer in kernel space
  2. change to the socket model
  3. replace the current bluetooth stack without losing function

I reject to merge this pr. Anyway, you can send email to dev@ and ask other people opinion.

My recommendation is to keep the protocol stack implementation in the kernel, and use libc to provide the userspace isolation layer for protected/kernel build modes. This way:

  1. Flat build: The stack runs directly in kernel space with zero overhead — performance comparable to Zephyr.
  2. Protected/kernel build: The profile/application layer sits in userspace (libc), communicating with the kernel-side transport/driver layer through the socket/VFS interface.

This approach gives us the best of both worlds — performance when we need it (flat build), and isolation when we need it (protected/kernel build) — without the drastic rewrite of moving everything to userspace.

I'd suggest everyone take another look at NuttX's current Bluetooth capabilities. The reality is that many companies are choosing not to adopt NuttX precisely because of the lack of a mature Bluetooth stack. A fully functional Bluetooth host stack is no longer optional — it's a baseline requirement for most IoT products today (BLE, LE Audio, mesh, etc.).

Adding a proper Bluetooth stack to the kernel is a positive step for promoting NuttX adoption. It unlocks a whole category of use cases that are currently simply not possible, and makes NuttX a viable option for a much broader range of devices. This is good for the entire ecosystem. @jerpelea @acassis @xiaoxiang781216

@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch from ef6e918 to c0d36c3 Compare October 15, 2026 15:59
@acassis

acassis commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

As AI’s code generation capability improves, ensuring code quality becomes ever more important. Before the code finish:

  1. keep only the transport/driver layer in kernel space
  2. change to the socket model
  3. replace the current bluetooth stack without losing function

I reject to merge this pr. Anyway, you can send email to dev@ and ask other people opinion.

My recommendation is to keep the protocol stack implementation in the kernel, and use libc to provide the userspace isolation layer for protected/kernel build modes. This way:

1. Flat build: The stack runs directly in kernel space with zero overhead — performance comparable to Zephyr.

2. Protected/kernel build: The profile/application layer sits in userspace (libc), communicating with the kernel-side transport/driver layer through the socket/VFS interface.

This approach gives us the best of both worlds — performance when we need it (flat build), and isolation when we need it (protected/kernel build) — without the drastic rewrite of moving everything to userspace.

I'd suggest everyone take another look at NuttX's current Bluetooth capabilities. The reality is that many companies are choosing not to adopt NuttX precisely because of the lack of a mature Bluetooth stack. A fully functional Bluetooth host stack is no longer optional — it's a baseline requirement for most IoT products today (BLE, LE Audio, mesh, etc.).

Adding a proper Bluetooth stack to the kernel is a positive step for promoting NuttX adoption. It unlocks a whole category of use cases that are currently simply not possible, and makes NuttX a viable option for a much broader range of devices. This is good for the entire ecosystem. @jerpelea @acassis @xiaoxiang781216

Hi @anchao I think we need to evolve the NuttX BLE and although the initial BLE stack used on NuttX is the same used on Zephyr that came from Intel, I don't know if we should use the code from Zephyr. Or is it a rewrite from scratch?

I think for the size of this PR and the importance of this subject, I suggest it should be better if you send first an email to the mailing list explaining your proposal/approach.

I think if we use code from Zephyr, the same CVEs which affect them will affect us. And it will prevent the diversity protection (when a company uses multiple RTOSs to avoid an single hacking put down all theirs devices).

@anchao

anchao commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Hi @anchao I think we need to evolve the NuttX BLE and although the initial BLE stack used on NuttX is the same used on Zephyr that came from Intel, I don't know if we should use the code from Zephyr. Or is it a rewrite from scratch?

I think for the size of this PR and the importance of this subject, I suggest it should be better if you send first an email to the mailing list explaining your proposal/approach.

I think if we use code from Zephyr, the same CVEs which affect them will affect us. And it will prevent the diversity protection (when a company uses multiple RTOSs to avoid an single hacking put down all theirs devices).

@acassis

I agree that this is an important topic and probably deserves broader discussion on the mailing list before we decide the long-term direction. I can prepare a proposal email to explain the motivation, scope, current limitation, and the
maintenance plan.

To clarify the approach: this is not a rewrite from scratch. The current PR is a port/adaptation of the Zephyr Bluetooth host stack into NuttX, with a NuttX compatibility layer for kernel primitives, work queues, timeout handling, logging, settings, net_buf, iterable sections, and build integration.

The reason I took this approach is that the Bluetooth stack has evolved far beyond a basic BLE host. Today, a practical Bluetooth host needs to cover much more than GAP/GATT/ATT/SMP:

  • BLE peripheral/central roles
  • GATT services and clients
  • BR/EDR Classic
  • SDP/RFCOMM
  • A2DP
  • AVRCP
  • HID/HFP/PBAP/MAP/BIP/OBEX/GOEP
  • Bluetooth Mesh
  • LE Audio
  • BAP/CAP/PACS/ASCS
  • VCP/MICP/CSIP/TBS/MCS/HAS/TMAP/GMAP/PBP and related profiles

Rebuilding all of this on top of the original NuttX BLE implementation would be a very large multi-year effort. Even if we start from the existing NuttX BLE code, we would still need to implement and maintain a large amount of profile
and protocol code that already exists and is actively used in Zephyr. My concern is that evolving the original BLE-only implementation into a full modern Bluetooth host stack may not be realistic with the current maintenance capacity.

About the CVE concern: I think this is a valid point. If we import or derive code from Zephyr, some vulnerabilities may also apply to the NuttX port. But I think there are also trade-offs:

  1. Reusing a mature and widely tested stack gives us a much broader feature set and a better-tested protocol base than writing everything from scratch.

  2. Known Zephyr Bluetooth CVEs become easier to track, because we can monitor upstream fixes and apply the relevant ones to the NuttX port.

  3. A from-scratch implementation would avoid sharing the exact same code, but it would also introduce new implementation risks and would require significant security review across a very large protocol surface.

  4. The NuttX port is not intended to blindly expose Zephyr internals. The compatibility layer is kept local to net/bt, and the public API is exposed through the NuttX namespace. This gives us room to adapt, harden, and maintain the integration in a NuttX-specific way.

So I think the main question is the trade-off between:

  • keeping diversity by evolving an independent NuttX BLE stack, but with a much smaller feature set and much higher implementation cost; or
  • adopting a mature Bluetooth host stack as the base, accepting the need to track upstream security fixes, but gaining Classic Bluetooth, Mesh, LE Audio, and many profiles much earlier.

For the current PR, I also want to make the limitation explicit:

  • Current support is limited to flat builds only.
  • Protected/kernel builds are not supported yet.
  • The current validation target is the simulator platform.
  • The simulator test framework covers Classic Bluetooth and BLE paths.
  • Support for protected/kernel builds is planned for 27Q2~4, and the related profiles will be added to the libc build where needed.

@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch from c0d36c3 to 6d6ddbb Compare October 16, 2026 03:50
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report · Explore what changed →

No memory changes detected for:


Catch memory regressions in CI with MemBrowse. Free for open source.

@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch from 6d6ddbb to b519d24 Compare October 19, 2026 03:22
@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch 3 times, most recently from f5e37bd to e8ede6c Compare October 19, 2026 03:52
@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch from aa6012c to 38d14a0 Compare October 23, 2026 08:38
@acassis

acassis commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

@acassis

Thanks for the clarification and suggestion.

I have updated the license handling accordingly:

* For the Zephyr-derived Bluetooth host stack files, I removed the added NuttX/ASF boilerplate headers and kept the original upstream copyright and SPDX notices.

* I added the Zephyr Bluetooth host stack origin information to the top-level LICENSE file.

* For the NuttX integration/glue files that were newly created from scratch, I kept the normal NuttX ASF license headers.

* I also kept a short porting note in the derived files to identify the Apache NuttX adaptation work.

Regarding the Kconfig naming, I would prefer to keep CONFIG_BT as the main Bluetooth entry. This matches the naming convention used by both Linux and Zephyr, and should make it easier for Bluetooth developers to understand and use the configuration. If we need to support multiple Bluetooth stacks in the future, I think we can add a choice under CONFIG_BT at that point instead of renaming the main option now.

Thank you @anchao

But using CONFIG_BT will make it impossible to change the current NuttX BLE stack name in the future. Also associating CONFIG_BT to only ZBLUE will pass an impression we don't have option to use other BT stack. Unless you find a way to dissociate CONFIG_BT from this ZBLUE implementation and make CONFIG_BT generic as a requirement for CONFIG_WIRELESS_BLUETOOTH and CONFIG_NIMBLE

@anchao

anchao commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

@acassis

Regarding CONFIG_BT, let me explain the rationale:

  1. Naming consistency zblue is a full port of the Zephyr RTOS Bluetooth host stack. Its public API follows Zephyr's bt_ naming conventions exactly (e.g. bt_enable(), bt_le_adv_start(), bt_gatt_service_register()), and the Kconfig symbols correspondingly use the Zephyr-style CONFIG_BT_* scheme. If we introduce an intermediate abstraction layer like CONFIG_WIRELESS_BLUETOOTH in Kconfig but leave the API layer unchanged, it creates an inconsistency — users would see one naming convention in Kconfig and a completely different one when writing code. Since the API is already locked to Zephyr compatibility, keeping Kconfig consistent with it is the right design choice.
  2. Current NuttX Bluetooth Kconfig landscape NuttX currently has the following Bluetooth-related configuration subsystems:
Subsystem Top-level Kconfig Location
Legacy BLE stack (Intel/Zephyr arduino101 port) WIRELESS_BLUETOOTH / WIRELESS_BLUETOOTH_HOST wireless/bluetooth/Kconfig
NimBLE (Apache Mynewt port) NIMBLE nuttx-apps wireless/bluetooth/nimble/Kconfig
HCI driver layer DRIVERS_BLUETOOTH drivers/wireless/bluetooth/Kconfig
Bluetooth socket (based on legacy stack) NET_BLUETOOTH net/bluetooth/Kconfig
New Zephyr Bluetooth host stack (zblue) BT libs/zblue/Kconfig

Note that WIRELESS_BLUETOOTH_HOST and NIMBLE are already mutually exclusive (NimBLE has depends on !WIRELESS_BLUETOOTH_HOST), so the top level has always been a two-way choice.

  1. No additional protocol stacks on the horizon The end goal of introducing zblue is to replace the legacy WIRELESS_BLUETOOTH implementation with CONFIG_BT. zblue is far more feature-complete than the legacy stack (LE Audio, Mesh, BR/EDR Classic, etc.). So there won't be a scenario where a generic CONFIG_BT needs to dispatch across "multiple Bluetooth stacks" — zblue will be the single in-kernel Bluetooth host implementation going forward.
  2. Userspace compatibility I'll make sure that as CONFIG_BT replaces the legacy stack, existing userspace tools (such as btsak, btsnoop-related IOCTLs, etc.) remain compatible, avoiding breaking changes for upper-layer applications.

@acassis

acassis commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

@acassis

Regarding CONFIG_BT, let me explain the rationale:

1. **Naming consistency**
   zblue is a full port of the Zephyr RTOS Bluetooth host stack. Its public API follows Zephyr's `bt_` naming conventions exactly (e.g. `bt_enable()`, `bt_le_adv_start()`, `bt_gatt_service_register()`), and the Kconfig symbols correspondingly use the Zephyr-style `CONFIG_BT_*` scheme. If we introduce an intermediate abstraction layer like `CONFIG_WIRELESS_BLUETOOTH` in Kconfig but leave the API layer unchanged, it creates an inconsistency — users would see one naming convention in Kconfig and a completely different one when writing code. Since the API is already locked to Zephyr compatibility, keeping Kconfig consistent with it is the right design choice.

2. **Current NuttX Bluetooth Kconfig landscape**
   NuttX currently has the following Bluetooth-related configuration subsystems:

Subsystem Top-level Kconfig Location
Legacy BLE stack (Intel/Zephyr arduino101 port) WIRELESS_BLUETOOTH / WIRELESS_BLUETOOTH_HOST wireless/bluetooth/Kconfig
NimBLE (Apache Mynewt port) NIMBLE nuttx-apps wireless/bluetooth/nimble/Kconfig
HCI driver layer DRIVERS_BLUETOOTH drivers/wireless/bluetooth/Kconfig
Bluetooth socket (based on legacy stack) NET_BLUETOOTH net/bluetooth/Kconfig
New Zephyr Bluetooth host stack (zblue) BT libs/zblue/Kconfig

Note that WIRELESS_BLUETOOTH_HOST and NIMBLE are already mutually exclusive (NimBLE has depends on !WIRELESS_BLUETOOTH_HOST), so the top level has always been a two-way choice.

3. **No additional protocol stacks on the horizon**
   The end goal of introducing zblue is to replace the legacy `WIRELESS_BLUETOOTH` implementation with `CONFIG_BT`. zblue is far more feature-complete than the legacy stack (LE Audio, Mesh, BR/EDR Classic, etc.). So there won't be a scenario where a generic `CONFIG_BT` needs to dispatch across "multiple Bluetooth stacks" — zblue will be the single in-kernel Bluetooth host implementation going forward.

4. **Userspace compatibility**
   I'll make sure that as `CONFIG_BT` replaces the legacy stack, existing userspace tools (such as `btsak`, `btsnoop`-related IOCTLs, etc.) remain compatible, avoiding breaking changes for upper-layer applications.

@anchao as I said before the zblue should be an option not the default. Using the fact that nobody worked on BLE on NuttX until now doesn't mean item 3 is true, as I said I started working on it.

I think it is fine to keep the convection/API used on Zephyr (bt_*), but CONFIG_BT should be like a CONFIG_NET. And CONFIG_NIBLE, CONFIG_ZBLUE or CONFIG_WIRELESS_BLUETOOTH (or CONFIG_NXBLE/NXBT/BTBLUE whatever we rename it) should be selected as the stack.

Please use this opportunity to make the BLUETOOTH selection on NuttX more simple and intuitive. Assuming ZBLUE as the default and main option is not safe, some people will prefer other option (as @raiden00pl commented)

@anchao

anchao commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

@acassis

I appreciate the detailed feedback, and I understand the concern about not assuming zblue as the sole option. Let me share my perspective on why I think keeping CONFIG_BT as-is is actually the simpler and more intuitive path here.

  1. zblue is not BLE-only — it's a full Bluetooth stack This isn't just another BLE host. zblue covers Classic Bluetooth (BR/EDR with A2DP, AVRCP, HFP, HID, etc.), Bluetooth Mesh, and LE Audio (BAP, CAP, TMAP, PBP, and a dozen more profiles). The legacy WIRELESS_BLUETOOTH stack and NimBLE are both BLE-only by comparison. From a functionality standpoint, zblue is the most comprehensive Bluetooth implementation in NuttX, and it makes sense for its Kconfig to reflect that scope rather than being pigeonholed as "one of several BLE options."
  2. No naming conflict exists todayCONFIG_BT doesn't collide with any existing NuttX Kconfig symbol. The current stacks already have their own distinct top-level names:
Stack Top-level config Scope
Legacy NuttX BLE WIRELESS_BLUETOOTH BLE only
NimBLE NIMBLE BLE only
zblue BT LE + Classic + Mesh + LE Audio

There's no ambiguity for users — each stack has a clearly identifiable entry point. Adding a CONFIG_BT umbrella on top would actually increase complexity by introducing an extra level of indirection for a problem that doesn't exist yet.

  1. Familiarity for developers coming from Linux/Zephyr One of the explicit goals of this port is to lower the barrier for developers already familiar with the Zephyr Bluetooth ecosystem. A developer who has written prj.conf with CONFIG_BT=y / CONFIG_BT_PERIPHERAL=y in Zephyr will immediately recognize the same configuration scheme in NuttX. This isn't a theoretical benefit — it means existing Zephyr Bluetooth documentation, knowledge, and patterns transfer directly. Renaming to something NuttX-specific (e.g. CONFIG_ZBLUE) would sacrifice that familiarity for no practical gain.
  2. The CONFIG_NET analogy is worth reconsidering I don't think CONFIG_BT maps cleanly to the CONFIG_NET pattern. CONFIG_NET is a genuine umbrella because multiple networking stacks were never the plan — it's a single subsystem with optional features layered underneath. The Bluetooth situation is actually similar: we have legacy stacks that predate this work, and zblue is designed to eventually supersede them, not coexist indefinitely alongside them. Adding a choice menu now to choose between stacks that have different feature sets, different APIs, and different maturity levels doesn't simplify things for users — it forces them to understand the tradeoffs between three implementations before they can even get started.
  3. Premature abstraction If, at some future point, someone contributes another full-featured Bluetooth host stack that uses the same bt_* API surface and genuinely needs to coexist under a shared Kconfig umbrella, that would be the right time to introduce a choice menu. Doing it now, when there's only one stack using this API namespace, is solving a hypothetical problem. The existing stacks (WIRELESS_BLUETOOTH, NIMBLE) each have their own API surface and their own Kconfig entry — they don't need to live under CONFIG_BT.
  4. Practical counter-proposal How about this: we keep CONFIG_BT as the entry point for the Zephyr-derived host stack for now. If another Bluetooth host stack emerges that shares the same bt_* API conventions and genuinely needs to be selectable under a common Kconfig namespace, I'll be the first to help refactor CONFIG_BT into a choice menu at that point. But I'd rather not add an abstraction layer today that serves no immediate purpose and makes the configuration less recognizable for the developers most likely to use this feature.

@anchao

anchao commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

By the way, there's an interesting comparison worth noting. Not long ago, someone proposed integrating lwIP as an auxiliary TCP/IP stack in NuttX (PR #20159 #20159 / #20160). It was ultimately rejected, and rightfully so — NuttX's native TCP/IP stack is already mature and performant; when tuned properly, it matches or exceeds lwIP. In that case, enhancing the native solution is clearly the right choice over importing a third-party one.

Bluetooth on NuttX is the mirror image of this situation. The native BT capability has been so lacking that the community has repeatedly resorted to third-party imports like NimBLE just to fill the gap. For an RTOS to depend on fragmented third-party solutions for something as fundamental as Bluetooth is, frankly, not a healthy state.

zblue is an attempt to fix exactly this — to provide a single, comprehensive, well-maintained Bluetooth stack that can eventually replace both the legacy WIRELESS_BLUETOOTH and the third-party NIMBLE. It's not "another option" — it's the consolidation path. So I'd argue that giving it a clean, direct CONFIG_BT entry point, rather than tucking it behind an abstraction layer built for a fragmentation problem we're actively trying to solve, is the right call.

@anchao

anchao commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

@acassis on the naming question, I'd like to make one more case. I've been deeply involved in the development of most of NuttX's core kernel, driver subsystems, and network stack over the years, so I believe I have solid technical judgment on this. I've put a lot of thought into the current naming and architecture, and I remain strongly convinced that CONFIG_BT as proposed is the right approach here.

@acassis

acassis commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

@anchao I think enhancing the native stack is always the best option, because we got an implementation that is not the same code from a foreign project and are not affected by the same vulnerabilities.

Just to prove my point, from 2019 until now were 73 vulnerabilities found on ZBlue:
(CVE-2019-9506, CVE-2020-10061, CVE-2020-10065, CVE-2020-10066, CVE-2020-10068, CVE-2020-10069, CVE-2021-3430,
CVE-2021-3431, CVE-2021-3432, CVE-2021-3433, CVE-2021-3434, CVE-2021-3435, CVE-2021-3436, CVE-2021-3454,
CVE-2021-3455, CVE-2021-3581, CVE-2021-3966, CVE-2022-1041, CVE-2022-1042, CVE-2022-2993, CVE-2022-3806,
CVE-2023-0396, CVE-2023-0397, CVE-2023-1901, CVE-2023-1902, CVE-2023-4258, CVE-2023-4264, CVE-2023-4424,
CVE-2023-5055, CVE-2023-5753, CVE-2024-1638, CVE-2024-3077, CVE-2024-3332, CVE-2024-4785, CVE-2024-5754,
CVE-2024-5931, CVE-2024-6135, CVE-2024-6137, CVE-2024-6258, CVE-2024-6259, CVE-2024-6442, CVE-2024-6443,
CVE-2024-6444, CVE-2024-8798, CVE-2025-7403, CVE-2025-9557, CVE-2025-9558, CVE-2025-10456, CVE-2025-10457,
CVE-2025-10458, CVE-2025-12035, CVE-2025-12890, CVE-2026-2411, CVE-2026-5068, CVE-2026-5589, CVE-2026-9263,
CVE-2026-10593, CVE-2026-10641, CVE-2026-10651, CVE-2026-10653, CVE-2026-10654, CVE-2026-10658, CVE-2026-10660
CVE-2026-10675, CVE-2026-10680, CVE-2026-10685, CVE-2026-10774, CVE-2026-11368, CVE-2026-11893, CVE-2026-11894
CVE-2026-12236, CVE-2026-13213, CVE-2026-15460, and counting)

21 only this year! You can think: good these are vulnerabilities that were fixed and we will not be affected. The problem is the year didn't finish, they will discover a lot more before the end of the year, and many more in the coming years.

And since Zephyr is becoming used in more products from different vendors (like Windows) it mean any product with NuttX will be affected as well.

Perhaps ZBlue could be a great stack (if you think so), but it still a big surface area from a foreign code injected on NuttX in the most critical part of NuttX (kernel), it means any vulnerability found on that stack will put a NuttX product in risk.

This is why I suggested to add a Kconfig "Bluetooth Support" and inside it add:

[] NuttX Native BLE stack (WIP)
[] ZBlue (Zephyr Bluetooth stack)
[] NimBLE stack

I think we need to hear more from other developers, seems like only you and I are interested on it.
Ping @xiaoxiang781216 @raiden00pl @hartmannathan @jerpelea @cederom @michallenc @casaroli @simbit18

@anchao

anchao commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for sharing your concerns. I understand your point about the security surface and the risk of importing code from another project.

However, I think we also need to look at the current state of the native NuttX Bluetooth stack realistically. Today it is still at a very early stage and does not yet provide a complete BLE host stack. As far as I know, there is currently no real product or project using the native NuttX Bluetooth stack as a complete BLE solution. That makes it very difficult to use it directly for product work today.

For commercial products, rewriting and validating a full Bluetooth host stack from scratch is usually not a realistic option. The protocol surface is large, the qualification and interoperability cost is high, and it takes a long time to reach a production-ready level. In practice, companies usually either buy a commercial stack or base their work on an existing mature open-source stack.

This is also one of the reasons why ZBlue is useful here. Before moving to an open-source solution, some vendors had to rely on expensive commercial Bluetooth stacks. Now that openvela/NuttX needs an open stack that can continue to evolve in the open, starting from ZBlue gives us a practical path forward instead of starting from zero.

I agree that security is a very important concern. But I think the CVE list can also be viewed from another angle: Zephyr Bluetooth is widely used, heavily tested, and actively analyzed by security researchers. Vulnerabilities are found because the stack is used and reviewed in many real products. If we maintain the NuttX port actively and keep tracking upstream fixes, we can benefit from that ecosystem instead of carrying an untested private implementation.

If the concern is that users may misunderstand the maturity or security status, I am fine with making that clearer in the Kconfig/help text and documentation. For example, we can explicitly state that ZBlue is an optional Bluetooth host stack derived from Zephyr, that users should track security updates, and that it is not meant to imply that the native NuttX Bluetooth stack is being removed.

I also agree with your suggestion that the Kconfig structure should make the choice explicit. Having something like this makes sense to me:

Bluetooth Support
  [ ] NuttX native BLE stack (WIP)
  [ ] ZBlue (Zephyr Bluetooth stack)
  [ ] NimBLE stack

My only concern is that we should not block ZBlue just because the native stack is not yet complete. I see these as complementary options:

  • Native NuttX stack: long-term direction, but currently WIP
  • ZBlue: practical full-featured stack that can be maintained and improved now
  • NimBLE: another possible option if someone wants to integrate and maintain it

If this stack can be merged, my team is willing to help maintain it in NuttX. That includes tracking upstream security fixes, fixing integration issues, improving performance/resource usage, and handling compatibility problems. So I do not think this has to become an unmaintained foreign code dump.

I agree that we should hear more opinions from other developers and maintainers. My main point is that adding ZBlue as an explicit optional stack gives NuttX users a practical Bluetooth solution today, while still leaving room for the native stack to continue improving.

@acassis

acassis commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Thanks for sharing your concerns. I understand your point about the security surface and the risk of importing code from another project.

However, I think we also need to look at the current state of the native NuttX Bluetooth stack realistically. Today it is still at a very early stage and does not yet provide a complete BLE host stack. As far as I know, there is currently no real product or project using the native NuttX Bluetooth stack as a complete BLE solution. That makes it very difficult to use it directly for product work today.

For commercial products, rewriting and validating a full Bluetooth host stack from scratch is usually not a realistic option. The protocol surface is large, the qualification and interoperability cost is high, and it takes a long time to reach a production-ready level. In practice, companies usually either buy a commercial stack or base their work on an existing mature open-source stack.

This is also one of the reasons why ZBlue is useful here. Before moving to an open-source solution, some vendors had to rely on expensive commercial Bluetooth stacks. Now that openvela/NuttX needs an open stack that can continue to evolve in the open, starting from ZBlue gives us a practical path forward instead of starting from zero.

I agree that security is a very important concern. But I think the CVE list can also be viewed from another angle: Zephyr Bluetooth is widely used, heavily tested, and actively analyzed by security researchers. Vulnerabilities are found because the stack is used and reviewed in many real products. If we maintain the NuttX port actively and keep tracking upstream fixes, we can benefit from that ecosystem instead of carrying an untested private implementation.

If the concern is that users may misunderstand the maturity or security status, I am fine with making that clearer in the Kconfig/help text and documentation. For example, we can explicitly state that ZBlue is an optional Bluetooth host stack derived from Zephyr, that users should track security updates, and that it is not meant to imply that the native NuttX Bluetooth stack is being removed.

I also agree with your suggestion that the Kconfig structure should make the choice explicit. Having something like this makes sense to me:

Bluetooth Support
  [ ] NuttX native BLE stack (WIP)
  [ ] ZBlue (Zephyr Bluetooth stack)
  [ ] NimBLE stack

My only concern is that we should not block ZBlue just because the native stack is not yet complete. I see these as complementary options:

* Native NuttX stack: long-term direction, but currently WIP

* ZBlue: practical full-featured stack that can be maintained and improved now

* NimBLE: another possible option if someone wants to integrate and maintain it

If this stack can be merged, my team is willing to help maintain it in NuttX. That includes tracking upstream security fixes, fixing integration issues, improving performance/resource usage, and handling compatibility problems. So I do not think this has to become an unmaintained foreign code dump.

I agree that we should hear more opinions from other developers and maintainers. My main point is that adding ZBlue as an explicit optional stack gives NuttX users a practical Bluetooth solution today, while still leaving room for the native stack to continue improving.

@anchao I agree 100% with everything you said, my only concern is assuming CONFIG_BT is ZBLUE you are removing the chance to let the NuttX native Bluetooth stack to become the default CONFIG_BT in the future.

This is why I suggested using CONFIG_ZBLUE, just like we have CONFIG_NINBLE.

@anchao

anchao commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@anchao I agree 100% with everything you said, my only concern is assuming CONFIG_BT is ZBLUE you are removing the chance to let the NuttX native Bluetooth stack to become the default CONFIG_BT in the future.

This is why I suggested using CONFIG_ZBLUE, just like we have CONFIG_NINBLE.

@acassis

I understand your concern, but I would like to clarify one point.

If this were only about renaming directories, moving files, or changing the
internal build/layout structure, I would have no problem with that. I have
already adjusted the layout several times based on review feedback.

What I am trying to avoid is exposing the implementation identity in the public
Kconfig or API naming. For developers who are familiar with Bluetooth stacks in
Linux or Zephyr, CONFIG_BT is the natural and expected entry point for Bluetooth
support. Having the main host stack option named after a specific internal
implementation, such as CONFIG_ZBLUE, makes the configuration less intuitive and
harder to understand from a Bluetooth developer's point of view.

In my view, CONFIG_BT should mean "Bluetooth support", not necessarily "this is
forever tied to one implementation name". The implementation can still live
under libs/zblue internally, but the user-facing Kconfig entry should remain the
common Bluetooth entry.

At this stage, CONFIG_BT does not conflict with the existing native NuttX
Bluetooth Kconfig in a practical way. Also, our plan is to rework the current
NuttX Bluetooth architecture quite soon, possibly in the next couple of weeks.
The intention is for CONFIG_BT to become the common Bluetooth host entry and to
replace the current incomplete native stack path. This work will also include
the integration with the existing Bluetooth network support and btsak, and use
ZBlue to provide the L2CAP/host implementation inside NuttX.

So I do not see CONFIG_BT as taking away the future of the native stack. Instead,
I see it as defining the common Bluetooth entry point that the improved NuttX
Bluetooth architecture will use.

Maybe we can also ask projects that are currently using NimBLE(cc @raiden00pl ): if NuttX
provides a complete and well-maintained BLE implementation in the kernel, would
they still prefer to use a third-party Bluetooth stack? I think that feedback
would be useful for deciding the long-term direction.

@acassis

acassis commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

@anchao I agree 100% with everything you said, my only concern is assuming CONFIG_BT is ZBLUE you are removing the chance to let the NuttX native Bluetooth stack to become the default CONFIG_BT in the future.
This is why I suggested using CONFIG_ZBLUE, just like we have CONFIG_NINBLE.

@acassis

I understand your concern, but I would like to clarify one point.

If this were only about renaming directories, moving files, or changing the internal build/layout structure, I would have no problem with that. I have already adjusted the layout several times based on review feedback.

What I am trying to avoid is exposing the implementation identity in the public Kconfig or API naming. For developers who are familiar with Bluetooth stacks in Linux or Zephyr, CONFIG_BT is the natural and expected entry point for Bluetooth support. Having the main host stack option named after a specific internal implementation, such as CONFIG_ZBLUE, makes the configuration less intuitive and harder to understand from a Bluetooth developer's point of view.

In my view, CONFIG_BT should mean "Bluetooth support", not necessarily "this is forever tied to one implementation name". The implementation can still live under libs/zblue internally, but the user-facing Kconfig entry should remain the common Bluetooth entry.

At this stage, CONFIG_BT does not conflict with the existing native NuttX Bluetooth Kconfig in a practical way. Also, our plan is to rework the current NuttX Bluetooth architecture quite soon, possibly in the next couple of weeks. The intention is for CONFIG_BT to become the common Bluetooth host entry and to replace the current incomplete native stack path. This work will also include the integration with the existing Bluetooth network support and btsak, and use ZBlue to provide the L2CAP/host implementation inside NuttX.

So I do not see CONFIG_BT as taking away the future of the native stack. Instead, I see it as defining the common Bluetooth entry point that the improved NuttX Bluetooth architecture will use.

Maybe we can also ask projects that are currently using NimBLE(cc @raiden00pl ): if NuttX provides a complete and well-maintained BLE implementation in the kernel, would they still prefer to use a third-party Bluetooth stack? I think that feedback would be useful for deciding the long-term direction.

@anchao but NuttX Kconfig is not 1:1 to Linux or Zephyr (it shouldn't be). So I think CONFIG_BT should mean BT/BLE supoort and then we have the stack used: CONFIG_BT_NIMBLE, CONFIG_BT_ZBLUE, etc.

Does it makes more sense? If we used CONFIG_BT to compile the ZBLUE stack only, it will be difficult to repurpose it to other stack later. So I think separating CONFIG_BT from the used stack makes more sense.

@anchao

anchao commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@anchao but NuttX Kconfig is not 1:1 to Linux or Zephyr (it shouldn't be). So I think CONFIG_BT should mean BT/BLE supoort and then we have the stack used: CONFIG_BT_NIMBLE, CONFIG_BT_ZBLUE, etc.

Does it makes more sense? If we used CONFIG_BT to compile the ZBLUE stack only, it will be difficult to repurpose it to other stack later. So I think separating CONFIG_BT from the used stack makes more sense.

@acassis

Yes, I understand your point, and I agree that NuttX Kconfig does not have to be
1:1 with Linux or Zephyr.

At this stage, many of the Bluetooth Kconfig options are inherited from Zephyr,
because the stack is derived from Zephyr. However, after this point, I do not
expect us to keep synchronizing the Kconfig directly with Zephyr. We have already
made many NuttX-specific integration changes, and it will become increasingly
difficult to keep this as a clean downstream sync.

So my view is that this is more like forking the current Bluetooth host stack
into NuttX and maintaining it as the NuttX Bluetooth implementation from now on,
rather than keeping it as a stack that is always selected as "Zephyr Bluetooth"
inside NuttX.

The main reason I would still like to keep the CONFIG_BT_* naming is that the
core Bluetooth configuration model is already familiar to developers who have
used Linux or Zephyr Bluetooth before. It also describes the Bluetooth features
themselves, not only the implementation identity. For example, options like
CONFIG_BT_CONN, CONFIG_BT_HCI, CONFIG_BT_L2CAP, CONFIG_BT_GATT, etc. are natural
Bluetooth feature names.

If CONFIG_BT is merged as the common Bluetooth host entry in NuttX, my
expectation is that it will become the main NuttX Bluetooth implementation going
forward. Similar to the TCP/IP stack in NuttX, I think the community should
focus on maintaining and improving one in-tree implementation instead of carrying
multiple host stacks long-term.

For NimBLE, if there are active users or maintainers who still need it, we can
discuss that with them. But if there is no strong user requirement for keeping a
separate NimBLE path, I think it would be better to encourage users to move to
the NuttX-maintained ZBlue-based Bluetooth stack once it provides the required
BLE functionality.

So I agree with the idea that CONFIG_BT should mean Bluetooth support in NuttX.
The difference is that I do not see ZBlue as a temporary third-party stack once
it is merged and maintained in-tree. I see it as the basis of the future NuttX
Bluetooth host implementation.

@acassis

acassis commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

@anchao but NuttX Kconfig is not 1:1 to Linux or Zephyr (it shouldn't be). So I think CONFIG_BT should mean BT/BLE supoort and then we have the stack used: CONFIG_BT_NIMBLE, CONFIG_BT_ZBLUE, etc.
Does it makes more sense? If we used CONFIG_BT to compile the ZBLUE stack only, it will be difficult to repurpose it to other stack later. So I think separating CONFIG_BT from the used stack makes more sense.

@acassis

Yes, I understand your point, and I agree that NuttX Kconfig does not have to be 1:1 with Linux or Zephyr.

At this stage, many of the Bluetooth Kconfig options are inherited from Zephyr, because the stack is derived from Zephyr. However, after this point, I do not expect us to keep synchronizing the Kconfig directly with Zephyr. We have already made many NuttX-specific integration changes, and it will become increasingly difficult to keep this as a clean downstream sync.

So my view is that this is more like forking the current Bluetooth host stack into NuttX and maintaining it as the NuttX Bluetooth implementation from now on, rather than keeping it as a stack that is always selected as "Zephyr Bluetooth" inside NuttX.

The main reason I would still like to keep the CONFIG_BT_* naming is that the core Bluetooth configuration model is already familiar to developers who have used Linux or Zephyr Bluetooth before. It also describes the Bluetooth features themselves, not only the implementation identity. For example, options like CONFIG_BT_CONN, CONFIG_BT_HCI, CONFIG_BT_L2CAP, CONFIG_BT_GATT, etc. are natural Bluetooth feature names.

If CONFIG_BT is merged as the common Bluetooth host entry in NuttX, my expectation is that it will become the main NuttX Bluetooth implementation going forward. Similar to the TCP/IP stack in NuttX, I think the community should focus on maintaining and improving one in-tree implementation instead of carrying multiple host stacks long-term.

For NimBLE, if there are active users or maintainers who still need it, we can discuss that with them. But if there is no strong user requirement for keeping a separate NimBLE path, I think it would be better to encourage users to move to the NuttX-maintained ZBlue-based Bluetooth stack once it provides the required BLE functionality.

So I agree with the idea that CONFIG_BT should mean Bluetooth support in NuttX. The difference is that I do not see ZBlue as a temporary third-party stack once it is merged and maintained in-tree. I see it as the basis of the future NuttX Bluetooth host implementation.

@anchao

I think that is our main point of divergence: I think ZBlue should be an option to allow others BT/BLE stack be used in the future, you think that ZBlue should become the NuttX default BT/BLE stack.

If you use CONFIG_BT_ZBLUE_HCI/L2CAP/GATT, etc, everybody will understand what it means, but selecting CONFIG_BT_HCI/etc to ZBLUE means we are giving it higher privilege (I think NimBLE and other should have the same opportunity to evolve). NimBLE for instance is actively maintained and was certified on Espressif chips: https://www.espressif.com/en/news/BLE_5.0_Certification

So, my point is: I am fine to let ZBlue in, but I'm not fine to let it to become the standard/official NuttX BT/BLE stack.

@anchao

anchao commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@anchao

I think that is our main point of divergence: I think ZBlue should be an option to allow others BT/BLE stack be used in the future, you think that ZBlue should become the NuttX default BT/BLE stack.

If you use CONFIG_BT_ZBLUE_HCI/L2CAP/GATT, etc, everybody will understand what it means, but selecting CONFIG_BT_HCI/etc to ZBLUE means we are giving it higher privilege (I think NimBLE and other should have the same opportunity to evolve). NimBLE for instance is actively maintained and was certified on Espressif chips: https://www.espressif.com/en/news/BLE_5.0_Certification

So, my point is: I am fine to let ZBlue in, but I'm not fine to let it to become the standard/official NuttX BT/BLE stack.

@acassis I think we've reached an impasse here. I'm unable to convince you, and I'm not willing to restructure the Kconfig naming in the way you're asking for. So I'm going to withdraw this PR for now. Thanks for the discussion.

@anchao anchao closed this Oct 24, 2026
@cederom

cederom commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Ugh :-( I hoped this zblue stuff will land in NuttX, because it would be verified, tested, and supported solution.. from other RTOS but well NuttX could also benefit here!

Regarding the zblue security there are many CVEs yes, that means the code it tested, maintained, and fixed, and probably it will have less issues in future. Our own implementation will also have bugs. More people see the code more people test code more bugs are discovered and then fixed.

Because that could be standalone and independent solution users could select alternative implementations (i.e. NXBT, Nimble, ZBlue). I agree here.

I know it's a hard situation, this impasse, I been there several times, but it can be fixed. I know a lot of work have been done already by Anchao and some of this needs a rework again. But this is very very important area and the implementation needs to be tip-top right from start so I would listen to the hints from the maintainers during code review.

@anchao

anchao commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

@acassis

I think there are 3 technical details worth considering again.

First, in ESP-IDF, Bluedroid and NimBLE are mutually exclusive host stack choices. That means users who need Classic Bluetooth have to select Bluedroid, and then they cannot use NimBLE at the same time for BLE-only features. This also means that features such as LE Mesh or LE Audio cannot naturally be combined with the Classic Bluetooth stack if they are only available from a different host stack.

https://github.com/espressif/esp-idf/blob/d35ea023029363d97c42565f85e0db23486f26b2/components/bt/Kconfig#L9-L33

This is one important difference from the ZBlue direction. ZBlue provides a single host stack architecture that can cover Classic, BLE, Mesh, LE Audio, and other Bluetooth features under one Bluetooth host implementation. So from a long-term architecture point of view, I think it is not exactly the same problem as choosing between Bluedroid and NimBLE in ESP-IDF.

Second, regarding the Kconfig naming, if we use ESP-IDF as a reference, I think we should also notice that its naming is not strictly stack-prefixed everywhere. For example, once Bluedroid is selected, many Classic/BLE feature options still use generic CONFIG_BT_* names, such as:

CONFIG_BT_CLASSIC_ENABLED
CONFIG_BT_A2DP_ENABLE
CONFIG_BT_AVRCP_ENABLED
CONFIG_BT_SPP_ENABLED
CONFIG_BT_L2CAP_ENABLED
CONFIG_BT_BLE_ENABLED
CONFIG_BT_GATTS_ENABLE
CONFIG_BT_GATTC_ENABLE

https://github.com/espressif/esp-idf/blob/d35ea023029363d97c42565f85e0db23486f26b2/components/bt/host/bluedroid/Kconfig.in#L105

So even ESP-IDF does not consistently use CONFIG_BT_BLUEDROID_* for all Bluedroid features. The stack name is mainly used for selecting the host stack, while many actual Bluetooth feature options remain under generic CONFIG_BT_*.

That is why I still think exposing ZBlue in every Bluetooth feature Kconfig name is not necessarily the right direction. It makes the configuration look more implementation-specific than the feature itself, and I think this will be harder for Bluetooth developers to understand and maintain in the long term.

Third, this naming inconsistency is even more visible in the Bluetooth controller part. ESP-IDF's BLE controller feature set is actually very similar to Zephyr's Bluetooth controller in terms of BLE 5 features, extended advertising, periodic advertising/sync, 2M PHY, and coded PHY support. However, unlike Zephyr, which uses a consistent and unified CONFIG_BT_CTLR_* prefix for Bluetooth controller options, ESP-IDF does not follow a single naming convention here. For example, it mixes multiple naming styles in the same Bluetooth subsystem:

CONFIG_BT_CONTROLLER_*
CONFIG_BTDM_CTRL_*
CONFIG_BT_CTRL_*
CONFIG_BT_LE_*

Some examples are:

CONFIG_BT_CTRL_BLE_MAX_ACT
CONFIG_BT_CTRL_ADV_DUP_FILT_MAX
CONFIG_BT_LE_50_FEATURE_SUPPORT
CONFIG_BT_LE_LL_CFG_FEAT_LE_2M_PHY
CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
CONFIG_BT_LE_EXT_ADV
CONFIG_BT_LE_ENABLE_PERIODIC_ADV
CONFIG_BT_LE_ENABLE_PERIODIC_SYNC

In Zephyr, similar controller capabilities are organized under one coherent controller namespace, for example:

CONFIG_BT_CTLR_PHY_2M
CONFIG_BT_CTLR_PHY_CODED
CONFIG_BT_CTLR_ADV_EXT
CONFIG_BT_CTLR_ADV_PERIODIC
CONFIG_BT_CTLR_SYNC_PERIODIC

So if ESP-IDF is used as the reference model, I think we should also recognize that its Bluetooth configuration is not a clean, unified design. It looks more like several historical parts stitched together with different naming conventions. Is this kind of fragmented Bluetooth organization really the direction we want to carry forward in NuttX, instead of keeping a coherent Bluetooth configuration model?

@acassis

acassis commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

@acassis

I think there are 3 technical details worth considering again.

First, in ESP-IDF, Bluedroid and NimBLE are mutually exclusive host stack choices. That means users who need Classic Bluetooth have to select Bluedroid, and then they cannot use NimBLE at the same time for BLE-only features. This also means that features such as LE Mesh or LE Audio cannot naturally be combined with the Classic Bluetooth stack if they are only available from a different host stack.

https://github.com/espressif/esp-idf/blob/d35ea023029363d97c42565f85e0db23486f26b2/components/bt/Kconfig#L9-L33

This is one important difference from the ZBlue direction. ZBlue provides a single host stack architecture that can cover Classic, BLE, Mesh, LE Audio, and other Bluetooth features under one Bluetooth host implementation. So from a long-term architecture point of view, I think it is not exactly the same problem as choosing between Bluedroid and NimBLE in ESP-IDF.

Second, regarding the Kconfig naming, if we use ESP-IDF as a reference, I think we should also notice that its naming is not strictly stack-prefixed everywhere. For example, once Bluedroid is selected, many Classic/BLE feature options still use generic CONFIG_BT_* names, such as:

CONFIG_BT_CLASSIC_ENABLED
CONFIG_BT_A2DP_ENABLE
CONFIG_BT_AVRCP_ENABLED
CONFIG_BT_SPP_ENABLED
CONFIG_BT_L2CAP_ENABLED
CONFIG_BT_BLE_ENABLED
CONFIG_BT_GATTS_ENABLE
CONFIG_BT_GATTC_ENABLE

https://github.com/espressif/esp-idf/blob/d35ea023029363d97c42565f85e0db23486f26b2/components/bt/host/bluedroid/Kconfig.in#L105

So even ESP-IDF does not consistently use CONFIG_BT_BLUEDROID_* for all Bluedroid features. The stack name is mainly used for selecting the host stack, while many actual Bluetooth feature options remain under generic CONFIG_BT_*.

That is why I still think exposing ZBlue in every Bluetooth feature Kconfig name is not necessarily the right direction. It makes the configuration look more implementation-specific than the feature itself, and I think this will be harder for Bluetooth developers to understand and maintain in the long term.

Third, this naming inconsistency is even more visible in the Bluetooth controller part. ESP-IDF's BLE controller feature set is actually very similar to Zephyr's Bluetooth controller in terms of BLE 5 features, extended advertising, periodic advertising/sync, 2M PHY, and coded PHY support. However, unlike Zephyr, which uses a consistent and unified CONFIG_BT_CTLR_* prefix for Bluetooth controller options, ESP-IDF does not follow a single naming convention here. For example, it mixes multiple naming styles in the same Bluetooth subsystem:

CONFIG_BT_CONTROLLER_*
CONFIG_BTDM_CTRL_*
CONFIG_BT_CTRL_*
CONFIG_BT_LE_*

Some examples are:

CONFIG_BT_CTRL_BLE_MAX_ACT
CONFIG_BT_CTRL_ADV_DUP_FILT_MAX
CONFIG_BT_LE_50_FEATURE_SUPPORT
CONFIG_BT_LE_LL_CFG_FEAT_LE_2M_PHY
CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
CONFIG_BT_LE_EXT_ADV
CONFIG_BT_LE_ENABLE_PERIODIC_ADV
CONFIG_BT_LE_ENABLE_PERIODIC_SYNC

In Zephyr, similar controller capabilities are organized under one coherent controller namespace, for example:

CONFIG_BT_CTLR_PHY_2M
CONFIG_BT_CTLR_PHY_CODED
CONFIG_BT_CTLR_ADV_EXT
CONFIG_BT_CTLR_ADV_PERIODIC
CONFIG_BT_CTLR_SYNC_PERIODIC

So if ESP-IDF is used as the reference model, I think we should also recognize that its Bluetooth configuration is not a clean, unified design. It looks more like several historical parts stitched together with different naming conventions. Is this kind of fragmented Bluetooth organization really the direction we want to carry forward in NuttX, instead of keeping a coherent Bluetooth configuration model?

@anchao

Good point, I think if we have a similar CONFIG_ZBLUE_ENABLED, CONFIG_NIMBLE_ENABLED, etc, we could keep the generic CONFIG_BT_* in place and reuse it between stacks.

If you decide to modify to follow this approach I am fine with it.

@anchao

anchao commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

@anchao

Good point, I think if we have a similar CONFIG_ZBLUE_ENABLED, CONFIG_NIMBLE_ENABLED, etc, we could keep the generic CONFIG_BT_* in place and reuse it between stacks.

If you decide to modify to follow this approach I am fine with it.

@acassis Thanks, I think this is a good compromise.

I updated the PR to add an explicit CONFIG_ZBLUE_ENABLED option for selecting
the ZBlue Bluetooth host stack. With this change, users can now clearly see and
select the ZBlue stack itself, instead of having the stack selection hidden
behind the generic Bluetooth feature namespace.

At the same time, I kept the existing Bluetooth feature options under the
generic CONFIG_BT_* naming. My intention is that CONFIG_ZBLUE_ENABLED
identifies the implementation/stack choice, while the CONFIG_BT_* options
continue to describe Bluetooth features and profiles rather than exposing the
implementation name in every feature symbol.

So the configuration model is now:

  • CONFIG_ZBLUE_ENABLED: select the ZBlue Bluetooth host stack
  • CONFIG_BT_*: Bluetooth features, roles, profiles, services, Mesh, LE Audio,
    Classic, buffer sizing, and related host options

Thanks for the suggestion. I think this keeps the stack selection explicit while
preserving the familiar Bluetooth feature naming for developers.

@anchao anchao reopened this Oct 26, 2026
@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch from 38d14a0 to f500b39 Compare October 26, 2026 13:05
acassis
acassis previously approved these changes Oct 26, 2026
Comment thread drivers/wireless/bluetooth/bt_driver.c Outdated
Comment thread include/nuttx/net/bluetooth/addr.h Outdated
Comment thread boards/sim/sim/sim/src/sim_bringup.c Outdated
Comment thread include/nuttx/net/bluetooth/compat/net_buf.h
Comment thread include/nuttx/atomic.h
Comment thread mm/net_buf/CMakeLists.txt Outdated
Comment thread net/Kconfig Outdated
Comment thread libs/zblue/CMakeLists.txt
@@ -0,0 +1,40 @@
# ##############################################################################
# libs/zblue/CMakeLists.txt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still prefer zblue belong nuttx-apps.git, @raiden00pl what's your opinion?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won’t comment on where the Bluetooth code should be placed, but I notice this PR consists entirely of code—where are the tests? Since we already have the BSWorld simulation testing system, and it’s now supported in the default CI pipeline, we really should add corresponding Bluetooth tests for this PR. Otherwise, how can we ensure the stability of such an extensive set of fixes? Although BR/EDR is not yet supported, the vast majority of LE (Low Energy) functionality can certainly be tested.

@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch from 6a55baa to bc3479e Compare October 27, 2026 07:37
Add a native NuttX Bluetooth host stack under libs/zblue together with the
public Bluetooth header namespace, net_buf memory support, and build
integration.  The stack provides a complete host-side foundation that can be
built inside NuttX without requiring an external RTOS runtime, while keeping
the controller interface separated through the HCI transport and driver
abstraction layers.

The implementation is organized by protocol layer and upper profile coverage:

- Core Host:
  - Bluetooth address handling
  - identity management
  - HCI command and event processing
  - buffer ownership and monitor support
  - settings storage and key management
  - SMP pairing support
  - GATT database handling
  - ATT request processing
  - L2CAP channels
  - ISO channels
  - advertising and scanning
  - connection management
  - direction finding and channel sounding
  - common data helpers

  These pieces provide both the internal protocol machinery and the public APIs
  needed by applications, services, and profiles.

- Classic BR/EDR:
  - inquiry and connection management
  - BR/EDR L2CAP
  - RFCOMM
  - SDP
  - SCO plumbing
  - secure simple pairing
  - A2DP
  - AVRCP and AVRCP cover art
  - GOEP and OBEX
  - BIP
  - PBAP
  - MAP
  - HFP Audio Gateway
  - HFP Hands-Free
  - HID Device and HID Host

- Bluetooth Mesh:
  - provisioning and bearer handling
  - network, transport, and access layers
  - subnet and key management
  - replay protection
  - beacons
  - friend and low-power-node behavior
  - GATT proxy and proxy client/server
  - heartbeat
  - configuration client/server
  - health client/server
  - model message helpers
  - settings persistence
  - BLOB transfer
  - firmware update and distribution
  - remote provisioning
  - large composition data
  - directed forwarding
  - bridge configuration
  - on-demand private proxy
  - opcode aggregation
  - private beacon
  - SAR configuration
  - solicitation PDU RPL
  - statistics
  - related client and server models

- LE Audio:
  - BAP unicast client/server
  - BAP broadcast source/sink
  - scan delegator and broadcast assistant
  - PACS and ASCS
  - CAP acceptor, initiator, and commander
  - AICS
  - VCP and VOCS
  - MICP
  - CSIP
  - TBS
  - MCS and MCC
  - media proxy
  - HAS
  - TMAS and TMAP
  - GMAP
  - PBP
  - CCID and CCP
  - codec helpers
  - LC3 preset definitions
  - endpoint and stream management

  These components provide the public headers and implementation structure
  needed for both unicast and broadcast audio roles as well as coordinated and
  content-control audio use cases.

- GATT Services:
  - GAP
  - BAS
  - DIS
  - TPS
  - HRS
  - CTS
  - ETS
  - IAS
  - ANS
  - NUS
  - OTS
  - service configuration and callbacks
  - object transfer support
  - Nordic UART service instances
  - immediate alert client/server helpers
  - battery service variants

- Common Support:
  - crypto helpers
  - EAD
  - SBC codec support
  - host utility code
  - NuttX-backed kernel object wrappers
  - work queues and timeout helpers
  - atomics
  - settings and logging support
  - device stubs
  - iterable sections
  - HCI driver registration
  - path-derived public header guards

  Keep the compatibility surface local to the Bluetooth subsystem and expose
  public APIs through the NuttX include tree.

- Build and Configuration:
  - standalone libs/zblue Make build integration
  - CMake build integration
  - Kconfig coverage for the core host
  - Kconfig coverage for Classic, Mesh, services, and LE Audio
  - Kconfig coverage for crypto, common library, and net_buf support
  - private include paths for internal compatibility headers

  The build integration keeps Bluetooth implementation details from leaking
  into unrelated NuttX targets.

Note: The current Bluetooth host stack supports only flat builds. Protected and
kernel builds are not supported yet.

Signed-off-by: chao an <anchao.archer@bytedance.com>
@anchao
anchao force-pushed the nuttx_bluetooth_host_stack branch from bc3479e to 47ab26d Compare October 27, 2026 08:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: simulator Issues related to the SIMulator Area: Bluetooth Board: simulator Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants