Skip to content

docs: "FF FF FE FF" notification request delivers no battery on AirPods Pro 2 (A2698); FF FF FF FF does #770

Description

@flipbytes-dk

Summary

docs/AAP Definitions.md documents two notification-request packets and says of the first:

04 00 04 00 0F 00 FF FF FE FF

This packet also works.

On AirPods Pro 2 (Lightning), model A2698, firmware 81.2675000075000000.6877 it does not — it produces no battery notifications at all, while the FF FF FF FF variant produces them in under a second.

The doc is headed "As per AirPods Pro 2 (USB-C) Firmware 7A305", so this is most likely a model/firmware difference rather than a plain error. But as written the claim is unqualified, and following it leads you to conclude that battery reporting is broken on your firmware rather than that you sent the wrong subscribe packet.

Measurement

Same device, same session, same handshake (00 00 04 00 01 00 02 00 00 00 00 00 00 00 00 00) and same 4D set-features packet. Only the last two bytes of the notification request differ.

Notification request Battery packets Other notifications
04 00 04 00 0F 00 FF FF FE FF 0 in 70 s 11 ear-detection events
04 00 04 00 0F 00 FF FF FF FF first at 0.94 s, then unprompted yes

The eleven ear-detection events on the FE run are the important control: the L2CAP link was up and the device was actively notifying, so this is not a dead socket or a failed handshake. It subscribes to something, just not to battery.

Reproduced across several runs with a minimal stdlib-Python L2CAP client (no library involved), so it is not an artifact of the daemon.

Suggested change

Qualify the line, e.g.:

This packet also works on AirPods Pro 2 (USB-C) firmware 7A305, but does not deliver battery notifications on all models — AirPods Pro 2 (A2698, firmware 81.2675…6877) returns none. Prefer 04 00 04 00 0F 00 FF FF FF FF.

Happy to open a PR if that wording is close to what you'd want.

Environment

  • AirPods Pro 2, model A2698, firmware 81.2675000075000000.6877
  • Arch Linux, BlueZ 5.87, kernel 7.1.9
  • Direct L2CAP on PSM 0x1001, Python stdlib AF_BLUETOOTH/SOCK_SEQPACKET

Thanks for the doc — reverse-engineering from it was otherwise completely straightforward, and everything else in it matched what I saw on the wire byte for byte.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions