Updated to hostap_2_6
[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             logger.info("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             logger.info("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             logger.info("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             logger.info("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             logger.info("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             logger.info("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             logger.info("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                 res_sta1_mbies.startswith("FAIL") or
756                 res_sta2_mbies.startswith("FAIL")):
757                 raise Exception("Failure. MB IEs must be present 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                 res_sta1_mbies.startswith("FAIL") or
843                 res_sta2_mbies.startswith("FAIL")):
844                 raise Exception("Failure. MB IEs must be present 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 (orig_sta1_mbies.startswith("FAIL") or
872                 orig_sta2_mbies.startswith("FAIL") or
873                 res_sta1_mbies.startswith("FAIL") or
874                 res_sta2_mbies.startswith("FAIL")):
875                 raise Exception("Failure. MB IEs must be 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 (orig_sta1_mbies.startswith("FAIL") or
904                 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 must be present 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 (orig_sta1_mbies.startswith("FAIL") or
936                 orig_sta2_mbies.startswith("FAIL") or
937                 res_sta1_mbies.startswith("FAIL") or
938                 res_sta2_mbies.startswith("FAIL")):
939                 raise Exception("Failure. MB IEs must be 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 (orig_sta1_mbies.startswith("FAIL") or
970                 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 must be present 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     try:
1531         run_fst_ap_start_session_oom(apdev, ap1)
1532     finally:
1533         ap1.stop()
1534
1535 def run_fst_ap_start_session_oom(apdev, ap1):
1536     with alloc_fail(ap1, 1, "fst_iface_create"):
1537         ap2_started = False
1538         try:
1539             ap2 = fst_module_aux.FstAP(apdev[1]['ifname'], 'fst_11g', 'b',
1540                                        fst_test_common.fst_test_def_chan_g,
1541                                        fst_test_common.fst_test_def_group,
1542                                        fst_test_common.fst_test_def_prio_high,
1543                                        fst_test_common.fst_test_def_llt)
1544             try:
1545                 # This will fail in fst_iface_create() OOM
1546                 ap2.start()
1547             except:
1548                 pass
1549         finally:
1550             try:
1551                 ap2.stop()
1552             except:
1553                 pass
1554
1555 # STA side FST module tests
1556
1557 def test_fst_sta_start_session(dev, apdev, test_params):
1558     """FST STA start session"""
1559     fst_start_session(apdev, test_params, bad_param_none, False)
1560
1561 def test_fst_sta_start_session_no_add_params(dev, apdev, test_params):
1562     """FST STA start session - no add params"""
1563     fst_start_session(apdev, test_params, bad_param_session_add_no_params,
1564                       False)
1565
1566 def test_fst_sta_start_session_bad_group_id(dev, apdev, test_params):
1567     """FST STA start session - bad group id"""
1568     fst_start_session(apdev, test_params, bad_param_group_id, False)
1569
1570 def test_fst_sta_start_session_no_set_params(dev, apdev, test_params):
1571     """FST STA start session - no set params"""
1572     fst_start_session(apdev, test_params, bad_param_session_set_no_params,
1573                       False)
1574
1575 def test_fst_sta_start_session_set_unknown_param(dev, apdev, test_params):
1576     """FST STA start session - set unknown param"""
1577     fst_start_session(apdev, test_params, bad_param_session_set_unknown_param,
1578                       False)
1579
1580 def test_fst_sta_start_session_bad_session_id(dev, apdev, test_params):
1581     """FST STA start session - bad session id"""
1582     fst_start_session(apdev, test_params, bad_param_session_id, False)
1583
1584 def test_fst_sta_start_session_bad_new_iface(dev, apdev, test_params):
1585     """FST STA start session - bad new iface"""
1586     fst_start_session(apdev, test_params, bad_param_new_iface, False)
1587
1588 def test_fst_sta_start_session_bad_old_iface(dev, apdev, test_params):
1589     """FST STA start session - bad old iface"""
1590     fst_start_session(apdev, test_params, bad_param_old_iface, False)
1591
1592 def test_fst_sta_start_session_negative_llt(dev, apdev, test_params):
1593     """FST STA start session - negative llt"""
1594     fst_start_session(apdev, test_params, bad_param_negative_llt, False)
1595
1596 def test_fst_sta_start_session_zero_llt(dev, apdev, test_params):
1597     """FST STA start session - zero llt"""
1598     fst_start_session(apdev, test_params, bad_param_zero_llt, False)
1599
1600 def test_fst_sta_start_session_llt_too_big(dev, apdev, test_params):
1601     """FST STA start session - llt too large"""
1602     fst_start_session(apdev, test_params, bad_param_llt_too_big, False)
1603
1604 def test_fst_sta_start_session_invalid_peer_addr(dev, apdev, test_params):
1605     """FST STA start session - invalid peer address"""
1606     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1607                       'GG:GG:GG:GG:GG:GG')
1608
1609 def test_fst_sta_start_session_multicast_peer_addr(dev, apdev, test_params):
1610     """FST STA start session - multicast peer address"""
1611     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1612                       '11:00:11:22:33:44')
1613
1614 def test_fst_sta_start_session_broadcast_peer_addr(dev, apdev, test_params):
1615     """FST STA start session - broadcast peer addr"""
1616     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1617                       'FF:FF:FF:FF:FF:FF')
1618
1619 def test_fst_sta_initiate_session(dev, apdev, test_params):
1620     """FST STA initiate session"""
1621     fst_initiate_session(apdev, test_params, bad_param_none, False)
1622
1623 def test_fst_sta_initiate_session_no_params(dev, apdev, test_params):
1624     """FST STA initiate session - no params"""
1625     fst_initiate_session(apdev, test_params,
1626                          bad_param_session_initiate_no_params, False)
1627
1628 def test_fst_sta_initiate_session_invalid_session_id(dev, apdev, test_params):
1629     """FST STA initiate session - invalid session id"""
1630     fst_initiate_session(apdev, test_params,
1631                          bad_param_session_initiate_bad_session_id, False)
1632
1633 def test_fst_sta_initiate_session_no_new_iface(dev, apdev, test_params):
1634     """FST STA initiate session - no new iface"""
1635     fst_initiate_session(apdev, test_params,
1636                          bad_param_session_initiate_with_no_new_iface_set,
1637                          False)
1638
1639 def test_fst_sta_initiate_session_bad_peer_addr(dev, apdev, test_params):
1640     """FST STA initiate session - bad peer address"""
1641     fst_initiate_session(apdev, test_params,
1642                          bad_param_session_initiate_with_bad_peer_addr_set,
1643                          False)
1644
1645 def test_fst_sta_initiate_session_request_with_bad_stie(dev, apdev,
1646                                                         test_params):
1647     """FST STA initiate session - request with bad stie"""
1648     fst_initiate_session(apdev, test_params,
1649                          bad_param_session_initiate_request_with_bad_stie,
1650                          False)
1651
1652 def test_fst_sta_initiate_session_response_with_reject(dev, apdev, test_params):
1653     """FST STA initiate session - response with reject"""
1654     fst_initiate_session(apdev, test_params, bad_param_session_initiate_response_with_reject, False)
1655
1656 def test_fst_sta_initiate_session_response_with_bad_stie(dev, apdev, test_params):
1657     """FST STA initiate session - response with bad stie"""
1658     fst_initiate_session(apdev, test_params,
1659                          bad_param_session_initiate_response_with_bad_stie,
1660                          False)
1661
1662 def test_fst_sta_initiate_session_response_with_zero_llt(dev, apdev,
1663                                                          test_params):
1664     """FST STA initiate session - response with zero llt"""
1665     fst_initiate_session(apdev, test_params,
1666                          bad_param_session_initiate_response_with_zero_llt,
1667                          False)
1668
1669 def test_fst_sta_initiate_session_stt_no_response(dev, apdev, test_params):
1670     """FST STA initiate session - stt no response"""
1671     fst_initiate_session(apdev, test_params,
1672                          bad_param_session_initiate_stt_no_response, False)
1673
1674 def test_fst_sta_initiate_session_concurrent_setup_request(dev, apdev,
1675                                                            test_params):
1676     """FST STA initiate session - concurrent setup request"""
1677     fst_initiate_session(apdev, test_params,
1678                          bad_param_session_initiate_concurrent_setup_request,
1679                          False)
1680
1681 def test_fst_sta_session_request_with_no_session(dev, apdev, test_params):
1682     """FST STA session request with no session"""
1683     fst_send_unexpected_frame(apdev, test_params, frame_type_session_request,
1684                               False)
1685
1686 def test_fst_sta_session_response_accept_with_no_session(dev, apdev,
1687                                                          test_params):
1688     """FST STA session response accept with no session"""
1689     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1690                               False, "accept")
1691
1692 def test_fst_sta_session_response_reject_with_no_session(dev, apdev,
1693                                                          test_params):
1694     """FST STA session response reject with no session"""
1695     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1696                               False, "reject")
1697
1698 def test_fst_sta_ack_request_with_no_session(dev, apdev, test_params):
1699     """FST STA ack request with no session"""
1700     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_request, False)
1701
1702 def test_fst_sta_ack_response_with_no_session(dev, apdev, test_params):
1703     """FST STA ack response with no session"""
1704     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_response,
1705                               False)
1706
1707 def test_fst_sta_tear_down_response_with_no_session(dev, apdev, test_params):
1708     """FST STA tear down response with no session"""
1709     fst_send_unexpected_frame(apdev, test_params, frame_type_tear_down, False)
1710
1711 def test_fst_sta_transfer_session(dev, apdev, test_params):
1712     """FST STA transfer session"""
1713     fst_transfer_session(apdev, test_params, bad_param_none, False)
1714
1715 def test_fst_sta_transfer_session_no_params(dev, apdev, test_params):
1716     """FST STA transfer session - no params"""
1717     fst_transfer_session(apdev, test_params,
1718                          bad_param_session_transfer_no_params, False)
1719
1720 def test_fst_sta_transfer_session_bad_session_id(dev, apdev, test_params):
1721     """FST STA transfer session - bad session id"""
1722     fst_transfer_session(apdev, test_params,
1723                          bad_param_session_transfer_bad_session_id, False)
1724
1725 def test_fst_sta_transfer_session_setup_skipped(dev, apdev, test_params):
1726     """FST STA transfer session - setup skipped"""
1727     fst_transfer_session(apdev, test_params,
1728                          bad_param_session_transfer_setup_skipped, False)
1729
1730 def test_fst_sta_ack_request_with_session_not_set_up(dev, apdev, test_params):
1731     """FST STA ack request with session not set up"""
1732     fst_bad_transfer(apdev, test_params,
1733                      bad_scenario_ack_req_session_not_set_up, False)
1734
1735 def test_fst_sta_ack_request_with_session_not_established_init_side(dev, apdev, test_params):
1736     """FST STA ack request with session not established init side"""
1737     fst_bad_transfer(apdev, test_params,
1738                      bad_scenario_ack_req_session_not_established_init_side,
1739                      False)
1740
1741 def test_fst_sta_ack_request_with_session_not_established_resp_side(dev, apdev, test_params):
1742     """FST STA ack request with session not established resp side"""
1743     fst_bad_transfer(apdev, test_params,
1744                      bad_scenario_ack_req_session_not_established_resp_side,
1745                      False)
1746
1747 def test_fst_sta_ack_request_with_bad_fsts_id(dev, apdev, test_params):
1748     """FST STA ack request with bad fsts id"""
1749     fst_bad_transfer(apdev, test_params, bad_scenario_ack_req_bad_fsts_id,
1750                      False)
1751
1752 def test_fst_sta_ack_response_with_session_not_set_up(dev, apdev, test_params):
1753     """FST STA ack response with session not set up"""
1754     fst_bad_transfer(apdev, test_params,
1755                      bad_scenario_ack_resp_session_not_set_up, False)
1756
1757 def test_fst_sta_ack_response_with_session_not_established_init_side(dev, apdev, test_params):
1758     """FST STA ack response with session not established init side"""
1759     fst_bad_transfer(apdev, test_params,
1760                      bad_scenario_ack_resp_session_not_established_init_side,
1761                      False)
1762
1763 def test_fst_sta_ack_response_with_session_not_established_resp_side(dev, apdev, test_params):
1764     """FST STA ack response with session not established resp side"""
1765     fst_bad_transfer(apdev, test_params,
1766                      bad_scenario_ack_resp_session_not_established_resp_side,
1767                      False)
1768
1769 def test_fst_sta_ack_response_with_no_ack_request(dev, apdev, test_params):
1770     """FST STA ack response with no ack request"""
1771     fst_bad_transfer(apdev, test_params, bad_scenario_ack_resp_no_ack_req,
1772                      False)
1773
1774 def test_fst_sta_tear_down_session(dev, apdev, test_params):
1775     """FST STA tear down session"""
1776     fst_tear_down_session(apdev, test_params, bad_param_none, False)
1777
1778 def test_fst_sta_tear_down_session_no_params(dev, apdev, test_params):
1779     """FST STA tear down session - no params"""
1780     fst_tear_down_session(apdev, test_params,
1781                           bad_param_session_teardown_no_params, False)
1782
1783 def test_fst_sta_tear_down_session_bad_session_id(dev, apdev, test_params):
1784     """FST STA tear down session - bad session id"""
1785     fst_tear_down_session(apdev, test_params,
1786                           bad_param_session_teardown_bad_session_id, False)
1787
1788 def test_fst_sta_tear_down_session_setup_skipped(dev, apdev, test_params):
1789     """FST STA tear down session - setup skipped"""
1790     fst_tear_down_session(apdev, test_params,
1791                           bad_param_session_teardown_setup_skipped, False)
1792
1793 def test_fst_sta_tear_down_session_bad_fsts_id(dev, apdev, test_params):
1794     """FST STA tear down session - bad fsts id"""
1795     fst_tear_down_session(apdev, test_params,
1796                           bad_param_session_teardown_bad_fsts_id, False)
1797
1798 def test_fst_sta_remove_session_not_established(dev, apdev, test_params):
1799     """FST STA tear down session - not established"""
1800     fst_remove_session(apdev, test_params,
1801                        remove_scenario_non_established_session, False)
1802
1803 def test_fst_sta_remove_session_established(dev, apdev, test_params):
1804     """FST STA remove session - established"""
1805     fst_remove_session(apdev, test_params,
1806                        remove_scenario_established_session, False)
1807
1808 def test_fst_sta_remove_session_no_params(dev, apdev, test_params):
1809     """FST STA remove session - no params"""
1810     fst_remove_session(apdev, test_params, remove_scenario_no_params, False)
1811
1812 def test_fst_sta_remove_session_bad_session_id(dev, apdev, test_params):
1813     """FST STA remove session - bad session id"""
1814     fst_remove_session(apdev, test_params, remove_scenario_bad_session_id,
1815                        False)
1816
1817 def test_fst_rsn_ap_transfer_session(dev, apdev, test_params):
1818     """FST RSN AP transfer session"""
1819     fst_transfer_session(apdev, test_params, bad_param_none, True, rsn=True)
1820
1821 MGMT_SUBTYPE_ACTION = 13
1822 ACTION_CATEG_FST = 18
1823 FST_ACTION_SETUP_REQUEST = 0
1824 FST_ACTION_SETUP_RESPONSE = 1
1825 FST_ACTION_TEAR_DOWN = 2
1826 FST_ACTION_ACK_REQUEST = 3
1827 FST_ACTION_ACK_RESPONSE = 4
1828 FST_ACTION_ON_CHANNEL_TUNNEL = 5
1829
1830 def hostapd_tx_and_status(hapd, msg):
1831     hapd.set("ext_mgmt_frame_handling", "1")
1832     hapd.mgmt_tx(msg)
1833     ev = hapd.wait_event([ "MGMT-TX-STATUS" ], timeout=1)
1834     if ev is None or "ok=1" not in ev:
1835         raise Exception("No ACK")
1836     hapd.set("ext_mgmt_frame_handling", "0")
1837
1838 def test_fst_proto(dev, apdev, test_params):
1839     """FST protocol testing"""
1840     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1841     try:
1842         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1843         hapd = ap1.get_instance()
1844         sta = sta1.get_instance()
1845         dst = sta.own_addr()
1846         src = apdev[0]['bssid']
1847
1848         msg = {}
1849         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1850         msg['da'] = dst
1851         msg['sa'] = src
1852         msg['bssid'] = src
1853
1854         # unknown FST Action (255) received!
1855         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST, 255)
1856         hostapd_tx_and_status(hapd, msg)
1857
1858         # FST Request dropped: too short
1859         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1860                                      FST_ACTION_SETUP_REQUEST)
1861         hostapd_tx_and_status(hapd, msg)
1862
1863         # FST Request dropped: invalid STIE (EID)
1864         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1865                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1866                                      163, 11, 0, 0, 0, 0, 0, 0, 0, 0)
1867         hostapd_tx_and_status(hapd, msg)
1868
1869         # FST Request dropped: invalid STIE (Len)
1870         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1871                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1872                                      164, 10, 0, 0, 0, 0, 0, 0, 0, 0)
1873         hostapd_tx_and_status(hapd, msg)
1874
1875         # FST Request dropped: new and old band IDs are the same
1876         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1877                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1878                                      164, 11, 0, 0, 0, 0, 0, 0, 0, 0)
1879         hostapd_tx_and_status(hapd, msg)
1880
1881         ifaces = sta1.list_ifaces()
1882         id = int(ifaces[0]['name'].split('|')[1])
1883         # FST Request dropped: new iface not found (new_band_id mismatch)
1884         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1885                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1886                                      164, 11, 0, 0, id + 1, 0, 0, 0, 0, 0)
1887         hostapd_tx_and_status(hapd, msg)
1888
1889         # FST Action 'Setup Response' dropped: no session in progress found
1890         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1891                                      FST_ACTION_SETUP_RESPONSE)
1892         hostapd_tx_and_status(hapd, msg)
1893
1894         # Create session
1895         initiator = ap1
1896         responder = sta1
1897         new_iface = ap2.ifname()
1898         new_peer_addr = ap2.get_actual_peer_addr()
1899         resp_newif = sta2.ifname()
1900         peeraddr = None
1901         initiator.add_peer(responder, peeraddr, new_peer_addr)
1902         sid = initiator.add_session()
1903         initiator.configure_session(sid, new_iface)
1904         initiator.initiate_session(sid, "accept")
1905
1906         # FST Response dropped due to wrong state: SETUP_COMPLETION
1907         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1908                                      FST_ACTION_SETUP_RESPONSE)
1909         hostapd_tx_and_status(hapd, msg)
1910
1911         # Too short FST Tear Down dropped
1912         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1913                                      FST_ACTION_TEAR_DOWN)
1914         hostapd_tx_and_status(hapd, msg)
1915
1916         # tear down for wrong FST Setup ID (0)
1917         msg['payload'] = struct.pack("<BBL", ACTION_CATEG_FST,
1918                                      FST_ACTION_TEAR_DOWN, 0)
1919         hostapd_tx_and_status(hapd, msg)
1920
1921         # Ack received on wrong interface
1922         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1923                                      FST_ACTION_ACK_REQUEST)
1924         hostapd_tx_and_status(hapd, msg)
1925
1926         # Ack Response in inappropriate session state (SETUP_COMPLETION)
1927         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1928                                      FST_ACTION_ACK_RESPONSE)
1929         hostapd_tx_and_status(hapd, msg)
1930
1931         # Unsupported FST Action frame (On channel tunnel)
1932         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1933                                      FST_ACTION_ON_CHANNEL_TUNNEL)
1934         hostapd_tx_and_status(hapd, msg)
1935
1936         # FST Request dropped: new iface not found (new_band_id match)
1937         # FST Request dropped due to MAC comparison
1938         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1939                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1940                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
1941         hostapd_tx_and_status(hapd, msg)
1942
1943         hapd2 = ap2.get_instance()
1944         dst2 = sta2.get_instance().own_addr()
1945         src2 = apdev[1]['bssid']
1946
1947         msg2 = {}
1948         msg2['fc'] = MGMT_SUBTYPE_ACTION << 4
1949         msg2['da'] = dst2
1950         msg2['sa'] = src2
1951         msg2['bssid'] = src2
1952         # FST Response dropped: wlan6 is not the old iface
1953         msg2['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1954                                       FST_ACTION_SETUP_RESPONSE)
1955         hostapd_tx_and_status(hapd2, msg2)
1956
1957         sta.dump_monitor()
1958
1959         group = ap1.fst_group
1960         ap1.send_iface_detach_request(ap1.iface)
1961
1962         sta.flush_scan_cache()
1963         sta.request("REASSOCIATE")
1964         sta.wait_connected()
1965
1966         # FST Request dropped due to no interface connection
1967         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1968                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1969                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
1970         hostapd_tx_and_status(hapd, msg)
1971     finally:
1972         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1973         try:
1974             fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1975         except:
1976             pass
1977
1978 def test_fst_setup_response_proto(dev, apdev, test_params):
1979     """FST protocol testing for Setup Response"""
1980     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1981     try:
1982         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1983         hapd = ap1.get_instance()
1984         sta = sta1.get_instance()
1985         dst = sta.own_addr()
1986         src = apdev[0]['bssid']
1987
1988         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
1989         sta1.set_fst_parameters(llt='0')
1990         sid = sta1.add_session()
1991         sta1.configure_session(sid, sta2.ifname())
1992         sta1.initiate_session(sid, "")
1993
1994         msg = {}
1995         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1996         msg['da'] = dst
1997         msg['sa'] = src
1998         msg['bssid'] = src
1999
2000         # Too short FST Response dropped
2001         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
2002                                      FST_ACTION_SETUP_RESPONSE)
2003         hostapd_tx_and_status(hapd, msg)
2004
2005         # FST Response dropped: invalid STIE (EID)
2006         dialog_token = 1
2007         status_code = 0
2008         id = 0
2009         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2010                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2011                                      status_code,
2012                                      163, 11, 0, 0, id, 0, 0, 0, 0, 0)
2013         hostapd_tx_and_status(hapd, msg)
2014
2015         # FST Response dropped: invalid STIE (Len)
2016         dialog_token = 1
2017         status_code = 0
2018         id = 0
2019         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2020                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2021                                      status_code,
2022                                      164, 10, 0, 0, id, 0, 0, 0, 0, 0)
2023         hostapd_tx_and_status(hapd, msg)
2024
2025         # FST Response dropped due to wrong dialog token
2026         dialog_token = 123
2027         status_code = 0
2028         id = 0
2029         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2030                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2031                                      status_code,
2032                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
2033         hostapd_tx_and_status(hapd, msg)
2034
2035         # FST Response dropped due to wrong FST Session ID
2036         dialog_token = 1
2037         status_code = 0
2038         id = 1
2039         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2040                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2041                                      status_code,
2042                                      164, 11, int(sid) + 123456,
2043                                      0, id, 0, 0, 0, 0, 0)
2044         hostapd_tx_and_status(hapd, msg)
2045
2046         # FST Response with non-zero status code
2047         dialog_token = 1
2048         status_code = 1
2049         id = 1
2050         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2051                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2052                                      status_code,
2053                                      164, 11, int(sid), 0, id, 0, 0, 0, 0, 0)
2054         hostapd_tx_and_status(hapd, msg)
2055     finally:
2056         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2057         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2058
2059 def test_fst_ack_response_proto(dev, apdev, test_params):
2060     """FST protocol testing for Ack Response"""
2061     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2062     try:
2063         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2064         hapd = ap2.get_instance()
2065         sta = sta2.get_instance()
2066         dst = sta.own_addr()
2067         src = apdev[1]['bssid']
2068
2069         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
2070         sta1.set_fst_parameters(llt='0')
2071         sid = sta1.add_session()
2072         sta1.configure_session(sid, sta2.ifname())
2073
2074         s = sta1.grequest("FST-MANAGER SESSION_INITIATE "+ sid)
2075         if not s.startswith('OK'):
2076             raise Exception("Cannot initiate fst session: %s" % s)
2077         ev = sta1.peer_obj.wait_gevent([ "FST-EVENT-SESSION" ], timeout=5)
2078         if ev is None:
2079             raise Exception("No FST-EVENT-SESSION received")
2080         event = fst_module_aux.parse_fst_session_event(ev)
2081         if event == None:
2082             raise Exception("Unrecognized FST event: " % ev)
2083         if event['type'] != 'EVENT_FST_SETUP':
2084             raise Exception("Expected FST_SETUP event, got: " + event['type'])
2085         ev = sta1.peer_obj.wait_gevent(["FST-EVENT-SESSION"], timeout=5)
2086         if ev is None:
2087             raise Exception("No FST-EVENT-SESSION received")
2088         event = fst_module_aux.parse_fst_session_event(ev)
2089         if event == None:
2090             raise Exception("Unrecognized FST event: " % ev)
2091         if event['type'] != 'EVENT_FST_SESSION_STATE':
2092             raise Exception("Expected EVENT_FST_SESSION_STATE event, got: " + event['type'])
2093         if event['new_state'] != "SETUP_COMPLETION":
2094             raise Exception("Expected new state SETUP_COMPLETION, got: " + event['new_state'])
2095
2096         hapd.set("ext_mgmt_frame_handling", "1")
2097         s = sta1.peer_obj.grequest("FST-MANAGER SESSION_RESPOND "+ event['id'] + " accept")
2098         if not s.startswith('OK'):
2099             raise Exception("Error session_respond: %s" % s)
2100         req = hapd.mgmt_rx()
2101         if req is None:
2102             raise Exception("No Ack Request seen")
2103         msg = {}
2104         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
2105         msg['da'] = dst
2106         msg['sa'] = src
2107         msg['bssid'] = src
2108
2109         # Too short FST Ack Response dropped
2110         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
2111                                      FST_ACTION_ACK_RESPONSE)
2112         hapd.mgmt_tx(msg)
2113         ev = hapd.wait_event([ "MGMT-TX-STATUS" ], timeout=1)
2114         if ev is None or "ok=1" not in ev:
2115             raise Exception("No ACK")
2116
2117         # Ack Response for wrong FSt Setup ID
2118         msg['payload'] = struct.pack("<BBBL", ACTION_CATEG_FST,
2119                                      FST_ACTION_ACK_RESPONSE,
2120                                      0, int(sid) + 123456)
2121         hostapd_tx_and_status(hapd, msg)
2122     finally:
2123         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2124         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2125
2126 def test_fst_ap_config_oom(dev, apdev, test_params):
2127     """FST AP configuration and OOM"""
2128     ap1 = fst_module_aux.FstAP(apdev[0]['ifname'], 'fst_11a', 'a',
2129                                fst_test_common.fst_test_def_chan_a,
2130                                fst_test_common.fst_test_def_group,
2131                                fst_test_common.fst_test_def_prio_low)
2132     hapd = ap1.start(return_early=True)
2133     with alloc_fail(hapd, 1, "fst_group_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_iface_create"):
2139         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2140         if not res.startswith("FAIL"):
2141             raise Exception("FST-ATTACH succeeded unexpectedly")
2142
2143     with alloc_fail(hapd, 1, "fst_group_create_mb_ie"):
2144         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2145         # This is allowed to complete currently
2146
2147     ap1.stop()
2148
2149 def test_fst_send_oom(dev, apdev, test_params):
2150     """FST send action OOM"""
2151     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2152     try:
2153         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2154         hapd = ap1.get_instance()
2155         sta = sta1.get_instance()
2156         dst = sta.own_addr()
2157         src = apdev[0]['bssid']
2158
2159         # Create session
2160         initiator = ap1
2161         responder = sta1
2162         new_iface = ap2.ifname()
2163         new_peer_addr = ap2.get_actual_peer_addr()
2164         resp_newif = sta2.ifname()
2165         peeraddr = None
2166         initiator.add_peer(responder, peeraddr, new_peer_addr)
2167         sid = initiator.add_session()
2168         initiator.configure_session(sid, new_iface)
2169         with alloc_fail(hapd, 1, "fst_session_send_action"):
2170             res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2171             if not res.startswith("FAIL"):
2172                 raise Exception("Unexpected SESSION_INITIATE result")
2173
2174         res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2175         if not res.startswith("OK"):
2176             raise Exception("SESSION_INITIATE failed")
2177
2178         tests = [ "", "foo", sid, sid + " foo", sid + " foo=bar" ]
2179         for t in tests:
2180             res = initiator.grequest("FST-MANAGER SESSION_SET " + t)
2181             if not res.startswith("FAIL"):
2182                 raise Exception("Invalid SESSION_SET accepted")
2183
2184         with alloc_fail(hapd, 1, "fst_session_send_action"):
2185             res = initiator.grequest("FST-MANAGER SESSION_TEARDOWN " + sid)
2186             if not res.startswith("FAIL"):
2187                 raise Exception("Unexpected SESSION_TEARDOWN result")
2188     finally:
2189         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2190         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2191
2192 def test_fst_session_oom(dev, apdev, test_params):
2193     """FST session create OOM"""
2194     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2195     try:
2196         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2197         hapd = ap1.get_instance()
2198         sta = sta1.get_instance()
2199         dst = sta.own_addr()
2200         src = apdev[0]['bssid']
2201
2202         # Create session
2203         initiator = ap1
2204         responder = sta1
2205         new_iface = ap2.ifname()
2206         new_peer_addr = ap2.get_actual_peer_addr()
2207         resp_newif = sta2.ifname()
2208         peeraddr = None
2209         initiator.add_peer(responder, peeraddr, new_peer_addr)
2210         with alloc_fail(hapd, 1, "fst_session_create"):
2211             sid = initiator.grequest("FST-MANAGER SESSION_ADD " + initiator.fst_group)
2212             if not sid.startswith("FAIL"):
2213                 raise Exception("Unexpected SESSION_ADD success")
2214         sid = initiator.add_session()
2215         initiator.configure_session(sid, new_iface)
2216         with alloc_fail(sta, 1, "fst_session_create"):
2217             res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2218             if not res.startswith("OK"):
2219                 raise Exception("Unexpected SESSION_INITIATE result")
2220     finally:
2221         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2222         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2223
2224 def test_fst_attach_zero_llt(dev, apdev):
2225     """FST attach with llt=0"""
2226     sta1 = fst_module_aux.FstSTA('wlan5', fst_test_common.fst_test_def_group,
2227                                  "100", "0")
2228     sta1.start()
2229     sta1.stop()
2230
2231 def test_fst_session_respond_fail(dev, apdev, test_params):
2232     """FST-MANAGER SESSION_RESPOND failure"""
2233     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2234     try:
2235         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2236         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
2237         sid = sta1.add_session()
2238         sta1.configure_session(sid, sta2.ifname())
2239         sta1.send_session_setup_request(sid)
2240         sta1.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
2241         ev = ap1.wait_for_session_event(5, [], ['EVENT_FST_SETUP'])
2242         if not 'id' in ev:
2243             raise Exception("No session id in FST setup event")
2244         # Disconnect STA to make SESSION_RESPOND fail due to no peer found
2245         sta = sta1.get_instance()
2246         sta.request("DISCONNECT")
2247         sta.wait_disconnected()
2248         req = "FST-MANAGER SESSION_RESPOND %s reject" % ev['id']
2249         s = ap1.grequest(req)
2250         if not s.startswith("FAIL"):
2251             raise Exception("SESSION_RESPOND succeeded unexpectedly")
2252     finally:
2253         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2254         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2255
2256 def fst_session_set(dev, sid, param, value):
2257     cmd = "FST-MANAGER SESSION_SET %s %s=%s" % (sid, param, value)
2258     if "OK" not in dev.global_request(cmd):
2259         raise Exception(cmd + " failed")
2260
2261 def fst_session_set_ap(dev, sid, param, value):
2262     cmd = "FST-MANAGER SESSION_SET %s %s=%s" % (sid, param, value)
2263     if "OK" not in dev.request(cmd):
2264         raise Exception(cmd + " failed")
2265
2266 def fst_attach_ap(dev, ifname, group):
2267     cmd = "FST-ATTACH %s %s" % (ifname, group)
2268     if "OK" not in dev.request(cmd):
2269         raise Exception("FST-ATTACH (AP) failed")
2270     ev = dev.wait_event(['FST-EVENT-IFACE'], timeout=5)
2271     if ev is None:
2272         raise Exception("No FST-EVENT-IFACE attached (AP)")
2273     for t in [ "attached", "ifname=" + ifname, "group=" + group ]:
2274         if t not in ev:
2275             raise Exception("Unexpected FST-EVENT-IFACE data (AP): " + ev)
2276
2277 def fst_attach_sta(dev, ifname, group):
2278     if "OK" not in dev.global_request("FST-ATTACH %s %s" % (ifname, group)):
2279         raise Exception("FST-ATTACH (STA) failed")
2280     ev = dev.wait_global_event(['FST-EVENT-IFACE'], timeout=5)
2281     if ev is None:
2282         raise Exception("No FST-EVENT-IFACE attached (STA)")
2283     for t in [ "attached", "ifname=" + ifname, "group=" + group ]:
2284         if t not in ev:
2285             raise Exception("Unexpected FST-EVENT-IFACE data (STA): " + ev)
2286
2287 def fst_detach_ap(dev, ifname, group):
2288     if "OK" not in dev.request("FST-DETACH " + ifname):
2289         raise Exception("FST-DETACH (AP) failed for " + ifname)
2290     ev = dev.wait_event(['FST-EVENT-IFACE'], timeout=5)
2291     if ev is None:
2292         raise Exception("No FST-EVENT-IFACE detached (AP) for " + ifname)
2293     for t in [ "detached", "ifname=" + ifname, "group=" + group ]:
2294         if t not in ev:
2295             raise Exception("Unexpected FST-EVENT-IFACE data (AP): " + ev)
2296
2297 def fst_detach_sta(dev, ifname, group):
2298     dev.dump_monitor()
2299     if "OK" not in dev.global_request("FST-DETACH " + ifname):
2300         raise Exception("FST-DETACH (STA) failed for " + ifname)
2301     ev = dev.wait_global_event(['FST-EVENT-IFACE'], timeout=5)
2302     if ev is None:
2303         raise Exception("No FST-EVENT-IFACE detached (STA) for " + ifname)
2304     for t in [ "detached", "ifname=" + ifname, "group=" + group ]:
2305         if t not in ev:
2306             raise Exception("Unexpected FST-EVENT-IFACE data (STA): " + ev)
2307
2308 def fst_wait_event_peer_ap(dev, event, ifname, addr):
2309     ev = dev.wait_event(['FST-EVENT-PEER'], timeout=5)
2310     if ev is None:
2311         raise Exception("No FST-EVENT-PEER connected (AP)")
2312     for t in [ " " + event + " ", "ifname=" + ifname, "peer_addr=" + addr ]:
2313         if t not in ev:
2314             raise Exception("Unexpected FST-EVENT-PEER data (AP): " + ev)
2315
2316 def fst_wait_event_peer_sta(dev, event, ifname, addr):
2317     ev = dev.wait_global_event(['FST-EVENT-PEER'], timeout=5)
2318     if ev is None:
2319         raise Exception("No FST-EVENT-PEER connected (STA)")
2320     for t in [ " " + event + " ", "ifname=" + ifname, "peer_addr=" + addr ]:
2321         if t not in ev:
2322             raise Exception("Unexpected FST-EVENT-PEER data (STA): " + ev)
2323
2324 def fst_setup_req(dev, hglobal, freq, dst, req, stie, mbie="", no_wait=False):
2325     act = req + stie + mbie
2326     dev.request("MGMT_TX %s %s freq=%d action=%s" % (dst, dst, freq, act))
2327     ev = dev.wait_event(['MGMT-TX-STATUS'], timeout=5)
2328     if ev is None or "result=SUCCESS" not in ev:
2329         raise Exception("FST Action frame not ACKed")
2330
2331     if no_wait:
2332         return
2333     while True:
2334         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2335         if ev is None:
2336             raise Exception("No FST-EVENT-SESSION (AP)")
2337         if "new_state=SETUP_COMPLETION" in ev:
2338             break
2339
2340 def fst_start_and_connect(apdev, group, sgroup):
2341     hglobal = hostapd.HostapdGlobal()
2342     if "OK" not in hglobal.request("FST-MANAGER TEST_REQUEST IS_SUPPORTED"):
2343         raise HwsimSkip("No FST testing support")
2344
2345     params = { "ssid": "fst_11a", "hw_mode": "a", "channel": "36",
2346                "country_code": "US" }
2347     hapd = hostapd.add_ap(apdev[0], params)
2348
2349     fst_attach_ap(hglobal, apdev[0]['ifname'], group)
2350
2351     cmd = "FST-ATTACH %s %s" % (apdev[0]['ifname'], group)
2352     if "FAIL" not in hglobal.request(cmd):
2353         raise Exception("Duplicated FST-ATTACH (AP) accepted")
2354
2355     params = { "ssid": "fst_11g", "hw_mode": "g", "channel": "1",
2356                "country_code": "US" }
2357     hapd2 = hostapd.add_ap(apdev[1], params)
2358     fst_attach_ap(hglobal, apdev[1]['ifname'], group)
2359
2360     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2361     wpas.interface_add("wlan5")
2362     fst_attach_sta(wpas, wpas.ifname, sgroup)
2363
2364     wpas.interface_add("wlan6", set_ifname=False)
2365     wpas2 = WpaSupplicant(ifname="wlan6")
2366     fst_attach_sta(wpas, wpas2.ifname, sgroup)
2367
2368     wpas.connect("fst_11a", key_mgmt="NONE", scan_freq="5180",
2369                  wait_connect=False)
2370     wpas.wait_connected()
2371
2372     fst_wait_event_peer_sta(wpas, "connected", wpas.ifname, apdev[0]['bssid'])
2373     fst_wait_event_peer_ap(hglobal, "connected", apdev[0]['ifname'],
2374                            wpas.own_addr())
2375
2376     wpas2.connect("fst_11g", key_mgmt="NONE", scan_freq="2412",
2377                   wait_connect=False)
2378     wpas2.wait_connected()
2379
2380     fst_wait_event_peer_sta(wpas, "connected", wpas2.ifname, apdev[1]['bssid'])
2381     fst_wait_event_peer_ap(hglobal, "connected", apdev[1]['ifname'],
2382                            wpas2.own_addr())
2383     return hglobal, wpas, wpas2, hapd, hapd2
2384
2385 def test_fst_test_setup(dev, apdev, test_params):
2386     """FST setup using separate commands"""
2387     try:
2388         _test_fst_test_setup(dev, apdev, test_params)
2389     finally:
2390         subprocess.call(['iw', 'reg', 'set', '00'])
2391         dev[0].flush_scan_cache()
2392         dev[1].flush_scan_cache()
2393
2394 def _test_fst_test_setup(dev, apdev, test_params):
2395     group = "fstg0b"
2396     sgroup = "fstg1b"
2397     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2398
2399     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2400     if "FAIL" in sid:
2401         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2402
2403     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2404     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2405     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2406     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2407
2408     if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2409         raise Exception("FST-MANAGER SESSION_INITIATE failed")
2410
2411     while True:
2412         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2413         if ev is None:
2414             raise Exception("No FST-EVENT-SESSION (AP)")
2415         if "new_state=SETUP_COMPLETION" in ev:
2416             f = re.search("session_id=(\d+)", ev)
2417             if f is None:
2418                 raise Exception("No session_id in FST-EVENT-SESSION")
2419             sid_ap = f.group(1)
2420             cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2421             if "OK" not in hglobal.request(cmd):
2422                 raise Exception("FST-MANAGER SESSION_RESPOND failed on AP")
2423             break
2424
2425     ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2426     if ev is None:
2427         raise Exception("No FST-EVENT-SESSION")
2428     if "new_state=SETUP_COMPLETION" not in ev:
2429         raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2430
2431     ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2432     if ev is None:
2433         raise Exception("No FST-EVENT-SESSION")
2434     if "event_type=EVENT_FST_ESTABLISHED" not in ev:
2435         raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2436
2437     cmd = "FST-MANAGER SESSION_REMOVE " + sid
2438     if "OK" not in wpas.global_request(cmd):
2439         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2440     ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2441     if ev is None:
2442         raise Exception("No FST-EVENT-SESSION")
2443     if "new_state=INITIAL" not in ev:
2444         raise Exception("Unexpected FST-EVENT-SESSION data (STA): " + ev)
2445
2446     ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2447     if ev is None:
2448         raise Exception("No FST-EVENT-SESSION (AP)")
2449     if "new_state=INITIAL" not in ev:
2450         raise Exception("Unexpected FST-EVENT-SESSION data (AP): " + ev)
2451
2452     if "FAIL" not in wpas.global_request(cmd):
2453         raise Exception("Duplicated FST-MANAGER SESSION_REMOVE accepted")
2454
2455     hglobal.request("FST-MANAGER SESSION_REMOVE " + sid_ap)
2456
2457     wpas.request("DISCONNECT")
2458     wpas.wait_disconnected()
2459     fst_wait_event_peer_sta(wpas, "disconnected", wpas.ifname,
2460                             apdev[0]['bssid'])
2461     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[0]['ifname'],
2462                            wpas.own_addr())
2463
2464     wpas2.request("DISCONNECT")
2465     wpas2.wait_disconnected()
2466     fst_wait_event_peer_sta(wpas, "disconnected", wpas2.ifname,
2467                             apdev[1]['bssid'])
2468     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[1]['ifname'],
2469                            wpas2.own_addr())
2470
2471     fst_detach_ap(hglobal, apdev[0]['ifname'], group)
2472     if "FAIL" not in hglobal.request("FST-DETACH " + apdev[0]['ifname']):
2473         raise Exception("Duplicated FST-DETACH (AP) accepted")
2474     hapd.disable()
2475
2476     fst_detach_ap(hglobal, apdev[1]['ifname'], group)
2477     hapd2.disable()
2478
2479     fst_detach_sta(wpas, wpas.ifname, sgroup)
2480     fst_detach_sta(wpas, wpas2.ifname, sgroup)
2481
2482 def test_fst_setup_mbie_diff(dev, apdev, test_params):
2483     """FST setup and different MBIE in FST Setup Request"""
2484     try:
2485         _test_fst_setup_mbie_diff(dev, apdev, test_params)
2486     finally:
2487         subprocess.call(['iw', 'reg', 'set', '00'])
2488         dev[0].flush_scan_cache()
2489         dev[1].flush_scan_cache()
2490
2491 def _test_fst_setup_mbie_diff(dev, apdev, test_params):
2492     group = "fstg0c"
2493     sgroup = "fstg1c"
2494     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2495
2496     # FST Setup Request: Category, FST Action, Dialog Token (non-zero),
2497     # LLT (32 bits, see 10.32), Session Transition (see 8.4.2.147),
2498     # Multi-band element (optional, see 8.4.2.140)
2499
2500     # Session Transition: EID, Len, FSTS ID(4), Session Control,
2501     # New Band (Band ID, Setup, Operation), Old Band (Band ID, Setup, Operation)
2502
2503     # Multi-band element: EID, Len, Multi-band Control, Band ID,
2504     # Operating Class, Channel Number, BSSID (6), Beacon Interval (2),
2505     # TSF Offset (8), Multi-band Connection Capability, FSTSessionTimeOut,
2506     # STA MAC Address (6, optional), Pairwise Cipher Suite Count (2, optional),
2507     # Pairwise Cipher Suite List (4xm, optional)
2508
2509     # MBIE with the non-matching STA MAC Address:
2510     req = "1200011a060000"
2511     stie = "a40b0100000000020001040001"
2512     mbie = "9e1c0c0200010200000004000000000000000000000000ff0200000006ff"
2513     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2514
2515     # MBIE without the STA MAC Address:
2516     req = "1200011a060000"
2517     stie = "a40b0100000000020001040001"
2518     mbie = "9e16040200010200000004000000000000000000000000ff"
2519     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2520
2521     # MBIE with unsupported STA Role:
2522     req = "1200011a060000"
2523     stie = "a40b0100000000020001040001"
2524     mbie = "9e16070200010200000004000000000000000000000000ff"
2525     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2526
2527     # MBIE with unsupported Band ID:
2528     req = "1200011a060000"
2529     stie = "a40b0100000000020001040001"
2530     mbie = "9e1604ff00010200000004000000000000000000000000ff"
2531     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie, mbie)
2532
2533     # FST Setup Request without MBIE (different FSTS ID):
2534     req = "1200011a060000"
2535     stie = "a40b0200000000020001040001"
2536     fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie)
2537
2538     # MBIE update OOM on AP
2539     req = "1200011a060000"
2540     stie = "a40b0100000000020001040001"
2541     mbie = "9e16040200010200000004000000000000000000000000ff"
2542     try:
2543         with alloc_fail(hapd, 1, "mb_ies_by_info"):
2544             fst_setup_req(wpas, hglobal, 5180, apdev[0]['bssid'], req, stie,
2545                           mbie, no_wait=True)
2546     except HwsimSkip, e:
2547         # Skip exception to allow proper cleanup
2548         pass
2549
2550     # Remove sessions to avoid causing issues to following test ases
2551     s = hglobal.request("FST-MANAGER LIST_SESSIONS " + group)
2552     if not s.startswith("FAIL"):
2553         for sid in s.split(' '):
2554             if len(sid):
2555                 hglobal.request("FST-MANAGER SESSION_REMOVE " + sid)
2556
2557 def test_fst_many_setup(dev, apdev, test_params):
2558     """FST setup multiple times"""
2559     try:
2560         _test_fst_many_setup(dev, apdev, test_params)
2561     finally:
2562         subprocess.call(['iw', 'reg', 'set', '00'])
2563         dev[0].flush_scan_cache()
2564         dev[1].flush_scan_cache()
2565
2566 def _test_fst_many_setup(dev, apdev, test_params):
2567     group = "fstg0d"
2568     sgroup = "fstg1d"
2569     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2570
2571     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2572     if "FAIL" in sid:
2573         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2574
2575     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2576     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2577     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2578     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2579
2580     for i in range(257):
2581         if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2582             raise Exception("FST-MANAGER SESSION_INITIATE failed")
2583
2584         while True:
2585             ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2586             if ev is None:
2587                 raise Exception("No FST-EVENT-SESSION (AP)")
2588             if "new_state=SETUP_COMPLETION" in ev:
2589                 f = re.search("session_id=(\d+)", ev)
2590                 if f is None:
2591                     raise Exception("No session_id in FST-EVENT-SESSION")
2592                 sid_ap = f.group(1)
2593                 cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2594                 if "OK" not in hglobal.request(cmd):
2595                     raise Exception("FST-MANAGER SESSION_RESPOND failed on AP")
2596                 break
2597
2598         ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2599         if ev is None:
2600             raise Exception("No FST-EVENT-SESSION (STA)")
2601         if "new_state=SETUP_COMPLETION" not in ev:
2602             raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2603
2604         ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2605         if ev is None:
2606             raise Exception("No FST-EVENT-SESSION (STA)")
2607         if "event_type=EVENT_FST_ESTABLISHED" not in ev:
2608             raise Exception("Unexpected FST-EVENT-SESSION data: " + ev)
2609
2610         if "OK" not in wpas.global_request("FST-MANAGER SESSION_TEARDOWN " + sid):
2611             raise Exception("FST-MANAGER SESSION_INITIATE failed")
2612
2613         if i == 0:
2614             if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_TEARDOWN " + sid):
2615                 raise Exception("Duplicate FST-MANAGER SESSION_TEARDOWN accepted")
2616
2617         ev = wpas.wait_global_event(["FST-EVENT-SESSION"], timeout=5)
2618         if ev is None:
2619             raise Exception("No FST-EVENT-SESSION (STA teardown -->initial)")
2620         if "new_state=INITIAL" not in ev:
2621             raise Exception("Unexpected FST-EVENT-SESSION data (STA): " + ev)
2622
2623         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2624         if ev is None:
2625             raise Exception("No FST-EVENT-SESSION (AP teardown -->initial)")
2626         if "new_state=INITIAL" not in ev:
2627             raise Exception("Unexpected FST-EVENT-SESSION data (AP): " + ev)
2628
2629         if "OK" not in hglobal.request("FST-MANAGER SESSION_REMOVE " + sid_ap):
2630             raise Exception("FST-MANAGER SESSION_REMOVE (AP) failed")
2631
2632     if "OK" not in wpas.global_request("FST-MANAGER SESSION_REMOVE " + sid):
2633         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2634
2635     wpas.request("DISCONNECT")
2636     wpas.wait_disconnected()
2637     fst_wait_event_peer_sta(wpas, "disconnected", wpas.ifname,
2638                             apdev[0]['bssid'])
2639     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[0]['ifname'],
2640                            wpas.own_addr())
2641
2642     wpas2.request("DISCONNECT")
2643     wpas2.wait_disconnected()
2644     fst_wait_event_peer_sta(wpas, "disconnected", wpas2.ifname,
2645                             apdev[1]['bssid'])
2646     fst_wait_event_peer_ap(hglobal, "disconnected", apdev[1]['ifname'],
2647                            wpas2.own_addr())
2648
2649     fst_detach_ap(hglobal, apdev[0]['ifname'], group)
2650     fst_detach_ap(hglobal, apdev[1]['ifname'], group)
2651     hapd.disable()
2652     hapd2.disable()
2653
2654     fst_detach_sta(wpas, wpas.ifname, sgroup)
2655     fst_detach_sta(wpas, wpas2.ifname, sgroup)
2656
2657 def test_fst_attach_wpas_error(dev, apdev, test_params):
2658     """FST attach errors in wpa_supplicant"""
2659     if "OK" not in dev[0].global_request("FST-MANAGER TEST_REQUEST IS_SUPPORTED"):
2660         raise HwsimSkip("No FST testing support")
2661     group = "fstg0"
2662     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2663     wpas.interface_add("wlan5")
2664     fst_attach_sta(wpas, wpas.ifname, group)
2665     if "FAIL" not in wpas.global_request("FST-ATTACH %s %s" % (wpas.ifname,
2666                                                                group)):
2667         raise Exception("Duplicated FST-ATTACH accepted")
2668     if "FAIL" not in wpas.global_request("FST-ATTACH %s %s" % ("foofoo",
2669                                                                group)):
2670         raise Exception("FST-ATTACH for unknown interface accepted")
2671
2672 def test_fst_session_initiate_errors(dev, apdev, test_params):
2673     """FST SESSION_INITIATE error cases"""
2674     try:
2675         _test_fst_session_initiate_errors(dev, apdev, test_params)
2676     finally:
2677         subprocess.call(['iw', 'reg', 'set', '00'])
2678         dev[0].flush_scan_cache()
2679         dev[1].flush_scan_cache()
2680
2681 def _test_fst_session_initiate_errors(dev, apdev, test_params):
2682     group = "fstg0"
2683     sgroup = "fstg1"
2684     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2685
2686     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2687     if "FAIL" in sid:
2688         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2689
2690     # No old peer MAC address
2691     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2692         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2693
2694     fst_session_set(wpas, sid, "old_peer_addr", "00:ff:ff:ff:ff:ff")
2695     # No new peer MAC address
2696     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2697         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2698
2699     fst_session_set(wpas, sid, "new_peer_addr", "00:ff:ff:ff:ff:fe")
2700     # No old interface defined
2701     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2702         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2703
2704     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2705     # No new interface defined
2706     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2707         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2708
2709     fst_session_set(wpas, sid, "new_ifname", wpas.ifname)
2710     # Same interface set as old and new
2711     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2712         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2713
2714     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2715     # The preset old peer address is not connected
2716     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2717         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2718
2719     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2720     # The preset new peer address is not connected
2721     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2722         raise Exception("Invalid FST-MANAGER SESSION_INITIATE accepted")
2723
2724     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2725     # Initiate session setup
2726     if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2727         raise Exception("FST-MANAGER SESSION_INITIATE failed")
2728
2729     # Session in progress
2730     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2731         raise Exception("Duplicated FST-MANAGER SESSION_INITIATE accepted")
2732
2733     sid2 = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2734     if "FAIL" in sid:
2735         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2736     fst_session_set(wpas, sid2, "old_ifname", wpas.ifname)
2737     fst_session_set(wpas, sid2, "old_peer_addr", apdev[0]['bssid'])
2738     fst_session_set(wpas, sid2, "new_ifname", wpas2.ifname)
2739     fst_session_set(wpas, sid2, "new_peer_addr", apdev[1]['bssid'])
2740
2741     # There is another session in progress (old)
2742     if "FAIL" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid2):
2743         raise Exception("Duplicated FST-MANAGER SESSION_INITIATE accepted")
2744
2745     if "OK" not in wpas.global_request("FST-MANAGER SESSION_REMOVE " + sid):
2746         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2747
2748     while True:
2749         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2750         if ev is None:
2751             raise Exception("No FST-EVENT-SESSION (AP)")
2752         if "new_state=SETUP_COMPLETION" in ev:
2753             f = re.search("session_id=(\d+)", ev)
2754             if f is None:
2755                 raise Exception("No session_id in FST-EVENT-SESSION")
2756             sid_ap = f.group(1)
2757             break
2758     if "OK" not in hglobal.request("FST-MANAGER SESSION_REMOVE " + sid_ap):
2759         raise Exception("FST-MANAGER SESSION_REMOVE (AP) failed")
2760
2761     if "OK" not in wpas.global_request("FST-MANAGER SESSION_REMOVE " + sid2):
2762         raise Exception("FST-MANAGER SESSION_REMOVE failed")
2763
2764 def test_fst_session_respond_errors(dev, apdev, test_params):
2765     """FST SESSION_RESPOND error cases"""
2766     try:
2767         _test_fst_session_respond_errors(dev, apdev, test_params)
2768     finally:
2769         subprocess.call(['iw', 'reg', 'set', '00'])
2770         dev[0].flush_scan_cache()
2771         dev[1].flush_scan_cache()
2772
2773 def _test_fst_session_respond_errors(dev, apdev, test_params):
2774     group = "fstg0b"
2775     sgroup = "fstg1b"
2776     hglobal, wpas, wpas2, hapd, hapd2 = fst_start_and_connect(apdev, group, sgroup)
2777
2778     sid = wpas.global_request("FST-MANAGER SESSION_ADD " + sgroup).strip()
2779     if "FAIL" in sid:
2780         raise Exception("FST-MANAGER SESSION_ADD (STA) failed")
2781
2782     fst_session_set(wpas, sid, "old_ifname", wpas.ifname)
2783     fst_session_set(wpas, sid, "old_peer_addr", apdev[0]['bssid'])
2784     fst_session_set(wpas, sid, "new_ifname", wpas2.ifname)
2785     fst_session_set(wpas, sid, "new_peer_addr", apdev[1]['bssid'])
2786
2787     if "OK" not in wpas.global_request("FST-MANAGER SESSION_INITIATE " + sid):
2788         raise Exception("FST-MANAGER SESSION_INITIATE failed")
2789
2790     while True:
2791         ev = hglobal.wait_event(['FST-EVENT-SESSION'], timeout=5)
2792         if ev is None:
2793             raise Exception("No FST-EVENT-SESSION (AP)")
2794         if "new_state=SETUP_COMPLETION" in ev:
2795             f = re.search("session_id=(\d+)", ev)
2796             if f is None:
2797                 raise Exception("No session_id in FST-EVENT-SESSION")
2798             sid_ap = f.group(1)
2799             break
2800
2801     # The preset peer address is not in the peer list
2802     fst_session_set_ap(hglobal, sid_ap, "old_peer_addr", "00:00:00:00:00:01")
2803     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2804     if "FAIL" not in hglobal.request(cmd):
2805         raise Exception("Invalid FST-MANAGER SESSION_RESPOND accepted")
2806
2807     # Same interface set as old and new
2808     fst_session_set_ap(hglobal, sid_ap, "old_peer_addr", wpas.own_addr())
2809     fst_session_set_ap(hglobal, sid_ap, "old_ifname", apdev[1]['ifname'])
2810     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2811     if "FAIL" not in hglobal.request(cmd):
2812         raise Exception("Invalid FST-MANAGER SESSION_RESPOND accepted")
2813
2814     # valid command
2815     fst_session_set_ap(hglobal, sid_ap, "old_ifname", apdev[0]['ifname'])
2816     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2817     if "OK" not in hglobal.request(cmd):
2818         raise Exception("FST-MANAGER SESSION_RESPOND failed")
2819
2820     # incorrect state
2821     cmd = "FST-MANAGER SESSION_RESPOND %s accept" % sid_ap
2822     if "FAIL" not in hglobal.request(cmd):
2823         raise Exception("Invalid FST-MANAGER SESSION_RESPOND accepted")
2824
2825     cmd = "FST-MANAGER SESSION_REMOVE " + sid
2826     if "OK" not in wpas.global_request(cmd):
2827         raise Exception("FST-MANAGER SESSION_REMOVE (STA) failed")
2828
2829     cmd = "FST-MANAGER SESSION_REMOVE %s" % sid_ap
2830     if "OK" not in hglobal.request(cmd):
2831         raise Exception("FST-MANAGER SESSION_REMOVE (AP) failed")