From 4c5265f0c220b654d9e1fc62df9491220c58a7f2 Mon Sep 17 00:00:00 2001 From: Mygod Date: Thu, 2 Jul 2020 08:39:42 +0800 Subject: [PATCH] Fix frequency calculations --- .../be/mygod/vpnhotspot/RepeaterService.kt | 13 ++++--- .../vpnhotspot/manage/RepeaterManager.kt | 14 ++------ .../net/wifi/SoftApConfigurationCompat.kt | 36 ++++++++++++++----- .../net/wifi/WifiApDialogFragment.kt | 26 +++++++++++--- 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt index ab80fcef..fa67c8e3 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt @@ -45,7 +45,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene private const val KEY_NETWORK_NAME = "service.repeater.networkName" private const val KEY_PASSPHRASE = "service.repeater.passphrase" - private const val KEY_OPERATING_BAND = "service.repeater.band" + private const val KEY_OPERATING_BAND = "service.repeater.band.v2" private const val KEY_OPERATING_CHANNEL = "service.repeater.oc" private const val KEY_DEVICE_ADDRESS = "service.repeater.mac" /** @@ -80,7 +80,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene var operatingChannel: Int get() { val result = app.pref.getString(KEY_OPERATING_CHANNEL, null)?.toIntOrNull() ?: 0 - return if (result in 1..165) result else 0 + return if (result > 0) result else 0 } set(value) = app.pref.edit { putString(KEY_OPERATING_CHANNEL, value.toString()) } var deviceAddress: MacAddressCompat? @@ -359,8 +359,13 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene setNetworkName(PLACEHOLDER_NETWORK_NAME) setPassphrase(passphrase) operatingChannel.let { oc -> - if (oc == 0) setGroupOperatingBand(operatingBand) - else setGroupOperatingFrequency(SoftApConfigurationCompat.channelToFrequency(oc)) + if (oc == 0) setGroupOperatingBand(when (operatingBand) { + SoftApConfigurationCompat.BAND_ANY -> WifiP2pConfig.GROUP_OWNER_BAND_AUTO + SoftApConfigurationCompat.BAND_2GHZ -> WifiP2pConfig.GROUP_OWNER_BAND_2GHZ + SoftApConfigurationCompat.BAND_5GHZ -> WifiP2pConfig.GROUP_OWNER_BAND_5GHZ + else -> throw IllegalArgumentException("Unknown band") + }) + else setGroupOperatingFrequency(SoftApConfigurationCompat.channelToFrequency(operatingBand, oc)) } setDeviceAddress(deviceAddress?.toPlatform()) }.build().run { 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 4c5268e4..63e54b21 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt @@ -192,12 +192,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic ssid = networkName securityType = SoftApConfiguration.SECURITY_TYPE_WPA2_PSK // is not actually used this.passphrase = passphrase - band = when (RepeaterService.operatingBand) { - WifiP2pConfig.GROUP_OWNER_BAND_AUTO -> SoftApConfigurationCompat.BAND_ANY - WifiP2pConfig.GROUP_OWNER_BAND_2GHZ -> SoftApConfigurationCompat.BAND_2GHZ - WifiP2pConfig.GROUP_OWNER_BAND_5GHZ -> SoftApConfigurationCompat.BAND_5GHZ - else -> throw IllegalArgumentException("Unknown operatingBand") - } + band = RepeaterService.operatingBand channel = RepeaterService.operatingChannel bssid = RepeaterService.deviceAddress } to false @@ -231,12 +226,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic if (RepeaterService.safeMode) { RepeaterService.networkName = config.ssid RepeaterService.passphrase = config.passphrase - RepeaterService.operatingBand = when (config.band) { - SoftApConfigurationCompat.BAND_ANY -> WifiP2pConfig.GROUP_OWNER_BAND_AUTO - SoftApConfigurationCompat.BAND_2GHZ -> WifiP2pConfig.GROUP_OWNER_BAND_2GHZ - SoftApConfigurationCompat.BAND_5GHZ -> WifiP2pConfig.GROUP_OWNER_BAND_5GHZ - else -> throw IllegalArgumentException("Unknown band") - } + RepeaterService.operatingBand = config.band } else holder.config?.let { master -> val binder = binder if (binder?.group?.networkName != config.ssid || master.psk != config.passphrase || diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt index db015ac5..b91b20bf 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt @@ -53,17 +53,35 @@ data class SoftApConfigurationCompat( private val qrSanitizer = Regex("([\\\\\":;,])") /** - * The frequency which AP resides on (MHz). Resides in range [2412, 5815]. + * Based on: + * https://elixir.bootlin.com/linux/v5.7.6/source/net/wireless/util.c#L75 + * TODO [com.android.server.wifi.util.ApConfigUtil] */ - fun channelToFrequency(channel: Int) = when (channel) { - in 1..14 -> 2407 + 5 * channel - in 15..165 -> 5000 + 5 * channel - else -> throw IllegalArgumentException("Invalid channel $channel") + fun channelToFrequency(band: Int, chan: Int) = when (band) { + BAND_2GHZ -> when (chan) { + 14 -> 2484 + in 1 until 14 -> 2407 + chan * 5 + else -> throw IllegalArgumentException("Invalid 2GHz channel $chan") + } + BAND_5GHZ -> when (chan) { + in 182..196 -> 4000 + chan * 5 + in 1..Int.MAX_VALUE -> 5000 + chan * 5 + else -> throw IllegalArgumentException("Invalid 5GHz channel $chan") + } + BAND_6GHZ -> if (chan in 1..253) { + 5940 + chan * 5 + } else throw IllegalArgumentException("Invalid 6GHz channel $chan") + // BAND_60GHZ -> if (chan in 1 until 7) 56160 + chan * 2160 + else -> throw IllegalArgumentException("Invalid band $band") } - fun frequencyToChannel(frequency: Int) = when (frequency % 5) { - 2 -> ((frequency - 2407) / 5).also { check(it in 1..14) { "Invalid 2.4 GHz frequency $frequency" } } - 0 -> ((frequency - 5000) / 5).also { check(it in 15..165) { "Invalid 5 GHz frequency $frequency" } } - else -> throw IllegalArgumentException("Invalid frequency $frequency") + fun frequencyToChannel(freq: Int) = when (freq) { + 2484 -> 14 + in Int.MIN_VALUE until 2484 -> (freq - 2407) / 5 + in 4910..4980 -> (freq - 4000) / 5 + in Int.MIN_VALUE until 5945 -> (freq - 5000) / 5 + in Int.MIN_VALUE..45000 -> (freq - 5940) / 5 + in 58320..70200 -> (freq - 56160) / 2160 + else -> throw IllegalArgumentException("Invalid frequency $freq") } /** diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt index 08c269e8..6d4e817b 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt @@ -41,7 +41,24 @@ class WifiApDialogFragment : AlertDialogFragment() + for (chan in 1..14) list.add(BandOption.Channel(SoftApConfigurationCompat.BAND_2GHZ, chan)) + for (chan in 1..196) list.add(BandOption.Channel(SoftApConfigurationCompat.BAND_5GHZ, chan)) + if (Build.VERSION.SDK_INT >= 30) { + for (chan in 1..253) list.add(BandOption.Channel(SoftApConfigurationCompat.BAND_6GHZ, chan)) + } + list + } + /** + * Source: https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/c2fc6a1/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java#1396 + */ + private val p2pChannels by lazy { + (1..165).map { + val band = if (it <= 14) SoftApConfigurationCompat.BAND_2GHZ else SoftApConfigurationCompat.BAND_5GHZ + BandOption.Channel(band, it) + } + } } @Parcelize @@ -73,8 +90,8 @@ class WifiApDialogFragment : AlertDialogFragment= 28) add(BandOption.BandAny) add(BandOption.Band2GHz) add(BandOption.Band5GHz) if (Build.VERSION.SDK_INT >= 30) add(BandOption.Band6GHz) + addAll(channels) } - addAll(channels) } adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, 0, bandOptions).apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)