Hi anchao,

  Thank you for the detailed reply, and for the offer to work together. I am
  glad we agree on the most important point: NuttX should have one
  Zephyr-based Bluetooth host, not two.

  Let me first list where I think we already agree, then the open points and
  a proposed order of work.

  Where we agree:

  1. One common stack. We are happy to use the openvela stack as the common
     base and to work on it together with you.
  2. Long-term architecture for protected/kernel builds: a BlueZ/Linux-style
     split, with HCI/core/L2CAP and socket integration in the kernel, and
     profiles, services and tools in userspace. This is the path described in
     Section 5 of the proposal.
  3. Flat builds may keep a more direct HCI path (btdev callback) for low-end
     IoT chips. We see no conflict with that; it can be an option next to the
     socket model.
  4. Kconfig: CONFIG_ZBLUE_ENABLED as the top-level switch, with CONFIG_BT_*
     for the feature options, as agreed with Alan, is fine with us.

  Open point 1: fork vs. staying in sync with Zephyr

  You are right that the port layer needs NuttX kernel-style primitives
  today, and that the compatibility layer has a cost. In flat build we use
  some internal primitives; making the port layer use only public interfaces
  is part of the protected/kernel work.

  Our suggestion is to fork only where the NuttX architecture requires it,
  not by default:

  - The layers that move into the kernel (HCI core, connection management,
    L2CAP, socket integration) become NuttX-maintained code. Those are the
    parts that must be adapted to NuttX networking, memory management and
    build modes anyway.
  - The layers above (profiles, GATT services, LE Audio, Mesh, Classic
    profiles) only depend on the Zephyr Bluetooth host API, not on the Zephyr
    kernel. That is also where most upstream development and security fixes
    happen. Keeping them close to upstream lets NuttX keep picking those
    fixes up with little effort.

  This way the compatibility layer shrinks over time instead of growing, and
  the divergence happens step by step, where it brings real value.

  Open point 2: external repository vs. in-tree

  We suggest starting with an external git repository, fetched at a pinned
  revision like NimBLE. This keeps the first patches small and easy to review,
  and gives everyone a working stack to test against from the start. The
  kernel part will live in nuttx.git. Once the userspace part only contains
  the layers above L2CAP, we can move it into nuttx-apps.git if the community
  prefers that.

  Proposed order of work:

  1. Integrate the stack into nuttx-apps as an external git repository, as
     described in the proposal.
  2. Move the L2CAP layer and below into the NuttX kernel, replacing the
     current kernel Bluetooth implementation (wireless/bluetooth and
     net/bluetooth). The new kernel part must keep the existing functionality
     and add BR/EDR Classic support.
  3. Change the stack in nuttx-apps to drop its own L2CAP-and-below layers and
     use the NuttX kernel instead (sockets for protected/kernel builds; for
     flat builds, optionally a direct function-call/callback path to the
     kernel L2CAP layer). If needed at this step, the remaining Zephyr-derived
     code can be moved into nuttx-apps.git.

  Each step is a separate series of small patches, and the stack keeps working
  after every step.

  I would like to hear what Xiang, Alan, raiden00pl and others think about
  this order and the two points above.

  Proposed next step: once this is settled, we write a short joint roadmap
  (owners and schedule for each step), post it here for review, and then
  start with small, reviewable patches.

  Thanks again for the open discussion.

  Best regards,
  Kai Cheng


________________________________
From: chao an <[email protected]>
Sent: Wednesday, October 28, 2026 9:03 PM
To: [email protected]
Cc: 黄玉龙; 高子豪; 梁超众; 李剑; 陈建; 成凯
Subject: Re: [External Mail][DISCUSS] Proposal: integrate a Zephyr-based 
Bluetooth host (openvela zblue) as a userspace stack in nuttx-apps, kept in 
sync with upstream Zephyr


