LA WiFi How-to

1 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。

2 probe_request & Beacon
2.1 WIFI基本知识整理
http://blog.csdn.net/acs713/article/details/8740974

2.2 android wifi Scan Probe Request分析
http://blog.sina.com.cn/s/blog_a4f2bd7d01011b9k.html

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

3 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

4 LA WiFi
4.1 根据avc log自动生成Android Selinux策略
4.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

4.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

4.2 内核模块ko签名问题
4.2.1 KBA
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是不同的。

4.2.2 Linux ko模块编译脚本
4.2.2.1 Vendor
@ device/<vvv>/common/dlkm/AndroidKernelModule.mk

4.2.2.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

4.2.3 URLs
android安装内核module,提示Required key not available
https://blog.csdn.net/lewif/article/details/49305385

4.3 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() - 停止周期扫描

4.4 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);

    [...]
}

4.5 Android状态机机制
4.5.1 State和StateMachine
State.java - 状态,其它类继承该类,产生N多状态
StateMachine.java - 管理状态,其它类继承该类,生成State管理类

4.5.2 URLs
Android自定义增加系统服务和AIDL
https://blog.csdn.net/wds1181977/article/details/51851284

android状态机机制StateMachine
https://www.cnblogs.com/dongtaochen2039/archive/2012/03/31/2424626.html

4.6 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 4-1 Android状态机机制StateMachine
LA WiFi How-to

4.7 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);
                [...]
        }
    }
    [...]
}

4.8 URLs
Android WiFi 经常掉线出现的几个原因分析!
https://blog.csdn.net/chi_wy/article/details/50963279

5 iw How-to
5.1 Help
iw help
iw list

5.2 Trigger Scan
iw dev wlan0 scan

5.3 Virtual Interface
5.3.1 URLs
mac80211 Multiple Virtual Interface (vif) Support
https://wireless.wiki.kernel.org/en/users/Documentation/iw/vif

VirtualWifi同时 连接 多个AP
https://wenku.baidu.com/view/f982a011f5335a8103d22021.html

5.3.2 Add Vif
iw list
iw phy phy0 interface add <name> type <type>
or
iw dev wlan0 interface add <name> type <type>

- iw dev wlan0 interface add wlan1 type station

About using both interfaces at the same time and the message about them not being unique, this is probably because they both use the same MAC address. You can try to change the MAC address of the new interface before activating it.

ip link set dev <dev-name> address <new-mac-address>

5.3.3 Del Vif
iw dev <name> del
- iw dev wlan1 del

5.4 Set the Channel or Frequency
iw dev <devname> set channel <channel>
- iw dev mon0 set channel 7

5.5 获得链路状态
iw dev wlan0 link

5.6 Monitor Netlink Event
iw event -f -t

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

7 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