linux下WIFI无法开启AP的问题

背景

        在这之前没有了解过太多关于AP的知识,只是知道在linux下开启AP一般都是使用hostapd,甚至于hostapd.conf的相关配置也是大多从网上找的,直到这次,同事一直反馈,设备的AP在外场测试时总是有概率开启不成功的问题,但是在家又是可以开启的。后来我拿到了日志,开始了分析原因。

问题分析

        之前因为只是简单测试能不能开启AP和手机能不能连接AP并ping通设备,至于开启成功的概率,至少是我没怎么遇到开启失败的情况,所以也没有关注过这个问题。现在这个问题同事反馈过多次,不得不分析处理一下。我通过-d参数获取了hostapd运行的日志,从中分析问题原因。

hostapd /etc/hostapd.conf -d

        废话不多说,直接上日志:

uap0: interface state UNINITIALIZED->COUNTRY_UPDATE
Previous country code 00, new country code CN 
Continue interface setup after channel list update
ctrl_iface not configured!
random: Got 20/20 bytes from /dev/random
Channel list update timeout - try to continue anyway
nl80211: Regulatory information - country=00
nl80211: 2402-2472 @ 40 MHz 20 mBm
nl80211: 2457-2482 @ 20 MHz 20 mBm (no IR)
nl80211: 2474-2494 @ 20 MHz 20 mBm (no OFDM) (no IR)
nl80211: 5170-5250 @ 80 MHz 20 mBm (no IR)
nl80211: 5250-5330 @ 80 MHz 20 mBm (DFS) (no IR)
nl80211: 5490-5730 @ 160 MHz 20 mBm (DFS) (no IR)
nl80211: 5735-5835 @ 80 MHz 20 mBm (no IR)
nl80211: 57240-63720 @ 2160 MHz 0 mBm
nl80211: Added 802.11b mode based on 802.11g information
nl80211: Mode IEEE 802.11g: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467[NO_IR] 2472[NO_IR] 2484[NO_IR]
nl80211: Mode IEEE 802.11a: 5180[NO_IR] 5200[NO_IR] 5220[NO_IR] 5240[NO_IR] 5260[NO_IR][RADAR] 5280[NO_IR][RADAR] 5300[NO_IR][RADAR] 5320[NO_IR][RADAR] 5500[NO_IR][RADAR] 5520[NO_IR][RADAR] 5540[NO_IR][RADAR]
nl80211: Mode IEEE 802.11b: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467[NO_IR] 2472[NO_IR] 2484[NO_IR]
ACS: Automatic channel selection started, this may take a bit
ACS: No available channels found
uap0: IEEE 802.11 Configured channel (0) or frequency (0) (secondary_channel=0) not found from the channel list of the current mode (2) IEEE 802.11a
uap0: IEEE 802.11 Hardware does not support configured channel
Could not select hw_mode and channel. (-3)
uap0: interface state COUNTRY_UPDATE->DISABLED
uap0: AP-DISABLED 
hostapd_interface_deinit_free(0x66cae0)
hostapd_interface_deinit_free: num_bss=1 conf->num_bss=1
hostapd_interface_deinit(0x66cae0)
uap0: interface state DISABLED->DISABLED
hostapd_bss_deinit: deinit bss uap0
uap0: Deauthenticate all stations
nl80211: sta_remove -> DEL_STATION uap0 ff:ff:ff:ff:ff:ff --> 0 (Success)
uap0: AP-DISABLED 
hostapd_cleanup(hapd=0x66eda8 (uap0))
uap0: CTRL-EVENT-TERMINATING 
hostapd_free_hapd_data: Interface uap0 wasn't started

        我截取了部分hostapd -d的日志,日志中显示,国家码由00变为CN,但是后面的显示nl80211: Regulatory information - country=00,感觉像是国家码设置并没有成功。这个是其中的一个疑点。另外的一个是,ACS: No available channels found,意思是自动信道选择的功能没有选择到合适的信道资源,这个可能就是AP开启不成功的主要原因了。

        再看看当时的hostapd.conf配置了什么。

interface=uap0
hw_mode=a
channel=0
ieee80211d=1
country_code=CN
ieee80211n=1
ieee80211ac=1
wmm_enabled=1
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0

ssid=XIAOGUI-5G
auth_algs=1
wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_passphrase=12345678
ignore_broadcast_ssid=0
macaddr_acl=0

        结合这个配置和日志,我是大概知道是啥原因了,就像上面说的,配置选择了hw_mode=a模式,也就是Mode IEEE 802.11a,但是hostapd运行时扫描到的5GHz频段中的信道资源不能使用,所以导致AP无法开启。

        那就是下一个问题,为啥不能用呢?

