文章目录

  • 一、ACS初始化函数
  • 二、函数跳转驱动

最近在调试wifi的热点相关的东西,做下笔记。代码根据log进行调用追踪。
之前说过,我在关闭CONFIG_ACS的开关后,可以实现热点的打开。但我尝试去打开ACS的逻辑开关过后,发现了新的问题,为了方便自己记录流程,所以做了这个笔记。

一、ACS初始化函数

log

2-23 09:29:48.979  2251  2251 I hostapd : ACS: Automatic channel selection started, this may take a bit start !!!!
02-23 09:29:48.979  2251  2251 E hostapd :acs_request_scan funcation start !!!
02-23 09:29:48.979  2251  2251 E hostapd : ACS: Scanning 1 / 5
02-23 09:29:48.979  2251  2251 E hostapd : hostapd_driver_scan 111
02-23 09:29:50.708  2251  2251 E hostapd : acs_request_scan Failed to request initial scan
02-23 09:29:50.708  2251  2251 I hostapd : wlan0: IEEE 802.11 Configured channel (0) or frequency (0) not found from the channel list of the current mode (1) IEEE 802.11g
02-23 09:29:50.708  2251  2251 W hostapd : wlan0: IEEE 802.11 Configured channel (0) or frequency (0) not found from the channel list of the current mode (1) IEEE 802.11g
02-23 09:29:50.709  2251  2251 I hostapd : wlan0: IEEE 802.11 Hardware does not support configured channel
02-23 09:29:50.709  2251  2251 W hostapd : wlan0: IEEE 802.11 Hardware does not support configured channel
02-23 09:29:50.709  2251  2251 E hostapd : Could not select hw_mode and channel. (-3)
02-23 09:29:50.709  2251  2251 I hostapd : wlan0: interface state UNINITIALIZED->DISABLED
02-23 09:29:50.709  2251  2251 I hostapd : wlan0: AP-DISABLED
02-23 09:29:50.709  2251  2251 E hostapd : wlan0: Unable to setup interface.
02-23 09:29:50.709  2251  2251 I hostapd : nl80211: deinit ifname=wlan0 disabled_11b_rates=0
external/wpa_supplicant_8/wpa_supplicant/src/ap/acs.c/*首先进入初始化函数*/
enum hostapd_chan_status acs_init(struct hostapd_iface *iface)
{wpa_printf(MSG_INFO, "ACS: Automatic channel selection started, this may take a bit");if (iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) {wpa_printf(MSG_INFO, "ACS: Offloading to driver");if (hostapd_drv_do_acs(iface->bss[0]))return HOSTAPD_CHAN_INVALID;return HOSTAPD_CHAN_ACS;}if (!iface->current_mode &&iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY)return HOSTAPD_CHAN_INVALID;acs_cleanup(iface);//清除之前的数据防止干扰/*调用acs_request_scan函数进行扫描*/if (acs_request_scan(iface) < 0)return HOSTAPD_CHAN_INVALID;/*设置接口状态*/hostapd_set_state(iface, HAPD_IFACE_ACS);wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_STARTED);/*让上层函数知道需要等到acs扫描流程*/return HOSTAPD_CHAN_ACS;
}

调用acs_request_scan函数进行扫描,也就是正真执行扫描的地方。

static int acs_request_scan(struct hostapd_iface *iface)
{struct wpa_driver_scan_params params;int i, *freq;int num_channels;struct hostapd_hw_modes *mode;/*创建存储channel信息用的变量*/os_memset(&params, 0, sizeof(params));num_channels = 0;for (i = 0; i < iface->num_hw_features; i++) {mode = &iface->hw_features[i];if (!hostapd_hw_skip_mode(iface, mode))num_channels += mode->num_channels;}params.freqs = os_calloc(num_channels + 1, sizeof(params.freqs[0]));if (params.freqs == NULL)return -1;freq = params.freqs;for (i = 0; i < iface->num_hw_features; i++) {mode = &iface->hw_features[i];if (!hostapd_hw_skip_mode(iface, mode))freq = acs_request_scan_add_freqs(iface, mode, freq);}*freq = 0;if (params.freqs == freq) {wpa_printf(MSG_ERROR, "ACS: No available channels found");os_free(params.freqs);return -1;}/*将scan函数赋值成acs_scan_complete,之后执行scan_cb的时候就会调acs_scan_complete*/iface->scan_cb = acs_scan_complete;/*这里输出当前执行到第几次acs扫描,将MSG_DEBUG,改为MSG_ERROR可看到扫描次数*/wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d",iface->acs_num_completed_scans + 1,iface->conf->acs_num_scans);/*进行单次扫描,调用这个函数,我的log在这里出错*/if (hostapd_driver_scan(iface->bss[0], &params) < 0) {wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");acs_cleanup(iface);//清除数据os_free(params.freqs);//释放什么return -1;}os_free(params.freqs);return 0;
}

