From c7077f2a5704aec7508d2fd44175a3082e1c331f Mon Sep 17 00:00:00 2001 From: Seb3thehacker Date: Thu, 15 Oct 2026 10:43:32 -0700 Subject: [PATCH] version: answer 1.7 to head units offering 4.x and 6.x too, as they accept it --- .../java/app/seb3thehacker/gearslip/ProtocolVersion.kt | 8 ++++++-- .../seb3thehacker/gearslip/ConnectionLifecycleTest.kt | 4 ++-- .../app/seb3thehacker/gearslip/ProtocolVersionTest.kt | 9 +++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/ProtocolVersion.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/ProtocolVersion.kt index ea7b906..2a063c2 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/ProtocolVersion.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/ProtocolVersion.kt @@ -1,6 +1,10 @@ package app.seb3thehacker.gearslip -/** Advertises our supported 1.x version, as Android Auto does for older head units. */ +/** + * Advertises our supported 1.x version, as Android Auto does for older head units. Head units that + * offer a newer major version (LIVI asks for 6.1, a RAV4 and the DHU for 4.2) still accept a 1.x + * answer, so only a major version of 0 is refused. + */ internal object ProtocolVersion { data class Response(val major: Int, val minor: Int, val supported: Boolean) { val bytes: ByteArray get() = byteArrayOf( @@ -9,5 +13,5 @@ internal object ProtocolVersion { ) } - fun respond(major: Int, minor: Int): Response = Response(1, 7, major == 1 && minor in 0..0xffff) + fun respond(major: Int, minor: Int): Response = Response(1, 7, major >= 1 && minor in 0..0xffff) } diff --git a/gearslip/src/test/java/app/seb3thehacker/gearslip/ConnectionLifecycleTest.kt b/gearslip/src/test/java/app/seb3thehacker/gearslip/ConnectionLifecycleTest.kt index 186cc68..5575ad6 100644 --- a/gearslip/src/test/java/app/seb3thehacker/gearslip/ConnectionLifecycleTest.kt +++ b/gearslip/src/test/java/app/seb3thehacker/gearslip/ConnectionLifecycleTest.kt @@ -104,7 +104,7 @@ class ConnectionLifecycleTest { } @Test fun `unsupported version sends rejection and ends without waiting for peer EOF`() { - val input = CountingInput(message(1, byteArrayOf(0, 2, 0, 0))) + val input = CountingInput(message(1, byteArrayOf(0, 0, 0, 9))) val output = ByteArrayOutputStream() val runner = GearslipRunner(input, output, ::identity) runner.run() @@ -112,7 +112,7 @@ class ConnectionLifecycleTest { val parser = Frames.Parser() parser.append(output.toByteArray(), output.size()) val response = requireNotNull(parser.next()) - assertArrayEquals(byteArrayOf(0, 2) + ProtocolVersion.respond(2, 0).bytes, response.payload) + assertArrayEquals(byteArrayOf(0, 2) + ProtocolVersion.respond(0, 9).bytes, response.payload) assertEquals("Unsupported protocol", SessionStatus.state.value.headline) } diff --git a/gearslip/src/test/java/app/seb3thehacker/gearslip/ProtocolVersionTest.kt b/gearslip/src/test/java/app/seb3thehacker/gearslip/ProtocolVersionTest.kt index c71e7df..b96a5dd 100644 --- a/gearslip/src/test/java/app/seb3thehacker/gearslip/ProtocolVersionTest.kt +++ b/gearslip/src/test/java/app/seb3thehacker/gearslip/ProtocolVersionTest.kt @@ -10,8 +10,13 @@ class ProtocolVersionTest { assertArrayEquals(byteArrayOf(0, 1, 0, 7, 0, 0), ProtocolVersion.respond(1, 9).bytes) } - @Test fun `unsupported major is never reported as a successful downgrade`() { - val response = ProtocolVersion.respond(4, 3) + @Test fun `newer head units get the 1x answer they accept`() { + assertArrayEquals(byteArrayOf(0, 1, 0, 7, 0, 0), ProtocolVersion.respond(4, 2).bytes) + assertArrayEquals(byteArrayOf(0, 1, 0, 7, 0, 0), ProtocolVersion.respond(6, 1).bytes) + } + + @Test fun `major version 0 is refused`() { + val response = ProtocolVersion.respond(0, 9) assertFalse(response.supported) assertArrayEquals(byteArrayOf(0, 1, 0, 7, -1, -1), response.bytes) }