wifi的concurrent mode
所謂wifi的共存模式,有以下幾種:
- station mode + station mode
- station mode + ap mode
- station mode + p2p mode
- p2p mode + ap mode
WIFI模塊通常支持幾種工作模式,但也可以支持兩種模式並存,即AP MODE & STATION MODE。注意,這兩個網絡接口,都是在驅動中虛擬出來的,共享同一個物理硬件

AP MODE通用應用在無線局域網成員設備(即客戶端)的加入,即網絡下行。它提供以無線方式組建無線局域網WLAN,相當際WLAN的中心設備。
那STATION MODE,即工作站模式,也可以理解為某個網格中的一個工作站即客戶端。那當一個WIFI芯片提供這個功能時,它就可以連到另外的一個網絡當中,
如家用路由器就是這種,AP MODE提供給手機設備等連接,提供上網功能,實際能提供上網功能的就是STATION MODE做為INTERNET的一個工作站,所以
STATION MODE通常用於提供網絡的數據上行服務。
在芯片支持的前提下,LINUX或EMBED LINUX SYSTEM都提供了相應的驅動支持,可以使兩種模式同時存在,同時工作。
目前android自從JB version后,就開始支持station + p2p的共存,但其他的共存模式目前在android上都還未支持。現在市面上的wifi驅動主要是支持前三種共存,目前第四種共存模式,暫未見到;而station+ap mode,目前我們有在BXXX項目中使用,使用場景就是:
做Ap供其他的mid或phone來連接,同時自己又做station mode來連接外面可以上網的路由器,這樣在mid或phone上,就可以在訪問BXXX的同時,還可以上網。BXXX自己當然也可以上網了。
但需要主要的是,以上各模式中的station,ap,p2p在驅動中都需要對應的網絡接口的,所以如果要支持concurrent mode,你的驅動insmod后,必須吐出兩個網絡接口才行,如果只有一個網絡接口,那肯定是不支持concurrent mode的,見下圖,加載驅動后就會出現wlan0,p2p0兩個網絡接口。

