Android WiFi OBSS机制

  • 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帧后,连接设备根据回复信息,如满足需求,则进入到下一认证关联阶段。下图中可看到认证和关联帧,详细分析后面章节介绍。
    图 1 WiFi连接协议帧
    回到本节主题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%

图 2 802.11 probe response framework
图3 OBSS 字段

  • 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, &params))
                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”微信公众号。
谢谢大家支持~!

### OBSS_PD 阈值工作原理 在Wi-Fi标准中,OBSS_PD(Overlapping Basic Service Set Primary Detection)阈值用于管理不同接入点之间的干扰和信道共享效率。具体来说: #### 动态调整机制 OBSS_PD阈值并非固定不变,而是可以根据环境条件动态调整[^3]。这种灵活性有助于优化网络性能并减少不必要的传输延迟。 - **发射功率影响**:当设备以较小的发射功率运行时,允许设置更高的OBSS_PD阈值;反之,在高发射功率情况下,则应采用更低的阈值来确保足够的检测灵敏度。 - **目的**:通过这种方式可以在保持通信质量的同时最大化可用带宽资源利用率。 #### 实际应用场景中的表现 为了更好地理解这一机制的实际效果,考虑如下场景: 假设在一个多AP环境中存在多个重叠的基本服务集(BSS),即所谓的OBSS(overlapping BSS)。此时如果某个STA想要发送数据包前会先监听周围是否存在其他正在使用的频道活动信号强度超过了预设好的OBSS_PD门限值的话就会认为当前时刻不适合发包从而推迟自己的传输动作直到空闲为止。 ```python def should_transmit(current_power, obss_pd_threshold_high, obss_pd_threshold_low): """ Determine whether to transmit based on current power level and OBSS_PD thresholds. Args: current_power (float): Current transmission power of the device. obss_pd_threshold_high (int): Higher OBSS_PD threshold value for lower powers. obss_pd_threshold_low (int): Lower OBSS_PD threshold value for higher powers. Returns: bool: True if it is safe to transmit; False otherwise. """ if current_power < 10: # Assuming low power condition return detect_channel_activity() <= obss_pd_threshold_high else: return detect_channel_activity() <= obss_pd_threshold_low def detect_channel_activity(): """Simulate channel activity detection.""" import random return random.randint(50, 150) # Example usage print("Can we transmit?", should_transmit(7, 120, 80)) ``` 此代码片段展示了如何根据不同级别的发射功率决定是否应该继续尝试发送数据帧的过程模拟。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值