P2P GO Client角色的协商

zjli321 · · 4582 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1 P2P GO Client协商流程

 协商流程
P2P GO/Client的协商流程只需要简单的几步,如下图:
P2P连接发起端:指在P2P连接过程中主动发起P2P连接的机子,用A表示;
P2P连接接受端:指在P2P连接过程中接受P2P连接的机子,用B表示;

这里写图片描述
图1 P2P GO/Client协商流程
如上图所示:
1、 首先A在P2P连接初始化准备完成后,发送一个“GO Negotiation Request”给B;
2、 而这时候,B并没有准备好,这时B先保存下A的协商信息,然后发送一个“GO Negotiation Response”给A,该response包含有B的协商信息,但在该response中,B把状态state设置为P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE,表示当前P2P连接不可用;
3、 A在接收到该response后,保存B的协商信息,切换到Listen state,等待B的P2P连接初始化完成,并等待B发送“GO Negotiation Request”。所以第一次的协商并没有确定任何东西,主要用来通知B,A需要与B进行P2P连接;
4、 B在发送“GO Negotiation Response”后,进行P2P连接初始化,B在P2P连接初始化完成后,就发送一个“GO Negotiation Request”给A;
5、 而A在收到B的Request后,根据该Request的协商信息,就可以确定自己在P2P连接时的角色了。这时A发送一个“GO Negotiation Response”给B,在该Response中,state为P2P_SC_SUCCESS,表示可以进行P2P连接;
6、 B在收到A的Response后,也可以确定自己在P2P连接时的角色了;
7、 最后B发送一个“GO Negotiation Confirm”给A,该Confirm作用之一是作为协商的确认,同时确定了后面P2P连接所使用的信道;

在P2P GO/Client协商完成后,作为GO角色的设备后面就把自己切换到AP模式,而作为Client角色的设备就去连接GO的AP。

 协商时Request/Response内容
Request的部内容:
* Dialog Token: 1
Parsing WPS IE
Device Password ID: 4
Parsing P2P IE
Attribute 2 length 2
* Device Capability 21 Group Capability 2a
Attribute 4 length 1
* GO Intent: Intent 6 Tie breaker 0
Attribute 5 length 2
* Configuration Timeout
Attribute 6 length 5
* Listen Channel: Country XX(0x04) Regulatory Class 81 Channel Number 6
Attribute 9 length 6
* Intended P2P Interface Address: 96:bd:db:15:b9:38
Attribute 11 length 16
* Channel List: Country String ‘XX(0x04)’
Attribute 13 length 33
* Device Info: addr 96:bd:db:15:b9:38 primary device type 10-0050F204-5 device name ‘Android_dd11’ config methods 0x80
Attribute 17 length 5
* Operating Channel: Country XX(0x04) Regulatory Class 81 Channel Number 11 Peer country - hexdump(len=3): 58 58 04
其中* GO Intent: Intent 6 Tie breaker 0就是用于确定GO/Client角色的。

Response的部分内容:

* Dialog Token: 2
Parsing WPS IE
Device Password ID: 0
Parsing P2P IE
Attribute 0 length 1
* Status: 1
Attribute 2 length 2
* Device Capability 21 Group Capability 00
Attribute 4 length 1
* GO Intent: Intent 6 Tie breaker 0
Attribute 5 length 2
* Configuration Timeout
Attribute 17 length 5
* Operating Channel: Country XX(0x04) Regulatory Class 81 Channel Number 11
Attribute 9 length 6
* Intended P2P Interface Address: 96:bd:db:15:b9:38
Attribute 11 length 16
* Channel List: Country String ‘XX(0x04)’
Attribute 13 length 33
* Device Info: addr 96:bd:db:15:b9:38 primary device type 10-0050F204-5 device name ‘Android_dd11’ config methods 0x188

Confirm的部分内容:

* Dialog Token: 1
Parsing P2P IE
Attribute 0 length 1
* Status: 0
Attribute 2 length 2
* Device Capability 21 Group Capability 00
Attribute 17 length 5
* Operating Channel: Country XX(0x04) Regulatory Class 81 Channel Number 11
Attribute 11 length 16
* Channel List: Country String ‘XX(0x04)’

 P2P连接时的P2P命令
