Android WiFi开发总结

1 WLAN物理层
1.1 物理层的组成
PLCP:Physical Layer Convergence Procedure,物理层汇聚子层
PMD:Physical Medium Dependent,物理媒介相关层;调制解调就是这一层

1.2 信号RSSI
WPS key: press key within 3 seconds.
路由器有效信号范围:-20dB ~-90dB
一个房间的话,在-40dB左右;隔一堵墙,就会在-50dB左右。
-20dB一般很少,要靠得很近才有。
the smaller abs(rssi), the better.

1.3 WiFi信号通道设置多少最合适
- 建议选择1,6,11或13这些互相不冲突的信道。
- 无线AP无线信号覆盖范围内有两个以上的AP时,需要为每个AP设定不同的频段,以免共用信道发生冲突。而很多用户使用的无线设备的默认设置都是Channel为1,当两个以上的这样的无线AP设备相“遇”时冲突就在所难免。
- 无论是IEEE802.11b还是IEEE802.11g标准其都只支持3个不重叠的传输信道信道,只有信道1、6、11或13是不冲突的,但使用信道3的设备会干扰1和6,使用信道9的设备会干扰6和13。

1.4 MIMO
Figure 1-1 WiFi MIMO

1.5 MRMC Concurrency
1)MRMC是multi-role multi-channel operation的缩写。
2)The WiLink8.0 supports the multi-channel operation as time division multiplexing (TDM)-based concurrency. Each role gets a portion of the air time. The core of the multi-role operation is the scheduler that decides on each given time what role should be activated, and protects the role that should be suspended before moving to a new role.
3)TI AP+SoftAP是单信道TDM并发。
4)Cypress WLAN+P2P采用不同的信道实现TDM并发。
5)Linux中每一个role叫做vif。
Figure 1
-2 Concurrency Setup STA with Group Client

2 Android WiFi
2.1 根据avc log自动生成Android Selinux策略
2.1.1 生成policy文本文件
1)提取所有的avc log
adb shell "cat /proc/kmsg | grep avc" > avc_log.txt

or

adb shell
dmesg | grep avc > /dev/avc_log.txt
adb pull /dev/avc_log.txt .

2)使用audit2allow直接生成policy
sudo apt-get install policycoreutils
audit2allow -i avc_log.txt -o output_pol.te

vi output_pol.te

2.1.2 直接插入到sepolicy文件中
adb shell
dmesg > /dev/kern_msg.txt
adb pull /dev/kern_msg.txt .

cat kern_msg.log | audit2allow -p out/target/product/<device>/root/sepolicy

2.2 内核模块签名问题
CONFIG_MODULE_SIG=y
- 表示开启了签名机制,但是这时候模块签名或不签名都可以使用。

CONFIG_MODULE_SIG_FORCE=y
- 如果上述配置项使能,则模块必须有正确的签名才能正常使用。

CONFIG_MODULE_SIG_ALL=y
- 内核在编译的时候,并不会主动去给模块签名,除非你把上述配置项打开。

@ kernel/kernel/Makefile
其中,x509.genkey是生成key pair时的配置项,signing_key.priv、signing_key.x509分别为private key和数字证书。数字证书会打包进内核,里面有公钥等,用来解密。每编译一次,虽然配置文件每次都相同,但是生成的key pair是不同的。

2.3 Linux 内核模块编译脚本
2.3.1 芯片厂商的方法
@ device/<vvv>/common/dlkm/AndroidKernelModule.mk

2.3.2 OEM自定义方法
@ hello.c

@ Makefile
#no-pic:Position Independent Code, 位置无关代码
obj-m := hello.o

PREFIX=Android源码路径-LINUX/android
KERNELDIR := $(PREFIX)/out/target/product/<ppp>/obj/KERNEL_OBJ/
PWD :=$(shell pwd)
ARCH=arm
CROSS_COMPILE=$(PREFIX)/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-

CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
CFLAGS_MODULE=-fno-pic

modules:
    make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
clean:
    rm *.o *.ko *.mod.c *.order *.symvers

2.4 nl80211
nl80211:使用netlink配置WiFi,代码层次关系从上到下分别是nl80211-cfg80211-mac80211(包含ieee80211_ops),缩写为NCM;而wext基于ioctl方式配置WiFi

@ net/wireless/nl80211.c
mac80211的add_virtual_intf() - 将net_device添加到/sys/class/net目录下(譬如p2p0 - for hostapd、wlan0 - for STA);netd会调用NL80211_CMD_NEW_INTERFACE创建一个虚拟接口
mac80211的del_virtual_intf() - 将net_device从sys/class/net目录下删除(譬如p2p0 - for hostapd、wlan0 - for STA);netd会调用NL80211_CMD_DEL_INTERFACE删除一个虚拟接口

@ net/mac80211/iface.c
ieee80211_open() - 调用ieee80211_ops的add_interface(),一般指ifconfig wlan0 up
ieee80211_stop() - 调用ieee80211_ops的remove_interface(),一般指ifconfig wlan0 down

hw_scan() - 开始单次扫描
cancel_hw_scan() - 停止单次扫描
sched_scan_start() - 开始周期扫描
sched_scan_stop() - 停止周期扫描

