1# P2P protocol tests for various messages
2# Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
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 binascii
9import struct
10import time
11import logging
12logger = logging.getLogger()
13
14import hostapd
15from p2p_utils import *
16from test_gas import anqp_adv_proto
17from test_p2ps import set_random_listen_chan
18
19def ie_ssid(ssid):
20    return struct.pack("<BB", WLAN_EID_SSID, len(ssid)) + ssid.encode()
21
22def ie_supp_rates():
23    return struct.pack("<BBBBBBBBBB", WLAN_EID_SUPP_RATES, 8,
24                       2*6, 2*9, 2*12, 2*18, 2*24, 2*36, 2*48, 2*54)
25
26def ie_p2p(attrs):
27    return struct.pack("<BBBBBB", WLAN_EID_VENDOR_SPECIFIC, 4 + len(attrs),
28                       0x50, 0x6f, 0x9a, 9) + attrs
29
30def ie_wsc(attrs):
31    return struct.pack("<BBBBBB", WLAN_EID_VENDOR_SPECIFIC, 4 + len(attrs),
32                       0x00, 0x50, 0xf2, 4) + attrs
33
34def wsc_attr_config_methods(methods=0):
35    return struct.pack(">HHH", WSC_ATTR_CONFIG_METHODS, 2, methods)
36
37def p2p_attr_status(status=P2P_SC_SUCCESS):
38    return struct.pack("<BHB", P2P_ATTR_STATUS, 1, status)
39
40def p2p_attr_minor_reason_code(code=0):
41    return struct.pack("<BHB", P2P_ATTR_MINOR_REASON_CODE, 1, code)
42
43def p2p_attr_capability(dev_capab=0, group_capab=0):
44    return struct.pack("<BHBB", P2P_ATTR_CAPABILITY, 2, dev_capab, group_capab)
45
46def p2p_attr_device_id(addr):
47    val = struct.unpack('6B', binascii.unhexlify(addr.replace(':', '')))
48    t = (P2P_ATTR_DEVICE_ID, 6) + val
49    return struct.pack('<BH6B', *t)
50
51def p2p_attr_go_intent(go_intent=0, tie_breaker=0):
52    return struct.pack("<BHB", P2P_ATTR_GROUP_OWNER_INTENT, 1,
53                       (go_intent << 1) | (tie_breaker & 0x01))
54
55def p2p_attr_config_timeout(go_config_timeout=0, client_config_timeout=0):
56    return struct.pack("<BHBB", P2P_ATTR_CONFIGURATION_TIMEOUT, 2,
57                       go_config_timeout, client_config_timeout)
58
59def p2p_attr_listen_channel(op_class=81, chan=1):
60    return struct.pack("<BHBBBBB", P2P_ATTR_LISTEN_CHANNEL, 5,
61                       0x58, 0x58, 0x04, op_class, chan)
62
63def p2p_attr_group_bssid(addr):
64    val = struct.unpack('6B', binascii.unhexlify(addr.replace(':', '')))
65    t = (P2P_ATTR_GROUP_BSSID, 6) + val
66    return struct.pack('<BH6B', *t)
67
68def p2p_attr_ext_listen_timing(period=0, interval=0):
69    return struct.pack("<BHHH", P2P_ATTR_EXT_LISTEN_TIMING, 4, period, interval)
70
71def p2p_attr_intended_interface_addr(addr):
72    val = struct.unpack('6B', binascii.unhexlify(addr.replace(':', '')))
73    t = (P2P_ATTR_INTENDED_INTERFACE_ADDR, 6) + val
74    return struct.pack('<BH6B', *t)
75
76def p2p_attr_manageability(bitmap=0):
77    return struct.pack("<BHB", P2P_ATTR_MANAGEABILITY, 1, bitmap)
78
79def p2p_attr_channel_list():
80    return struct.pack("<BH3BBB11B", P2P_ATTR_CHANNEL_LIST, 16,
81                       0x58, 0x58, 0x04,
82                       81, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
83
84def p2p_attr_device_info(addr, name="Test", config_methods=0, dev_type="00010050F2040001"):
85    val = struct.unpack('6B', binascii.unhexlify(addr.replace(':', '')))
86    val2 = struct.unpack('8B', binascii.unhexlify(dev_type))
87    t = (P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 4 + len(name)) + val
88    t2 = val2 + (0,)
89    return struct.pack("<BH6B", *t) + struct.pack(">H", config_methods) + struct.pack("8BB", *t2) + struct.pack('>HH', 0x1011, len(name)) + name.encode()
90
91def p2p_attr_group_id(addr, ssid):
92    val = struct.unpack('6B', binascii.unhexlify(addr.replace(':', '')))
93    t = (P2P_ATTR_GROUP_ID, 6 + len(ssid)) + val
94    return struct.pack('<BH6B', *t) + ssid.encode()
95
96def p2p_attr_operating_channel(op_class=81, chan=1):
97    return struct.pack("<BHBBBBB", P2P_ATTR_OPERATING_CHANNEL, 5,
98                       0x58, 0x58, 0x04, op_class, chan)
99
100def p2p_attr_invitation_flags(bitmap=0):
101    return struct.pack("<BHB", P2P_ATTR_INVITATION_FLAGS, 1, bitmap)
102
103def p2p_hdr_helper(dst, src, type=None, dialog_token=1, req=True):
104    msg = {}
105    msg['fc'] = MGMT_SUBTYPE_ACTION << 4
106    msg['da'] = dst
107    msg['sa'] = src
108    if req:
109        msg['bssid'] = dst
110    else:
111        msg['bssid'] = src
112    msg['payload'] = struct.pack("<BBBBBB",
113                                 ACTION_CATEG_PUBLIC, 9, 0x50, 0x6f, 0x9a, 9)
114    if type is not None:
115        msg['payload'] += struct.pack("<B", type)
116        if dialog_token:
117            msg['payload'] += struct.pack("<B", dialog_token)
118    return msg
119
120def p2p_hdr(dst, src, type=None, dialog_token=1):
121    return p2p_hdr_helper(dst, src, type, dialog_token, True)
122
123def p2p_hdr_resp(dst, src, type=None, dialog_token=1):
124    return p2p_hdr_helper(dst, src, type, dialog_token, False)
125
126def start_p2p(dev, apdev):
127    addr0 = dev[0].p2p_dev_addr()
128    dev[0].p2p_listen()
129    dev[1].p2p_find(social=True)
130    ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
131    if ev is None:
132        raise Exception("Device discovery timed out")
133    dev[1].p2p_stop_find()
134    peer = dev[1].get_peer(addr0)
135
136    bssid = apdev[0]['bssid']
137    params = {'ssid': "test", 'beacon_int': "2000"}
138    if peer['listen_freq'] == "2412":
139        params['channel'] = '1'
140    elif peer['listen_freq'] == "2437":
141        params['channel'] = '6'
142    elif peer['listen_freq'] == "2462":
143        params['channel'] = '11'
144    hapd = hostapd.add_ap(apdev[0], params)
145    hapd.set("ext_mgmt_frame_handling", "1")
146    return addr0, bssid, hapd, int(params['channel'])
147
148def p2p_probe(hapd, src, chan=1):
149    msg = {}
150    msg['fc'] = MGMT_SUBTYPE_PROBE_REQ << 4
151    msg['da'] = "ff:ff:ff:ff:ff:ff"
152    msg['sa'] = src
153    msg['bssid'] = "ff:ff:ff:ff:ff:ff"
154    attrs = p2p_attr_listen_channel(chan=chan)
155    msg['payload'] = ie_ssid("DIRECT-") + ie_supp_rates() + ie_p2p(attrs)
156    hapd.mgmt_tx(msg)
157
158def parse_p2p_public_action(payload):
159    pos = payload
160    (category, action) = struct.unpack('BB', pos[0:2])
161    if category != ACTION_CATEG_PUBLIC:
162        return None
163    if action != 9:
164        return None
165    pos = pos[2:]
166    (oui1, oui2, oui3, subtype) = struct.unpack('BBBB', pos[0:4])
167    if oui1 != 0x50 or oui2 != 0x6f or oui3 != 0x9a or subtype != 9:
168        return None
169    pos = pos[4:]
170    (subtype, dialog_token) = struct.unpack('BB', pos[0:2])
171    p2p = {}
172    p2p['subtype'] = subtype
173    p2p['dialog_token'] = dialog_token
174    pos = pos[2:]
175    p2p['elements'] = pos
176    while len(pos) > 2:
177        (id, elen) = struct.unpack('BB', pos[0:2])
178        pos = pos[2:]
179        if elen > len(pos):
180            raise Exception("Truncated IE in P2P Public Action frame (elen=%d left=%d)" % (elen, len(pos)))
181        if id == WLAN_EID_VENDOR_SPECIFIC:
182            if elen < 4:
183                raise Exception("Too short vendor specific IE in P2P Public Action frame (elen=%d)" % elen)
184            (oui1, oui2, oui3, subtype) = struct.unpack('BBBB', pos[0:4])
185            if oui1 == 0x50 and oui2 == 0x6f and oui3 == 0x9a and subtype == 9:
186                if 'p2p' in p2p:
187                    p2p['p2p'] += pos[4:elen]
188                else:
189                    p2p['p2p'] = pos[4:elen]
190            if oui1 == 0x00 and oui2 == 0x50 and oui3 == 0xf2 and subtype == 4:
191                p2p['wsc'] = pos[4:elen]
192        pos = pos[elen:]
193    if len(pos) > 0:
194        raise Exception("Invalid element in P2P Public Action frame")
195
196    if 'p2p' in p2p:
197        p2p['p2p_attrs'] = {}
198        pos = p2p['p2p']
199        while len(pos) >= 3:
200            (id, alen) = struct.unpack('<BH', pos[0:3])
201            pos = pos[3:]
202            if alen > len(pos):
203                logger.info("P2P payload: " + binascii.hexlify(p2p['p2p']))
204                raise Exception("Truncated P2P attribute in P2P Public Action frame (alen=%d left=%d p2p-payload=%d)" % (alen, len(pos), len(p2p['p2p'])))
205            p2p['p2p_attrs'][id] = pos[0:alen]
206            pos = pos[alen:]
207        if P2P_ATTR_STATUS in p2p['p2p_attrs']:
208            p2p['p2p_status'] = struct.unpack('B', p2p['p2p_attrs'][P2P_ATTR_STATUS])[0]
209
210    if 'wsc' in p2p:
211        p2p['wsc_attrs'] = {}
212        pos = p2p['wsc']
213        while len(pos) >= 4:
214            (id, alen) = struct.unpack('>HH', pos[0:4])
215            pos = pos[4:]
216            if alen > len(pos):
217                logger.info("WSC payload: " + binascii.hexlify(p2p['wsc']))
218                raise Exception("Truncated WSC attribute in P2P Public Action frame (alen=%d left=%d wsc-payload=%d)" % (alen, len(pos), len(p2p['wsc'])))
219            p2p['wsc_attrs'][id] = pos[0:alen]
220            pos = pos[alen:]
221
222    return p2p
223
224@remote_compatible
225def test_p2p_msg_empty(dev, apdev):
226    """P2P protocol test: empty P2P Public Action frame"""
227    dst, src, hapd, channel = start_p2p(dev, apdev)
228    msg = p2p_hdr(dst, src)
229    hapd.mgmt_tx(msg)
230
231@remote_compatible
232def test_p2p_msg_long_ssid(dev, apdev):
233    """P2P protocol test: Too long SSID in P2P Public Action frame"""
234    dst, src, hapd, channel = start_p2p(dev, apdev)
235
236    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=1)
237    attrs = p2p_attr_config_timeout()
238    attrs += p2p_attr_invitation_flags()
239    attrs += p2p_attr_operating_channel()
240    attrs += p2p_attr_group_bssid(src)
241    attrs += p2p_attr_channel_list()
242    attrs += p2p_attr_group_id(src, 'DIRECT-foo')
243    attrs += p2p_attr_device_info(src, config_methods=0x0108)
244    msg['payload'] += ie_p2p(attrs)
245    msg['payload'] += ie_ssid(255 * 'A')
246    hapd.mgmt_tx(msg)
247    ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
248    if ev is None:
249        raise Exception("Timeout on device found event")
250
251@remote_compatible
252def test_p2p_msg_long_dev_name(dev, apdev):
253    """P2P protocol test: Too long Device Name in P2P Public Action frame"""
254    dst, src, hapd, channel = start_p2p(dev, apdev)
255
256    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=1)
257    attrs = p2p_attr_config_timeout()
258    attrs += p2p_attr_invitation_flags()
259    attrs += p2p_attr_operating_channel()
260    attrs += p2p_attr_group_bssid(src)
261    attrs += p2p_attr_channel_list()
262    attrs += p2p_attr_group_id(src, 'DIRECT-foo')
263    attrs += p2p_attr_device_info(src, config_methods=0x0108,
264                                  name="123456789012345678901234567890123")
265    msg['payload'] += ie_p2p(attrs)
266    hapd.mgmt_tx(msg)
267    ev = dev[0].wait_event(["P2P-DEVICE-FOUND"], timeout=0.1)
268    if ev is not None:
269        raise Exception("Unexpected device found event")
270
271def test_p2p_msg_invitation_req(dev, apdev):
272    """P2P protocol tests for invitation request processing"""
273    dst, src, hapd, channel = start_p2p(dev, apdev)
274
275    # Empty P2P Invitation Request (missing dialog token)
276    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=None)
277    hapd.mgmt_tx(msg)
278    dialog_token = 0
279
280    # Various p2p_parse() failure cases due to invalid attributes
281
282    # Too short attribute header
283    dialog_token += 1
284    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
285    attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
286    msg['payload'] += ie_p2p(attrs)
287    hapd.mgmt_tx(msg)
288
289    # Minimal attribute underflow
290    dialog_token += 1
291    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
292    attrs = struct.pack("<BH", P2P_ATTR_CAPABILITY, 1)
293    msg['payload'] += ie_p2p(attrs)
294    hapd.mgmt_tx(msg)
295
296    # Large attribute underflow
297    dialog_token += 1
298    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
299    attrs = struct.pack("<BHB", P2P_ATTR_CAPABILITY, 0xffff, 1)
300    msg['payload'] += ie_p2p(attrs)
301    hapd.mgmt_tx(msg)
302
303    # Too short Capability attribute
304    dialog_token += 1
305    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
306    attrs = struct.pack("<BHB", P2P_ATTR_CAPABILITY, 1, 0)
307    msg['payload'] += ie_p2p(attrs)
308    hapd.mgmt_tx(msg)
309
310    # Too short Device ID attribute
311    dialog_token += 1
312    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
313    val = struct.unpack('5B', binascii.unhexlify("1122334455"))
314    t = (P2P_ATTR_DEVICE_ID, 5) + val
315    attrs = struct.pack('<BH5B', *t)
316    msg['payload'] += ie_p2p(attrs)
317    hapd.mgmt_tx(msg)
318
319    # Too short GO Intent attribute
320    dialog_token += 1
321    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
322    attrs = struct.pack("<BH", P2P_ATTR_GROUP_OWNER_INTENT, 0)
323    msg['payload'] += ie_p2p(attrs)
324    hapd.mgmt_tx(msg)
325
326    # Too short Status attribute
327    dialog_token += 1
328    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
329    attrs = struct.pack("<BH", P2P_ATTR_STATUS, 0)
330    msg['payload'] += ie_p2p(attrs)
331    hapd.mgmt_tx(msg)
332
333    # null Listen channel and too short Listen Channel attribute
334    dialog_token += 1
335    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
336    attrs = struct.pack("<BH", P2P_ATTR_LISTEN_CHANNEL, 0)
337    attrs += struct.pack("<BHB", P2P_ATTR_LISTEN_CHANNEL, 1, 0)
338    msg['payload'] += ie_p2p(attrs)
339    hapd.mgmt_tx(msg)
340
341    # null Operating channel and too short Operating Channel attribute
342    dialog_token += 1
343    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
344    attrs = struct.pack("<BH", P2P_ATTR_OPERATING_CHANNEL, 0)
345    attrs += struct.pack("<BHB", P2P_ATTR_OPERATING_CHANNEL, 1, 0)
346    msg['payload'] += ie_p2p(attrs)
347    hapd.mgmt_tx(msg)
348
349    # Too short Channel List attribute
350    dialog_token += 1
351    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
352    attrs = struct.pack("<BHBB", P2P_ATTR_CHANNEL_LIST, 2, 1, 2)
353    msg['payload'] += ie_p2p(attrs)
354    hapd.mgmt_tx(msg)
355
356    # Too short Device Info attribute
357    dialog_token += 1
358    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
359    attrs = struct.pack("<BHBB", P2P_ATTR_DEVICE_INFO, 2, 1, 2)
360    msg['payload'] += ie_p2p(attrs)
361    hapd.mgmt_tx(msg)
362
363    # Truncated Secondary Device Types in Device Info attribute
364    dialog_token += 1
365    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
366    attrs = struct.pack("<BH6BH8BB", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1,
367                        0, 0, 0, 0, 0, 0,
368                        0,
369                        0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22,
370                        255)
371    msg['payload'] += ie_p2p(attrs)
372    hapd.mgmt_tx(msg)
373
374    # Missing Device Name in Device Info attribute
375    dialog_token += 1
376    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
377    attrs = struct.pack("<BH6BH8BB8B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8,
378                        0, 0, 0, 0, 0, 0,
379                        0,
380                        0, 0, 0, 0, 0, 0, 0, 0,
381                        1,
382                        1, 2, 3, 4, 5, 6, 7, 8)
383    msg['payload'] += ie_p2p(attrs)
384    hapd.mgmt_tx(msg)
385
386    # Invalid Device Name header in Device Info attribute
387    dialog_token += 1
388    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
389    attrs = struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4,
390                        0, 0, 0, 0, 0, 0,
391                        0,
392                        0, 0, 0, 0, 0, 0, 0, 0,
393                        1,
394                        1, 2, 3, 4, 5, 6, 7, 8,
395                        0x11, 0x12, 0, 0)
396    msg['payload'] += ie_p2p(attrs)
397    hapd.mgmt_tx(msg)
398
399    # Invalid Device Name header length in Device Info attribute
400    dialog_token += 1
401    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
402    attrs = struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4,
403                        0, 0, 0, 0, 0, 0,
404                        0,
405                        0, 0, 0, 0, 0, 0, 0, 0,
406                        1,
407                        1, 2, 3, 4, 5, 6, 7, 8,
408                        0x10, 0x11, 0xff, 0xff)
409    msg['payload'] += ie_p2p(attrs)
410    hapd.mgmt_tx(msg)
411
412    # Invalid Device Name header length in Device Info attribute
413    dialog_token += 1
414    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
415    devname = b'A'
416    attrs = struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4 + len(devname),
417                        0, 0, 0, 0, 0, 0,
418                        0,
419                        0, 0, 0, 0, 0, 0, 0, 0,
420                        1,
421                        1, 2, 3, 4, 5, 6, 7, 8,
422                        0x10, 0x11, 0, len(devname) + 1) + devname
423    msg['payload'] += ie_p2p(attrs)
424    hapd.mgmt_tx(msg)
425
426    # Device Name filtering and too long Device Name in Device Info attribute
427    dialog_token += 1
428    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
429    attrs = struct.pack("<BH6BH8BB8B4B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4 + 4,
430                        0, 0, 0, 0, 0, 0,
431                        0,
432                        0, 0, 0, 0, 0, 0, 0, 0,
433                        1,
434                        1, 2, 3, 4, 5, 6, 7, 8,
435                        0x10, 0x11, 0, 4,
436                        64, 9, 0, 64)
437    devname = b'123456789012345678901234567890123'
438    attrs += struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4 + len(devname),
439                         0, 0, 0, 0, 0, 0,
440                         0,
441                         0, 0, 0, 0, 0, 0, 0, 0,
442                         1,
443                         1, 2, 3, 4, 5, 6, 7, 8,
444                         0x10, 0x11, 0, len(devname)) + devname
445    msg['payload'] += ie_p2p(attrs)
446    hapd.mgmt_tx(msg)
447
448    # Too short Configuration Timeout attribute
449    dialog_token += 1
450    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
451    attrs = struct.pack("<BHB", P2P_ATTR_CONFIGURATION_TIMEOUT, 1, 1)
452    msg['payload'] += ie_p2p(attrs)
453    hapd.mgmt_tx(msg)
454
455    # Too short Intended P2P Interface Address attribute
456    dialog_token += 1
457    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
458    attrs = struct.pack("<BHB", P2P_ATTR_INTENDED_INTERFACE_ADDR, 1, 1)
459    msg['payload'] += ie_p2p(attrs)
460    hapd.mgmt_tx(msg)
461
462    # Too short P2P Group BSSID attribute
463    dialog_token += 1
464    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
465    attrs = struct.pack("<BHB", P2P_ATTR_GROUP_BSSID, 1, 1)
466    msg['payload'] += ie_p2p(attrs)
467    hapd.mgmt_tx(msg)
468
469    # Too short P2P Group ID attribute
470    dialog_token += 1
471    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
472    attrs = struct.pack("<BHB", P2P_ATTR_GROUP_ID, 1, 1)
473    msg['payload'] += ie_p2p(attrs)
474    hapd.mgmt_tx(msg)
475
476    # Too long P2P Group ID attribute
477    dialog_token += 1
478    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
479    attrs = struct.pack("<BH6B", P2P_ATTR_GROUP_ID, 6 + 33, 0, 0, 0, 0, 0, 0) + b"123456789012345678901234567890123"
480    msg['payload'] += ie_p2p(attrs)
481    hapd.mgmt_tx(msg)
482
483    # Too short Invitation Flags attribute
484    dialog_token += 1
485    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
486    attrs = struct.pack("<BH", P2P_ATTR_INVITATION_FLAGS, 0)
487    msg['payload'] += ie_p2p(attrs)
488    hapd.mgmt_tx(msg)
489
490    # Valid and too short Manageability attribute
491    dialog_token += 1
492    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
493    attrs = p2p_attr_manageability()
494    attrs += struct.pack("<BH", P2P_ATTR_MANAGEABILITY, 0)
495    msg['payload'] += ie_p2p(attrs)
496    hapd.mgmt_tx(msg)
497
498    # Too short NoA attribute
499    dialog_token += 1
500    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
501    attrs = struct.pack("<BHB", P2P_ATTR_NOTICE_OF_ABSENCE, 1, 1)
502    msg['payload'] += ie_p2p(attrs)
503    hapd.mgmt_tx(msg)
504
505    # Valid and too short Extended Listen Timing attributes
506    dialog_token += 1
507    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
508    attrs = p2p_attr_ext_listen_timing(period=100, interval=50)
509    attrs += struct.pack("<BHBBB", P2P_ATTR_EXT_LISTEN_TIMING, 3, 0, 0, 0)
510    msg['payload'] += ie_p2p(attrs)
511    hapd.mgmt_tx(msg)
512
513    # Valid and too short Minor Reason Code attributes
514    dialog_token += 1
515    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
516    attrs = p2p_attr_minor_reason_code(code=2)
517    attrs += struct.pack("<BH", P2P_ATTR_MINOR_REASON_CODE, 0)
518    msg['payload'] += ie_p2p(attrs)
519    hapd.mgmt_tx(msg)
520
521    # Unknown attribute and too short OOB GO Negotiation Channel attribute
522    dialog_token += 1
523    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
524    attrs = struct.pack("<BHB", 99, 1, 1)
525    attrs += struct.pack("<BHB", P2P_ATTR_OOB_GO_NEG_CHANNEL, 1, 1)
526    msg['payload'] += ie_p2p(attrs)
527    hapd.mgmt_tx(msg)
528
529    # Too short Service Hash attribute
530    dialog_token += 1
531    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
532    attrs = struct.pack("<BH5B", P2P_ATTR_SERVICE_HASH, 5, 1, 2, 3, 4, 5)
533    msg['payload'] += ie_p2p(attrs)
534    hapd.mgmt_tx(msg)
535
536    # Too short Connection Capability attribute
537    dialog_token += 1
538    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
539    attrs = struct.pack("<BH", P2P_ATTR_CONNECTION_CAPABILITY, 0)
540    msg['payload'] += ie_p2p(attrs)
541    hapd.mgmt_tx(msg)
542
543    # Too short Advertisement ID attribute
544    dialog_token += 1
545    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
546    attrs = struct.pack("<BH9B", P2P_ATTR_ADVERTISEMENT_ID, 9, 1, 2, 3, 4, 5,
547                        6, 7, 8, 9)
548    msg['payload'] += ie_p2p(attrs)
549    hapd.mgmt_tx(msg)
550
551    # Truncated and too short Service Instance attributes
552    dialog_token += 1
553    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
554    attrs = struct.pack("<BH8B", P2P_ATTR_ADVERTISED_SERVICE, 8, 1, 2, 3, 4, 5,
555                        6, 2, 8)
556    attrs += struct.pack("<BH7B", P2P_ATTR_ADVERTISED_SERVICE, 7, 1, 2, 3, 4, 5,
557                         6, 7)
558    msg['payload'] += ie_p2p(attrs)
559    hapd.mgmt_tx(msg)
560
561    # Too short Session ID attribute
562    dialog_token += 1
563    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
564    attrs = struct.pack("<BH4B", P2P_ATTR_SESSION_ID, 4, 1, 2, 3, 4)
565    msg['payload'] += ie_p2p(attrs)
566    hapd.mgmt_tx(msg)
567
568    # Too short Feature Capability attribute
569    dialog_token += 1
570    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
571    attrs = struct.pack("<BH", P2P_ATTR_FEATURE_CAPABILITY, 0)
572    msg['payload'] += ie_p2p(attrs)
573    hapd.mgmt_tx(msg)
574
575    # Too short Persistent Group attribute
576    dialog_token += 1
577    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
578    attrs = struct.pack("<BH5B", P2P_ATTR_PERSISTENT_GROUP, 5, 1, 2, 3, 4, 5)
579    msg['payload'] += ie_p2p(attrs)
580    hapd.mgmt_tx(msg)
581
582    # Too long Persistent Group attribute
583    dialog_token += 1
584    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
585    attrs = struct.pack("<BH9L3B", P2P_ATTR_PERSISTENT_GROUP, 6 + 32 + 1,
586                        1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3)
587    msg['payload'] += ie_p2p(attrs)
588    hapd.mgmt_tx(msg)
589
590    if hapd.mgmt_rx(timeout=0.5) is not None:
591        raise Exception("Unexpected management frame received")
592
593    dev[0].dump_monitor()
594    dialog_token += 1
595    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
596    attrs = p2p_attr_config_timeout()
597    attrs += p2p_attr_invitation_flags()
598    attrs += p2p_attr_operating_channel()
599    attrs += p2p_attr_group_bssid(src)
600    attrs += p2p_attr_channel_list()
601    attrs += p2p_attr_group_id(src, "DIRECT-foo")
602    attrs += p2p_attr_device_info(src, config_methods=0x0108)
603    msg['payload'] += ie_p2p(attrs)
604    hapd.mgmt_tx(msg)
605    ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
606    if ev is None:
607        raise Exception("Timeout on device found event")
608    ev = dev[0].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=5)
609    if ev is None:
610        raise Exception("Timeout on invitation event " + str(dialog_token))
611    if hapd.mgmt_rx(timeout=1) is None:
612        raise Exception("No invitation response " + str(dialog_token))
613
614    time.sleep(0.1)
615    dev[0].dump_monitor()
616    dialog_token += 1
617    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
618    attrs = p2p_attr_config_timeout()
619    attrs += p2p_attr_invitation_flags()
620    attrs += p2p_attr_operating_channel()
621    attrs += p2p_attr_group_bssid(src)
622    attrs += p2p_attr_channel_list()
623    attrs += p2p_attr_group_id(src, "DIRECT-foo")
624    attrs += p2p_attr_device_info(src, config_methods=0x0108)
625    msg['payload'] += ie_p2p(attrs)
626    hapd.mgmt_tx(msg)
627    ev = dev[0].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=5)
628    if ev is None:
629        raise Exception("Timeout on invitation event " + str(dialog_token))
630    if hapd.mgmt_rx(timeout=1) is None:
631        raise Exception("No invitation response " + str(dialog_token))
632
633    time.sleep(0.1)
634    dev[0].dump_monitor()
635    dialog_token += 1
636    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
637    #attrs = p2p_attr_config_timeout()
638    attrs = p2p_attr_invitation_flags()
639    attrs += p2p_attr_operating_channel()
640    attrs += p2p_attr_group_bssid(src)
641    attrs += p2p_attr_channel_list()
642    attrs += p2p_attr_group_id(src, "DIRECT-foo")
643    attrs += p2p_attr_device_info(src, config_methods=0x0108)
644    msg['payload'] += ie_p2p(attrs)
645    hapd.mgmt_tx(msg)
646    if hapd.mgmt_rx(timeout=1) is None:
647        raise Exception("No invitation response " + str(dialog_token))
648
649    time.sleep(0.1)
650    dev[0].dump_monitor()
651    dialog_token += 1
652    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
653    attrs = p2p_attr_config_timeout()
654    #attrs = p2p_attr_invitation_flags()
655    attrs += p2p_attr_operating_channel()
656    attrs += p2p_attr_group_bssid(src)
657    attrs += p2p_attr_channel_list()
658    attrs += p2p_attr_group_id(src, "DIRECT-foo")
659    attrs += p2p_attr_device_info(src, config_methods=0x0108)
660    msg['payload'] += ie_p2p(attrs)
661    hapd.mgmt_tx(msg)
662    if hapd.mgmt_rx(timeout=1) is None:
663        raise Exception("No invitation response " + str(dialog_token))
664
665    time.sleep(0.1)
666    dev[0].dump_monitor()
667    dialog_token += 1
668    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
669    attrs = p2p_attr_config_timeout()
670    attrs = p2p_attr_invitation_flags()
671    #attrs += p2p_attr_operating_channel()
672    attrs += p2p_attr_group_bssid(src)
673    attrs += p2p_attr_channel_list()
674    attrs += p2p_attr_group_id(src, "DIRECT-foo")
675    attrs += p2p_attr_device_info(src, config_methods=0x0108)
676    msg['payload'] += ie_p2p(attrs)
677    hapd.mgmt_tx(msg)
678    if hapd.mgmt_rx(timeout=1) is None:
679        raise Exception("No invitation response " + str(dialog_token))
680
681    time.sleep(0.1)
682    dev[0].dump_monitor()
683    dialog_token += 1
684    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
685    attrs = p2p_attr_config_timeout()
686    attrs = p2p_attr_invitation_flags()
687    attrs += p2p_attr_operating_channel()
688    #attrs += p2p_attr_group_bssid(src)
689    attrs += p2p_attr_channel_list()
690    attrs += p2p_attr_group_id(src, "DIRECT-foo")
691    attrs += p2p_attr_device_info(src, config_methods=0x0108)
692    msg['payload'] += ie_p2p(attrs)
693    hapd.mgmt_tx(msg)
694    if hapd.mgmt_rx(timeout=1) is None:
695        raise Exception("No invitation response " + str(dialog_token))
696
697    time.sleep(0.1)
698    dev[0].dump_monitor()
699    dialog_token += 1
700    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
701    attrs = p2p_attr_config_timeout()
702    attrs = p2p_attr_invitation_flags()
703    attrs += p2p_attr_operating_channel()
704    attrs += p2p_attr_group_bssid(src)
705    #attrs += p2p_attr_channel_list()
706    attrs += p2p_attr_group_id(src, "DIRECT-foo")
707    attrs += p2p_attr_device_info(src, config_methods=0x0108)
708    msg['payload'] += ie_p2p(attrs)
709    hapd.mgmt_tx(msg)
710    if hapd.mgmt_rx(timeout=1) is None:
711        raise Exception("No invitation response " + str(dialog_token))
712
713    time.sleep(0.1)
714    dev[0].dump_monitor()
715    dialog_token += 1
716    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
717    attrs = p2p_attr_config_timeout()
718    attrs = p2p_attr_invitation_flags()
719    attrs += p2p_attr_operating_channel()
720    attrs += p2p_attr_group_bssid(src)
721    attrs += p2p_attr_channel_list()
722    #attrs += p2p_attr_group_id(src, "DIRECT-foo")
723    attrs += p2p_attr_device_info(src, config_methods=0x0108)
724    msg['payload'] += ie_p2p(attrs)
725    hapd.mgmt_tx(msg)
726    if hapd.mgmt_rx(timeout=1) is None:
727        raise Exception("No invitation response " + str(dialog_token))
728
729    time.sleep(0.1)
730    dev[0].dump_monitor()
731    dialog_token += 1
732    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
733    attrs = p2p_attr_config_timeout()
734    attrs = p2p_attr_invitation_flags()
735    attrs += p2p_attr_operating_channel()
736    attrs += p2p_attr_group_bssid(src)
737    attrs += p2p_attr_channel_list()
738    attrs += p2p_attr_group_id(src, "DIRECT-foo")
739    #attrs += p2p_attr_device_info(src, config_methods=0x0108)
740    msg['payload'] += ie_p2p(attrs)
741    hapd.mgmt_tx(msg)
742    if hapd.mgmt_rx(timeout=1) is None:
743        raise Exception("No invitation response " + str(dialog_token))
744
745    time.sleep(0.1)
746    dev[0].dump_monitor()
747    dialog_token += 1
748    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
749    hapd.mgmt_tx(msg)
750    if hapd.mgmt_rx(timeout=1) is None:
751        raise Exception("No invitation response " + str(dialog_token))
752
753    # Unusable peer operating channel preference
754    time.sleep(0.1)
755    dev[0].dump_monitor()
756    dialog_token += 1
757    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
758    attrs = p2p_attr_config_timeout()
759    attrs = p2p_attr_invitation_flags()
760    attrs += p2p_attr_operating_channel(chan=15)
761    attrs += p2p_attr_group_bssid(src)
762    attrs += p2p_attr_channel_list()
763    attrs += p2p_attr_group_id(src, "DIRECT-foo")
764    attrs += p2p_attr_device_info(src, config_methods=0x0108)
765    msg['payload'] += ie_p2p(attrs)
766    hapd.mgmt_tx(msg)
767    if hapd.mgmt_rx(timeout=1) is None:
768        raise Exception("No invitation response " + str(dialog_token))
769
770def test_p2p_msg_invitation_req_to_go(dev, apdev):
771    """P2P protocol tests for invitation request processing on GO device"""
772    res = form(dev[0], dev[1])
773    dev[0].dump_monitor()
774    dev[1].dump_monitor()
775    addr0 = dev[0].p2p_dev_addr()
776    addr1 = dev[1].p2p_dev_addr()
777    peer = dev[1].get_peer(addr0)
778    listen_freq = peer['listen_freq']
779
780    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
781        raise Exception("Failed to enable external management frame handling")
782
783    networks = dev[0].list_networks()
784    if len(networks) != 1:
785        raise Exception("Unexpected number of networks")
786    if "[P2P-PERSISTENT]" not in networks[0]['flags']:
787        raise Exception("Not the persistent group data")
788    dev[0].p2p_start_go(persistent=networks[0]['id'], freq=listen_freq)
789
790    dialog_token = 0
791
792    # Unusable peer operating channel preference
793    dialog_token += 1
794    msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_REQ,
795                  dialog_token=dialog_token)
796    attrs = p2p_attr_config_timeout()
797    attrs = p2p_attr_invitation_flags(bitmap=1)
798    attrs += p2p_attr_operating_channel(chan=15)
799    attrs += p2p_attr_channel_list()
800    attrs += p2p_attr_group_id(res['go_dev_addr'], res['ssid'])
801    attrs += p2p_attr_device_info(addr1, config_methods=0x0108)
802    msg['payload'] += ie_p2p(attrs)
803
804    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr0, addr0, peer['listen_freq'], binascii.hexlify(msg['payload']).decode()))
805
806    rx_msg = dev[1].mgmt_rx()
807    if rx_msg is None:
808        raise Exception("MGMT-RX timeout")
809    p2p = parse_p2p_public_action(rx_msg['payload'])
810    if p2p is None:
811        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
812    if p2p['subtype'] != P2P_INVITATION_RESP:
813        raise Exception("Unexpected subtype %d" % p2p['subtype'])
814    if p2p['p2p_status'] != 0:
815        raise Exception("Unexpected status %d" % p2p['p2p_status'])
816
817    # Forced channel re-selection due to channel list
818    dialog_token += 1
819    msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_REQ,
820                  dialog_token=dialog_token)
821    attrs = p2p_attr_config_timeout()
822    attrs = p2p_attr_invitation_flags(bitmap=1)
823    attrs += struct.pack("<BH3BBBB", P2P_ATTR_CHANNEL_LIST, 6,
824                         0x58, 0x58, 0x04,
825                         81, 1, 3)
826    attrs += p2p_attr_group_id(res['go_dev_addr'], res['ssid'])
827    attrs += p2p_attr_device_info(addr1, config_methods=0x0108)
828    msg['payload'] += ie_p2p(attrs)
829
830    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr0, addr0, peer['listen_freq'], binascii.hexlify(msg['payload']).decode()))
831
832    rx_msg = dev[1].mgmt_rx()
833    if rx_msg is None:
834        raise Exception("MGMT-RX timeout")
835    p2p = parse_p2p_public_action(rx_msg['payload'])
836    if p2p is None:
837        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
838    if p2p['subtype'] != P2P_INVITATION_RESP:
839        raise Exception("Unexpected subtype %d" % p2p['subtype'])
840    if p2p['p2p_status'] != 7 and dev[1].get_mcc() <= 1:
841        raise Exception("Unexpected status %d" % p2p['p2p_status'])
842
843@remote_compatible
844def test_p2p_msg_invitation_req_unknown(dev, apdev):
845    """P2P protocol tests for invitation request from unknown peer"""
846    dst, src, hapd, channel = start_p2p(dev, apdev)
847    dialog_token = 0
848
849    dialog_token += 1
850    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
851    attrs = p2p_attr_config_timeout()
852    attrs += p2p_attr_invitation_flags()
853    attrs += p2p_attr_operating_channel()
854    attrs += p2p_attr_group_bssid(src)
855    attrs += p2p_attr_channel_list()
856    #attrs += p2p_attr_group_id(src, "DIRECT-foo")
857    #attrs += p2p_attr_device_info(src, config_methods=0x0108)
858    msg['payload'] += ie_p2p(attrs)
859    hapd.mgmt_tx(msg)
860    ev = dev[0].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=5)
861    if ev is None:
862        raise Exception("Timeout on invitation event " + str(dialog_token))
863    if hapd.mgmt_rx(timeout=1) is None:
864        raise Exception("No invitation response " + str(dialog_token))
865
866@remote_compatible
867def test_p2p_msg_invitation_no_common_channels(dev, apdev):
868    """P2P protocol tests for invitation request without common channels"""
869    dst, src, hapd, channel = start_p2p(dev, apdev)
870    dialog_token = 0
871
872    dialog_token += 1
873    msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
874    attrs = p2p_attr_config_timeout()
875    attrs += p2p_attr_invitation_flags()
876    attrs += p2p_attr_operating_channel()
877    attrs += p2p_attr_group_bssid(src)
878    attrs += struct.pack("<BH3BBB", P2P_ATTR_CHANNEL_LIST, 5,
879                         0x58, 0x58, 0x04,
880                         81, 0)
881    attrs += p2p_attr_group_id(src, "DIRECT-foo")
882    attrs += p2p_attr_device_info(src, config_methods=0x0108)
883    msg['payload'] += ie_p2p(attrs)
884    hapd.mgmt_tx(msg)
885    if hapd.mgmt_rx(timeout=1) is None:
886        raise Exception("No invitation response " + str(dialog_token))
887    ev = dev[0].wait_event(["P2P-INVITATION-RECEIVED"], timeout=0.1)
888    if ev is not None:
889        raise Exception("Unexpected invitation event")
890
891def test_p2p_msg_invitation_resp(dev, apdev):
892    """P2P protocol tests for invitation response processing"""
893    form(dev[0], dev[1])
894    dev[0].dump_monitor()
895    dev[1].dump_monitor()
896
897    dst, src, hapd, channel = start_p2p(dev, apdev)
898
899    addr0 = dev[0].p2p_dev_addr()
900    addr1 = dev[1].p2p_dev_addr()
901    peer = dev[1].get_peer(addr0)
902
903    # P2P Invitation Response from unknown peer
904    msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=1)
905    hapd.mgmt_tx(msg)
906
907    # P2P Invitation Response from peer that is not in invitation
908    msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=2)
909    attrs = p2p_attr_status()
910    msg['payload'] += ie_p2p(attrs)
911    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
912        addr0, addr0, peer['listen_freq'], binascii.hexlify(msg['payload']).decode()))
913    time.sleep(0.25)
914
915    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
916        raise Exception("Failed to enable external management frame handling")
917
918    invite(dev[0], dev[1])
919    rx_msg = dev[1].mgmt_rx()
920    if rx_msg is None:
921        raise Exception("MGMT-RX timeout")
922    p2p = parse_p2p_public_action(rx_msg['payload'])
923    if p2p is None:
924        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
925    if p2p['subtype'] != P2P_INVITATION_REQ:
926        raise Exception("Unexpected subtype %d" % p2p['subtype'])
927
928    # Invalid attribute to cause p2p_parse() failure
929    msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
930    attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
931    msg['payload'] += ie_p2p(attrs)
932    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
933        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
934
935    invite(dev[0], dev[1])
936    rx_msg = dev[1].mgmt_rx()
937    if rx_msg is None:
938        raise Exception("MGMT-RX timeout")
939    p2p = parse_p2p_public_action(rx_msg['payload'])
940    if p2p is None:
941        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
942    if p2p['subtype'] != P2P_INVITATION_REQ:
943        raise Exception("Unexpected subtype %d" % p2p['subtype'])
944
945    # missing mandatory Status attribute
946    msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
947    attrs = p2p_attr_channel_list()
948    msg['payload'] += ie_p2p(attrs)
949    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
950        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
951
952    invite(dev[0], dev[1])
953    rx_msg = dev[1].mgmt_rx()
954    if rx_msg is None:
955        raise Exception("MGMT-RX timeout")
956    p2p = parse_p2p_public_action(rx_msg['payload'])
957    if p2p is None:
958        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
959    if p2p['subtype'] != P2P_INVITATION_REQ:
960        raise Exception("Unexpected subtype %d" % p2p['subtype'])
961
962    # no channel match (no common channel found at all)
963    msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
964    attrs = p2p_attr_status()
965    attrs += struct.pack("<BH3BBBB", P2P_ATTR_CHANNEL_LIST, 6,
966                         0x58, 0x58, 0x04,
967                         81, 1, 15)
968    msg['payload'] += ie_p2p(attrs)
969    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
970        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
971
972    invite(dev[0], dev[1])
973    rx_msg = dev[1].mgmt_rx()
974    if rx_msg is None:
975        raise Exception("MGMT-RX timeout")
976    p2p = parse_p2p_public_action(rx_msg['payload'])
977    if p2p is None:
978        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
979    if p2p['subtype'] != P2P_INVITATION_REQ:
980        raise Exception("Unexpected subtype %d" % p2p['subtype'])
981
982    # no channel match (no acceptable P2P channel)
983    msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
984    attrs = p2p_attr_status()
985    attrs += struct.pack("<BH3BBBB", P2P_ATTR_CHANNEL_LIST, 6,
986                         0x58, 0x58, 0x04,
987                         81, 1, 12)
988    msg['payload'] += ie_p2p(attrs)
989    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
990        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
991
992    invite(dev[0], dev[1])
993    rx_msg = dev[1].mgmt_rx()
994    if rx_msg is None:
995        raise Exception("MGMT-RX timeout")
996    p2p = parse_p2p_public_action(rx_msg['payload'])
997    if p2p is None:
998        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
999    if p2p['subtype'] != P2P_INVITATION_REQ:
1000        raise Exception("Unexpected subtype %d" % p2p['subtype'])
1001
1002    # missing mandatory Channel List attribute (ignored as a workaround)
1003    msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
1004    attrs = p2p_attr_status()
1005    msg['payload'] += ie_p2p(attrs)
1006    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1007        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
1008
1009    ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
1010    if ev is None:
1011        raise Exception("Group was not started")
1012
1013def test_p2p_msg_invitation_resend(dev, apdev):
1014    """P2P protocol tests for invitation resending on no-common-channels"""
1015    form(dev[0], dev[1])
1016    dev[0].dump_monitor()
1017    dev[1].dump_monitor()
1018    addr0 = dev[0].p2p_dev_addr()
1019    addr1 = dev[1].p2p_dev_addr()
1020
1021    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
1022        raise Exception("Failed to enable external management frame handling")
1023
1024    logger.info("Forced channel in invitation")
1025    invite(dev[0], dev[1], extra="freq=2422")
1026    rx_msg = dev[1].mgmt_rx()
1027    if rx_msg is None:
1028        raise Exception("MGMT-RX timeout")
1029    p2p = parse_p2p_public_action(rx_msg['payload'])
1030    if p2p is None:
1031        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1032    if p2p['subtype'] != P2P_INVITATION_REQ:
1033        raise Exception("Unexpected subtype %d" % p2p['subtype'])
1034    msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_RESP,
1035                  dialog_token=p2p['dialog_token'])
1036    attrs = p2p_attr_status(status=P2P_SC_FAIL_NO_COMMON_CHANNELS)
1037    msg['payload'] += ie_p2p(attrs)
1038    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1039        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
1040    ev = dev[0].wait_global_event(["P2P-INVITATION-RESULT"], timeout=15)
1041    if ev is None:
1042        raise Exception("Timeout on invitation result")
1043    if "status=7" not in ev:
1044        raise Exception("Unexpected invitation result: " + ev)
1045
1046    logger.info("Any channel allowed, only preference provided in invitation")
1047    invite(dev[0], dev[1], extra="pref=2422")
1048    rx_msg = dev[1].mgmt_rx()
1049    if rx_msg is None:
1050        raise Exception("MGMT-RX timeout")
1051    p2p = parse_p2p_public_action(rx_msg['payload'])
1052    if p2p is None:
1053        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1054    if p2p['subtype'] != P2P_INVITATION_REQ:
1055        raise Exception("Unexpected subtype %d" % p2p['subtype'])
1056    msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_RESP,
1057                  dialog_token=p2p['dialog_token'])
1058    attrs = p2p_attr_status(status=P2P_SC_FAIL_NO_COMMON_CHANNELS)
1059    msg['payload'] += ie_p2p(attrs)
1060    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 0"):
1061        raise Exception("Failed to disable external management frame handling")
1062    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1063        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
1064    ev = dev[0].wait_global_event(["P2P-INVITATION-RESULT"], timeout=15)
1065    if ev is None:
1066        raise Exception("Timeout on invitation result")
1067    if "status=0" not in ev:
1068        raise Exception("Unexpected invitation result: " + ev)
1069
1070    ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
1071    if ev is None:
1072        raise Exception("Group was not started on dev0")
1073    ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
1074    if ev is None:
1075        raise Exception("Group was not started on dev1")
1076
1077def test_p2p_msg_invitation_resend_duplicate(dev, apdev):
1078    """P2P protocol tests for invitation resending on no-common-channels and duplicated response"""
1079    form(dev[0], dev[1])
1080    dev[0].dump_monitor()
1081    dev[1].dump_monitor()
1082    addr0 = dev[0].p2p_dev_addr()
1083    addr1 = dev[1].p2p_dev_addr()
1084
1085    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
1086        raise Exception("Failed to enable external management frame handling")
1087
1088    logger.info("Any channel allowed, only preference provided in invitation")
1089    invite(dev[0], dev[1], extra="pref=2422")
1090    rx_msg = dev[1].mgmt_rx()
1091    if rx_msg is None:
1092        raise Exception("MGMT-RX timeout")
1093    p2p = parse_p2p_public_action(rx_msg['payload'])
1094    if p2p is None:
1095        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1096    if p2p['subtype'] != P2P_INVITATION_REQ:
1097        raise Exception("Unexpected subtype %d" % p2p['subtype'])
1098    msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_RESP,
1099                  dialog_token=p2p['dialog_token'])
1100    attrs = p2p_attr_status(status=P2P_SC_FAIL_NO_COMMON_CHANNELS)
1101    msg['payload'] += ie_p2p(attrs)
1102    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1103        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
1104
1105    rx_msg = dev[1].mgmt_rx()
1106    if rx_msg is None:
1107        raise Exception("MGMT-RX timeout")
1108    p2p = parse_p2p_public_action(rx_msg['payload'])
1109    if p2p is None:
1110        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1111    if p2p['subtype'] != P2P_INVITATION_REQ:
1112        raise Exception("Unexpected subtype %d" % p2p['subtype'])
1113
1114    logger.info("Retransmit duplicate of previous response")
1115    mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1116        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode()))
1117
1118    logger.info("Transmit real response")
1119    msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_RESP,
1120                  dialog_token=p2p['dialog_token'])
1121    attrs = p2p_attr_status(status=P2P_SC_SUCCESS)
1122    attrs += p2p_attr_channel_list()
1123    msg['payload'] += ie_p2p(attrs)
1124    if "FAIL" in dev[1].request("MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1125        addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload']).decode())):
1126        raise Exception("Failed to transmit real response")
1127    dev[1].request("SET ext_mgmt_frame_handling 0")
1128
1129    ev = dev[0].wait_global_event(["P2P-INVITATION-RESULT"], timeout=10)
1130    if ev is None:
1131        raise Exception("Timeout on invitation result")
1132    if "status=0" not in ev:
1133        raise Exception("Unexpected invitation result: " + ev)
1134    ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
1135    if ev is None:
1136        raise Exception("Group formation timed out")
1137    dev[0].group_form_result(ev)
1138    dev[0].remove_group()
1139
1140@remote_compatible
1141def test_p2p_msg_pd_req(dev, apdev):
1142    """P2P protocol tests for provision discovery request processing"""
1143    dst, src, hapd, channel = start_p2p(dev, apdev)
1144    dialog_token = 0
1145
1146    # Too short attribute header
1147    dialog_token += 1
1148    msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
1149    attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
1150    msg['payload'] += ie_p2p(attrs)
1151    hapd.mgmt_tx(msg)
1152
1153    if hapd.mgmt_rx(timeout=0.5) is not None:
1154        raise Exception("Unexpected management frame received")
1155
1156    # No attributes
1157    dialog_token += 1
1158    msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
1159    attrs = b''
1160    msg['payload'] += ie_p2p(attrs)
1161    hapd.mgmt_tx(msg)
1162    if hapd.mgmt_rx(timeout=1) is None:
1163        raise Exception("No PD response " + str(dialog_token))
1164
1165    # Valid request
1166    time.sleep(0.1)
1167    dialog_token += 1
1168    msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
1169    attrs = wsc_attr_config_methods(methods=0x1008)
1170    msg['payload'] += ie_wsc(attrs)
1171    attrs = p2p_attr_capability()
1172    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1173    msg['payload'] += ie_p2p(attrs)
1174    hapd.mgmt_tx(msg)
1175    ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
1176    if ev is None:
1177        raise Exception("Timeout on device found event")
1178    ev = dev[0].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=5)
1179    if ev is None:
1180        raise Exception("Timeout on PD event")
1181    if hapd.mgmt_rx(timeout=1) is None:
1182        raise Exception("No PD response " + str(dialog_token))
1183
1184    # Unknown group
1185    time.sleep(0.1)
1186    dialog_token += 1
1187    msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
1188    attrs = wsc_attr_config_methods(methods=0x1008)
1189    msg['payload'] += ie_wsc(attrs)
1190    attrs = p2p_attr_capability()
1191    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1192    attrs += p2p_attr_group_id("02:02:02:02:02:02", "DIRECT-foo")
1193    msg['payload'] += ie_p2p(attrs)
1194    hapd.mgmt_tx(msg)
1195    if hapd.mgmt_rx(timeout=1) is None:
1196        raise Exception("No PD response " + str(dialog_token))
1197    ev = dev[0].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=1)
1198    if ev is not None:
1199        raise Exception("Unexpected PD event")
1200
1201    # Listen channel is not yet known
1202    if "FAIL" not in dev[0].global_request("P2P_PROV_DISC " + src + " display"):
1203        raise Exception("Unexpected P2P_PROV_DISC success")
1204
1205    # Unknown peer
1206    if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 02:03:04:05:06:07 display"):
1207        raise Exception("Unexpected P2P_PROV_DISC success (2)")
1208
1209def test_p2p_msg_pd(dev, apdev):
1210    """P2P protocol tests for provision discovery request processing (known)"""
1211    dst, src, hapd, channel = start_p2p(dev, apdev)
1212    dialog_token = 0
1213
1214    p2p_probe(hapd, src, chan=channel)
1215    time.sleep(0.1)
1216
1217    # Valid request
1218    dialog_token += 1
1219    msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
1220    attrs = wsc_attr_config_methods(methods=0x1008)
1221    msg['payload'] += ie_wsc(attrs)
1222    attrs = p2p_attr_capability()
1223    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1224    msg['payload'] += ie_p2p(attrs)
1225    hapd.mgmt_tx(msg)
1226    ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
1227    if ev is None:
1228        raise Exception("Timeout on device found event")
1229    ev = dev[0].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=5)
1230    if ev is None:
1231        raise Exception("Timeout on PD event")
1232    if hapd.mgmt_rx(timeout=1) is None:
1233        raise Exception("No PD response " + str(dialog_token))
1234
1235    if "FAIL" in dev[0].global_request("P2P_PROV_DISC " + src + " display"):
1236        raise Exception("Unexpected P2P_PROV_DISC failure")
1237    frame = hapd.mgmt_rx(timeout=1)
1238    if frame is None:
1239        raise Exception("No PD request " + str(dialog_token))
1240    p2p = parse_p2p_public_action(frame['payload'])
1241    if p2p is None:
1242        raise Exception("Failed to parse PD request")
1243
1244    # invalid dialog token
1245    msg = p2p_hdr_resp(dst, src, type=P2P_PROV_DISC_RESP,
1246                       dialog_token=p2p['dialog_token'] + 1)
1247    hapd.mgmt_tx(msg)
1248    ev = dev[0].wait_global_event(["P2P-PROV-DISC-FAILURE"], timeout=0.1)
1249    if ev is not None:
1250        raise Exception("Unexpected PD result event")
1251
1252    # valid dialog token
1253    msg = p2p_hdr_resp(dst, src, type=P2P_PROV_DISC_RESP,
1254                       dialog_token=p2p['dialog_token'])
1255    hapd.mgmt_tx(msg)
1256    ev = dev[0].wait_global_event(["P2P-PROV-DISC-FAILURE"], timeout=5)
1257    if ev is None:
1258        raise Exception("Timeout on PD result event")
1259
1260    # valid dialog token
1261    msg = p2p_hdr_resp(dst, src, type=P2P_PROV_DISC_RESP,
1262                       dialog_token=p2p['dialog_token'])
1263    hapd.mgmt_tx(msg)
1264    ev = dev[0].wait_global_event(["P2P-PROV-DISC-FAILURE"], timeout=0.1)
1265    if ev is not None:
1266        raise Exception("Unexpected PD result event")
1267
1268def check_p2p_response(hapd, dialog_token, status):
1269    resp = hapd.mgmt_rx(timeout=2)
1270    if resp is None:
1271        raise Exception("No GO Neg Response " + str(dialog_token))
1272    p2p = parse_p2p_public_action(resp['payload'])
1273    if p2p is None:
1274        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1275    if dialog_token != p2p['dialog_token']:
1276        raise Exception("Unexpected dialog token in response")
1277    if p2p['p2p_status'] != status:
1278        raise Exception("Unexpected status code %s in response (expected %d)" % (p2p['p2p_status'], status))
1279
1280def test_p2p_msg_go_neg_both_start(dev, apdev):
1281    """P2P protocol test for simultaneous GO Neg initiation"""
1282    try:
1283        dev[0].global_request("P2P_SET listen_channel 6")
1284        dev[1].global_request("P2P_SET listen_channel 6")
1285        run_p2p_msg_go_neg_both_start(dev)
1286    finally:
1287        set_random_listen_chan(dev[0])
1288        set_random_listen_chan(dev[1])
1289
1290def run_p2p_msg_go_neg_both_start(dev):
1291    addr0 = dev[0].p2p_dev_addr()
1292    addr1 = dev[1].p2p_dev_addr()
1293    dev[0].p2p_listen()
1294    dev[1].discover_peer(addr0)
1295    dev[1].p2p_listen()
1296    dev[0].discover_peer(addr1)
1297    dev[0].p2p_listen()
1298    if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 1"):
1299        raise Exception("Failed to enable external management frame handling")
1300    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
1301        raise Exception("Failed to enable external management frame handling")
1302    dev[0].request("P2P_CONNECT {} pbc".format(addr1))
1303    dev[1].request("P2P_CONNECT {} pbc".format(addr0))
1304    msg = dev[0].mgmt_rx()
1305    if msg is None:
1306        raise Exception("MGMT-RX timeout")
1307    msg = dev[1].mgmt_rx()
1308    if msg is None:
1309        raise Exception("MGMT-RX timeout(2)")
1310    if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 0"):
1311        raise Exception("Failed to disable external management frame handling")
1312    ev = dev[0].wait_global_event(["P2P-GO-NEG-SUCCESS"], timeout=2)
1313    if ev is not None:
1314        raise Exception("Unexpected GO Neg success")
1315    if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 0"):
1316        raise Exception("Failed to disable external management frame handling")
1317    ev = dev[0].wait_global_event(["P2P-GO-NEG-SUCCESS"], timeout=10)
1318    if ev is None:
1319        raise Exception("GO Neg did not succeed")
1320    ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=5)
1321    if ev is None:
1322        raise Exception("Group formation not succeed")
1323    ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=5)
1324    if ev is None:
1325        raise Exception("Group formation not succeed")
1326
1327def test_p2p_msg_go_neg_req(dev, apdev):
1328    """P2P protocol tests for invitation request from unknown peer"""
1329    dst, src, hapd, channel = start_p2p(dev, apdev)
1330    dialog_token = 0
1331
1332    # invalid attribute
1333    dialog_token += 1
1334    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1335    attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
1336    msg['payload'] += ie_p2p(attrs)
1337    hapd.mgmt_tx(msg)
1338    frame = hapd.mgmt_rx(timeout=0.1)
1339    if frame is not None:
1340        print(frame)
1341        raise Exception("Unexpected GO Neg Response")
1342
1343    # missing atributes
1344    dialog_token += 1
1345    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1346    attrs = p2p_attr_capability()
1347    attrs += p2p_attr_go_intent()
1348    attrs += p2p_attr_config_timeout()
1349    #attrs += p2p_attr_listen_channel()
1350    attrs += p2p_attr_ext_listen_timing()
1351    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1352    attrs += p2p_attr_channel_list()
1353    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1354    attrs += p2p_attr_operating_channel()
1355    msg['payload'] += ie_p2p(attrs)
1356    hapd.mgmt_tx(msg)
1357    if hapd.mgmt_rx(timeout=2) is None:
1358        raise Exception("No GO Neg Response " + str(dialog_token))
1359    time.sleep(0.1)
1360
1361    dialog_token += 1
1362    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1363    attrs = p2p_attr_capability()
1364    attrs += p2p_attr_go_intent()
1365    attrs += p2p_attr_config_timeout()
1366    attrs += p2p_attr_listen_channel()
1367    attrs += p2p_attr_ext_listen_timing()
1368    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1369    attrs += p2p_attr_channel_list()
1370    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1371    #attrs += p2p_attr_operating_channel()
1372    msg['payload'] += ie_p2p(attrs)
1373    hapd.mgmt_tx(msg)
1374    if hapd.mgmt_rx(timeout=2) is None:
1375        raise Exception("No GO Neg Response " + str(dialog_token))
1376    time.sleep(0.1)
1377
1378    dialog_token += 1
1379    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1380    attrs = p2p_attr_capability()
1381    attrs += p2p_attr_go_intent()
1382    attrs += p2p_attr_config_timeout()
1383    attrs += p2p_attr_listen_channel()
1384    attrs += p2p_attr_ext_listen_timing()
1385    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1386    #attrs += p2p_attr_channel_list()
1387    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1388    attrs += p2p_attr_operating_channel()
1389    msg['payload'] += ie_p2p(attrs)
1390    hapd.mgmt_tx(msg)
1391    if hapd.mgmt_rx(timeout=2) is None:
1392        raise Exception("No GO Neg Response " + str(dialog_token))
1393    time.sleep(0.1)
1394
1395    dialog_token += 1
1396    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1397    attrs = p2p_attr_capability()
1398    attrs += p2p_attr_go_intent()
1399    attrs += p2p_attr_config_timeout()
1400    attrs += p2p_attr_listen_channel()
1401    attrs += p2p_attr_ext_listen_timing()
1402    #attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1403    attrs += p2p_attr_channel_list()
1404    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1405    attrs += p2p_attr_operating_channel()
1406    msg['payload'] += ie_p2p(attrs)
1407    hapd.mgmt_tx(msg)
1408    if hapd.mgmt_rx(timeout=2) is None:
1409        raise Exception("No GO Neg Response " + str(dialog_token))
1410    time.sleep(0.1)
1411
1412    dialog_token += 1
1413    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1414    attrs = p2p_attr_capability()
1415    attrs += p2p_attr_go_intent()
1416    attrs += p2p_attr_config_timeout()
1417    attrs += p2p_attr_listen_channel()
1418    attrs += p2p_attr_ext_listen_timing()
1419    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1420    attrs += p2p_attr_channel_list()
1421    #attrs += p2p_attr_device_info(src, config_methods=0x0108)
1422    attrs += p2p_attr_operating_channel()
1423    msg['payload'] += ie_p2p(attrs)
1424    hapd.mgmt_tx(msg)
1425    if hapd.mgmt_rx(timeout=2) is None:
1426        raise Exception("No GO Neg Response " + str(dialog_token))
1427    time.sleep(0.1)
1428
1429    # SA != P2P Device address
1430    dialog_token += 1
1431    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1432    attrs = p2p_attr_capability()
1433    attrs += p2p_attr_go_intent()
1434    attrs += p2p_attr_config_timeout()
1435    attrs += p2p_attr_listen_channel()
1436    attrs += p2p_attr_ext_listen_timing()
1437    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1438    attrs += p2p_attr_channel_list()
1439    attrs += p2p_attr_device_info("02:02:02:02:02:02", config_methods=0x0108)
1440    attrs += p2p_attr_operating_channel()
1441    msg['payload'] += ie_p2p(attrs)
1442    hapd.mgmt_tx(msg)
1443    if hapd.mgmt_rx(timeout=2) is None:
1444        raise Exception("No GO Neg Response " + str(dialog_token))
1445    time.sleep(0.1)
1446
1447    # unexpected Status attribute
1448    dialog_token += 1
1449    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1450    attrs = p2p_attr_capability()
1451    attrs += p2p_attr_go_intent()
1452    attrs += p2p_attr_config_timeout()
1453    attrs += p2p_attr_listen_channel()
1454    attrs += p2p_attr_ext_listen_timing()
1455    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1456    attrs += p2p_attr_channel_list()
1457    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1458    attrs += p2p_attr_operating_channel()
1459    attrs += p2p_attr_status(status=P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
1460    msg['payload'] += ie_p2p(attrs)
1461    hapd.mgmt_tx(msg)
1462    if hapd.mgmt_rx(timeout=2) is None:
1463        raise Exception("No GO Neg Response(1) " + str(dialog_token))
1464    time.sleep(0.1)
1465
1466    # valid (with workarounds) GO Neg Req
1467    dialog_token += 1
1468    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1469    #attrs = p2p_attr_capability()
1470    #attrs += p2p_attr_go_intent()
1471    #attrs += p2p_attr_config_timeout()
1472    attrs = p2p_attr_listen_channel()
1473    attrs += p2p_attr_ext_listen_timing()
1474    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1475    attrs += p2p_attr_channel_list()
1476    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1477    attrs += p2p_attr_operating_channel()
1478    msg['payload'] += ie_p2p(attrs)
1479    hapd.mgmt_tx(msg)
1480    check_p2p_response(hapd, dialog_token,
1481                       P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
1482    ev = dev[0].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=2)
1483    if ev is None:
1484        raise Exception("Timeout on GO Neg event " + str(dialog_token))
1485
1486    dev[0].request("P2P_CONNECT " + src + " 12345670 display auth")
1487
1488    # ready - missing attributes (with workarounds) GO Neg Req
1489    time.sleep(0.1)
1490    dialog_token += 1
1491    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1492    #attrs = p2p_attr_capability()
1493    #attrs += p2p_attr_go_intent()
1494    #attrs += p2p_attr_config_timeout()
1495    attrs = p2p_attr_listen_channel()
1496    attrs += p2p_attr_ext_listen_timing()
1497    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1498    attrs += p2p_attr_channel_list()
1499    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1500    attrs += p2p_attr_operating_channel()
1501    msg['payload'] += ie_p2p(attrs)
1502    hapd.mgmt_tx(msg)
1503    if hapd.mgmt_rx(timeout=2) is None:
1504        raise Exception("No GO Neg Response " + str(dialog_token))
1505
1506    # ready - invalid GO Intent GO Neg Req
1507    time.sleep(0.1)
1508    dialog_token += 1
1509    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1510    #attrs = p2p_attr_capability()
1511    attrs = p2p_attr_go_intent(go_intent=16)
1512    #attrs += p2p_attr_config_timeout()
1513    attrs += p2p_attr_listen_channel()
1514    attrs += p2p_attr_ext_listen_timing()
1515    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1516    attrs += p2p_attr_channel_list()
1517    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1518    attrs += p2p_attr_operating_channel()
1519    msg['payload'] += ie_p2p(attrs)
1520    hapd.mgmt_tx(msg)
1521    check_p2p_response(hapd, dialog_token, P2P_SC_FAIL_INVALID_PARAMS)
1522
1523    # ready - invalid Channel List
1524    time.sleep(0.1)
1525    dialog_token += 1
1526    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1527    attrs = p2p_attr_capability()
1528    attrs += p2p_attr_go_intent()
1529    attrs += p2p_attr_config_timeout()
1530    attrs += p2p_attr_listen_channel()
1531    attrs += p2p_attr_ext_listen_timing()
1532    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1533    attrs += struct.pack("<BH3BBB11B", P2P_ATTR_CHANNEL_LIST, 16,
1534                         0x58, 0x58, 0x04,
1535                         81, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
1536    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1537    attrs += p2p_attr_operating_channel()
1538    msg['payload'] += ie_p2p(attrs)
1539    hapd.mgmt_tx(msg)
1540    check_p2p_response(hapd, dialog_token, P2P_SC_FAIL_NO_COMMON_CHANNELS)
1541
1542    # ready - invalid GO Neg Req (unsupported Device Password ID)
1543    time.sleep(0.1)
1544    dialog_token += 1
1545    msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1546    attrs = p2p_attr_capability()
1547    attrs += p2p_attr_go_intent()
1548    attrs += p2p_attr_config_timeout()
1549    attrs += p2p_attr_listen_channel()
1550    attrs += p2p_attr_ext_listen_timing()
1551    attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1552    # very long channel list
1553    attrs += struct.pack("<BH3BBB11B30B", P2P_ATTR_CHANNEL_LIST, 46,
1554                         0x58, 0x58, 0x04,
1555                         81, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
1556                         1, 1, 1, 2, 1, 2, 3, 1, 3, 4, 1, 4, 5, 1, 5,
1557                         6, 1, 6, 7, 1, 7, 8, 1, 8, 9, 1, 9, 10, 1, 10)
1558    attrs += p2p_attr_device_info(src, config_methods=0x0108)
1559    attrs += p2p_attr_operating_channel()
1560    msg['payload'] += ie_p2p(attrs)
1561    hapd.mgmt_tx(msg)
1562    check_p2p_response(hapd, dialog_token, P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD)
1563
1564def mgmt_tx(dev, msg):
1565    for i in range(0, 20):
1566        if "FAIL" in dev.request(msg):
1567            raise Exception("Failed to send Action frame")
1568        ev = dev.wait_event(["MGMT-TX-STATUS"], timeout=10)
1569        if ev is None:
1570            raise Exception("Timeout on MGMT-TX-STATUS")
1571        if "result=SUCCESS" in ev:
1572            break
1573        time.sleep(0.01)
1574    if "result=SUCCESS" not in ev:
1575        raise Exception("Peer did not ack Action frame")
1576
1577def rx_go_neg_req(dev):
1578    msg = dev.mgmt_rx()
1579    if msg is None:
1580        raise Exception("MGMT-RX timeout")
1581    p2p = parse_p2p_public_action(msg['payload'])
1582    if p2p is None:
1583        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1584    if p2p['subtype'] != P2P_GO_NEG_REQ:
1585        raise Exception("Unexpected subtype %d" % p2p['subtype'])
1586    p2p['freq'] = msg['freq']
1587    return p2p
1588
1589def rx_go_neg_conf(dev, status=None, dialog_token=None):
1590    msg = dev.mgmt_rx()
1591    if msg is None:
1592        raise Exception("MGMT-RX timeout")
1593    p2p = parse_p2p_public_action(msg['payload'])
1594    if p2p is None:
1595        raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1596    if p2p['subtype'] != P2P_GO_NEG_CONF:
1597        raise Exception("Unexpected subtype %d" % p2p['subtype'])
1598    if dialog_token is not None and dialog_token != p2p['dialog_token']:
1599        raise Exception("Unexpected dialog token")
1600    if status is not None and p2p['p2p_status'] != status:
1601        raise Exception("Unexpected status %d" % p2p['p2p_status'])
1602
1603def check_p2p_go_neg_fail_event(dev, status):
1604    ev = dev.wait_global_event(["P2P-GO-NEG-FAILURE"], timeout=5)
1605    if ev is None:
1606        raise Exception("GO Negotiation failure not reported")
1607    if "status=%d" % status not in ev:
1608        raise Exception("Unexpected failure reason: " + ev)
1609
1610def test_p2p_msg_go_neg_req_reject(dev, apdev):
1611    """P2P protocol tests for user reject incorrectly in GO Neg Req"""
1612    addr0 = dev[0].p2p_dev_addr()
1613    addr1 = dev[1].p2p_dev_addr()
1614    dev[0].p2p_listen()
1615    dev[1].discover_peer(addr0)
1616    dev[1].group_request("P2P_CONNECT " + addr0 + " pbc")
1617    ev = dev[0].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=10)
1618    if ev is None:
1619        raise Exception("Timeout on GO Neg Req")
1620
1621    peer = dev[0].get_peer(addr1)
1622    dev[0].p2p_stop_find()
1623
1624    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_REQ, dialog_token=123)
1625    attrs = p2p_attr_capability()
1626    attrs += p2p_attr_status(status=P2P_SC_FAIL_REJECTED_BY_USER)
1627    attrs += p2p_attr_go_intent()
1628    attrs += p2p_attr_config_timeout()
1629    attrs += p2p_attr_listen_channel()
1630    attrs += p2p_attr_ext_listen_timing()
1631    attrs += p2p_attr_intended_interface_addr(addr0)
1632    attrs += p2p_attr_channel_list()
1633    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1634    attrs += p2p_attr_operating_channel()
1635    msg['payload'] += ie_p2p(attrs)
1636
1637    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(
1638        addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload']).decode()))
1639
1640    ev = dev[1].wait_global_event(["P2P-GO-NEG-FAILURE"], timeout=5)
1641    if ev is None:
1642        raise Exception("GO Negotiation failure not reported")
1643    if "status=%d" % P2P_SC_FAIL_REJECTED_BY_USER not in ev:
1644        raise Exception("Unexpected failure reason: " + ev)
1645
1646def test_p2p_msg_unexpected_go_neg_resp(dev, apdev):
1647    """P2P protocol tests for unexpected GO Neg Resp"""
1648    addr0 = dev[0].p2p_dev_addr()
1649    addr1 = dev[1].p2p_dev_addr()
1650    dev[1].p2p_listen()
1651    dev[0].discover_peer(addr1)
1652    dev[0].p2p_stop_find()
1653    dev[0].dump_monitor()
1654
1655    peer = dev[0].get_peer(addr1)
1656
1657    logger.debug("GO Neg Resp without GO Neg session")
1658    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=123)
1659    attrs = p2p_attr_status()
1660    attrs += p2p_attr_capability()
1661    attrs += p2p_attr_go_intent()
1662    attrs += p2p_attr_config_timeout()
1663    attrs += p2p_attr_intended_interface_addr(addr0)
1664    attrs += p2p_attr_channel_list()
1665    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1666    attrs += p2p_attr_operating_channel()
1667    msg['payload'] += ie_p2p(attrs)
1668    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(
1669        addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload']).decode()))
1670
1671    dev[0].p2p_listen()
1672    dev[1].discover_peer(addr0)
1673    dev[0].dump_monitor()
1674    dev[1].dump_monitor()
1675
1676    logger.debug("Unexpected GO Neg Resp while waiting for new GO Neg session")
1677    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1678        raise Exception("P2P_CONNECT failed")
1679    ev = dev[0].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=10)
1680    if ev is None:
1681        raise Exception("Timeout on GO Neg Req")
1682    dev[0].p2p_stop_find()
1683    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(
1684        addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload']).decode()))
1685    dev[0].dump_monitor()
1686    dev[1].dump_monitor()
1687
1688    logger.debug("Invalid attribute in GO Neg Response")
1689    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=197)
1690    attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
1691    msg['payload'] += ie_p2p(attrs)
1692    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(
1693        addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload']).decode()))
1694    frame = dev[0].mgmt_rx(timeout=0.1)
1695    if frame is not None:
1696        raise Exception("Unexpected GO Neg Confirm")
1697    dev[0].dump_monitor()
1698    dev[1].dump_monitor()
1699
1700    logger.debug("GO Neg Resp with unexpected dialog token")
1701    dev[1].p2p_stop_find()
1702    if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 1"):
1703        raise Exception("Failed to enable external management frame handling")
1704    dev[0].p2p_listen()
1705    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1706        raise Exception("P2P_CONNECT failed(2)")
1707    p2p = rx_go_neg_req(dev[0])
1708    dev[0].p2p_stop_find()
1709    dialog_token = p2p['dialog_token']
1710    if dialog_token < 255:
1711        dialog_token += 1
1712    else:
1713        dialog_token = 1
1714    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1715    attrs = p2p_attr_status()
1716    attrs += p2p_attr_capability()
1717    attrs += p2p_attr_go_intent()
1718    attrs += p2p_attr_config_timeout()
1719    attrs += p2p_attr_intended_interface_addr(addr0)
1720    attrs += p2p_attr_channel_list()
1721    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1722    attrs += p2p_attr_operating_channel()
1723    msg['payload'] += ie_p2p(attrs)
1724    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1725        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1726    dev[0].dump_monitor()
1727    dev[1].dump_monitor()
1728
1729    logger.debug("GO Neg Resp without Status")
1730    dev[1].p2p_stop_find()
1731    dev[0].p2p_listen()
1732    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1733        raise Exception("P2P_CONNECT failed(2)")
1734    p2p = rx_go_neg_req(dev[0])
1735    dev[0].p2p_stop_find()
1736    dialog_token = p2p['dialog_token']
1737    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1738    #attrs = p2p_attr_status()
1739    attrs = p2p_attr_capability()
1740    attrs += p2p_attr_go_intent()
1741    attrs += p2p_attr_config_timeout()
1742    attrs += p2p_attr_intended_interface_addr(addr0)
1743    attrs += p2p_attr_channel_list()
1744    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1745    attrs += p2p_attr_operating_channel()
1746    msg['payload'] += ie_p2p(attrs)
1747    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1748        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1749    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1750    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1751    dev[0].dump_monitor()
1752    dev[1].dump_monitor()
1753
1754    logger.debug("GO Neg Resp without Intended Address")
1755    dev[1].p2p_stop_find()
1756    dev[0].p2p_listen()
1757    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1758        raise Exception("P2P_CONNECT failed(2)")
1759    p2p = rx_go_neg_req(dev[0])
1760    dev[0].p2p_stop_find()
1761    dialog_token = p2p['dialog_token']
1762    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1763    attrs = p2p_attr_status()
1764    #attrs += p2p_attr_capability()
1765    attrs += p2p_attr_go_intent()
1766    attrs += p2p_attr_config_timeout()
1767    #attrs += p2p_attr_intended_interface_addr(addr0)
1768    attrs += p2p_attr_channel_list()
1769    #attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1770    attrs += p2p_attr_operating_channel()
1771    msg['payload'] += ie_p2p(attrs)
1772    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1773        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1774    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1775    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1776    dev[0].dump_monitor()
1777    dev[1].dump_monitor()
1778
1779    logger.debug("GO Neg Resp without GO Intent")
1780    dev[1].p2p_stop_find()
1781    dev[0].p2p_listen()
1782    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1783        raise Exception("P2P_CONNECT failed(2)")
1784    p2p = rx_go_neg_req(dev[0])
1785    dev[0].p2p_stop_find()
1786    dialog_token = p2p['dialog_token']
1787    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1788    attrs = p2p_attr_status()
1789    attrs += p2p_attr_capability()
1790    #attrs += p2p_attr_go_intent()
1791    attrs += p2p_attr_config_timeout()
1792    attrs += p2p_attr_intended_interface_addr(addr0)
1793    attrs += p2p_attr_channel_list()
1794    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1795    attrs += p2p_attr_operating_channel()
1796    msg['payload'] += ie_p2p(attrs)
1797    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1798        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1799    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1800    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1801    dev[0].dump_monitor()
1802    dev[1].dump_monitor()
1803
1804    logger.debug("GO Neg Resp with invalid GO Intent")
1805    dev[1].p2p_stop_find()
1806    dev[0].p2p_listen()
1807    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1808        raise Exception("P2P_CONNECT failed(2)")
1809    p2p = rx_go_neg_req(dev[0])
1810    dev[0].p2p_stop_find()
1811    dialog_token = p2p['dialog_token']
1812    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1813    attrs = p2p_attr_status()
1814    attrs += p2p_attr_capability()
1815    attrs += p2p_attr_go_intent(go_intent=16)
1816    attrs += p2p_attr_config_timeout()
1817    attrs += p2p_attr_intended_interface_addr(addr0)
1818    attrs += p2p_attr_channel_list()
1819    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1820    attrs += p2p_attr_operating_channel()
1821    msg['payload'] += ie_p2p(attrs)
1822    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1823        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1824    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1825    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1826    dev[0].dump_monitor()
1827    dev[1].dump_monitor()
1828
1829    logger.debug("GO Neg Resp with incompatible GO Intent")
1830    dev[1].p2p_stop_find()
1831    dev[0].p2p_listen()
1832    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=15"):
1833        raise Exception("P2P_CONNECT failed(2)")
1834    p2p = rx_go_neg_req(dev[0])
1835    dev[0].p2p_stop_find()
1836    dialog_token = p2p['dialog_token']
1837    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1838    attrs = p2p_attr_status()
1839    attrs += p2p_attr_capability()
1840    attrs += p2p_attr_go_intent(go_intent=15)
1841    attrs += p2p_attr_config_timeout()
1842    attrs += p2p_attr_intended_interface_addr(addr0)
1843    attrs += p2p_attr_channel_list()
1844    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1845    attrs += p2p_attr_operating_channel()
1846    msg['payload'] += ie_p2p(attrs)
1847    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1848        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1849    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INCOMPATIBLE_PARAMS)
1850    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INCOMPATIBLE_PARAMS, dialog_token)
1851    dev[0].dump_monitor()
1852    dev[1].dump_monitor()
1853
1854    logger.debug("GO Neg Resp without P2P Group ID")
1855    dev[1].p2p_stop_find()
1856    dev[0].p2p_listen()
1857    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1858        raise Exception("P2P_CONNECT failed(2)")
1859    p2p = rx_go_neg_req(dev[0])
1860    dev[0].p2p_stop_find()
1861    dialog_token = p2p['dialog_token']
1862    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1863    attrs = p2p_attr_status()
1864    attrs += p2p_attr_capability()
1865    attrs += p2p_attr_go_intent(go_intent=15)
1866    attrs += p2p_attr_config_timeout()
1867    attrs += p2p_attr_intended_interface_addr(addr0)
1868    attrs += p2p_attr_channel_list()
1869    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1870    attrs += p2p_attr_operating_channel()
1871    #attrs += p2p_attr_group_id(src, "DIRECT-foo")
1872    msg['payload'] += ie_p2p(attrs)
1873    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1874        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1875    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1876    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1877    dev[0].dump_monitor()
1878    dev[1].dump_monitor()
1879
1880    logger.debug("GO Neg Resp without Operating Channel")
1881    dev[1].p2p_stop_find()
1882    dev[0].p2p_listen()
1883    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1884        raise Exception("P2P_CONNECT failed(2)")
1885    p2p = rx_go_neg_req(dev[0])
1886    dev[0].p2p_stop_find()
1887    dialog_token = p2p['dialog_token']
1888    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1889    attrs = p2p_attr_status()
1890    attrs += p2p_attr_capability()
1891    attrs += p2p_attr_go_intent(go_intent=15)
1892    #attrs += p2p_attr_config_timeout()
1893    attrs += p2p_attr_intended_interface_addr(addr0)
1894    attrs += p2p_attr_channel_list()
1895    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1896    #attrs += p2p_attr_operating_channel()
1897    attrs += p2p_attr_group_id(addr0, "DIRECT-foo")
1898    msg['payload'] += ie_p2p(attrs)
1899    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1900        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1901    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1902    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1903    dev[0].dump_monitor()
1904    dev[1].dump_monitor()
1905
1906    logger.debug("GO Neg Resp without Channel List")
1907    dev[1].p2p_stop_find()
1908    dev[0].p2p_listen()
1909    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1910        raise Exception("P2P_CONNECT failed(2)")
1911    p2p = rx_go_neg_req(dev[0])
1912    dev[0].p2p_stop_find()
1913    dialog_token = p2p['dialog_token']
1914    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1915    attrs = p2p_attr_status()
1916    attrs += p2p_attr_capability()
1917    attrs += p2p_attr_go_intent(go_intent=15)
1918    attrs += p2p_attr_config_timeout()
1919    attrs += p2p_attr_intended_interface_addr(addr0)
1920    #attrs += p2p_attr_channel_list()
1921    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1922    attrs += p2p_attr_operating_channel()
1923    attrs += p2p_attr_group_id(addr0, "DIRECT-foo")
1924    msg['payload'] += ie_p2p(attrs)
1925    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1926        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1927    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1928    rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1929    dev[0].dump_monitor()
1930    dev[1].dump_monitor()
1931
1932    logger.debug("GO Neg Resp without common channels")
1933    dev[1].p2p_stop_find()
1934    dev[0].p2p_listen()
1935    if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1936        raise Exception("P2P_CONNECT failed(2)")
1937    p2p = rx_go_neg_req(dev[0])
1938    dev[0].p2p_stop_find()
1939    dialog_token = p2p['dialog_token']
1940    msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1941    attrs = p2p_attr_status()
1942    attrs += p2p_attr_capability()
1943    attrs += p2p_attr_go_intent(go_intent=15)
1944    attrs += p2p_attr_config_timeout()
1945    attrs += p2p_attr_intended_interface_addr(addr0)
1946    attrs += struct.pack("<BH3BBB", P2P_ATTR_CHANNEL_LIST, 5,
1947                         0x58, 0x58, 0x04,
1948                         81, 0)
1949    attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1950    attrs += p2p_attr_operating_channel()
1951    attrs += p2p_attr_group_id(addr0, "DIRECT-foo")
1952    msg['payload'] += ie_p2p(attrs)
1953    mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(
1954        addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload']).decode()))
1955    check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_NO_COMMON_CHANNELS)
1956    rx_go_neg_conf(dev[0], P2P_SC_FAIL_NO_COMMON_CHANNELS, dialog_token)
1957    dev[0].dump_monitor()
1958    dev[1].dump_monitor()
1959
1960def test_p2p_msg_group_info(dev):
1961    """P2P protocol tests for Group Info parsing"""
1962    try:
1963        _test_p2p_msg_group_info(dev)
1964    finally:
1965        dev[0].request("VENDOR_ELEM_REMOVE 2 *")
1966
1967def _test_p2p_msg_group_info(dev):
1968    tests = ["dd08506f9a090e010001",
1969             "dd08506f9a090e010000",
1970             "dd20506f9a090e190018" + "112233445566" + "aabbccddeeff" + "00" + "0000" + "0000000000000000" + "ff",
1971             "dd20506f9a090e190018" + "112233445566" + "aabbccddeeff" + "00" + "0000" + "0000000000000000" + "00",
1972             "dd24506f9a090e1d001c" + "112233445566" + "aabbccddeeff" + "00" + "0000" + "0000000000000000" + "00" + "00000000",
1973             "dd24506f9a090e1d001c" + "112233445566" + "aabbccddeeff" + "00" + "0000" + "0000000000000000" + "00" + "10110001",
1974             "dd24506f9a090e1d001c" + "112233445566" + "aabbccddeeff" + "00" + "0000" + "0000000000000000" + "00" + "1011ffff"]
1975    for t in tests:
1976        dev[0].request("VENDOR_ELEM_REMOVE 2 *")
1977        if "OK" not in dev[0].request("VENDOR_ELEM_ADD 2 " + t):
1978            raise Exception("VENDOR_ELEM_ADD failed")
1979        dev[0].p2p_start_go(freq=2412)
1980        bssid = dev[0].get_group_status_field('bssid')
1981        dev[2].request("BSS_FLUSH 0")
1982        dev[2].scan_for_bss(bssid, freq=2412, force_scan=True)
1983        bss = dev[2].request("BSS " + bssid)
1984        if 'p2p_group_client' in bss:
1985            raise Exception("Unexpected p2p_group_client")
1986        dev[0].remove_group()
1987
1988MGMT_SUBTYPE_ACTION = 13
1989ACTION_CATEG_PUBLIC = 4
1990
1991GAS_INITIAL_REQUEST = 10
1992GAS_INITIAL_RESPONSE = 11
1993GAS_COMEBACK_REQUEST = 12
1994GAS_COMEBACK_RESPONSE = 13
1995
1996def gas_hdr(dst, src, type, req=True, dialog_token=0):
1997    msg = {}
1998    msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1999    msg['da'] = dst
2000    msg['sa'] = src
2001    if req:
2002        msg['bssid'] = dst
2003    else:
2004        msg['bssid'] = src
2005    if dialog_token is None:
2006        msg['payload'] = struct.pack("<BB", ACTION_CATEG_PUBLIC, type)
2007    else:
2008        msg['payload'] = struct.pack("<BBB", ACTION_CATEG_PUBLIC, type,
2009                                     dialog_token)
2010    return msg
2011
2012@remote_compatible
2013def test_p2p_msg_sd(dev, apdev):
2014    """P2P protocol tests for service discovery messages"""
2015    dst, src, hapd, channel = start_p2p(dev, apdev)
2016
2017    logger.debug("Truncated GAS Initial Request - no Dialog Token field")
2018    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST, dialog_token=None)
2019    hapd.mgmt_tx(msg)
2020
2021    logger.debug("Truncated GAS Initial Request - no Advertisement Protocol element")
2022    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2023    hapd.mgmt_tx(msg)
2024
2025    logger.debug("Truncated GAS Initial Request - no Advertisement Protocol element length")
2026    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2027    msg['payload'] += struct.pack('B', 108)
2028    hapd.mgmt_tx(msg)
2029
2030    logger.debug("Invalid GAS Initial Request - unexpected IE")
2031    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2032    msg['payload'] += struct.pack('BB', 0, 0)
2033    hapd.mgmt_tx(msg)
2034
2035    logger.debug("Truncated GAS Initial Request - too short Advertisement Protocol element")
2036    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2037    msg['payload'] += struct.pack('BB', 108, 0)
2038    hapd.mgmt_tx(msg)
2039
2040    logger.debug("Truncated GAS Initial Request - too short Advertisement Protocol element 2")
2041    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2042    msg['payload'] += struct.pack('BBB', 108, 1, 127)
2043    hapd.mgmt_tx(msg)
2044
2045    logger.debug("Invalid GAS Initial Request - unsupported GAS advertisement protocol id 255")
2046    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2047    msg['payload'] += struct.pack('BBBB', 108, 2, 127, 255)
2048    hapd.mgmt_tx(msg)
2049
2050    logger.debug("Truncated GAS Initial Request - no Query Request length field")
2051    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2052    msg['payload'] += anqp_adv_proto()
2053    hapd.mgmt_tx(msg)
2054
2055    logger.debug("Truncated GAS Initial Request - too short Query Request length field")
2056    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2057    msg['payload'] += anqp_adv_proto()
2058    msg['payload'] += struct.pack('<B', 0)
2059    hapd.mgmt_tx(msg)
2060
2061    logger.debug("Truncated GAS Initial Request - too short Query Request field (minimum underflow)")
2062    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2063    msg['payload'] += anqp_adv_proto()
2064    msg['payload'] += struct.pack('<H', 1)
2065    hapd.mgmt_tx(msg)
2066
2067    logger.debug("Truncated GAS Initial Request - too short Query Request field (maximum underflow)")
2068    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2069    msg['payload'] += anqp_adv_proto()
2070    msg['payload'] += struct.pack('<H', 65535)
2071    hapd.mgmt_tx(msg)
2072
2073    logger.debug("Truncated GAS Initial Request - too short Query Request field")
2074    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2075    msg['payload'] += anqp_adv_proto()
2076    msg['payload'] += struct.pack('<H', 0)
2077    hapd.mgmt_tx(msg)
2078
2079    logger.debug("Invalid GAS Initial Request - unsupported ANQP Info ID 65535")
2080    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2081    msg['payload'] += anqp_adv_proto()
2082    msg['payload'] += struct.pack('<HHH', 4, 65535, 0)
2083    hapd.mgmt_tx(msg)
2084
2085    logger.debug("Invalid GAS Initial Request - invalid ANQP Query Request length (truncated frame)")
2086    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2087    msg['payload'] += anqp_adv_proto()
2088    msg['payload'] += struct.pack('<HHH', 4, 56797, 65535)
2089    hapd.mgmt_tx(msg)
2090
2091    logger.debug("Invalid GAS Initial Request - invalid ANQP Query Request length (too short Query Request to contain OUI + OUI-type)")
2092    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2093    msg['payload'] += anqp_adv_proto()
2094    msg['payload'] += struct.pack('<HHH', 4, 56797, 0)
2095    hapd.mgmt_tx(msg)
2096
2097    logger.debug("Invalid GAS Initial Request - unsupported ANQP vendor OUI-type")
2098    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2099    msg['payload'] += anqp_adv_proto()
2100    req = struct.pack('<HH', 56797, 4) + struct.pack('>L', 0x506f9a00)
2101    msg['payload'] += struct.pack('<H', len(req)) + req
2102    hapd.mgmt_tx(msg)
2103
2104    logger.debug("Truncated GAS Initial Request - no Service Update Indicator")
2105    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2106    msg['payload'] += anqp_adv_proto()
2107    req = struct.pack('<HH', 56797, 4) + struct.pack('>L', 0x506f9a09)
2108    msg['payload'] += struct.pack('<H', len(req)) + req
2109    hapd.mgmt_tx(msg)
2110
2111    logger.debug("Truncated GAS Initial Request - truncated Service Update Indicator")
2112    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2113    msg['payload'] += anqp_adv_proto()
2114    req = struct.pack('<HH', 56797, 4) + struct.pack('>L', 0x506f9a09)
2115    req += struct.pack('<B', 0)
2116    msg['payload'] += struct.pack('<H', len(req)) + req
2117    hapd.mgmt_tx(msg)
2118
2119    logger.debug("Unexpected GAS Initial Response")
2120    hapd.dump_monitor()
2121    msg = gas_hdr(dst, src, GAS_INITIAL_RESPONSE)
2122    msg['payload'] += struct.pack('<HH', 0, 0)
2123    msg['payload'] += anqp_adv_proto()
2124    msg['payload'] += struct.pack('<H', 0)
2125    hapd.mgmt_tx(msg)
2126
2127    logger.debug("Truncated GAS Comeback Request - no Dialog Token field")
2128    msg = gas_hdr(dst, src, GAS_COMEBACK_REQUEST, dialog_token=None)
2129    hapd.mgmt_tx(msg)
2130
2131    logger.debug("GAS Comeback Request - no pending SD response fragment available")
2132    msg = gas_hdr(dst, src, GAS_COMEBACK_REQUEST)
2133    hapd.mgmt_tx(msg)
2134
2135    logger.debug("Unexpected GAS Comeback Response")
2136    hapd.dump_monitor()
2137    msg = gas_hdr(dst, src, GAS_COMEBACK_RESPONSE)
2138    msg['payload'] += struct.pack('<HBH', 0, 0, 0)
2139    msg['payload'] += anqp_adv_proto()
2140    msg['payload'] += struct.pack('<H', 0)
2141    hapd.mgmt_tx(msg)
2142
2143    logger.debug("Minimal GAS Initial Request")
2144    hapd.dump_monitor()
2145    msg = gas_hdr(dst, src, GAS_INITIAL_REQUEST)
2146    msg['payload'] += anqp_adv_proto()
2147    req = struct.pack('<HH', 56797, 4) + struct.pack('>L', 0x506f9a09)
2148    req += struct.pack('<H', 0)
2149    msg['payload'] += struct.pack('<H', len(req)) + req
2150    hapd.mgmt_tx(msg)
2151    resp = hapd.mgmt_rx()
2152    if resp is None:
2153        raise Exception("No response to minimal GAS Initial Request")
2154