P2P连接发起端命令:
p2p-dev-wlan0: Control interface command ‘P2P_FIND 120’
p2p-dev-wlan0: Control interface command ‘P2P_STOP_FIND’
p2p-dev-wlan0: Control interface command ‘P2P_PEER 96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘P2P_PEER 96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘P2P_PROV_DISC 96:bd:db:15:b9:38 pbc’
p2p-dev-wlan0: Control interface command ‘P2P_PEER 96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘P2P_CONNECT 96:bd:db:15:b9:38 pbc persistent go_intent=6 ’
p2p-dev-wlan0: Control interface command ‘LIST_NETWORKS’
p2p-dev-wlan0: Control interface command ‘GET_NETWORK 0 mode’
p2p-wlan0-1: Control interface command ‘SET p2p_group_idle 10’
p2p-wlan0-1: Control interface command ‘SET p2p_group_idle 0’
不同厂家实现P2P wlan口的方式不一样,这只是一种实现方式,其中p2p-dev-wlan0为虚拟的网口,在P2P扫描、协商阶段都是使用该网口,p2p-wlan0-1内核实际注册的网口,实际P2P的连接就是使用该网口,p2p-wlan0-1网口在接收到P2P_CONNECT命令时才创建,该厂家p2p-wlan0-1网口的创建是由supplicant层通过nl80211 driver的wpa_driver_nl80211_if_add函数调用内核进行创建,最终调用到wifi驱动的wl_cfg80211_add_virtual_iface进行网口的创建,该函数虽然看起来只是增加虚拟网口,但也是可以创建实际的网口的,p2p-dev-wlan0(虚拟网口)与p2p-wlan0-1(实际网口)都是由该函数创建的。在这里整个协商过程是在收到P2P_CONNECT命令后才开始的。

P2P连接发起端命令:
p2p-dev-wlan0: Control interface command ‘P2P_FIND 120’
p2p-dev-wlan0: Control interface command ‘P2P_STOP_FIND’
p2p-dev-wlan0: Control interface command ‘P2P_PEER 96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘P2P_CONNECT 96:bd:db:15:b9:38 pbc persistent go_intent=6 ’
p2p-dev-wlan0: Control interface command ‘LIST_NETWORKS’
p2p-dev-wlan0: Control interface command ‘GET_NETWORK 0 mode’
p2p-wlan0-6: Control interface command ‘SET p2p_group_idle 10’
在P2P连接接受端,当上层确认允许P2P连接时,先P2P_STOP_FIND,再往下发送P2P_PEER、P2P_CONNECT,这是就会创建实际的P2P连接网口p2p-wlan0-6,然后就是发送一个“GO Negotiation Request”。

2 已保存群组时的协商过程

在P2P连接完成后,若P2P连接断开后,再发起P2P连接,并不一定都需要P2P GO/Client的协商过程,这依赖双方是否都保存有P2P连接信息。下面先介绍P2P连接后保存的信息,作为GO或Client时,保存的信息并不相同。
 作为GO时保存的信息如下:
network={
ssid=”DIRECT-ZT-Android_7ab3”
bssid=6e:fa:a7:dc:14:d6
psk=”zT32EqmT”
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
mode=3
disabled=2
p2p_client_list=96:bd:db:15:b9:38
}
ssid:GO的名称;
bssid:GO自己的mac地址;
psk:GO的密码;
p2p_client_list:所连接的Client的mac地址;
 作为Client时保存的信息如下:
network={
ssid=”DIRECT-H0-Android_dd11”
bssid=96:bd:db:15:b9:38
psk=03e45fa923d8fbaf58920fdb484487bf19a98090d23278c72e326bfea44a9b50
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
disabled=2
}
ssid:所连接GO的名称;
bssid:所连接GO的mac地址;
psk:所连接GO的密码,已加密;

 不同情况下的P2P连接差异
