From a44fd6e60193adc58c1b7d7f342a554f475540e9 Mon Sep 17 00:00:00 2001 From: Jerome Gero Date: Wed, 11 Feb 2026 17:49:46 -0500 Subject: [PATCH 1/7] fix: use base64 BWIFI for WiFi credential provisioning SSIDs containing non-alphanumeric characters (periods, hyphens, etc.) fail to connect when sent via the plain-text SET WIFI serial command. The firmware already supports SET BWIFI which accepts base64-encoded SSID and password, eliminating all parsing issues. This change switches both the desktop and Android serial handlers to use it. --- .../dev/slimevr/android/serial/AndroidSerialHandler.kt | 7 +++++-- .../dev/slimevr/desktop/serial/DesktopSerialHandler.kt | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt index aa48ee178b..481bb79309 100644 --- a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt +++ b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt @@ -281,8 +281,11 @@ class AndroidSerialHandler(val activity: AppCompatActivity) : @Synchronized override fun setWifi(ssid: String, passwd: String) { - writeSerial("SET WIFI \"${ssid}\" \"${passwd}\"") - addLog("-> SET WIFI \"$ssid\" \"${passwd.replace(".".toRegex(), "*")}\"\n") + val encoder = java.util.Base64.getEncoder() + val b64ssid = encoder.encodeToString(ssid.toByteArray(StandardCharsets.UTF_8)) + val b64passwd = encoder.encodeToString(passwd.toByteArray(StandardCharsets.UTF_8)) + writeSerial("SET BWIFI $b64ssid $b64passwd") + addLog("-> SET BWIFI $b64ssid ${b64passwd.replace(".".toRegex(), "*")}\n") } override fun getCurrentPort(): SlimeSerialPort? = this.currentPort diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt index 1b911837be..353698c767 100644 --- a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt +++ b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt @@ -199,9 +199,12 @@ class DesktopSerialHandler : val os = currentPort?.outputStream ?: return val writer = OutputStreamWriter(os) try { - writer.append("SET WIFI \"").append(ssid).append("\" \"").append(passwd).append("\"\n") + val encoder = java.util.Base64.getEncoder() + val b64ssid = encoder.encodeToString(ssid.toByteArray(StandardCharsets.UTF_8)) + val b64passwd = encoder.encodeToString(passwd.toByteArray(StandardCharsets.UTF_8)) + writer.append("SET BWIFI ").append(b64ssid).append(" ").append(b64passwd).append("\n") writer.flush() - addLog("-> SET WIFI \"$ssid\" \"${passwd.replace(".".toRegex(), "*")}\"\n") + addLog("-> SET BWIFI $b64ssid ${b64passwd.replace(".".toRegex(), "*")}\n") } catch (e: IOException) { addLog("$e\n") LogManager.warning("[SerialHandler] Serial port write error", e) From c3cdac92a0056117ea92abe528bd3f9240537584 Mon Sep 17 00:00:00 2001 From: Jerome Gero Date: Wed, 11 Feb 2026 18:48:11 -0500 Subject: [PATCH 2/7] Update server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt Co-authored-by: Butterscotch! --- .../java/dev/slimevr/android/serial/AndroidSerialHandler.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt index 481bb79309..9432576439 100644 --- a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt +++ b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt @@ -281,9 +281,8 @@ class AndroidSerialHandler(val activity: AppCompatActivity) : @Synchronized override fun setWifi(ssid: String, passwd: String) { - val encoder = java.util.Base64.getEncoder() - val b64ssid = encoder.encodeToString(ssid.toByteArray(StandardCharsets.UTF_8)) - val b64passwd = encoder.encodeToString(passwd.toByteArray(StandardCharsets.UTF_8)) + val b64ssid = Base64.Default.encode(ssid.encodeToByteArray()) + val b64passwd = Base64.Default.encode(passwd.encodeToByteArray()) writeSerial("SET BWIFI $b64ssid $b64passwd") addLog("-> SET BWIFI $b64ssid ${b64passwd.replace(".".toRegex(), "*")}\n") } From f07e767e8eabae05b2396adcfa979595bf382e77 Mon Sep 17 00:00:00 2001 From: Jerome Gero Date: Wed, 11 Feb 2026 18:48:18 -0500 Subject: [PATCH 3/7] Update server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt Co-authored-by: Butterscotch! --- .../java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt index 353698c767..0abb490c97 100644 --- a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt +++ b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt @@ -199,9 +199,8 @@ class DesktopSerialHandler : val os = currentPort?.outputStream ?: return val writer = OutputStreamWriter(os) try { - val encoder = java.util.Base64.getEncoder() - val b64ssid = encoder.encodeToString(ssid.toByteArray(StandardCharsets.UTF_8)) - val b64passwd = encoder.encodeToString(passwd.toByteArray(StandardCharsets.UTF_8)) + val b64ssid = Base64.Default.encode(ssid.encodeToByteArray()) + val b64passwd = Base64.Default.encode(passwd.encodeToByteArray()) writer.append("SET BWIFI ").append(b64ssid).append(" ").append(b64passwd).append("\n") writer.flush() addLog("-> SET BWIFI $b64ssid ${b64passwd.replace(".".toRegex(), "*")}\n") From 84812762fa3433bad729956b77703ba62b071fca Mon Sep 17 00:00:00 2001 From: Jerome Gero Date: Wed, 11 Feb 2026 18:48:31 -0500 Subject: [PATCH 4/7] Update server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt Co-authored-by: Butterscotch! --- .../java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt index 0abb490c97..6931e1742f 100644 --- a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt +++ b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt @@ -203,7 +203,7 @@ class DesktopSerialHandler : val b64passwd = Base64.Default.encode(passwd.encodeToByteArray()) writer.append("SET BWIFI ").append(b64ssid).append(" ").append(b64passwd).append("\n") writer.flush() - addLog("-> SET BWIFI $b64ssid ${b64passwd.replace(".".toRegex(), "*")}\n") + addLog("-> SET BWIFI $b64ssid ${StringUtils.repeat('*', b64passwd.length)}\n") } catch (e: IOException) { addLog("$e\n") LogManager.warning("[SerialHandler] Serial port write error", e) From 5c8b7a1f12e26b83b46f3a359649c988b5521607 Mon Sep 17 00:00:00 2001 From: Jerome Gero Date: Wed, 11 Feb 2026 18:49:12 -0500 Subject: [PATCH 5/7] Update server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt Co-authored-by: Butterscotch! --- .../java/dev/slimevr/android/serial/AndroidSerialHandler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt index 9432576439..c60c0a7fb0 100644 --- a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt +++ b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt @@ -284,7 +284,7 @@ class AndroidSerialHandler(val activity: AppCompatActivity) : val b64ssid = Base64.Default.encode(ssid.encodeToByteArray()) val b64passwd = Base64.Default.encode(passwd.encodeToByteArray()) writeSerial("SET BWIFI $b64ssid $b64passwd") - addLog("-> SET BWIFI $b64ssid ${b64passwd.replace(".".toRegex(), "*")}\n") + addLog("-> SET BWIFI $b64ssid ${"*".repeat(b64passwd.length)}\n") } override fun getCurrentPort(): SlimeSerialPort? = this.currentPort From 63b24ef3e1a68a868f00f26ca68ca2f5b0f87fd7 Mon Sep 17 00:00:00 2001 From: Butterscotch! Date: Wed, 11 Feb 2026 18:51:49 -0500 Subject: [PATCH 6/7] Fix String repeat inconsistency --- .../java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt index 6931e1742f..4384445777 100644 --- a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt +++ b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt @@ -203,7 +203,7 @@ class DesktopSerialHandler : val b64passwd = Base64.Default.encode(passwd.encodeToByteArray()) writer.append("SET BWIFI ").append(b64ssid).append(" ").append(b64passwd).append("\n") writer.flush() - addLog("-> SET BWIFI $b64ssid ${StringUtils.repeat('*', b64passwd.length)}\n") + addLog("-> SET BWIFI $b64ssid ${"*".repeat(b64passwd.length)}\n") } catch (e: IOException) { addLog("$e\n") LogManager.warning("[SerialHandler] Serial port write error", e) From ab1256f2c310ff0a67641546ec0d97ce0518fd5b Mon Sep 17 00:00:00 2001 From: Butterscotch! Date: Wed, 11 Feb 2026 19:16:07 -0500 Subject: [PATCH 7/7] Fix issues with Kotlin Base64 --- .../dev/slimevr/android/serial/AndroidSerialHandler.kt | 7 +++++-- .../dev/slimevr/desktop/serial/DesktopSerialHandler.kt | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt index c60c0a7fb0..13e954e41c 100644 --- a/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt +++ b/server/android/src/main/java/dev/slimevr/android/serial/AndroidSerialHandler.kt @@ -20,6 +20,8 @@ import java.nio.ByteBuffer import java.nio.charset.StandardCharsets import java.util.concurrent.CopyOnWriteArrayList import java.util.stream.Stream +import kotlin.io.encoding.Base64 +import kotlin.io.encoding.ExperimentalEncodingApi import kotlin.streams.asSequence import kotlin.streams.asStream import dev.slimevr.serial.SerialPort as SlimeSerialPort @@ -279,10 +281,11 @@ class AndroidSerialHandler(val activity: AppCompatActivity) : currentPort?.port?.write(buff, 0) } + @OptIn(ExperimentalEncodingApi::class) @Synchronized override fun setWifi(ssid: String, passwd: String) { - val b64ssid = Base64.Default.encode(ssid.encodeToByteArray()) - val b64passwd = Base64.Default.encode(passwd.encodeToByteArray()) + val b64ssid = Base64.encode(ssid.encodeToByteArray()) + val b64passwd = Base64.encode(passwd.encodeToByteArray()) writeSerial("SET BWIFI $b64ssid $b64passwd") addLog("-> SET BWIFI $b64ssid ${"*".repeat(b64passwd.length)}\n") } diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt index 4384445777..72b49e5fa4 100644 --- a/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt +++ b/server/desktop/src/main/java/dev/slimevr/desktop/serial/DesktopSerialHandler.kt @@ -14,6 +14,8 @@ import java.util.* import java.util.concurrent.CopyOnWriteArrayList import java.util.stream.Stream import kotlin.concurrent.timerTask +import kotlin.io.encoding.Base64 +import kotlin.io.encoding.ExperimentalEncodingApi import kotlin.streams.asSequence import kotlin.streams.asStream import dev.slimevr.serial.SerialPort as SlimeSerialPort @@ -194,13 +196,14 @@ class DesktopSerialHandler : currentPort?.outputStream?.write(buff) } + @OptIn(ExperimentalEncodingApi::class) @Synchronized override fun setWifi(ssid: String, passwd: String) { val os = currentPort?.outputStream ?: return val writer = OutputStreamWriter(os) try { - val b64ssid = Base64.Default.encode(ssid.encodeToByteArray()) - val b64passwd = Base64.Default.encode(passwd.encodeToByteArray()) + val b64ssid = Base64.encode(ssid.encodeToByteArray()) + val b64passwd = Base64.encode(passwd.encodeToByteArray()) writer.append("SET BWIFI ").append(b64ssid).append(" ").append(b64passwd).append("\n") writer.flush() addLog("-> SET BWIFI $b64ssid ${"*".repeat(b64passwd.length)}\n")