nl80211: Mode IEEE 802.11a: 5180[NO_IR] 5200[NO_IR] 5220[NO_IR] 5240[NO_IR] 5260[NO_IR][RADAR] 5280[NO_IR][RADAR] 5300[NO_IR][RADAR] 5320[NO_IR][RADAR] 5500[NO_IR][RADAR] 5520[NO_IR][RADAR] 5540[NO_IR][RADAR]

        日志里显示这些信道,都是带[NO_IR]或者[RADAR]的,啥意思,不懂就找GPT,看看它是怎么胡说的。

什么是雷达信道,有什么影响?

信道52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,144可作为雷达信道,如果某国家和地区支持的信道和雷达信道有重叠,则使用信道时请尽量避开雷达信道。当AP工作在5G射频频段时,AP通过DFS功能,进行雷达检测,当检测到雷达信道后会自动切换到其他工作信道,避免干扰雷达。

        Soga,原来在设置为5GHz频段时,这些信道与雷达信道时重叠的,hostapd检查到雷达信道的时候,这些信道就是不可用的。那意思就是,信道屁股后面有[RADAR]标识的基本就时不能用的。

        那啥是[NO_IR],没有红外?这里的IR是指“initiate radiation”,意思是启动辐射。NO_IR估计就是这个信道无法启动辐射,意思还是这个信道不可用。

        那就是说,hostapd检测到的信道都是不可用状态,所以无法启动AP,问题原因分析结束,下课。

解决问题

        既然知道无法开启的原因,那怎么解决呢?能不能不检测信道强行开启呢?有一个资源叫做《WLAN国家码与信道顺从表》,这里面详细罗列了各个地区5GHz各个信道的带宽资源分布。但我发现,设备hostapd检测的部分信道并不是CN,这也证实了,前面说的国家码设置并没有生效,那就先解决这个问题。

        在linux下,国家码的设置通常有几种方式,一般都是伴随着WIFI的模式确定的。

        在STA模式下,可以使用wpa_cli工具设置。

wpa_cli -i wlan0 set country [country_code]

         在AP模式下,国家码的指定通常在配置文件中体现,也就是在hostapd.conf中指定country_code=CN

        另外,国家码的设置还可以通过iw这个工具设置。

iw reg set [country_code]

        由于设备中AP模式下在配置文件中指定国家码不生效,所以我尝试在命令行中直接用iw工具设置,但是好像也没有成功。

$ iw reg set US
$ iw reg get
global
country 00: DFS-UNSET
        (2402 - 2472 @ 40), (6, 20), (N/A)
        (2457 - 2482 @ 20), (6, 20), (N/A), AUTO-BW, PASSIVE-SCAN
        (2474 - 2494 @ 20), (6, 20), (N/A), NO-OFDM, PASSIVE-SCAN
        (5170 - 5250 @ 80), (6, 20), (N/A), AUTO-BW, PASSIVE-SCAN
        (5250 - 5330 @ 80), (6, 20), (0 ms), DFS, AUTO-BW, PASSIVE-SCAN
        (5490 - 5730 @ 160), (6, 20), (0 ms), DFS, PASSIVE-SCAN
        (5735 - 5835 @ 80), (6, 20), (N/A), PASSIVE-SCAN
        (57240 - 63720 @ 2160), (N/A, 0), (N/A)

        经过了解,国家码的设置是通过系统的cfg80211驱动实现的,于是我打开了cfg80211相关的所有驱动调试输出,终于发现问题。

        由于内核的配置使能了 CONFIG_CFG80211_INTERNAL_REGDB=y,所以内核在编译的时候会把默认net/wireless/db.txt这个文件编译到内核中。但是,我的内核的这个文件,竟然是啥都没有的,==

#
# This file is a placeholder to prevent accidental build breakage if someone
# enables CONFIG_CFG80211_INTERNAL_REGDB.  Almost no one actually needs to
# enable that build option.
#
# You should be using CRDA instead.  It is even better if you use the CRDA
# package provided by your distribution, since they will probably keep it
# up-to-date on your behalf.
#
# If you _really_ intend to use CONFIG_CFG80211_INTERNAL_REGDB then you will
# need to replace this file with one containing appropriately formatted
# regulatory rules that cover the regulatory domains you will be using.  Your
# best option is to extract the db.txt file from the wireless-regdb git
# repository:
#
#   git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
#

        好吧,根据它的解释,这个方式不是很好,需要用CRDA的方式动态的设置数据,我还没了解过CRDA,先不管,先用这个内置数据的方式吧。它提供了一个链接,从这个连接里下载,然后把下载的db.txt替换这个et/wireless/db.txt,重新编译内核。

        又是激动人心的时候,用新的内核启动后,设置国家码就生效了。

