MousePods, AirPods 3 센서 데이터를 리눅스 마우스 입력으로 연결
Matteo Gaudioso(@starman-tech)의 MousePods는 AirPods 3의 RemoteHID 모션 데이터를 읽어 Linux에서 커서 조작용 가상 마우스 입력으로 바꿉니다. 작성자가 Ubuntu 24.04·BlueZ 5.72에서 측정한 센서 속도는 최대 약 210Hz였지만, Bluetooth 연결을 공유할 때 데이터 간격이 벌어져 저장소는 100Hz를 권합니다. OpenTrack·가상 조이스틱 출력도 마련됐지만 게임 안에서의 동작은 아직 시험하지 않았습니다.

리눅스에 연결한 AirPods 3는 일반 Bluetooth 이어폰으로 음악을 재생하지만, 머리 움직임을 추적하는 관성 센서(IMU) 데이터는 오디오 연결만으로 드러나지 않았습니다. Reddit 계정 Matteocean으로 활동하는 Matteo Gaudioso(@starman-tech)는 이 데이터를 커서 조작에 쓰는 오픈소스 프로그램 MousePods를 공개했습니다. 그는 Claude Code가 코드 대부분을 작성했고, 실제 AirPods를 시험하며 주요 판단을 내린 일은 자신이 맡았다고 Reddit에 적었습니다. 해결의 핵심은 AirPods 3의 센서 통신 방식을 찾아 Linux의 Bluetooth 수신 설정을 맞춘 데 있습니다.
AirPods Pro 2·3·4와 AirPods 4는 센서 데이터를 SensorDataWX 방식으로 전달하지만, AirPods 3는 이 방식에 응답하지 않습니다. 대신 AACP 연결의 기존 RTBuddy 채널 0x800에서 Apple의 RemoteHID를 사용해 센서를 가상 HID 장치로 제공합니다. RemoteHID는 센서별 장치를 열거하고 HID 보고서 요청으로 데이터를 전달합니다. MousePods는 L2CAP의 PSM 0x1001에 연결해 HostConnect를 보내고, AirPods가 DeviceConnect 응답에 실어 보내는 각 센서의 HID 설명자를 받습니다.
Linux의 기본 L2CAP 수신 MTU는 672바이트입니다. AirPods 3가 연결 초기에 보내는 모션 센서 설명자는 이보다 커서 기본 설정에서는 센서 장치가 호스트에 나타나지 않습니다. 저장소에 기록된 설명자 크기는 가속도계 820바이트, 자이로스코프 819바이트, 융합 모션 장치 833바이트입니다. MousePods는 수신 MTU를 iOS에서 사용하는 값인 2582바이트로 요청해 이 센서들이 열거되도록 합니다.
장치가 나타난 뒤에는 MousePods가 SetReport의 feature 1에 센서 보고 간격을 마이크로초 단위로 지정합니다. 그러면 AirPods가 InputReport로 데이터를 보내기 시작합니다. 통합 모션 데이터에는 이어버드의 자세를 나타내는 쿼터니언과 각속도, 사용자 가속도, 중력 벡터가 담깁니다. 가속도계와 자이로스코프의 원시 보고도 별도로 받을 수 있습니다.
MousePods는 쿼터니언을 이용해 yaw·pitch·roll 각도를 계산한 뒤 Linux의 uinput 가상 입력 장치로 전달합니다. 운영체제는 이를 마우스로 인식하므로 사용자는 고개를 돌리거나 기울여 커서를 움직일 수 있습니다. 앱에는 센서 상태를 보는 화면과 보정 기능도 포함돼 있습니다. 실행에는 BlueZ를 사용하는 Linux, 페어링해 연결한 AirPods, /dev/uinput 쓰기 권한이 필요합니다. 저장소는 대부분의 데스크톱 배포판에서 로그인 사용자에게 이 권한을 부여하며, root 없이 실행할 수 있다고 안내합니다. AirPods 3의 센서는 이어버드가 케이스 안에 있으면 꺼집니다.
센서 주파수는 요청한 보고 간격에 따라 달라집니다. 작성자가 AirPods 3, Ubuntu 24.04, BlueZ 5.72에서 측정한 값은 10,000마이크로초 간격에서 약 110Hz, 5,000마이크로초 이하에서 최대 약 210Hz였습니다. A2DP 오디오와 BLE 마우스가 Bluetooth 연결을 함께 쓰는 상태에서 약 180Hz로 측정했을 때는 23초 동안 데이터 간격이 50밀리초를 넘는 경우가 12번 있었습니다. 저장소는 이런 연결 상황의 기본 운용값으로 100Hz를 권합니다.
저장소에는 머리 방향을 OpenTrack에 UDP로 보내거나 가상 조이스틱으로 출력하는 기능도 있습니다. OpenTrack을 거치면 TrackIR·FreeTrack 입력을 쓰는 게임에 연결할 수 있고, 가상 조이스틱은 카메라 방향을 조이스틱 축에 지정하는 Linux 게임을 겨냥합니다. 저장소는 UDP 패킷 형식과 조이스틱, 각도 계산을 테스트했고, 쿼터니언도 실제 캡처 데이터와 대조했다고 밝혔습니다. 게임 안에서의 동작은 아직 시험하지 않았습니다. 추적은 회전만 다루는 3자유도 방식이라 몸의 위치 이동은 측정하지 않으며, 절대 방향 기준이 없는 yaw는 사용 중 다시 중심을 맞춰야 합니다.
참고 자료
- Someone used Claude Code to reverse-engineer the Apple AirPods 3, and now head-tracking works on Linux
- used claude code to figure out how airpods 3 send head tracking data, turns out nobody had done it before : r/ClaudeAI
- GitHub - starman-tech/mousepods: Your AirPods are a mouse: AirPods 3 head tracking on Linux, and the first public documentation of Apple RemoteHID (HID over AACP) · GitHub
- mousepods/docs/DISCOVERIES.md at main · starman-tech/mousepods · GitHub
- mousepods/docs/SIMS.md at main · starman-tech/mousepods · GitHub