2.1:station的啟動方式
inmod wifi drivers modules //加載wifi驅動模塊,在這里可以指定各個網絡接口的名字,正常會出wlan0和p2p0兩個網絡接口。
ifconfig wlan0 up //打開station mode對應的wlan0網絡接口
如下設置wpa_supplicant.conf,這樣讓station mode一起來就自動去鏈接指定的ap
/ # cat /data/misc/wifi/wpa_supplicant.conf
ctrl_interface=wlan0
update_config=1
network={
ssid="ASUS_BEN_NEW"
psk="33333333"
priority=1
}
/system/bin/wpa_supplicant -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf //啟動wpa_supplicant后台服務
執行wpa_cli,就可以查看這個時候station 是
/ # wpa_cli wpa_cli v2.0-devel-4.2.1 Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors This software may be distributed under the terms of the BSD license. See README for more details. Using interface 'wlan0' Interactive mode <3>CTRL-EVENT-SCAN-RESULTS sta sta_autoconnect status > status bssid=50:46:5d:00:68:e8 ssid=ASUS_BEN_NEW id=0 mode=station pairwise_cipher=CCMP group_cipher=CCMP key_mgmt=WPA2-PSK wpa_state=COMPLETED ip_address=192.168.1.136 p2p_device_address=00:92:cc:0c:e0:89 address=00:92:cc:0c:e0:89 <3>CTRL-EVENT-STATE-CHANGE id=0 state=9 BSSID=50:46:5d:00:68:e8 SSID=ASUS_BEN_NEW <3>CTRL-EVENT-CONNECTED - connection to 50:46:5d:00:68:e8 completed (reauth) [id=0 id_str=] > p2p0: STA a0:f4:59:45:fc:d5 WPA: group key handshake completed (RSN)
否已經跟路由器連接上了,在確認已經跟路由器連接上后,這個時候只是關聯,鑒權完成,data port打開,但還未分配ip地址。
/ # wpa_cli wpa_cli v2.0-devel-4.2.1 Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors This software may be distributed under the terms of the BSD license. See README for more details. Using interface 'wlan0' Interactive mode <3>CTRL-EVENT-SCAN-RESULTS sta sta_autoconnect status > status bssid=50:46:5d:00:68:e8 ssid=ASUS_BEN_NEW id=0 mode=station pairwise_cipher=CCMP group_cipher=CCMP key_mgmt=WPA2-PSK wpa_state=COMPLETED ip_address=192.168.1.136 p2p_device_address=00:92:cc:0c:e0:89 address=00:92:cc:0c:e0:89 <3>CTRL-EVENT-STATE-CHANGE id=0 state=9 BSSID=50:46:5d:00:68:e8 SSID=ASUS_BEN_NEW <3>CTRL-EVENT-CONNECTED - connection to 50:46:5d:00:68:e8 completed (reauth) [id=0 id_str=] > p2p0: STA a0:f4:59:45:fc:d5 WPA: group key handshake completed (RSN)
設置/system/etc/dhcpcd/dhcpcd.conf文件
/ # cat /system/etc/dhcpcd/dhcpcd.conf # dhcpcd configuration for Android Wi-Fi interface # See dhcpcd.conf(5) for details. # Disable solicitation of IPv6 Router Advertisements noipv6rs interface wlan0 # dhcpcd-run-hooks uses these options. option subnet_mask, routers, domain_name_servers
system/bin/dhcpcd -aABKL -f/system/etc/dhcpcd/dhcpcd.conf -handroid-e4cf57339578c6dc wlan0//開始申請ip地址
ifconfig -a //通過這個命令,可以看到這個時候wlan0已經被分配了ip地址。這個時候如果可以ping通路由器的ip地址,說明station mode的啟動已經ok。
ap的啟動方式
- 設定/data/misc/wifi/hostapd.conf內容,由於上面已經加載了wifi驅動,所以這里不需要再加載
/ # cat /proc/1261/cmdline hostapd/data/misc/wifi/hostapd.conf/ # / # / # cat /data/misc/wifi/hostapd.conf interface=p2p0 ssid=CAST-0CE089 channel=1 auth_algs=1 wpa=2 wpa_passphrase=198d02d6 wpa_key_mgmt=WPA-PSK rsn_pairwise=TKIP CCMP ctrl_interface=/data/misc/wifi/hostapd beacon_int=100 hw_mode=g ieee80211n=1 wme_enabled=1 max_num_sta=8
上面的配置文件中:interface關鍵字指定ap mode使用的網絡接口名字;ssid字段指定了ap的ssid名字;wpa*相關字段設定了ap的加密鑒權方式及密碼;ctrl_interface設定控制接口,一般用於hostap_cli來跟他連接。
ifconfig p2p0 up //打開p2p0網絡接口
ifconfig p2p0 192.168.5.1 //配置p2p0網絡接口的ip地址
hostapd /data/misc/wifi/hostapd.conf & // 啟動hostapd后台,至此ap應該可以被其他wifi設備搜索到,說明啟動成功,這個時候應該可以關聯,鑒權成功,但由於ap端還未啟動dhcp service,所以最終未能分配到ip地址而連接失敗
/system/bin/dnsmasq --no-daemon --no-resolv --no-poll --address=/b.tv/192.168.5.1 --dhcp-range=192.168.5.2,192.168.5.254,24h //dnsmasq有兩個作用:一個是可以起到dhcp service的作用,另一個可以實現dns的forward;上面的--address指定了域名和ip地址的對應關系,--dhcp-range指定了dhcp的地址分配范圍
設定dnsmasq的dns轉發,通常設定為8.8.8.8或8.8.4.4//不設定的話,mid或phone后面雖然可以通過ip地址ping通百度,但卻不能夠通過瀏覽器來瀏覽網頁,原因就是dnsmasq的dns沒有設置好
這個時候,其他wifi設備如果能夠掃描到它,並且還能連上它,分配的ip地址也是在192.168.5.2到192.168.5.254之間,並且能夠ping通路由器的ip(在這里是192.168.5.1),說明ap mode的啟動是成功。
station 與 ap之間的路由
至此,station mode和ap mode都已經啟動成功,並且wlan0和p2p0都有ip地址,但這個時候,你在BXXX或mid上卻不能ping通百度的ip地址(ping 180.76.3.151),但是在BXXX上可以ping 通route,在mid上可以ping通BXXX(見上面的框架圖),為什么呢,因為你沒有設置默認路由的關系。
- route add 192.168.1.1 wlan0 //在BastCast上,為wlan0接口添加路由
- route add 192.168.5.1 p2p0//在BastCast上,為p2p0接口添加路由
- route add default gw 192.168.1.1 ////在BastCast上,添加默認路由
- iptables -t nat -A natctrl_nat_POSTROUTING -o wlan0 -j MASQUERADE //設定nat,這樣內網才能給外網通訊
- echo 1 > /proc/sys/net/ipv4/ip_forward //是能內核的ip轉發功能,默認是禁止的。
- ping 180.76.3.151 //這個時候在BXXX上應該就可以ping通百度的ip地址了
- 如果正確設置了dnsmasque的dns轉發功能,應該可以通過瀏覽器上網了
參考資料
關於iptable:http://kuangkuang.blog.51cto.com/838/247230
關於dnsmasq:https://wiki.archlinux.org/index.php/Dnsmasq
關於dnsmasq:http://blog.chinaunix.net/uid-192452-id-3991843.html
關於realteck wifi的參考文件:
Realtek_WiFi_concurrent_mode_Introduction.pdf
Quick_Start_Guide_for_Station_Mode.pdf
Quick_Start_Guide_for_SoftAP.pdf
wpa_cli_with_wpa_supplicant.pdf
