Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / tests / hwsim / test_fst_module.py
1 # FST functionality tests
2 # Copyright (c) 2015, Qualcomm Atheros, Inc.
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import logging
8 logger = logging.getLogger()
9 import struct
10 import subprocess
11 import time
12 import os
13 import re
14
15 import hwsim_utils
16 from hwsim import HWSimRadio
17 import hostapd
18 from wpasupplicant import WpaSupplicant
19 import fst_test_common
20 import fst_module_aux
21 from utils import alloc_fail, HwsimSkip
22
23 #enum - bad parameter types
24 bad_param_none = 0
25 bad_param_session_add_no_params = 1
26 bad_param_group_id = 2
27 bad_param_session_set_no_params = 3
28 bad_param_session_set_unknown_param = 4
29 bad_param_session_id = 5
30 bad_param_old_iface = 6
31 bad_param_new_iface = 7
32 bad_param_negative_llt = 8
33 bad_param_zero_llt = 9
34 bad_param_llt_too_big = 10
35 bad_param_llt_nan = 11
36 bad_param_peer_addr = 12
37 bad_param_session_initiate_no_params = 13
38 bad_param_session_initiate_bad_session_id = 14
39 bad_param_session_initiate_with_no_new_iface_set = 15
40 bad_param_session_initiate_with_bad_peer_addr_set = 16
41 bad_param_session_initiate_request_with_bad_stie = 17
42 bad_param_session_initiate_response_with_reject = 18
43 bad_param_session_initiate_response_with_bad_stie = 19
44 bad_param_session_initiate_response_with_zero_llt = 20
45 bad_param_session_initiate_stt_no_response = 21
46 bad_param_session_initiate_concurrent_setup_request = 22
47 bad_param_session_transfer_no_params = 23
48 bad_param_session_transfer_bad_session_id = 24
49 bad_param_session_transfer_setup_skipped = 25
50 bad_param_session_teardown_no_params = 26
51 bad_param_session_teardown_bad_session_id = 27
52 bad_param_session_teardown_setup_skipped = 28
53 bad_param_session_teardown_bad_fsts_id = 29
54
55 bad_param_names = ("None",
56                    "No params passed to session add",
57                    "Group ID",
58                    "No params passed to session set",
59                    "Unknown param passed to session set",
60                    "Session ID",
61                    "Old interface name",
62                    "New interface name",
63                    "Negative LLT",
64                    "Zero LLT",
65                    "LLT too big",
66                    "LLT is not a number",
67                    "Peer address",
68                    "No params passed to session initiate",
69                    "Session ID",
70                    "No new_iface was set",
71                    "Peer address",
72                    "Request with bad st ie",
73                    "Response with reject",
74                    "Response with bad st ie",
75                    "Response with zero llt",
76                    "No response, STT",
77                    "Concurrent setup request",
78                    "No params passed to session transfer",
79                    "Session ID",
80                    "Session setup skipped",
81                    "No params passed to session teardown",
82                    "Bad session",
83                    "Session setup skipped",
84                    "Bad fsts_id")
85
86 def fst_start_session(apdev, test_params, bad_param_type, start_on_ap,
87                       peer_addr = None):
88     """This function makes the necessary preparations and the adds and sets a
89     session using either correct or incorrect parameters depending on the value
90     of bad_param_type. If the call ends as expected (with session being
91     successfully added and set in case of correct parameters or with the
92     expected exception in case of incorrect parameters), the function silently
93     exits. Otherwise, it throws an exception thus failing the test."""
94
95     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
96     bad_parameter_detected = False
97     exception_already_raised = False
98     try:
99         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
100         if start_on_ap:
101             initiator = ap1
102             responder = sta1
103             new_iface = ap2.ifname()
104             new_peer_addr = ap2.get_actual_peer_addr()
105         else:
106             initiator = sta1
107             responder = ap1
108             new_iface = sta2.ifname()
109             new_peer_addr = sta2.get_actual_peer_addr()
110         initiator.add_peer(responder, peer_addr, new_peer_addr)
111         group_id = None
112         if bad_param_type == bad_param_group_id:
113             group_id = '-1'
114         elif bad_param_type == bad_param_session_add_no_params:
115             group_id = ''
116         initiator.set_fst_parameters(group_id=group_id)
117         sid = initiator.add_session()
118         if bad_param_type == bad_param_session_set_no_params:
119             res = initiator.set_session_param(None)
120             if not res.startswith("OK"):
121                 raise Exception("Session set operation failed")
122         elif bad_param_type == bad_param_session_set_unknown_param:
123             res = initiator.set_session_param("bad_param=1")
124             if not res.startswith("OK"):
125                 raise Exception("Session set operation failed")
126         else:
127             if bad_param_type == bad_param_session_initiate_with_no_new_iface_set:
128                 new_iface = None
129             elif bad_param_type == bad_param_new_iface:
130                 new_iface = 'wlan12'
131             old_iface = None if bad_param_type != bad_param_old_iface else 'wlan12'
132             llt = None
133             if bad_param_type == bad_param_negative_llt:
134                 llt = '-1'
135             elif bad_param_type == bad_param_zero_llt:
136                 llt = '0'
137             elif bad_param_type == bad_param_llt_too_big:
138                 llt = '4294967296'    #0x100000000
139             elif bad_param_type == bad_param_llt_nan:
140                 llt = 'nan'
141             elif bad_param_type == bad_param_session_id:
142                 sid = '-1'
143             initiator.set_fst_parameters(llt=llt)
144             initiator.configure_session(sid, new_iface, old_iface)
145     except Exception, e:
146         if e.args[0].startswith("Cannot add FST session with groupid"):
147             if bad_param_type == bad_param_group_id or bad_param_type == bad_param_session_add_no_params:
148                 bad_parameter_detected = True
149         elif e.args[0].startswith("Cannot set FST session new_ifname:"):
150             if bad_param_type == bad_param_new_iface:
151                 bad_parameter_detected = True
152         elif e.args[0].startswith("Session set operation failed"):
153             if (bad_param_type == bad_param_session_set_no_params or
154                 bad_param_type == bad_param_session_set_unknown_param):
155                 bad_parameter_detected = True
156         elif e.args[0].startswith("Cannot set FST session old_ifname:"):
157             if (bad_param_type == bad_param_old_iface or
158                 bad_param_type == bad_param_session_id or
159                 bad_param_type == bad_param_session_set_no_params):
160                 bad_parameter_detected = True
161         elif e.args[0].startswith("Cannot set FST session llt:"):
162             if (bad_param_type == bad_param_negative_llt or
163                 bad_param_type == bad_param_llt_too_big or
164                 bad_param_type == bad_param_llt_nan):
165                 bad_parameter_detected = True
166         elif e.args[0].startswith("Cannot set FST session peer address:"):
167             if bad_param_type == bad_param_peer_addr:
168                 bad_parameter_detected = True
169         if not bad_parameter_detected:
170             # The exception was unexpected
171             logger.info(e)
172             exception_already_raised = True
173             raise
174     finally:
175         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
176         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
177         if not exception_already_raised:
178             if bad_parameter_detected:
179                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
180             else:
181                 if bad_param_type == bad_param_none or bad_param_type == bad_param_zero_llt:
182                     logger.info("Success. Session added and set")
183                 else:
184                     exception_text = ""
185                     if bad_param_type == bad_param_peer_addr:
186                         exception_text = "Failure. Bad parameter was not detected (Peer address == %s)" % ap1.get_new_peer_addr()
187                     else:
188                         exception_text = "Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type]
189                     raise Exception(exception_text)
190         else:
191             print "Failure. Unexpected exception"
192
193 def fst_initiate_session(apdev, test_params, bad_param_type, init_on_ap):
194     """This function makes the necessary preparations and then adds, sets and
195     initiates a session using either correct or incorrect parameters at each
196     stage depending on the value of bad_param_type. If the call ends as expected
197     (with session being successfully added, set and initiated in case of correct
198     parameters or with the expected exception in case of incorrect parameters),
199     the function silently exits. Otherwise it throws an exception thus failing
200     the test."""
201     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
202     bad_parameter_detected = False
203     exception_already_raised = False
204     try:
205         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
206         # This call makes sure FstHostapd singleton object is created and, as a
207         # result, the global control interface is registered (this is done from
208         # the constructor).
209         ap1.get_global_instance()
210         if init_on_ap:
211             initiator = ap1
212             responder = sta1
213             new_iface = ap2.ifname() if bad_param_type != bad_param_session_initiate_with_no_new_iface_set else None
214             new_peer_addr = ap2.get_actual_peer_addr()
215             resp_newif = sta2.ifname()
216         else:
217             initiator = sta1
218             responder = ap1
219             new_iface = sta2.ifname() if bad_param_type != bad_param_session_initiate_with_no_new_iface_set else None
220             new_peer_addr = sta2.get_actual_peer_addr()
221             resp_newif = ap2.ifname()
222         peeraddr = None if bad_param_type != bad_param_session_initiate_with_bad_peer_addr_set else '10:DE:AD:DE:AD:11'
223         initiator.add_peer(responder, peeraddr, new_peer_addr)
224         if bad_param_type == bad_param_session_initiate_response_with_zero_llt:
225             initiator.set_fst_parameters(llt='0')
226         sid = initiator.add_session()
227         initiator.configure_session(sid, new_iface)
228         if bad_param_type == bad_param_session_initiate_no_params:
229             sid = ''
230         elif bad_param_type == bad_param_session_initiate_bad_session_id:
231             sid = '-1'
232         if bad_param_type == bad_param_session_initiate_request_with_bad_stie:
233             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
234             initiator.send_test_session_setup_request(str(actual_fsts_id), "bad_new_band")
235             responder.wait_for_session_event(5)
236         elif bad_param_type == bad_param_session_initiate_response_with_reject:
237             initiator.send_session_setup_request(sid)
238             initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
239             setup_event = responder.wait_for_session_event(5, [],
240                                                            ['EVENT_FST_SETUP'])
241             if not 'id' in setup_event:
242                 raise Exception("No session id in FST setup event")
243             responder.send_session_setup_response(str(setup_event['id']),
244                                                   "reject")
245             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
246             if event['new_state'] != "INITIAL" or event['reason'] != "REASON_REJECT":
247                 raise Exception("Response with reject not handled as expected")
248             bad_parameter_detected = True
249         elif bad_param_type == bad_param_session_initiate_response_with_bad_stie:
250             initiator.send_session_setup_request(sid)
251             initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
252             responder.wait_for_session_event(5, [], ['EVENT_FST_SETUP'])
253             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
254             responder.send_test_session_setup_response(str(actual_fsts_id),
255                                                        "accept", "bad_new_band")
256             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
257             if event['new_state'] != "INITIAL" or event['reason'] != "REASON_ERROR_PARAMS":
258                 raise Exception("Response with bad STIE not handled as expected")
259             bad_parameter_detected = True
260         elif bad_param_type == bad_param_session_initiate_response_with_zero_llt:
261             initiator.initiate_session(sid, "accept")
262             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
263             if event['new_state'] != "TRANSITION_DONE":
264                 raise Exception("Response reception for a session with llt=0 not handled as expected")
265             bad_parameter_detected = True
266         elif bad_param_type == bad_param_session_initiate_stt_no_response:
267             initiator.send_session_setup_request(sid)
268             initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
269             responder.wait_for_session_event(5, [], ['EVENT_FST_SETUP'])
270             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
271             if event['new_state'] != "INITIAL" or event['reason'] != "REASON_STT":
272                 raise Exception("No response scenario not handled as expected")
273             bad_parameter_detected = True
274         elif bad_param_type == bad_param_session_initiate_concurrent_setup_request:
275             responder.add_peer(initiator)
276             resp_sid = responder.add_session()
277             responder.configure_session(resp_sid, resp_newif)
278             initiator.send_session_setup_request(sid)
279             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
280             responder.send_test_session_setup_request(str(actual_fsts_id))
281             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
282             initiator_addr = initiator.get_own_mac_address()
283             responder_addr = responder.get_own_mac_address()
284             if initiator_addr < responder_addr:
285                 event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
286                 if event['new_state'] != "INITIAL" or event['reason'] != "REASON_SETUP":
287                     raise Exception("Concurrent setup scenario not handled as expected")
288                 event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SETUP"])
289                 # The incoming setup request received by the initiator has
290                 # priority over the one sent previously by the initiator itself
291                 # because the initiator's MAC address is numerically lower than
292                 # the one of the responder. Thus, the initiator should generate
293                 # an FST_SETUP event.
294             else:
295                 event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
296                 if event['new_state'] != "INITIAL" or event['reason'] != "REASON_STT":
297                     raise Exception("Concurrent setup scenario not handled as expected")
298                 # The incoming setup request was dropped at the initiator
299                 # because its MAC address is numerically bigger than the one of
300                 # the responder. Thus, the initiator continue to wait for a
301                 # setup response until the STT event fires.
302             bad_parameter_detected = True
303         else:
304             initiator.initiate_session(sid, "accept")
305     except Exception, e:
306         if e.args[0].startswith("Cannot initiate fst session"):
307             if bad_param_type != bad_param_none:
308                 bad_parameter_detected = True
309         elif e.args[0].startswith("No FST-EVENT-SESSION received"):
310             if bad_param_type == bad_param_session_initiate_request_with_bad_stie:
311                 bad_parameter_detected = True
312         if not bad_parameter_detected:
313             #The exception was unexpected
314             logger.info(e)
315             exception_already_raised = True
316             raise
317     finally:
318         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
319         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
320         if not exception_already_raised:
321             if bad_parameter_detected:
322                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
323             else:
324                 if bad_param_type == bad_param_none:
325                     logger.info("Success. Session initiated")
326                 else:
327                     raise Exception("Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type])
328         else:
329             print "Failure. Unexpected exception"
330
331 def fst_transfer_session(apdev, test_params, bad_param_type, init_on_ap,
332                          rsn=False):
333     """This function makes the necessary preparations and then adds, sets,
334     initiates and attempts to transfer a session using either correct or
335     incorrect parameters at each stage depending on the value of bad_param_type.
336     If the call ends as expected the function silently exits. Otherwise, it
337     throws an exception thus failing the test."""
338     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev, rsn=rsn)
339     bad_parameter_detected = False
340     exception_already_raised = False
341     try:
342         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2, rsn=rsn)
343         # This call makes sure FstHostapd singleton object is created and, as a
344         # result, the global control interface is registered (this is done from
345         # the constructor).
346         ap1.get_global_instance()
347         if init_on_ap:
348             initiator = ap1
349             responder = sta1
350             new_iface = ap2.ifname()
351             new_peer_addr = ap2.get_actual_peer_addr()
352         else:
353             initiator = sta1
354             responder = ap1
355             new_iface = sta2.ifname()
356             new_peer_addr = sta2.get_actual_peer_addr()
357         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
358         sid = initiator.add_session()
359         initiator.configure_session(sid, new_iface)
360         if bad_param_type != bad_param_session_transfer_setup_skipped:
361             initiator.initiate_session(sid, "accept")
362         if bad_param_type == bad_param_session_transfer_no_params:
363             sid = ''
364         elif bad_param_type == bad_param_session_transfer_bad_session_id:
365             sid = '-1'
366         initiator.transfer_session(sid)
367     except Exception, e:
368         if e.args[0].startswith("Cannot transfer fst session"):
369             if bad_param_type != bad_param_none:
370                 bad_parameter_detected = True
371         if not bad_parameter_detected:
372             # The exception was unexpected
373             logger.info(e)
374             exception_already_raised = True
375             raise
376     finally:
377         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
378         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
379         if not exception_already_raised:
380             if bad_parameter_detected:
381                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
382             else:
383                 if bad_param_type == bad_param_none:
384                     logger.info("Success. Session transferred")
385                 else:
386                     raise Exception("Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type])
387         else:
388             print "Failure. Unexpected exception"
389
390
391 def fst_tear_down_session(apdev, test_params, bad_param_type, init_on_ap):
392     """This function makes the necessary preparations and then adds, sets, and
393     initiates a session. It then issues a tear down command using either
394     correct or incorrect parameters at each stage. If the call ends as expected,
395     the function silently exits. Otherwise, it throws an exception thus failing
396     the test."""
397     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
398     bad_parameter_detected = False
399     exception_already_raised = False
400     try:
401         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
402         # This call makes sure FstHostapd singleton object is created and, as a
403         # result, the global control interface is registered (this is done from
404         # the constructor).
405         ap1.get_global_instance()
406         if init_on_ap:
407             initiator = ap1
408             responder = sta1
409             new_iface = ap2.ifname()
410             new_peer_addr = ap2.get_actual_peer_addr()
411         else:
412             initiator = sta1
413             responder = ap1
414             new_iface = sta2.ifname()
415             new_peer_addr = sta2.get_actual_peer_addr()
416         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
417         sid = initiator.add_session()
418         initiator.configure_session(sid, new_iface)
419         if bad_param_type != bad_param_session_teardown_setup_skipped:
420             initiator.initiate_session(sid, "accept")
421         if bad_param_type == bad_param_session_teardown_bad_fsts_id:
422             initiator.send_test_tear_down('-1')
423             responder.wait_for_session_event(5)
424         else:
425             if bad_param_type == bad_param_session_teardown_no_params:
426                 sid = ''
427             elif bad_param_type == bad_param_session_teardown_bad_session_id:
428                 sid = '-1'
429             initiator.teardown_session(sid)
430     except Exception, e:
431         if e.args[0].startswith("Cannot tear down fst session"):
432             if (bad_param_type == bad_param_session_teardown_no_params or
433                 bad_param_type == bad_param_session_teardown_bad_session_id or
434                 bad_param_type == bad_param_session_teardown_setup_skipped):
435                 bad_parameter_detected = True
436         elif e.args[0].startswith("No FST-EVENT-SESSION received"):
437             if bad_param_type == bad_param_session_teardown_bad_fsts_id:
438                 bad_parameter_detected = True
439         if not bad_parameter_detected:
440             # The exception was unexpected
441             logger.info(e)
442             exception_already_raised = True
443             raise
444     finally:
445         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
446         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
447         if not exception_already_raised:
448             if bad_parameter_detected:
449                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
450             else:
451                 if bad_param_type == bad_param_none:
452                     logger.info("Success. Session torn down")
453                 else:
454                     raise Exception("Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type])
455         else:
456             print "Failure. Unexpected exception"
457
458
459 #enum - remove session scenarios
460 remove_scenario_no_params = 0
461 remove_scenario_bad_session_id = 1
462 remove_scenario_non_established_session = 2
463 remove_scenario_established_session = 3
464
465 remove_scenario_names = ("No params",
466                          "Bad session id",
467                          "Remove non-established session",
468                          "Remove established session")
469
470
471 def fst_remove_session(apdev, test_params, remove_session_scenario, init_on_ap):
472     """This function attempts to remove a session at various stages of its
473     formation, depending on the value of remove_session_scenario. If the call
474     ends as expected, the function silently exits. Otherwise, it throws an
475     exception thus failing the test."""
476     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
477     bad_parameter_detected = False
478     exception_already_raised = False
479     try:
480         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
481         # This call makes sure FstHostapd singleton object is created and, as a
482         # result, the global control interface is registered (this is done from
483         # the constructor).
484         ap1.get_global_instance()
485         if init_on_ap:
486             initiator = ap1
487             responder = sta1
488             new_iface = ap2.ifname()
489             new_peer_addr = ap2.get_actual_peer_addr()
490         else:
491             initiator = sta1
492             responder = ap1
493             new_iface = sta2.ifname()
494             new_peer_addr = sta2.get_actual_peer_addr()
495         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
496         sid = initiator.add_session()
497         initiator.configure_session(sid, new_iface)
498         if remove_session_scenario != remove_scenario_no_params:
499             if remove_session_scenario != remove_scenario_non_established_session:
500                 initiator.initiate_session(sid, "accept")
501         if remove_session_scenario == remove_scenario_no_params:
502             sid = ''
503         elif remove_session_scenario == remove_scenario_bad_session_id:
504             sid = '-1'
505         initiator.remove_session(sid)
506     except Exception, e:
507         if e.args[0].startswith("Cannot remove fst session"):
508             if (remove_session_scenario == remove_scenario_no_params or
509                 remove_session_scenario == remove_scenario_bad_session_id):
510                 bad_parameter_detected = True
511         elif e.args[0].startswith("No FST-EVENT-SESSION received"):
512             if remove_session_scenario == remove_scenario_non_established_session:
513                 bad_parameter_detected = True
514         if not bad_parameter_detected:
515             #The exception was unexpected
516             logger.info(e)
517             exception_already_raised = True
518             raise
519     finally:
520         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
521         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
522         if not exception_already_raised:
523             if bad_parameter_detected:
524                 logger.info("Success. Remove scenario ended as expected (%s)" % remove_scenario_names[remove_session_scenario])
525             else:
526                 if remove_session_scenario == remove_scenario_established_session:
527                     logger.info("Success. Session removed")
528                 else:
529                     raise Exception("Failure. Remove scenario ended in an unexpected way (%s)" % remove_scenario_names[remove_session_scenario])
530         else:
531             print "Failure. Unexpected exception"
532
533
534 #enum - frame types
535 frame_type_session_request = 0
536 frame_type_session_response = 1
537 frame_type_ack_request = 2
538 frame_type_ack_response = 3
539 frame_type_tear_down = 4
540
541 frame_type_names = ("Session request",
542                     "Session Response",
543                     "Ack request",
544                     "Ack response",
545                     "Tear down")
546
547 def fst_send_unexpected_frame(apdev, test_params, frame_type, send_from_ap, additional_param = ''):
548     """This function creates two pairs of APs and stations, makes them connect
549     and then causes one side to send an unexpected FST frame of the specified
550     type to the other. The other side should then identify and ignore the
551     frame."""
552     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
553     exception_already_raised = False
554     frame_receive_timeout = False
555     try:
556         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
557         # This call makes sure FstHostapd singleton object is created and, as a
558         # result, the global control interface is registered (this is done from
559         # the constructor).
560         ap1.get_global_instance()
561         if send_from_ap:
562             sender = ap1
563             receiver = sta1
564             new_iface = ap2.ifname()
565             new_peer_addr = ap2.get_actual_peer_addr()
566         else:
567             sender = sta1
568             receiver = ap1
569             new_iface = sta2.ifname()
570             new_peer_addr = sta2.get_actual_peer_addr()
571         sender.add_peer(receiver, new_peer_addr = new_peer_addr)
572         sid=sender.add_session()
573         sender.configure_session(sid, new_iface)
574         if frame_type == frame_type_session_request:
575             sender.send_session_setup_request(sid)
576             event = receiver.wait_for_session_event(5)
577             if event['type'] != 'EVENT_FST_SETUP':
578                 raise Exception("Unexpected indication: " + event['type'])
579         elif frame_type == frame_type_session_response:
580             #fsts_id doesn't matter, no actual session exists
581             sender.send_test_session_setup_response('0', additional_param)
582             receiver.wait_for_session_event(5)
583         elif frame_type == frame_type_ack_request:
584             #fsts_id doesn't matter, no actual session exists
585             sender.send_test_ack_request('0')
586             receiver.wait_for_session_event(5)
587         elif frame_type == frame_type_ack_response:
588             #fsts_id doesn't matter, no actual session exists
589             sender.send_test_ack_response('0')
590             receiver.wait_for_session_event(5)
591         elif frame_type == frame_type_tear_down:
592             #fsts_id doesn't matter, no actual session exists
593             sender.send_test_tear_down('0')
594             receiver.wait_for_session_event(5)
595     except Exception, e:
596         if e.args[0].startswith("No FST-EVENT-SESSION received"):
597             if frame_type != frame_type_session_request:
598                 frame_receive_timeout = True
599         else:
600             logger.info(e)
601             exception_already_raised = True
602             raise
603     finally:
604         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
605         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
606         if not exception_already_raised:
607             if frame_receive_timeout:
608                 logger.info("Success. Frame was ignored (%s)" % frame_type_names[frame_type])
609             else:
610                 if frame_type == frame_type_session_request:
611                     logger.info("Success. Frame received, session created")
612                 else:
613                     raise Exception("Failure. Frame was not ignored (%s)" % frame_type_names[frame_type])
614         else:
615             print "Failure. Unexpected exception"
616
617
618 #enum - bad session transfer scenarios
619 bad_scenario_none = 0
620 bad_scenario_ack_req_session_not_set_up = 1
621 bad_scenario_ack_req_session_not_established_init_side = 2
622 bad_scenario_ack_req_session_not_established_resp_side = 3
623 bad_scenario_ack_req_bad_fsts_id = 4
624 bad_scenario_ack_resp_session_not_set_up = 5
625 bad_scenario_ack_resp_session_not_established_init_side = 6
626 bad_scenario_ack_resp_session_not_established_resp_side = 7
627 bad_scenario_ack_resp_no_ack_req = 8
628 bad_scenario_ack_resp_bad_fsts_id = 9
629
630 bad_scenario_names = ("None",
631                       "Ack request received before the session was set up",
632                       "Ack request received on the initiator side before session was established",
633                       "Ack request received on the responder side before session was established",
634                       "Ack request received with bad fsts_id",
635                       "Ack response received before the session was set up",
636                       "Ack response received on the initiator side before session was established",
637                       "Ack response received on the responder side before session was established",
638                       "Ack response received before ack request was sent",
639                       "Ack response received with bad fsts_id")
640
641 def fst_bad_transfer(apdev, test_params, bad_scenario_type, init_on_ap):
642     """This function makes the necessary preparations and then adds and sets a
643     session. It then initiates and it unless instructed otherwise) and attempts
644     to send one of the frames involved in the session transfer protocol,
645     skipping or distorting one of the stages according to the value of
646     bad_scenario_type parameter."""
647     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
648     bad_parameter_detected = False
649     exception_already_raised = False
650     try:
651         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
652         # This call makes sure FstHostapd singleton object is created and, as a
653         # result, the global control interface is registered (this is done from
654         # the constructor).
655         ap1.get_global_instance()
656         if init_on_ap:
657             initiator = ap1
658             responder = sta1
659             new_iface = ap2.ifname()
660             new_peer_addr = ap2.get_actual_peer_addr()
661         else:
662             initiator = sta1
663             responder = ap1
664             new_iface = sta2.ifname()
665             new_peer_addr = sta2.get_actual_peer_addr()
666         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
667         sid = initiator.add_session()
668         initiator.configure_session(sid, new_iface)
669         if (bad_scenario_type != bad_scenario_ack_req_session_not_set_up and
670             bad_scenario_type != bad_scenario_ack_resp_session_not_set_up):
671             if (bad_scenario_type != bad_scenario_ack_req_session_not_established_init_side and
672                 bad_scenario_type != bad_scenario_ack_resp_session_not_established_init_side and
673                 bad_scenario_type != bad_scenario_ack_req_session_not_established_resp_side and
674                 bad_scenario_type != bad_scenario_ack_resp_session_not_established_resp_side):
675                 response =  "accept"
676             else:
677                 response = ''
678             initiator.initiate_session(sid, response)
679         if bad_scenario_type == bad_scenario_ack_req_session_not_set_up:
680             #fsts_id doesn't matter, no actual session exists
681             responder.send_test_ack_request('0')
682             initiator.wait_for_session_event(5)
683             # We want to send the unexpected frame to the side that already has
684             # a session created
685         elif bad_scenario_type == bad_scenario_ack_resp_session_not_set_up:
686             #fsts_id doesn't matter, no actual session exists
687             responder.send_test_ack_response('0')
688             initiator.wait_for_session_event(5)
689             # We want to send the unexpected frame to the side that already has
690             # a session created
691         elif bad_scenario_type == bad_scenario_ack_req_session_not_established_init_side:
692             #fsts_id doesn't matter, no actual session exists
693             initiator.send_test_ack_request('0')
694             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
695         elif bad_scenario_type == bad_scenario_ack_req_session_not_established_resp_side:
696             #fsts_id doesn't matter, no actual session exists
697             responder.send_test_ack_request('0')
698             initiator.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
699         elif bad_scenario_type == bad_scenario_ack_resp_session_not_established_init_side:
700             #fsts_id doesn't matter, no actual session exists
701             initiator.send_test_ack_response('0')
702             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
703         elif bad_scenario_type == bad_scenario_ack_resp_session_not_established_resp_side:
704             #fsts_id doesn't matter, no actual session exists
705             responder.send_test_ack_response('0')
706             initiator.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
707         elif bad_scenario_type == bad_scenario_ack_req_bad_fsts_id:
708             initiator.send_test_ack_request('-1')
709             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
710         elif bad_scenario_type == bad_scenario_ack_resp_bad_fsts_id:
711             initiator.send_test_ack_response('-1')
712             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
713         elif bad_scenario_type == bad_scenario_ack_resp_no_ack_req:
714             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
715             initiator.send_test_ack_response(str(actual_fsts_id))
716             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
717         else:
718             raise Exception("Unknown bad scenario identifier")
719     except Exception, e:
720         if e.args[0].startswith("No FST-EVENT-SESSION received"):
721             bad_parameter_detected = True
722         if not bad_parameter_detected:
723             # The exception was unexpected
724             logger.info(e)
725             exception_already_raised = True
726             raise
727     finally:
728         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
729         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
730         if not exception_already_raised:
731             if bad_parameter_detected:
732                 logger.info("Success. Bad scenario was handled correctly (%s)" % bad_scenario_names[bad_scenario_type])
733             else:
734                 raise Exception("Failure. Bad scenario was handled incorrectly (%s)" % bad_scenario_names[bad_scenario_type])
735         else:
736             print "Failure. Unexpected exception"
737
738 def test_fst_sta_connect_to_non_fst_ap(dev, apdev, test_params):
739     """FST STA connecting to non-FST AP"""
740     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
741     with HWSimRadio() as (radio, iface):
742         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
743         try:
744             orig_sta1_mbies = sta1.get_local_mbies()
745             orig_sta2_mbies = sta2.get_local_mbies()
746             vals = sta2.scan()
747             freq = vals['freq']
748             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g",
749                                         key_mgmt="NONE", scan_freq=freq)
750             time.sleep(2)
751             res_sta1_mbies = sta1.get_local_mbies()
752             res_sta2_mbies = sta2.get_local_mbies()
753             if (orig_sta1_mbies.startswith("FAIL") or
754                 orig_sta2_mbies.startswith("FAIL") or
755                 not res_sta1_mbies.startswith("FAIL") or
756                 not res_sta2_mbies.startswith("FAIL")):
757                 raise Exception("Failure. MB IEs have not been removed on the stations")
758         except Exception, e:
759             logger.info(e)
760             raise
761         finally:
762             sta2.disconnect_from_external_ap()
763             fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
764             hostapd.HostapdGlobal().remove(iface)
765
766 def test_fst_sta_connect_to_fst_ap(dev, apdev, test_params):
767     """FST STA connecting to FST AP"""
768     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
769     try:
770         orig_sta2_mbies = sta2.get_local_mbies()
771         vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
772         sta1.connect(ap1, key_mgmt="NONE",
773                      scan_freq=fst_test_common.fst_test_def_freq_a)
774         time.sleep(2)
775         res_sta2_mbies = sta2.get_local_mbies()
776         if res_sta2_mbies == orig_sta2_mbies:
777             raise Exception("Failure. MB IEs have not been updated")
778     except Exception, e:
779         logger.info(e)
780         raise
781     finally:
782         sta1.disconnect()
783         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
784
785 def test_fst_ap_connect_to_fst_sta(dev, apdev, test_params):
786     """FST AP connecting to FST STA"""
787     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
788     try:
789         orig_ap_mbies = ap1.get_local_mbies()
790         vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
791         sta1.connect(ap1, key_mgmt="NONE",
792                      scan_freq=fst_test_common.fst_test_def_freq_a)
793         time.sleep(2)
794         res_ap_mbies = ap1.get_local_mbies()
795         if res_ap_mbies != orig_ap_mbies:
796             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
797     except Exception, e:
798         logger.info(e)
799         raise
800     finally:
801         sta1.disconnect()
802         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
803
804 def test_fst_ap_connect_to_non_fst_sta(dev, apdev, test_params):
805     """FST AP connecting to non-FST STA"""
806     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
807     try:
808         orig_ap_mbies = ap2.get_local_mbies()
809         vals = dev[0].scan(None, fst_test_common.fst_test_def_freq_g)
810         fst_module_aux.external_sta_connect(dev[0], ap2, key_mgmt="NONE",
811                                             scan_freq=fst_test_common.fst_test_def_freq_g)
812         time.sleep(2)
813         res_ap_mbies = ap2.get_local_mbies()
814         if res_ap_mbies != orig_ap_mbies:
815             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
816     except Exception, e:
817         logger.info(e)
818         raise
819     finally:
820         fst_module_aux.disconnect_external_sta(dev[0], ap2)
821         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
822
823 def test_fst_second_sta_connect_to_non_fst_ap(dev, apdev, test_params):
824     """FST STA 2nd connecting to non-FST AP"""
825     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
826     with HWSimRadio() as (radio, iface):
827         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
828         try:
829             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
830             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
831             time.sleep(2)
832             orig_sta1_mbies = sta1.get_local_mbies()
833             orig_sta2_mbies = sta2.get_local_mbies()
834             vals = sta2.scan()
835             freq = vals['freq']
836             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
837             time.sleep(2)
838             res_sta1_mbies = sta1.get_local_mbies()
839             res_sta2_mbies = sta2.get_local_mbies()
840             if (orig_sta1_mbies.startswith("FAIL") or
841                 orig_sta2_mbies.startswith("FAIL") or
842                 not res_sta1_mbies.startswith("FAIL") or
843                 not res_sta2_mbies.startswith("FAIL")):
844                 raise Exception("Failure. MB IEs have not been removed on the stations")
845         except Exception, e:
846             logger.info(e)
847             raise
848         finally:
849             sta1.disconnect()
850             sta2.disconnect_from_external_ap()
851             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
852             hostapd.HostapdGlobal().remove(iface)
853
854 def test_fst_second_sta_connect_to_fst_ap(dev, apdev, test_params):
855     """FST STA 2nd connecting to FST AP"""
856     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
857     with HWSimRadio() as (radio, iface):
858         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
859         try:
860             vals = sta2.scan()
861             freq = vals['freq']
862             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
863             time.sleep(2)
864             orig_sta1_mbies = sta1.get_local_mbies()
865             orig_sta2_mbies = sta2.get_local_mbies()
866             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
867             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
868             time.sleep(2)
869             res_sta1_mbies = sta1.get_local_mbies()
870             res_sta2_mbies = sta2.get_local_mbies()
871             if (not orig_sta1_mbies.startswith("FAIL") or
872                 not orig_sta2_mbies.startswith("FAIL") or
873                 not res_sta1_mbies.startswith("FAIL") or
874                 not res_sta2_mbies.startswith("FAIL")):
875                 raise Exception("Failure. MB IEs should have stayed non-present on the stations")
876         except Exception, e:
877             logger.info(e)
878             raise
879         finally:
880             sta1.disconnect()
881             sta2.disconnect_from_external_ap()
882             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
883             hostapd.HostapdGlobal().remove(iface)
884
885 def test_fst_disconnect_1_of_2_stas_from_non_fst_ap(dev, apdev, test_params):
886     """FST disconnect 1 of 2 STAs from non-FST AP"""
887     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
888     with HWSimRadio() as (radio, iface):
889         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
890         try:
891             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
892             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
893             vals = sta2.scan()
894             freq = vals['freq']
895             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
896             time.sleep(2)
897             orig_sta1_mbies = sta1.get_local_mbies()
898             orig_sta2_mbies = sta2.get_local_mbies()
899             sta2.disconnect_from_external_ap()
900             time.sleep(2)
901             res_sta1_mbies = sta1.get_local_mbies()
902             res_sta2_mbies = sta2.get_local_mbies()
903             if (not orig_sta1_mbies.startswith("FAIL") or
904                 not orig_sta2_mbies.startswith("FAIL") or
905                 res_sta1_mbies.startswith("FAIL") or
906                 res_sta2_mbies.startswith("FAIL")):
907                 raise Exception("Failure. MB IEs haven't reappeared on the stations")
908         except Exception, e:
909             logger.info(e)
910             raise
911         finally:
912             sta1.disconnect()
913             sta2.disconnect_from_external_ap()
914             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
915             hostapd.HostapdGlobal().remove(iface)
916
917 def test_fst_disconnect_1_of_2_stas_from_fst_ap(dev, apdev, test_params):
918     """FST disconnect 1 of 2 STAs from FST AP"""
919     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
920     with HWSimRadio() as (radio, iface):
921         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
922         try:
923             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
924             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
925             vals = sta2.scan()
926             freq = vals['freq']
927             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
928             time.sleep(2)
929             orig_sta1_mbies = sta1.get_local_mbies()
930             orig_sta2_mbies = sta2.get_local_mbies()
931             sta1.disconnect()
932             time.sleep(2)
933             res_sta1_mbies = sta1.get_local_mbies()
934             res_sta2_mbies = sta2.get_local_mbies()
935             if (not orig_sta1_mbies.startswith("FAIL") or
936                 not orig_sta2_mbies.startswith("FAIL") or
937                 not res_sta1_mbies.startswith("FAIL") or
938                 not res_sta2_mbies.startswith("FAIL")):
939                 raise Exception("Failure. MB IEs should have stayed non-present on the stations")
940         except Exception, e:
941             logger.info(e)
942             raise
943         finally:
944             sta1.disconnect()
945             sta2.disconnect_from_external_ap()
946             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
947             hostapd.HostapdGlobal().remove(iface)
948
949 def test_fst_disconnect_2_of_2_stas_from_non_fst_ap(dev, apdev, test_params):
950     """FST disconnect 2 of 2 STAs from non-FST AP"""
951     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
952     with HWSimRadio() as (radio, iface):
953         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
954         try:
955             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
956             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
957             vals = sta2.scan()
958             freq = vals['freq']
959             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
960             time.sleep(2)
961             sta1.disconnect()
962             time.sleep(2)
963             orig_sta1_mbies = sta1.get_local_mbies()
964             orig_sta2_mbies = sta2.get_local_mbies()
965             sta2.disconnect_from_external_ap()
966             time.sleep(2)
967             res_sta1_mbies = sta1.get_local_mbies()
968             res_sta2_mbies = sta2.get_local_mbies()
969             if (not orig_sta1_mbies.startswith("FAIL") or
970                 not orig_sta2_mbies.startswith("FAIL") or
971                 res_sta1_mbies.startswith("FAIL") or
972                 res_sta2_mbies.startswith("FAIL")):
973                 raise Exception("Failure. MB IEs haven't reappeared on the stations")
974         except Exception, e:
975             logger.info(e)
976             raise
977         finally:
978             sta1.disconnect()
979             sta2.disconnect_from_external_ap()
980             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
981             hostapd.HostapdGlobal().remove(iface)
982
983 def test_fst_disconnect_2_of_2_stas_from_fst_ap(dev, apdev, test_params):
984     """FST disconnect 2 of 2 STAs from FST AP"""
985     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
986     with HWSimRadio() as (radio, iface):
987         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g"})
988         try:
989             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
990             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
991             vals = sta2.scan()
992             freq = vals['freq']
993             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
994             time.sleep(2)
995             sta2.disconnect_from_external_ap()
996             time.sleep(2)
997             orig_sta1_mbies = sta1.get_local_mbies()
998             orig_sta2_mbies = sta2.get_local_mbies()
999             sta1.disconnect()
1000             time.sleep(2)
1001             res_sta1_mbies = sta1.get_local_mbies()
1002             res_sta2_mbies = sta2.get_local_mbies()
1003             if (orig_sta1_mbies.startswith("FAIL") or
1004                 orig_sta2_mbies.startswith("FAIL") or
1005                 res_sta1_mbies.startswith("FAIL") or
1006                 res_sta2_mbies.startswith("FAIL")):
1007                 raise Exception("Failure. MB IEs should have stayed present on both stations")
1008             # Mandatory part of 8.4.2.140 Multi-band element is 24 bytes = 48 hex chars
1009             basic_sta1_mbies = res_sta1_mbies[0:48] + res_sta1_mbies[60:108]
1010             basic_sta2_mbies = res_sta2_mbies[0:48] + res_sta2_mbies[60:108]
1011             if (basic_sta1_mbies != basic_sta2_mbies):
1012                 raise Exception("Failure. Basic MB IEs should have become identical on both stations")
1013             addr_sta1_str = sta1.get_own_mac_address().replace(":", "")
1014             addr_sta2_str = sta2.get_own_mac_address().replace(":", "")
1015             # Mandatory part of 8.4.2.140 Multi-band element is followed by STA MAC Address field (6 bytes = 12 hex chars)
1016             addr_sta1_mbie1 = res_sta1_mbies[48:60]
1017             addr_sta1_mbie2 = res_sta1_mbies[108:120]
1018             addr_sta2_mbie1 = res_sta2_mbies[48:60]
1019             addr_sta2_mbie2 = res_sta2_mbies[108:120]
1020             if (addr_sta1_mbie1 != addr_sta1_mbie2 or
1021                 addr_sta1_mbie1 != addr_sta2_str or
1022                 addr_sta2_mbie1 != addr_sta2_mbie2 or
1023                 addr_sta2_mbie1 != addr_sta1_str):
1024                 raise Exception("Failure. STA Address in MB IEs should have been same as the other STA's")
1025         except Exception, e:
1026             logger.info(e)
1027             raise
1028         finally:
1029             sta1.disconnect()
1030             sta2.disconnect_from_external_ap()
1031             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
1032             hostapd.HostapdGlobal().remove(iface)
1033
1034 def test_fst_disconnect_non_fst_sta(dev, apdev, test_params):
1035     """FST disconnect non-FST STA"""
1036     ap1, ap2, fst_sta1, fst_sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1037     external_sta_connected = False
1038     try:
1039         vals = fst_sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
1040         fst_sta1.connect(ap1, key_mgmt="NONE",
1041                          scan_freq=fst_test_common.fst_test_def_freq_a)
1042         vals = dev[0].scan(None, fst_test_common.fst_test_def_freq_g)
1043         fst_module_aux.external_sta_connect(dev[0], ap2, key_mgmt="NONE",
1044                                             scan_freq=fst_test_common.fst_test_def_freq_g)
1045         external_sta_connected = True
1046         time.sleep(2)
1047         fst_sta1.disconnect()
1048         time.sleep(2)
1049         orig_ap_mbies = ap2.get_local_mbies()
1050         fst_module_aux.disconnect_external_sta(dev[0], ap2)
1051         external_sta_connected = False
1052         time.sleep(2)
1053         res_ap_mbies = ap2.get_local_mbies()
1054         if res_ap_mbies != orig_ap_mbies:
1055             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
1056     except Exception, e:
1057         logger.info(e)
1058         raise
1059     finally:
1060         fst_sta1.disconnect()
1061         if external_sta_connected:
1062             fst_module_aux.disconnect_external_sta(dev[0], ap2)
1063         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, fst_sta1, fst_sta2)
1064
1065 def test_fst_disconnect_fst_sta(dev, apdev, test_params):
1066     """FST disconnect FST STA"""
1067     ap1, ap2, fst_sta1, fst_sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1068     external_sta_connected = False;
1069     try:
1070         vals = fst_sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
1071         fst_sta1.connect(ap1, key_mgmt="NONE",
1072                          scan_freq=fst_test_common.fst_test_def_freq_a)
1073         vals = dev[0].scan(None, fst_test_common.fst_test_def_freq_g)
1074         fst_module_aux.external_sta_connect(dev[0], ap2, key_mgmt="NONE",
1075                                             scan_freq=fst_test_common.fst_test_def_freq_g)
1076         external_sta_connected = True
1077         time.sleep(2)
1078         fst_module_aux.disconnect_external_sta(dev[0], ap2)
1079         external_sta_connected = False
1080         time.sleep(2)
1081         orig_ap_mbies = ap2.get_local_mbies()
1082         fst_sta1.disconnect()
1083         time.sleep(2)
1084         res_ap_mbies = ap2.get_local_mbies()
1085         if res_ap_mbies != orig_ap_mbies:
1086             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
1087     except Exception, e:
1088         logger.info(e)
1089         raise
1090     finally:
1091         fst_sta1.disconnect()
1092         if external_sta_connected:
1093             fst_module_aux.disconnect_external_sta(dev[0], ap2)
1094         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, fst_sta1, fst_sta2)
1095
1096 def test_fst_dynamic_iface_attach(dev, apdev, test_params):
1097     """FST dynamic interface attach"""
1098     ap1 = fst_module_aux.FstAP(apdev[0]['ifname'], 'fst_11a', 'a',
1099                                fst_test_common.fst_test_def_chan_a,
1100                                fst_test_common.fst_test_def_group,
1101                                fst_test_common.fst_test_def_prio_low,
1102                                fst_test_common.fst_test_def_llt)
1103     ap1.start()
1104     ap2 = fst_module_aux.FstAP(apdev[1]['ifname'], 'fst_11g', 'b',
1105                                fst_test_common.fst_test_def_chan_g,
1106                                '', '', '')
1107     ap2.start()
1108
1109     sta1 = fst_module_aux.FstSTA('wlan5',
1110                                  fst_test_common.fst_test_def_group,
1111                                  fst_test_common.fst_test_def_prio_low,
1112                                  fst_test_common.fst_test_def_llt)
1113     sta1.start()
1114     sta2 = fst_module_aux.FstSTA('wlan6', '', '', '')
1115     sta2.start()
1116
1117     try:
1118         orig_sta2_mbies = sta2.get_local_mbies()
1119         orig_ap2_mbies = ap2.get_local_mbies()
1120         sta2.send_iface_attach_request(sta2.ifname(),
1121                                        fst_test_common.fst_test_def_group,
1122                                        '52', '27')
1123         event = sta2.wait_for_iface_event(5)
1124         if event['event_type'] != 'attached':
1125             raise Exception("Failure. Iface was not properly attached")
1126         ap2.send_iface_attach_request(ap2.ifname(),
1127                                       fst_test_common.fst_test_def_group,
1128                                       '102', '77')
1129         event = ap2.wait_for_iface_event(5)
1130         if event['event_type'] != 'attached':
1131             raise Exception("Failure. Iface was not properly attached")
1132         time.sleep(2)
1133         res_sta2_mbies = sta2.get_local_mbies()
1134         res_ap2_mbies = ap2.get_local_mbies()
1135         sta2.send_iface_detach_request(sta2.ifname())
1136         event = sta2.wait_for_iface_event(5)
1137         if event['event_type'] != 'detached':
1138             raise Exception("Failure. Iface was not properly detached")
1139         ap2.send_iface_detach_request(ap2.ifname())
1140         event = ap2.wait_for_iface_event(5)
1141         if event['event_type'] != 'detached':
1142             raise Exception("Failure. Iface was not properly detached")
1143         if (not orig_sta2_mbies.startswith("FAIL") or
1144             not orig_ap2_mbies.startswith("FAIL") or
1145             res_sta2_mbies.startswith("FAIL") or
1146             res_ap2_mbies.startswith("FAIL")):
1147             raise Exception("Failure. MB IEs should have appeared on the station and on the AP")
1148     except Exception, e:
1149         logger.info(e)
1150         raise
1151     finally:
1152         ap1.stop()
1153         ap2.stop()
1154         sta1.stop()
1155         sta2.stop()
1156
1157 # AP side FST module tests
1158
1159 def test_fst_ap_start_session(dev, apdev, test_params):
1160     """FST AP start session"""
1161     fst_start_session(apdev, test_params, bad_param_none, True)
1162
1163 def test_fst_ap_start_session_no_add_params(dev, apdev, test_params):
1164     """FST AP start session - no add params"""
1165     fst_start_session(apdev, test_params, bad_param_session_add_no_params, True)
1166
1167 def test_fst_ap_start_session_bad_group_id(dev, apdev, test_params):
1168     """FST AP start session - bad group id"""
1169     fst_start_session(apdev, test_params, bad_param_group_id, True)
1170
1171 def test_fst_ap_start_session_no_set_params(dev, apdev, test_params):
1172     """FST AP start session - no set params"""
1173     fst_start_session(apdev, test_params, bad_param_session_set_no_params, True)
1174
1175 def test_fst_ap_start_session_set_unknown_param(dev, apdev, test_params):
1176     """FST AP start session - set unknown param"""
1177     fst_start_session(apdev, test_params, bad_param_session_set_unknown_param,
1178                       True)
1179
1180 def test_fst_ap_start_session_bad_session_id(dev, apdev, test_params):
1181     """FST AP start session - bad session id"""
1182     fst_start_session(apdev, test_params, bad_param_session_id, True)
1183
1184 def test_fst_ap_start_session_bad_new_iface(dev, apdev, test_params):
1185     """FST AP start session - bad new iface"""
1186     fst_start_session(apdev, test_params, bad_param_new_iface, True)
1187
1188 def test_fst_ap_start_session_bad_old_iface(dev, apdev, test_params):
1189     """FST AP start session - bad old iface"""
1190     fst_start_session(apdev, test_params, bad_param_old_iface, True)
1191
1192 def test_fst_ap_start_session_negative_llt(dev, apdev, test_params):
1193     """FST AP start session - negative llt"""
1194     fst_start_session(apdev, test_params, bad_param_negative_llt, True)
1195
1196 def test_fst_ap_start_session_zero_llt(dev, apdev, test_params):
1197     """FST AP start session - zero llt"""
1198     fst_start_session(apdev, test_params, bad_param_zero_llt, True)
1199
1200 def test_fst_ap_start_session_llt_too_big(dev, apdev, test_params):
1201     """FST AP start session - llt too large"""
1202     fst_start_session(apdev, test_params, bad_param_llt_too_big, True)
1203
1204 def test_fst_ap_start_session_invalid_peer_addr(dev, apdev, test_params):
1205     """FST AP start session - invalid peer address"""
1206     fst_start_session(apdev, test_params, bad_param_peer_addr, True,
1207                       'GG:GG:GG:GG:GG:GG')
1208
1209 def test_fst_ap_start_session_multicast_peer_addr(dev, apdev, test_params):
1210     """FST AP start session - multicast peer address"""
1211     fst_start_session(apdev, test_params, bad_param_peer_addr, True,
1212                       '01:00:11:22:33:44')
1213
1214 def test_fst_ap_start_session_broadcast_peer_addr(dev, apdev, test_params):
1215     """FST AP start session - broadcast peer address"""
1216     fst_start_session(apdev, test_params, bad_param_peer_addr, True,
1217                       'FF:FF:FF:FF:FF:FF')
1218
1219 def test_fst_ap_initiate_session(dev, apdev, test_params):
1220     """FST AP initiate session"""
1221     fst_initiate_session(apdev, test_params, bad_param_none, True)
1222
1223 def test_fst_ap_initiate_session_no_params(dev, apdev, test_params):
1224     """FST AP initiate session - no params"""
1225     fst_initiate_session(apdev, test_params,
1226                          bad_param_session_initiate_no_params, True)
1227
1228 def test_fst_ap_initiate_session_invalid_session_id(dev, apdev, test_params):
1229     """FST AP initiate session - invalid session id"""
1230     fst_initiate_session(apdev, test_params,
1231                          bad_param_session_initiate_bad_session_id, True)
1232
1233 def test_fst_ap_initiate_session_no_new_iface(dev, apdev, test_params):
1234     """FST AP initiate session - no new iface"""
1235     fst_initiate_session(apdev, test_params,
1236                          bad_param_session_initiate_with_no_new_iface_set, True)
1237
1238 def test_fst_ap_initiate_session_bad_peer_addr(dev, apdev, test_params):
1239     """FST AP initiate session - bad peer address"""
1240     fst_initiate_session(apdev, test_params,
1241                          bad_param_session_initiate_with_bad_peer_addr_set,
1242                          True)
1243
1244 def test_fst_ap_initiate_session_request_with_bad_stie(dev, apdev, test_params):
1245     """FST AP initiate session - request with bad stie"""
1246     fst_initiate_session(apdev, test_params,
1247                          bad_param_session_initiate_request_with_bad_stie, True)
1248
1249 def test_fst_ap_initiate_session_response_with_reject(dev, apdev, test_params):
1250     """FST AP initiate session - response with reject"""
1251     fst_initiate_session(apdev, test_params,
1252                          bad_param_session_initiate_response_with_reject, True)
1253
1254 def test_fst_ap_initiate_session_response_with_bad_stie(dev, apdev,
1255                                                         test_params):
1256     """FST AP initiate session - response with bad stie"""
1257     fst_initiate_session(apdev, test_params,
1258                          bad_param_session_initiate_response_with_bad_stie,
1259                          True)
1260
1261 def test_fst_ap_initiate_session_response_with_zero_llt(dev, apdev,
1262                                                         test_params):
1263     """FST AP initiate session - zero llt"""
1264     fst_initiate_session(apdev, test_params,
1265                          bad_param_session_initiate_response_with_zero_llt,
1266                          True)
1267
1268 def test_fst_ap_initiate_session_stt_no_response(dev, apdev, test_params):
1269     """FST AP initiate session - stt no response"""
1270     fst_initiate_session(apdev, test_params,
1271                          bad_param_session_initiate_stt_no_response, True)
1272
1273 def test_fst_ap_initiate_session_concurrent_setup_request(dev, apdev,
1274                                                           test_params):
1275     """FST AP initiate session - concurrent setup request"""
1276     fst_initiate_session(apdev, test_params,
1277                          bad_param_session_initiate_concurrent_setup_request,
1278                          True)
1279
1280 def test_fst_ap_session_request_with_no_session(dev, apdev, test_params):
1281     """FST AP session request with no session"""
1282     fst_send_unexpected_frame(apdev, test_params, frame_type_session_request,
1283                               True)
1284
1285 def test_fst_ap_session_response_accept_with_no_session(dev, apdev,
1286                                                         test_params):
1287     """FST AP session response accept with no session"""
1288     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1289                               True, "accept")
1290
1291 def test_fst_ap_session_response_reject_with_no_session(dev, apdev,
1292                                                         test_params):
1293     """FST AP session response reject with no session"""
1294     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1295                               True, "reject")
1296
1297 def test_fst_ap_ack_request_with_no_session(dev, apdev, test_params):
1298     """FST AP ack request with no session"""
1299     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_request, True)
1300
1301 def test_fst_ap_ack_response_with_no_session(dev, apdev, test_params):
1302     """FST AP ack response with no session"""
1303     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_response, True)
1304
1305 def test_fst_ap_tear_down_response_with_no_session(dev, apdev, test_params):
1306     """FST AP tear down response with no session"""
1307     fst_send_unexpected_frame(apdev, test_params, frame_type_tear_down, True)
1308
1309 def test_fst_ap_transfer_session(dev, apdev, test_params):
1310     """FST AP transfer session"""
1311     fst_transfer_session(apdev, test_params, bad_param_none, True)
1312
1313 def test_fst_ap_transfer_session_no_params(dev, apdev, test_params):
1314     """FST AP transfer session - no params"""
1315     fst_transfer_session(apdev, test_params,
1316                          bad_param_session_transfer_no_params, True)
1317
1318 def test_fst_ap_transfer_session_bad_session_id(dev, apdev, test_params):
1319     """FST AP transfer session - bad session id"""
1320     fst_transfer_session(apdev, test_params,
1321                          bad_param_session_transfer_bad_session_id, True)
1322
1323 def test_fst_ap_transfer_session_setup_skipped(dev, apdev, test_params):
1324     """FST AP transfer session - setup skipped"""
1325     fst_transfer_session(apdev, test_params,
1326                          bad_param_session_transfer_setup_skipped, True)
1327
1328 def test_fst_ap_ack_request_with_session_not_set_up(dev, apdev, test_params):
1329     """FST AP ack request with session not set up"""
1330     fst_bad_transfer(apdev, test_params,
1331                      bad_scenario_ack_req_session_not_set_up, True)
1332
1333 def test_fst_ap_ack_request_with_session_not_established_init_side(dev, apdev,
1334                                                                    test_params):
1335     """FST AP ack request with session not established init side"""
1336     fst_bad_transfer(apdev, test_params,
1337                      bad_scenario_ack_req_session_not_established_init_side,
1338                      True)
1339
1340 def test_fst_ap_ack_request_with_session_not_established_resp_side(dev, apdev,
1341                                                                    test_params):
1342     """FST AP ack request with session not established resp side"""
1343     fst_bad_transfer(apdev, test_params,
1344                      bad_scenario_ack_req_session_not_established_resp_side,
1345                      True)
1346
1347 def test_fst_ap_ack_request_with_bad_fsts_id(dev, apdev, test_params):
1348     """FST AP ack request with bad fsts id"""
1349     fst_bad_transfer(apdev, test_params, bad_scenario_ack_req_bad_fsts_id, True)
1350
1351 def test_fst_ap_ack_response_with_session_not_set_up(dev, apdev, test_params):
1352     """FST AP ack response with session not set up"""
1353     fst_bad_transfer(apdev, test_params,
1354                      bad_scenario_ack_resp_session_not_set_up, True)
1355
1356 def test_fst_ap_ack_response_with_session_not_established_init_side(dev, apdev, test_params):
1357     """FST AP ack response with session not established init side"""
1358     fst_bad_transfer(apdev, test_params,
1359                      bad_scenario_ack_resp_session_not_established_init_side,
1360                      True)
1361
1362 def test_fst_ap_ack_response_with_session_not_established_resp_side(dev, apdev, test_params):
1363     """FST AP ack response with session not established resp side"""
1364     fst_bad_transfer(apdev, test_params,
1365                      bad_scenario_ack_resp_session_not_established_resp_side,
1366                      True)
1367
1368 def test_fst_ap_ack_response_with_no_ack_request(dev, apdev, test_params):
1369     """FST AP ack response with no ack request"""
1370     fst_bad_transfer(apdev, test_params, bad_scenario_ack_resp_no_ack_req, True)
1371
1372 def test_fst_ap_tear_down_session(dev, apdev, test_params):
1373     """FST AP tear down session"""
1374     fst_tear_down_session(apdev, test_params, bad_param_none, True)
1375
1376 def test_fst_ap_tear_down_session_no_params(dev, apdev, test_params):
1377     """FST AP tear down session - no params"""
1378     fst_tear_down_session(apdev, test_params,
1379                           bad_param_session_teardown_no_params, True)
1380
1381 def test_fst_ap_tear_down_session_bad_session_id(dev, apdev, test_params):
1382     """FST AP tear down session - bad session id"""
1383     fst_tear_down_session(apdev, test_params,
1384                           bad_param_session_teardown_bad_session_id, True)
1385
1386 def test_fst_ap_tear_down_session_setup_skipped(dev, apdev, test_params):
1387     """FST AP tear down session - setup skipped"""
1388     fst_tear_down_session(apdev, test_params,
1389                           bad_param_session_teardown_setup_skipped, True)
1390
1391 def test_fst_ap_tear_down_session_bad_fsts_id(dev, apdev, test_params):
1392     """FST AP tear down session - bad fsts id"""
1393     fst_tear_down_session(apdev, test_params,
1394                           bad_param_session_teardown_bad_fsts_id, True)
1395
1396 def test_fst_ap_remove_session_not_established(dev, apdev, test_params):
1397     """FST AP remove session - not established"""
1398     fst_remove_session(apdev, test_params,
1399                        remove_scenario_non_established_session, True)
1400
1401 def test_fst_ap_remove_session_established(dev, apdev, test_params):
1402     """FST AP remove session - established"""
1403     fst_remove_session(apdev, test_params,
1404                        remove_scenario_established_session, True)
1405
1406 def test_fst_ap_remove_session_no_params(dev, apdev, test_params):
1407     """FST AP remove session - no params"""
1408     fst_remove_session(apdev, test_params, remove_scenario_no_params, True)
1409
1410 def test_fst_ap_remove_session_bad_session_id(dev, apdev, test_params):
1411     """FST AP remove session - bad session id"""
1412     fst_remove_session(apdev, test_params, remove_scenario_bad_session_id, True)
1413
1414 def test_fst_ap_ctrl_iface(dev, apdev, test_params):
1415     """FST control interface behavior"""
1416     hglobal = hostapd.HostapdGlobal()
1417     start_num_groups = 0
1418     res = hglobal.request("FST-MANAGER LIST_GROUPS")
1419     del hglobal
1420     if "FAIL" not in res:
1421         start_num_groups = len(res.splitlines())
1422
1423     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1424     try:
1425         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1426         initiator = ap1
1427         responder = sta1
1428         initiator.add_peer(responder, None)
1429         initiator.set_fst_parameters(group_id=None)
1430         sid = initiator.add_session()
1431         res = initiator.get_session_params(sid)
1432         logger.info("Initial session params:\n" + str(res))
1433         if res['state'] != 'INITIAL':
1434             raise Exception("Unexpected state: " + res['state'])
1435         initiator.set_fst_parameters(llt=None)
1436         initiator.configure_session(sid, ap2.ifname(), None)
1437         res = initiator.get_session_params(sid)
1438         logger.info("Session params after configuration:\n" + str(res))
1439         res = initiator.iface_peers(initiator.ifname())
1440         logger.info("Interface peers: " + str(res))
1441         if len(res) != 1:
1442             raise Exception("Unexpected number of peers")
1443         res = initiator.get_peer_mbies(initiator.ifname(),
1444                                        initiator.get_new_peer_addr())
1445         logger.info("Peer MB IEs: " + str(res))
1446         res = initiator.list_ifaces()
1447         logger.info("Interfaces: " + str(res))
1448         if len(res) != 2:
1449             raise Exception("Unexpected number of interfaces")
1450         res = initiator.list_groups()
1451         logger.info("Groups: " + str(res))
1452         if len(res) != 1 + start_num_groups:
1453             raise Exception("Unexpected number of groups")
1454
1455         tests = [ "LIST_IFACES unknown",
1456                   "LIST_IFACES     unknown2",
1457                   "SESSION_GET 12345678",
1458                   "SESSION_SET " + sid + " unknown=foo",
1459                   "SESSION_RESPOND 12345678 foo",
1460                   "SESSION_RESPOND " + sid,
1461                   "SESSION_RESPOND " + sid + " foo",
1462                   "TEST_REQUEST foo",
1463                   "TEST_REQUEST SEND_SETUP_REQUEST",
1464                   "TEST_REQUEST SEND_SETUP_REQUEST foo",
1465                   "TEST_REQUEST SEND_SETUP_RESPONSE",
1466                   "TEST_REQUEST SEND_SETUP_RESPONSE foo",
1467                   "TEST_REQUEST SEND_ACK_REQUEST",
1468                   "TEST_REQUEST SEND_ACK_REQUEST foo",
1469                   "TEST_REQUEST SEND_ACK_RESPONSE",
1470                   "TEST_REQUEST SEND_ACK_RESPONSE foo",
1471                   "TEST_REQUEST SEND_TEAR_DOWN",
1472                   "TEST_REQUEST SEND_TEAR_DOWN foo",
1473                   "TEST_REQUEST GET_FSTS_ID",
1474                   "TEST_REQUEST GET_FSTS_ID foo",
1475                   "TEST_REQUEST GET_LOCAL_MBIES",
1476                   "TEST_REQUEST GET_LOCAL_MBIES foo",
1477                   "GET_PEER_MBIES",
1478                   "GET_PEER_MBIES ",
1479                   "GET_PEER_MBIES unknown",
1480                   "GET_PEER_MBIES unknown unknown",
1481                   "GET_PEER_MBIES unknown  " + initiator.get_new_peer_addr(),
1482                   "GET_PEER_MBIES " + initiator.ifname() + " 01:ff:ff:ff:ff:ff",
1483                   "GET_PEER_MBIES " + initiator.ifname() + " 00:ff:ff:ff:ff:ff",
1484                   "GET_PEER_MBIES " + initiator.ifname() + " 00:00:00:00:00:00",
1485                   "IFACE_PEERS",
1486                   "IFACE_PEERS ",
1487                   "IFACE_PEERS unknown",
1488                   "IFACE_PEERS unknown unknown",
1489                   "IFACE_PEERS " + initiator.fst_group,
1490                   "IFACE_PEERS " + initiator.fst_group + " unknown" ]
1491         for t in tests:
1492             if "FAIL" not in initiator.grequest("FST-MANAGER " + t):
1493                 raise Exception("Unexpected response for invalid FST-MANAGER command " + t)
1494         if "UNKNOWN FST COMMAND" not in initiator.grequest("FST-MANAGER unknown"):
1495             raise Exception("Unexpected response for unknown FST-MANAGER command")
1496
1497         tests = [ "FST-DETACH", "FST-DETACH ", "FST-DETACH unknown",
1498                   "FST-ATTACH", "FST-ATTACH ", "FST-ATTACH unknown",
1499                   "FST-ATTACH unknown unknown" ]
1500         for t in tests:
1501             if "FAIL" not in initiator.grequest(t):
1502                 raise Exception("Unexpected response for invalid command " + t)
1503
1504         try:
1505             # Trying to add same interface again needs to fail.
1506             ap1.send_iface_attach_request(ap1.iface, ap1.fst_group,
1507                                           ap1.fst_llt, ap1.fst_pri)
1508             raise Exception("Duplicate FST-ATTACH succeeded")
1509         except Exception, e:
1510             if not str(e).startswith("Cannot attach"):
1511                 raise
1512
1513         try:
1514             ap1.get_fsts_id_by_sid("123")
1515         except Exception, e:
1516             if not str(e).startswith("Cannot get fsts_id for sid"):
1517                 raise
1518     finally:
1519         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1520         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1521
1522 def test_fst_ap_start_session_oom(dev, apdev, test_params):
1523     """FST AP setup failing due to OOM"""
1524     ap1 = fst_module_aux.FstAP(apdev[0]['ifname'], 'fst_11a', 'a',
1525                                fst_test_common.fst_test_def_chan_a,
1526                                fst_test_common.fst_test_def_group,
1527                                fst_test_common.fst_test_def_prio_low,
1528                                fst_test_common.fst_test_def_llt)
1529     ap1.start()
1530     with alloc_fail(ap1, 1, "fst_iface_create"):
1531         ap2_started = False
1532         try:
1533             ap2 = fst_module_aux.FstAP(apdev[1]['ifname'], 'fst_11g', 'b',
1534                                        fst_test_common.fst_test_def_chan_g,
1535                                        fst_test_common.fst_test_def_group,
1536                                        fst_test_common.fst_test_def_prio_high,
1537                                        fst_test_common.fst_test_def_llt)
1538             try:
1539                 # This will fail in fst_iface_create() OOM
1540                 ap2.start()
1541             except:
1542                 pass
1543         finally:
1544             ap1.stop()
1545             try:
1546                 ap2.stop()
1547             except:
1548                 pass
1549
1550 # STA side FST module tests
1551
1552 def test_fst_sta_start_session(dev, apdev, test_params):
1553     """FST STA start session"""
1554     fst_start_session(apdev, test_params, bad_param_none, False)
1555
1556 def test_fst_sta_start_session_no_add_params(dev, apdev, test_params):
1557     """FST STA start session - no add params"""
1558     fst_start_session(apdev, test_params, bad_param_session_add_no_params,
1559                       False)
1560
1561 def test_fst_sta_start_session_bad_group_id(dev, apdev, test_params):
1562     """FST STA start session - bad group id"""
1563     fst_start_session(apdev, test_params, bad_param_group_id, False)
1564
1565 def test_fst_sta_start_session_no_set_params(dev, apdev, test_params):
1566     """FST STA start session - no set params"""
1567     fst_start_session(apdev, test_params, bad_param_session_set_no_params,
1568                       False)
1569
1570 def test_fst_sta_start_session_set_unknown_param(dev, apdev, test_params):
1571     """FST STA start session - set unknown param"""
1572     fst_start_session(apdev, test_params, bad_param_session_set_unknown_param,
1573                       False)
1574
1575 def test_fst_sta_start_session_bad_session_id(dev, apdev, test_params):
1576     """FST STA start session - bad session id"""
1577     fst_start_session(apdev, test_params, bad_param_session_id, False)
1578
1579 def test_fst_sta_start_session_bad_new_iface(dev, apdev, test_params):
1580     """FST STA start session - bad new iface"""
1581     fst_start_session(apdev, test_params, bad_param_new_iface, False)
1582
1583 def test_fst_sta_start_session_bad_old_iface(dev, apdev, test_params):
1584     """FST STA start session - bad old iface"""
1585     fst_start_session(apdev, test_params, bad_param_old_iface, False)
1586
1587 def test_fst_sta_start_session_negative_llt(dev, apdev, test_params):
1588     """FST STA start session - negative llt"""
1589     fst_start_session(apdev, test_params, bad_param_negative_llt, False)
1590
1591 def test_fst_sta_start_session_zero_llt(dev, apdev, test_params):
1592     """FST STA start session - zero llt"""
1593     fst_start_session(apdev, test_params, bad_param_zero_llt, False)
1594
1595 def test_fst_sta_start_session_llt_too_big(dev, apdev, test_params):
1596     """FST STA start session - llt too large"""
1597     fst_start_session(apdev, test_params, bad_param_llt_too_big, False)
1598
1599 def test_fst_sta_start_session_invalid_peer_addr(dev, apdev, test_params):
1600     """FST STA start session - invalid peer address"""
1601     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1602                       'GG:GG:GG:GG:GG:GG')
1603
1604 def test_fst_sta_start_session_multicast_peer_addr(dev, apdev, test_params):
1605     """FST STA start session - multicast peer address"""
1606     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1607                       '11:00:11:22:33:44')
1608
1609 def test_fst_sta_start_session_broadcast_peer_addr(dev, apdev, test_params):
1610     """FST STA start session - broadcast peer addr"""
1611     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1612                       'FF:FF:FF:FF:FF:FF')
1613
1614 def test_fst_sta_initiate_session(dev, apdev, test_params):
1615     """FST STA initiate session"""
1616     fst_initiate_session(apdev, test_params, bad_param_none, False)
1617
1618 def test_fst_sta_initiate_session_no_params(dev, apdev, test_params):
1619     """FST STA initiate session - no params"""
1620     fst_initiate_session(apdev, test_params,
1621                          bad_param_session_initiate_no_params, False)
1622
1623 def test_fst_sta_initiate_session_invalid_session_id(dev, apdev, test_params):
1624     """FST STA initiate session - invalid session id"""
1625     fst_initiate_session(apdev, test_params,
1626                          bad_param_session_initiate_bad_session_id, False)
1627
1628 def test_fst_sta_initiate_session_no_new_iface(dev, apdev, test_params):
1629     """FST STA initiate session - no new iface"""
1630     fst_initiate_session(apdev, test_params,
1631                          bad_param_session_initiate_with_no_new_iface_set,
1632                          False)
1633
1634 def test_fst_sta_initiate_session_bad_peer_addr(dev, apdev, test_params):
1635     """FST STA initiate session - bad peer address"""
1636     fst_initiate_session(apdev, test_params,
1637                          bad_param_session_initiate_with_bad_peer_addr_set,
1638                          False)
1639
1640 def test_fst_sta_initiate_session_request_with_bad_stie(dev, apdev,
1641                                                         test_params):
1642     """FST STA initiate session - request with bad stie"""
1643     fst_initiate_session(apdev, test_params,
1644                          bad_param_session_initiate_request_with_bad_stie,
1645                          False)
1646
1647 def test_fst_sta_initiate_session_response_with_reject(dev, apdev, test_params):
1648     """FST STA initiate session - response with reject"""
1649     fst_initiate_session(apdev, test_params, bad_param_session_initiate_response_with_reject, False)
1650
1651 def test_fst_sta_initiate_session_response_with_bad_stie(dev, apdev, test_params):
1652     """FST STA initiate session - response with bad stie"""
1653     fst_initiate_session(apdev, test_params,
1654                          bad_param_session_initiate_response_with_bad_stie,
1655                          False)
1656
1657 def test_fst_sta_initiate_session_response_with_zero_llt(dev, apdev,
1658                                                          test_params):
1659     """FST STA initiate session - response with zero llt"""
1660     fst_initiate_session(apdev, test_params,
1661                          bad_param_session_initiate_response_with_zero_llt,
1662                          False)
1663
1664 def test_fst_sta_initiate_session_stt_no_response(dev, apdev, test_params):
1665     """FST STA initiate session - stt no response"""
1666     fst_initiate_session(apdev, test_params,
1667                          bad_param_session_initiate_stt_no_response, False)
1668
1669 def test_fst_sta_initiate_session_concurrent_setup_request(dev, apdev,
1670                                                            test_params):
1671     """FST STA initiate session - concurrent setup request"""
1672     fst_initiate_session(apdev, test_params,
1673                          bad_param_session_initiate_concurrent_setup_request,
1674                          False)
1675
1676 def test_fst_sta_session_request_with_no_session(dev, apdev, test_params):
1677     """FST STA session request with no session"""
1678     fst_send_unexpected_frame(apdev, test_params, frame_type_session_request,
1679                               False)
1680
1681 def test_fst_sta_session_response_accept_with_no_session(dev, apdev,
1682                                                          test_params):
1683     """FST STA session response accept with no session"""
1684     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1685                               False, "accept")
1686
1687 def test_fst_sta_session_response_reject_with_no_session(dev, apdev,
1688                                                          test_params):
1689     """FST STA session response reject with no session"""
1690     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1691                               False, "reject")
1692
1693 def test_fst_sta_ack_request_with_no_session(dev, apdev, test_params):
1694     """FST STA ack request with no session"""
1695     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_request, False)
1696
1697 def test_fst_sta_ack_response_with_no_session(dev, apdev, test_params):
1698     """FST STA ack response with no session"""
1699     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_response,
1700                               False)
1701
1702 def test_fst_sta_tear_down_response_with_no_session(dev, apdev, test_params):
1703     """FST STA tear down response with no session"""
1704     fst_send_unexpected_frame(apdev, test_params, frame_type_tear_down, False)
1705
1706 def test_fst_sta_transfer_session(dev, apdev, test_params):
1707     """FST STA transfer session"""
1708     fst_transfer_session(apdev, test_params, bad_param_none, False)
1709
1710 def test_fst_sta_transfer_session_no_params(dev, apdev, test_params):
1711     """FST STA transfer session - no params"""
1712     fst_transfer_session(apdev, test_params,
1713                          bad_param_session_transfer_no_params, False)
1714
1715 def test_fst_sta_transfer_session_bad_session_id(dev, apdev, test_params):
1716     """FST STA transfer session - bad session id"""
1717     fst_transfer_session(apdev, test_params,
1718                          bad_param_session_transfer_bad_session_id, False)
1719
1720 def test_fst_sta_transfer_session_setup_skipped(dev, apdev, test_params):
1721     """FST STA transfer session - setup skipped"""
1722     fst_transfer_session(apdev, test_params,
1723                          bad_param_session_transfer_setup_skipped, False)
1724
1725 def test_fst_sta_ack_request_with_session_not_set_up(dev, apdev, test_params):
1726     """FST STA ack request with session not set up"""
1727     fst_bad_transfer(apdev, test_params,
1728                      bad_scenario_ack_req_session_not_set_up, False)
1729
1730 def test_fst_sta_ack_request_with_session_not_established_init_side(dev, apdev, test_params):
1731     """FST STA ack request with session not established init side"""
1732     fst_bad_transfer(apdev, test_params,
1733                      bad_scenario_ack_req_session_not_established_init_side,
1734                      False)
1735
1736 def test_fst_sta_ack_request_with_session_not_established_resp_side(dev, apdev, test_params):
1737     """FST STA ack request with session not established resp side"""
1738     fst_bad_transfer(apdev, test_params,
1739                      bad_scenario_ack_req_session_not_established_resp_side,
1740                      False)
1741
1742 def test_fst_sta_ack_request_with_bad_fsts_id(dev, apdev, test_params):
1743     """FST STA ack request with bad fsts id"""
1744     fst_bad_transfer(apdev, test_params, bad_scenario_ack_req_bad_fsts_id,
1745                      False)
1746
1747 def test_fst_sta_ack_response_with_session_not_set_up(dev, apdev, test_params):
1748     """FST STA ack response with session not set up"""
1749     fst_bad_transfer(apdev, test_params,
1750                      bad_scenario_ack_resp_session_not_set_up, False)
1751
1752 def test_fst_sta_ack_response_with_session_not_established_init_side(dev, apdev, test_params):
1753     """FST STA ack response with session not established init side"""
1754     fst_bad_transfer(apdev, test_params,
1755                      bad_scenario_ack_resp_session_not_established_init_side,
1756                      False)
1757
1758 def test_fst_sta_ack_response_with_session_not_established_resp_side(dev, apdev, test_params):
1759     """FST STA ack response with session not established resp side"""
1760     fst_bad_transfer(apdev, test_params,
1761                      bad_scenario_ack_resp_session_not_established_resp_side,
1762                      False)
1763
1764 def test_fst_sta_ack_response_with_no_ack_request(dev, apdev, test_params):
1765     """FST STA ack response with no ack request"""
1766     fst_bad_transfer(apdev, test_params, bad_scenario_ack_resp_no_ack_req,
1767                      False)
1768
1769 def test_fst_sta_tear_down_session(dev, apdev, test_params):
1770     """FST STA tear down session"""
1771     fst_tear_down_session(apdev, test_params, bad_param_none, False)
1772
1773 def test_fst_sta_tear_down_session_no_params(dev, apdev, test_params):
1774     """FST STA tear down session - no params"""
1775     fst_tear_down_session(apdev, test_params,
1776                           bad_param_session_teardown_no_params, False)
1777
1778 def test_fst_sta_tear_down_session_bad_session_id(dev, apdev, test_params):
1779     """FST STA tear down session - bad session id"""
1780     fst_tear_down_session(apdev, test_params,
1781                           bad_param_session_teardown_bad_session_id, False)
1782
1783 def test_fst_sta_tear_down_session_setup_skipped(dev, apdev, test_params):
1784     """FST STA tear down session - setup skipped"""
1785     fst_tear_down_session(apdev, test_params,
1786                           bad_param_session_teardown_setup_skipped, False)
1787
1788 def test_fst_sta_tear_down_session_bad_fsts_id(dev, apdev, test_params):
1789     """FST STA tear down session - bad fsts id"""
1790     fst_tear_down_session(apdev, test_params,
1791                           bad_param_session_teardown_bad_fsts_id, False)
1792
1793 def test_fst_sta_remove_session_not_established(dev, apdev, test_params):
1794     """FST STA tear down session - not established"""
1795     fst_remove_session(apdev, test_params,
1796                        remove_scenario_non_established_session, False)
1797
1798 def test_fst_sta_remove_session_established(dev, apdev, test_params):
1799     """FST STA remove session - established"""
1800     fst_remove_session(apdev, test_params,
1801                        remove_scenario_established_session, False)
1802
1803 def test_fst_sta_remove_session_no_params(dev, apdev, test_params):
1804     """FST STA remove session - no params"""
1805     fst_remove_session(apdev, test_params, remove_scenario_no_params, False)
1806
1807 def test_fst_sta_remove_session_bad_session_id(dev, apdev, test_params):
1808     """FST STA remove session - bad session id"""
1809     fst_remove_session(apdev, test_params, remove_scenario_bad_session_id,
1810                        False)
1811
1812 def test_fst_rsn_ap_transfer_session(dev, apdev, test_params):
1813     """FST RSN AP transfer session"""
1814     fst_transfer_session(apdev, test_params, bad_param_none, True, rsn=True)
1815
1816 MGMT_SUBTYPE_ACTION = 13
1817 ACTION_CATEG_FST = 18
1818 FST_ACTION_SETUP_REQUEST = 0
1819 FST_ACTION_SETUP_RESPONSE = 1
1820 FST_ACTION_TEAR_DOWN = 2
1821 FST_ACTION_ACK_REQUEST = 3
1822 FST_ACTION_ACK_RESPONSE = 4
1823 FST_ACTION_ON_CHANNEL_TUNNEL = 5
1824
1825 def hostapd_tx_and_status(hapd, msg):
1826     hapd.set("ext_mgmt_frame_handling", "1")
1827     hapd.mgmt_tx(msg)
1828     ev = hapd.wait_event([ "MGMT-TX-STATUS" ], timeout=1)
1829     if ev is None or "ok=1" not in ev:
1830         raise Exception("No ACK")
1831     hapd.set("ext_mgmt_frame_handling", "0")
1832
1833 def test_fst_proto(dev, apdev, test_params):
1834     """FST protocol testing"""
1835     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1836     try:
1837         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1838         hapd = ap1.get_instance()
1839         sta = sta1.get_instance()
1840         dst = sta.own_addr()
1841         src = apdev[0]['bssid']
1842
1843         msg = {}
1844         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1845         msg['da'] = dst
1846         msg['sa'] = src
1847         msg['bssid'] = src
1848
1849         # unknown FST Action (255) received!
1850         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST, 255)
1851         hostapd_tx_and_status(hapd, msg)
1852
1853         # FST Request dropped: too short
1854         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1855                                      FST_ACTION_SETUP_REQUEST)
1856         hostapd_tx_and_status(hapd, msg)
1857
1858         # FST Request dropped: invalid STIE (EID)
1859         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1860                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1861                                      163, 11, 0, 0, 0, 0, 0, 0, 0, 0)
1862         hostapd_tx_and_status(hapd, msg)
1863
1864         # FST Request dropped: invalid STIE (Len)
1865         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1866                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1867                                      164, 10, 0, 0, 0, 0, 0, 0, 0, 0)
1868         hostapd_tx_and_status(hapd, msg)
1869
1870         # FST Request dropped: new and old band IDs are the same
1871         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1872                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1873                                      164, 11, 0, 0, 0, 0, 0, 0, 0, 0)
1874         hostapd_tx_and_status(hapd, msg)
1875
1876         ifaces = sta1.list_ifaces()
1877         id = int(ifaces[0]['name'].split('|')[1])
1878         # FST Request dropped: new iface not found (new_band_id mismatch)
1879         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1880                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1881                                      164, 11, 0, 0, id + 1, 0, 0, 0, 0, 0)
1882         hostapd_tx_and_status(hapd, msg)
1883
1884         # FST Action 'Setup Response' dropped: no session in progress found
1885         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1886                                      FST_ACTION_SETUP_RESPONSE)
1887         hostapd_tx_and_status(hapd, msg)
1888
1889         # Create session
1890         initiator = ap1
1891         responder = sta1
1892         new_iface = ap2.ifname()
1893         new_peer_addr = ap2.get_actual_peer_addr()
1894         resp_newif = sta2.ifname()
1895         peeraddr = None
1896         initiator.add_peer(responder, peeraddr, new_peer_addr)
1897         sid = initiator.add_session()
1898         initiator.configure_session(sid, new_iface)
1899         initiator.initiate_session(sid, "accept")
1900
1901         # FST Response dropped due to wrong state: SETUP_COMPLETION
1902         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1903                                      FST_ACTION_SETUP_RESPONSE)
1904         hostapd_tx_and_status(hapd, msg)
1905
1906         # Too short FST Tear Down dropped
1907         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1908                                      FST_ACTION_TEAR_DOWN)
1909         hostapd_tx_and_status(hapd, msg)
1910
1911         # tear down for wrong FST Setup ID (0)
1912         msg['payload'] = struct.pack("<BBL", ACTION_CATEG_FST,
1913                                      FST_ACTION_TEAR_DOWN, 0)
1914         hostapd_tx_and_status(hapd, msg)
1915
1916         # Ack received on wrong interface
1917         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1918                                      FST_ACTION_ACK_REQUEST)
1919         hostapd_tx_and_status(hapd, msg)
1920
1921         # Ack Response in inappropriate session state (SETUP_COMPLETION)
1922         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1923                                      FST_ACTION_ACK_RESPONSE)
1924         hostapd_tx_and_status(hapd, msg)
1925
1926         # Unsupported FST Action frame (On channel tunnel)
1927         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1928                                      FST_ACTION_ON_CHANNEL_TUNNEL)
1929         hostapd_tx_and_status(hapd, msg)
1930
1931         # FST Request dropped: new iface not found (new_band_id match)
1932         # FST Request dropped due to MAC comparison
1933         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1934                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1935                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
1936         hostapd_tx_and_status(hapd, msg)
1937
1938         hapd2 = ap2.get_instance()
1939         dst2 = sta2.get_instance().own_addr()
1940         src2 = apdev[1]['bssid']
1941
1942         msg2 = {}
1943         msg2['fc'] = MGMT_SUBTYPE_ACTION << 4
1944         msg2['da'] = dst2
1945         msg2['sa'] = src2
1946         msg2['bssid'] = src2
1947         # FST Response dropped: wlan6 is not the old iface
1948         msg2['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1949                                       FST_ACTION_SETUP_RESPONSE)
1950         hostapd_tx_and_status(hapd2, msg2)
1951
1952         sta.dump_monitor()
1953
1954         group = ap1.fst_group
1955         ap1.send_iface_detach_request(ap1.iface)
1956
1957         sta.flush_scan_cache()
1958         sta.request("REASSOCIATE")
1959         sta.wait_connected()
1960
1961         # FST Request dropped due to no interface connection
1962         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1963                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1964                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
1965         hostapd_tx_and_status(hapd, msg)
1966     finally:
1967         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1968         try:
1969             fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1970         except:
1971             pass
1972
1973 def test_fst_setup_response_proto(dev, apdev, test_params):
1974     """FST protocol testing for Setup Response"""
1975     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1976     try:
1977         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1978         hapd = ap1.get_instance()
1979         sta = sta1.get_instance()
1980         dst = sta.own_addr()
1981         src = apdev[0]['bssid']
1982
1983         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
1984         sta1.set_fst_parameters(llt='0')
1985         sid = sta1.add_session()
1986         sta1.configure_session(sid, sta2.ifname())
1987         sta1.initiate_session(sid, "")
1988
1989         msg = {}
1990         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1991         msg['da'] = dst
1992         msg['sa'] = src
1993         msg['bssid'] = src
1994
1995         # Too short FST Response dropped
1996         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1997                                      FST_ACTION_SETUP_RESPONSE)
1998         hostapd_tx_and_status(hapd, msg)
1999
2000         # FST Response dropped: invalid STIE (EID)
2001         dialog_token = 1
2002         status_code = 0
2003         id = 0
2004         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2005                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2006                                      status_code,
2007                                      163, 11, 0, 0, id, 0, 0, 0, 0, 0)
2008         hostapd_tx_and_status(hapd, msg)
2009
2010         # FST Response dropped: invalid STIE (Len)
2011         dialog_token = 1
2012         status_code = 0
2013         id = 0
2014         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2015                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2016                                      status_code,
2017                                      164, 10, 0, 0, id, 0, 0, 0, 0, 0)
2018         hostapd_tx_and_status(hapd, msg)
2019
2020         # FST Response dropped due to wrong dialog token
2021         dialog_token = 123
2022         status_code = 0
2023         id = 0
2024         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2025                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2026                                      status_code,
2027                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
2028         hostapd_tx_and_status(hapd, msg)
2029
2030         # FST Response dropped due to wrong FST Session ID
2031         dialog_token = 1
2032         status_code = 0
2033         id = 1
2034         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2035                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2036                                      status_code,
2037                                      164, 11, int(sid) + 123456,
2038                                      0, id, 0, 0, 0, 0, 0)
2039         hostapd_tx_and_status(hapd, msg)
2040
2041         # FST Response with non-zero status code
2042         dialog_token = 1
2043         status_code = 1
2044         id = 1
2045         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2046                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2047                                      status_code,
2048                                      164, 11, int(sid), 0, id, 0, 0, 0, 0, 0)
2049         hostapd_tx_and_status(hapd, msg)
2050     finally:
2051         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2052         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2053
2054 def test_fst_ack_response_proto(dev, apdev, test_params):
2055     """FST protocol testing for Ack Response"""
2056     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2057     try:
2058         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2059         hapd = ap2.get_instance()
2060         sta = sta2.get_instance()
2061         dst = sta.own_addr()
2062         src = apdev[1]['bssid']
2063
2064         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
2065         sta1.set_fst_parameters(llt='0')
2066         sid = sta1.add_session()
2067         sta1.configure_session(sid, sta2.ifname())
2068
2069         s = sta1.grequest("FST-MANAGER SESSION_INITIATE "+ sid)
2070         if not s.startswith('OK'):
2071             raise Exception("Cannot initiate fst session: %s" % s)
2072         ev = sta1.peer_obj.wait_gevent([ "FST-EVENT-SESSION" ], timeout=5)
2073         if ev is None:
2074             raise Exception("No FST-EVENT-SESSION received")
2075         event = fst_module_aux.parse_fst_session_event(ev)
2076         if event == None:
2077             raise Exception("Unrecognized FST event: " % ev)
2078         if event['type'] != 'EVENT_FST_SETUP':
2079             raise Exception("Expected FST_SETUP event, got: " + event['type'])
2080         ev = sta1.peer_obj.wait_gevent(["FST-EVENT-SESSION"], timeout=5)
2081         if ev is None:
2082             raise Exception("No FST-EVENT-SESSION received")
2083         event = fst_module_aux.parse_fst_session_event(ev)
2084         if event == None:
2085             raise Exception("Unrecognized FST event: " % ev)
2086         if event['type'] != 'EVENT_FST_SESSION_STATE':
2087             raise Exception("Expected EVENT_FST_SESSION_STATE event, got: " + event['type'])
2088         if event['new_state'] != "SETUP_COMPLETION":
2089             raise Exception("Expected new state SETUP_COMPLETION, got: " + event['new_state'])
2090
2091         hapd.set("ext_mgmt_frame_handling", "1")
2092         s = sta1.peer_obj.grequest("FST-MANAGER SESSION_RESPOND "+ event['id'] + " accept")
2093         if not s.startswith('OK'):
2094             raise Exception("Error session_respond: %s" % s)
2095         req = hapd.mgmt_rx()
2096         if req is None:
2097             raise Exception("No Ack Request seen")
2098         msg = {}
2099         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
2100         msg['da'] = dst
2101         msg['sa'] = src
2102         msg['bssid'] = src
2103
2104         # Too short FST Ack Response dropped
2105         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
2106                                      FST_ACTION_ACK_RESPONSE)
2107         hapd.mgmt_tx(msg)
2108         ev = hapd.wait_event([ "MGMT-TX-STATUS" ], timeout=1)
2109         if ev is None or "ok=1" not in ev:
2110             raise Exception("No ACK")
2111
2112         # Ack Response for wrong FSt Setup ID
2113         msg['payload'] = struct.pack("<BBBL", ACTION_CATEG_FST,
2114                                      FST_ACTION_ACK_RESPONSE,
2115                                      0, int(sid) + 123456)
2116         hostapd_tx_and_status(hapd, msg)
2117     finally:
2118         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2119         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2120
2121 def test_fst_ap_config_oom(dev, apdev, test_params):
2122     """FST AP configuration and OOM"""
2123     ap1 = fst_module_aux.FstAP(apdev[0]['ifname'], 'fst_11a', 'a',
2124                                fst_test_common.fst_test_def_chan_a,
2125                                fst_test_common.fst_test_def_group,
2126                                fst_test_common.fst_test_def_prio_low)
2127     hapd = ap1.start(return_early=True)
2128     with alloc_fail(hapd, 1, "fst_group_create"):
2129         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2130         if not res.startswith("FAIL"):
2131             raise Exception("FST-ATTACH succeeded unexpectedly")
2132
2133     with alloc_fail(hapd, 1, "fst_iface_create"):
2134         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2135         if not res.startswith("FAIL"):
2136             raise Exception("FST-ATTACH succeeded unexpectedly")
2137
2138     with alloc_fail(hapd, 1, "fst_group_create_mb_ie"):
2139         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2140         # This is allowed to complete currently
2141
2142     ap1.stop()
2143
2144 def test_fst_send_oom(dev, apdev, test_params):
2145     """FST send action OOM"""
2146     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2147     try:
2148         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2149         hapd = ap1.get_instance()
2150         sta = sta1.get_instance()
2151         dst = sta.own_addr()
2152         src = apdev[0]['bssid']
2153
2154         # Create session
2155         initiator = ap1
2156         responder = sta1
2157         new_iface = ap2.ifname()
2158         new_peer_addr = ap2.get_actual_peer_addr()
2159         resp_newif = sta2.ifname()
2160         peeraddr = None
2161         initiator.add_peer(responder, peeraddr, new_peer_addr)
2162         sid = initiator.add_session()
2163         initiator.configure_session(sid, new_iface)
2164         with alloc_fail(hapd, 1, "fst_session_send_action"):
2165             res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2166             if not res.startswith("FAIL"):
2167                 raise Exception("Unexpected SESSION_INITIATE result")
2168
2169         res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2170         if not res.startswith("OK"):
2171             raise Exception("SESSION_INITIATE failed")
2172
2173         tests = [ "", "foo", sid, sid + " foo", sid + " foo=bar" ]
2174         for t in tests:
2175             res = initiator.grequest("FST-MANAGER SESSION_SET " + t)
2176             if not res.startswith("FAIL"):
2177                 raise Exception("Invalid SESSION_SET accepted")
2178
2179         with alloc_fail(hapd, 1, "fst_session_send_action"):
2180             res = initiator.grequest("FST-MANAGER SESSION_TEARDOWN " + sid)
2181             if not res.startswith("FAIL"):
2182                 raise Exception("Unexpected SESSION_TEARDOWN result")
2183     finally:
2184         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2185         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2186
2187 def test_fst_session_oom(dev, apdev, test_params):
2188     """FST session create OOM"""
2189     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2190     try:
2191         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2192         hapd = ap1.get_instance()
2193         sta = sta1.get_instance()
2194         dst = sta.own_addr()
2195         src = apdev[0]['bssid']
2196
2197         # Create session
2198         initiator = ap1
2199         responder = sta1
2200         new_iface = ap2.ifname()
2201         new_peer_addr = ap2.get_actual_peer_addr()
2202         resp_newif = sta2.ifname()
2203         peeraddr = None
2204         initiator.add_peer(responder, peeraddr, new_peer_addr)
2205         with alloc_fail(hapd, 1, "fst_session_create"):
2206             sid = initiator.grequest("FST-MANAGER SESSION_ADD " + initiator.fst_group)
2207             if not sid.startswith("FAIL"):
2208                 raise Exception("Unexpected SESSION_ADD success")
2209         sid = initiator.add_session()
2210         initiator.configure_session(sid, new_iface)
2211         with alloc_fail(sta, 1, "fst_session_create"):
2212             res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2213             if not res.startswith("OK"):
2214                 raise Exception("Unexpected SESSION_INITIATE result")
2215     finally:
2216         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2217         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2218
2219 def test_fst_attach_zero_llt(dev, apdev):
2220     """FST attach with llt=0"""
2221     sta1 = fst_module_aux.FstSTA('wlan5', fst_test_common.fst_test_def_group,
2222                                  "100", "0")
2223     sta1.start()
2224     sta1.stop()
2225
2226 def test_fst_session_respond_fail(dev, apdev, test_params):
2227     """FST-MANAGER SESSION_RESPOND failure"""
2228     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2229     try:
2230         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2231         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
2232         sid = sta1.add_session()
2233         sta1.configure_session(sid, sta2.ifname())
2234         sta1.send_session_setup_request(sid)
2235         sta1.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
2236         ev = ap1.wait_for_session_event(5, [], ['EVENT_FST_SETUP'])
2237         if not 'id' in ev:
2238             raise Exception("No session id in FST setup event")
2239         # Disconnect STA to make SESSION_RESPOND fail due to no peer found
2240         sta = sta1.get_instance()
2241         sta.request("DISCONNECT")
2242         sta.wait_disconnected()
2243         req = "FST-MANAGER SESSION_RESPOND %s reject" % ev['id']
2244         s = ap1.grequest(req)
2245         if not s.startswith("FAIL"):
2246             raise Exception("SESSION_RESPOND succeeded unexpectedly")
2247     finally:
2248         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2249         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2250
2251 def fst_session_set(dev, sid, param, value):
2252     cmd = "FST-MANAGER SESSION_SET %s %s=%s" % (sid, param, value)
2253     if "OK" not in dev.global_request(cmd):
2254         raise Exception(cmd + " failed")
2255
2256 def fst_session_set_ap(dev, sid, param, value):
2257     cmd = "FST-MANAGER SESSION_SET %s %s=%s" % (sid, param, value)
2258     if "OK" not in dev.request(cmd):
2259         raise Exception(cmd + " failed")
2260
2261 def fst_attach_ap(dev, ifname, group):
2262     cmd = "FST-ATTACH %s %s" % (ifname, group)
2263     if "OK" not in dev.request(cmd):
2264         raise Exception("FST-ATTACH (AP) failed")
2265     ev = dev.wait_event(['FST-EVENT-IFACE'], timeout=5)
2266     if ev is None:
2267         raise Exception("No FST-EVENT-IFACE attached (AP)")
2268     for t in [ "attached", "ifname=" + ifname, "group=" + group ]:
2269         if t not in ev:
2270             raise Exception("Unexpected FST-EVENT-IFACE data (AP): " + ev)
2271
2272 def fst_attach_sta(dev, ifname, group):
2273     if "OK" not in dev.global_request("FST-ATTACH %s %s" % (ifname, group)):
2274         raise Exception("FST-ATTACH (STA) failed")
2275     ev = dev.wait_global_event(['FST-EVENT-IFACE'], timeout=5)
2276     if ev is None:
2277         raise Exception("No FST-EVENT-IFACE attached (STA)")
2278     for t in [ "attached", "ifname=" + ifname, "group=" + group ]:
2279         if t not in ev:
2280             raise Exception("Unexpected FST-EVENT-IFACE data (STA): " + ev)
2281
2282 def fst_detach_ap(dev, ifname, group):
2283     if "OK" not in dev.request("FST-DETACH " + ifname):
2284         raise Exception("FST-DETACH (AP) failed for " + ifname)
2285     ev = dev.wait_event(['FST-EVENT-IFACE'], timeout=5)
2286     if ev is None:
2287         raise Exception("No FST-EVENT-IFACE detached (AP) for " + ifname)
2288     for t in [ "detached", "ifname=" + ifname, "group=" + group ]:
2289         if t not in ev:
2290             raise Exception("Unexpected FST-EVENT-IFACE data (AP): " + ev)
2291
2292 def fst_detach_sta(dev, ifname, group):
2293     dev.dump_monitor()
2294     if "OK" not in dev.global_request("FST-DETACH " + ifname):
2295         raise Exception("FST-DETACH (STA) failed for " + ifname)
2296     ev = dev.wait_global_event(['FST-EVENT-IFACE'], timeout=5)
2297     if ev is None:
2298         raise Exception("No FST-EVENT-IFACE detached (STA) for " + ifname)
2299     for t in [ "detached", "ifname=" + ifname, "group=" + group ]:
2300         if t not in ev:
2301             raise Exception("Unexpected FST-EVENT-IFACE data (STA): " + ev)
2302
2303 def fst_wait_event_peer_ap(dev, event, ifname, addr):
2304     ev = dev.wait_event(['FST-EVENT-PEER'], timeout=5)
2305     if ev is None:
2306         raise Exception("No FST-EVENT-PEER connected (AP)")
2307     for t in [ " " + event + " ", "ifname=" + ifname, "peer_addr=" + addr ]:
2308         if t not in ev:
2309             raise Exception("Unexpected FST-EVENT-PEER data (AP): " + ev)
2310
2311 def fst_wait_event_peer_sta(dev, event, ifname, addr):
2312     ev = dev.wait_global_event(['FST-EVENT-PEER'], timeout=5)
2313     if ev is None:
2314         raise Exception("No FST-EVENT-PEER connected (STA)")
2315     for t in [ " " + event + " ", "ifname=" + ifname, "peer_addr=" + addr ]:
2316         if t not in ev:
2317             raise Exception("Unexpected FST-EVENT-PEER data (STA): " + ev)
2318
2319 def fst_setup_req(dev, hglobal, freq, dst, req, stie, mbie="", no_wait=False):
2320     act = req + stie + mbie
2321     dev.request("MGMT_TX %s %s freq=%d action=%s" % (dst, dst, freq, act))
2322     ev = dev.wait_event(['MGMT-TX-STATUS'], timeout=5)
2323     if ev is None or "result=SUCCESS" not in ev:
2324         raise Exception("FST Action frame not ACKed")
2325
2326     if no_wait:
2327         return
2328     while True:
2329         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2330         if ev is None:
2331             raise Exception("No FST-EVENT-SESSION (AP)")
2332         if "new_state=SETUP_COMPLETION" in ev:
2333             break
2334
2335 def fst_start_and_connect(apdev, group, sgroup):
2336     hglobal = hostapd.HostapdGlobal()
2337     if "OK" not in hglobal.request("FST-MANAGER TEST_REQUEST IS_SUPPORTED"):
2338         raise HwsimSkip("No FST testing support")
2339
2340     params = { "ssid": "fst_11a", "hw_mode": "a", "channel": "36",
2341                "country_code": "US" }
2342     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2343
2344     fst_attach_ap(hglobal, apdev[0]['ifname'], group)
2345
2346     cmd = "FST-ATTACH %s %s" % (apdev[0]['ifname'], group)
2347     if "FAIL" not in hglobal.request(cmd):
2348         raise Exception("Duplicated FST-ATTACH (AP) accepted")
2349
2350     params = { "ssid": "fst_11g", "hw_mode": "g", "channel": "1",
2351                "country_code": "US" }
2352     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
2353     fst_attach_ap(hglobal, apdev[1]['ifname'], group)
2354
2355     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2356     wpas.interface_add("wlan5")
2357     fst_attach_sta(wpas, wpas.ifname, sgroup)
2358
2359     wpas.interface_add("wlan6", set_ifname=False)
2360     wpas2 = WpaSupplicant(ifname="wlan6")
2361     fst_attach_sta(wpas, wpas2.ifname, sgroup)
2362
2363     wpas.connect("fst_11a", key_mgmt="NONE", scan_freq="5180",
2364                  wait_connect=False)
2365     wpas.wait_connected()
2366
2367     fst_wait_event_peer_sta(wpas, "connected", wpas.ifname, apdev[0]['bssid'])
2368     fst_wait_event_peer_ap(hglobal, "connected", apdev[0]['ifname'],
2369                            wpas.own_addr())
2370
2371     wpas2.connect("fst_11g", key_mgmt="NONE", scan_freq="2412",
2372                   wait_connect=False)
2373     wpas2.wait_connected()
2374
2375     fst_wait_event_peer_sta(wpas, "connected", wpas2.ifname, apdev[1]['bssid'])
2376     fst_wait_event_peer_ap(hglobal, "connected", apdev[1]['ifname'],
2377                            wpas2.own_addr())
2378     return hglobal, wpas, wpas2, hapd, hapd2
2379
2380 def test_fst_test_setup(dev, apdev, test_params):
2381     """FST setup using separate commands"""
2382     try:
2383         _test_fst_test_setup(dev, apdev, test_params)
2384     finally:
2385         subprocess.call(['iw', 'reg', 'set', '00'])
2386         dev[0].flush_scan_cache()
2387         dev[1].flush_scan_cache()
2388
2389 def _test_fst_test_setup(dev, apdev, test_params):
2390     group = "fstg0b"
2391     sgroup = "fstg1b"
2392     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2393
2394     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2395     if "FAIL" in sid:
2396         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2397
2398     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2399     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2400     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2401     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2402
2403     if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2404         raise Exception("FST-MANAGER SESSION_INITIATE failed")
2405
2406     while True:
2407         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2408         if ev is None:
2409             raise Exception("No FST-EVENT-SESSION (AP)")
2410         if "new_state=SETUP_COMPLETION" in ev:
2411             f = re.search("session_id=(\d+)", ev)
2412             if f is None:
2413                 raise Exception("No session_id in FST-EVENT-SESSION")
2414             sid_ap = f.group(1)
2415             cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2416             if "OK" not in hglobal.request(cmd):
2417                 raise Exception("FST-MANAGER SESSION_RESPOND failed on AP")
2418             break
2419
2420     ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2421     if ev is None:
2422         raise Exception("No FST-EVENT-SESSION")
2423     if "new_state=SETUP_COMPLETION" not in ev:
2424         raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2425
2426     ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2427     if ev is None:
2428         raise Exception("No FST-EVENT-SESSION")
2429     if "event_type=EVENT_FST_ESTABLISHED" not in ev:
2430         raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2431
2432     cmd = "FST-MANAGER SESSION_REMOVE " + sid
2433     if "OK" not in wpas.global_request(cmd):
2434         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2435     ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2436     if ev is None:
2437         raise Exception("No FST-EVENT-SESSION")
2438     if "new_state=INITIAL" not in ev:
2439         raise Exception("Unexpected FST-EVENT-SESSION data (STA): " + ev)
2440
2441     ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2442     if ev is None:
2443         raise Exception("No FST-EVENT-SESSION (AP)")
2444     if "new_state=INITIAL" not in ev:
2445         raise Exception("Unexpected FST-EVENT-SESSION data (AP): " + ev)
2446
2447     if "FAIL" not in wpas.global_request(cmd):
2448         raise Exception("Duplicated FST-MANAGER SESSION_REMOVE accepted")
2449
2450     hglobal.request("FST-MANAGER SESSION_REMOVE " + sid_ap)
2451
2452     wpas.request("DISCONNECT")
2453     wpas.wait_disconnected()
2454     fst_wait_event_peer_sta(wpas, "disconnected", wpas.ifname,
2455                             apdev[0]['bssid'])
2456     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[0]['ifname'],
2457                            wpas.own_addr())
2458
2459     wpas2.request("DISCONNECT")
2460     wpas2.wait_disconnected()
2461     fst_wait_event_peer_sta(wpas, "disconnected", wpas2.ifname,
2462                             apdev[1]['bssid'])
2463     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[1]['ifname'],
2464                            wpas2.own_addr())
2465
2466     fst_detach_ap(hglobal, apdev[0]['ifname'], group)
2467     if "FAIL" not in hglobal.request("FST-DETACH " + apdev[0]['ifname']):
2468         raise Exception("Duplicated FST-DETACH (AP) accepted")
2469     hapd.disable()
2470
2471     fst_detach_ap(hglobal, apdev[1]['ifname'], group)
2472     hapd2.disable()
2473
2474     fst_detach_sta(wpas, wpas.ifname, sgroup)
2475     fst_detach_sta(wpas, wpas2.ifname, sgroup)
2476
2477 def test_fst_setup_mbie_diff(dev, apdev, test_params):
2478     """FST setup and different MBIE in FST Setup Request"""
2479     try:
2480         _test_fst_setup_mbie_diff(dev, apdev, test_params)
2481     finally:
2482         subprocess.call(['iw', 'reg', 'set', '00'])
2483         dev[0].flush_scan_cache()
2484         dev[1].flush_scan_cache()
2485
2486 def _test_fst_setup_mbie_diff(dev, apdev, test_params):
2487     group = "fstg0c"
2488     sgroup = "fstg1c"
2489     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2490
2491     # FST Setup Request: Category, FST Action, Dialog Token (non-zero),
2492     # LLT (32 bits, see 10.32), Session Transition (see 8.4.2.147),
2493     # Multi-band element (optional, see 8.4.2.140)
2494
2495     # Session Transition: EID, Len, FSTS ID(4), Session Control,
2496     # New Band (Band ID, Setup, Operation), Old Band (Band ID, Setup, Operation)
2497
2498     # Multi-band element: EID, Len, Multi-band Control, Band ID,
2499     # Operating Class, Channel Number, BSSID (6), Beacon Interval (2),
2500     # TSF Offset (8), Multi-band Connection Capability, FSTSessionTimeOut,
2501     # STA MAC Address (6, optional), Pairwise Cipher Suite Count (2, optional),
2502     # Pairwise Cipher Suite List (4xm, optional)
2503
2504     # MBIE with the non-matching STA MAC Address:
2505     req = "1200011a060000"
2506     stie = "a40b0100000000020001040001"
2507     mbie = "9e1c0c0200010200000004000000000000000000000000ff0200000006ff"
2508     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2509
2510     # MBIE without the STA MAC Address:
2511     req = "1200011a060000"
2512     stie = "a40b0100000000020001040001"
2513     mbie = "9e16040200010200000004000000000000000000000000ff"
2514     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2515
2516     # MBIE with unsupported STA Role:
2517     req = "1200011a060000"
2518     stie = "a40b0100000000020001040001"
2519     mbie = "9e16070200010200000004000000000000000000000000ff"
2520     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2521
2522     # MBIE with unsupported Band ID:
2523     req = "1200011a060000"
2524     stie = "a40b0100000000020001040001"
2525     mbie = "9e1604ff00010200000004000000000000000000000000ff"
2526     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2527
2528     # FST Setup Request without MBIE (different FSTS ID):
2529     req = "1200011a060000"
2530     stie = "a40b0200000000020001040001"
2531     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie)
2532
2533     # MBIE update OOM on AP
2534     req = "1200011a060000"
2535     stie = "a40b0100000000020001040001"
2536     mbie = "9e16040200010200000004000000000000000000000000ff"
2537     with alloc_fail(hapd, 1, "mb_ies_by_info"):
2538         fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie,
2539                       no_wait=True)
2540
2541 def test_fst_many_setup(dev, apdev, test_params):
2542     """FST setup multiple times"""
2543     try:
2544         _test_fst_many_setup(dev, apdev, test_params)
2545     finally:
2546         subprocess.call(['iw', 'reg', 'set', '00'])
2547         dev[0].flush_scan_cache()
2548         dev[1].flush_scan_cache()
2549
2550 def _test_fst_many_setup(dev, apdev, test_params):
2551     group = "fstg0d"
2552     sgroup = "fstg1d"
2553     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2554
2555     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2556     if "FAIL" in sid:
2557         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2558
2559     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2560     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2561     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2562     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2563
2564     for i in range(257):
2565         if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2566             raise Exception("FST-MANAGER SESSION_INITIATE failed")
2567
2568         while True:
2569             ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2570             if ev is None:
2571                 raise Exception("No FST-EVENT-SESSION (AP)")
2572             if "new_state=SETUP_COMPLETION" in ev:
2573                 f = re.search("session_id=(\d+)", ev)
2574                 if f is None:
2575                     raise Exception("No session_id in FST-EVENT-SESSION")
2576                 sid_ap = f.group(1)
2577                 cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2578                 if "OK" not in hglobal.request(cmd):
2579                     raise Exception("FST-MANAGER SESSION_RESPOND failed on AP")
2580                 break
2581
2582         ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2583         if ev is None:
2584             raise Exception("No FST-EVENT-SESSION (STA)")
2585         if "new_state=SETUP_COMPLETION" not in ev:
2586             raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2587
2588         ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2589         if ev is None:
2590             raise Exception("No FST-EVENT-SESSION (STA)")
2591         if "event_type=EVENT_FST_ESTABLISHED" not in ev:
2592             raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2593
2594         if "OK" not in wpas.global_request("FST-MANAGER SESSION_TEARDOWN " + sid):
2595             raise Exception("FST-MANAGER SESSION_INITIATE failed")
2596
2597         if i == 0:
2598             if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_TEARDOWN " + sid):
2599                 raise Exception("Duplicate FST-MANAGER SESSION_TEARDOWN accepted")
2600
2601         ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2602         if ev is None:
2603             raise Exception("No FST-EVENT-SESSION (STA teardown -->initial)")
2604         if "new_state=INITIAL" not in ev:
2605             raise Exception("Unexpected FST-EVENT-SESSION data (STA): " + ev)
2606
2607         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2608         if ev is None:
2609             raise Exception("No FST-EVENT-SESSION (AP teardown -->initial)")
2610         if "new_state=INITIAL" not in ev:
2611             raise Exception("Unexpected FST-EVENT-SESSION data (AP): " + ev)
2612
2613         if "OK" not in hglobal.request("FST-MANAGER SESSION_REMOVE " + sid_ap):
2614             raise Exception("FST-MANAGER SESSION_REMOVE (AP) failed")
2615
2616     if "OK" not in wpas.global_request("FST-MANAGER SESSION_REMOVE " + sid):
2617         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2618
2619     wpas.request("DISCONNECT")
2620     wpas.wait_disconnected()
2621     fst_wait_event_peer_sta(wpas, "disconnected", wpas.ifname,
2622                             apdev[0]['bssid'])
2623     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[0]['ifname'],
2624                            wpas.own_addr())
2625
2626     wpas2.request("DISCONNECT")
2627     wpas2.wait_disconnected()
2628     fst_wait_event_peer_sta(wpas, "disconnected", wpas2.ifname,
2629                             apdev[1]['bssid'])
2630     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[1]['ifname'],
2631                            wpas2.own_addr())
2632
2633     fst_detach_ap(hglobal, apdev[0]['ifname'], group)
2634     fst_detach_ap(hglobal, apdev[1]['ifname'], group)
2635     hapd.disable()
2636     hapd2.disable()
2637
2638     fst_detach_sta(wpas, wpas.ifname, sgroup)
2639     fst_detach_sta(wpas, wpas2.ifname, sgroup)
2640
2641 def test_fst_attach_wpas_error(dev, apdev, test_params):
2642     """FST attach errors in wpa_supplicant"""
2643     if "OK" not in dev[0].global_request("FST-MANAGER TEST_REQUEST IS_SUPPORTED"):
2644         raise HwsimSkip("No FST testing support")
2645     group = "fstg0"
2646     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2647     wpas.interface_add("wlan5")
2648     fst_attach_sta(wpas, wpas.ifname, group)
2649     if "FAIL" not in wpas.global_request("FST-ATTACH %s %s" % (wpas.ifname,
2650                                                                group)):
2651         raise Exception("Duplicated FST-ATTACH accepted")
2652     if "FAIL" not in wpas.global_request("FST-ATTACH %s %s" % ("foofoo",
2653                                                                group)):
2654         raise Exception("FST-ATTACH for unknown interface accepted")
2655
2656 def test_fst_session_initiate_errors(dev, apdev, test_params):
2657     """FST SESSION_INITIATE error cases"""
2658     try:
2659         _test_fst_session_initiate_errors(dev, apdev, test_params)
2660     finally:
2661         subprocess.call(['iw', 'reg', 'set', '00'])
2662         dev[0].flush_scan_cache()
2663         dev[1].flush_scan_cache()
2664
2665 def _test_fst_session_initiate_errors(dev, apdev, test_params):
2666     group = "fstg0"
2667     sgroup = "fstg1"
2668     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2669
2670     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2671     if "FAIL" in sid:
2672         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2673
2674     # No old peer MAC address
2675     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2676         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2677
2678     fst_session_set(wpas, sid, "old_peer_addr", "00:ff:ff:ff:ff:ff")
2679     # No new peer MAC address
2680     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2681         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2682
2683     fst_session_set(wpas, sid, "new_peer_addr", "00:ff:ff:ff:ff:fe")
2684     # No old interface defined
2685     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2686         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2687
2688     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2689     # No new interface defined
2690     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2691         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2692
2693     fst_session_set(wpas, sid, "new_ifname", wpas.ifname)
2694     # Same interface set as old and new
2695     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2696         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2697
2698     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2699     # The preset old peer address is not connected
2700     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2701         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2702
2703     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2704     # The preset new peer address is not connected
2705     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2706         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2707
2708     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2709     # Initiate session setup
2710     if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2711         raise Exception("FST-MANAGER SESSION_INITIATE failed")
2712
2713     # Session in progress
2714     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2715         raise Exception("Duplicated FST-MANAGER SESSION_INITIATE accepted")
2716
2717     sid2 = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2718     if "FAIL" in sid:
2719         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2720     fst_session_set(wpas, sid2, "old_ifname", wpas.ifname)
2721     fst_session_set(wpas, sid2, "old_peer_addr", apdev[0]['bssid'])
2722     fst_session_set(wpas, sid2, "new_ifname", wpas2.ifname)
2723     fst_session_set(wpas, sid2, "new_peer_addr", apdev[1]['bssid'])
2724
2725     # There is another session in progress (old)
2726     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid2):
2727         raise Exception("Duplicated FST-MANAGER SESSION_INITIATE accepted")
2728
2729     if "OK" not in wpas.global_request("FST-MANAGER SESSION_REMOVE " + sid):
2730         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2731
2732     while True:
2733         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2734         if ev is None:
2735             raise Exception("No FST-EVENT-SESSION (AP)")
2736         if "new_state=SETUP_COMPLETION" in ev:
2737             f = re.search("session_id=(\d+)", ev)
2738             if f is None:
2739                 raise Exception("No session_id in FST-EVENT-SESSION")
2740             sid_ap = f.group(1)
2741             break
2742     if "OK" not in hglobal.request("FST-MANAGER SESSION_REMOVE " + sid_ap):
2743         raise Exception("FST-MANAGER SESSION_REMOVE (AP) failed")
2744
2745     if "OK" not in wpas.global_request("FST-MANAGER SESSION_REMOVE " + sid2):
2746         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2747
2748 def test_fst_session_respond_errors(dev, apdev, test_params):
2749     """FST SESSION_RESPOND error cases"""
2750     try:
2751         _test_fst_session_respond_errors(dev, apdev, test_params)
2752     finally:
2753         subprocess.call(['iw', 'reg', 'set', '00'])
2754         dev[0].flush_scan_cache()
2755         dev[1].flush_scan_cache()
2756
2757 def _test_fst_session_respond_errors(dev, apdev, test_params):
2758     group = "fstg0b"
2759     sgroup = "fstg1b"
2760     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2761
2762     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2763     if "FAIL" in sid:
2764         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2765
2766     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2767     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2768     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2769     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2770
2771     if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2772         raise Exception("FST-MANAGER SESSION_INITIATE failed")
2773
2774     while True:
2775         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2776         if ev is None:
2777             raise Exception("No FST-EVENT-SESSION (AP)")
2778         if "new_state=SETUP_COMPLETION" in ev:
2779             f = re.search("session_id=(\d+)", ev)
2780             if f is None:
2781                 raise Exception("No session_id in FST-EVENT-SESSION")
2782             sid_ap = f.group(1)
2783             break
2784
2785     # The preset peer address is not in the peer list
2786     fst_session_set_ap(hglobal, sid_ap, "old_peer_addr", "00:00:00:00:00:01")
2787     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2788     if "FAIL" not in hglobal.request(cmd):
2789         raise Exception("Invalid FST-MANAGER SESSION_RESPOND accepted")
2790
2791     # Same interface set as old and new
2792     fst_session_set_ap(hglobal, sid_ap, "old_peer_addr", wpas.own_addr())
2793     fst_session_set_ap(hglobal, sid_ap, "old_ifname", apdev[1]['ifname'])
2794     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2795     if "FAIL" not in hglobal.request(cmd):
2796         raise Exception("Invalid FST-MANAGER SESSION_RESPOND accepted")
2797
2798     # valid command
2799     fst_session_set_ap(hglobal, sid_ap, "old_ifname", apdev[0]['ifname'])
2800     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2801     if "OK" not in hglobal.request(cmd):
2802         raise Exception("FST-MANAGER SESSION_RESPOND failed")
2803
2804     # incorrect state
2805     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2806     if "FAIL" not in hglobal.request(cmd):
2807         raise Exception("Invalid FST-MANAGER SESSION_RESPOND accepted")
2808
2809     cmd = "FST-MANAGER SESSION_REMOVE " + sid
2810     if "OK" not in wpas.global_request(cmd):
2811         raise Exception("FST-MANAGER SESSION_REMOVE (STA) failed")
2812
2813     cmd = "FST-MANAGER SESSION_REMOVE %s" % sid_ap
2814     if "OK" not in hglobal.request(cmd):
2815         raise Exception("FST-MANAGER SESSION_REMOVE (AP) failed")