connection proxy negotiation

This commit is contained in:
Seb3thehacker committed 2026-10-07 23:41:16 -07:00
1 parent d0fd6ecb5c
commit fb4b0e2914
1 file changed
+21 -8
@@ -11,6 +11,7 @@ import android.net.Network
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.net.NetworkRequest import android.net.NetworkRequest
import android.net.wifi.WifiNetworkSpecifier import android.net.wifi.WifiNetworkSpecifier
import android.provider.Settings
import app.seb3thehacker.gearslip.GearslipLog import app.seb3thehacker.gearslip.GearslipLog
import app.seb3thehacker.gearslip.Protobuf import app.seb3thehacker.gearslip.Protobuf
import app.seb3thehacker.gearslip.SessionStatus import app.seb3thehacker.gearslip.SessionStatus
@@ -51,8 +52,12 @@ object WirelessLink {
private const val MSG_START_REQUEST = 1 private const val MSG_START_REQUEST = 1
private const val MSG_INFO_REQUEST = 2 private const val MSG_INFO_REQUEST = 2
private const val MSG_INFO_RESPONSE = 3 private const val MSG_INFO_RESPONSE = 3
/** The wireless setup's status for success, shared by every message that carries one. */ /**
private const val STATUS_SUCCESS = 1L * The wireless setup's status for success, shared by every message that carries one.
* aa-proxy-rs sends 0 to real cars and they carry on; a Renault Media Nav given 1 went quiet
* and closed the channel. (open-android-auto's table, which says 1, is marked unverified.)
*/
private const val STATUS_SUCCESS = 0L
private const val MSG_VERSION_REQUEST = 4 private const val MSG_VERSION_REQUEST = 4
private const val MSG_VERSION_RESPONSE = 5 private const val MSG_VERSION_RESPONSE = 5
private const val MSG_CONNECTION_STATUS = 6 private const val MSG_CONNECTION_STATUS = 6
@@ -110,6 +115,11 @@ object WirelessLink {
network = null network = null
} }
/** A stable id for this phone as this app sees it, standing in for the serial a real phone sends. */
@SuppressLint("HardwareIds")
private fun deviceId(context: Context): String =
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID) ?: "gearslip"
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
private fun run(context: Context, device: BluetoothDevice) { private fun run(context: Context, device: BluetoothDevice) {
val name = name(device) val name = name(device)
@@ -153,16 +163,20 @@ object WirelessLink {
MSG_VERSION_REQUEST -> { MSG_VERSION_REQUEST -> {
log.i("<- VersionRequest") log.i("<- VersionRequest")
log.hex(" version", body) log.hex(" version", body)
// Fields 1 and 2 are the major and minor version: answering with the // Laid out the way a real phone's reply is (aa-proxy-rs and LIVI both
// car's own has worked on LIVI. Field 4 is the status, and 1 is success // parse it from real phones): 1 and 2 the version, echoing the car's;
// (0 means "unsolicited message"), per open-android-auto's // 3 a serial; 4 the status; 6 the device's ids.
// WifiVersionStatusEnum.proto. LIVI never reads it, so it proved nothing.
val f = Wire.fields(body) val f = Wire.fields(body)
val serial = deviceId(context)
val ids = Protobuf.stringField(1, serial) + Protobuf.stringField(2, UUID.randomUUID().toString())
val reply = Protobuf.varintField(1, Wire.varint(f, 1) ?: 1) + val reply = Protobuf.varintField(1, Wire.varint(f, 1) ?: 1) +
Protobuf.varintField(2, Wire.varint(f, 2) ?: 0) + Protobuf.varintField(2, Wire.varint(f, 2) ?: 0) +
Protobuf.varintField(4, STATUS_SUCCESS) Protobuf.stringField(3, serial) +
Protobuf.varintField(4, STATUS_SUCCESS) +
Protobuf.varint(((6 shl 3) or 2).toLong()) + Protobuf.varint(ids.size.toLong()) + ids
send(output, MSG_VERSION_RESPONSE, reply) send(output, MSG_VERSION_RESPONSE, reply)
log.i("-> VersionResponse") log.i("-> VersionResponse")
log.hex(" reply", reply)
} }
MSG_START_REQUEST -> { MSG_START_REQUEST -> {
val f = Wire.fields(body) val f = Wire.fields(body)
@@ -239,7 +253,6 @@ object WirelessLink {
override fun onUnavailable() { override fun onUnavailable() {
log.w("Wi-Fi: couldn't join \"$ssid\" (declined, out of range, or wrong password)") log.w("Wi-Fi: couldn't join \"$ssid\" (declined, out of range, or wrong password)")
// -1: Wi-Fi network unavailable.
runCatching { send(output, MSG_CONNECTION_STATUS, Protobuf.varintField(1, -1)) } runCatching { send(output, MSG_CONNECTION_STATUS, Protobuf.varintField(1, -1)) }
SessionStatus.failed( SessionStatus.failed(
"Couldn't join the car's Wi-Fi", "Couldn't join the car's Wi-Fi",