[外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给[email protected]进行反馈

Hi Chengkai and Vela team,

First, thank you for writing this proposal. I think this is a good start: the 
community is now discussing the Bluetooth host stack direction seriously, and 
that is very helpful for NuttX.

I agree that we should converge on one Zephyr-based Bluetooth host instead of 
maintaining two unrelated solutions. However, I have a different view on the 
long-term implementation model.

My current opinion is that once we import the Zephyr Bluetooth host into NuttX, 
we should treat it more like a forked NuttX Bluetooth stack, not as a subtree 
that keeps rebasing/syncing with Zephyr forever.

The reason is that zblue is deeply coupled with the Zephyr kernel model. If we 
want to keep it continuously synchronized with Zephyr, then in practice we also 
need to keep a large Zephyr compatibility layer alive. For an official NuttX 
solution, I do not think it is ideal to introduce and maintain a large part of 
the Zephyr kernel abstraction just for one protocol stack.

Some comments on the questions:

  1.  About putting a userspace Zephyr host in nuttx-apps and fetching it from 
an external repository while keeping it synchronized with Zephyr:
I still have concerns about this model.
First, zblue is not really an independent userspace library. It was designed to 
run inside Zephyr and depends heavily on Zephyr kernel concepts. Even if it is 
placed in apps, the porting layer still needs many NuttX kernel-style 
primitives, such as nxsem, nxmutex, work queues, ticks, timers, and internal 
scheduling behavior. So I do not think simply placing it in nuttx-apps makes it 
a clean application-level library.
Second, this does not match the original direction that Greg wanted for the 
NuttX Bluetooth stack. My understanding is that the goal was a Unix-like 
Bluetooth architecture, where data communication goes through network/socket 
APIs. A pure userspace Zephyr-style host over HCI does not really provide that 
architecture.
Third, I think keeping full long-term synchronization with Zephyr will be very 
difficult unless we preserve too much of Zephyr's own kernel model. Once we 
adapt the stack seriously to NuttX APIs, networking, memory management, driver 
model, and build modes, it will naturally diverge. So I prefer to accept that 
it becomes a NuttX-maintained Bluetooth stack based on Zephyr, rather than 
trying to keep it as an almost-unmodified Zephyr module.
  2.  About where the external repository should live:
My preference is not to maintain it as a separate external repository in the 
long term. I think it should be integrated directly into either nuttx.git or 
nuttx-apps.git, depending on the final layering decision. This makes review, 
CI, release management, and maintenance clearer for the NuttX community.
  3.  About coexistence with PR #20686:
I am very happy to drop my current PR if the community agrees on a better 
common direction. My original goal is not to push my own implementation, but to 
help NuttX get a complete Bluetooth stack and improve the kernel-side 
networking architecture.
If the openvela roadmap is aligned with that goal, especially if it can 
eventually support a Unix-like Bluetooth model for NuttX, I would be very happy 
to work with you and use your solution as the base.
  4.  About Kconfig naming:
I discussed this with Alan before. The current compromise is to use a global 
switch like CONFIG_ZBLUE_ENABLED, while keeping the internal Kconfig options 
close to Zephyr style, such as CONFIG_BT_*. I think this is friendly to both 
Zephyr and Linux Bluetooth developers, while still making the top-level NuttX 
feature explicit.
  5.  About the long-term split:
My preference is:
     *   For protected/kernel builds, move toward a BlueZ/Linux-style split: 
kernel-side HCI/core/L2CAP/socket integration, with profiles and tools in 
userspace.
     *   For flat builds, allow a more direct HCI/btdev callback path for 
better performance on low-end IoT chips.
In other words, I do not think we need one single boundary for all build modes. 
NuttX supports very different deployment models, so the Bluetooth architecture 
may also need to support different integration paths.

Again, thanks for proposing this. I think the most important thing is to reach 
a common direction first. I am open to working together and adjusting my PR if 
we can agree on a roadmap that gives NuttX a complete Bluetooth stack while 
also moving toward the right long-term architecture.

BRs,

成凯 via dev <[email protected]<mailto:[email protected]>> 于2026年10月28日周三 
20:46写道:
    Hi all,

    Apologies for the garbled characters in my previous mail; my mail client
    used a non-UTF-8 encoding. The "??5" / "��5" references mean "Section 5"
    (Optional path to a BlueZ/Linux-style split), "Section 7" is the Plan, and
    the dashes in the phase titles are plain hyphens. The content is otherwise
    unchanged.

    Please also ignore the confidentiality footer added by our mail gateway;
    this proposal is intended for public discussion.

    Best regards,
    Kai Cheng



________________________________
From: 成凯 via dev <[email protected]<mailto:[email protected]>>
Sent: Wednesday, October 28, 2026 5:54 PM
To: [email protected]<mailto:[email protected]>
Cc: 黄玉龙; 高子豪; 梁超众; 李剑; 陈建; 成凯
Subject: [External Mail][DISCUSS] Proposal: integrate a Zephyr-based Bluetooth 
host (openvela zblue) as a userspace stack in nuttx-apps, kept in sync with 
upstream Zephyr

[外部邮件] 
此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给[email protected]<mailto:[email protected]>进行反馈

Hi all,

Following the discussion on PR #20686 [1] and the thread "PR #20686 — 
Introducing
a Zephyr-based Bluetooth host stack under net/bt" [2], I would like to propose 
an
alternative integration model for a full-featured (BLE + BR/EDR Classic)
Bluetooth host on NuttX, and ask for the community's opinion before we start
sending patches.

First, thanks to Archer (anchao) for pushing this topic forward. Everyone in the
thread seems to agree that NuttX needs a more complete Bluetooth host. The open
question is where it should live and how it should be maintained. This proposal
only covers that question.

------------------------------------------------------------------------------
1. Summary
------------------------------------------------------------------------------

- Integrate the Zephyr Bluetooth host as a userspace library in nuttx-apps,
  under wireless/bluetooth/, the same way NimBLE is integrated today [3].
- The stack source lives in a standalone repository and is fetched at a pinned
  revision at build time. Zephyr's subsys/bluetooth is kept unmodified; all
  NuttX adaptation goes into a separate, small port layer.
- At the start, the NuttX kernel only provides the HCI transport (the
  existing drivers/wireless/bluetooth bt_driver_s drivers, exposed to
  userspace through the H4 character device or the HCI user-channel socket).
  If the community prefers a BlueZ/Linux-style split, the L2/L3 layers can be
  moved into the kernel step by step from this base (see §5).
- The stack is an optional choice selected by Kconfig, next to the native
  wireless/bluetooth stack and NimBLE. It does not replace them, and it is not
  presented as the default NuttX Bluetooth stack.
- Fixes go to upstream Zephyr first and come back to NuttX through regular
  rebases.

If the community agrees with this direction, we will upstream our existing,
production-proven stack step by step (stack integration first, then tests,
then the optional Bluetooth service layer).

------------------------------------------------------------------------------
2. What we already have
------------------------------------------------------------------------------

The openvela team at Xiaomi has run a Zephyr-based Bluetooth host on
NuttX/openvela in production for some time:

- Baseline: Zephyr v4.0 (upstream commit 2efc8598e39, 2024-11), plus later
  upstream fixes and our own work.
- Features: LE GAP/GATT/ATT/SMP, and BR/EDR Classic with A2DP (SRC/SNK),
  AVRCP (CT/TG), HFP (AG/HF), SPP/RFCOMM, SDP, HID Device/Host and
  GATT over BR/EDR. LE Audio and Mesh come from upstream.
- Products: shipping in smart speakers (since 2025), smart panels, and
  wearables (watches and bands).
- Qualification: Bluetooth SIG qualification against Core 6.2 (Declaration ID
  Q386483).
- Qualification testing: the stack plugs directly into AutoPTS through the
  Zephyr BTP tester. A full dual-mode qualification test run takes about
  2 person-days.
- Simulation: conformance tests can run in simulation on BSWorld or a
  software RF controller, without real hardware or phones. This is key to
  keeping the stack's quality up as it evolves.
- Performance: the host runs in userspace in a flat build and reaches about
  210 kB/s SPP throughput on a wearable SoC. Running outside the kernel has not
  been a bottleneck for us.
- Upstream work: our team is one of the major contributors to Classic
  Bluetooth in the Zephyr community.
- Public code: https://github.com/open-vela/external_zblue (stack) and
  https://github.com/open-vela/frameworks_bluetooth (service layer). These
  repositories contain our 2025 changes. The 2026 changes are still in our
  internal tree and will be released and upstreamed.

------------------------------------------------------------------------------
3. Points raised in the PR #20686 discussion
------------------------------------------------------------------------------

My reading of the review comments and the mailing-list thread:

a) Profiles, shell commands and other application-level code do not belong in
   kernel space (Xiang Xiao, raiden00pl).
