From 1b2010f9397df450d405e011efe41a0d2e6677cf Mon Sep 17 00:00:00 2001 From: Seb3thehacker Date: Wed, 30 Sep 2026 13:28:29 -0700 Subject: [PATCH] car rejection leason logging --- .gitignore | 3 ++- .../seb3thehacker/gearslip/GearslipRunner.kt | 25 +++++++++++++++++++ .../seb3thehacker/gearslip/SessionReport.kt | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9a36ebc..1e4e04f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,5 @@ CLAUDE.md *.pdf extraction/ .claude/ -todo \ No newline at end of file +todo +logs/ \ No newline at end of file diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt index 007aa80..1681a40 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt @@ -175,11 +175,34 @@ class GearslipRunner( MSG_AUTH_COMPLETE -> onAuthComplete(body) MSG_SERVICE_DISCOVERY_RESPONSE -> onServiceDiscoveryResponse(body) MSG_PING_REQUEST -> onPingRequest(body) + MSG_BYEBYE_REQUEST -> onByeByeRequest(body) AudioLink.MSG_FOCUS_RESPONSE -> audioLink?.onFocus(Protobuf.readInt32Field(body, 1) ?: 0) else -> log.i("unhandled control message id=$messageId (${body.size} bytes) - continuing") } } + /** + * The head unit asking to end the session. It drops USB a few seconds later whether or not + * we answer, so the point here is the reason: an Audi MIB2+ sent this about a second after + * video started, every time, and the old build logged it only as "id=15". + */ + private fun onByeByeRequest(body: ByteArray) { + val reason = Protobuf.readInt32Field(body, 1) + val name = when (reason) { + 1 -> "USER_SELECTION" + 2 -> "DEVICE_SWITCH" + 3 -> "NOT_SUPPORTED" + 4 -> "NOT_CURRENTLY_SUPPORTED" + 5 -> "PROBE_SUPPORTED" + else -> "unknown" + } + log.w("<- ByeByeRequest: reason=$reason ($name) in state $state") + log.hex(" byebye raw", body) + SessionReport.fail(SessionReport.Category.BYEBYE, "ByeByeRequest reason=$reason ($name)", state.name) + send(MSG_BYEBYE_RESPONSE, ByteArray(0), encrypted = true) + log.i("-> ByeByeResponse") + } + private fun onVersionRequest(body: ByteArray) { if (body.size < 4) { log.w("VersionRequest too short (${body.size} bytes)") @@ -903,6 +926,8 @@ class GearslipRunner( const val MSG_SERVICE_DISCOVERY_RESPONSE = 6 const val MSG_PING_REQUEST = 11 const val MSG_PING_RESPONSE = 12 + const val MSG_BYEBYE_REQUEST = 15 + const val MSG_BYEBYE_RESPONSE = 16 const val MSG_CHANNEL_OPEN_REQUEST = 7 const val MSG_CHANNEL_OPEN_RESPONSE = 8 diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/SessionReport.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/SessionReport.kt index 7b43c68..53ff774 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/SessionReport.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/SessionReport.kt @@ -23,6 +23,7 @@ object SessionReport { AUTH("authentication failed"), SERVICE_DISCOVERY("service discovery failed"), VIDEO("video stream failed"), + BYEBYE("head unit ended the session"), CRASH("app crash"), UNKNOWN("unclassified"), }