RK3288 Android 10 系统开发[5] - 解决wifi mac随机问题

在Android10的使用过程中,由于业务要求使用wifi mac地址作为设备的 SN ,所以要求mac地址必须是唯一且固定的。然而测试发现在wifi 连接过程中会出现短暂时间的随机mac,wifi连接成功后保持稳定。

Android 官方解释

rand mac

从官方解析来看,高版本安卓系统为了安全考虑,支持随机分配wifi mac.

但是要支持的话需要修改以下参数:

frameworks/base/core/res/res/values/config.xml
- config_wifi_connected_mac_randomization_supported
- config_wifi_p2p_mac_randomization_supported

但是这两个参数默认已经配置为 false 了。只能换个方向查。

wifi 随机 mac

追踪日志,dmesg 中发现wifi 扫描过程中确实会更新mac地址,而且随机的mac地址前3个字节是固定的。

[   27.378506] pno_mac_addr: 00000000: da a1 19 60 00 87                                ...`..
[   27.383501] RTW: wlan0- hw port(0) mac_addr =da:a1:19:60:00:87
[   27.384074] RTW: p2p0- hw port(1) mac_addr =62:fb:00:80:13:b3
...
[   28.866340] RTW: wlan0- hw port(0) mac_addr =60:fb:00:80:13:b3
[   28.869420] RTW: p2p0- hw port(1) mac_addr =62:fb:00:80:13:b3

rtl8188eu 驱动

在 wifi 驱动代码搜索关键词 pno_mac_addr.

  • kernel/drivers/net/wireless/rockchip_wlan/rtl8188eu/
$ grep -rn pno_mac_addr |grep print
os_dep/linux/rtw_cfgvendor.c:1596:      print_hex_dump(KERN_DEBUG, "pno_mac_addr: ",
os_dep/linux/rtw_cfgvendor.c:1646:              print_hex_dump(KERN_DEBUG, "pno_mac_addr: ",

打开 os_dep/linux/rtw_cfgvendor.c 文件找到对应代码。

void rtw_hal_pno_random_gen_mac_addr(PADAPTER adapter)
{
    u8 mac_addr[ETH_ALEN];
    struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);

    memcpy(mac_addr, pwdev_priv->pno_mac_addr, ETH_ALEN);
    if (mac_addr[0] == 0xFF) return;
    rtw_hal_random_gen_mac_addr(mac_addr);
    memcpy(pwdev_priv->pno_mac_addr, mac_addr, ETH_ALEN);
#ifdef CONFIG_RTW_DEBUG
    print_hex_dump(KERN_DEBUG, "pno_mac_addr: ",
               DUMP_PREFIX_OFFSET, 16, 1, pwdev_priv->pno_mac_addr,
               ETH_ALEN, 1);
#endif
}

确实有一个产生随机mac地址的函数 rtw_hal_pno_random_gen_mac_addr.

搜索这个函数。

$ grep -rn rtw_hal_pno_random_gen_mac_addr
os_dep/linux/rtw_cfgvendor.h:631:void rtw_hal_pno_random_gen_mac_addr(PADAPTER adapter);
os_dep/linux/rtw_cfgvendor.c:1586:void rtw_hal_pno_random_gen_mac_addr(PADAPTER adapter)
core/rtw_mlme_ext.c:14909:                      rtw_hal_pno_random_gen_mac_addr(padapter);

打开 core/rtw_mlme_ext.c.

    case SCAN_START:
#if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
        if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
                && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
                && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) {
            u16 seq_num;

#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
            rtw_hal_pno_random_gen_mac_addr(padapter);
#endif
            rtw_hal_set_hw_mac_addr(padapter, pwdev_priv->pno_mac_addr);
            get_random_bytes(&seq_num, 2);
            pwdev_priv->pno_scan_seq_num = seq_num & 0xFFF;
            RTW_INFO("%s pno_scan_seq_num %d\n", __func__,
                 pwdev_priv->pno_scan_seq_num);
        }
#endif

可以看出,随机mac的功能是通过 CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI 来控制的, 而且仅在 SCAN_START 的情况下会调用,也就是 wifi 扫描过程中触发。

这个配置参数定义于 include/drv_conf.h 头文件中。

#if (CONFIG_RTW_ANDROID < 11)
#ifndef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
#define CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
#endif
#else
#ifndef CONFIG_RTW_SCAN_RAND
#define CONFIG_RTW_SCAN_RAND
#endif

这里的判断依据是Android版本是否小于11,我们在Makefile中定义的Android版本是10,所以这个配置是打开的。

解决方案

根据以上分析,很容易得出解决方案,把这个CONFIG禁掉不就好了。上patch.

--- a/drivers/net/wireless/rockchip_wlan/rtl8188eu/include/drv_conf.h
+++ b/drivers/net/wireless/rockchip_wlan/rtl8188eu/include/drv_conf.h
@@ -123,7 +123,7 @@
        #endif
        #if (CONFIG_RTW_ANDROID < 11)
        #ifndef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
-       #define CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
+       //#define CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
        #endif
        #else
        #ifndef CONFIG_RTW_SCAN_RAND

经验证,禁掉该配置后wifi mac不会随机变化了。

reference