一、WifiStateMachine
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
IBinder b = ServiceManager.getService(Context.NETWORKMANAGERMENT_SERVICE);
mNwService = INetworkManagermentService.Stub.asInterface(b);
static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported);
{
return (jboolean)(::wifi_start_supplicant(p2pSupported) == 0);
}
static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject, jstring jIface)
{
ScopedUtfChars ifname(env, jIface);
return (jboolean)(::wifi_connect_to_supplicant(ifname.c_str()) == 0);
}
二、WiFi P2P
- Wifi- Direct 支持多个wifi设备在没有AP的情况下互相链接
- WifiP2pService和WifiServie类似,用于处理和P2P相关的工作
- 缩写为wifi peer to peer technical Specification
1.成组
- GO相当于AP,GC相当于STA
- 误区:在P2P网络中,GO等同于AP,所以Legacy Client也能搜索到GO,并且关联上它,但是由于Legacy Client不能处理P2P协议,所以一些特有功能不能在Lagacy client中实现。
2.简易流程
- Device构建P2P Group, 首先通过WSC获取安全信息,然后Client将利用协商好的安全设置信息去关联GO
3.基本要求
- 安全模块需要支持WPA2
- 支持WMM(wifi multimedia)
一些必须支持的项目
- 其中discovery重点描述的技术点;Group Operation描述了一个GO如何管理一个Group,本次略去;Power managerment描述电源管理,是如何省电的,本次略去
4.discovery
- 包含四个技术子项:
- Device discovery: 用于搜索周围P2p设备
- Service discovery: 支持搜索指定服务
- Group Formation: 用于决定是GO,谁是GC
- P2P Invitation: 用于激活一个Persistent Group, 或者邀请一个GC加入Group
- 利用两种帧,Probe Request和Probe Response,一个P2P设备既要发送Request又要发送Response来回复其它设备,然而在AP中,只有AP会发送Respose帧
- 详细工作流程
- Search state: 在2.4GHz的1,6,11频段上分别发送Probe request,三个频段称为Social Channels,为了区别非P2P的Probe Request帧,必选在帧中包含P2P IE
- Listen state: 设备随机在1,6,11频段中选择一个频段监听Request的帧并且回复response帧,选择的频段叫做listen channel,并且一旦选择好了,就不能更改了
- Scan Phase:主动发送request帧,该阶段不会处理其他设备的request帧
- Find Phase: 设备在search state和listen state之间来回切换,search state阶段会发送request帧,而listen阶段接受request帧并且发送回复respose帧
看我网上偷来的图
- 在Find Phase阶段,对Listen state时间进行了对子带哪个,时间是100TU的整倍数,处于两个默认值中间随机值1和3,该做法是为了保证两个设备交替变化,进入谁也扫描不到对方的尴尬境地。
5.Group Formation介绍
- 包含两个阶段:
- GO negotiation: 协商谁来做GO
- Provisioning: 借助WSC来交换安全配置信息,此后,GC就可以利用安全信息配置来关联GO
- 协商过程会利用一种名为P2p Public Action类型的帧来交换信息
- 协商的过程,经历三次帧交换,他们之间交换的报文,无需了解,知道了也会忘,知道个过程即可,如果要搞这种,再去详细了解
网上偷来的图,三次帧交换的过程,协商
- 三次帧分别为GON request 、GON response、GON confirmation,帧里面包含一些P2P 和WSC的属性信息
- GON request含GO Intent属性,表示对扮演GO的渴望程度,值越高越想成为GO,取值为1-15
- 谁能称为GO制定了游戏规则
- 通俗的讲谁的GO intent的值高,谁就是GO,如果一样呢,就要用到一个Tie Breaker是决胜要素,该字段为1的称为GO,Tie breaker是随机值,因此相同概率很低,取值也是0-1随机值
- 如果两个设备的GO intent都是15, 那谁也成不了GO
- P2P有两个地址,Intended P2P Interface Address,代表设备加入Group后的MAC地址,P2P device address,这个地址是在discovery之前用来成组的地址,是唯一的,不会变的,另一个地址是协商之后,生产的,Group解散了Interface address也就失效了
- GON response,中规定SSID必须以“direct-xy”开头,xy为随机的两个大小写字母或者数字
- GON Confiremation帧,如果发送者将扮演GO角色,需要在帧中包含Group ID属性
- P2P状态机流转如下,也不需要过多分析:
6.代码分析
- wifi P2p service的状态机
- 该模块有两个重要处理模块WifiP2pSettings和WifiP2pService, 代码懒得看了,流程搞懂就好了,service的代码都是一些处理细节,没有特别多的技术含量,不如WPA supplicant模块分析起来有价值,从网上抄了一段总结:
- (1)P2pStateMachine收到第一条消息CMD_ENABLE_P2P,创建一个WifiMonitor对象和wpa_supplicant进程尽心交互,状态机最后转入P2pEnablingState
- (2)P2pEnablingState中,状态机处理P2P_CONNECT_EVENT消息,代表WifiMonitor成功连接上了wpa_supplicant,处理结束后流转到Inactive State
- (3)InactiveState父状态为P2pEnabledState,该状态的EA将初始化P2P设置
- (4)状态机收到DISCOVER_PEERS消息,在EnabledState中被处理,wpa将发起discovery流程来搜索附近的P2P设备
- (5)状态搜索到设备将会收到一条消息P2P_DEVICE_FOUND_EVENT消息,进行处理
- (6)用户选择某个设备之后,settings发送CONNECT消息给状态机,转入ProvisionDiscoveryState
- (7)该状态通知WPAS开展Provisioning Discovery流程,顺利的话,状态机收到P2P_PROV_DISC_PBC_RSP_EVENT消息,通知WPAS和对端设备启动Group Formation流程,状态机转入GroupNeotiationState状态
- (8)GOurp创建王城,状态机收到P2P_GROUP_STARTED_EVENT消息,如果该设备扮演GO,将会启动DHCP,也就是dnsmasq
- (9)对端GC建立后,关联GO,AP_STA_CONNECTED_EVENT消息发个和状态机
下次分析难点wpa_supplicant P2P ,将逐行分析代码。
三、源码
- gitee路径:https://gitee.com/dongqianrui/AndroidStudioProject/tree/master/Test1
- CSDN:https://blog.csdn.net/weixin_44630050
- 博客园:https://www.cnblogs.com/ruigege0000/
- 欢迎关注微信公众号:傅里叶变换,个人账号,仅用于技术交流