然后会调用这个函数

external/wpa_supplicant_8/src/ap/ap_drv_ops.cint hostapd_driver_scan(struct hostapd_data *hapd,struct wpa_driver_scan_params *params)
{/*如果scan2注册了,则调用该函数,返回对应的函数*/if (hapd->driver && hapd->driver->scan2)return hapd->driver->scan2(hapd->drv_priv, params);return -1;
}

后面又会调用到:至于为啥会跑到这里,不太清楚,但是log显示下一个函数就是这里出错的

static int setup_interface2(struct hostapd_iface *iface)
{iface->wait_channel_update = 0;if (hostapd_get_hw_features(iface)) {//获取硬件信息/* Not all drivers support this yet, so continue without hw* feature data. */} else {//我的设备会走这个else分支int ret = hostapd_select_hw_mode(iface);//选择硬件模式,我的硬件模式有问题,导致了后面一系列问题。if (ret < 0) {//异常情况处理返回 -3 wpa_printf(MSG_ERROR, "Could not select hw_mode and ""channel. (%d)", ret);goto fail;}if (ret == 1) {//正常情况之需要进行acs扫描流程wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)");return 0;}ret = hostapd_check_ht_capab(iface);//不需要acs扫描流程,已有选定的信道if (ret < 0)goto fail;if (ret == 1) {//等待acs扫描结束后,也会调到hostapd_setup_interface_complete结束函数wpa_printf(MSG_DEBUG, "Interface initialization will ""be completed in a callback");return 0;}if (iface->conf->ieee80211h)wpa_printf(MSG_DEBUG, "DFS support is enabled");}return hostapd_setup_interface_complete(iface, 0);//初始化结束函数
fail:hostapd_set_state(iface, HAPD_IFACE_DISABLED);//异常处理wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);if (iface->interfaces && iface->interfaces->terminate_on_error)eloop_terminate();return -1;
}

下面其实就是这里出现错误

/external/wpa_supplicant_8/hostapd/src/ap/hw_features.cstatic void hostapd_notify_bad_chans(struct hostapd_iface *iface)
{if (!iface->current_mode) {hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,HOSTAPD_LEVEL_WARNING,"Hardware does not support configured mode");return;}hostapd_logger(iface->bss[0], NULL,HOSTAPD_MODULE_IEEE80211,HOSTAPD_LEVEL_WARNING,"Configured channel (%d) or frequency (%d) not found from the channel list of the current mode (%d) %s",iface->conf->channel,iface->freq,iface->current_mode->mode,hostapd_hw_mode_txt(iface->current_mode->mode));hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,HOSTAPD_LEVEL_WARNING,"Hardware does not support configured channel");//出现这个错误
}

同时在选择硬件模式的时候会调用 hostapd_select_hw_mode这个函数

int hostapd_select_hw_mode(struct hostapd_iface *iface)
{int i;if (iface->num_hw_features < 1)return -1;if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G || iface->conf->ieee80211n || iface->conf->ieee80211ac) && iface->conf->channel == 14) {wpa_printf(MSG_INFO, "Disable OFDM/HT/VHT on channel 14");iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211B;iface->conf->ieee80211n = 0;iface->conf->ieee80211ac = 0;}//异常处理iface->current_mode = NULL;//把值清为NULLfor (i = 0; i < iface->num_hw_features; i++) {//遍历当前接口的hw_features/*其中iface的结构体定义如下,struct hostapd_iface {... ...struct hostapd_hw_modes *hw_features;//接口支持的hw_modes的数组int num_hw_features;//接口支持的hw_modes的个数... ...}*/struct hostapd_hw_modes *mode = &iface->hw_features[i];if (mode->mode == iface->conf->hw_mode) {//如果hostapd.conf中配的hw_mode与当前接口支持的模式匹配成功了,//就将接口当前模式赋为这个值,跳出循环iface->current_mode = mode;break;}}if (iface->current_mode == NULL) {//如果没有匹配的上的模式,则报错,返回-2进行异常处理if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) ||!(iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY)){wpa_printf(MSG_ERROR,"Hardware does not support configured mode");hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_WARNING,"Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)", (int) iface->conf->hw_mode);return -2;}}switch (hostapd_check_chans(iface)) {//调用hostapd_check_chans函数//会判断是否需要acs扫描选择信道。如果hostapd.conf中channel配置成0(不配置就是0),就需要经过acs扫描算法流程//若hostapd.conf中没配置channel,则说明已选定了信道,就判断该信道是否validcase HOSTAPD_CHAN_VALID: //没配置channelreturn 0;case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */return 1;case HOSTAPD_CHAN_INVALID: //异常情况条件的处理default:hostapd_notify_bad_chans(iface);return -3;}
}

