mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-15 10:46:12 -04:00
feat: Add AAP session tests for AirPods Pro 2 USB-C
Add AirPodsPro2UsbcAapSessionTest with real captured bytes from a live device session (model A3048, Pixel 8, 2026-04-02). Covers handshake, device info, battery states, private keys, all Pro 2 USB-C settings (including ADAPTIVE ANC, VolumeSwipe, ConversationalAwareness), ear detection across 6 transitions, and unhandled messages. Also document ChargingState observations across models and EndCallMuteMic subtype variations in code comments.
This commit is contained in:
@@ -75,12 +75,14 @@ data class AapPodState(
|
||||
}
|
||||
|
||||
enum class ChargingState(val wireValue: Int) {
|
||||
// Pro 1 sends 0x00 transiently when a pod is first removed from the case (reverts to NOT_CHARGING within seconds).
|
||||
// Pro 2 USB-C skips this and reports NOT_CHARGING immediately. Likely a firmware timing difference.
|
||||
UNDEFINED(0x00),
|
||||
CHARGING(0x01),
|
||||
NOT_CHARGING(0x02),
|
||||
DISCONNECTED(0x04),
|
||||
// TODO: Observed on AirPods Pro 3 in charging case. Possibly Apple's "Optimized Battery Charging" limit.
|
||||
// Verify behavior with Pro 2 and Pro 1 to confirm whether this is model-specific or firmware-specific.
|
||||
// Observed on Pro 3 and Pro 2 USB-C in charging case. Apple's "Optimized Battery Charging" feature.
|
||||
// Not observed on Pro 1 (firmware 51.9.6) — may require newer firmware or hardware.
|
||||
CHARGING_OPTIMIZED(0x05),
|
||||
;
|
||||
|
||||
|
||||
+3
-1
@@ -324,7 +324,9 @@ class DefaultAapDeviceProfile(
|
||||
AapSetting.EndCallMuteMic::class to AapSetting.EndCallMuteMic(muteMic, endCall)
|
||||
}
|
||||
0x00, 0x20 -> {
|
||||
// Alternate/compact response format: byte 2 is a combined mode value
|
||||
// Compact response format: byte 2 is a combined mode value.
|
||||
// 0x00: observed on Pro 1 (fw 51.9.6, 2026-04-02) and Pro 2 USB-C (fw 81.x, 2026-04-02) and Pro 3.
|
||||
// 0x20: observed on Pro 1 (fw 51.9.6, 2026-03-31). Same device can send either subtype across sessions.
|
||||
val combined = payload[2].toInt() and 0xFF
|
||||
val (muteMic, endCall) = when (combined) {
|
||||
0x02 -> AapSetting.EndCallMuteMic.MuteMicMode.SINGLE_PRESS to AapSetting.EndCallMuteMic.EndCallMode.DOUBLE_PRESS
|
||||
|
||||
Reference in New Issue
Block a user