b) A monolithic third-party host stack should live in nuttx-apps or a separate
   git, integrated by download like NimBLE (Xiang Xiao).
c) A stack of this size is a large attack surface. Keeping it out of the kernel
   protects at least protected and kernel builds (Alan Carvalho de Assis,
   casaroli).
d) It should be one selectable option, not the implicit "official" NuttX
   Bluetooth stack (Alan Carvalho de Assis).
e) Tests are required, e.g. sim-based or BSWorld (LingaoM, cederom).
f) Copyright and license headers of the imported code must be handled
   correctly (jerpelea, acassis, Xiang Xiao).
g) Unfinished work should not land on master (raiden00pl, Xiang Xiao).

The proposal below tries to meet all of these.

------------------------------------------------------------------------------
4. Proposed architecture
------------------------------------------------------------------------------

    +----------------------------------------------------------+
    | Applications / btshell / (optional) Bluetooth service    |  userspace
    +----------------------------------------------------------+
    | Zephyr Bluetooth host (unmodified subsys/bluetooth)      |  userspace
    |   GAP/GATT/SMP/L2CAP/RFCOMM/SDP/A2DP/AVRCP/HFP/HID/...   |  (nuttx-apps)
    +----------------------------------------------------------+
    | Port layer: k_thread/k_sem/k_work/k_timer, net_buf,      |  userspace
    | settings backend, logging, iterable sections, HCI glue   |
    +=========================== HCI =========================+
    | HCI transport: /dev/ttyHCIx (H4) or HCI user channel     |  kernel
    | bt_uart / bt_rpmsghci / bt_slip / sim HCI socket ...     |  (existing)
    +----------------------------------------------------------+
    | Controller                                               |
    +----------------------------------------------------------+

Design rules:

1. Upstream code stays unmodified. Zephyr's subsys/bluetooth is not reformatted
   or edited in place. Like NimBLE, it is third-party code and not subject to
   nxstyle. Any change the stack needs is sent to Zephyr first. (If parts are
   later moved into the kernel as described in §5, those parts are maintained
   in NuttX; the rest keeps this rule.)
2. NuttX adaptation stays in the port layer. Zephyr kernel APIs are implemented
   on top of NuttX. Upstream Bluetooth code keeps calling the Zephyr API, so
   upstream patches still apply.
3. The initial kernel/user boundary is HCI. The only kernel component is the
   HCI transport, which NuttX already has. The host stack uses public
   interfaces only (open/read/write/poll or the HCI socket).
4. Kconfig is namespaced. One top-level option (e.g. CONFIG_ZBLUE, like
   CONFIG_NIMBLE) selects the stack. The Zephyr CONFIG_BT_* feature options
   live under it inside nuttx-apps. If a kernel-side stack also uses
   CONFIG_BT_*, the two must be made mutually exclusive or renamed; we are
   happy to work this out with Archer.
5. Build modes: flat build first. Because only public interfaces are used, we
   plan protected and kernel build support as a follow-up phase (see §7).

Why we start with the split at HCI:

The Zephyr host is not layered like Linux. L2CAP is tightly coupled with
conn.c, ATT, SMP and the buffer and work-queue model. Splitting at HCI keeps
the upstream code untouched and gives NuttX a complete, working stack from
day one. It is the same model Android uses (a userspace host on top of an HCI
transport) and the model NimBLE already uses on NuttX. Moving L2CAP and below
into the kernel (the BlueZ model) is possible, but it means restructuring
those layers, so we propose it as a separate, step-by-step path (§5).


