admin管理员组

文章数量:1550529



I have noticed that most android devices do not properly roam between access point that host the same SSID. I have 2 access points at home, upstairs and downstairs. They both share the same settings except the channel. I have a Nexus 5 with locked bootloader and completely stock v4.2.2.

Situation:
I'm standing next to my WiFi access point downstairs, I have full signal bars and perfect connection. I then move upstairs (2 stories up) and move next to the AP located upstairs.
Expected behaviour:
The phone should notice that the AP it is connected to has very weak signal, barely 1 bar left near -85/-90 db which is hardly usable. On the next background scan it should also find the second AP has much better signal, around -45db and decide to 'roam' to the other AP.
Actual behaviour:
The phone maintains a persistent connection with the AP downstairs for hours and does not 'roam' to the AP upstairs causing bad connection and battery drain.
My theory:
I have seen this happen on my HTC One X and performed extensive research on this topic. My conclusion was that WPA_Supplicant is responsible for making the roaming decisions. WPA_Supplicant has a module that is called 'bgscan' which features a mode called 'simple'. This module can be configured to perform periodic background scans when the signal level drops under a certain level and when it finds a stronger AP during the scan it can 'roam' when the difference between the AP's is significant enough.
I also found that this module was compiled, present and functioning by default. The only missing piece is that the configuration line in the wpa_supplicant.conf is missing preventing the bgscan module from loading. I added the line into the section for the relevant network:
bgscan="simple:120:-75:600"
The syntax for the configuration line is as follows and it should be placed in the network section rather than the global section:
bgscan="simple:<short bgscan interval in seconds>:<signal strength threshold>:<long interval>"
My bgscan simple line implies that if the signal is stronger/better than -75db it will perform a bgscan every 10 minutes, if the signal is worse it will perform a scan every 2 minutes. I have monitored the log on my HTC One X and when I moved away from the AP downstairs it performed a bgscan, picked up the AP upstairs and decided to 'roam'. This is all very nicely reported in the logs.
When this configuration line is not present the phone will try to maintain a connection with the first AP it has seen and only connect to another when it completely looses signal. Obviously this is very bad for battery consumption and signal quality. 
Final thoughts and questions
Just to clarify, I'm only talking about simple client-side roaming. This is nothing to do with more advanced configurations like Fast BSS handover or 802.11R.
1. WHY is this module compiled if Android doesn't use it? Is it not used for a reason? 2. I think this can be fixed by making Android add the bgscan line in the the network section block whenever it connects to a new network.
The battery impact should be very minimal if properly configured and I've heard people complain about this A LOT whilst the fix is so easy. Just enabling something that has been written and compiled and is functioning just fine.
References
The module in question:  https://android.googlesource/platform/external/wpa_supplicant_8/+/ics-plus-aosp/wpa_supplicant/bgscan_simple.c Configuration syntax:  http://hostap.epitest.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf Post on XDA with my conclusion:  http://forum.xda-developers/showpost.php?p=46134045&postcount=15357
If you browse through that topic on XDA you can see some of the research I have performed. That topic is about an HTC One X but I think in general most android devices suffer from this unless a vendor has customized and added it themselves.
Any thoughts? I think this should be enabled by default.
This is what a successful 'roam' looks like:
D/wpa_supplicant(  716): bgscan simple: Request a background scan
D/wpa_supplicant(  716): Scan requested (ret=0) - scan timeout 30 seconds
D/wpa_supplicant(  716): nl80211: Event message available
D/wpa_supplicant(  716): nl80211: Scan trigger
D/wpa_supplicant(  716): nl80211: Event message available
D/wpa_supplicant(  716): nl80211: Scan aborted
D/wpa_supplicant(  716): wlan0: Event SCAN_RESULTS (3) received
D/wpa_supplicant(  716): nl80211: Associated on 2412 MHz
D/wpa_supplicant(  716): nl80211: Associated with 68:7f:74:75:1c:7e
D/wpa_supplicant(  716): nl80211: Received scan results (2 BSSes)
D/wpa_supplicant(  716): nl80211: Survey data missing
D/wpa_supplicant(  716): nl80211: Scan results indicate BSS status with 68:7f:74:75:1c:7e as associated
D/wpa_supplicant(  716): wlan0: BSS: Start scan result update 527
D/wpa_supplicant(  716): wlan0: BSS: Add new id 97 BSSID 00:1e:2a:21:f7:3d SSID 'pakjebakmeel24'
D/wpa_supplicant(  716): CTRL_IFACE monitor send - hexdump(len=39): 2f 64 61 74 61 2f 6d 69 73 63 2f 77 69 66 69 2f 73 6f 63 6b 65 74 73 2f 77 70 61 5f 63 74 72 6c ...
D/wpa_supplicant(  716): wlan0: New scan results available
D/wpa_supplicant(  716): CTRL_IFACE monitor send - hexdump(len=39): 2f 64 61 74 61 2f 6d 69 73 63 2f 77 69 66 69 2f 73 6f 63 6b 65 74 73 2f 77 70 61 5f 63 74 72 6c ...
D/wpa_supplicant(  716): bgscan simple: scan result notification
D/wpa_supplicant(  716): wlan0: Selecting BSS from priority group 2
D/wpa_supplicant(  716): wlan0: 0: 00:1e:2a:21:f7:3d ssid='pakjebakmeel24' wpa_ie_len=0 rsn_ie_len=20 caps=0x431 level=-71
D/wpa_supplicant(  716): wlan0:    selected based on RSN IE
D/wpa_supplicant(  716): wlan0:    selected BSS 00:1e:2a:21:f7:3d ssid='pakjebakmeel24'
D/wpa_supplicant(  716): wlan0: Considering within-ESS reassociation
D/wpa_supplicant(  716): wlan0: Current BSS: 68:7f:74:75:1c:7e level=-79
D/wpa_supplicant(  716): wlan0: Selected BSS: 00:1e:2a:21:f7:3d level=-71
D/wpa_supplicant(  716): wlan0: Saving prev AP info for roaming recovery - SSID ID: 1 BSSID: 68:7f:74:75:1c:7e
D/wpa_supplicant(  716): wlan0: Request association: reassociate: 0  selected: 00:1e:2a:21:f7:3d  bssid: 68:7f:74:75:1c:7e  pending: 00:00:00:00:00:00  wpa_state: COMPLETED

