darken bd4d87c06a feat(aap): Add Custom EQ protocol support
Adds decode and encode for AAP opcode 0x63, Apple's iOS 27 "Custom EQ"
(three bands plus a Recommended/Custom mode selector, H2 models).

The wire format comes from librepods commit 7341e41 and has never been
confirmed on hardware, so the decoder validates every field and returns
null on any mismatch -- including a strict payload-length equality, so a
frame carrying trailing unknown bytes is surfaced verbatim in the
unknown-message hex log rather than mis-parsed into plausible values.
Nothing optimistically assumes the write lands: SetCustomEq deliberately
has no optimistic state update and no verification predicate, because an
unacknowledged write must not render as success, and the device is not
known to report this setting at all.

Also recovers two bytes the 0x53 decoder was discarding. Opcode 0x53 is
the Headphone Accommodations configuration -- an iOS Accessibility
feature that the iOS 18.1+ hearing-aid feature reuses -- and payload
bytes 4 and 5 are its "Apply To: Phone / Media" flags. They are plain
0x01 flags, not the Apple-bool 0x01/0x02 encoding used by the 0x09
control settings. They describe scope only and say nothing about whether
a profile exists, so isAllZero stays a pure band-data predicate.

A debug-only card (BuildConfig.DEBUG, mirroring the existing PME chart)
drives the opcode for hardware evaluation. It edits local draft state and
sends exactly one packet per Apply tap; slider-driven sends would flood
the link and make a logcat observation window unreadable. Apply is
disabled while no pod is worn, because AapOutboundController queues
non-exempt commands in that state and the queue collapses repeats,
surfacing them later at an unrelated moment. That guard reads the AAP
EarDetection setting rather than PodDevice's BLE-fallback property, so it
matches the controller's gate in every state -- notably, neither gates
when the AAP setting is absent.

On-device evaluation, both legs negative: AirPods Pro 2 USB-C (A3048,
fw 81.2675000075000000.6814) and AirPods Pro 3 (A3064, fw ...6503)
never advertise 0x63 across settings bursts of 33 and 26 frames, never
echo a write, never persist one across a case-cycle reconnect, and
produce no audible change. Both accept the write at the socket and
discard it. This does not establish that the byte format is wrong -- a
device ignoring an unimplemented opcode is indistinguishable from one
rejecting a malformed frame -- and it is not evidence that privileged
access is required, since neither device advertises the feature at all.
2026-08-21 15:23:32 +02:00
2025-03-19 22:29:09 +01:00
2025-03-19 22:30:14 +01:00
2021-12-28 17:11:50 +01:00
2021-12-28 17:11:50 +01:00
2021-12-28 17:12:27 +01:00
2025-03-21 19:36:03 +01:00
2026-08-16 19:51:18 +00:00
2026-08-16 19:51:18 +00:00

CAPod banner

Companion App for AirPods (CAPod)

GitHub release (latest SemVer including pre-releases) RB Status Code tests & eval Crowdin Github Downloads Google Play Downloads

A companion app that adds support for AirPod specific features to Android:

  • Battery level for pods & cases.
  • Charging status for pods & case.
  • Additional infos about connection, microphone & case.
  • Can receive and show all nearby devices.
  • Ear detection with automatic play/pause.
  • Automatically connect phone & AirPods.
  • Show popup when case is opened.
  • Widgets

CAPod is ad-free. Some additional features require an in-app purchase.

Currently supported models:

  • AirPods 1. Generation
  • AirPods 2. Generation
  • AirPods 3. Generation
  • AirPods 4. Generation
  • AirPods 4. Generation with ANC
  • AirPods Pro 1. Generation
  • AirPods Pro 2. Generation
  • AirPods Pro 2. Generation (USB-C)
  • AirPods Pro 3. Generation
  • AirPods Max
  • AirPods Max (USB-C)
  • AirPods Max 2. Generation
  • Power Beats Pro
  • Power Beats Pro 2
  • Power Beats 3
  • Power Beats 4
  • Beats Solo 3
  • Beats Solo Pro
  • Beats Solo 4
  • Beats Solo Buds
  • Beats Studio 3
  • Beats Studio Buds
  • Beats Studio Buds+
  • Beats Studio Pro
  • Beats X
  • Beats Flex
  • Beats Fit Pro
  • Fake AirPods 1. Generation 🎭
  • Fake AirPods 2. Generation 🎭
  • Fake AirPods 3. Generation 🎭
  • Fake AirPods Pro1 🎭
  • Fake AirPods Pro2 🎭

Download

Source Status
Google Play https://play.google.com/store/apps/details?id=eu.darken.capod
Google Play Beta https://play.google.com/apps/testing/eu.darken.capod
Github (Release) https://github.com/d4rken-org/capod/releases
Github (Pre-Release) https://github.com/d4rken-org/capod/releases
F-Droid https://f-droid.org/en/packages/eu.darken.capod/
F-Droid (IzzyOnDroid) https://apt.izzysoft.de/packages/eu.darken.capod/

Support the project

Get help

Screenshots

Thanks to

  • The OpenPods project, specifically @adolfintel and @Electric1447
  • Martin, Jeremy & Alpuche, Douglas & Bodeman, Kristina & Brown, Lamont & Fenske, Ellis & Foppe, Lucas & Mayberry, Travis & Rye, Erik & Sipes, Brandon & Teplov, Sam. (2019). Handoff All Your Privacy A Review of Apples Bluetooth Low Energy Continuity Protocol. Proceedings on Privacy Enhancing Technologies. 2019. 34-53. 10.2478/popets-2019-0057.
  • Celosia, Guillaume. (2020). Privacy Challenges in Wireless Communications of the Internet of Things.
  • The MagicPods project. If you are looking for "CAPod for Windows", check it out.
  • @kavishdevar and his LibrePods project for sharing a lot of cool stuff.
  • Crowdin for supporting open-source projects.

License

CAPod's code is available under a GPL v3 license, this excludes:

  • CAPod icons, logos, mascots and marketing materials/assets.
  • CAPod animations and videos.
  • CAPod documentation.
  • Google Play screenshots.
  • Google Play texts & descriptions.
  • Translations.
Languages
Kotlin 99.1%
Shell 0.8%