-
1
欢迎大家一起学习探讨通信之WLAN。今天我插入一篇探讨下WiFi的新Feature,基于Android 9.0分析探讨。
好,我们先看下OBSS的原型:
Overlapping BSS:重叠的BSS。作用是帮助AP报告当前无线信道环境的状况。 -
2
这个功能在什么时候触发的呢?
如下图1所示,WiFi连接空口日志。关于WiFi连接协议帧交互后续我们进行分析。回顾WiFi的扫描介绍,在下图中可以看到802.11 probe Requst和802.11 probe Response帧。在WiFi网络回复802.11 probe Response帧后,连接设备根据回复信息,如满足需求,则进入到下一认证关联阶段。下图中可看到认证和关联帧,详细分析后面章节介绍。
回到本节主题WiFi OBSS机制,该功能在AP支持的情况下,才会触发使用。WiFi网络一般支持的功能都会在Beacon帧或802.11 probe Response中字段中携带表明。所以在WiFi网络回复的probe Response帧中可看到如下字段,如图2所示probe Response帧字段,如图3所示probe Response帧中OBSS字段。
Overlapping BSS Scan Parameters
Element ID: 74 Overlapping BSS Scan Parameters [193]
Length: 14 [194]
OBSS Scan Passive Dwell:20 [195-196] //被动扫描停留时长20 TUs
OBSS Scan Active Dwell:10 [197-198] //主动扫描停留时长10 TUs
BSS Channel Width Trigger Scan Interval:300 seconds [199-200]
//触发扫描间隔300秒
OBSS Scan Passive Total Per Channel:200 [201-202]
//被动扫描每个信道总时长200 TUs
OBSS Scan Active Total Per Channel:20 [203-204]
//主动扫描每个信道总时长20 TUs
BSS Width Channel Transition Delay Factor:5 [205-206]
//BSS带宽信道转换延迟因子5
OBSS Scan Activity Threshold:25 hundreths of a percent [207-208]
//OBSS Scan运行门限值:25%
-
3
接下来我们看下代码层面如何处理?
驱动层:
驱动一般会对Linux 版本判断,大于某一版本后即可支持该功能,定义与NL80211_FEATURE_NEED_OBSS_SCAN相关的宏定义,表明支持OBSS 功能。
- @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform
- OBSS scans and generate 20/40 BSS coex reports. This flag is used only
- for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied.
Kernel层:
-
4
在注册cfg80211设备时,会表明支持“NL80211_FEATURE_NEED_OBSS_SCAN ”功能。
drivers/net/wireless/cfg80211.c
/*
* This function registers the device with CFG802.11 subsystem.
* The function creates the wireless device/wiphy, populates it with
* default parameters and handler function pointers, and finally
* registers the device.
*/
int register_cfg80211(struct adapter *adapter)
{
wiphy->features |= NL80211_FEATURE_HT_IBSS |
NL80211_FEATURE_INACTIVITY_TIMER |
NL80211_FEATURE_LOW_PRIORITY_SCAN |
//添加与OBSS相关的feature
NL80211_FEATURE_NEED_OBSS_SCAN |
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
}
wpa_supplicant层
- 5
wpa_supplicant是改功能的具体实现,详细看下代码实现。WiFi连接时,使能该OBSS功能,WiFi断开时,关闭OBSS功能。
wpa_supplicant/wpa_supplicant.c
/**
- wpa_supplicant_set_state - Set current connection state
- @wpa_s: Pointer to wpa_supplicant data
- @state: The new connection state
- - This function is called whenever the connection state changes, e.g.,
- association is completed for WPA/WPA2 4-Way Handshake is started.
*/
void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
enum wpa_states state)
{
if (state == WPA_COMPLETED && wpa_s->new_connection) {
sme_sched_obss_scan(wpa_s, 1);
//设置使能OBSS周期扫描
} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||state == WPA_ASSOCIATED) {
wpa_s->new_connection = 1;
sme_sched_obss_scan(wpa_s, 0);
//设置关闭OBSS周期扫描
}
}
-
6
wpa_supplicant中对OBSS feature是否支持获取及相关功能flag定义。
src/drivers/driver.h
#define WPA_DRIVER_FLAGS_OBSS_SCAN 0x04000000
src/drivers/driver_nl80211_capa.c
static void wiphy_info_feature_flags(struct wiphy_info_data *info,
struct nlattr *tb)
{
if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
}
* @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform
* OBSS scans and generate 20/40 BSS coex reports. This flag is used only
* for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied.
enum nl80211_feature_flags {
NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10,
}
-
7
wpa_supplicant中对OBSS feature实现如下。
wpa_supplicant/sme.c
void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable)
if (!enable) //如果enble为0,直接返回。
return;
/*
* Schedule OBSS scan if driver is using station SME in wpa_supplicant
* or it expects OBSS scan to be performed by wpa_supplicant.
*/
if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) ||
ssid == NULL || ssid->mode != IEEE80211_MODE_INFRA)
return;//如果当前未连接或flag表示不支持直接返回
//获取路由器协议帧中支持的间隔扫描时间。
wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6);
if (wpa_s->sme.obss_scan_int < 10) {
wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u " "replaced with the minimum 10 sec", wpa_s->sme.obss_scan_int);
wpa_s->sme.obss_scan_int = 10;
//如果扫描间隔小于10秒,则赋值为10秒。
}
//注册扫描触发时间
eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
sme_obss_scan_timeout, wpa_s, NULL);
}
static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct wpa_driver_scan_params params;
if (!wpa_s->current_bss) { //当前未连接直接返回。
wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request");
return;
}
//触发WiFi扫描。
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms))
wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
else
wpa_s->sme.sched_obss_scan = 1;
os_free(params.freqs);
//注册WiFi扫描
eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
sme_obss_scan_timeout, wpa_s, NULL);
}
日志打印
- 8
实测WiFi连接log打印如下。
04-22 16:43:00.516 890 890 D wpa_supplicant: nl80211: Received scan results (3 BSSes)
04-22 16:48:00.488 890 890 D wpa_supplicant: nl80211: Received scan results (6 BSSes)
04-22 16:53:00.450 890 890 D wpa_supplicant: nl80211: Received scan results (6 BSSes)
注:
对以上所述专业知识有修正意见或建议,可随时留言反馈。如感兴趣更多通信知识,可关注“通信之WLAN”微信公众号。
谢谢大家支持~!