You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6ef4273
Browse filesBrowse the repository at this point in the historyBrowse files
Rename WiFi -> WLAN across the docs; wland/org.nextbsd.wlan
The daemon is `wland`, the CLI is `wlan`, the launchd job is
org.nextbsd.wland advertising Mach service org.nextbsd.wlan.
`wlan` matches what already exists at both ends: FreeBSD's
wlan0/net80211/wlan_xauth below, and Gershwin's existing
scanForWLANs/setWLANEnabled: protocol and "WLAN" prefPane tab
above. Nothing breaks — none of the renamed code is written yet.
Files: nextbsd-wifi-{plan,research}.html -> nextbsd-wlan-*.html,
with all inbound links repointed.
Deliberately NOT renamed, since renaming would make the docs wrong:
- FreeBSD/LinuxKPI driver names (iwlwifi, if_iwlwifi,
wlans_iwlwifi0) and the shipping IntelWiFi.kext
- Apple's real closed daemon `wifid` and its identifiers
(com.apple.wifid, CWWiFiClient, Apple80211)
- the HelloWifid repo, and the Wi-Fi Alliance / Wi-Fi Direct
standard names
The SC entity stays AirPort — that's Apple's schema name.
Namespace: record in the Keychain plan that com.apple.* -> org.nextbsd.*
is the intended direction, deferred only because the labels are baked
into shipped jobs, plists, and bootstrap_look_up() sites. The operative
rule is "does Apple-derived code look this label up?", not "is it new?":
securityd keeps com.apple.* because a clean-room Security.framework
hardcodes bootstrap_look_up("com.apple.securityd"), while wland has no
Apple-derived consumer and so takes org.nextbsd.* from day one.
Also repairs a garbled link title in launchd-research.html left by an
earlier find/replace ("...Apple stack researchmdash; the Apple stack...").
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: freebsd-bluetooth-management.html
+19-19Lines changed: 19 additions & 19 deletions
Original file line number
Diff line number
Diff line change
@@ -84,26 +84,26 @@
84
84
</nav>
85
85
86
86
<h1>FreeBSD Bluetooth management — Apple stack research <spanclass="pill info">RESEARCH</span></h1>
87
-
<pclass="subtitle">How macOS Bluetooth works (a fully closed <code>bluetoothd</code> + <code>IOBluetooth</code>/<code>CoreBluetooth</code> + <code>IOBluetoothFamily.kext</code> stack), why there is <em>zero</em> Apple open-source for it, why FreeBSD's ancient Netgraph stack can't do BLE, and what an Apple-shape Bluetooth path would actually require. Companion to the <ahref="nextbsd-wifi-research.html">WiFi management</a> and <ahref="freebsd-keychain-port-plan.html">Keychain</a> plans.</p>
87
+
<pclass="subtitle">How macOS Bluetooth works (a fully closed <code>bluetoothd</code> + <code>IOBluetooth</code>/<code>CoreBluetooth</code> + <code>IOBluetoothFamily.kext</code> stack), why there is <em>zero</em> Apple open-source for it, why FreeBSD's ancient Netgraph stack can't do BLE, and what an Apple-shape Bluetooth path would actually require. Companion to the <ahref="nextbsd-wlan-research.html">WLAN management</a> and <ahref="freebsd-keychain-port-plan.html">Keychain</a> plans.</p>
88
88
89
89
<sectionid="tldr" class="tldr">
90
90
<h3>TL;DR</h3>
91
91
<ul>
92
-
<li><strong>Apple's Bluetooth stack is the most closed part of the system.</strong>WiFi had one open piece (<code>eap8021x</code>); Keychain had published-but-unbuildable source. Bluetooth has <strong>nothing</strong> — no daemon source, no kext source, no framework implementation. Only the public API <em>headers</em> exist.</li>
92
+
<li><strong>Apple's Bluetooth stack is the most closed part of the system.</strong>WLAN had one open piece (<code>eap8021x</code>); Keychain had published-but-unbuildable source. Bluetooth has <strong>nothing</strong> — no daemon source, no kext source, no framework implementation. Only the public API <em>headers</em> exist.</li>
93
93
<li><strong>How it works:</strong> apps call <code>CoreBluetooth</code> (BLE/GATT) or <code>IOBluetooth</code> (Classic) → those proxy over XPC/Mach IPC to <strong><code>bluetoothd</code></strong>, the userspace management brain → which drives <code>IOBluetoothFamily.kext</code> → which speaks HCI to the controller. Same shape as <code>wifid</code>, mapped almost one-to-one.</li>
94
94
<li><strong>Plus a proprietary layer on top.</strong><code>MagicPairing</code> (iCloud-synced keys for AirPods / Magic peripherals) and the <code>Continuity</code> BLE-advertisement protocol (Handoff, AirDrop discovery, proximity pairing) are Apple-only protocols riding on standard HCI — documented only via reverse engineering.</li>
95
-
<li><strong>FreeBSD's side is the real problem.</strong> The Netgraph stack (<code>ng_hci</code>/<code>ng_l2cap</code>/<code>ng_btsocket</code> + <code>hcsecd</code>/<code>sdpd</code>/<code>bthidd</code>) dates to 2002 and supports <strong>Classic Bluetooth only — no BLE, no GATT, no SMP.</strong> Unlike WiFi, the gap is in the <em>kernel</em>, and there is no <code>wpa_supplicant</code>-equivalent BSD-licensed engine to lean on.</li>
96
-
<li><strong>Why this matters for the project:</strong> a CoreBluetooth-equivalent is fundamentally a <em>BLE/GATT</em> API, and FreeBSD can't do BLE. So an Apple-shape Bluetooth story needs a kernel/stack BLE effort <em>first</em> (extend Netgraph, port the GPL/Linux-bound BlueZ, or build a greenfield userland LE stack), then a <code>com.apple.bluetoothd</code> brain on top. Much heavier than WiFi. Out of scope now; documented so the option space is settled.</li>
95
+
<li><strong>FreeBSD's side is the real problem.</strong> The Netgraph stack (<code>ng_hci</code>/<code>ng_l2cap</code>/<code>ng_btsocket</code> + <code>hcsecd</code>/<code>sdpd</code>/<code>bthidd</code>) dates to 2002 and supports <strong>Classic Bluetooth only — no BLE, no GATT, no SMP.</strong> Unlike WLAN, the gap is in the <em>kernel</em>, and there is no <code>wpa_supplicant</code>-equivalent BSD-licensed engine to lean on.</li>
96
+
<li><strong>Why this matters for the project:</strong> a CoreBluetooth-equivalent is fundamentally a <em>BLE/GATT</em> API, and FreeBSD can't do BLE. So an Apple-shape Bluetooth story needs a kernel/stack BLE effort <em>first</em> (extend Netgraph, port the GPL/Linux-bound BlueZ, or build a greenfield userland LE stack), then a <code>com.apple.bluetoothd</code> brain on top. Much heavier than WLAN. Out of scope now; documented so the option space is settled.</li>
97
97
</ul>
98
98
</section>
99
99
100
100
<h2id="stack">1. How the closed Apple stack works</h2>
101
101
102
-
<p>macOS Bluetooth is layered exactly like the WiFi stack: a kernel driver family, a closed userspace management daemon that owns all the policy, and public framework facades that proxy to it over IPC. From the controller up:</p>
102
+
<p>macOS Bluetooth is layered exactly like the WLAN stack: a kernel driver family, a closed userspace management daemon that owns all the policy, and public framework facades that proxy to it over IPC. From the controller up:</p>
@@ -162,7 +162,7 @@ <h3 id="diagram">1.1 The architecture</h3>
162
162
| HCI (USB on Intel; custom transport on Apple Silicon)
163
163
v
164
164
+-----------+-----------+
165
-
| Bluetooth controller | (Broadcom/Apple combo Wi-Fi+BT silicon)
165
+
| Bluetooth controller | (Broadcom/Apple combo WLAN+BT silicon)
166
166
+-----------------------+</div>
167
167
168
168
<h3id="classic-vs-ble">1.2 Two frameworks because there are two Bluetooths</h3>
@@ -191,12 +191,12 @@ <h3 id="proprietary">1.4 The proprietary layer — MagicPairing & Continuity
191
191
<p>Beyond standard Bluetooth, <code>bluetoothd</code> implements two Apple-only protocols that are the actual "magic" and are <strong>entirely undocumented</strong> (known only through reverse engineering of <code>bluetoothd</code> strings and device firmware):</p>
192
192
<ul>
193
193
<li><strong>MagicPairing</strong> — Apple's proprietary pairing for AirPods and Magic Keyboard/Mouse/Trackpad. You pair once, and the keys sync via iCloud so the peripheral works on every device on your account. It rides on top of standard HCI (so it works with off-the-shelf radios) but is not part of any Bluetooth spec. TU Darmstadt's analysis reverse-engineered it from <code>bluetoothd</code> and the AirPods' RTKit firmware, and found ten security flaws across the iOS/macOS/RTKit implementations. (<ahref="https://arxiv.org/pdf/2005.07255">Heinze et al., MagicPairing, WiSec 2020</a>)</li>
194
-
<li><strong>Continuity</strong> — a family of <em>BLE advertisement</em> messages Apple devices broadcast for Handoff, AirDrop discovery, proximity pairing ("bring AirPods near your Mac"), Universal Clipboard, and instant hotspot. Reverse-engineered and catalogued by the <ahref="https://github.com/furiousMAC/continuity">furiousMAC/continuity</a> project. This is the BLE half of how Apple devices <em>find</em> each other before falling back to AWDL/WiFi for bulk transfer.</li>
194
+
<li><strong>Continuity</strong> — a family of <em>BLE advertisement</em> messages Apple devices broadcast for Handoff, AirDrop discovery, proximity pairing ("bring AirPods near your Mac"), Universal Clipboard, and instant hotspot. Reverse-engineered and catalogued by the <ahref="https://github.com/furiousMAC/continuity">furiousMAC/continuity</a> project. This is the BLE half of how Apple devices <em>find</em> each other before falling back to AWDL/WLAN for bulk transfer.</li>
195
195
</ul>
196
196
<p>Neither is portable — they depend on iCloud key infrastructure (MagicPairing) and the broader Continuity daemon ecosystem. Even with a perfect BLE stack, AirDrop-grade interop would require reimplementing these closed protocols.</p>
197
197
198
198
<h3id="keys">1.5 Where pairing keys live — the keychain tie-in</h3>
199
-
<p>Bluetooth bonding produces long-lived secrets (Classic link keys, BLE LTKs) that must persist across reboots and be available before login (so a paired keyboard works at the login window). On macOS these live in a mix of <code>com.apple.Bluetooth.plist</code> and keychain-protected storage. This is the same problem the <ahref="freebsd-keychain-port-plan.html">Keychain plan</a> addresses for WiFi PSKs: a <code>com.apple.bluetoothd</code> would want a <strong>system-scoped secret store</strong> for bond keys — exactly the System-keychain consumer that plan calls out. Bluetooth and WiFi both push toward the same <code>secd</code>-equivalent.</p>
199
+
<p>Bluetooth bonding produces long-lived secrets (Classic link keys, BLE LTKs) that must persist across reboots and be available before login (so a paired keyboard works at the login window). On macOS these live in a mix of <code>com.apple.Bluetooth.plist</code> and keychain-protected storage. This is the same problem the <ahref="freebsd-keychain-port-plan.html">Keychain plan</a> addresses for WLAN PSKs: a <code>com.apple.bluetoothd</code> would want a <strong>system-scoped secret store</strong> for bond keys — exactly the System-keychain consumer that plan calls out. Bluetooth and WLAN both push toward the same <code>secd</code>-equivalent.</p>
200
200
201
201
<h2id="oss">2. Open-source status — there is none</h2>
202
202
<p>This is the headline difference from every other component we've researched. Apple publishes <strong>no Bluetooth implementation at all.</strong></p>
@@ -209,7 +209,7 @@ <h2 id="oss">2. Open-source status — there is none</h2>
209
209
<tr><td>MagicPairing / Continuity</td><td><spanclass="yesno no">Closed</span></td><td>Undocumented proprietary protocols; only third-party reverse-engineering exists.</td></tr>
210
210
</tbody>
211
211
</table>
212
-
<divclass="gap"><strong>The spectrum, across everything we've looked at:</strong> Security/Keychain — framework source <em>published</em> (just unbuildable). WiFi — one component open (<code>eap8021x</code>). <strong>Bluetooth — nothing open; headers only.</strong> So there is no Apple code to even <em>study</em> for a port, let alone vendor. Any FreeBSD Bluetooth work is clean-room by necessity.</div>
212
+
<divclass="gap"><strong>The spectrum, across everything we've looked at:</strong> Security/Keychain — framework source <em>published</em> (just unbuildable). WLAN — one component open (<code>eap8021x</code>). <strong>Bluetooth — nothing open; headers only.</strong> So there is no Apple code to even <em>study</em> for a port, let alone vendor. Any FreeBSD Bluetooth work is clean-room by necessity.</div>
213
213
214
214
<h2id="layers">3. The protocol layers, explained</h2>
215
215
<p>Because "port Bluetooth" means rebuilding these layers, here's what each is — and which half (Classic / BLE) it belongs to.</p>
@@ -256,10 +256,10 @@ <h3>5.1 Why we can't just take BlueZ</h3>
256
256
<li><strong>Kernel coupling:</strong> BlueZ moved most of the host stack <em>into the Linux kernel</em> (the <code>bluetooth</code> subsystem: <code>AF_BLUETOOTH</code> sockets, the <code>mgmt</code> API, kernel L2CAP/SMP). <code>bluetoothd</code>(BlueZ) is a thin manager over that kernel stack — it does <em>not</em> contain a portable host stack. Porting it means porting or emulating the Linux kernel Bluetooth subsystem, not just building a daemon.</li>
257
257
<li><strong>IPC:</strong> D-Bus API, foreign to the Mach/DO world.</li>
258
258
</ul>
259
-
<p>So BlueZ gives you a manager whose engine lives in a kernel you don't have. There is no clean, BSD-licensed, net80211-style userland BLE engine to adopt — the single biggest difference from the WiFi situation.</p>
259
+
<p>So BlueZ gives you a manager whose engine lives in a kernel you don't have. There is no clean, BSD-licensed, net80211-style userland BLE engine to adopt — the single biggest difference from the WLAN situation.</p>
260
260
261
261
<h2id="path">6. What an Apple-shape Bluetooth path would require</h2>
262
-
<p>Unlike WiFi (where the kernel was ready and only a userland brain was needed), Bluetooth needs the <strong>kernel/stack BLE layer built first</strong>. Three ways to get there:</p>
262
+
<p>Unlike WLAN (where the kernel was ready and only a userland brain was needed), Bluetooth needs the <strong>kernel/stack BLE layer built first</strong>. Three ways to get there:</p>
@@ -297,22 +297,22 @@ <h3 id="hypothetical">6.1 The hypothetical <code>com.apple.bluetoothd</code></h3
297
297
- (NSData *)value;
298
298
- (void)setNotifyValue:(BOOL)enabled;
299
299
@end</code></pre>
300
-
<p>Backed by the chosen engine for the actual GATT/SMP work, persisting bond keys in the <ahref="freebsd-keychain-port-plan.html">System keychain</a>. This is the direct analog of <code>wifid-fbsd</code> — a thin Apple-shape brain over a protocol engine — except the engine has to be built, not adopted.</p>
300
+
<p>Backed by the chosen engine for the actual GATT/SMP work, persisting bond keys in the <ahref="freebsd-keychain-port-plan.html">System keychain</a>. This is the direct analog of <code>wland</code> — a thin Apple-shape brain over a protocol engine — except the engine has to be built, not adopted.</p>
301
301
302
302
<h2id="continuity">7. The AirDrop / Continuity tie-in</h2>
303
-
<p>Bluetooth isn't independent of the WiFi work. Apple's proximity magic is a <strong>two-radio</strong> dance:</p>
303
+
<p>Bluetooth isn't independent of the WLAN work. Apple's proximity magic is a <strong>two-radio</strong> dance:</p>
304
304
<divclass="ascii-diagram"> Discovery / signalling Bulk transfer
305
305
----------------------- -----------------------
306
-
BLE Continuity adverts ---> AWDL (Wi-Fi peer-to-peer)
307
-
(this doc's gap) (WiFi doc's gap)
306
+
BLE Continuity adverts ---> AWDL (WLAN peer-to-peer)
307
+
(this doc's gap) (WLAN doc's gap)
308
308
| |
309
309
+------- AirDrop / Handoff ------+</div>
310
310
<ul>
311
311
<li><strong>BLE</strong> handles <em>discovery</em> — devices broadcast Continuity advertisements so a nearby Mac knows an iPhone is there and offering AirDrop.</li>
312
-
<li><strong>AWDL</strong> (the WiFi plan's gap) handles the <em>high-speed transfer</em> once discovery completes.</li>
312
+
<li><strong>AWDL</strong> (the WLAN plan's gap) handles the <em>high-speed transfer</em> once discovery completes.</li>
313
313
<li><strong>Bonjour/mDNS</strong> (the <ahref="freebsd-mdnsresponder-plan.html">mDNSResponder plan</a>) names the services.</li>
314
314
</ul>
315
-
<p>So full AirDrop interop requires <em>all three</em> gaps closed — BLE (here), AWDL (WiFi), and Bonjour — plus the closed Continuity/MagicPairing protocols reimplemented. That makes AirDrop a long-horizon, cross-cutting goal, not a single deliverable. The realistic near-term scope here is <strong>standard BLE</strong> (connect to a heart-rate monitor, a BLE keyboard, a sensor) — not Apple-proprietary peer interop.</p>
315
+
<p>So full AirDrop interop requires <em>all three</em> gaps closed — BLE (here), AWDL (WLAN), and Bonjour — plus the closed Continuity/MagicPairing protocols reimplemented. That makes AirDrop a long-horizon, cross-cutting goal, not a single deliverable. The realistic near-term scope here is <strong>standard BLE</strong> (connect to a heart-rate monitor, a BLE keyboard, a sensor) — not Apple-proprietary peer interop.</p>
316
316
317
317
<h2id="open">8. Open questions</h2>
318
318
<divclass="open-q"><strong>Q1. Is BLE actually needed soon?</strong> Classic (existing Netgraph) already covers Bluetooth keyboards/mice/audio for a desktop. BLE matters for modern peripherals, watches, trackers, and Continuity. Is there a concrete near-term consumer, or is Classic-only acceptable for now?</div>
<li><strong>CoreBluetooth API reference:</strong><ahref="https://developer.apple.com/documentation/corebluetooth">developer.apple.com/documentation/corebluetooth</a></li>
330
330
<li><strong>FreeBSD Bluetooth handbook:</strong><ahref="https://docs.freebsd.org/en/books/handbook/network/#network-bluetooth">docs.freebsd.org — Bluetooth</a> (<code>ng_bluetooth</code>, <code>hcsecd</code>, <code>sdpd</code>, <code>bthidd</code>)</li>
331
331
<li><strong>BlueZ (Linux stack, for contrast):</strong><ahref="http://www.bluez.org/">bluez.org</a></li>
0 commit comments