I/wpa_supplicant(  716): wlan0: EPBUG: Going to authenticate




///  /data/misc/wifi/wpa_supplicant.conf.

ctrl_interface=wlan0
driver_param=use_multi_chan_concurrent=1 use_p2p_group_interface=1
update_config=1
device_name=endeavoru
manufacturer=HTC
model_name=HTC One X
model_number=HTC One X
serial_number=SH34BW101272
device_type=10-0050F204-5
config_methods=physical_display virtual_push_button
p2p_disabled=1
disassoc_low_ack=1
p2p_go_max_inactivity=60
p2p_go_ht40=1
p2p_multi_chan=1
concurrent_sched_scan=1
autoscan=periodic:30


network={
ssid="Mobile-Wireless"
psk="<VERYSECRETPASSWORD"
key_mgmt=WPA-PSK
priority=2
bgscan="simple:20:-30:20"
}

//wpa_supplicant 小结:

当bgscan触发的扫描结束时
wpa_supplicant_event中接收EVENT_SCAN_RESULTS事件 ->
wpa_supplicant_event_scan_results -> 
_wpa_supplicant_event_scan_results 本函数中通知 -> bgscan_notify_scan 如果bgscan模块没有处理roam事件,则返回0.交由默认_wpa_supplicant_event_scan_results中处理 ->
wpas_select_network_from_last_scan 本函数首选判断是否扫描到可用bssid ->

选择bssid函数:wpa_supplicant_pick_network
判断是否roam函数:wpa_supplicant_need_to_roam 如果需要则 -> wpa_supplicant_connect 进行association

wpa_supplicant_need_to_roam:
如果定义了:CONFIG_NO_ROAMING则没有roam.
其他如下:
min_diff = 2;
if (current_bss->level < 0) {
if (current_bss->level < -85)
min_diff = 1;
else if (current_bss->level < -80)
min_diff = 2;
else if (current_bss->level < -75)
min_diff = 3;
else if (current_bss->level < -70)
min_diff = 4;
else
min_diff = 5;
}


本文标签: wpasupplicantroambgscan