调用 hostapd_check_chans 函数

static enum hostapd_chan_status hostapd_check_chans(struct hostapd_iface *iface)
{if (iface->conf->channel) {//如果hostapd.conf配置了非零的channel值,即指定了AP所在的channelif (hostapd_is_usable_chans(iface))//调用hostapd_is_usable_chans函数判断下是否为可用信道return HOSTAPD_CHAN_VALID;elsereturn HOSTAPD_CHAN_INVALID;}/** The user set channel=0 or channel=acs_survey* which is used to trigger ACS.*/switch (acs_init(iface)) {//如果配置的channel值是0,则需要进行acs算法流程,故而要初始化acscase HOSTAPD_CHAN_ACS: //需要进行acs算法return HOSTAPD_CHAN_ACS;case HOSTAPD_CHAN_VALID: //若不需要acs,则出了异常情况,返回INVALIDcase HOSTAPD_CHAN_INVALID:default:return HOSTAPD_CHAN_INVALID;}
}

external的相关代码后面就没有再跟了,因为函数已经走向了错误的方向,所以这个此就到这里吧。

二、函数跳转驱动

log:

02-25 01:21:05.690  2164  2164 I hostapd : rfkill: Cannot open RFKILL control device
02-25 01:21:05.692  2164  2164 I hostapd : ACS: Automatic channel selection started, this may take a bit start !!!!
02-25 01:21:05.692  2164  2164 E hostapd : Enter acs_request_scan funcation start !!!
02-25 01:21:05.692  2164  2164 E hostapd : ACS: Scanning 1 / 5
02-25 01:21:05.692  2164  2164 E hostapd : enter hostapd_driver_scan 111
02-25 01:21:05.693     0     0 E [dhd][wlan0] wl_run_escan: LEGACY_SCAN sync ID: 0, bssidx: 0
02-25 01:21:05.701     0     0 I         : [dhd] CFG80211-ERROR) wl_run_escan :  Escan set error (-4)
02-25 01:21:05.707     0     0 I         : [dhd] CFG80211-ERROR) wl_run_escan : scan error (-4)
02-25 01:21:05.713     0     0 I         : [dhd] CFG80211-ERROR) wl_cfg80211_scan : scan error (-11)
02-25 01:21:05.720     0     0 E [dhd][wlan0] wl_cfg80211_add_del_bss: wl bss 2 bssidx:0
02-25 01:21:05.730     0     0 E [dhd][wlan0] wl_run_escan: LEGACY_SCAN sync ID: 1, bssidx: 0
02-25 01:21:05.737     0     0 I         : [dhd] CFG80211-ERROR) wl_run_escan :  Escan set error (-4)
02-25 01:21:05.744     0     0 I         : [dhd] CFG80211-ERROR) wl_run_escan : scan error (-4)
02-25 01:21:05.750     0     0 I         : [dhd] CFG80211-ERROR) wl_cfg80211_scan : scan error (-11)
02-25 01:21:05.759  2164  2164 E hostapd : ACS: acs_request_scan Failed to request initial scan

从log可以看出,当调用函数到hostapd_driver_scan(单次扫描的时候)

int hostapd_driver_scan(struct hostapd_data *hapd,struct wpa_driver_scan_params *params)
{if (hapd->driver && hapd->driver->scan2) { wpa_printf(MSG_ERROR,"enter hostapd_driver_scan 111");return hapd->driver->scan2(hapd->drv_priv, params);}wpa_printf(MSG_ERROR,"enter hostapd_driver_scan 222");return -1;
}

添加打印后确定会从scan2这里调用驱动里面的函数

kernel_imx/drivers/net/wireless/bcmdhd/wl_cfgscan.cstatic s32
wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev,struct cfg80211_scan_request *request, uint16 action)
{s32 err = BCME_OK;u32 n_channels;u32 n_ssids;s32 params_size;wl_escan_params_t *eparams = NULL;wl_escan_params_v2_t *eparams_v2 = NULL;u8 *scan_params = NULL;u8 *params = NULL;u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)];u32 num_chans = 0;s32 channel;u32 n_valid_chan;s32 search_state = WL_P2P_DISC_ST_SCAN;u32 i, j, n_nodfs = 0;u16 *default_chan_list = NULL;wl_uint32_list_t *list;s32 bssidx = -1;struct net_device *dev = NULL;........
}

