1# P2P vendor specific extension tests
2# Copyright (c) 2014-2015, Qualcomm Atheros, Inc.
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7from remotehost import remote_compatible
8import logging
9logger = logging.getLogger()
10import os
11
12from tshark import run_tshark
13from p2p_utils import *
14
15@remote_compatible
16def test_p2p_ext_discovery(dev):
17    """P2P device discovery with vendor specific extensions"""
18    addr0 = dev[0].p2p_dev_addr()
19    addr1 = dev[1].p2p_dev_addr()
20
21    try:
22        if "OK" not in dev[0].request("VENDOR_ELEM_ADD 1 dd050011223344"):
23            raise Exception("VENDOR_ELEM_ADD failed")
24        res = dev[0].request("VENDOR_ELEM_GET 1")
25        if res != "dd050011223344":
26            raise Exception("Unexpected VENDOR_ELEM_GET result: " + res)
27        if "OK" not in dev[0].request("VENDOR_ELEM_ADD 1 dd06001122335566"):
28            raise Exception("VENDOR_ELEM_ADD failed")
29        res = dev[0].request("VENDOR_ELEM_GET 1")
30        if res != "dd050011223344dd06001122335566":
31            raise Exception("Unexpected VENDOR_ELEM_GET result(2): " + res)
32        res = dev[0].request("VENDOR_ELEM_GET 2")
33        if res != "":
34            raise Exception("Unexpected VENDOR_ELEM_GET result(3): " + res)
35        if "OK" not in dev[0].request("VENDOR_ELEM_REMOVE 1 dd050011223344"):
36            raise Exception("VENDOR_ELEM_REMOVE failed")
37        res = dev[0].request("VENDOR_ELEM_GET 1")
38        if res != "dd06001122335566":
39            raise Exception("Unexpected VENDOR_ELEM_GET result(4): " + res)
40        if "OK" not in dev[0].request("VENDOR_ELEM_REMOVE 1 dd06001122335566"):
41            raise Exception("VENDOR_ELEM_REMOVE failed")
42        res = dev[0].request("VENDOR_ELEM_GET 1")
43        if res != "":
44            raise Exception("Unexpected VENDOR_ELEM_GET result(5): " + res)
45        if "OK" not in dev[0].request("VENDOR_ELEM_ADD 1 dd050011223344dd06001122335566"):
46            raise Exception("VENDOR_ELEM_ADD failed(2)")
47
48        if "FAIL" not in dev[0].request("VENDOR_ELEM_REMOVE 1 dd051122334455"):
49            raise Exception("Unexpected VENDOR_ELEM_REMOVE success")
50        if "FAIL" not in dev[0].request("VENDOR_ELEM_REMOVE 1 dd"):
51            raise Exception("Unexpected VENDOR_ELEM_REMOVE success(2)")
52        if "FAIL" not in dev[0].request("VENDOR_ELEM_ADD 1 ddff"):
53            raise Exception("Unexpected VENDOR_ELEM_ADD success(3)")
54
55        dev[0].p2p_listen()
56        if not dev[1].discover_peer(addr0):
57            raise Exception("Device discovery timed out")
58        if not dev[0].discover_peer(addr1):
59            raise Exception("Device discovery timed out")
60
61        peer = dev[1].get_peer(addr0)
62        if peer['vendor_elems'] != "dd050011223344dd06001122335566":
63            raise Exception("Vendor elements not reported correctly")
64
65        res = dev[0].request("VENDOR_ELEM_GET 1")
66        if res != "dd050011223344dd06001122335566":
67            raise Exception("Unexpected VENDOR_ELEM_GET result(6): " + res)
68        if "OK" not in dev[0].request("VENDOR_ELEM_REMOVE 1 dd06001122335566"):
69            raise Exception("VENDOR_ELEM_REMOVE failed")
70        res = dev[0].request("VENDOR_ELEM_GET 1")
71        if res != "dd050011223344":
72            raise Exception("Unexpected VENDOR_ELEM_GET result(7): " + res)
73    finally:
74        dev[0].request("VENDOR_ELEM_REMOVE 1 *")
75
76@remote_compatible
77def test_p2p_ext_discovery_go(dev):
78    """P2P device discovery with vendor specific extensions for GO"""
79    addr0 = dev[0].p2p_dev_addr()
80    addr1 = dev[1].p2p_dev_addr()
81
82    try:
83        if "OK" not in dev[0].request("VENDOR_ELEM_ADD 2 dd050011223344dd06001122335566"):
84            raise Exception("VENDOR_ELEM_ADD failed")
85        if "OK" not in dev[0].request("VENDOR_ELEM_ADD 3 dd050011223344dd06001122335566"):
86            raise Exception("VENDOR_ELEM_ADD failed")
87        if "OK" not in dev[0].request("VENDOR_ELEM_ADD 12 dd050011223344dd06001122335566"):
88            raise Exception("VENDOR_ELEM_ADD failed")
89
90        dev[0].p2p_start_go(freq="2412")
91        if not dev[1].discover_peer(addr0):
92            raise Exception("Device discovery timed out")
93        peer = dev[1].get_peer(addr0)
94        if peer['vendor_elems'] != "dd050011223344dd06001122335566":
95            logger.info("Peer vendor_elems: " + peer['vendor_elems'])
96            raise Exception("Vendor elements not reported correctly")
97    finally:
98        dev[0].request("VENDOR_ELEM_REMOVE 2 *")
99        dev[0].request("VENDOR_ELEM_REMOVE 3 *")
100        dev[0].request("VENDOR_ELEM_REMOVE 12 *")
101
102def test_p2p_ext_vendor_elem_probe_req(dev):
103    """VENDOR_ELEM in P2P Probe Request frames"""
104    try:
105        _test_p2p_ext_vendor_elem_probe_req(dev)
106    finally:
107        dev[0].request("VENDOR_ELEM_REMOVE 0 *")
108
109def _test_p2p_ext_vendor_elem_probe_req(dev):
110    addr1 = dev[1].p2p_dev_addr()
111    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 0 dd050011223300"):
112        raise Exception("VENDOR_ELEM_ADD failed")
113    dev[1].p2p_listen()
114    if not dev[0].discover_peer(addr1):
115        raise Exception("Device discovery timed out")
116    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
117        raise Exception("Failed to enable external management frame handling")
118    ev = dev[1].wait_event(["MGMT-RX"], timeout=5)
119    if ev is None:
120        raise Exception("MGMT-RX timeout")
121    if " 40" not in ev:
122        raise Exception("Not a Probe Request frame")
123    if "dd050011223300" not in ev:
124        raise Exception("Vendor element not found from Probe Request frame")
125    dev[0].p2p_stop_find()
126    dev[1].p2p_stop_find()
127
128def test_p2p_ext_vendor_elem_pd_req(dev):
129    """VENDOR_ELEM in PD Request frames"""
130    try:
131        _test_p2p_ext_vendor_elem_pd_req(dev)
132    finally:
133        dev[0].request("VENDOR_ELEM_REMOVE 4 *")
134
135def _test_p2p_ext_vendor_elem_pd_req(dev):
136    addr0 = dev[0].p2p_dev_addr()
137    addr1 = dev[1].p2p_dev_addr()
138    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 4 dd050011223301"):
139        raise Exception("VENDOR_ELEM_ADD failed")
140    dev[1].p2p_listen()
141    if not dev[0].discover_peer(addr1):
142        raise Exception("Device discovery timed out")
143    dev[0].p2p_stop_find()
144    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
145        raise Exception("Failed to enable external management frame handling")
146    dev[0].global_request("P2P_PROV_DISC " + addr1 + " display")
147    for i in range(5):
148        ev = dev[1].wait_event(["MGMT-RX"], timeout=5)
149        if ev is None:
150            raise Exception("MGMT-RX timeout")
151        if " d0" in ev:
152            break
153    if "dd050011223301" not in ev:
154        raise Exception("Vendor element not found from PD Request frame")
155    dev[1].p2p_stop_find()
156    dev[0].p2p_stop_find()
157
158def test_p2p_ext_vendor_elem_pd_resp(dev):
159    """VENDOR_ELEM in PD Response frames"""
160    try:
161        _test_p2p_ext_vendor_elem_pd_resp(dev)
162    finally:
163        dev[0].request("VENDOR_ELEM_REMOVE 5 *")
164
165def _test_p2p_ext_vendor_elem_pd_resp(dev):
166    addr0 = dev[0].p2p_dev_addr()
167    addr1 = dev[1].p2p_dev_addr()
168    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 5 dd050011223302"):
169        raise Exception("VENDOR_ELEM_ADD failed")
170    dev[0].p2p_listen()
171    if not dev[1].discover_peer(addr0):
172        raise Exception("Device discovery timed out")
173    dev[1].p2p_stop_find()
174    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
175        raise Exception("Failed to enable external management frame handling")
176    dev[1].global_request("P2P_PROV_DISC " + addr0 + " display")
177    for i in range(5):
178        ev = dev[1].wait_event(["MGMT-RX"], timeout=5)
179        if ev is None:
180            raise Exception("MGMT-RX timeout")
181        if " d0" in ev:
182            break
183    if "dd050011223302" not in ev:
184        raise Exception("Vendor element not found from PD Response frame")
185    dev[0].p2p_stop_find()
186    dev[1].p2p_stop_find()
187
188def test_p2p_ext_vendor_elem_go_neg_req(dev):
189    """VENDOR_ELEM in GO Negotiation Request frames"""
190    try:
191        _test_p2p_ext_vendor_elem_go_neg_req(dev)
192    finally:
193        dev[0].request("VENDOR_ELEM_REMOVE 6 *")
194
195def _test_p2p_ext_vendor_elem_go_neg_req(dev):
196    addr0 = dev[0].p2p_dev_addr()
197    addr1 = dev[1].p2p_dev_addr()
198    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 6 dd050011223303"):
199        raise Exception("VENDOR_ELEM_ADD failed")
200    dev[1].p2p_listen()
201    if not dev[0].discover_peer(addr1):
202        raise Exception("Device discovery timed out")
203    dev[0].p2p_stop_find()
204    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
205        raise Exception("Failed to enable external management frame handling")
206    dev[0].global_request("P2P_CONNECT " + addr1 + " 12345670 display")
207    for i in range(5):
208        ev = dev[1].wait_event(["MGMT-RX"], timeout=5)
209        if ev is None:
210            raise Exception("MGMT-RX timeout")
211        if " d0" in ev:
212            break
213    if "dd050011223303" not in ev:
214        raise Exception("Vendor element not found from GO Negotiation Request frame")
215    dev[1].p2p_stop_find()
216    dev[0].p2p_stop_find()
217
218def test_p2p_ext_vendor_elem_go_neg_resp(dev):
219    """VENDOR_ELEM in GO Negotiation Response frames"""
220    try:
221        _test_p2p_ext_vendor_elem_go_neg_resp(dev)
222    finally:
223        dev[0].request("VENDOR_ELEM_REMOVE 7 *")
224
225def _test_p2p_ext_vendor_elem_go_neg_resp(dev):
226    addr0 = dev[0].p2p_dev_addr()
227    addr1 = dev[1].p2p_dev_addr()
228    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 7 dd050011223304"):
229        raise Exception("VENDOR_ELEM_ADD failed")
230    dev[0].p2p_listen()
231    if not dev[1].discover_peer(addr0):
232        raise Exception("Device discovery timed out")
233    dev[1].p2p_stop_find()
234    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
235        raise Exception("Failed to enable external management frame handling")
236    dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 display")
237    for i in range(5):
238        ev = dev[1].wait_event(["MGMT-RX"], timeout=5)
239        if ev is None:
240            raise Exception("MGMT-RX timeout")
241        if " d0" in ev:
242            break
243    if "dd050011223304" not in ev:
244        raise Exception("Vendor element not found from GO Negotiation Response frame")
245    dev[0].p2p_stop_find()
246    dev[1].p2p_stop_find()
247
248def test_p2p_ext_vendor_elem_go_neg_conf(dev, apdev, params):
249    """VENDOR_ELEM in GO Negotiation Confirm frames"""
250    try:
251        _test_p2p_ext_vendor_elem_go_neg_conf(dev, apdev, params)
252    finally:
253        dev[0].request("VENDOR_ELEM_REMOVE 8 *")
254
255def _test_p2p_ext_vendor_elem_go_neg_conf(dev, apdev, params):
256    addr0 = dev[0].p2p_dev_addr()
257    addr1 = dev[1].p2p_dev_addr()
258    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 8 dd050011223305"):
259        raise Exception("VENDOR_ELEM_ADD failed")
260    dev[0].p2p_listen()
261    dev[1].p2p_go_neg_auth(addr0, "12345670", "enter")
262    dev[1].p2p_listen()
263    dev[0].p2p_go_neg_init(addr1, "12345678", "display")
264    ev = dev[0].wait_global_event(["P2P-GO-NEG-SUCCESS"], timeout=15)
265    if ev is None:
266        raise Exception("GO negotiation timed out")
267    ev = dev[0].wait_global_event(["P2P-GROUP-FORMATION-FAILURE"], timeout=15)
268    if ev is None:
269        raise Exception("Group formation failure not indicated")
270    dev[0].dump_monitor()
271    dev[1].p2p_go_neg_auth_result(expect_failure=True)
272    dev[1].dump_monitor()
273
274    out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
275                     "wifi_p2p.public_action.subtype == 2")
276    if "Vendor Specific Data: 3305" not in out:
277        raise Exception("Vendor element not found from GO Negotiation Confirm frame")
278
279def test_p2p_ext_vendor_elem_invitation(dev):
280    """VENDOR_ELEM in Invitation frames"""
281    try:
282        _test_p2p_ext_vendor_elem_invitation(dev)
283    finally:
284        dev[0].request("VENDOR_ELEM_REMOVE 9 *")
285        dev[0].request("VENDOR_ELEM_REMOVE 10 *")
286
287def _test_p2p_ext_vendor_elem_invitation(dev):
288    addr0 = dev[0].p2p_dev_addr()
289    addr1 = dev[1].p2p_dev_addr()
290    form(dev[0], dev[1])
291    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 9 dd050011223306"):
292        raise Exception("VENDOR_ELEM_ADD failed")
293    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 10 dd050011223307"):
294        raise Exception("VENDOR_ELEM_ADD failed")
295    dev[1].p2p_listen()
296    if not dev[0].discover_peer(addr1):
297        raise Exception("Device discovery timed out")
298    peer = dev[0].get_peer(addr1)
299    dev[0].p2p_stop_find()
300    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
301        raise Exception("Failed to enable external management frame handling")
302    dev[0].global_request("P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr1)
303    for i in range(5):
304        ev = dev[1].wait_event(["MGMT-RX"], timeout=5)
305        if ev is None:
306            raise Exception("MGMT-RX timeout")
307        if " d0" in ev:
308            break
309    if "dd050011223306" not in ev:
310        raise Exception("Vendor element not found from Invitation Request frame")
311    dev[0].p2p_stop_find()
312    dev[1].p2p_stop_find()
313
314    dev[0].dump_monitor()
315    dev[1].dump_monitor()
316
317    dev[0].p2p_listen()
318    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 0"):
319        raise Exception("Failed to disable external management frame handling")
320    if not dev[1].discover_peer(addr0):
321        raise Exception("Device discovery timed out")
322    peer = dev[1].get_peer(addr0)
323    dev[1].p2p_stop_find()
324    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
325        raise Exception("Failed to enable external management frame handling")
326    dev[1].global_request("P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr0)
327    for i in range(5):
328        ev = dev[1].wait_event(["MGMT-RX"], timeout=5)
329        if ev is None:
330            raise Exception("MGMT-RX timeout")
331        if " d0" in ev:
332            break
333    if "dd050011223307" not in ev:
334        raise Exception("Vendor element not found from Invitation Response frame")
335    ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=5)
336    if ev is None:
337        raise Exception("Group start not reported")
338    dev[0].group_form_result(ev)
339    dev[0].remove_group()
340    dev[0].p2p_stop_find()
341    dev[1].p2p_stop_find()
342
343def test_p2p_ext_vendor_elem_assoc(dev, apdev, params):
344    """VENDOR_ELEM in Association frames"""
345    try:
346        _test_p2p_ext_vendor_elem_assoc(dev, apdev, params)
347    finally:
348        dev[0].request("VENDOR_ELEM_REMOVE 11 *")
349        dev[1].request("VENDOR_ELEM_REMOVE 12 *")
350        dev[0].request("VENDOR_ELEM_REMOVE 13 *")
351
352def _test_p2p_ext_vendor_elem_assoc(dev, apdev, params):
353    addr0 = dev[0].p2p_dev_addr()
354    addr1 = dev[1].p2p_dev_addr()
355
356    res = dev[0].get_driver_status()
357    p2p_device = True if (int(res['capa.flags'], 0) & 0x20000000) else False
358
359    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 11 dd050011223308"):
360        raise Exception("VENDOR_ELEM_ADD failed")
361    if "OK" not in dev[1].request("VENDOR_ELEM_ADD 12 dd050011223309"):
362        raise Exception("VENDOR_ELEM_ADD failed")
363    if not p2p_device and "OK" not in dev[0].request("VENDOR_ELEM_ADD 13 dd05001122330a"):
364        raise Exception("VENDOR_ELEM_ADD failed")
365    dev[0].p2p_listen()
366    dev[1].p2p_listen()
367    dev[1].p2p_go_neg_auth(addr0, "12345670", "enter", go_intent=15)
368    dev[0].p2p_go_neg_init(addr1, "12345670", "display", go_intent=0,
369                           timeout=15)
370    dev[1].p2p_go_neg_auth_result()
371    dev[1].remove_group()
372    dev[0].wait_go_ending_session()
373
374    out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
375                     "wlan.fc.type_subtype == 0x00", wait=False)
376    if "Vendor Specific Data: 3308" not in out:
377        raise Exception("Vendor element (P2P) not found from Association Request frame")
378    if not p2p_device and "Vendor Specific Data: 330a" not in out:
379        raise Exception("Vendor element (non-P2P) not found from Association Request frame")
380
381    out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
382                     "wlan.fc.type_subtype == 0x01", wait=False)
383    if "Vendor Specific Data: 3309" not in out:
384        raise Exception("Vendor element not found from Association Response frame")
385