diff --git a/README.md b/README.md index d92b647f..e4e1c982 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,6 @@ If some of these are unavailable, you can alternatively install a recent version Wi-Fi driver `wpa_supplicant`: -* P2P configuration file is assumed to be saved to `/data/misc/wifi/p2p_supplicant.conf` or - `/data/vendor/wifi/wpa/p2p_supplicant.conf` for API 28+ and have reasonable format; +* P2P configuration file is assumed to be saved to `/data/vendor/wifi/wpa/p2p_supplicant.conf` or + `/data/misc/wifi/p2p_supplicant.conf` and have reasonable format; * Android system is expected to restart `wpa_supplicant` after it crashes. diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt index 809f7cc6..abfe5d0f 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt @@ -64,7 +64,13 @@ object TrafficRecorder { private fun doUpdate(timestamp: Long) { val oldRecords = LongSparseArray() - loop@ for (line in RootSession.use { it.execOutUnjoinedWithWait("$IPTABLES -nvx -L vpnhotspot_fwd").drop(2) }) { + loop@ for (line in RootSession.use { + val command = "$IPTABLES -nvx -L vpnhotspot_fwd" + val result = it.execQuiet(command) + val message = it.checkOutput(command, result, false, false) + if (result.err.isNotEmpty()) Timber.i(message) + result.out.drop(2) + }) { val columns = line.split("\\s+".toRegex()).filter { it.isNotEmpty() } try { check(columns.size >= 9) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt index a675e467..5c66f88b 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt @@ -15,11 +15,11 @@ import java.io.File class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress: String?) { companion object { private const val TAG = "P2pSupplicantConfiguration" + private const val CONF_PATH_TREBLE = "/data/vendor/wifi/wpa/p2p_supplicant.conf" + private const val CONF_PATH_LEGACY = "/data/misc/wifi/p2p_supplicant.conf" private val networkParser = "^(bssid=(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})|psk=(ext:|\"(.*)\"|[0-9a-fA-F]{64}\$))".toRegex() private val whitespaceMatcher = "\\s+".toRegex() - private val confPath = if (Build.VERSION.SDK_INT >= 28) - "/data/vendor/wifi/wpa/p2p_supplicant.conf" else "/data/misc/wifi/p2p_supplicant.conf" } private class NetworkBlock : ArrayList() { @@ -46,7 +46,10 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress: RootSession.use { val result = ArrayList() var target: NetworkBlock? = null - val parser = Parser(it.execOutUnjoined("cat $confPath")) + val command = "cat $CONF_PATH_TREBLE || cat $CONF_PATH_LEGACY" + val shell = it.execQuiet(command) + it.checkOutput(command, shell, false, false) + val parser = Parser(shell.out) try { while (parser.next()) { if (parser.trimmed.startsWith("network={")) { @@ -77,7 +80,7 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress: } } else result.add(parser.line) } - Pair(result, target!!) + Triple(result, target!!, shell.err.isNotEmpty()) } catch (e: RuntimeException) { DebugHelper.setString(TAG, parser.lines.joinToString("\n")) DebugHelper.setString("$TAG.ownerAddress", ownerAddress) @@ -89,7 +92,7 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress: val psk = group.passphrase ?: content.second.psk!! fun update(ssid: String, psk: String) { - val (lines, block) = content + val (lines, block, legacy) = content block[block.ssidLine!!] = "\tssid=" + ssid.toByteArray() .joinToString("") { (it.toInt() and 255).toString(16).padStart(2, '0') } block[block.pskLine!!] = "\tpsk=\"$psk\"" // no control chars or weird stuff @@ -100,7 +103,7 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress: } // pkill not available on Lollipop. Source: https://android.googlesource.com/platform/system/core/+/master/shell_and_utilities/README.md RootSession.use { - it.exec("cat ${tempFile.absolutePath} > $confPath") + it.exec("cat ${tempFile.absolutePath} > ${if (legacy) CONF_PATH_LEGACY else CONF_PATH_TREBLE}") if (Build.VERSION.SDK_INT >= 23) it.exec("pkill wpa_supplicant") else { val result = it.execOut("ps | grep wpa_supplicant").split(whitespaceMatcher) check(result.size >= 2) { "wpa_supplicant not found, please toggle Airplane mode manually" } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/RootSession.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/RootSession.kt index cd466c6f..d53dbec5 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/RootSession.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/RootSession.kt @@ -57,8 +57,8 @@ class RootSession : AutoCloseable { } class UnexpectedOutputException(msg: String) : RuntimeException(msg) - private fun checkOutput(command: String, result: Shell.Result, out: Boolean = result.out.isNotEmpty(), - err: Boolean = result.err.isNotEmpty()): String { + fun checkOutput(command: String, result: Shell.Result, out: Boolean = result.out.isNotEmpty(), + err: Boolean = result.err.isNotEmpty()): String { val msg = StringBuilder("$command exited with ${result.code}") if (out) result.out.forEach { msg.append("\n$it") } if (err) result.err.forEach { msg.append("\nE $it") } @@ -101,22 +101,11 @@ class RootSession : AutoCloseable { }).exec() } fun exec(command: String) = checkOutput(command, execQuiet(command)) - fun execWithWait(command: String) { - val result = execQuiet(command) - val message = checkOutput(command, result, err = false) - if (result.err.isNotEmpty()) Timber.i(message) - } fun execOutUnjoined(command: String): List { val result = execQuiet(command) checkOutput(command, result, false) return result.out } - fun execOutUnjoinedWithWait(command: String): List { - val result = execQuiet(command) - val message = checkOutput(command, result, false, false) - if (result.err.isNotEmpty()) Timber.i(message) - return result.out - } fun execOut(command: String): String = execOutUnjoined(command).joinToString("\n") /** @@ -127,7 +116,11 @@ class RootSession : AutoCloseable { fun exec(command: String, revert: String? = null, wait: Boolean = false) { if (revert != null) revertCommands.addFirst(revert) // add first just in case exec fails - if (wait) this@RootSession.execWithWait(command) else this@RootSession.exec(command) + if (wait) { + val result = this@RootSession.execQuiet(command) + val message = checkOutput(command, result, err = false) + if (result.err.isNotEmpty()) Timber.i(message) + } else this@RootSession.exec(command) } fun execQuiet(command: String) = this@RootSession.execQuiet(command)