------------------------------------------------------------------------------
5. Optional path to a BlueZ/Linux-style split
------------------------------------------------------------------------------

Some community members prefer the Linux/BlueZ layering, where the lower
protocol layers (HCI core, connection management, L2CAP, and possibly SMP)
live in the kernel and are exposed through AF_BLUETOOTH sockets, while
profiles, services and tools stay in userspace. This proposal is compatible
with that goal, and our stack can serve as the base for it.

The difference from PR #20686 is the direction of migration:

  - PR #20686 puts the whole host into the kernel first and plans to move
    parts back to userspace later.
  - We start with a complete, product-proven host in userspace, and move the
    L2/L3 layers into the kernel step by step, only where the community
    agrees.

Every intermediate state is a working stack, every step can be reviewed and
tested on its own, and the code that has not moved yet keeps tracking
upstream Zephyr.

Possible steps, each a separate patch series:

  1. Define the kernel/user interface first: AF_BLUETOOTH sockets for L2CAP
     (BTPROTO_L2CAP, struct sockaddr_l2), building on the existing NuttX
     definitions in include/netpacket/bluetooth.h, plus an HCI management
     interface.
  2. Move the HCI core and connection management into the kernel, next to
     the existing HCI drivers.
  3. Move L2CAP (LE and BR/EDR) into the kernel behind the socket interface.
  4. Decide case by case for SMP, ATT/GATT and RFCOMM, based on review and
     measurements.

What stays in nuttx-apps in all cases: profiles (A2DP, AVRCP, HFP, HID,
...), GATT services, the Bluetooth service layer, shell and tools.

Trade-off: code moved into the kernel will diverge from upstream Zephyr and
must be maintained in NuttX. Moving it layer by layer, and keeping the
Zephyr API at the boundary where possible, limits that cost and lets the
community decide how far to go.

------------------------------------------------------------------------------
6. Comparison with PR #20686
------------------------------------------------------------------------------

                         PR #20686 (current)           This proposal
  Location               nuttx (net/bt, now libs/)     nuttx-apps + external 
repo
  Upstream code          reformatted, Zephyr APIs      unmodified; port layer 
only
                         replaced in place
  Zephyr sync            close to a re-port per        rebase onto new Zephyr
                         release (author describes     releases
                         it as a fork)
  Security fixes         backported by hand            picked from upstream
  Kernel attack surface  whole host in kernel          HCI transport only
  Shell / profiles       inside kernel tree            userspace
  Build modes            flat only                     flat first, then
                                                       protected/kernel
  License headers        need rewriting in tree        upstream files keep their
                                                       headers, not in nuttx.git
  Evolution path         whole host in kernel first,   working host in userspace
                         then move parts out           first, then move L2/L3
                                                       into kernel if agreed

Notes:

- Sync cost: the PR reformats the code to nxstyle and replaces Zephyr kernel
  APIs inside protocol files. A whitespace-insensitive diff against
  Zephyr v4.5.0-rc1 still differs in roughly 19% of lines, so upstream patches
  no longer apply directly. Archer also wrote on the PR that he does not expect
  to keep synchronizing with Zephyr ("more like forking"). For a code base this
  size, with a steady stream of upstream CVE fixes (Alan listed more than 70
  since 2019), we think staying close to upstream is the main long-term value.
- Performance: as Xiang pointed out, in a flat build a userspace stack has the
  same direct-call cost as an in-kernel one. The remaining per-packet overhead
  is the HCI transport (VFS + one copy). Our static estimate on a wearable SoC
  is a few KB of RAM and negligible CPU. Very constrained parts (for example
  the 80 MHz M0 / 64 KB case Archer described) can get an optional
  flat-build-only direct HCI binding later, without moving the host into the
  kernel.

------------------------------------------------------------------------------
7. Plan
------------------------------------------------------------------------------

Phase 0 – Consensus (this thread)
  Agree on location, naming, Kconfig namespace and coexistence with PR #20686.

