From e6e2362a797201c42b2ac979e002cd5e0c6dd08e Mon Sep 17 00:00:00 2001 From: Mygod Date: Thu, 4 Jun 2020 22:11:17 -0400 Subject: [PATCH] Add ability to specify device address for wifi p2p --- .../java/be/mygod/vpnhotspot/RepeaterService.kt | 14 ++++++++++++++ .../be/mygod/vpnhotspot/manage/RepeaterManager.kt | 6 +++++- .../be/mygod/vpnhotspot/net/MacAddressCompat.kt | 2 ++ .../net/wifi/P2pSupplicantConfiguration.kt | 5 +++-- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt index 22f5dea7..178742ed 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt @@ -28,6 +28,7 @@ import be.mygod.vpnhotspot.util.* import be.mygod.vpnhotspot.widget.SmartSnackbar import kotlinx.coroutines.* import timber.log.Timber +import java.lang.IllegalArgumentException import java.lang.reflect.InvocationTargetException import java.net.NetworkInterface @@ -44,6 +45,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene private const val KEY_PASSPHRASE = "service.repeater.passphrase" private const val KEY_OPERATING_BAND = "service.repeater.band" private const val KEY_OPERATING_CHANNEL = "service.repeater.oc" + private const val KEY_DEVICE_ADDRESS = "service.repeater.mac" /** * Placeholder for bypassing networkName check. */ @@ -90,6 +92,17 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene return if (result in 1..165) result else 0 } set(value) = app.pref.edit { putString(KEY_OPERATING_CHANNEL, value.toString()) } + var deviceAddress: MacAddressCompat? + get() = try { + MacAddressCompat(app.pref.getLong(KEY_DEVICE_ADDRESS, MacAddressCompat.ANY_ADDRESS.addr)).run { + validate() + if (this == MacAddressCompat.ANY_ADDRESS) null else this + } + } catch (e: IllegalArgumentException) { + Timber.w(e) + null + } + set(value) = app.pref.edit { putLong(KEY_DEVICE_ADDRESS, (value ?: MacAddressCompat.ANY_ADDRESS).addr) } } enum class Status { @@ -317,6 +330,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene if (oc == 0) setGroupOperatingBand(operatingBand) else setGroupOperatingFrequency(SoftApConfigurationCompat.channelToFrequency(oc)) } + setDeviceAddress(deviceAddress?.toPlatform()) }.build().run { useParcel { p -> p.writeParcelable(this, 0) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt index 1004b897..1cc12484 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt @@ -192,13 +192,15 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic else -> throw IllegalArgumentException("Unknown operatingBand") } channel = RepeaterService.operatingChannel + bssid = RepeaterService.deviceAddress } } } else { val group = binder?.group if (group != null) try { val config = withContext(Dispatchers.Default) { - P2pSupplicantConfiguration(group, binder?.thisDevice?.deviceAddress) + P2pSupplicantConfiguration(group, + binder?.thisDevice?.deviceAddress, RepeaterService.deviceAddress?.toString()) } holder.config = config return SoftApConfigurationCompat.empty().apply { @@ -209,6 +211,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic band = SoftApConfigurationCompat.BAND_ANY channel = RepeaterService.operatingChannel } + bssid = RepeaterService.deviceAddress } } catch (e: RuntimeException) { Timber.w(e) @@ -239,5 +242,6 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic holder.config = null } if (Build.VERSION.SDK_INT >= 23) RepeaterService.operatingChannel = config.channel + RepeaterService.deviceAddress = config.bssid } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt index 04f9d104..d3123188 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt @@ -72,6 +72,8 @@ inline class MacAddressCompat(val addr: Long) : Parcelable { fun MacAddress.toCompat() = fromBytes(toByteArray()) } + fun validate() = require(addr and ((1L shl 48) - 1).inv() == 0L) + fun toList() = ByteBuffer.allocate(8).run { order(ByteOrder.LITTLE_ENDIAN) putLong(addr) 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 90bbc113..4c795f7f 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 @@ -14,7 +14,7 @@ import java.io.File * https://android.googlesource.com/platform/external/wpa_supplicant_8/+/d2986c2/wpa_supplicant/config.c#488 * https://android.googlesource.com/platform/external/wpa_supplicant_8/+/6fa46df/wpa_supplicant/config_file.c#182 */ -class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress: String?) { +class P2pSupplicantConfiguration(private val group: WifiP2pGroup, vararg ownerAddresses: String?) { companion object { private const val TAG = "P2pSupplicantConfiguration" private const val CONF_PATH_TREBLE = "/data/vendor/wifi/wpa/p2p_supplicant.conf" @@ -53,7 +53,8 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress: RootSession.checkOutput(command, shell, false, false) val parser = Parser(shell.out) try { - val bssids = listOfNotNull(group.owner.deviceAddress, ownerAddress, RepeaterService.lastMac) + val bssids = (listOf(group.owner.deviceAddress, RepeaterService.lastMac) + ownerAddresses) + .filterNotNull() .distinct() .filter { try {