1、 设备双方都没有保存有P2P连接信息
该情况就走第一节介绍的协商过程。
2、 设备双方都保存有P2P连接信息
这种情况下,由于双方都保存有P2P连接信息,就根据上次P2P连接的信息连接就可以了,也就是上次是做GO的,还是做GO,做Client的也一样,同时GO的名称,mac地址,密码,Client mac地址都是知道的,所以不需要再协商了,
只要GO/Client任意一端发起连接就可以了,但这次就不需要发送P2P_CONNECT命令了,只要发送P2P_INVITE命令就可以了,命令如下:
p2p-dev-wlan0: Control interface command ‘P2P_INVITE persistent=0 peer=96:bd:db:15:b9:38’
3、 发起端没有保存P2P连接信息,接受端保存有P2P连接信息
由于发起端没有保存P2P连接信息,也没有选择了,也是走第一节介绍的协商过程。
4、 发起端保存有P2P连接信息,接受端没有保存P2P连接信息
由于发起端保存有P2P连接信息,所以发起端先发送P2P_INVITE,但由于接受端没有保存有P2P连接信息,这次的P2P_INVITE以失败告终,后面就是走第一节介绍的协商过程了。整个命令过程如下:
p2p-dev-wlan0: Control interface command ‘P2P_FIND 120’
p2p-dev-wlan0: Control interface command ‘P2P_STOP_FIND’
p2p-dev-wlan0: Control interface command ‘P2P_PEER 96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘P2P_PEER 96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘P2P_INVITE persistent=0 peer=96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘GET_NETWORK 0 p2p_client_list’
p2p-dev-wlan0: Control interface command ‘REMOVE_NETWORK 0’
p2p-dev-wlan0: Control interface command ‘P2P_PEER 96:bd:db:15:b9:38’
p2p-dev-wlan0: Control interface command ‘P2P_CONNECT 96:bd:db:15:b9:38 pbc persistent go_intent=6 ’
p2p-dev-wlan0: Control interface command ‘LIST_NETWORKS’
p2p-dev-wlan0: Control interface command ‘GET_NETWORK 0 mode’
p2p-wlan0-13: Control interface command ‘SET p2p_group_idle 10’

3 GO Client角色的协商过程

 协商参数
协商过程中,GO、Client角色由两个参数确定:
Intent:作为GO的优先级;
breaker:在Intent相同是,用于判定谁做GO;
Intent的取值范围为:0~1(#define P2P_MAX_GO_INTENT 15)
该Intent初始化时为0,在每次P2P_CONNECT时,由上层传下来,android系统下,java层默认为6,该定义在:
/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
在协商时,谁的Intent值大,谁就作为GO;如果一端指定Intent值为15(P2P_MAX_GO_INTENT)那这端是GO,如果两端都指定Intent为15,那这次的协商就会失败。在协商两端的值都不为15,并且值相等的情况下,就要breaker的值进行判定谁做GO了。
breaker的值只有0或1,该值在初始化时采用随机生成:
if (os_get_random(&p2p->next_tie_breaker, 1) < 0)
p2p->next_tie_breaker = 0;
p2p->next_tie_breaker &= 0x01;

dev->tie_breaker = p2p->next_tie_breaker;
p2p->next_tie_breaker = !p2p->next_tie_breaker;
breaker值在每次发起P2P_CONNECT时都取反一次,这样做的目的是在双方的Intent值相同的情况下,多次协商时,双方都有机会做GO。并且在发送Request时才填入自己的breaker值,在回应Response时,是把对方的breaker值取反后作为breaker值发送。
在协商流程中,由第二次Request/Response的Intent、breaker值决定谁做GO,这是谁的Intent(非15的情况下)值大谁就做GO,当Intent值相同时,这时由发送Request端的breaker值确定谁做GO,当发送Request端的breaker的值为1时,发送Request端作为GO,反之则作为Client。接收Request端的就刚好相反。

 参数在协商阶段的作用
这里结合图1进行说明:
1、 A发送Request给B,该Request包含A的Intent、breaker值;
2、 B收到Request后,由于B还没准备好,回应一个Response给A,该Response中包含B的Intent值,同时把A的breaker值取反作为breaker填入Response中。在wifi打开的首次接受P2P连接时,由于B上层还没有调用过P2P_CONNECT,这时的Intent值为0,但这次的Intent值不影响最后的GO、Client判定;
3、 上面个这个回合的Request/Response不做GO、Client判定;
4、 B发送Request给A,该Request包含A的Intent、breaker值;
5、 A收到Request后,回应一个Response给B,该Response中包含A的Intent值,同时把B的breaker值取反作为breaker填入Response中;
6、 在这回合的Request/Response中,就决定了谁做GO,谁的Intent(非15的情况下)值大谁就做GO,在Intent相同的情况下,若B的breaker值为1,则B做GO,若B的breaker值为0,则B做Client,A的角色则刚好与B相反;

可以看到,最终的GO、Client角色是在第二回合的Request/Response中决定的。


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:zjli321

查看原文:P2P GO Client角色的协商

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4582 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传