Phase 1 – Stack integration (nuttx-apps)
  - wireless/bluetooth/zblue: Makefile/CMake download at a pinned ref, Kconfig,
    port layer.
  - Uses the existing HCI transports; no kernel changes expected (only small,
    separate fixes if any).
  - btshell as an NSH builtin (the Zephyr shell, Classic and LE commands).
  - sim configuration with a host HCI dongle, built in CI.

Phase 2 – Tests
  - sim-based tests for LE and Classic in CI (BSWorld integration).
  - AutoPTS support through the Zephyr BTP tester.
  - Samples: LE peripheral/central, A2DP sink, HFP HF, SPP.

Phase 3 – Protected / kernel build
  - Port layer audited to use only public NuttX/POSIX interfaces.
  - Validated on a protected and a kernel build target.

Phase 4 – Bluetooth service layer (optional)
  - Upstream the openvela Bluetooth service ("btservice"): a stable C API for
    applications, multi-client IPC, and a stack abstraction layer, so
    applications do not depend on the host stack API.

Phase 5 – Boards
  - Board configurations with real controllers (UART / RPMsg HCI).

Phase 6 – L2/L3 migration to the kernel (optional, if agreed)
  - Follow the steps in §5, one layer per patch series.

Ongoing
  - Track Zephyr releases and send fixes upstream first.
  - We will provide maintainers for the integration.

The main goal of this mail is to collect feedback on the direction. We will
follow up with a detailed effort estimate and schedule for each phase once the
direction is agreed.

------------------------------------------------------------------------------
8. Licensing
------------------------------------------------------------------------------

- Zephyr-derived files stay in the external repository with their original
  Apache-2.0 headers and SPDX tags. They are not copied into apache/nuttx or
  apache/nuttx-apps.
- New glue code in nuttx-apps uses the standard ASF header and is contributed
  under ICLA/CCLA.

------------------------------------------------------------------------------
9. Questions for the community
------------------------------------------------------------------------------

1. Is a userspace Zephyr-based host in nuttx-apps, fetched from an external
   repository and kept in sync with Zephyr, acceptable as the integration
   model?
2. Where should the external repository live (open-vela GitHub organization,
   or another location the PMC prefers)?
3. How should this coexist with PR #20686? We would rather converge on one
   Zephyr-based host than ship two. We are glad to work with Archer on a
   common approach.
4. Any preference on the top-level Kconfig name (CONFIG_ZBLUE or other)?
5. Should the long-term target stay at the HCI split, or move towards the
   BlueZ/Linux-style split described in §5?

Feedback is very welcome.

[1] https://github.com/apache/nuttx/pull/20686
[2] https://www.mail-archive.com/[email protected]/msg15328.html
[3] https://github.com/apache/nuttx-apps/tree/master/wireless/bluetooth/nimble

Best regards,

Kai Cheng


#/******本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件!
 This e-mail and its attachments contain confidential information from XIAOMI, 
which is intended only for the person or entity whose address is listed above. 
Any use of the information contained herein in any way (including, but not 
limited to, total or partial disclosure, reproduction, or dissemination) by 
persons other than the intended recipient(s) is prohibited. If you receive this 
e-mail in error, please notify the sender by phone or email immediately and 
delete it!******/#
#/******本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件!
 This e-mail and its attachments contain confidential information from XIAOMI, 
which is intended only for the person or entity whose address is listed above. 
Any use of the information contained herein in any way (including, but not 
limited to, total or partial disclosure, reproduction, or dissemination) by 
persons other than the intended recipient(s) is prohibited. If you receive this 
e-mail in error, please notify the sender by phone or email immediately and 
delete it!******/#
#/******本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件!
 This e-mail and its attachments contain confidential information from XIAOMI, 
which is intended only for the person or entity whose address is listed above. 
Any use of the information contained herein in any way (including, but not 
limited to, total or partial disclosure, reproduction, or dissemination) by 
persons other than the intended recipient(s) is prohibited. If you receive this 
e-mail in error, please notify the sender by phone or email immediately and 
delete it!******/#

Reply via email to