Skip to content

Commit 5c665fd

Browse files
update channel availability logic
1 parent 12f8fa3 commit 5c665fd

23 files changed

+727
-680
lines changed

app/build.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Build Properties
2-
#Sat Mar 29 12:53:53 EDT 2025
3-
version_build=0
2+
#Sun Mar 30 17:02:47 EDT 2025
3+
version_build=1
44
version_major=3
55
version_minor=2
66
version_patch=0

app/src/main/kotlin/com/vrem/wifianalyzer/settings/CountryPreference.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import java.util.Locale
2727
private fun data(): List<Data> {
2828
val currentLocale: Locale = MainContext.INSTANCE.settings.languageLocale()
2929
return WiFiChannelCountry.findAll()
30-
.map { Data(it.countryCode(), it.countryName(currentLocale)) }
30+
.map { Data(it.countryCode, it.countryName(currentLocale)) }
3131
.sorted()
3232
}
3333

app/src/main/kotlin/com/vrem/wifianalyzer/wifi/accesspoint/AccessPointDetail.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,18 @@ class AccessPointDetail {
9797
val wiFiSignal = wiFiDetail.wiFiSignal
9898
setLevelImage(view, wiFiSignal)
9999
setWiFiStandardImage(view, wiFiSignal)
100+
setWiFiWidth(view, wiFiSignal)
100101
it.text = "${wiFiSignal.wiFiChannelStart.frequency} - ${wiFiSignal.wiFiChannelEnd.frequency}"
101-
view.findViewById<TextView>(R.id.width).text =
102-
"(${wiFiSignal.wiFiWidth.frequencyWidth}${WiFiSignal.FREQUENCY_UNITS})"
103102
view.findViewById<TextView>(R.id.capabilities).text = wiFiDetail.wiFiSecurity.securities
104103
.toList()
105104
.joinToString(" ", "[", "]")
106105
}
107106

