2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
8 logger
= logging
.getLogger()
15 MGMT_SUBTYPE_PROBE_REQ
= 4
16 MGMT_SUBTYPE_ACTION
= 13
17 ACTION_CATEG_PUBLIC
= 4
22 P2P_INVITATION_REQ
= 3
23 P2P_INVITATION_RESP
= 4
27 P2P_PROV_DISC_RESP
= 8
30 P2P_ATTR_MINOR_REASON_CODE
= 1
31 P2P_ATTR_CAPABILITY
= 2
32 P2P_ATTR_DEVICE_ID
= 3
33 P2P_ATTR_GROUP_OWNER_INTENT
= 4
34 P2P_ATTR_CONFIGURATION_TIMEOUT
= 5
35 P2P_ATTR_LISTEN_CHANNEL
= 6
36 P2P_ATTR_GROUP_BSSID
= 7
37 P2P_ATTR_EXT_LISTEN_TIMING
= 8
38 P2P_ATTR_INTENDED_INTERFACE_ADDR
= 9
39 P2P_ATTR_MANAGEABILITY
= 10
40 P2P_ATTR_CHANNEL_LIST
= 11
41 P2P_ATTR_NOTICE_OF_ABSENCE
= 12
42 P2P_ATTR_DEVICE_INFO
= 13
43 P2P_ATTR_GROUP_INFO
= 14
44 P2P_ATTR_GROUP_ID
= 15
45 P2P_ATTR_INTERFACE
= 16
46 P2P_ATTR_OPERATING_CHANNEL
= 17
47 P2P_ATTR_INVITATION_FLAGS
= 18
48 P2P_ATTR_OOB_GO_NEG_CHANNEL
= 19
49 P2P_ATTR_SERVICE_HASH
= 21
50 P2P_ATTR_SESSION_INFORMATION_DATA
= 22
51 P2P_ATTR_CONNECTION_CAPABILITY
= 23
52 P2P_ATTR_ADVERTISEMENT_ID
= 24
53 P2P_ATTR_ADVERTISED_SERVICE
= 25
54 P2P_ATTR_SESSION_ID
= 26
55 P2P_ATTR_FEATURE_CAPABILITY
= 27
56 P2P_ATTR_PERSISTENT_GROUP
= 28
57 P2P_ATTR_VENDOR_SPECIFIC
= 221
60 P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
= 1
61 P2P_SC_FAIL_INCOMPATIBLE_PARAMS
= 2
62 P2P_SC_FAIL_LIMIT_REACHED
= 3
63 P2P_SC_FAIL_INVALID_PARAMS
= 4
64 P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE
= 5
65 P2P_SC_FAIL_PREV_PROTOCOL_ERROR
= 6
66 P2P_SC_FAIL_NO_COMMON_CHANNELS
= 7
67 P2P_SC_FAIL_UNKNOWN_GROUP
= 8
68 P2P_SC_FAIL_BOTH_GO_INTENT_15
= 9
69 P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD
= 10
70 P2P_SC_FAIL_REJECTED_BY_USER
= 11
72 WSC_ATTR_CONFIG_METHODS
= 0x1008
75 WLAN_EID_SUPP_RATES
= 1
76 WLAN_EID_VENDOR_SPECIFIC
= 221
78 def go_neg_pin_authorized_persistent(i_dev
, r_dev
, i_intent
=None, r_intent
=None,
79 i_method
='enter', r_method
='display',
80 test_data
=True, r_listen
=True):
84 pin
= r_dev
.wps_read_pin()
85 logger
.info("Start GO negotiation " + i_dev
.ifname
+ " -> " + r_dev
.ifname
)
86 r_dev
.p2p_go_neg_auth(i_dev
.p2p_dev_addr(), pin
, r_method
,
87 go_intent
=r_intent
, persistent
=True)
90 i_res
= i_dev
.p2p_go_neg_init(r_dev
.p2p_dev_addr(), pin
, i_method
,
91 timeout
=20, go_intent
=i_intent
,
93 r_res
= r_dev
.p2p_go_neg_auth_result()
94 logger
.debug("i_res: " + str(i_res
))
95 logger
.debug("r_res: " + str(r_res
))
98 logger
.info("Group formed")
100 hwsim_utils
.test_connectivity_p2p(r_dev
, i_dev
)
101 return [i_res
, r_res
]
103 def terminate_group(go
, cli
):
104 logger
.info("Terminate persistent group")
106 cli
.wait_go_ending_session()
108 def invite(inv
, resp
, extra
=None, persistent_reconnect
=True, use_listen
=True):
109 addr
= resp
.p2p_dev_addr()
110 if persistent_reconnect
:
111 resp
.global_request("SET persistent_reconnect 1")
113 resp
.global_request("SET persistent_reconnect 0")
117 resp
.p2p_find(social
=True)
118 if not inv
.discover_peer(addr
, social
=True):
119 raise Exception("Peer " + addr
+ " not found")
121 peer
= inv
.get_peer(addr
)
122 cmd
= "P2P_INVITE persistent=" + peer
['persistent'] + " peer=" + addr
124 cmd
= cmd
+ " " + extra
125 inv
.global_request(cmd
)
127 def check_result(go
, cli
):
128 ev
= go
.wait_global_event(["P2P-GROUP-STARTED",
129 "Failed to start AP functionality"], timeout
=30)
131 raise Exception("Timeout on group re-invocation (on GO)")
132 if "P2P-GROUP-STARTED" not in ev
:
133 raise Exception("GO failed to start the group for re-invocation")
134 if "[PERSISTENT]" not in ev
:
135 raise Exception("Re-invoked group not marked persistent")
136 go_res
= go
.group_form_result(ev
)
137 if go_res
['role'] != 'GO':
138 raise Exception("Persistent group GO did not become GO")
139 if not go_res
['persistent']:
140 raise Exception("Persistent group not re-invoked as persistent (GO)")
141 ev
= cli
.wait_global_event(["P2P-GROUP-STARTED"], timeout
=30)
143 raise Exception("Timeout on group re-invocation (on client)")
144 if "[PERSISTENT]" not in ev
:
145 raise Exception("Re-invoked group not marked persistent")
146 cli_res
= cli
.group_form_result(ev
)
147 if cli_res
['role'] != 'client':
148 raise Exception("Persistent group client did not become client")
149 if not cli_res
['persistent']:
150 raise Exception("Persistent group not re-invoked as persistent (cli)")
151 return [go_res
, cli_res
]
153 def form(go
, cli
, test_data
=True, reverse_init
=False, r_listen
=True):
154 logger
.info("Form a persistent group")
156 [i_res
, r_res
] = go_neg_pin_authorized_persistent(i_dev
=cli
, i_intent
=0,
157 r_dev
=go
, r_intent
=15,
161 [i_res
, r_res
] = go_neg_pin_authorized_persistent(i_dev
=go
, i_intent
=15,
162 r_dev
=cli
, r_intent
=0,
165 if not i_res
['persistent'] or not r_res
['persistent']:
166 raise Exception("Formed group was not persistent")
167 terminate_group(go
, cli
)
173 def invite_from_cli(go
, cli
, terminate
=True):
174 logger
.info("Re-invoke persistent group from client")
176 [go_res
, cli_res
] = check_result(go
, cli
)
177 hwsim_utils
.test_connectivity_p2p(go
, cli
)
179 terminate_group(go
, cli
)
180 return [go_res
, cli_res
]
182 def invite_from_go(go
, cli
, terminate
=True, extra
=None):
183 logger
.info("Re-invoke persistent group from GO")
184 invite(go
, cli
, extra
=extra
)
185 [go_res
, cli_res
] = check_result(go
, cli
)
186 hwsim_utils
.test_connectivity_p2p(go
, cli
)
188 terminate_group(go
, cli
)
189 return [go_res
, cli_res
]
191 def autogo(go
, freq
=None, persistent
=None):
192 logger
.info("Start autonomous GO " + go
.ifname
)
193 res
= go
.p2p_start_go(freq
=freq
, persistent
=persistent
)
194 logger
.debug("res: " + str(res
))
197 def connect_cli(go
, client
, social
=False, freq
=None):
198 logger
.info("Try to connect the client to the GO")
199 pin
= client
.wps_read_pin()
200 go
.p2p_go_authorize_client(pin
)
201 res
= client
.p2p_connect_group(go
.p2p_dev_addr(), pin
, timeout
=60,
202 social
=social
, freq
=freq
)
203 logger
.info("Client connected")
204 hwsim_utils
.test_connectivity_p2p(go
, client
)
207 def check_grpform_results(i_res
, r_res
):
208 if i_res
['result'] != 'success' or r_res
['result'] != 'success':
209 raise Exception("Failed group formation")
210 if i_res
['ssid'] != r_res
['ssid']:
211 raise Exception("SSID mismatch")
212 if i_res
['freq'] != r_res
['freq']:
213 raise Exception("freq mismatch")
214 if 'go_neg_freq' in r_res
and i_res
['go_neg_freq'] != r_res
['go_neg_freq']:
215 raise Exception("go_neg_freq mismatch")
216 if i_res
['freq'] != i_res
['go_neg_freq']:
217 raise Exception("freq/go_neg_freq mismatch")
218 if i_res
['role'] != i_res
['go_neg_role']:
219 raise Exception("role/go_neg_role mismatch")
220 if 'go_neg_role' in r_res
and r_res
['role'] != r_res
['go_neg_role']:
221 raise Exception("role/go_neg_role mismatch")
222 if i_res
['go_dev_addr'] != r_res
['go_dev_addr']:
223 raise Exception("GO Device Address mismatch")
225 def go_neg_init(i_dev
, r_dev
, pin
, i_method
, i_intent
, res
):
226 logger
.debug("Initiate GO Negotiation from i_dev")
228 i_res
= i_dev
.p2p_go_neg_init(r_dev
.p2p_dev_addr(), pin
, i_method
, timeout
=20, go_intent
=i_intent
)
229 logger
.debug("i_res: " + str(i_res
))
230 except Exception as e
:
232 logger
.info("go_neg_init thread caught an exception from p2p_go_neg_init: " + str(e
))
235 def go_neg_pin(i_dev
, r_dev
, i_intent
=None, r_intent
=None, i_method
='enter', r_method
='display'):
238 pin
= r_dev
.wps_read_pin()
239 logger
.info("Start GO negotiation " + i_dev
.ifname
+ " -> " + r_dev
.ifname
)
242 t
= threading
.Thread(target
=go_neg_init
, args
=(i_dev
, r_dev
, pin
, i_method
, i_intent
, res
))
244 logger
.debug("Wait for GO Negotiation Request on r_dev")
245 ev
= r_dev
.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout
=15)
247 raise Exception("GO Negotiation timed out")
249 logger
.debug("Re-initiate GO Negotiation from r_dev")
250 r_res
= r_dev
.p2p_go_neg_init(i_dev
.p2p_dev_addr(), pin
, r_method
, go_intent
=r_intent
, timeout
=20)
251 logger
.debug("r_res: " + str(r_res
))
256 raise Exception("go_neg_init thread failed")
257 logger
.debug("i_res: " + str(i_res
))
258 logger
.info("Group formed")
259 hwsim_utils
.test_connectivity_p2p(r_dev
, i_dev
)
261 return [i_res
, r_res
]
263 def go_neg_pin_authorized(i_dev
, r_dev
, i_intent
=None, r_intent
=None,
264 expect_failure
=False, i_go_neg_status
=None,
265 i_method
='enter', r_method
='display', test_data
=True,
266 i_freq
=None, r_freq
=None,
267 i_freq2
=None, r_freq2
=None,
268 i_max_oper_chwidth
=None, r_max_oper_chwidth
=None,
269 i_ht40
=False, i_vht
=False, r_ht40
=False, r_vht
=False):
271 pin
= r_dev
.wps_read_pin()
272 logger
.info("Start GO negotiation " + i_dev
.ifname
+ " -> " + r_dev
.ifname
)
273 r_dev
.p2p_go_neg_auth(i_dev
.p2p_dev_addr(), pin
, r_method
,
274 go_intent
=r_intent
, freq
=r_freq
, freq2
=r_freq2
,
275 max_oper_chwidth
=r_max_oper_chwidth
, ht40
=r_ht40
,
278 i_res
= i_dev
.p2p_go_neg_init(r_dev
.p2p_dev_addr(), pin
, i_method
,
279 timeout
=20, go_intent
=i_intent
,
280 expect_failure
=expect_failure
, freq
=i_freq
,
282 max_oper_chwidth
=i_max_oper_chwidth
,
283 ht40
=i_ht40
, vht
=i_vht
)
284 r_res
= r_dev
.p2p_go_neg_auth_result(expect_failure
=expect_failure
)
285 logger
.debug("i_res: " + str(i_res
))
286 logger
.debug("r_res: " + str(r_res
))
290 if i_res
['result'] != 'go-neg-failed':
291 raise Exception("Expected GO Negotiation failure not reported")
292 if i_res
['status'] != i_go_neg_status
:
293 raise Exception("Expected GO Negotiation status not seen")
296 logger
.info("Group formed")
298 hwsim_utils
.test_connectivity_p2p(r_dev
, i_dev
)
299 return [i_res
, r_res
]
301 def go_neg_init_pbc(i_dev
, r_dev
, i_intent
, res
, freq
, provdisc
):
302 logger
.debug("Initiate GO Negotiation from i_dev")
304 i_res
= i_dev
.p2p_go_neg_init(r_dev
.p2p_dev_addr(), None, "pbc",
305 timeout
=20, go_intent
=i_intent
, freq
=freq
,
307 logger
.debug("i_res: " + str(i_res
))
308 except Exception as e
:
310 logger
.info("go_neg_init_pbc thread caught an exception from p2p_go_neg_init: " + str(e
))
313 def go_neg_pbc(i_dev
, r_dev
, i_intent
=None, r_intent
=None, i_freq
=None, r_freq
=None, provdisc
=False, r_listen
=False):
317 r_dev
.p2p_find(social
=True)
318 i_dev
.p2p_find(social
=True)
319 logger
.info("Start GO negotiation " + i_dev
.ifname
+ " -> " + r_dev
.ifname
)
322 t
= threading
.Thread(target
=go_neg_init_pbc
, args
=(i_dev
, r_dev
, i_intent
, res
, i_freq
, provdisc
))
324 logger
.debug("Wait for GO Negotiation Request on r_dev")
325 ev
= r_dev
.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout
=15)
327 raise Exception("GO Negotiation timed out")
329 # Allow some time for the GO Neg Resp to go out before initializing new
332 logger
.debug("Re-initiate GO Negotiation from r_dev")
333 r_res
= r_dev
.p2p_go_neg_init(i_dev
.p2p_dev_addr(), None, "pbc",
334 go_intent
=r_intent
, timeout
=20, freq
=r_freq
)
335 logger
.debug("r_res: " + str(r_res
))
340 raise Exception("go_neg_init_pbc thread failed")
341 logger
.debug("i_res: " + str(i_res
))
342 logger
.info("Group formed")
343 hwsim_utils
.test_connectivity_p2p(r_dev
, i_dev
)
345 return [i_res
, r_res
]
347 def go_neg_pbc_authorized(i_dev
, r_dev
, i_intent
=None, r_intent
=None,
348 expect_failure
=False, i_freq
=None, r_freq
=None):
350 logger
.info("Start GO negotiation " + i_dev
.ifname
+ " -> " + r_dev
.ifname
)
351 r_dev
.p2p_go_neg_auth(i_dev
.p2p_dev_addr(), None, "pbc",
352 go_intent
=r_intent
, freq
=r_freq
)
354 i_res
= i_dev
.p2p_go_neg_init(r_dev
.p2p_dev_addr(), None, "pbc", timeout
=20,
356 expect_failure
=expect_failure
, freq
=i_freq
)
357 r_res
= r_dev
.p2p_go_neg_auth_result(expect_failure
=expect_failure
)
358 logger
.debug("i_res: " + str(i_res
))
359 logger
.debug("r_res: " + str(r_res
))
364 logger
.info("Group formed")
365 return [i_res
, r_res
]
367 def remove_group(dev1
, dev2
):