tests: More protocol testing coverage for P2P invitation messages
[mech_eap.git] / tests / hwsim / test_p2p_messages.py
1 # P2P protocol tests for various messages
2 # Copyright (c) 2014, 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
7 import binascii
8 import struct
9 import time
10 import logging
11 logger = logging.getLogger()
12
13 import hostapd
14 from test_p2p_persistent import form
15 from test_p2p_persistent import invite
16
17 MGMT_SUBTYPE_PROBE_REQ = 4
18 MGMT_SUBTYPE_ACTION = 13
19 ACTION_CATEG_PUBLIC = 4
20
21 P2P_GO_NEG_REQ = 0
22 P2P_GO_NEG_RESP = 1
23 P2P_GO_NEG_CONF = 2
24 P2P_INVITATION_REQ = 3
25 P2P_INVITATION_RESP = 4
26 P2P_DEV_DISC_REQ = 5
27 P2P_DEV_DISC_RESP = 6
28 P2P_PROV_DISC_REQ = 7
29 P2P_PROV_DISC_RESP = 8
30
31 P2P_ATTR_STATUS = 0
32 P2P_ATTR_MINOR_REASON_CODE = 1
33 P2P_ATTR_CAPABILITY = 2
34 P2P_ATTR_DEVICE_ID = 3
35 P2P_ATTR_GROUP_OWNER_INTENT = 4
36 P2P_ATTR_CONFIGURATION_TIMEOUT = 5
37 P2P_ATTR_LISTEN_CHANNEL = 6
38 P2P_ATTR_GROUP_BSSID = 7
39 P2P_ATTR_EXT_LISTEN_TIMING = 8
40 P2P_ATTR_INTENDED_INTERFACE_ADDR = 9
41 P2P_ATTR_MANAGEABILITY = 10
42 P2P_ATTR_CHANNEL_LIST = 11
43 P2P_ATTR_NOTICE_OF_ABSENCE = 12
44 P2P_ATTR_DEVICE_INFO = 13
45 P2P_ATTR_GROUP_INFO = 14
46 P2P_ATTR_GROUP_ID = 15
47 P2P_ATTR_INTERFACE = 16
48 P2P_ATTR_OPERATING_CHANNEL = 17
49 P2P_ATTR_INVITATION_FLAGS = 18
50 P2P_ATTR_OOB_GO_NEG_CHANNEL = 19
51 P2P_ATTR_VENDOR_SPECIFIC = 221
52
53 P2P_SC_SUCCESS = 0
54 P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE = 1
55 P2P_SC_FAIL_INCOMPATIBLE_PARAMS = 2
56 P2P_SC_FAIL_LIMIT_REACHED = 3
57 P2P_SC_FAIL_INVALID_PARAMS = 4
58 P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE = 5
59 P2P_SC_FAIL_PREV_PROTOCOL_ERROR = 6
60 P2P_SC_FAIL_NO_COMMON_CHANNELS = 7
61 P2P_SC_FAIL_UNKNOWN_GROUP = 8
62 P2P_SC_FAIL_BOTH_GO_INTENT_15 = 9
63 P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD = 10
64 P2P_SC_FAIL_REJECTED_BY_USER = 11
65
66 WSC_ATTR_CONFIG_METHODS = 0x1008
67
68 WLAN_EID_SSID = 0
69 WLAN_EID_SUPP_RATES = 1
70 WLAN_EID_VENDOR_SPECIFIC = 221
71
72 def ie_ssid(ssid):
73     return struct.pack("<BB", WLAN_EID_SSID, len(ssid)) + ssid
74
75 def ie_supp_rates():
76     return struct.pack("<BBBBBBBBBB", WLAN_EID_SUPP_RATES, 8,
77                        2*6, 2*9, 2*12, 2*18, 2*24, 2*36, 2*48, 2*54)
78
79 def ie_p2p(attrs):
80     return struct.pack("<BBBBBB", WLAN_EID_VENDOR_SPECIFIC, 4 + len(attrs),
81                        0x50, 0x6f, 0x9a, 9) + attrs
82
83 def ie_wsc(attrs):
84     return struct.pack("<BBBBBB", WLAN_EID_VENDOR_SPECIFIC, 4 + len(attrs),
85                        0x00, 0x50, 0xf2, 4) + attrs
86
87 def wsc_attr_config_methods(methods=0):
88     return struct.pack(">HHH", WSC_ATTR_CONFIG_METHODS, 2, methods)
89
90 def p2p_attr_status(status=P2P_SC_SUCCESS):
91     return struct.pack("<BHB", P2P_ATTR_STATUS, 1, status)
92
93 def p2p_attr_minor_reason_code(code=0):
94     return struct.pack("<BHB", P2P_ATTR_MINOR_REASON_CODE, 1, code)
95
96 def p2p_attr_capability(dev_capab=0, group_capab=0):
97     return struct.pack("<BHBB", P2P_ATTR_CAPABILITY, 2, dev_capab, group_capab)
98
99 def p2p_attr_device_id(addr):
100     val = struct.unpack('6B', binascii.unhexlify(addr.replace(':','')))
101     t = (P2P_ATTR_DEVICE_ID, 6) + val
102     return struct.pack('<BH6B', *t)
103
104 def p2p_attr_go_intent(go_intent=0, tie_breaker=0):
105     return struct.pack("<BHB", P2P_ATTR_GROUP_OWNER_INTENT, 1,
106                        (go_intent << 1) | (tie_breaker & 0x01))
107
108 def p2p_attr_config_timeout(go_config_timeout=0, client_config_timeout=0):
109     return struct.pack("<BHBB", P2P_ATTR_CONFIGURATION_TIMEOUT, 2,
110                        go_config_timeout, client_config_timeout)
111
112 def p2p_attr_listen_channel(op_class=81, chan=1):
113     return struct.pack("<BHBBBBB", P2P_ATTR_LISTEN_CHANNEL, 5,
114                        0x58, 0x58, 0x04, op_class, chan)
115
116 def p2p_attr_group_bssid(addr):
117     val = struct.unpack('6B', binascii.unhexlify(addr.replace(':','')))
118     t = (P2P_ATTR_GROUP_BSSID, 6) + val
119     return struct.pack('<BH6B', *t)
120
121 def p2p_attr_ext_listen_timing(period=0, interval=0):
122     return struct.pack("<BHHH", P2P_ATTR_EXT_LISTEN_TIMING, 4, period, interval)
123
124 def p2p_attr_intended_interface_addr(addr):
125     val = struct.unpack('6B', binascii.unhexlify(addr.replace(':','')))
126     t = (P2P_ATTR_INTENDED_INTERFACE_ADDR, 6) + val
127     return struct.pack('<BH6B', *t)
128
129 def p2p_attr_manageability(bitmap=0):
130     return struct.pack("<BHB", P2P_ATTR_MANAGEABILITY, 1, bitmap)
131
132 def p2p_attr_channel_list():
133     return struct.pack("<BH3BBB11B", P2P_ATTR_CHANNEL_LIST, 16,
134                        0x58, 0x58, 0x04,
135                        81, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
136
137 def p2p_attr_device_info(addr, name="Test", config_methods=0, dev_type="00010050F2040001"):
138     val = struct.unpack('6B', binascii.unhexlify(addr.replace(':','')))
139     val2 = struct.unpack('8B', binascii.unhexlify(dev_type))
140     t = (P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 4 + len(name)) + val + (config_methods,) + val2 + (0,)
141     return struct.pack("<BH6BH8BB", *t) + struct.pack('>HH', 0x1011, len(name)) +name
142
143 def p2p_attr_group_id(addr, ssid):
144     val = struct.unpack('6B', binascii.unhexlify(addr.replace(':','')))
145     t = (P2P_ATTR_GROUP_ID, 6 + len(ssid)) + val
146     return struct.pack('<BH6B', *t) + ssid
147
148 def p2p_attr_operating_channel(op_class=81, chan=1):
149     return struct.pack("<BHBBBBB", P2P_ATTR_OPERATING_CHANNEL, 5,
150                        0x58, 0x58, 0x04, op_class, chan)
151
152 def p2p_attr_invitation_flags(bitmap=0):
153     return struct.pack("<BHB", P2P_ATTR_INVITATION_FLAGS, 1, bitmap)
154
155 def p2p_hdr_helper(dst, src, type=None, dialog_token=1, req=True):
156     msg = {}
157     msg['fc'] = MGMT_SUBTYPE_ACTION << 4
158     msg['da'] = dst
159     msg['sa'] = src
160     if req:
161         msg['bssid'] = dst
162     else:
163         msg['bssid'] = src
164     msg['payload'] = struct.pack("<BBBBBB",
165                                  ACTION_CATEG_PUBLIC, 9, 0x50, 0x6f, 0x9a, 9)
166     if type is not None:
167         msg['payload'] += struct.pack("<B", type)
168         if dialog_token:
169             msg['payload'] += struct.pack("<B", dialog_token)
170     return msg
171
172 def p2p_hdr(dst, src, type=None, dialog_token=1):
173     return p2p_hdr_helper(dst, src, type, dialog_token, True)
174
175 def p2p_hdr_resp(dst, src, type=None, dialog_token=1):
176     return p2p_hdr_helper(dst, src, type, dialog_token, False)
177
178 def start_p2p(dev, apdev):
179     addr0 = dev[0].p2p_dev_addr()
180     dev[0].p2p_listen()
181     dev[1].p2p_find(social=True)
182     ev = dev[1].wait_event(["P2P-DEVICE-FOUND"], timeout=5)
183     if ev is None:
184         raise Exception("Device discovery timed out")
185     dev[1].p2p_stop_find()
186     peer = dev[1].get_peer(addr0)
187
188     bssid = apdev[0]['bssid']
189     params = { 'ssid': "test", 'beacon_int': "2000" }
190     if peer['listen_freq'] == "2412":
191         params['channel'] = '1'
192     elif peer['listen_freq'] == "2437":
193         params['channel'] = '6'
194     elif peer['listen_freq'] == "2462":
195         params['channel'] = '11'
196     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
197     hapd.set("ext_mgmt_frame_handling", "1")
198     return addr0, bssid, hapd, int(params['channel'])
199
200 def p2p_probe(hapd, src, chan=1):
201     msg = {}
202     msg['fc'] = MGMT_SUBTYPE_PROBE_REQ << 4
203     msg['da'] = "ff:ff:ff:ff:ff:ff"
204     msg['sa'] = src
205     msg['bssid'] = "ff:ff:ff:ff:ff:ff"
206     attrs = p2p_attr_listen_channel(chan=chan)
207     msg['payload'] = ie_ssid("DIRECT-") + ie_supp_rates() + ie_p2p(attrs)
208     hapd.mgmt_tx(msg)
209
210 def parse_p2p_public_action(payload):
211     pos = payload
212     (category, action) = struct.unpack('BB', pos[0:2])
213     if category != ACTION_CATEG_PUBLIC:
214         return None
215     if action != 9:
216         return None
217     pos = pos[2:]
218     (oui1,oui2,oui3,subtype) = struct.unpack('BBBB', pos[0:4])
219     if oui1 != 0x50 or oui2 != 0x6f or oui3 != 0x9a or subtype != 9:
220         return None
221     pos = pos[4:]
222     (subtype,dialog_token) = struct.unpack('BB', pos[0:2])
223     p2p = {}
224     p2p['subtype'] = subtype
225     p2p['dialog_token'] = dialog_token
226     pos = pos[2:]
227     p2p['elements'] = pos
228     while len(pos) > 2:
229         (id,elen) = struct.unpack('BB', pos[0:2])
230         pos = pos[2:]
231         if elen > len(pos):
232             raise Exception("Truncated IE in P2P Public Action frame (elen=%d left=%d)" % (elen, len(pos)))
233         if id == WLAN_EID_VENDOR_SPECIFIC:
234             if elen < 4:
235                 raise Exception("Too short vendor specific IE in P2P Public Action frame (elen=%d)" % elen)
236             (oui1,oui2,oui3,subtype) = struct.unpack('BBBB', pos[0:4])
237             if oui1 == 0x50 and oui2 == 0x6f and oui3 == 0x9a and subtype == 9:
238                 if 'p2p' in p2p:
239                     p2p['p2p'] += pos[4:elen]
240                 else:
241                     p2p['p2p'] = pos[4:elen]
242             if oui1 == 0x00 and oui2 == 0x50 and oui3 == 0xf2 and subtype == 4:
243                 p2p['wsc'] = pos[4:elen]
244         pos = pos[elen:]
245     if len(pos) > 0:
246         raise Exception("Invalid element in P2P Public Action frame")
247
248     if 'p2p' in p2p:
249         p2p['p2p_attrs'] = {}
250         pos = p2p['p2p']
251         while len(pos) >= 3:
252             (id,alen) = struct.unpack('<BH', pos[0:3])
253             pos = pos[3:]
254             if alen > len(pos):
255                 logger.info("P2P payload: " + binascii.hexlify(p2p['p2p']))
256                 raise Exception("Truncated P2P attribute in P2P Public Action frame (alen=%d left=%d p2p-payload=%d)" % (alen, len(pos), len(p2p['p2p'])))
257             p2p['p2p_attrs'][id] = pos[0:alen]
258             pos = pos[alen:]
259         if P2P_ATTR_STATUS in p2p['p2p_attrs']:
260             p2p['p2p_status'] = struct.unpack('B', p2p['p2p_attrs'][P2P_ATTR_STATUS])[0]
261
262     if 'wsc' in p2p:
263         p2p['wsc_attrs'] = {}
264         pos = p2p['wsc']
265         while len(pos) >= 4:
266             (id,alen) = struct.unpack('>HH', pos[0:4])
267             pos = pos[4:]
268             if alen > len(pos):
269                 logger.info("WSC payload: " + binascii.hexlify(p2p['wsc']))
270                 raise Exception("Truncated WSC attribute in P2P Public Action frame (alen=%d left=%d wsc-payload=%d)" % (alen, len(pos), len(p2p['wsc'])))
271             p2p['wsc_attrs'][id] = pos[0:alen]
272             pos = pos[alen:]
273
274     return p2p
275
276 def test_p2p_msg_empty(dev, apdev):
277     """P2P protocol test: empty P2P Public Action frame"""
278     dst, src, hapd, channel = start_p2p(dev, apdev)
279     msg = p2p_hdr(dst, src)
280     hapd.mgmt_tx(msg)
281
282 def test_p2p_msg_invitation_req(dev, apdev):
283     """P2P protocol tests for invitation request processing"""
284     dst, src, hapd, channel = start_p2p(dev, apdev)
285
286     # Empty P2P Invitation Request (missing dialog token)
287     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=None)
288     hapd.mgmt_tx(msg)
289     dialog_token = 0
290
291     # Various p2p_parse() failure cases due to invalid attributes
292
293     # Too short attribute header
294     dialog_token += 1
295     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
296     attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
297     msg['payload'] += ie_p2p(attrs)
298     hapd.mgmt_tx(msg)
299
300     # Minimal attribute underflow
301     dialog_token += 1
302     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
303     attrs = struct.pack("<BH", P2P_ATTR_CAPABILITY, 1)
304     msg['payload'] += ie_p2p(attrs)
305     hapd.mgmt_tx(msg)
306
307     # Large attribute underflow
308     dialog_token += 1
309     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
310     attrs = struct.pack("<BHB", P2P_ATTR_CAPABILITY, 0xffff, 1)
311     msg['payload'] += ie_p2p(attrs)
312     hapd.mgmt_tx(msg)
313
314     # Too short Capability attribute
315     dialog_token += 1
316     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
317     attrs = struct.pack("<BHB", P2P_ATTR_CAPABILITY, 1, 0)
318     msg['payload'] += ie_p2p(attrs)
319     hapd.mgmt_tx(msg)
320
321     # Too short Device ID attribute
322     dialog_token += 1
323     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
324     val = struct.unpack('5B', binascii.unhexlify("1122334455"))
325     t = (P2P_ATTR_DEVICE_ID, 5) + val
326     attrs = struct.pack('<BH5B', *t)
327     msg['payload'] += ie_p2p(attrs)
328     hapd.mgmt_tx(msg)
329
330     # Too short GO Intent attribute
331     dialog_token += 1
332     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
333     attrs = struct.pack("<BH", P2P_ATTR_GROUP_OWNER_INTENT, 0)
334     msg['payload'] += ie_p2p(attrs)
335     hapd.mgmt_tx(msg)
336
337     # Too short Status attribute
338     dialog_token += 1
339     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
340     attrs = struct.pack("<BH", P2P_ATTR_STATUS, 0)
341     msg['payload'] += ie_p2p(attrs)
342     hapd.mgmt_tx(msg)
343
344     # null Listen channel and too short Listen Channel attribute
345     dialog_token += 1
346     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
347     attrs = struct.pack("<BH", P2P_ATTR_LISTEN_CHANNEL, 0)
348     attrs += struct.pack("<BHB", P2P_ATTR_LISTEN_CHANNEL, 1, 0)
349     msg['payload'] += ie_p2p(attrs)
350     hapd.mgmt_tx(msg)
351
352     # null Operating channel and too short Operating Channel attribute
353     dialog_token += 1
354     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
355     attrs = struct.pack("<BH", P2P_ATTR_OPERATING_CHANNEL, 0)
356     attrs += struct.pack("<BHB", P2P_ATTR_OPERATING_CHANNEL, 1, 0)
357     msg['payload'] += ie_p2p(attrs)
358     hapd.mgmt_tx(msg)
359
360     # Too short Channel List attribute
361     dialog_token += 1
362     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
363     attrs = struct.pack("<BHBB", P2P_ATTR_CHANNEL_LIST, 2, 1, 2)
364     msg['payload'] += ie_p2p(attrs)
365     hapd.mgmt_tx(msg)
366
367     # Too short Device Info attribute
368     dialog_token += 1
369     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
370     attrs = struct.pack("<BHBB", P2P_ATTR_DEVICE_INFO, 2, 1, 2)
371     msg['payload'] += ie_p2p(attrs)
372     hapd.mgmt_tx(msg)
373
374     # Truncated Secondary Device Types in Device Info attribute
375     dialog_token += 1
376     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
377     attrs = struct.pack("<BH6BH8BB", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1,
378                         0, 0, 0, 0, 0, 0,
379                         0,
380                         0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22,
381                         255)
382     msg['payload'] += ie_p2p(attrs)
383     hapd.mgmt_tx(msg)
384
385     # Missing Device Name 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("<BH6BH8BB8B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8,
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     msg['payload'] += ie_p2p(attrs)
395     hapd.mgmt_tx(msg)
396
397     # Invalid Device Name header in Device Info attribute
398     dialog_token += 1
399     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
400     attrs = struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4,
401                         0, 0, 0, 0, 0, 0,
402                         0,
403                         0, 0, 0, 0, 0, 0, 0, 0,
404                         1,
405                         1, 2, 3, 4, 5, 6, 7, 8,
406                         0x11, 0x12, 0, 0)
407     msg['payload'] += ie_p2p(attrs)
408     hapd.mgmt_tx(msg)
409
410     # Invalid Device Name header length in Device Info attribute
411     dialog_token += 1
412     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
413     attrs = struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4,
414                         0, 0, 0, 0, 0, 0,
415                         0,
416                         0, 0, 0, 0, 0, 0, 0, 0,
417                         1,
418                         1, 2, 3, 4, 5, 6, 7, 8,
419                         0x10, 0x11, 0xff, 0xff)
420     msg['payload'] += ie_p2p(attrs)
421     hapd.mgmt_tx(msg)
422
423     # Invalid Device Name header length in Device Info attribute
424     dialog_token += 1
425     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
426     devname = 'A'
427     attrs = struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4 + len(devname),
428                         0, 0, 0, 0, 0, 0,
429                         0,
430                         0, 0, 0, 0, 0, 0, 0, 0,
431                         1,
432                         1, 2, 3, 4, 5, 6, 7, 8,
433                         0x10, 0x11, 0, len(devname) + 1) + devname
434     msg['payload'] += ie_p2p(attrs)
435     hapd.mgmt_tx(msg)
436
437     # Device Name filtering and too long Device Name in Device Info attribute
438     dialog_token += 1
439     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
440     attrs = struct.pack("<BH6BH8BB8B4B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4 + 4,
441                         0, 0, 0, 0, 0, 0,
442                         0,
443                         0, 0, 0, 0, 0, 0, 0, 0,
444                         1,
445                         1, 2, 3, 4, 5, 6, 7, 8,
446                         0x10, 0x11, 0, 4,
447                         64, 9, 0, 64)
448     devname = '123456789012345678901234567890123'
449     attrs += struct.pack("<BH6BH8BB8B4B", P2P_ATTR_DEVICE_INFO, 6 + 2 + 8 + 1 + 8 + 4 + len(devname),
450                          0, 0, 0, 0, 0, 0,
451                          0,
452                          0, 0, 0, 0, 0, 0, 0, 0,
453                          1,
454                          1, 2, 3, 4, 5, 6, 7, 8,
455                          0x10, 0x11, 0, len(devname)) + devname
456     msg['payload'] += ie_p2p(attrs)
457     hapd.mgmt_tx(msg)
458
459     # Too short Configuration Timeout attribute
460     dialog_token += 1
461     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
462     attrs = struct.pack("<BHB", P2P_ATTR_CONFIGURATION_TIMEOUT, 1, 1)
463     msg['payload'] += ie_p2p(attrs)
464     hapd.mgmt_tx(msg)
465
466     # Too short Intended P2P Interface Address attribute
467     dialog_token += 1
468     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
469     attrs = struct.pack("<BHB", P2P_ATTR_INTENDED_INTERFACE_ADDR, 1, 1)
470     msg['payload'] += ie_p2p(attrs)
471     hapd.mgmt_tx(msg)
472
473     # Too short P2P Group BSSID attribute
474     dialog_token += 1
475     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
476     attrs = struct.pack("<BHB", P2P_ATTR_GROUP_BSSID, 1, 1)
477     msg['payload'] += ie_p2p(attrs)
478     hapd.mgmt_tx(msg)
479
480     # Too short P2P Group ID attribute
481     dialog_token += 1
482     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
483     attrs = struct.pack("<BHB", P2P_ATTR_GROUP_ID, 1, 1)
484     msg['payload'] += ie_p2p(attrs)
485     hapd.mgmt_tx(msg)
486
487     # Too long P2P Group ID attribute
488     dialog_token += 1
489     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
490     attrs = struct.pack("<BH6B", P2P_ATTR_GROUP_ID, 6 + 33, 0, 0, 0, 0, 0, 0) + "123456789012345678901234567890123"
491     msg['payload'] += ie_p2p(attrs)
492     hapd.mgmt_tx(msg)
493
494     # Too short Invitation Flags attribute
495     dialog_token += 1
496     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
497     attrs = struct.pack("<BH", P2P_ATTR_INVITATION_FLAGS, 0)
498     msg['payload'] += ie_p2p(attrs)
499     hapd.mgmt_tx(msg)
500
501     # Valid and too short Manageability attribute
502     dialog_token += 1
503     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
504     attrs = p2p_attr_manageability()
505     attrs += struct.pack("<BH", P2P_ATTR_MANAGEABILITY, 0)
506     msg['payload'] += ie_p2p(attrs)
507     hapd.mgmt_tx(msg)
508
509     # Too short NoA attribute
510     dialog_token += 1
511     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
512     attrs = struct.pack("<BHB", P2P_ATTR_NOTICE_OF_ABSENCE, 1, 1)
513     msg['payload'] += ie_p2p(attrs)
514     hapd.mgmt_tx(msg)
515
516     # Valid and too short Extended Listen Timing attributes
517     dialog_token += 1
518     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
519     attrs = p2p_attr_ext_listen_timing(period=100, interval=50)
520     attrs += struct.pack("<BHBBB", P2P_ATTR_EXT_LISTEN_TIMING, 3, 0, 0, 0)
521     msg['payload'] += ie_p2p(attrs)
522     hapd.mgmt_tx(msg)
523
524     # Valid and too short Minor Reason Code attributes
525     dialog_token += 1
526     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
527     attrs = p2p_attr_minor_reason_code(code=2)
528     attrs += struct.pack("<BH", P2P_ATTR_MINOR_REASON_CODE, 0)
529     msg['payload'] += ie_p2p(attrs)
530     hapd.mgmt_tx(msg)
531
532     # Unknown attribute and too short OOB GO Negotiation Channel attribute
533     dialog_token += 1
534     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
535     attrs = struct.pack("<BHB", 99, 1, 1)
536     attrs += struct.pack("<BHB", P2P_ATTR_OOB_GO_NEG_CHANNEL, 1, 1)
537     msg['payload'] += ie_p2p(attrs)
538     hapd.mgmt_tx(msg)
539
540     if hapd.mgmt_rx(timeout=0.5) is not None:
541         raise Exception("Unexpected management frame received")
542
543     dev[0].dump_monitor()
544     dialog_token += 1
545     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
546     attrs = p2p_attr_config_timeout()
547     attrs += p2p_attr_invitation_flags()
548     attrs += p2p_attr_operating_channel()
549     attrs += p2p_attr_group_bssid(src)
550     attrs += p2p_attr_channel_list()
551     attrs += p2p_attr_group_id(src, "DIRECT-foo")
552     attrs += p2p_attr_device_info(src, config_methods=0x0108)
553     msg['payload'] += ie_p2p(attrs)
554     hapd.mgmt_tx(msg)
555     ev = dev[0].wait_event(["P2P-DEVICE-FOUND"], timeout=5)
556     if ev is None:
557         raise Exception("Timeout on device found event")
558     ev = dev[0].wait_event(["P2P-INVITATION-RECEIVED"], timeout=5)
559     if ev is None:
560         raise Exception("Timeout on invitation event " + str(dialog_token))
561     if hapd.mgmt_rx(timeout=1) is None:
562         raise Exception("No invitation response " + str(dialog_token))
563
564     time.sleep(0.1)
565     dev[0].dump_monitor()
566     dialog_token += 1
567     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
568     attrs = p2p_attr_config_timeout()
569     attrs += p2p_attr_invitation_flags()
570     attrs += p2p_attr_operating_channel()
571     attrs += p2p_attr_group_bssid(src)
572     attrs += p2p_attr_channel_list()
573     attrs += p2p_attr_group_id(src, "DIRECT-foo")
574     attrs += p2p_attr_device_info(src, config_methods=0x0108)
575     msg['payload'] += ie_p2p(attrs)
576     hapd.mgmt_tx(msg)
577     ev = dev[0].wait_event(["P2P-INVITATION-RECEIVED"], timeout=5)
578     if ev is None:
579         raise Exception("Timeout on invitation event " + str(dialog_token))
580     if hapd.mgmt_rx(timeout=1) is None:
581         raise Exception("No invitation response " + str(dialog_token))
582
583     time.sleep(0.1)
584     dev[0].dump_monitor()
585     dialog_token += 1
586     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
587     #attrs = p2p_attr_config_timeout()
588     attrs = p2p_attr_invitation_flags()
589     attrs += p2p_attr_operating_channel()
590     attrs += p2p_attr_group_bssid(src)
591     attrs += p2p_attr_channel_list()
592     attrs += p2p_attr_group_id(src, "DIRECT-foo")
593     attrs += p2p_attr_device_info(src, config_methods=0x0108)
594     msg['payload'] += ie_p2p(attrs)
595     hapd.mgmt_tx(msg)
596     if hapd.mgmt_rx(timeout=1) is None:
597         raise Exception("No invitation response " + str(dialog_token))
598
599     time.sleep(0.1)
600     dev[0].dump_monitor()
601     dialog_token += 1
602     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
603     attrs = p2p_attr_config_timeout()
604     #attrs = p2p_attr_invitation_flags()
605     attrs += p2p_attr_operating_channel()
606     attrs += p2p_attr_group_bssid(src)
607     attrs += p2p_attr_channel_list()
608     attrs += p2p_attr_group_id(src, "DIRECT-foo")
609     attrs += p2p_attr_device_info(src, config_methods=0x0108)
610     msg['payload'] += ie_p2p(attrs)
611     hapd.mgmt_tx(msg)
612     if hapd.mgmt_rx(timeout=1) is None:
613         raise Exception("No invitation response " + str(dialog_token))
614
615     time.sleep(0.1)
616     dev[0].dump_monitor()
617     dialog_token += 1
618     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
619     attrs = p2p_attr_config_timeout()
620     attrs = p2p_attr_invitation_flags()
621     #attrs += p2p_attr_operating_channel()
622     attrs += p2p_attr_group_bssid(src)
623     attrs += p2p_attr_channel_list()
624     attrs += p2p_attr_group_id(src, "DIRECT-foo")
625     attrs += p2p_attr_device_info(src, config_methods=0x0108)
626     msg['payload'] += ie_p2p(attrs)
627     hapd.mgmt_tx(msg)
628     if hapd.mgmt_rx(timeout=1) is None:
629         raise Exception("No invitation response " + str(dialog_token))
630
631     time.sleep(0.1)
632     dev[0].dump_monitor()
633     dialog_token += 1
634     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
635     attrs = p2p_attr_config_timeout()
636     attrs = p2p_attr_invitation_flags()
637     attrs += p2p_attr_operating_channel()
638     #attrs += p2p_attr_group_bssid(src)
639     attrs += p2p_attr_channel_list()
640     attrs += p2p_attr_group_id(src, "DIRECT-foo")
641     attrs += p2p_attr_device_info(src, config_methods=0x0108)
642     msg['payload'] += ie_p2p(attrs)
643     hapd.mgmt_tx(msg)
644     if hapd.mgmt_rx(timeout=1) is None:
645         raise Exception("No invitation response " + str(dialog_token))
646
647     time.sleep(0.1)
648     dev[0].dump_monitor()
649     dialog_token += 1
650     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
651     attrs = p2p_attr_config_timeout()
652     attrs = p2p_attr_invitation_flags()
653     attrs += p2p_attr_operating_channel()
654     attrs += p2p_attr_group_bssid(src)
655     #attrs += p2p_attr_channel_list()
656     attrs += p2p_attr_group_id(src, "DIRECT-foo")
657     attrs += p2p_attr_device_info(src, config_methods=0x0108)
658     msg['payload'] += ie_p2p(attrs)
659     hapd.mgmt_tx(msg)
660     if hapd.mgmt_rx(timeout=1) is None:
661         raise Exception("No invitation response " + str(dialog_token))
662
663     time.sleep(0.1)
664     dev[0].dump_monitor()
665     dialog_token += 1
666     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
667     attrs = p2p_attr_config_timeout()
668     attrs = p2p_attr_invitation_flags()
669     attrs += p2p_attr_operating_channel()
670     attrs += p2p_attr_group_bssid(src)
671     attrs += p2p_attr_channel_list()
672     #attrs += p2p_attr_group_id(src, "DIRECT-foo")
673     attrs += p2p_attr_device_info(src, config_methods=0x0108)
674     msg['payload'] += ie_p2p(attrs)
675     hapd.mgmt_tx(msg)
676     if hapd.mgmt_rx(timeout=1) is None:
677         raise Exception("No invitation response " + str(dialog_token))
678
679     time.sleep(0.1)
680     dev[0].dump_monitor()
681     dialog_token += 1
682     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
683     attrs = p2p_attr_config_timeout()
684     attrs = p2p_attr_invitation_flags()
685     attrs += p2p_attr_operating_channel()
686     attrs += p2p_attr_group_bssid(src)
687     attrs += p2p_attr_channel_list()
688     attrs += p2p_attr_group_id(src, "DIRECT-foo")
689     #attrs += p2p_attr_device_info(src, config_methods=0x0108)
690     msg['payload'] += ie_p2p(attrs)
691     hapd.mgmt_tx(msg)
692     if hapd.mgmt_rx(timeout=1) is None:
693         raise Exception("No invitation response " + str(dialog_token))
694
695     time.sleep(0.1)
696     dev[0].dump_monitor()
697     dialog_token += 1
698     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
699     hapd.mgmt_tx(msg)
700     if hapd.mgmt_rx(timeout=1) is None:
701         raise Exception("No invitation response " + str(dialog_token))
702
703     # Unusable peer operating channel preference
704     time.sleep(0.1)
705     dev[0].dump_monitor()
706     dialog_token += 1
707     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
708     attrs = p2p_attr_config_timeout()
709     attrs = p2p_attr_invitation_flags()
710     attrs += p2p_attr_operating_channel(chan=15)
711     attrs += p2p_attr_group_bssid(src)
712     attrs += p2p_attr_channel_list()
713     attrs += p2p_attr_group_id(src, "DIRECT-foo")
714     attrs += p2p_attr_device_info(src, config_methods=0x0108)
715     msg['payload'] += ie_p2p(attrs)
716     hapd.mgmt_tx(msg)
717     if hapd.mgmt_rx(timeout=1) is None:
718         raise Exception("No invitation response " + str(dialog_token))
719
720 def test_p2p_msg_invitation_req_to_go(dev, apdev):
721     """P2P protocol tests for invitation request processing on GO device"""
722     res = form(dev[0], dev[1])
723     dev[0].dump_monitor()
724     dev[1].dump_monitor()
725     addr0 = dev[0].p2p_dev_addr()
726     addr1 = dev[1].p2p_dev_addr()
727     peer = dev[1].get_peer(addr0)
728     listen_freq = peer['listen_freq']
729
730     if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
731         raise Exception("Failed to enable external management frame handling")
732
733     networks = dev[0].list_networks()
734     if len(networks) != 1:
735         raise Exception("Unexpected number of networks")
736     if "[P2P-PERSISTENT]" not in networks[0]['flags']:
737         raise Exception("Not the persistent group data")
738     if "OK" not in dev[0].global_request("P2P_GROUP_ADD persistent=" + networks[0]['id'] + " freq=" + listen_freq):
739         raise Exception("Could not state GO")
740
741     dialog_token = 0
742
743     # Unusable peer operating channel preference
744     dialog_token += 1
745     msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_REQ,
746                   dialog_token=dialog_token)
747     attrs = p2p_attr_config_timeout()
748     attrs = p2p_attr_invitation_flags(bitmap=1)
749     attrs += p2p_attr_operating_channel(chan=15)
750     attrs += p2p_attr_channel_list()
751     attrs += p2p_attr_group_id(res['go_dev_addr'], res['ssid'])
752     attrs += p2p_attr_device_info(addr1, config_methods=0x0108)
753     msg['payload'] += ie_p2p(attrs)
754
755     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, peer['listen_freq'], binascii.hexlify(msg['payload'])))
756
757     rx_msg = dev[1].mgmt_rx()
758     if rx_msg is None:
759         raise Exception("MGMT-RX timeout")
760     p2p = parse_p2p_public_action(rx_msg['payload'])
761     if p2p is None:
762         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
763     if p2p['subtype'] != P2P_INVITATION_RESP:
764         raise Exception("Unexpected subtype %d" % p2p['subtype'])
765     if p2p['p2p_status'] != 0:
766         raise Exception("Unexpected status %d" % p2p['p2p_status'])
767
768     # Forced channel re-selection due to channel list
769     dialog_token += 1
770     msg = p2p_hdr(addr0, addr1, type=P2P_INVITATION_REQ,
771                   dialog_token=dialog_token)
772     attrs = p2p_attr_config_timeout()
773     attrs = p2p_attr_invitation_flags(bitmap=1)
774     attrs += struct.pack("<BH3BBBB", P2P_ATTR_CHANNEL_LIST, 6,
775                          0x58, 0x58, 0x04,
776                          81, 1, 3)
777     attrs += p2p_attr_group_id(res['go_dev_addr'], res['ssid'])
778     attrs += p2p_attr_device_info(addr1, config_methods=0x0108)
779     msg['payload'] += ie_p2p(attrs)
780
781     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, peer['listen_freq'], binascii.hexlify(msg['payload'])))
782
783     rx_msg = dev[1].mgmt_rx()
784     if rx_msg is None:
785         raise Exception("MGMT-RX timeout")
786     p2p = parse_p2p_public_action(rx_msg['payload'])
787     if p2p is None:
788         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
789     if p2p['subtype'] != P2P_INVITATION_RESP:
790         raise Exception("Unexpected subtype %d" % p2p['subtype'])
791     if p2p['p2p_status'] != 7:
792         raise Exception("Unexpected status %d" % p2p['p2p_status'])
793
794 def test_p2p_msg_invitation_req_unknown(dev, apdev):
795     """P2P protocol tests for invitation request from unknown peer"""
796     dst, src, hapd, channel = start_p2p(dev, apdev)
797     dialog_token = 0
798
799     dialog_token += 1
800     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
801     attrs = p2p_attr_config_timeout()
802     attrs += p2p_attr_invitation_flags()
803     attrs += p2p_attr_operating_channel()
804     attrs += p2p_attr_group_bssid(src)
805     attrs += p2p_attr_channel_list()
806     #attrs += p2p_attr_group_id(src, "DIRECT-foo")
807     #attrs += p2p_attr_device_info(src, config_methods=0x0108)
808     msg['payload'] += ie_p2p(attrs)
809     hapd.mgmt_tx(msg)
810     ev = dev[0].wait_event(["P2P-INVITATION-RECEIVED"], timeout=5)
811     if ev is None:
812         raise Exception("Timeout on invitation event " + str(dialog_token))
813     if hapd.mgmt_rx(timeout=1) is None:
814         raise Exception("No invitation response " + str(dialog_token))
815
816 def test_p2p_msg_invitation_no_common_channels(dev, apdev):
817     """P2P protocol tests for invitation request without common channels"""
818     dst, src, hapd, channel = start_p2p(dev, apdev)
819     dialog_token = 0
820
821     dialog_token += 1
822     msg = p2p_hdr(dst, src, type=P2P_INVITATION_REQ, dialog_token=dialog_token)
823     attrs = p2p_attr_config_timeout()
824     attrs += p2p_attr_invitation_flags()
825     attrs += p2p_attr_operating_channel()
826     attrs += p2p_attr_group_bssid(src)
827     attrs += struct.pack("<BH3BBB", P2P_ATTR_CHANNEL_LIST, 5,
828                          0x58, 0x58, 0x04,
829                          81, 0)
830     attrs += p2p_attr_group_id(src, "DIRECT-foo")
831     attrs += p2p_attr_device_info(src, config_methods=0x0108)
832     msg['payload'] += ie_p2p(attrs)
833     hapd.mgmt_tx(msg)
834     if hapd.mgmt_rx(timeout=1) is None:
835         raise Exception("No invitation response " + str(dialog_token))
836     ev = dev[0].wait_event(["P2P-INVITATION-RECEIVED"], timeout=0.1)
837     if ev is not None:
838         raise Exception("Unexpected invitation event")
839
840 def test_p2p_msg_invitation_resp(dev, apdev):
841     """P2P protocol tests for invitation response processing"""
842     form(dev[0], dev[1])
843     dev[0].dump_monitor()
844     dev[1].dump_monitor()
845
846     dst, src, hapd, channel = start_p2p(dev, apdev)
847
848     addr0 = dev[0].p2p_dev_addr()
849     addr1 = dev[1].p2p_dev_addr()
850     peer = dev[1].get_peer(addr0)
851
852     # P2P Invitation Response from unknown peer
853     msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=1)
854     hapd.mgmt_tx(msg)
855
856     # P2P Invitation Response from peer that is not in invitation
857     msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=2)
858     attrs = p2p_attr_status()
859     msg['payload'] += ie_p2p(attrs)
860     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, peer['listen_freq'], binascii.hexlify(msg['payload'])))
861     time.sleep(0.1)
862
863     if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
864         raise Exception("Failed to enable external management frame handling")
865
866     invite(dev[0], dev[1])
867     rx_msg = dev[1].mgmt_rx()
868     if rx_msg is None:
869         raise Exception("MGMT-RX timeout")
870     p2p = parse_p2p_public_action(rx_msg['payload'])
871     if p2p is None:
872         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
873     if p2p['subtype'] != P2P_INVITATION_REQ:
874         raise Exception("Unexpected subtype %d" % p2p['subtype'])
875
876     # Invalid attribute to cause p2p_parse() failure
877     msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
878     attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
879     msg['payload'] += ie_p2p(attrs)
880     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload'])))
881
882     invite(dev[0], dev[1])
883     rx_msg = dev[1].mgmt_rx()
884     if rx_msg is None:
885         raise Exception("MGMT-RX timeout")
886     p2p = parse_p2p_public_action(rx_msg['payload'])
887     if p2p is None:
888         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
889     if p2p['subtype'] != P2P_INVITATION_REQ:
890         raise Exception("Unexpected subtype %d" % p2p['subtype'])
891
892     # missing mandatory Status attribute
893     msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
894     attrs = p2p_attr_channel_list()
895     msg['payload'] += ie_p2p(attrs)
896     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload'])))
897
898     invite(dev[0], dev[1])
899     rx_msg = dev[1].mgmt_rx()
900     if rx_msg is None:
901         raise Exception("MGMT-RX timeout")
902     p2p = parse_p2p_public_action(rx_msg['payload'])
903     if p2p is None:
904         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
905     if p2p['subtype'] != P2P_INVITATION_REQ:
906         raise Exception("Unexpected subtype %d" % p2p['subtype'])
907
908     # no channel match (no common channel found at all)
909     msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
910     attrs = p2p_attr_status()
911     attrs += struct.pack("<BH3BBBB", P2P_ATTR_CHANNEL_LIST, 6,
912                          0x58, 0x58, 0x04,
913                          81, 1, 15)
914     msg['payload'] += ie_p2p(attrs)
915     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload'])))
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     # no channel match (no acceptable P2P channel)
928     msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
929     attrs = p2p_attr_status()
930     attrs += struct.pack("<BH3BBBB", P2P_ATTR_CHANNEL_LIST, 6,
931                          0x58, 0x58, 0x04,
932                          81, 1, 12)
933     msg['payload'] += ie_p2p(attrs)
934     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload'])))
935
936     invite(dev[0], dev[1])
937     rx_msg = dev[1].mgmt_rx()
938     if rx_msg is None:
939         raise Exception("MGMT-RX timeout")
940     p2p = parse_p2p_public_action(rx_msg['payload'])
941     if p2p is None:
942         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
943     if p2p['subtype'] != P2P_INVITATION_REQ:
944         raise Exception("Unexpected subtype %d" % p2p['subtype'])
945
946     # missing mandatory Channel List attribute (ignored as a workaround)
947     msg = p2p_hdr(dst, src, type=P2P_INVITATION_RESP, dialog_token=p2p['dialog_token'])
948     attrs = p2p_attr_status()
949     msg['payload'] += ie_p2p(attrs)
950     mgmt_tx(dev[1], "MGMT_TX {} {} freq={} wait_time=50 no_cck=1 action={}".format(addr0, addr0, rx_msg['freq'], binascii.hexlify(msg['payload'])))
951
952     ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=15);
953     if ev is None:
954         raise Exception("Group was not started")
955
956 def test_p2p_msg_pd_req(dev, apdev):
957     """P2P protocol tests for provision discovery request processing"""
958     dst, src, hapd, channel = start_p2p(dev, apdev)
959     dialog_token = 0
960
961     # Too short attribute header
962     dialog_token += 1
963     msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
964     attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
965     msg['payload'] += ie_p2p(attrs)
966     hapd.mgmt_tx(msg)
967
968     if hapd.mgmt_rx(timeout=0.5) is not None:
969         raise Exception("Unexpected management frame received")
970
971     # No attributes
972     dialog_token += 1
973     msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
974     attrs = ""
975     msg['payload'] += ie_p2p(attrs)
976     hapd.mgmt_tx(msg)
977     if hapd.mgmt_rx(timeout=1) is None:
978         raise Exception("No PD response " + str(dialog_token))
979
980     # Valid request
981     time.sleep(0.1)
982     dialog_token += 1
983     msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
984     attrs = wsc_attr_config_methods(methods=0x1008)
985     msg['payload'] += ie_wsc(attrs)
986     attrs = p2p_attr_capability()
987     attrs += p2p_attr_device_info(src, config_methods=0x0108)
988     msg['payload'] += ie_p2p(attrs)
989     hapd.mgmt_tx(msg)
990     ev = dev[0].wait_event(["P2P-DEVICE-FOUND"], timeout=5)
991     if ev is None:
992         raise Exception("Timeout on device found event")
993     ev = dev[0].wait_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=5)
994     if ev is None:
995         raise Exception("Timeout on PD event")
996     if hapd.mgmt_rx(timeout=1) is None:
997         raise Exception("No PD response " + str(dialog_token))
998
999     # Unknown group
1000     time.sleep(0.1)
1001     dialog_token += 1
1002     msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
1003     attrs = wsc_attr_config_methods(methods=0x1008)
1004     msg['payload'] += ie_wsc(attrs)
1005     attrs = p2p_attr_capability()
1006     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1007     attrs += p2p_attr_group_id("02:02:02:02:02:02", "DIRECT-foo")
1008     msg['payload'] += ie_p2p(attrs)
1009     hapd.mgmt_tx(msg)
1010     if hapd.mgmt_rx(timeout=1) is None:
1011         raise Exception("No PD response " + str(dialog_token))
1012     ev = dev[0].wait_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=1)
1013     if ev is not None:
1014         raise Exception("Unexpected PD event")
1015
1016     # Listen channel is not yet known
1017     if "FAIL" not in dev[0].global_request("P2P_PROV_DISC " + src + " display"):
1018         raise Exception("Unexpected P2P_PROV_DISC success")
1019
1020     # Unknown peer
1021     if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 02:03:04:05:06:07 display"):
1022         raise Exception("Unexpected P2P_PROV_DISC success (2)")
1023
1024 def test_p2p_msg_pd(dev, apdev):
1025     """P2P protocol tests for provision discovery request processing (known)"""
1026     dst, src, hapd, channel = start_p2p(dev, apdev)
1027     dialog_token = 0
1028
1029     p2p_probe(hapd, src, chan=channel)
1030     time.sleep(0.1)
1031
1032     # Valid request
1033     dialog_token += 1
1034     msg = p2p_hdr(dst, src, type=P2P_PROV_DISC_REQ, dialog_token=dialog_token)
1035     attrs = wsc_attr_config_methods(methods=0x1008)
1036     msg['payload'] += ie_wsc(attrs)
1037     attrs = p2p_attr_capability()
1038     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1039     msg['payload'] += ie_p2p(attrs)
1040     hapd.mgmt_tx(msg)
1041     ev = dev[0].wait_event(["P2P-DEVICE-FOUND"], timeout=5)
1042     if ev is None:
1043         raise Exception("Timeout on device found event")
1044     ev = dev[0].wait_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=5)
1045     if ev is None:
1046         raise Exception("Timeout on PD event")
1047     if hapd.mgmt_rx(timeout=1) is None:
1048         raise Exception("No PD response " + str(dialog_token))
1049
1050     if "FAIL" in dev[0].global_request("P2P_PROV_DISC " + src + " display"):
1051         raise Exception("Unexpected P2P_PROV_DISC failure")
1052     frame = hapd.mgmt_rx(timeout=1)
1053     if frame is None:
1054         raise Exception("No PD request " + str(dialog_token))
1055     p2p = parse_p2p_public_action(frame['payload'])
1056     if p2p is None:
1057         raise Exception("Failed to parse PD request")
1058
1059     # invalid dialog token
1060     msg = p2p_hdr_resp(dst, src, type=P2P_PROV_DISC_RESP,
1061                        dialog_token=p2p['dialog_token'] + 1)
1062     hapd.mgmt_tx(msg)
1063     ev = dev[0].wait_event(["P2P-PROV-DISC-FAILURE"], timeout=0.1)
1064     if ev is not None:
1065         raise Exception("Unexpected PD result event")
1066
1067     # valid dialog token
1068     msg = p2p_hdr_resp(dst, src, type=P2P_PROV_DISC_RESP,
1069                        dialog_token=p2p['dialog_token'])
1070     hapd.mgmt_tx(msg)
1071     ev = dev[0].wait_event(["P2P-PROV-DISC-FAILURE"], timeout=5)
1072     if ev is None:
1073         raise Exception("Timeout on PD result event")
1074
1075     # valid dialog token
1076     msg = p2p_hdr_resp(dst, src, type=P2P_PROV_DISC_RESP,
1077                        dialog_token=p2p['dialog_token'])
1078     hapd.mgmt_tx(msg)
1079     ev = dev[0].wait_event(["P2P-PROV-DISC-FAILURE"], timeout=0.1)
1080     if ev is not None:
1081         raise Exception("Unexpected PD result event")
1082
1083 def check_p2p_response(hapd, dialog_token, status):
1084     resp = hapd.mgmt_rx(timeout=1)
1085     if resp is None:
1086         raise Exception("No GO Neg Response " + str(dialog_token))
1087     p2p = parse_p2p_public_action(resp['payload'])
1088     if p2p is None:
1089         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1090     if dialog_token != p2p['dialog_token']:
1091         raise Exception("Unexpected dialog token in response")
1092     if p2p['p2p_status'] != status:
1093         raise Exception("Unexpected status code %s in response (expected %d)" % (p2p['p2p_status'], status))
1094
1095 def test_p2p_msg_go_neg_both_start(dev, apdev):
1096     """P2P protocol test for simultaneous GO Neg initiation"""
1097     addr0 = dev[0].p2p_dev_addr()
1098     addr1 = dev[1].p2p_dev_addr()
1099     dev[0].p2p_listen()
1100     dev[1].discover_peer(addr0)
1101     dev[1].p2p_listen()
1102     dev[0].discover_peer(addr1)
1103     dev[0].p2p_listen()
1104     if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 1"):
1105         raise Exception("Failed to enable external management frame handling")
1106     if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 1"):
1107         raise Exception("Failed to enable external management frame handling")
1108     dev[0].request("P2P_CONNECT {} pbc".format(addr1))
1109     dev[1].request("P2P_CONNECT {} pbc".format(addr0))
1110     msg = dev[0].mgmt_rx()
1111     if msg is None:
1112         raise Exception("MGMT-RX timeout")
1113     msg = dev[1].mgmt_rx()
1114     if msg is None:
1115         raise Exception("MGMT-RX timeout(2)")
1116     if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 0"):
1117         raise Exception("Failed to disable external management frame handling")
1118     ev = dev[0].wait_global_event(["P2P-GO-NEG-SUCCESS"], timeout=2)
1119     if ev is not None:
1120         raise Exception("Unexpected GO Neg success")
1121     if "FAIL" in dev[1].request("SET ext_mgmt_frame_handling 0"):
1122         raise Exception("Failed to disable external management frame handling")
1123     ev = dev[0].wait_global_event(["P2P-GO-NEG-SUCCESS"], timeout=10)
1124     if ev is None:
1125         raise Exception("GO Neg did not succeed")
1126     ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=5);
1127     if ev is None:
1128         raise Exception("Group formation not succeed")
1129     ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=5);
1130     if ev is None:
1131         raise Exception("Group formation not succeed")
1132
1133 def test_p2p_msg_go_neg_req(dev, apdev):
1134     """P2P protocol tests for invitation request from unknown peer"""
1135     dst, src, hapd, channel = start_p2p(dev, apdev)
1136     dialog_token = 0
1137
1138     # invalid attribute
1139     dialog_token += 1
1140     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1141     attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
1142     msg['payload'] += ie_p2p(attrs)
1143     hapd.mgmt_tx(msg)
1144     frame = hapd.mgmt_rx(timeout=0.1)
1145     if frame is not None:
1146         print frame
1147         raise Exception("Unexpected GO Neg Response")
1148
1149     # missing atributes
1150     dialog_token += 1
1151     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1152     attrs = p2p_attr_capability()
1153     attrs += p2p_attr_go_intent()
1154     attrs += p2p_attr_config_timeout()
1155     #attrs += p2p_attr_listen_channel()
1156     attrs += p2p_attr_ext_listen_timing()
1157     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1158     attrs += p2p_attr_channel_list()
1159     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1160     attrs += p2p_attr_operating_channel()
1161     msg['payload'] += ie_p2p(attrs)
1162     hapd.mgmt_tx(msg)
1163     if hapd.mgmt_rx(timeout=1) is None:
1164         raise Exception("No GO Neg Response " + str(dialog_token))
1165     time.sleep(0.1)
1166
1167     dialog_token += 1
1168     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1169     attrs = p2p_attr_capability()
1170     attrs += p2p_attr_go_intent()
1171     attrs += p2p_attr_config_timeout()
1172     attrs += p2p_attr_listen_channel()
1173     attrs += p2p_attr_ext_listen_timing()
1174     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1175     attrs += p2p_attr_channel_list()
1176     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1177     #attrs += p2p_attr_operating_channel()
1178     msg['payload'] += ie_p2p(attrs)
1179     hapd.mgmt_tx(msg)
1180     if hapd.mgmt_rx(timeout=1) is None:
1181         raise Exception("No GO Neg Response " + str(dialog_token))
1182     time.sleep(0.1)
1183
1184     dialog_token += 1
1185     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1186     attrs = p2p_attr_capability()
1187     attrs += p2p_attr_go_intent()
1188     attrs += p2p_attr_config_timeout()
1189     attrs += p2p_attr_listen_channel()
1190     attrs += p2p_attr_ext_listen_timing()
1191     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1192     #attrs += p2p_attr_channel_list()
1193     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1194     attrs += p2p_attr_operating_channel()
1195     msg['payload'] += ie_p2p(attrs)
1196     hapd.mgmt_tx(msg)
1197     if hapd.mgmt_rx(timeout=1) is None:
1198         raise Exception("No GO Neg Response " + str(dialog_token))
1199     time.sleep(0.1)
1200
1201     dialog_token += 1
1202     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1203     attrs = p2p_attr_capability()
1204     attrs += p2p_attr_go_intent()
1205     attrs += p2p_attr_config_timeout()
1206     attrs += p2p_attr_listen_channel()
1207     attrs += p2p_attr_ext_listen_timing()
1208     #attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1209     attrs += p2p_attr_channel_list()
1210     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1211     attrs += p2p_attr_operating_channel()
1212     msg['payload'] += ie_p2p(attrs)
1213     hapd.mgmt_tx(msg)
1214     if hapd.mgmt_rx(timeout=1) is None:
1215         raise Exception("No GO Neg Response " + str(dialog_token))
1216     time.sleep(0.1)
1217
1218     dialog_token += 1
1219     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1220     attrs = p2p_attr_capability()
1221     attrs += p2p_attr_go_intent()
1222     attrs += p2p_attr_config_timeout()
1223     attrs += p2p_attr_listen_channel()
1224     attrs += p2p_attr_ext_listen_timing()
1225     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1226     attrs += p2p_attr_channel_list()
1227     #attrs += p2p_attr_device_info(src, config_methods=0x0108)
1228     attrs += p2p_attr_operating_channel()
1229     msg['payload'] += ie_p2p(attrs)
1230     hapd.mgmt_tx(msg)
1231     if hapd.mgmt_rx(timeout=1) is None:
1232         raise Exception("No GO Neg Response " + str(dialog_token))
1233     time.sleep(0.1)
1234
1235     # SA != P2P Device address
1236     dialog_token += 1
1237     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1238     attrs = p2p_attr_capability()
1239     attrs += p2p_attr_go_intent()
1240     attrs += p2p_attr_config_timeout()
1241     attrs += p2p_attr_listen_channel()
1242     attrs += p2p_attr_ext_listen_timing()
1243     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1244     attrs += p2p_attr_channel_list()
1245     attrs += p2p_attr_device_info("02:02:02:02:02:02", config_methods=0x0108)
1246     attrs += p2p_attr_operating_channel()
1247     msg['payload'] += ie_p2p(attrs)
1248     hapd.mgmt_tx(msg)
1249     if hapd.mgmt_rx(timeout=1) is None:
1250         raise Exception("No GO Neg Response " + str(dialog_token))
1251     time.sleep(0.1)
1252
1253     # unexpected Status attribute
1254     dialog_token += 1
1255     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1256     attrs = p2p_attr_capability()
1257     attrs += p2p_attr_go_intent()
1258     attrs += p2p_attr_config_timeout()
1259     attrs += p2p_attr_listen_channel()
1260     attrs += p2p_attr_ext_listen_timing()
1261     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1262     attrs += p2p_attr_channel_list()
1263     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1264     attrs += p2p_attr_operating_channel()
1265     attrs += p2p_attr_status(status=P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
1266     msg['payload'] += ie_p2p(attrs)
1267     hapd.mgmt_tx(msg)
1268     if hapd.mgmt_rx(timeout=1) is None:
1269         raise Exception("No GO Neg Response(1) " + str(dialog_token))
1270     time.sleep(0.1)
1271
1272     # valid (with workarounds) GO Neg Req
1273     dialog_token += 1
1274     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1275     #attrs = p2p_attr_capability()
1276     #attrs += p2p_attr_go_intent()
1277     #attrs += p2p_attr_config_timeout()
1278     attrs = p2p_attr_listen_channel()
1279     attrs += p2p_attr_ext_listen_timing()
1280     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1281     attrs += p2p_attr_channel_list()
1282     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1283     attrs += p2p_attr_operating_channel()
1284     msg['payload'] += ie_p2p(attrs)
1285     hapd.mgmt_tx(msg)
1286     check_p2p_response(hapd, dialog_token,
1287                        P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
1288     ev = dev[0].wait_event(["P2P-GO-NEG-REQUEST"], timeout=1)
1289     if ev is None:
1290         raise Exception("Timeout on GO Neg event " + str(dialog_token))
1291
1292     dev[0].request("P2P_CONNECT " + src + " 12345670 display auth")
1293
1294     # ready - missing attributes (with workarounds) GO Neg Req
1295     time.sleep(0.1)
1296     dialog_token += 1
1297     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1298     #attrs = p2p_attr_capability()
1299     #attrs += p2p_attr_go_intent()
1300     #attrs += p2p_attr_config_timeout()
1301     attrs = p2p_attr_listen_channel()
1302     attrs += p2p_attr_ext_listen_timing()
1303     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1304     attrs += p2p_attr_channel_list()
1305     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1306     attrs += p2p_attr_operating_channel()
1307     msg['payload'] += ie_p2p(attrs)
1308     hapd.mgmt_tx(msg)
1309     if hapd.mgmt_rx(timeout=1) is None:
1310         raise Exception("No GO Neg Response " + str(dialog_token))
1311
1312     # ready - invalid GO Intent GO Neg Req
1313     time.sleep(0.1)
1314     dialog_token += 1
1315     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1316     #attrs = p2p_attr_capability()
1317     attrs = p2p_attr_go_intent(go_intent=16)
1318     #attrs += p2p_attr_config_timeout()
1319     attrs += p2p_attr_listen_channel()
1320     attrs += p2p_attr_ext_listen_timing()
1321     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1322     attrs += p2p_attr_channel_list()
1323     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1324     attrs += p2p_attr_operating_channel()
1325     msg['payload'] += ie_p2p(attrs)
1326     hapd.mgmt_tx(msg)
1327     check_p2p_response(hapd, dialog_token, P2P_SC_FAIL_INVALID_PARAMS)
1328
1329     # ready - invalid Channel List
1330     time.sleep(0.1)
1331     dialog_token += 1
1332     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1333     attrs = p2p_attr_capability()
1334     attrs += p2p_attr_go_intent()
1335     attrs += p2p_attr_config_timeout()
1336     attrs += p2p_attr_listen_channel()
1337     attrs += p2p_attr_ext_listen_timing()
1338     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1339     attrs += struct.pack("<BH3BBB11B", P2P_ATTR_CHANNEL_LIST, 16,
1340                          0x58, 0x58, 0x04,
1341                          81, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
1342     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1343     attrs += p2p_attr_operating_channel()
1344     msg['payload'] += ie_p2p(attrs)
1345     hapd.mgmt_tx(msg)
1346     check_p2p_response(hapd, dialog_token, P2P_SC_FAIL_NO_COMMON_CHANNELS)
1347
1348     # ready - invalid GO Neg Req (unsupported Device Password ID)
1349     time.sleep(0.1)
1350     dialog_token += 1
1351     msg = p2p_hdr(dst, src, type=P2P_GO_NEG_REQ, dialog_token=dialog_token)
1352     attrs = p2p_attr_capability()
1353     attrs += p2p_attr_go_intent()
1354     attrs += p2p_attr_config_timeout()
1355     attrs += p2p_attr_listen_channel()
1356     attrs += p2p_attr_ext_listen_timing()
1357     attrs += p2p_attr_intended_interface_addr("02:02:02:02:02:02")
1358     # very long channel list
1359     attrs += struct.pack("<BH3BBB11B30B", P2P_ATTR_CHANNEL_LIST, 46,
1360                          0x58, 0x58, 0x04,
1361                          81, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
1362                          1, 1, 1, 2, 1, 2, 3, 1, 3, 4, 1, 4, 5, 1, 5,
1363                          6, 1, 6, 7, 1, 7, 8, 1, 8, 9, 1, 9, 10, 1, 10)
1364     attrs += p2p_attr_device_info(src, config_methods=0x0108)
1365     attrs += p2p_attr_operating_channel()
1366     msg['payload'] += ie_p2p(attrs)
1367     hapd.mgmt_tx(msg)
1368     check_p2p_response(hapd, dialog_token, P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD)
1369
1370 def mgmt_tx(dev, msg):
1371     for i in range(0, 20):
1372         if "FAIL" in dev.request(msg):
1373             raise Exception("Failed to send Action frame")
1374         ev = dev.wait_event(["MGMT-TX-STATUS"], timeout=10)
1375         if ev is None:
1376             raise Exception("Timeout on MGMT-TX-STATUS")
1377         if "result=SUCCESS" in ev:
1378             break
1379         time.sleep(0.01)
1380     if "result=SUCCESS" not in ev:
1381         raise Exception("Peer did not ack Action frame")
1382
1383 def rx_go_neg_req(dev):
1384     msg = dev.mgmt_rx()
1385     if msg is None:
1386         raise Exception("MGMT-RX timeout")
1387     p2p = parse_p2p_public_action(msg['payload'])
1388     if p2p is None:
1389         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1390     if p2p['subtype'] != P2P_GO_NEG_REQ:
1391         raise Exception("Unexpected subtype %d" % p2p['subtype'])
1392     p2p['freq'] = msg['freq']
1393     return p2p
1394
1395 def rx_go_neg_conf(dev, status=None, dialog_token=None):
1396     msg = dev.mgmt_rx()
1397     if msg is None:
1398         raise Exception("MGMT-RX timeout")
1399     p2p = parse_p2p_public_action(msg['payload'])
1400     if p2p is None:
1401         raise Exception("Not a P2P Public Action frame " + str(dialog_token))
1402     if p2p['subtype'] != P2P_GO_NEG_CONF:
1403         raise Exception("Unexpected subtype %d" % p2p['subtype'])
1404     if dialog_token is not None and dialog_token != p2p['dialog_token']:
1405         raise Exception("Unexpected dialog token")
1406     if status is not None and p2p['p2p_status'] != status:
1407         raise Exception("Unexpected status %d" % p2p['p2p_status'])
1408
1409 def check_p2p_go_neg_fail_event(dev, status):
1410     ev = dev.wait_global_event(["P2P-GO-NEG-FAILURE"], timeout=5)
1411     if ev is None:
1412         raise Exception("GO Negotiation failure not reported")
1413     if "status=%d" % status not in ev:
1414         raise Exception("Unexpected failure reason: " + ev)
1415
1416 def test_p2p_msg_go_neg_req_reject(dev, apdev):
1417     """P2P protocol tests for user reject incorrectly in GO Neg Req"""
1418     addr0 = dev[0].p2p_dev_addr()
1419     addr1 = dev[1].p2p_dev_addr()
1420     dev[0].p2p_listen()
1421     dev[1].discover_peer(addr0)
1422     dev[1].group_request("P2P_CONNECT " + addr0 + " pbc")
1423     ev = dev[0].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=10)
1424     if ev is None:
1425         raise Exception("Timeout on GO Neg Req")
1426
1427     peer = dev[0].get_peer(addr1)
1428     dev[0].p2p_stop_find()
1429
1430     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_REQ, dialog_token=123)
1431     attrs = p2p_attr_capability()
1432     attrs += p2p_attr_status(status=P2P_SC_FAIL_REJECTED_BY_USER)
1433     attrs += p2p_attr_go_intent()
1434     attrs += p2p_attr_config_timeout()
1435     attrs += p2p_attr_listen_channel()
1436     attrs += p2p_attr_ext_listen_timing()
1437     attrs += p2p_attr_intended_interface_addr(addr0)
1438     attrs += p2p_attr_channel_list()
1439     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1440     attrs += p2p_attr_operating_channel()
1441     msg['payload'] += ie_p2p(attrs)
1442
1443     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload'])))
1444
1445     ev = dev[1].wait_global_event(["P2P-GO-NEG-FAILURE"], timeout=5)
1446     if ev is None:
1447         raise Exception("GO Negotiation failure not reported")
1448     if "status=%d" % P2P_SC_FAIL_REJECTED_BY_USER not in ev:
1449         raise Exception("Unexpected failure reason: " + ev)
1450
1451 def test_p2p_msg_unexpected_go_neg_resp(dev, apdev):
1452     """P2P protocol tests for unexpected GO Neg Resp"""
1453     addr0 = dev[0].p2p_dev_addr()
1454     addr1 = dev[1].p2p_dev_addr()
1455     dev[1].p2p_listen()
1456     dev[0].discover_peer(addr1)
1457     dev[0].p2p_stop_find()
1458
1459     peer = dev[0].get_peer(addr1)
1460
1461     logger.debug("GO Neg Resp without GO Neg session")
1462     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=123)
1463     attrs = p2p_attr_status()
1464     attrs += p2p_attr_capability()
1465     attrs += p2p_attr_go_intent()
1466     attrs += p2p_attr_config_timeout()
1467     attrs += p2p_attr_intended_interface_addr(addr0)
1468     attrs += p2p_attr_channel_list()
1469     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1470     attrs += p2p_attr_operating_channel()
1471     msg['payload'] += ie_p2p(attrs)
1472     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload'])))
1473
1474     dev[0].p2p_listen()
1475     dev[1].discover_peer(addr0)
1476
1477     logger.debug("Unexpected GO Neg Resp while waiting for new GO Neg session")
1478     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1479         raise Exception("P2P_CONNECT failed")
1480     ev = dev[0].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=10)
1481     if ev is None:
1482         raise Exception("Timeout on GO Neg Req")
1483     dev[0].p2p_stop_find()
1484     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload'])))
1485
1486     logger.debug("Invalid attribute in GO Neg Response")
1487     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=197)
1488     attrs = struct.pack("<BB", P2P_ATTR_CAPABILITY, 0)
1489     msg['payload'] += ie_p2p(attrs)
1490     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=10 no_cck=1 action={}".format(addr1, addr1, peer['listen_freq'], binascii.hexlify(msg['payload'])))
1491     frame = dev[0].mgmt_rx(timeout=0.1)
1492     if frame is not None:
1493         raise Exception("Unexpected GO Neg Confirm")
1494
1495     logger.debug("GO Neg Resp with unexpected dialog token")
1496     dev[1].p2p_stop_find()
1497     if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 1"):
1498         raise Exception("Failed to enable external management frame handling")
1499     dev[0].p2p_listen()
1500     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1501         raise Exception("P2P_CONNECT failed(2)")
1502     p2p = rx_go_neg_req(dev[0])
1503     dev[0].p2p_stop_find()
1504     dialog_token = p2p['dialog_token']
1505     if dialog_token < 255:
1506         dialog_token += 1
1507     else:
1508         dialog_token = 1
1509     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1510     attrs = p2p_attr_status()
1511     attrs += p2p_attr_capability()
1512     attrs += p2p_attr_go_intent()
1513     attrs += p2p_attr_config_timeout()
1514     attrs += p2p_attr_intended_interface_addr(addr0)
1515     attrs += p2p_attr_channel_list()
1516     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1517     attrs += p2p_attr_operating_channel()
1518     msg['payload'] += ie_p2p(attrs)
1519     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1520
1521     logger.debug("GO Neg Resp without Status")
1522     dev[1].p2p_stop_find()
1523     dev[0].p2p_listen()
1524     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1525         raise Exception("P2P_CONNECT failed(2)")
1526     p2p = rx_go_neg_req(dev[0])
1527     dev[0].p2p_stop_find()
1528     dialog_token = p2p['dialog_token']
1529     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1530     #attrs = p2p_attr_status()
1531     attrs = p2p_attr_capability()
1532     attrs += p2p_attr_go_intent()
1533     attrs += p2p_attr_config_timeout()
1534     attrs += p2p_attr_intended_interface_addr(addr0)
1535     attrs += p2p_attr_channel_list()
1536     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1537     attrs += p2p_attr_operating_channel()
1538     msg['payload'] += ie_p2p(attrs)
1539     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1540     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1541     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1542
1543     logger.debug("GO Neg Resp without Intended Address")
1544     dev[1].p2p_stop_find()
1545     dev[0].p2p_listen()
1546     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1547         raise Exception("P2P_CONNECT failed(2)")
1548     p2p = rx_go_neg_req(dev[0])
1549     dev[0].p2p_stop_find()
1550     dialog_token = p2p['dialog_token']
1551     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1552     attrs = p2p_attr_status()
1553     #attrs += p2p_attr_capability()
1554     attrs += p2p_attr_go_intent()
1555     attrs += p2p_attr_config_timeout()
1556     #attrs += p2p_attr_intended_interface_addr(addr0)
1557     attrs += p2p_attr_channel_list()
1558     #attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1559     attrs += p2p_attr_operating_channel()
1560     msg['payload'] += ie_p2p(attrs)
1561     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1562     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1563     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1564
1565     logger.debug("GO Neg Resp without GO Intent")
1566     dev[1].p2p_stop_find()
1567     dev[0].p2p_listen()
1568     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1569         raise Exception("P2P_CONNECT failed(2)")
1570     p2p = rx_go_neg_req(dev[0])
1571     dev[0].p2p_stop_find()
1572     dialog_token = p2p['dialog_token']
1573     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1574     attrs = p2p_attr_status()
1575     attrs += p2p_attr_capability()
1576     #attrs += p2p_attr_go_intent()
1577     attrs += p2p_attr_config_timeout()
1578     attrs += p2p_attr_intended_interface_addr(addr0)
1579     attrs += p2p_attr_channel_list()
1580     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1581     attrs += p2p_attr_operating_channel()
1582     msg['payload'] += ie_p2p(attrs)
1583     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1584     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1585     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1586
1587     logger.debug("GO Neg Resp with invalid GO Intent")
1588     dev[1].p2p_stop_find()
1589     dev[0].p2p_listen()
1590     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc"):
1591         raise Exception("P2P_CONNECT failed(2)")
1592     p2p = rx_go_neg_req(dev[0])
1593     dev[0].p2p_stop_find()
1594     dialog_token = p2p['dialog_token']
1595     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1596     attrs = p2p_attr_status()
1597     attrs += p2p_attr_capability()
1598     attrs += p2p_attr_go_intent(go_intent=16)
1599     attrs += p2p_attr_config_timeout()
1600     attrs += p2p_attr_intended_interface_addr(addr0)
1601     attrs += p2p_attr_channel_list()
1602     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1603     attrs += p2p_attr_operating_channel()
1604     msg['payload'] += ie_p2p(attrs)
1605     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1606     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1607     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1608
1609     logger.debug("GO Neg Resp with incompatible GO Intent")
1610     dev[1].p2p_stop_find()
1611     dev[0].p2p_listen()
1612     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=15"):
1613         raise Exception("P2P_CONNECT failed(2)")
1614     p2p = rx_go_neg_req(dev[0])
1615     dev[0].p2p_stop_find()
1616     dialog_token = p2p['dialog_token']
1617     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1618     attrs = p2p_attr_status()
1619     attrs += p2p_attr_capability()
1620     attrs += p2p_attr_go_intent(go_intent=15)
1621     attrs += p2p_attr_config_timeout()
1622     attrs += p2p_attr_intended_interface_addr(addr0)
1623     attrs += p2p_attr_channel_list()
1624     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1625     attrs += p2p_attr_operating_channel()
1626     msg['payload'] += ie_p2p(attrs)
1627     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1628     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INCOMPATIBLE_PARAMS)
1629     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INCOMPATIBLE_PARAMS, dialog_token)
1630
1631     logger.debug("GO Neg Resp without P2P Group ID")
1632     dev[1].p2p_stop_find()
1633     dev[0].p2p_listen()
1634     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1635         raise Exception("P2P_CONNECT failed(2)")
1636     p2p = rx_go_neg_req(dev[0])
1637     dev[0].p2p_stop_find()
1638     dialog_token = p2p['dialog_token']
1639     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1640     attrs = p2p_attr_status()
1641     attrs += p2p_attr_capability()
1642     attrs += p2p_attr_go_intent(go_intent=15)
1643     attrs += p2p_attr_config_timeout()
1644     attrs += p2p_attr_intended_interface_addr(addr0)
1645     attrs += p2p_attr_channel_list()
1646     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1647     attrs += p2p_attr_operating_channel()
1648     #attrs += p2p_attr_group_id(src, "DIRECT-foo")
1649     msg['payload'] += ie_p2p(attrs)
1650     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1651     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1652     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1653
1654     logger.debug("GO Neg Resp without Operating Channel")
1655     dev[1].p2p_stop_find()
1656     dev[0].p2p_listen()
1657     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1658         raise Exception("P2P_CONNECT failed(2)")
1659     p2p = rx_go_neg_req(dev[0])
1660     dev[0].p2p_stop_find()
1661     dialog_token = p2p['dialog_token']
1662     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1663     attrs = p2p_attr_status()
1664     attrs += p2p_attr_capability()
1665     attrs += p2p_attr_go_intent(go_intent=15)
1666     #attrs += p2p_attr_config_timeout()
1667     attrs += p2p_attr_intended_interface_addr(addr0)
1668     attrs += p2p_attr_channel_list()
1669     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1670     #attrs += p2p_attr_operating_channel()
1671     attrs += p2p_attr_group_id(addr0, "DIRECT-foo")
1672     msg['payload'] += ie_p2p(attrs)
1673     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1674     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1675     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1676
1677     logger.debug("GO Neg Resp without Channel List")
1678     dev[1].p2p_stop_find()
1679     dev[0].p2p_listen()
1680     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1681         raise Exception("P2P_CONNECT failed(2)")
1682     p2p = rx_go_neg_req(dev[0])
1683     dev[0].p2p_stop_find()
1684     dialog_token = p2p['dialog_token']
1685     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1686     attrs = p2p_attr_status()
1687     attrs += p2p_attr_capability()
1688     attrs += p2p_attr_go_intent(go_intent=15)
1689     attrs += p2p_attr_config_timeout()
1690     attrs += p2p_attr_intended_interface_addr(addr0)
1691     #attrs += p2p_attr_channel_list()
1692     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1693     attrs += p2p_attr_operating_channel()
1694     attrs += p2p_attr_group_id(addr0, "DIRECT-foo")
1695     msg['payload'] += ie_p2p(attrs)
1696     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1697     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_INVALID_PARAMS)
1698     rx_go_neg_conf(dev[0], P2P_SC_FAIL_INVALID_PARAMS, dialog_token)
1699
1700     logger.debug("GO Neg Resp without common channels")
1701     dev[1].p2p_stop_find()
1702     dev[0].p2p_listen()
1703     if "FAIL" in dev[1].global_request("P2P_CONNECT " + addr0 + " pbc go_intent=0"):
1704         raise Exception("P2P_CONNECT failed(2)")
1705     p2p = rx_go_neg_req(dev[0])
1706     dev[0].p2p_stop_find()
1707     dialog_token = p2p['dialog_token']
1708     msg = p2p_hdr(addr1, addr0, type=P2P_GO_NEG_RESP, dialog_token=dialog_token)
1709     attrs = p2p_attr_status()
1710     attrs += p2p_attr_capability()
1711     attrs += p2p_attr_go_intent(go_intent=15)
1712     attrs += p2p_attr_config_timeout()
1713     attrs += p2p_attr_intended_interface_addr(addr0)
1714     attrs += struct.pack("<BH3BBB", P2P_ATTR_CHANNEL_LIST, 5,
1715                          0x58, 0x58, 0x04,
1716                          81, 0)
1717     attrs += p2p_attr_device_info(addr0, config_methods=0x0108)
1718     attrs += p2p_attr_operating_channel()
1719     attrs += p2p_attr_group_id(addr0, "DIRECT-foo")
1720     msg['payload'] += ie_p2p(attrs)
1721     mgmt_tx(dev[0], "MGMT_TX {} {} freq={} wait_time=200 no_cck=1 action={}".format(addr1, addr1, p2p['freq'], binascii.hexlify(msg['payload'])))
1722     check_p2p_go_neg_fail_event(dev[1], P2P_SC_FAIL_NO_COMMON_CHANNELS)
1723     rx_go_neg_conf(dev[0], P2P_SC_FAIL_NO_COMMON_CHANNELS, dialog_token)