107+
private fun setWiFiWidth(view: View, wiFiSignal: WiFiSignal) =
108+
view.findViewById<TextView>(R.id.width)?.let {
109+
it.text = ContextCompat.getString(view.context, wiFiSignal.wiFiWidth.textResource)
110+
}
111+
108112
private fun setWiFiStandardImage(view: View, wiFiSignal: WiFiSignal) =
109113
view.findViewById<TextView>(R.id.wiFiStandardValue)?.let {
110114
it.text = ContextCompat.getString(view.context, wiFiSignal.extra.wiFiStandard.valueResource)
@@ -174,8 +178,9 @@ class AccessPointDetail {
174178
with(wiFiSignal) {
175179
view.findViewById<TextView>(R.id.channel_start).text = "${wiFiChannelStart.channel}"
176180
view.findViewById<TextView>(R.id.channel_end).text = "${wiFiChannelEnd.channel}"
177-
view.findViewById<TextView>(R.id.channel_width).text =
178-
"(${wiFiWidth.frequencyWidth}${WiFiSignal.FREQUENCY_UNITS})"
181+
view.findViewById<TextView>(R.id.channel_width)?.let {
182+
it.text = ContextCompat.getString(view.context, wiFiSignal.wiFiWidth.textResource)
183+
}
179184
}
180185

181186
}

app/src/main/kotlin/com/vrem/wifianalyzer/wifi/band/WiFiBand.kt

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,42 +27,10 @@ internal val availableGHZ2: Available = { true }
2727
internal val availableGHZ5: Available = { MainContext.INSTANCE.wiFiManagerWrapper.is5GHzBandSupported() }
2828
internal val availableGHZ6: Available = { MainContext.INSTANCE.wiFiManagerWrapper.is6GHzBandSupported() }
2929

30-
/**
31-
* @see <a href="https://en.wikipedia.org/wiki/List_of_WLAN_channels">List of WLAN channels</a>
32-
*
33-
* WiFi Bands
34-
* 2.4GHz: 1, 2412 -> 13, 2472 (-1, 2402 -> 15, 2482)
35-
* 5GHz: 36, 5180 -> 177, 5885 (30, 5150 -> 184, 5920)
36-
* 6GHz: 1, 5955 -> 233, 7115 (-5, 5925 -> 235, 7125)
37-
*/
38-
private val channelRangeGHZ2 = WiFiChannelPair(WiFiChannel(-1, 2402), WiFiChannel(15, 2482))
39-
private val graphChannelsGHZ2 = (1..13).associate { it to "$it" }
40-
41-
private val channelRangeGHZ5 = WiFiChannelPair(WiFiChannel(30, 5150), WiFiChannel(184, 5920))
42-
private val graphChannelsGHZ5 = listOf(34, 50, 66, 82, 98, 113, 129, 147, 163, 178).associateWith {
43-
when (it) {
44-
113 -> "114"
45-
129 -> "130"
46-
178 -> "179"
47-
else -> "$it"
48-
}
49-
}
50-
51-
private val channelRangeGHZ6 = WiFiChannelPair(WiFiChannel(-5, 5925), WiFiChannel(235, 7125))
52-
private val graphChannelsGHZ6 = listOf(1, 31, 63, 95, 128, 160, 192, 222).associateWith {
53-
when (it) {
54-
128 -> "127"
55-
160 -> "159"
56-
192 -> "191"
57-
222 -> "223"
58-
else -> "$it"
59-
}
60-
}
61-
6230
enum class WiFiBand(@StringRes val textResource: Int, val wiFiChannels: WiFiChannels, val available: Available) {
63-
GHZ2(R.string.wifi_band_2ghz, WiFiChannels(channelRangeGHZ2, graphChannelsGHZ2, 1), availableGHZ2),
64-
GHZ5(R.string.wifi_band_5ghz, WiFiChannels(channelRangeGHZ5, graphChannelsGHZ5), availableGHZ5),
65-
GHZ6(R.string.wifi_band_6ghz, WiFiChannels(channelRangeGHZ6, graphChannelsGHZ6), availableGHZ6);
31+
GHZ2(R.string.wifi_band_2ghz, wiFiChannelsGHZ2, availableGHZ2),
32+
GHZ5(R.string.wifi_band_5ghz, wiFiChannelsGHZ5, availableGHZ5),
33+
GHZ6(R.string.wifi_band_6ghz, wiFiChannelsGHZ6, availableGHZ6);
6634

6735
val ghz2: Boolean get() = GHZ2 == this
6836
val ghz5: Boolean get() = GHZ5 == this

app/src/main/kotlin/com/vrem/wifianalyzer/wifi/band/WiFiChannelCountry.kt

Lines changed: 9 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -21,99 +21,24 @@ import com.vrem.util.allCountries
2121
import com.vrem.util.findByCountryCode
2222
import com.vrem.util.toCapitalize
2323
import java.util.Locale
24-
import java.util.SortedSet
2524

26-
typealias Rules = Pair<Set<String>, Set<Int>>
27-
28-
private val countriesETSI: Set<String> = setOf(
29-
"AT", // ETSI Austria
30-
"BE", // ETSI Belgium
31-
"CH", // ETSI Switzerland
32-
"CY", // ETSI Cyprus
33-
"CZ", // ETSI Czechia
34-
"DE", // ETSI Germany
35-
"DK", // ETSI Denmark
36-
"EE", // ETSI Estonia
37-
"ES", // ETSI Spain
38-
"FI", // ETSI Finland
39-
"FR", // ETSI France
40-
"GR", // ETSI Greece
41-
"HU", // ETSI Hungary
42-
"IE", // ETSI Ireland
43-
"IS", // ETSI Iceland
44-
"IT", // ETSI Italy
45-
"LI", // ETSI Liechtenstein
46-
"LT", // ETSI Lithuania
47-
"LU", // ETSI Luxembourg
48-
"LV", // ETSI Latvia
49-
"MT", // ETSI Malta
50-
"NL", // ETSI Netherlands
51-
"NO", // ETSI Norway
52-
"PL", // ETSI Poland
53-
"PT", // ETSI Portugal
54-
"RO", // ETSI Romania
55-
"SE", // ETSI Sweden
56-
"SI", // ETSI Slovenia
57-
"SK", // ETSI Slovakia
58-
"IL" // ETSI Israel
59-
)
60-
61-
// 2.4 GHz
62-
private val channelsGHZ2 = (1..13).toSortedSet()
63-
64-
// 5 GHz
65-
// 80/160 MHz center channels
66-
private val channelsGHZ5 = sortedSetOf(42, 50, 58, 74, 82, 90, 106, 114, 122, 138, 155, 163, 171)
67-
68-
// exclusion rules
69-
private val excludeGHZ5: List<Rules> = listOf(
70-
Rules(setOf("JP", "TR", "ZA"), sortedSetOf(155, 163, 171)),
71-
Rules(setOf("CN", "BH", "ID"), sortedSetOf(106, 114, 122, 138, 171)),
72-
Rules(setOf("RU"), sortedSetOf(106, 114, 122))
73-
)
74-
75-
// 6 GHz
76-
// 160/320 MHz center channels
77-
private val channelsGHZ6 = sortedSetOf(15, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 207)
78-
79-
// exclusion rules
80-
private val excludeGHZ6: List<Rules> = listOf(
81-
Rules(
82-
countriesETSI.union(setOf("JP", "RU", "NZ", "AU", "GL", "AE", "GB", "MX", "SG", "HK", "MO", "PH")),
83-
sortedSetOf(95, 111, 127, 143, 159, 175, 191, 207)
84-
)
85-
)
86-
87-
private class WiFiChannelsCountry(val channels: SortedSet<Int>, val exclude: List<Rules> = listOf()) {
88-
fun findChannels(locale: Locale): SortedSet<Int> {
89-
val countryCode = locale.country.toCapitalize(Locale.getDefault())
90-
val excludedChannels = exclude.filter { countryCode in it.first }.flatMap { it.second }
91-
return channels.subtract(excludedChannels).toSortedSet()
92-
}
93-
94-
fun available(channel: Int): Boolean = channels.contains(channel)
95-
}
96-
97-
class WiFiChannelCountry(private val locale: Locale) {
25+
class WiFiChannelCountry(val locale: Locale) {
9826
private val unknown = "-Unknown"
99-
private val wiFiBandChannelsCountry = mapOf(
100-
WiFiBand.GHZ2 to WiFiChannelsCountry(channelsGHZ2, excludeGHZ6),
101-
WiFiBand.GHZ5 to WiFiChannelsCountry(channelsGHZ5, excludeGHZ5),
102-
WiFiBand.GHZ6 to WiFiChannelsCountry(channelsGHZ6, excludeGHZ6),
103-
)
10427

105-
fun countryCode(): String = locale.country
28+
val countryCode: String
29+
get() = locale.country.toCapitalize(locale)
10630

10731
fun countryName(currentLocale: Locale): String {
10832
val countryName: String = locale.getDisplayCountry(currentLocale)
10933
return if (locale.country == countryName) countryName + unknown else countryName
11034
}
11135

112-
fun channels(wiFiBand: WiFiBand): SortedSet<Int> =
113-
wiFiBandChannelsCountry[wiFiBand]!!.findChannels(locale)
114-
115-
fun available(wiFiBand: WiFiBand, channel: Int): Boolean =
116-
wiFiBandChannelsCountry[wiFiBand]!!.available(channel)
36+
fun channels(wiFiBand: WiFiBand): List<Int> {
37+
val wiFiChannels = wiFiBand.wiFiChannels
38+
return wiFiChannels.availableChannels
39+
.subtract(wiFiChannels.excludeChannels.flatMap { it[countryCode] ?: emptyList() })
40+
.toList()
41+
}
11742

11843
companion object {
11944
fun find(countryCode: String): WiFiChannelCountry = WiFiChannelCountry(findByCountryCode(countryCode))

app/src/main/kotlin/com/vrem/wifianalyzer/wifi/band/WiFiChannels.kt

Lines changed: 145 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,155 @@
1818
package com.vrem.wifianalyzer.wifi.band
1919

2020
import com.vrem.util.EMPTY
21+
import com.vrem.wifianalyzer.wifi.model.WiFiWidth
2122

2223
internal const val FREQUENCY_SPREAD = 5
2324

2425
typealias WiFiRange = Pair<Int, Int>
2526
typealias WiFiChannelPair = Pair<WiFiChannel, WiFiChannel>
2627

27-
class WiFiChannels(val channelRange: WiFiChannelPair, val graphChannels: Map<Int, String>, val offset: Int = 2) {
28+
private val countriesETSI = listOf(
29+
"AT",
30+
"BE",
31+
"CH",
32+
"CY",
33+
"CZ",
34+
"DE",
35+
"DK",
36+
"EE",
37+
"ES",
38+
"FI",
39+
"FR",
40+
"GR",
41+
"HU",
42+
"IE",
43+
"IS",
44+
"IT",
45+
"LI",
46+
"LT",
47+
"LU",
48+
"LV",
49+
"MT",
50+
"NL",
51+
"NO",
52+
"PL",
53+
"PT",
54+
"RO",
55+
"SE",
56+
"SI",
57+
"SK",
58+
"IL"
59+
)
60+
61+
private fun excludeGHZ6(): List<Map<String, List<Int>>> {
62+
val exclude = (97..223).toList()
63+
val additional = listOf("JP", "RU", "NZ", "AU", "GL", "AE", "GB", "MX", "SG", "HK", "MO", "PH")
64+
return (countriesETSI + additional).map { mapOf(it to exclude) }
65+
}
66+
67+
private fun excludeGHZ5(): List<Map<String, List<Int>>> {
68+
val exclude1 = listOf(177)
69+
val exclude2 = (120..128).toList()
70+
val exclude3 = (169..177).toList()
71+
val exclude4 = (96..128).toList()
72+
val exclude5 = (173..177).toList()
73+
val exclude6 = (149..177).toList()
74+
val exclude7 = (96..144).toList()
75+
val exclude8 = listOf(144)
76+
val exclude9 = (165..177).toList()
77+
val additional = listOf(
78+
"AU" to exclude2 + exclude1,
79+
"CA" to exclude2 + exclude3,
80+
"UK" to exclude2 + exclude1,
81+
"RU" to exclude4 + exclude5,
82+
"JP" to exclude4 + exclude6,
83+
"IN" to exclude1,
84+
"SG" to exclude3,
85+
"CH" to exclude7 + exclude3,
86+
"IL" to exclude1,
87+
"KR" to exclude3,
88+
"TR" to exclude8 + exclude6,
89+
"ZA" to exclude8 + exclude6,
90+
"BR" to exclude3,
91+
"TW" to exclude3,
92+
"NZ" to exclude3,
93+
"BH" to exclude7 + exclude3,
94+
"VN" to exclude3,
95+
"ID" to exclude7 + exclude9,
96+
"PH" to exclude5
97+
)
98+
return countriesETSI.map { mapOf(it to exclude1) } + additional.map { mapOf(it.first to it.second) }
99+
}
100+
101+
102+
val wiFiChannelsGHZ2: WiFiChannels = WiFiChannels(
103+
WiFiChannelPair(WiFiChannel(-1, 2402), WiFiChannel(15, 2482)),
104+
1,
105+
mapOf(
106+
(WiFiWidth.MHZ_20 to listOf(1, 2, 3, 6, 7, 8, 11, 12, 13)),
107+
(WiFiWidth.MHZ_40 to listOf(3, 7, 11))
108+
),
109+
(1..13).associate { it to "$it" },
110+
listOf(1, 2, 3, 6, 7, 8, 11, 12, 13)
111+
)
112+
113+
val wiFiChannelsGHZ5: WiFiChannels = WiFiChannels(
114+
WiFiChannelPair(WiFiChannel(30, 5150), WiFiChannel(184, 5920)),
115+
2,
116+
mapOf(
117+
(WiFiWidth.MHZ_20 to ((32..144 step WiFiWidth.MHZ_20.step) + (149..177 step WiFiWidth.MHZ_20.step))),
118+
(WiFiWidth.MHZ_40 to ((38..142 step WiFiWidth.MHZ_40.step) + (151..175 step WiFiWidth.MHZ_40.step))),
119+
(WiFiWidth.MHZ_80 to ((42..138 step WiFiWidth.MHZ_80.step) + (155..171 step WiFiWidth.MHZ_80.step))),
120+
(WiFiWidth.MHZ_160 to ((50..114 step WiFiWidth.MHZ_160.step) + 163))
121+
),
122+
listOf(34, 50, 66, 82, 98, 113, 129, 147, 163, 178).associateWith {
123+
when (it) {
124+
113 -> "114"
125+
129 -> "130"
126+
178 -> "179"
127+
else -> "$it"
128+
}
129+
},
130+
((42..138 step WiFiWidth.MHZ_80.step) + (155..171 step WiFiWidth.MHZ_80.step) +
131+
(50..114 step WiFiWidth.MHZ_160.step) + 163)
132+
.toSortedSet()
133+
.toList(),
134+
excludeGHZ5()
135+
)
136+
137+
val wiFiChannelsGHZ6: WiFiChannels = WiFiChannels(
138+
WiFiChannelPair(WiFiChannel(-5, 5925), WiFiChannel(235, 7125)),
139+
2,
140+
mapOf(
141+
(WiFiWidth.MHZ_20 to (1..233 step WiFiWidth.MHZ_20.step).toList()),
142+
(WiFiWidth.MHZ_40 to (3..227 step WiFiWidth.MHZ_40.step).toList()),
143+
(WiFiWidth.MHZ_80 to (7..215 step WiFiWidth.MHZ_80.step).toList()),
144+
(WiFiWidth.MHZ_160 to (15..207 step WiFiWidth.MHZ_160.step).toList()),
145+
(WiFiWidth.MHZ_320 to (31..191 step WiFiWidth.MHZ_320.step).toList())
146+
),
147+
listOf(1, 31, 63, 95, 128, 160, 192, 222).associateWith {
148+
when (it) {
149+
128 -> "127"
150+
160 -> "159"
151+
192 -> "191"
152+
222 -> "223"
153+
else -> "$it"
154+
}
155+
},
156+
((15..207 step WiFiWidth.MHZ_160.step) + (31..191 step WiFiWidth.MHZ_320.step))
157+
.toSortedSet()
158+
.toList(),
159+
excludeGHZ6()
160+
)
161+
162+
class WiFiChannels(
163+
val channelRange: WiFiChannelPair,
164+
val offset: Int,
165+
val activeChannels: Map<WiFiWidth, List<Int>>,
166+
val graphChannels: Map<Int, String>,
167+
val availableChannels: List<Int>,
168+
val excludeChannels: List<Map<String, List<Int>>> = listOf()
169+
) {
28170

29171
fun availableChannels(wiFiBand: WiFiBand, countryCode: String): List<WiFiChannel> =
30172
WiFiChannelCountry.find(countryCode).channels(wiFiBand).map { wiFiChannelByChannel(it) }
@@ -46,7 +188,8 @@ class WiFiChannels(val channelRange: WiFiChannelPair, val graphChannels: Map<Int
46188
fun graphChannelByFrequency(frequency: Int): String =
47189
graphChannels[wiFiChannelByFrequency(frequency).channel] ?: String.EMPTY
48190

49-
fun wiFiChannels(): List<WiFiChannel> = (channelRange.first.channel..channelRange.second.channel).map { wiFiChannelByChannel(it) }
191+
fun wiFiChannels(): List<WiFiChannel> =
192+
(channelRange.first.channel..channelRange.second.channel).map { wiFiChannelByChannel(it) }
50193

51194
private fun wiFiChannel(frequency: Int): WiFiChannel {
52195
val firstChannel = (channelRange.first.channel + if (channelRange.first.channel < 0) -0.5 else 0.5).toInt()

0 commit comments

Comments
 (0)