2.5 nl80211如何找到具体的struct net_device
@ net/netlink/genetlink.c
static int genl_family_rcv_msg(struct genl_family *family,
                   struct sk_buff *skb,
                   struct nlmsghdr *nlh)
{
    [...]
    // ieee80211_alloc_hw() -> wiphy_new()中创建了struct cfg80211_registered_device
    // &nl80211_fam->pre_doit()
    if (family->pre_doit) {
        err = family->pre_doit(ops, skb, &info);
        if (err)
            goto out;
    }

    // nl80211_ops[i].doit(), call cfg80211_ops->xxx()
    err = ops->doit(skb, &info);

    // &nl80211_fam->post_doit()
    if (family->post_doit)
        family->post_doit(ops, skb, &info);

    [...]
}

2.6 WiFi State和StateMachine
State.java - 状态,其它类继承该类,产生N多状态
StateMachine.java - 管理状态,其它类继承该类,生成State管理类

2.7 STA和AP共存
在/sys/class/net下必须有2个节点:诸如p2p0(或者wds0)和wlan0。

@ net/wireless/nl80211.c
mac80211的add_virtual_intf() - 将net_device添加到/sys/class/net目录下(譬如p2p0 - for hostapd、wlan0 - for STA);netd会调用NL80211_CMD_NEW_INTERFACE创建一个虚拟接口
mac80211的del_virtual_intf() - 将net_device从sys/class/net目录下删除(譬如p2p0 - for hostapd、wlan0 - for STA);netd会调用NL80211_CMD_DEL_INTERFACE删除一个虚拟接口

@ /etc/wifi/wifi_concurrency_cfg.txt under WifiServiceImpl.java
WifiController.java - 决定使用SoftApStateMachine.java还是WifiStateMachine.java
SoftApStateMachine.java - AP和STA并发状态机,打开AP的代码就放在该类中;而打开STA的代码在WifiStateMachine.java中
WifiStateMachine.java - AP和STA不能并发状态机,打开AP和STA的代码都放在该类中,AP和STA只能二选一

Figure 2-1 Android状态机机制StateMachine

2.8 Tethering
- netd监听网络接口(/sys/class/net)的添加和删除,并发送给Tethering.java
@ Tethering.java
interfaceAdded()
interfaceRemoved()

- UI启动USB Tethering功能
@ Tethering.java
setUsbTethering()

- 使能路由和转发功能
@ TetherInterfaceStateMachine.java
class TetheredState extends State {
    [...]
    public boolean processMessage(Message message) {
        switch (message.what) {
            case CMD_TETHER_CONNECTION_CHANGED:
                [...]
                mNMService.enableNat(mIfaceName, newUpstreamIfaceName);
                mNMService.startInterfaceForwarding(mIfaceName,
                                    newUpstreamIfaceName);
                [...]
        }
    }
    [...]
}

2.9 Android captive detection
@ NetworkMonitor.java

# 查看所有配置
settings list global

# 使用https
settings put global captive_portal_use_https 1
settings put global captive_portal_https_url https://www.qualcomm.cn/generate_204

# 使用http
settings put global captive_portal_use_https 0
settings put global captive_portal_http_url http://connect.rom.miui.com/generate_204

# 使用默认,即删除配置
settings delete global captive_portal_http_url
settings delete global captive_portal_https_url

# 禁用captive探测
settings put global captive_portal_mode 0

3 常用网络调试工具
- SocketTool(测试MCU和PC Socket通信非常方便)
- WireShark

4 eCos Write MAC
ra0 的 MAC 是读取 0x0004,0x0006 和 0x0008 三个寄存器。
假设MAC地址:00:0C:43:76:20:58
用USB2UART线进入eCos命令行后。
cd net
iwpriv ra0 e2p 04=0C00
iwpriv ra0 e2p 06=7643
iwpriv ra0 e2p 08=5820

5 Abbreviations
CentOS yum:[jʌm],Yellowdog Updater,Modified
Ubuntu apt-get:Advanced Packaging Tool
BLA:bind()、listen()、accept()
BSS:Basic Service Set,AP或者IBSS或者STA
CNN:ConnectivityService、NetworkPolicyManagerService、NetworkStatsService(数据统计)、NetworkManagementService(最底层,物理网络接口的管理服务,与netd通信)
config_tether_upstream_types:Android手机配置为ApCli(AP-Client)时,作为Client的一方
config_tether_usb_regexs:regular expressions,正则表达式
genl:Generic Netlink
IBSS:Independent Basic Service Set,一般指ADHOC
MLME:Mac Layer Management Entity
NCM:nl80211-cfg80211-mac80211(包含ieee80211_ops);另一个意思是Network Control Model(iPhone CarPlay使用)
nl80211:使用netlink配置WiFi,代码层次关系从上到下分别是nl80211-cfg80211-mac80211(包含ieee80211_ops),缩写为NCM;而wext基于ioctl方式配置WiFi
RTS/CTS:Request To Send(STA发送给路由器),Clear To Send(由路由器发送给STA)
STA:STAtion
TAP/TUN:TUNnel
vif:Virtual Interface

发布了121 篇原创文章 · 获赞 49 · 访问量 32万+

猜你喜欢

转载自blog.csdn.net/zoosenpin/article/details/74738229
今日推荐