后面就是根据报错继续追函数的调用了。

一个简单的wifi热点启动流程追踪相关推荐

  1. android 13 热点启动流程

    近期在看一个热点启动的问题.发现网上基本上都算android 9 的wifi热点启动流程.自己去看android 13 的源码的时候发现与之前相比已经有一些小改动了. 在此总结一下wifie热点的启动 ...

  2. 记一次rk平台热点打开流程追踪记录

    记一次rk平台热点打开流程追踪记录 问题描述 rk平台偶现热点打开失败,错误日志如下: I/android.hardware.wifi@1.0-service: Starting legacy HAL ...

  3. 一个简单的Eclipse调试Debug流程(四)

    本文链接:https://blog.csdn.net/u011781521/article/details/55000066    http://blog.csdn.net/u010075335/ar ...

  4. (七十一)Android O WiFi热点 开启流程梳理

    前言:之前主要梳理了WiFi开启扫描连接的流程,现在梳理下WiFi 热点 的开启流程. 时序图mdj样式:https://download.csdn.net/download/sinat_200594 ...

  5. (九十七)Android O WiFi热点 开启流程梳理续(二)

    前言:从之前WiFi的连接流程可以知道WiFi最后一步会和服务端进行dhcp以获取ip地址,那么WiFi热点开启的时候应该也要配置相关dhcp属性,以供后续WiFi连接的时候ip分配,根据这块流程继续 ...

  6. 简单聊聊AspNetCore的启动流程

    首先,得和大家达成一个共识,即AspNetCore项目其实就是一个控制台项目.可以简单的理解,AspNetCore就是将一个Web服务器宿主在一个进程(即控制台)中,然后它在这个进程中进行http请求 ...

  7. MySQL:一个简单insert语句的大概流程

    简单记录,可能有误,主要记录重要的接口以备后用. 一.操作说明 我建了一个简单的表,插入一个简单的数据. mysql> create table testin(id int); Query OK ...

  8. 简单清晰的SpringBoot启动流程

    文章目录 前言 一.创建SpringApplication对象 二.执行 run() 方法 总结 前言 SpringBoot启动流程总体分为两步,第一步先SpringApplication对象,第二步 ...

  9. android wifihal 流程,Wifi笔记 | 启动流程 Native层

    一.Manager层调用到WifiNative 看一些关键性的操作: 启动Hal:startHal() 启动supplicant:startSupplicant() 加载驱动(loadDriver): ...

最新文章

  1. [LeetCode] Intersection of Two Linked Lists 求两个链表的交点
  2. MySQL5.6开启慢查询
  3. php 生成pdf 中文,php采用tcpdf生成pdf支持中文,图片
  4. 如何用软件工程消灭软件危机?
  5. HTML DOM节点的属性获取
  6. java 中map_Java中Map集合
  7. 阿里巴巴旗下平台口碑推出无人收银技术,改造便利店市场;重庆法院运用 AI 探索“智能判案”...
  8. 【数据结构基础】-串-顺序结构的基本操作实现
  9. 腾讯技术峰会:从模型部署到算法应用,云计算时代下的人工智能
  10. word vba 点击任意域代码,刷新整个文档的域代码值
  11. 中去掉外键_【Java笔记】035天,MySQL中的增删改查
  12. 动态规划 杭电1257
  13. 数学建模算法体系分类
  14. IntelliJ IDEA Maven安装配置
  15. 微信APP支付 C#
  16. 摄影场景拍摄方法笔记
  17. python是垃圾?
  18. JDK的下载与安装(详细版)
  19. 我花了18年时间才能和你坐在一起喝咖啡
  20. 关于跨境电商你了解多少 我们应该怎么做跨境电商?(下)

热门文章

  1. js在浏览器中对cookie进行增删改查
  2. Sql 修改表结构的操作
  3. MSAA,SSAA,CSAA,CFAA...如何正确地为您的游戏设置抗锯齿模式
  4. 购房流程 - 新浪网
  5. 利用思维导图,快速整理小学语文复习重点,建议为孩子收藏!
  6. 图像分割(MATLAB实现)
  7. kali Linux 2020.1B 最详细安装教程
  8. 30岁以上,没人脉、没资源、工作不顺心、更没钱,这4个小生意,拿去就可以干,只要你肯努力,就可以翻身
  9. [235]scrapy分布式爬虫scrapy-redis(二)
  10. JQJQJQJQdefferd详解