Experimental AirPods head-tracking bridge for Windows. It uses the third-party
MagicAAP kernel driver to reach Apple's Bluetooth Classic AAP channel, starts
the devmotion6 sensor service, decodes the fused orientation quaternion, and
sends an OpenTrack-compatible UDP pose.
This project is not affiliated with or endorsed by Apple, MagicPods, or OpenTrack. It does not contain or install the MagicAAP driver.
| Device | Model | Firmware | Start format |
|---|---|---|---|
| AirPods Max 2 | A3454 / Bluetooth PID 0x202D |
8E258 | max2 |
This is the only hardware and firmware combination tested so far. It streams motion at about 50 Hz using dynamically advertised RTBuddy service ID 6.
The decoder also understands the public service-14 and service-16 packet variants. These devices have head-motion hardware, but have not been tested with this Windows bridge:
- AirPods 3 and AirPods 4
- AirPods Pro 1, AirPods Pro 2, and AirPods Pro 3
- AirPods Max 1, Lightning and USB-C
- Beats models that support dynamic head tracking
Try --start-format devmotion6, --start-format alternate, or
--start-format legacy when testing one of those devices. Firmware may assign a
different RTBuddy service ID or use a different report layout, so inclusion in
this list is not a compatibility guarantee. AirPods 1 and AirPods 2 are not
expected to work because Apple does not list them as supporting head tracking.
Apple's current motion-capable AirPods families are listed in its head-tracking guide.
- A 64-bit Windows PC. Windows 11 is tested; the project targets Windows 10 version 1809 or newer.
- A Bluetooth adapter with Bluetooth Classic support.
- AirPods paired to Windows and worn while tracking.
- The MagicAAP driver installed. MagicPods 2.0.97 was used during development.
- The .NET 9 SDK to build and run the source.
- OpenTrack for game integration.
MagicAAP is a kernel driver. Follow its maintainer's current installation instructions and warnings; this project neither redistributes nor modifies it. Driver installation may require administrator access, Windows Test Mode, or a compatible signed build. Running AAP Head Tracker itself does not require administrator access after the driver is installed.
Only one application should consume the MagicAAP stream at a time. Fully exit MagicPods or stop its background process if the driver interface is busy. Also disconnect competing Apple devices while troubleshooting; development was done with the paired iPhone's Bluetooth disabled.
Clone and enter the repository:
git clone https://github.com/FIocker/aap-head-tracker.git
cd aap-head-trackerBuild:
dotnet buildIn OpenTrack, select UDP over network as the input and use port 4242.
Then start the bridge:
dotnet run -- bridgeThe defaults select the confirmed AirPods Max 2 exchange. Keep your head facing forward for the first half second while 25 samples establish the neutral pose. Press Ctrl+C to stop; the bridge sends an explicit sensor stop command before closing.
The UDP datagram is exactly 48 bytes: six little-endian doubles in the order
x, y, z, yaw, pitch, roll. Translation is zero and rotation is in degrees.
List the MagicAAP interfaces:
dotnet run -- listRun an eight-second probe and save the raw traffic:
dotnet run -- probe --seconds 8 --dump--dump writes a timestamped .hexlog under the build output directory. Raw
AAP traffic can contain Bluetooth addresses and device metadata. Capture files
are ignored by Git and should be redacted before sharing.
Show every command and experimental protocol option:
dotnet run -- --helpAirPods do not expose the Android Head Tracker HID protocol used by projects
such as Sony Head Tracker. AAP runs over Bluetooth Classic L2CAP PSM 0x1001,
which normal Windows applications cannot open directly. MagicAAP supplies the
kernel profile driver and exposes a device interface that this application can
open with ReadFile and WriteFile.
The Max 2 breakthrough was service discovery. Firmware 8E258 advertises
AccessoryService=devmotion6 as dynamic RTBuddy service ID 6 with a 191-byte
maximum report size. Public experiments using service 16 therefore did not
start this firmware's stream.
The working 50 Hz start command is:
04 00 04 00 17 00 00 00 10 00 10 00 08 98 01 42 0B 08 06 10 02 1A 05 01 20 4E 00 00
The matching stop command is:
04 00 04 00 17 00 00 00 10 00 10 00 08 9A 01 42 0B 08 06 10 02 1A 05 01 00 00 00 00
Each streamed report contains signed Q15 quaternion x, y, and z
components. The decoder reconstructs positive w, normalizes the quaternion,
removes the calibrated neutral orientation, and converts it to the
Max-2-validated OpenTrack yaw/pitch/roll axes. Rotating the report's gravity
vector by that quaternion held world gravity nearly constant across 1,468 live
motion samples.
- LibrePods supplied foundational AAP packet documentation and the legacy head-tracking exchanges.
- apple-wireshark RTBuddy supplied the protobuf grammar and service names.
- AirPods RTBuddy probe
clarified current
SensorDataWXservice settings. - The iOS 26.1 pseudocode archive helped identify the fused device-motion fields.
- Sony Head Tracker inspired this project and documents the OpenTrack six-double UDP contract. No Sony Head Tracker source code is included.
GPL-3.0-only. See LICENSE.