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