[root ~]# iw reg set CN
[root ~]# iw reg get
global
country CN: DFS-UNSET
        (2402 - 2482 @ 40), (20, 0), (N/A)
        (5170 - 5250 @ 80), (23, 0), (N/A)
        (5250 - 5330 @ 80), (23, 0), (N/A)
        (5735 - 5835 @ 80), (30, 0), (N/A)
        (57240 - 59400 @ 2160), (28, 0), (N/A)
        (59400 - 63720 @ 2160), (44, 0), (N/A)
        (63720 - 65880 @ 2160), (28, 0), (N/A)

        然后dmesg也有对应的输出信息:

cfg80211: Calling CRDA for country: CN
cfg80211: Regulatory domain changed to country: CN
cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
cfg80211:   (2402000 KHz - 2482000 KHz @ 40000 KHz), (2000 mBi, 0 mBm)
cfg80211:   (5170000 KHz - 5250000 KHz @ 80000 KHz), (2300 mBi, 0 mBm)
cfg80211:   (5250000 KHz - 5330000 KHz @ 80000 KHz), (2300 mBi, 0 mBm)
cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (3000 mBi, 0 mBm)
cfg80211:   (57240000 KHz - 59400000 KHz @ 2160000 KHz), (2800 mBi, 0 mBm)
cfg80211:   (59400000 KHz - 63720000 KHz @ 2160000 KHz), (4400 mBi, 0 mBm)
cfg80211:   (63720000 KHz - 65880000 KHz @ 2160000 KHz), (2800 mBi, 0 mBm)

         其实这上面的信息就是db.txt里设置的监管信息,约束了各个地区有效的频段和功率信息。

验证

        改完内核之后,再次启动hostapd进行验证,这次还是带-d参数,先看看启动的详细日志信息:

BSS count 1, BSSID mask 00:00:00:00:00:00 (0 bits)
uap0: interface state UNINITIALIZED->COUNTRY_UPDATE
Previous country code CN, new country code CN
nl80211: Regulatory information - country=CN
nl80211: 2402-2482 @ 40 MHz 0 mBm
nl80211: 5170-5250 @ 80 MHz 0 mBm
nl80211: 5250-5330 @ 80 MHz 0 mBm
nl80211: 5735-5835 @ 80 MHz 0 mBm
nl80211: 57240-59400 @ 2160 MHz 0 mBm
nl80211: 59400-63720 @ 2160 MHz 0 mBm
nl80211: 63720-65880 @ 2160 MHz 0 mBm
nl80211: Added 802.11b mode based on 802.11g information
nl80211: Mode IEEE 802.11g: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467 2472 2484[DISABLED]
nl80211: Mode IEEE 802.11a: 5180 5200 5220 5240 5260 5280 5300 5320 5500[DISABLED] 5520[DISABLED] 5540[DISABLED] 5560[DISABLED] 5580[DISABLED] 5600[DISABLED] 5620[DISABLED] 5640[DISABLED] 5660[DISABLED] 5680[DISABLED]
nl80211: Mode IEEE 802.11b: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467 2472 2484[DISABLED]
ACS: Automatic channel selection started, this may take a bit
ACS: Scanning 1 / 5
uap0: nl80211: scan request
nl80211: Passive scan requested
Scan requested (ret=0) - scan timeout 10 seconds
uap0: interface state COUNTRY_UPDATE->ACS
uap0: ACS-STARTED

        可以从日志中明显看到,nl80211: Regulatory information - country=CN,显示国家码CN已经生效了,这个是hostapd.conf中指定的country_code=CN导致的。

        另外从日志中看到,由于监管db生效了,DFS检测出来的信道也和前面说的信道资源匹配上了,并且大部分信道都是可以使用的状态,再也没有[NO_IR]和[RADAR]了,部分信道还是[DIASBLED]状态,这部分信道是不可用的。[DIASBLED]状态的信道在5GHz频点居多,这个估计也就是前面说的雷达信道,在CN区域是不可用的。

        由于5GHz频点除了[DIASBLED]状态的信道仍然有大部分信道资源可用,在ACS使能的状态下,基本是可以选择到合适的信道启动AP的,无法启动AP的问题就此解决。

        前面说到,内核已经不推荐使用内置db的方式,而是使用CRDA的方式动态的生成db,这个方式有时间还要了解一下,毕竟不能增加一个地区或者修改地区监管数据,还要重新升级内核吧?

        下课!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值