【发布时间】:2011-03-30 11:36:41
【问题描述】:
我发现几个 android wifi 应用程序(WiFi 管理器、WiFi 分析器)除了 BSSID/SSID 等外,还会显示 WiFi 网络的频道号。但我找不到任何关于他们如何做到这一点的信息。我唯一知道的是我可以获得一些 wifi 频率。也许他们确定了与该频率相对应的频道?有没有办法在android中检测wifi网络的通道?当然,这些信息没什么大不了的,没有它我也能活下去:)但我仍然很好奇......
【问题讨论】:
我发现几个 android wifi 应用程序(WiFi 管理器、WiFi 分析器)除了 BSSID/SSID 等外,还会显示 WiFi 网络的频道号。但我找不到任何关于他们如何做到这一点的信息。我唯一知道的是我可以获得一些 wifi 频率。也许他们确定了与该频率相对应的频道?有没有办法在android中检测wifi网络的通道?当然,这些信息没什么大不了的,没有它我也能活下去:)但我仍然很好奇......
【问题讨论】:
根据Radio-Electronics.com的说法,频道数确实与频率有关。
查 下 中 上 NUM FREQ 频率 FREQ MHZ MHZ MHZ 1 2401 2412 2423 2 2406 2417 2428 3 2411 2422 2433 4 2416 2427 2438 5 2421 2432 2443 6 2426 2437 2448 7 2431 2442 2453 8 2436 2447 2458 9 2441 2452 2463 10 2446 2457 2468 11 2451 2462 2473 12 2456 2467 2478 13 2461 2472 2483 14 2473 2484 2495对于 Android,ScanResult 包含频道的频率。
【讨论】:
@SuppressWarnings("boxing")
private final static ArrayList<Integer> channelsFrequency = new ArrayList<Integer>(
Arrays.asList(0, 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
2452, 2457, 2462, 2467, 2472, 2484));
public static Integer getFrequencyFromChannel(int channel) {
return channelsFrequency.get(channel);
}
public static int getChannelFromFrequency(int frequency) {
return channelsFrequency.indexOf(Integer.valueOf(frequency));
}
【讨论】:
您可以使用几个公式来表示转换,每个波段一个。该函数返回给定频率的频道,如果该频率不是有效的 wifi 频率(2.4GHz 和 5GHz),则返回 -1。
public static int convertFrequencyToChannel(int freq) {
if (freq >= 2412 && freq <= 2484) {
return (freq - 2412) / 5 + 1;
} else if (freq >= 5170 && freq <= 5825) {
return (freq - 5170) / 5 + 34;
} else {
return -1;
}
}
这是一种执行相同操作的紧凑方式。
【讨论】:
2484,返回的频道是15,而它应该是14。
根据标准 [802.11-2012],有一种更简单的方法可以从频率中计算出频道号。具体来说,
channel_center_frequency = channel_starting_frequency + 5 * channel_number
对于 5G 频段,
channel_number = 0, 1, ..., 200; channel_starting_frequency = 5000 兆赫。
对于 2.4G 频段,
channel_number = 1, 2, ..., 13; channel_starting_frequency = 2047 兆赫。
所有频道频率的列表可以在WiFi channels找到
将其翻译成代码 - 参考iw 来源:
int ieee80211_frequency_to_channel(int freq)
{
if (freq == 2484)
return 14;
if (freq < 2484)
return (freq - 2407) / 5;
return freq/5 - 1000;
}
【讨论】:
添加到answer by @artm,这是在Linux源代码中找到的更新算法:
int ieee80211_freq_khz_to_channel(u32 freq)
{
/* TODO: just handle MHz for now */
freq = KHZ_TO_MHZ(freq);
/* see 802.11 17.3.8.3.2 and Annex J */
if (freq == 2484)
return 14;
else if (freq < 2484)
return (freq - 2407) / 5;
else if (freq >= 4910 && freq <= 4980)
return (freq - 4000) / 5;
else if (freq < 5925)
return (freq - 5000) / 5;
else if (freq == 5935)
return 2;
else if (freq <= 45000) /* DMG band lower limit */
/* see 802.11ax D6.1 27.3.22.2 */
return (freq - 5950) / 5;
else if (freq >= 58320 && freq <= 70200)
return (freq - 56160) / 2160;
else
return 0;
}
来源:https://github.com/torvalds/linux/blob/master/net/wireless/util.c#L141,函数名:ieee80211_freq_khz_to_channel
【讨论】: