librepods-org / librepods-org/librepods

linux/rust: AirPods Pro 2 UI works but logs repeated “Expected AirPodsInformation … got something else” and IRK errors

Open
#288 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
29.9k
Forks
1.7k
PR merge metrics
No merged PRs in 30d

Description

Summary

On Ubuntu 24.04.3 with AirPods Pro 2, the Rust Linux client works (noise control, ANC, conversation awareness toggles etc.), but the logs show repeated errors such as:

Expected AirPodsInformation for device , got something else

Device information is not AirPods for adding LE IRK / LE encryption key

UI behaviour appears correct, but these errors suggest some state mismatch between the AACP device info and the UI/device registry.

Environment:
OS: Ubuntu 24.04.3 LTS x86_64
Kernel: 6.14.0-35-generic
DE: GNOME 46.0
WM: Mutter
Theme: Yaru [GTK2/3]
CPU: 12th Gen Intel i7-12650H
GPU: Intel Alder Lake-P GT1 [UHD Graphics]
GPU: NVIDIA GeForce RTX 3050 Mobile
LibrePods:
  • Branch: linux/rust
  • Built with: cargo build --release in linux-rust/
  • Run with: RUST_LOG=librepods=info ./target/release/librepods
Device:
  • AirPods Pro 2 (A3047/A3048 class)
  • Connected via GNOME Bluetooth, used as audio output
Steps to reproduce:
  • Boot Ubuntu, ensure Bluetooth is on.
  • Open AirPods case, put both buds in ears.
  • In GNOME Bluetooth, connect the AirPods Pro.
  • Start the Rust client:
RUST_LOG=librepods=info ./target/release/librepods

The app finds the already-connected AirPods and initialises AACP:

Found connected AirPods: AirPods Pro, initializing.
Creating new AirPodsDevice for AC:07:75:D5:90:F3
AACPManager connecting to ... PSM 0x1001...
L2CAP connection established ...
  • Click the device in the left sidebar (it initially shows as the MAC address).
  • The main pane now shows the full AirPods view (Name, Listening Mode, Personalized Volume, Conversation Awareness, Off Listening Mode).
  • Change Listening Mode between Off / Noise Cancellation / Transparency / Adaptive etc.
  • Toggle Personalized Volume, Conversation Awareness, and Off Listening Mode.
Expected behaviour:
  • UI shows AirPods controls and sends AACP commands.
  • Logs show corresponding Received Control Command: ListeningMode, value: X etc.
  • No persistent errors about AirPodsInformation or LE keys once the device is successfully initialised.
Actual behaviour:
  • Functionally everything works:
    • Noise control mode changes are audible.
    • Personalized volume / Conversation awareness toggles work.
    • Tray menu controls also work and update logs accordingly.
  • But the log is filled with errors whenever the device is selected or settings are changed:
[INFO  librepods::bluetooth::aacp] Received Battery Info: [BatteryInfo { component: Right, level: 99, status: NotCharging }, BatteryInfo { component: Left, level: 99, status: NotCharging }, BatteryInfo { component: Case, level: 0, status: Disconnected }]
[ERROR librepods::ui::airpods] Expected AirPodsInformation for device AC:07:75:D5:90:F3, got something else
[ERROR librepods::ui::airpods] Expected AirPodsInformation for device AC:07:75:D5:90:F3, got something else
...
[INFO  librepods::bluetooth::aacp] Received Control Command: ListeningMode, value: 02
[ERROR librepods::ui::airpods] Expected AirPodsInformation for device AC:07:75:D5:90:F3, got something else
  • On startup (after deleting ~/.local/share/librepods/devices.json), IRK / ENC key handling also logs:
[INFO  librepods::bluetooth::aacp] Received Proximity Keys Response: [(1, "..."), (4, "...")]
[ERROR librepods::bluetooth::aacp] Device information is not AirPods for adding LE IRK.
[ERROR librepods::bluetooth::aacp] Device information is not AirPods for adding LE encryption key.

So AACP initialisation and control commands succeed, but some internal structure used by the UI and LE key store seems to be DeviceInformation::Other() instead of DeviceInformation::AirPods() for this MAC.

Additional observation – case battery level:

Case battery reporting looks a bit odd:

With both buds in ear:

BatteryInfo { component: Case, level: 0, status: Disconnected }

With one bud in the case (lid open):

BatteryInfo { component: Left,  level: 97, status: NotCharging }
BatteryInfo { component: Right, level: 97, status: Charging }
BatteryInfo { component: Case,  level: 255, status: Disconnected }

So the buds’ levels and statuses are correct, but the case reports status: Disconnected with level: 255, which looks like a sentinel “no reading” value. Not sure if the UI intends to special-case 255 here.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the documented Ubuntu and AirPods setup, then inspect the librepods::ui::airpods and librepods::bluetooth::aacp paths involved in device information and LE key handling. Compare the device registry state with the successful AACP connection, and verify the intended handling of the case battery value 255; done means the controls still work without the repeated type errors or spurious key errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
linux, rust
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.