tests: FST protocol tests to verify invalid STIE header
[mech_eap.git] / 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
14 import hwsim_utils
15 from hwsim import HWSimRadio
16 import hostapd
17 import fst_test_common
18 import fst_module_aux
19 from utils import alloc_fail
20
21 #enum - bad parameter types
22 bad_param_none = 0
23 bad_param_session_add_no_params = 1
24 bad_param_group_id = 2
25 bad_param_session_set_no_params = 3
26 bad_param_session_set_unknown_param = 4
27 bad_param_session_id = 5
28 bad_param_old_iface = 6
29 bad_param_new_iface = 7
30 bad_param_negative_llt = 8
31 bad_param_zero_llt = 9
32 bad_param_llt_too_big = 10
33 bad_param_llt_nan = 11
34 bad_param_peer_addr = 12
35 bad_param_session_initiate_no_params = 13
36 bad_param_session_initiate_bad_session_id = 14
37 bad_param_session_initiate_with_no_new_iface_set = 15
38 bad_param_session_initiate_with_bad_peer_addr_set = 16
39 bad_param_session_initiate_request_with_bad_stie = 17
40 bad_param_session_initiate_response_with_reject = 18
41 bad_param_session_initiate_response_with_bad_stie = 19
42 bad_param_session_initiate_response_with_zero_llt = 20
43 bad_param_session_initiate_stt_no_response = 21
44 bad_param_session_initiate_concurrent_setup_request = 22
45 bad_param_session_transfer_no_params = 23
46 bad_param_session_transfer_bad_session_id = 24
47 bad_param_session_transfer_setup_skipped = 25
48 bad_param_session_teardown_no_params = 26
49 bad_param_session_teardown_bad_session_id = 27
50 bad_param_session_teardown_setup_skipped = 28
51 bad_param_session_teardown_bad_fsts_id = 29
52
53 bad_param_names = ("None",
54                    "No params passed to session add",
55                    "Group ID",
56                    "No params passed to session set",
57                    "Unknown param passed to session set",
58                    "Session ID",
59                    "Old interface name",
60                    "New interface name",
61                    "Negative LLT",
62                    "Zero LLT",
63                    "LLT too big",
64                    "LLT is not a number",
65                    "Peer address",
66                    "No params passed to session initiate",
67                    "Session ID",
68                    "No new_iface was set",
69                    "Peer address",
70                    "Request with bad st ie",
71                    "Response with reject",
72                    "Response with bad st ie",
73                    "Response with zero llt",
74                    "No response, STT",
75                    "Concurrent setup request",
76                    "No params passed to session transfer",
77                    "Session ID",
78                    "Session setup skipped",
79                    "No params passed to session teardown",
80                    "Bad session",
81                    "Session setup skipped",
82                    "Bad fsts_id")
83
84 def fst_start_session(apdev, test_params, bad_param_type, start_on_ap,
85                       peer_addr = None):
86     """This function makes the necessary preparations and the adds and sets a
87     session using either correct or incorrect parameters depending on the value
88     of bad_param_type. If the call ends as expected (with session being
89     successfully added and set in case of correct parameters or with the
90     expected exception in case of incorrect parameters), the function silently
91     exits. Otherwise, it throws an exception thus failing the test."""
92
93     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
94     bad_parameter_detected = False
95     exception_already_raised = False
96     try:
97         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
98         if start_on_ap:
99             initiator = ap1
100             responder = sta1
101             new_iface = ap2.ifname()
102             new_peer_addr = ap2.get_actual_peer_addr()
103         else:
104             initiator = sta1
105             responder = ap1
106             new_iface = sta2.ifname()
107             new_peer_addr = sta2.get_actual_peer_addr()
108         initiator.add_peer(responder, peer_addr, new_peer_addr)
109         group_id = None
110         if bad_param_type == bad_param_group_id:
111             group_id = '-1'
112         elif bad_param_type == bad_param_session_add_no_params:
113             group_id = ''
114         initiator.set_fst_parameters(group_id=group_id)
115         sid = initiator.add_session()
116         if bad_param_type == bad_param_session_set_no_params:
117             res = initiator.set_session_param(None)
118             if not res.startswith("OK"):
119                 raise Exception("Session set operation failed")
120         elif bad_param_type == bad_param_session_set_unknown_param:
121             res = initiator.set_session_param("bad_param=1")
122             if not res.startswith("OK"):
123                 raise Exception("Session set operation failed")
124         else:
125             if bad_param_type == bad_param_session_initiate_with_no_new_iface_set:
126                 new_iface = None
127             elif bad_param_type == bad_param_new_iface:
128                 new_iface = 'wlan12'
129             old_iface = None if bad_param_type != bad_param_old_iface else 'wlan12'
130             llt = None
131             if bad_param_type == bad_param_negative_llt:
132                 llt = '-1'
133             elif bad_param_type == bad_param_zero_llt:
134                 llt = '0'
135             elif bad_param_type == bad_param_llt_too_big:
136                 llt = '4294967296'    #0x100000000
137             elif bad_param_type == bad_param_llt_nan:
138                 llt = 'nan'
139             elif bad_param_type == bad_param_session_id:
140                 sid = '-1'
141             initiator.set_fst_parameters(llt=llt)
142             initiator.configure_session(sid, new_iface, old_iface)
143     except Exception, e:
144         if e.args[0].startswith("Cannot add FST session with groupid"):
145             if bad_param_type == bad_param_group_id or bad_param_type == bad_param_session_add_no_params:
146                 bad_parameter_detected = True
147         elif e.args[0].startswith("Cannot set FST session new_ifname:"):
148             if bad_param_type == bad_param_new_iface:
149                 bad_parameter_detected = True
150         elif e.args[0].startswith("Session set operation failed"):
151             if (bad_param_type == bad_param_session_set_no_params or
152                 bad_param_type == bad_param_session_set_unknown_param):
153                 bad_parameter_detected = True
154         elif e.args[0].startswith("Cannot set FST session old_ifname:"):
155             if (bad_param_type == bad_param_old_iface or
156                 bad_param_type == bad_param_session_id or
157                 bad_param_type == bad_param_session_set_no_params):
158                 bad_parameter_detected = True
159         elif e.args[0].startswith("Cannot set FST session llt:"):
160             if (bad_param_type == bad_param_negative_llt or
161                 bad_param_type == bad_param_llt_too_big or
162                 bad_param_type == bad_param_llt_nan):
163                 bad_parameter_detected = True
164         elif e.args[0].startswith("Cannot set FST session peer address:"):
165             if bad_param_type == bad_param_peer_addr:
166                 bad_parameter_detected = True
167         if not bad_parameter_detected:
168             # The exception was unexpected
169             logger.info(e)
170             exception_already_raised = True
171             raise
172     finally:
173         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
174         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
175         if not exception_already_raised:
176             if bad_parameter_detected:
177                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
178             else:
179                 if bad_param_type == bad_param_none or bad_param_type == bad_param_zero_llt:
180                     logger.info("Success. Session added and set")
181                 else:
182                     exception_text = ""
183                     if bad_param_type == bad_param_peer_addr:
184                         exception_text = "Failure. Bad parameter was not detected (Peer address == %s)" % ap1.get_new_peer_addr()
185                     else:
186                         exception_text = "Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type]
187                     raise Exception(exception_text)
188         else:
189             print "Failure. Unexpected exception"
190
191 def fst_initiate_session(apdev, test_params, bad_param_type, init_on_ap):
192     """This function makes the necessary preparations and then adds, sets and
193     initiates a session using either correct or incorrect parameters at each
194     stage depending on the value of bad_param_type. If the call ends as expected
195     (with session being successfully added, set and initiated in case of correct
196     parameters or with the expected exception in case of incorrect parameters),
197     the function silently exits. Otherwise it throws an exception thus failing
198     the test."""
199     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
200     bad_parameter_detected = False
201     exception_already_raised = False
202     try:
203         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
204         # This call makes sure FstHostapd singleton object is created and, as a
205         # result, the global control interface is registered (this is done from
206         # the constructor).
207         ap1.get_global_instance()
208         if init_on_ap:
209             initiator = ap1
210             responder = sta1
211             new_iface = ap2.ifname() if bad_param_type != bad_param_session_initiate_with_no_new_iface_set else None
212             new_peer_addr = ap2.get_actual_peer_addr()
213             resp_newif = sta2.ifname()
214         else:
215             initiator = sta1
216             responder = ap1
217             new_iface = sta2.ifname() if bad_param_type != bad_param_session_initiate_with_no_new_iface_set else None
218             new_peer_addr = sta2.get_actual_peer_addr()
219             resp_newif = ap2.ifname()
220         peeraddr = None if bad_param_type != bad_param_session_initiate_with_bad_peer_addr_set else '10:DE:AD:DE:AD:11'
221         initiator.add_peer(responder, peeraddr, new_peer_addr)
222         if bad_param_type == bad_param_session_initiate_response_with_zero_llt:
223             initiator.set_fst_parameters(llt='0')
224         sid = initiator.add_session()
225         initiator.configure_session(sid, new_iface)
226         if bad_param_type == bad_param_session_initiate_no_params:
227             sid = ''
228         elif bad_param_type == bad_param_session_initiate_bad_session_id:
229             sid = '-1'
230         if bad_param_type == bad_param_session_initiate_request_with_bad_stie:
231             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
232             initiator.send_test_session_setup_request(str(actual_fsts_id), "bad_new_band")
233             responder.wait_for_session_event(5)
234         elif bad_param_type == bad_param_session_initiate_response_with_reject:
235             initiator.send_session_setup_request(sid)
236             initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
237             setup_event = responder.wait_for_session_event(5, [],
238                                                            ['EVENT_FST_SETUP'])
239             if not 'id' in setup_event:
240                 raise Exception("No session id in FST setup event")
241             responder.send_session_setup_response(str(setup_event['id']),
242                                                   "reject")
243             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
244             if event['new_state'] != "INITIAL" or event['reason'] != "REASON_REJECT":
245                 raise Exception("Response with reject not handled as expected")
246             bad_parameter_detected = True
247         elif bad_param_type == bad_param_session_initiate_response_with_bad_stie:
248             initiator.send_session_setup_request(sid)
249             initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
250             responder.wait_for_session_event(5, [], ['EVENT_FST_SETUP'])
251             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
252             responder.send_test_session_setup_response(str(actual_fsts_id),
253                                                        "accept", "bad_new_band")
254             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
255             if event['new_state'] != "INITIAL" or event['reason'] != "REASON_ERROR_PARAMS":
256                 raise Exception("Response with bad STIE not handled as expected")
257             bad_parameter_detected = True
258         elif bad_param_type == bad_param_session_initiate_response_with_zero_llt:
259             initiator.initiate_session(sid, "accept")
260             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
261             if event['new_state'] != "TRANSITION_DONE":
262                 raise Exception("Response reception for a session with llt=0 not handled as expected")
263             bad_parameter_detected = True
264         elif bad_param_type == bad_param_session_initiate_stt_no_response:
265             initiator.send_session_setup_request(sid)
266             initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
267             responder.wait_for_session_event(5, [], ['EVENT_FST_SETUP'])
268             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
269             if event['new_state'] != "INITIAL" or event['reason'] != "REASON_STT":
270                 raise Exception("No response scenario not handled as expected")
271             bad_parameter_detected = True
272         elif bad_param_type == bad_param_session_initiate_concurrent_setup_request:
273             responder.add_peer(initiator)
274             resp_sid = responder.add_session()
275             responder.configure_session(resp_sid, resp_newif)
276             initiator.send_session_setup_request(sid)
277             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
278             responder.send_test_session_setup_request(str(actual_fsts_id))
279             event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
280             initiator_addr = initiator.get_own_mac_address()
281             responder_addr = responder.get_own_mac_address()
282             if initiator_addr < responder_addr:
283                 event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
284                 if event['new_state'] != "INITIAL" or event['reason'] != "REASON_SETUP":
285                     raise Exception("Concurrent setup scenario not handled as expected")
286                 event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SETUP"])
287                 # The incoming setup request received by the initiator has
288                 # priority over the one sent previously by the initiator itself
289                 # because the initiator's MAC address is numerically lower than
290                 # the one of the responder. Thus, the initiator should generate
291                 # an FST_SETUP event.
292             else:
293                 event = initiator.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
294                 if event['new_state'] != "INITIAL" or event['reason'] != "REASON_STT":
295                     raise Exception("Concurrent setup scenario not handled as expected")
296                 # The incoming setup request was dropped at the initiator
297                 # because its MAC address is numerically bigger than the one of
298                 # the responder. Thus, the initiator continue to wait for a
299                 # setup response until the STT event fires.
300             bad_parameter_detected = True
301         else:
302             initiator.initiate_session(sid, "accept")
303     except Exception, e:
304         if e.args[0].startswith("Cannot initiate fst session"):
305             if bad_param_type != bad_param_none:
306                 bad_parameter_detected = True
307         elif e.args[0].startswith("No FST-EVENT-SESSION received"):
308             if bad_param_type == bad_param_session_initiate_request_with_bad_stie:
309                 bad_parameter_detected = True
310         if not bad_parameter_detected:
311             #The exception was unexpected
312             logger.info(e)
313             exception_already_raised = True
314             raise
315     finally:
316         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
317         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
318         if not exception_already_raised:
319             if bad_parameter_detected:
320                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
321             else:
322                 if bad_param_type == bad_param_none:
323                     logger.info("Success. Session initiated")
324                 else:
325                     raise Exception("Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type])
326         else:
327             print "Failure. Unexpected exception"
328
329 def fst_transfer_session(apdev, test_params, bad_param_type, init_on_ap,
330                          rsn=False):
331     """This function makes the necessary preparations and then adds, sets,
332     initiates and attempts to transfer a session using either correct or
333     incorrect parameters at each stage depending on the value of bad_param_type.
334     If the call ends as expected the function silently exits. Otherwise, it
335     throws an exception thus failing the test."""
336     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev, rsn=rsn)
337     bad_parameter_detected = False
338     exception_already_raised = False
339     try:
340         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2, rsn=rsn)
341         # This call makes sure FstHostapd singleton object is created and, as a
342         # result, the global control interface is registered (this is done from
343         # the constructor).
344         ap1.get_global_instance()
345         if init_on_ap:
346             initiator = ap1
347             responder = sta1
348             new_iface = ap2.ifname()
349             new_peer_addr = ap2.get_actual_peer_addr()
350         else:
351             initiator = sta1
352             responder = ap1
353             new_iface = sta2.ifname()
354             new_peer_addr = sta2.get_actual_peer_addr()
355         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
356         sid = initiator.add_session()
357         initiator.configure_session(sid, new_iface)
358         if bad_param_type != bad_param_session_transfer_setup_skipped:
359             initiator.initiate_session(sid, "accept")
360         if bad_param_type == bad_param_session_transfer_no_params:
361             sid = ''
362         elif bad_param_type == bad_param_session_transfer_bad_session_id:
363             sid = '-1'
364         initiator.transfer_session(sid)
365     except Exception, e:
366         if e.args[0].startswith("Cannot transfer fst session"):
367             if bad_param_type != bad_param_none:
368                 bad_parameter_detected = True
369         if not bad_parameter_detected:
370             # The exception was unexpected
371             logger.info(e)
372             exception_already_raised = True
373             raise
374     finally:
375         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
376         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
377         if not exception_already_raised:
378             if bad_parameter_detected:
379                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
380             else:
381                 if bad_param_type == bad_param_none:
382                     logger.info("Success. Session transferred")
383                 else:
384                     raise Exception("Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type])
385         else:
386             print "Failure. Unexpected exception"
387
388
389 def fst_tear_down_session(apdev, test_params, bad_param_type, init_on_ap):
390     """This function makes the necessary preparations and then adds, sets, and
391     initiates a session. It then issues a tear down command using either
392     correct or incorrect parameters at each stage. If the call ends as expected,
393     the function silently exits. Otherwise, it throws an exception thus failing
394     the test."""
395     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
396     bad_parameter_detected = False
397     exception_already_raised = False
398     try:
399         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
400         # This call makes sure FstHostapd singleton object is created and, as a
401         # result, the global control interface is registered (this is done from
402         # the constructor).
403         ap1.get_global_instance()
404         if init_on_ap:
405             initiator = ap1
406             responder = sta1
407             new_iface = ap2.ifname()
408             new_peer_addr = ap2.get_actual_peer_addr()
409         else:
410             initiator = sta1
411             responder = ap1
412             new_iface = sta2.ifname()
413             new_peer_addr = sta2.get_actual_peer_addr()
414         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
415         sid = initiator.add_session()
416         initiator.configure_session(sid, new_iface)
417         if bad_param_type != bad_param_session_teardown_setup_skipped:
418             initiator.initiate_session(sid, "accept")
419         if bad_param_type == bad_param_session_teardown_bad_fsts_id:
420             initiator.send_test_tear_down('-1')
421             responder.wait_for_session_event(5)
422         else:
423             if bad_param_type == bad_param_session_teardown_no_params:
424                 sid = ''
425             elif bad_param_type == bad_param_session_teardown_bad_session_id:
426                 sid = '-1'
427             initiator.teardown_session(sid)
428     except Exception, e:
429         if e.args[0].startswith("Cannot tear down fst session"):
430             if (bad_param_type == bad_param_session_teardown_no_params or
431                 bad_param_type == bad_param_session_teardown_bad_session_id or
432                 bad_param_type == bad_param_session_teardown_setup_skipped):
433                 bad_parameter_detected = True
434         elif e.args[0].startswith("No FST-EVENT-SESSION received"):
435             if bad_param_type == bad_param_session_teardown_bad_fsts_id:
436                 bad_parameter_detected = True
437         if not bad_parameter_detected:
438             # The exception was unexpected
439             logger.info(e)
440             exception_already_raised = True
441             raise
442     finally:
443         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
444         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
445         if not exception_already_raised:
446             if bad_parameter_detected:
447                 logger.info("Success. Bad parameter was detected (%s)" % bad_param_names[bad_param_type])
448             else:
449                 if bad_param_type == bad_param_none:
450                     logger.info("Success. Session torn down")
451                 else:
452                     raise Exception("Failure. Bad parameter was not detected (%s)" % bad_param_names[bad_param_type])
453         else:
454             print "Failure. Unexpected exception"
455
456
457 #enum - remove session scenarios
458 remove_scenario_no_params = 0
459 remove_scenario_bad_session_id = 1
460 remove_scenario_non_established_session = 2
461 remove_scenario_established_session = 3
462
463 remove_scenario_names = ("No params",
464                          "Bad session id",
465                          "Remove non-established session",
466                          "Remove established session")
467
468
469 def fst_remove_session(apdev, test_params, remove_session_scenario, init_on_ap):
470     """This function attempts to remove a session at various stages of its
471     formation, depending on the value of remove_session_scenario. If the call
472     ends as expected, the function silently exits. Otherwise, it throws an
473     exception thus failing the test."""
474     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
475     bad_parameter_detected = False
476     exception_already_raised = False
477     try:
478         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
479         # This call makes sure FstHostapd singleton object is created and, as a
480         # result, the global control interface is registered (this is done from
481         # the constructor).
482         ap1.get_global_instance()
483         if init_on_ap:
484             initiator = ap1
485             responder = sta1
486             new_iface = ap2.ifname()
487             new_peer_addr = ap2.get_actual_peer_addr()
488         else:
489             initiator = sta1
490             responder = ap1
491             new_iface = sta2.ifname()
492             new_peer_addr = sta2.get_actual_peer_addr()
493         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
494         sid = initiator.add_session()
495         initiator.configure_session(sid, new_iface)
496         if remove_session_scenario != remove_scenario_no_params:
497             if remove_session_scenario != remove_scenario_non_established_session:
498                 initiator.initiate_session(sid, "accept")
499         if remove_session_scenario == remove_scenario_no_params:
500             sid = ''
501         elif remove_session_scenario == remove_scenario_bad_session_id:
502             sid = '-1'
503         initiator.remove_session(sid)
504     except Exception, e:
505         if e.args[0].startswith("Cannot remove fst session"):
506             if (remove_session_scenario == remove_scenario_no_params or
507                 remove_session_scenario == remove_scenario_bad_session_id):
508                 bad_parameter_detected = True
509         elif e.args[0].startswith("No FST-EVENT-SESSION received"):
510             if remove_session_scenario == remove_scenario_non_established_session:
511                 bad_parameter_detected = True
512         if not bad_parameter_detected:
513             #The exception was unexpected
514             logger.info(e)
515             exception_already_raised = True
516             raise
517     finally:
518         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
519         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
520         if not exception_already_raised:
521             if bad_parameter_detected:
522                 logger.info("Success. Remove scenario ended as expected (%s)" % remove_scenario_names[remove_session_scenario])
523             else:
524                 if remove_session_scenario == remove_scenario_established_session:
525                     logger.info("Success. Session removed")
526                 else:
527                     raise Exception("Failure. Remove scenario ended in an unexpected way (%s)" % remove_scenario_names[remove_session_scenario])
528         else:
529             print "Failure. Unexpected exception"
530
531
532 #enum - frame types
533 frame_type_session_request = 0
534 frame_type_session_response = 1
535 frame_type_ack_request = 2
536 frame_type_ack_response = 3
537 frame_type_tear_down = 4
538
539 frame_type_names = ("Session request",
540                     "Session Response",
541                     "Ack request",
542                     "Ack response",
543                     "Tear down")
544
545 def fst_send_unexpected_frame(apdev, test_params, frame_type, send_from_ap, additional_param = ''):
546     """This function creates two pairs of APs and stations, makes them connect
547     and then causes one side to send an unexpected FST frame of the specified
548     type to the other. The other side should then identify and ignore the
549     frame."""
550     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
551     exception_already_raised = False
552     frame_receive_timeout = False
553     try:
554         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
555         # This call makes sure FstHostapd singleton object is created and, as a
556         # result, the global control interface is registered (this is done from
557         # the constructor).
558         ap1.get_global_instance()
559         if send_from_ap:
560             sender = ap1
561             receiver = sta1
562             new_iface = ap2.ifname()
563             new_peer_addr = ap2.get_actual_peer_addr()
564         else:
565             sender = sta1
566             receiver = ap1
567             new_iface = sta2.ifname()
568             new_peer_addr = sta2.get_actual_peer_addr()
569         sender.add_peer(receiver, new_peer_addr = new_peer_addr)
570         sid=sender.add_session()
571         sender.configure_session(sid, new_iface)
572         if frame_type == frame_type_session_request:
573             sender.send_session_setup_request(sid)
574             event = receiver.wait_for_session_event(5)
575             if event['type'] != 'EVENT_FST_SETUP':
576                 raise Exception("Unexpected indication: " + event['type'])
577         elif frame_type == frame_type_session_response:
578             #fsts_id doesn't matter, no actual session exists
579             sender.send_test_session_setup_response('0', additional_param)
580             receiver.wait_for_session_event(5)
581         elif frame_type == frame_type_ack_request:
582             #fsts_id doesn't matter, no actual session exists
583             sender.send_test_ack_request('0')
584             receiver.wait_for_session_event(5)
585         elif frame_type == frame_type_ack_response:
586             #fsts_id doesn't matter, no actual session exists
587             sender.send_test_ack_response('0')
588             receiver.wait_for_session_event(5)
589         elif frame_type == frame_type_tear_down:
590             #fsts_id doesn't matter, no actual session exists
591             sender.send_test_tear_down('0')
592             receiver.wait_for_session_event(5)
593     except Exception, e:
594         if e.args[0].startswith("No FST-EVENT-SESSION received"):
595             if frame_type != frame_type_session_request:
596                 frame_receive_timeout = True
597         else:
598             logger.info(e)
599             exception_already_raised = True
600             raise
601     finally:
602         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
603         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
604         if not exception_already_raised:
605             if frame_receive_timeout:
606                 logger.info("Success. Frame was ignored (%s)" % frame_type_names[frame_type])
607             else:
608                 if frame_type == frame_type_session_request:
609                     logger.info("Success. Frame received, session created")
610                 else:
611                     raise Exception("Failure. Frame was not ignored (%s)" % frame_type_names[frame_type])
612         else:
613             print "Failure. Unexpected exception"
614
615
616 #enum - bad session transfer scenarios
617 bad_scenario_none = 0
618 bad_scenario_ack_req_session_not_set_up = 1
619 bad_scenario_ack_req_session_not_established_init_side = 2
620 bad_scenario_ack_req_session_not_established_resp_side = 3
621 bad_scenario_ack_req_bad_fsts_id = 4
622 bad_scenario_ack_resp_session_not_set_up = 5
623 bad_scenario_ack_resp_session_not_established_init_side = 6
624 bad_scenario_ack_resp_session_not_established_resp_side = 7
625 bad_scenario_ack_resp_no_ack_req = 8
626 bad_scenario_ack_resp_bad_fsts_id = 9
627
628 bad_scenario_names = ("None",
629                       "Ack request received before the session was set up",
630                       "Ack request received on the initiator side before session was established",
631                       "Ack request received on the responder side before session was established",
632                       "Ack request received with bad fsts_id",
633                       "Ack response received before the session was set up",
634                       "Ack response received on the initiator side before session was established",
635                       "Ack response received on the responder side before session was established",
636                       "Ack response received before ack request was sent",
637                       "Ack response received with bad fsts_id")
638
639 def fst_bad_transfer(apdev, test_params, bad_scenario_type, init_on_ap):
640     """This function makes the necessary preparations and then adds and sets a
641     session. It then initiates and it unless instructed otherwise) and attempts
642     to send one of the frames involved in the session transfer protocol,
643     skipping or distorting one of the stages according to the value of
644     bad_scenario_type parameter."""
645     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
646     bad_parameter_detected = False
647     exception_already_raised = False
648     try:
649         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
650         # This call makes sure FstHostapd singleton object is created and, as a
651         # result, the global control interface is registered (this is done from
652         # the constructor).
653         ap1.get_global_instance()
654         if init_on_ap:
655             initiator = ap1
656             responder = sta1
657             new_iface = ap2.ifname()
658             new_peer_addr = ap2.get_actual_peer_addr()
659         else:
660             initiator = sta1
661             responder = ap1
662             new_iface = sta2.ifname()
663             new_peer_addr = sta2.get_actual_peer_addr()
664         initiator.add_peer(responder, new_peer_addr = new_peer_addr)
665         sid = initiator.add_session()
666         initiator.configure_session(sid, new_iface)
667         if (bad_scenario_type != bad_scenario_ack_req_session_not_set_up and
668             bad_scenario_type != bad_scenario_ack_resp_session_not_set_up):
669             if (bad_scenario_type != bad_scenario_ack_req_session_not_established_init_side and
670                 bad_scenario_type != bad_scenario_ack_resp_session_not_established_init_side and
671                 bad_scenario_type != bad_scenario_ack_req_session_not_established_resp_side and
672                 bad_scenario_type != bad_scenario_ack_resp_session_not_established_resp_side):
673                 response =  "accept"
674             else:
675                 response = ''
676             initiator.initiate_session(sid, response)
677         if bad_scenario_type == bad_scenario_ack_req_session_not_set_up:
678             #fsts_id doesn't matter, no actual session exists
679             responder.send_test_ack_request('0')
680             initiator.wait_for_session_event(5)
681             # We want to send the unexpected frame to the side that already has
682             # a session created
683         elif bad_scenario_type == bad_scenario_ack_resp_session_not_set_up:
684             #fsts_id doesn't matter, no actual session exists
685             responder.send_test_ack_response('0')
686             initiator.wait_for_session_event(5)
687             # We want to send the unexpected frame to the side that already has
688             # a session created
689         elif bad_scenario_type == bad_scenario_ack_req_session_not_established_init_side:
690             #fsts_id doesn't matter, no actual session exists
691             initiator.send_test_ack_request('0')
692             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
693         elif bad_scenario_type == bad_scenario_ack_req_session_not_established_resp_side:
694             #fsts_id doesn't matter, no actual session exists
695             responder.send_test_ack_request('0')
696             initiator.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
697         elif bad_scenario_type == bad_scenario_ack_resp_session_not_established_init_side:
698             #fsts_id doesn't matter, no actual session exists
699             initiator.send_test_ack_response('0')
700             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
701         elif bad_scenario_type == bad_scenario_ack_resp_session_not_established_resp_side:
702             #fsts_id doesn't matter, no actual session exists
703             responder.send_test_ack_response('0')
704             initiator.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
705         elif bad_scenario_type == bad_scenario_ack_req_bad_fsts_id:
706             initiator.send_test_ack_request('-1')
707             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
708         elif bad_scenario_type == bad_scenario_ack_resp_bad_fsts_id:
709             initiator.send_test_ack_response('-1')
710             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
711         elif bad_scenario_type == bad_scenario_ack_resp_no_ack_req:
712             actual_fsts_id = initiator.get_fsts_id_by_sid(sid)
713             initiator.send_test_ack_response(str(actual_fsts_id))
714             responder.wait_for_session_event(5, ["EVENT_FST_SESSION_STATE"])
715         else:
716             raise Exception("Unknown bad scenario identifier")
717     except Exception, e:
718         if e.args[0].startswith("No FST-EVENT-SESSION received"):
719             bad_parameter_detected = True
720         if not bad_parameter_detected:
721             # The exception was unexpected
722             logger.info(e)
723             exception_already_raised = True
724             raise
725     finally:
726         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
727         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
728         if not exception_already_raised:
729             if bad_parameter_detected:
730                 logger.info("Success. Bad scenario was handled correctly (%s)" % bad_scenario_names[bad_scenario_type])
731             else:
732                 raise Exception("Failure. Bad scenario was handled incorrectly (%s)" % bad_scenario_names[bad_scenario_type])
733         else:
734             print "Failure. Unexpected exception"
735
736 def test_fst_sta_connect_to_non_fst_ap(dev, apdev, test_params):
737     """FST STA connecting to non-FST AP"""
738     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
739     with HWSimRadio() as (radio, iface):
740         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
741         try:
742             orig_sta1_mbies = sta1.get_local_mbies()
743             orig_sta2_mbies = sta2.get_local_mbies()
744             vals = sta2.scan()
745             freq = vals['freq']
746             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g",
747                                         key_mgmt="NONE", scan_freq=freq)
748             time.sleep(2)
749             res_sta1_mbies = sta1.get_local_mbies()
750             res_sta2_mbies = sta2.get_local_mbies()
751             if (orig_sta1_mbies.startswith("FAIL") or
752                 orig_sta2_mbies.startswith("FAIL") or
753                 not res_sta1_mbies.startswith("FAIL") or
754                 not res_sta2_mbies.startswith("FAIL")):
755                 raise Exception("Failure. MB IEs have not been removed on the stations")
756         except Exception, e:
757             logger.info(e)
758             raise
759         finally:
760             sta2.disconnect_from_external_ap()
761             fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
762
763 def test_fst_sta_connect_to_fst_ap(dev, apdev, test_params):
764     """FST STA connecting to FST AP"""
765     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
766     try:
767         orig_sta2_mbies = sta2.get_local_mbies()
768         vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
769         sta1.connect(ap1, key_mgmt="NONE",
770                      scan_freq=fst_test_common.fst_test_def_freq_a)
771         time.sleep(2)
772         res_sta2_mbies = sta2.get_local_mbies()
773         if res_sta2_mbies == orig_sta2_mbies:
774             raise Exception("Failure. MB IEs have not been updated")
775     except Exception, e:
776         logger.info(e)
777         raise
778     finally:
779         sta1.disconnect()
780         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
781
782 def test_fst_ap_connect_to_fst_sta(dev, apdev, test_params):
783     """FST AP connecting to FST STA"""
784     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
785     try:
786         orig_ap_mbies = ap1.get_local_mbies()
787         vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
788         sta1.connect(ap1, key_mgmt="NONE",
789                      scan_freq=fst_test_common.fst_test_def_freq_a)
790         time.sleep(2)
791         res_ap_mbies = ap1.get_local_mbies()
792         if res_ap_mbies != orig_ap_mbies:
793             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
794     except Exception, e:
795         logger.info(e)
796         raise
797     finally:
798         sta1.disconnect()
799         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
800
801 def test_fst_ap_connect_to_non_fst_sta(dev, apdev, test_params):
802     """FST AP connecting to non-FST STA"""
803     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
804     try:
805         orig_ap_mbies = ap2.get_local_mbies()
806         vals = dev[0].scan(None, fst_test_common.fst_test_def_freq_g)
807         fst_module_aux.external_sta_connect(dev[0], ap2, key_mgmt="NONE",
808                                             scan_freq=fst_test_common.fst_test_def_freq_g)
809         time.sleep(2)
810         res_ap_mbies = ap2.get_local_mbies()
811         if res_ap_mbies != orig_ap_mbies:
812             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
813     except Exception, e:
814         logger.info(e)
815         raise
816     finally:
817         fst_module_aux.disconnect_external_sta(dev[0], ap2)
818         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
819
820 def test_fst_second_sta_connect_to_non_fst_ap(dev, apdev, test_params):
821     """FST STA 2nd connecting to non-FST AP"""
822     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
823     with HWSimRadio() as (radio, iface):
824         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
825         try:
826             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
827             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
828             time.sleep(2)
829             orig_sta1_mbies = sta1.get_local_mbies()
830             orig_sta2_mbies = sta2.get_local_mbies()
831             vals = sta2.scan()
832             freq = vals['freq']
833             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
834             time.sleep(2)
835             res_sta1_mbies = sta1.get_local_mbies()
836             res_sta2_mbies = sta2.get_local_mbies()
837             if (orig_sta1_mbies.startswith("FAIL") or
838                 orig_sta2_mbies.startswith("FAIL") or
839                 not res_sta1_mbies.startswith("FAIL") or
840                 not res_sta2_mbies.startswith("FAIL")):
841                 raise Exception("Failure. MB IEs have not been removed on the stations")
842         except Exception, e:
843             logger.info(e)
844             raise
845         finally:
846             sta1.disconnect()
847             sta2.disconnect_from_external_ap()
848             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
849
850
851 def test_fst_second_sta_connect_to_fst_ap(dev, apdev, test_params):
852     """FST STA 2nd connecting to FST AP"""
853     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
854     with HWSimRadio() as (radio, iface):
855         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
856         try:
857             vals = sta2.scan()
858             freq = vals['freq']
859             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
860             time.sleep(2)
861             orig_sta1_mbies = sta1.get_local_mbies()
862             orig_sta2_mbies = sta2.get_local_mbies()
863             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
864             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
865             time.sleep(2)
866             res_sta1_mbies = sta1.get_local_mbies()
867             res_sta2_mbies = sta2.get_local_mbies()
868             if (not orig_sta1_mbies.startswith("FAIL") or
869                 not orig_sta2_mbies.startswith("FAIL") or
870                 not res_sta1_mbies.startswith("FAIL") or
871                 not res_sta2_mbies.startswith("FAIL")):
872                 raise Exception("Failure. MB IEs should have stayed non-present on the stations")
873         except Exception, e:
874             logger.info(e)
875             raise
876         finally:
877             sta1.disconnect()
878             sta2.disconnect_from_external_ap()
879             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
880
881 def test_fst_disconnect_1_of_2_stas_from_non_fst_ap(dev, apdev, test_params):
882     """FST disconnect 1 of 2 STAs from non-FST AP"""
883     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
884     with HWSimRadio() as (radio, iface):
885         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
886         try:
887             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
888             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
889             vals = sta2.scan()
890             freq = vals['freq']
891             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
892             time.sleep(2)
893             orig_sta1_mbies = sta1.get_local_mbies()
894             orig_sta2_mbies = sta2.get_local_mbies()
895             sta2.disconnect_from_external_ap()
896             time.sleep(2)
897             res_sta1_mbies = sta1.get_local_mbies()
898             res_sta2_mbies = sta2.get_local_mbies()
899             if (not orig_sta1_mbies.startswith("FAIL") or
900                 not orig_sta2_mbies.startswith("FAIL") or
901                 res_sta1_mbies.startswith("FAIL") or
902                 res_sta2_mbies.startswith("FAIL")):
903                 raise Exception("Failure. MB IEs haven't reappeared on the stations")
904         except Exception, e:
905             logger.info(e)
906             raise
907         finally:
908             sta1.disconnect()
909             sta2.disconnect_from_external_ap()
910             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
911
912
913 def test_fst_disconnect_1_of_2_stas_from_fst_ap(dev, apdev, test_params):
914     """FST disconnect 1 of 2 STAs from FST AP"""
915     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
916     with HWSimRadio() as (radio, iface):
917         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
918         try:
919             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
920             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
921             vals = sta2.scan()
922             freq = vals['freq']
923             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
924             time.sleep(2)
925             orig_sta1_mbies = sta1.get_local_mbies()
926             orig_sta2_mbies = sta2.get_local_mbies()
927             sta1.disconnect()
928             time.sleep(2)
929             res_sta1_mbies = sta1.get_local_mbies()
930             res_sta2_mbies = sta2.get_local_mbies()
931             if (not orig_sta1_mbies.startswith("FAIL") or
932                 not orig_sta2_mbies.startswith("FAIL") or
933                 not res_sta1_mbies.startswith("FAIL") or
934                 not res_sta2_mbies.startswith("FAIL")):
935                 raise Exception("Failure. MB IEs should have stayed non-present on the stations")
936         except Exception, e:
937             logger.info(e)
938             raise
939         finally:
940             sta1.disconnect()
941             sta2.disconnect_from_external_ap()
942             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
943
944 def test_fst_disconnect_2_of_2_stas_from_non_fst_ap(dev, apdev, test_params):
945     """FST disconnect 2 of 2 STAs from non-FST AP"""
946     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
947     with HWSimRadio() as (radio, iface):
948         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g" })
949         try:
950             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
951             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
952             vals = sta2.scan()
953             freq = vals['freq']
954             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
955             time.sleep(2)
956             sta1.disconnect()
957             time.sleep(2)
958             orig_sta1_mbies = sta1.get_local_mbies()
959             orig_sta2_mbies = sta2.get_local_mbies()
960             sta2.disconnect_from_external_ap()
961             time.sleep(2)
962             res_sta1_mbies = sta1.get_local_mbies()
963             res_sta2_mbies = sta2.get_local_mbies()
964             if (not orig_sta1_mbies.startswith("FAIL") or
965                 not orig_sta2_mbies.startswith("FAIL") or
966                 res_sta1_mbies.startswith("FAIL") or
967                 res_sta2_mbies.startswith("FAIL")):
968                 raise Exception("Failure. MB IEs haven't reappeared on the stations")
969         except Exception, e:
970             logger.info(e)
971             raise
972         finally:
973             sta1.disconnect()
974             sta2.disconnect_from_external_ap()
975             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
976
977 def test_fst_disconnect_2_of_2_stas_from_fst_ap(dev, apdev, test_params):
978     """FST disconnect 2 of 2 STAs from FST AP"""
979     fst_ap1, fst_ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
980     with HWSimRadio() as (radio, iface):
981         non_fst_ap = hostapd.add_ap(iface, { "ssid": "non_fst_11g"})
982         try:
983             vals = sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
984             sta1.connect(fst_ap1, key_mgmt="NONE", scan_freq=fst_test_common.fst_test_def_freq_a)
985             vals = sta2.scan()
986             freq = vals['freq']
987             sta2.connect_to_external_ap(non_fst_ap, ssid="non_fst_11g", key_mgmt="NONE", scan_freq=freq)
988             time.sleep(2)
989             sta2.disconnect_from_external_ap()
990             time.sleep(2)
991             orig_sta1_mbies = sta1.get_local_mbies()
992             orig_sta2_mbies = sta2.get_local_mbies()
993             sta1.disconnect()
994             time.sleep(2)
995             res_sta1_mbies = sta1.get_local_mbies()
996             res_sta2_mbies = sta2.get_local_mbies()
997             if (orig_sta1_mbies.startswith("FAIL") or
998                 orig_sta2_mbies.startswith("FAIL") or
999                 res_sta1_mbies.startswith("FAIL") or
1000                 res_sta2_mbies.startswith("FAIL")):
1001                 raise Exception("Failure. MB IEs should have stayed present on both stations")
1002             # Mandatory part of 8.4.2.140 Multi-band element is 24 bytes = 48 hex chars
1003             basic_sta1_mbies = res_sta1_mbies[0:48] + res_sta1_mbies[60:108]
1004             basic_sta2_mbies = res_sta2_mbies[0:48] + res_sta2_mbies[60:108]
1005             if (basic_sta1_mbies != basic_sta2_mbies):
1006                 raise Exception("Failure. Basic MB IEs should have become identical on both stations")
1007             addr_sta1_str = sta1.get_own_mac_address().replace(":", "")
1008             addr_sta2_str = sta2.get_own_mac_address().replace(":", "")
1009             # Mandatory part of 8.4.2.140 Multi-band element is followed by STA MAC Address field (6 bytes = 12 hex chars)
1010             addr_sta1_mbie1 = res_sta1_mbies[48:60]
1011             addr_sta1_mbie2 = res_sta1_mbies[108:120]
1012             addr_sta2_mbie1 = res_sta2_mbies[48:60]
1013             addr_sta2_mbie2 = res_sta2_mbies[108:120]
1014             if (addr_sta1_mbie1 != addr_sta1_mbie2 or
1015                 addr_sta1_mbie1 != addr_sta2_str or
1016                 addr_sta2_mbie1 != addr_sta2_mbie2 or
1017                 addr_sta2_mbie1 != addr_sta1_str):
1018                 raise Exception("Failure. STA Address in MB IEs should have been same as the other STA's")
1019         except Exception, e:
1020             logger.info(e)
1021             raise
1022         finally:
1023             sta1.disconnect()
1024             sta2.disconnect_from_external_ap()
1025             fst_module_aux.stop_two_ap_sta_pairs(fst_ap1, fst_ap2, sta1, sta2)
1026
1027 def test_fst_disconnect_non_fst_sta(dev, apdev, test_params):
1028     """FST disconnect non-FST STA"""
1029     ap1, ap2, fst_sta1, fst_sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1030     external_sta_connected = False
1031     try:
1032         vals = fst_sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
1033         fst_sta1.connect(ap1, key_mgmt="NONE",
1034                          scan_freq=fst_test_common.fst_test_def_freq_a)
1035         vals = dev[0].scan(None, fst_test_common.fst_test_def_freq_g)
1036         fst_module_aux.external_sta_connect(dev[0], ap2, key_mgmt="NONE",
1037                                             scan_freq=fst_test_common.fst_test_def_freq_g)
1038         external_sta_connected = True
1039         time.sleep(2)
1040         fst_sta1.disconnect()
1041         time.sleep(2)
1042         orig_ap_mbies = ap2.get_local_mbies()
1043         fst_module_aux.disconnect_external_sta(dev[0], ap2)
1044         external_sta_connected = False
1045         time.sleep(2)
1046         res_ap_mbies = ap2.get_local_mbies()
1047         if res_ap_mbies != orig_ap_mbies:
1048             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
1049     except Exception, e:
1050         logger.info(e)
1051         raise
1052     finally:
1053         fst_sta1.disconnect()
1054         if external_sta_connected:
1055             fst_module_aux.disconnect_external_sta(dev[0], ap2)
1056         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, fst_sta1, fst_sta2)
1057
1058 def test_fst_disconnect_fst_sta(dev, apdev, test_params):
1059     """FST disconnect FST STA"""
1060     ap1, ap2, fst_sta1, fst_sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1061     external_sta_connected = False;
1062     try:
1063         vals = fst_sta1.scan(freq=fst_test_common.fst_test_def_freq_a)
1064         fst_sta1.connect(ap1, key_mgmt="NONE",
1065                          scan_freq=fst_test_common.fst_test_def_freq_a)
1066         vals = dev[0].scan(None, fst_test_common.fst_test_def_freq_g)
1067         fst_module_aux.external_sta_connect(dev[0], ap2, key_mgmt="NONE",
1068                                             scan_freq=fst_test_common.fst_test_def_freq_g)
1069         external_sta_connected = True
1070         time.sleep(2)
1071         fst_module_aux.disconnect_external_sta(dev[0], ap2)
1072         external_sta_connected = False
1073         time.sleep(2)
1074         orig_ap_mbies = ap2.get_local_mbies()
1075         fst_sta1.disconnect()
1076         time.sleep(2)
1077         res_ap_mbies = ap2.get_local_mbies()
1078         if res_ap_mbies != orig_ap_mbies:
1079             raise Exception("Failure. MB IEs have been unexpectedly updated on the AP")
1080     except Exception, e:
1081         logger.info(e)
1082         raise
1083     finally:
1084         fst_sta1.disconnect()
1085         if external_sta_connected:
1086             fst_module_aux.disconnect_external_sta(dev[0], ap2)
1087         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, fst_sta1, fst_sta2)
1088
1089 def test_fst_dynamic_iface_attach(dev, apdev, test_params):
1090     """FST dynamic interface attach"""
1091     ap1 = fst_module_aux.FstAP(apdev[0]['ifname'], 'fst_11a', 'a',
1092                                fst_test_common.fst_test_def_chan_a,
1093                                fst_test_common.fst_test_def_group,
1094                                fst_test_common.fst_test_def_prio_low,
1095                                fst_test_common.fst_test_def_llt)
1096     ap1.start()
1097     ap2 = fst_module_aux.FstAP(apdev[1]['ifname'], 'fst_11g', 'b',
1098                                fst_test_common.fst_test_def_chan_g,
1099                                '', '', '')
1100     ap2.start()
1101
1102     sta1 = fst_module_aux.FstSTA('wlan5',
1103                                  fst_test_common.fst_test_def_group,
1104                                  fst_test_common.fst_test_def_prio_low,
1105                                  fst_test_common.fst_test_def_llt)
1106     sta1.start()
1107     sta2 = fst_module_aux.FstSTA('wlan6', '', '', '')
1108     sta2.start()
1109
1110     try:
1111         orig_sta2_mbies = sta2.get_local_mbies()
1112         orig_ap2_mbies = ap2.get_local_mbies()
1113         sta2.send_iface_attach_request(sta2.ifname(),
1114                                        fst_test_common.fst_test_def_group,
1115                                        '52', '27')
1116         event = sta2.wait_for_iface_event(5)
1117         if event['event_type'] != 'attached':
1118             raise Exception("Failure. Iface was not properly attached")
1119         ap2.send_iface_attach_request(ap2.ifname(),
1120                                       fst_test_common.fst_test_def_group,
1121                                       '102', '77')
1122         event = ap2.wait_for_iface_event(5)
1123         if event['event_type'] != 'attached':
1124             raise Exception("Failure. Iface was not properly attached")
1125         time.sleep(2)
1126         res_sta2_mbies = sta2.get_local_mbies()
1127         res_ap2_mbies = ap2.get_local_mbies()
1128         sta2.send_iface_detach_request(sta2.ifname())
1129         event = sta2.wait_for_iface_event(5)
1130         if event['event_type'] != 'detached':
1131             raise Exception("Failure. Iface was not properly detached")
1132         ap2.send_iface_detach_request(ap2.ifname())
1133         event = ap2.wait_for_iface_event(5)
1134         if event['event_type'] != 'detached':
1135             raise Exception("Failure. Iface was not properly detached")
1136         if (not orig_sta2_mbies.startswith("FAIL") or
1137             not orig_ap2_mbies.startswith("FAIL") or
1138             res_sta2_mbies.startswith("FAIL") or
1139             res_ap2_mbies.startswith("FAIL")):
1140             raise Exception("Failure. MB IEs should have appeared on the station and on the AP")
1141     except Exception, e:
1142         logger.info(e)
1143         raise
1144     finally:
1145         ap1.stop()
1146         ap2.stop()
1147         sta1.stop()
1148         sta2.stop()
1149
1150 # AP side FST module tests
1151
1152 def test_fst_ap_start_session(dev, apdev, test_params):
1153     """FST AP start session"""
1154     fst_start_session(apdev, test_params, bad_param_none, True)
1155
1156 def test_fst_ap_start_session_no_add_params(dev, apdev, test_params):
1157     """FST AP start session - no add params"""
1158     fst_start_session(apdev, test_params, bad_param_session_add_no_params, True)
1159
1160 def test_fst_ap_start_session_bad_group_id(dev, apdev, test_params):
1161     """FST AP start session - bad group id"""
1162     fst_start_session(apdev, test_params, bad_param_group_id, True)
1163
1164 def test_fst_ap_start_session_no_set_params(dev, apdev, test_params):
1165     """FST AP start session - no set params"""
1166     fst_start_session(apdev, test_params, bad_param_session_set_no_params, True)
1167
1168 def test_fst_ap_start_session_set_unknown_param(dev, apdev, test_params):
1169     """FST AP start session - set unknown param"""
1170     fst_start_session(apdev, test_params, bad_param_session_set_unknown_param,
1171                       True)
1172
1173 def test_fst_ap_start_session_bad_session_id(dev, apdev, test_params):
1174     """FST AP start session - bad session id"""
1175     fst_start_session(apdev, test_params, bad_param_session_id, True)
1176
1177 def test_fst_ap_start_session_bad_new_iface(dev, apdev, test_params):
1178     """FST AP start session - bad new iface"""
1179     fst_start_session(apdev, test_params, bad_param_new_iface, True)
1180
1181 def test_fst_ap_start_session_bad_old_iface(dev, apdev, test_params):
1182     """FST AP start session - bad old iface"""
1183     fst_start_session(apdev, test_params, bad_param_old_iface, True)
1184
1185 def test_fst_ap_start_session_negative_llt(dev, apdev, test_params):
1186     """FST AP start session - negative llt"""
1187     fst_start_session(apdev, test_params, bad_param_negative_llt, True)
1188
1189 def test_fst_ap_start_session_zero_llt(dev, apdev, test_params):
1190     """FST AP start session - zero llt"""
1191     fst_start_session(apdev, test_params, bad_param_zero_llt, True)
1192
1193 def test_fst_ap_start_session_llt_too_big(dev, apdev, test_params):
1194     """FST AP start session - llt too large"""
1195     fst_start_session(apdev, test_params, bad_param_llt_too_big, True)
1196
1197 def test_fst_ap_start_session_invalid_peer_addr(dev, apdev, test_params):
1198     """FST AP start session - invalid peer address"""
1199     fst_start_session(apdev, test_params, bad_param_peer_addr, True,
1200                       'GG:GG:GG:GG:GG:GG')
1201
1202 def test_fst_ap_start_session_multicast_peer_addr(dev, apdev, test_params):
1203     """FST AP start session - multicast peer address"""
1204     fst_start_session(apdev, test_params, bad_param_peer_addr, True,
1205                       '01:00:11:22:33:44')
1206
1207 def test_fst_ap_start_session_broadcast_peer_addr(dev, apdev, test_params):
1208     """FST AP start session - broadcast peer address"""
1209     fst_start_session(apdev, test_params, bad_param_peer_addr, True,
1210                       'FF:FF:FF:FF:FF:FF')
1211
1212 def test_fst_ap_initiate_session(dev, apdev, test_params):
1213     """FST AP initiate session"""
1214     fst_initiate_session(apdev, test_params, bad_param_none, True)
1215
1216 def test_fst_ap_initiate_session_no_params(dev, apdev, test_params):
1217     """FST AP initiate session - no params"""
1218     fst_initiate_session(apdev, test_params,
1219                          bad_param_session_initiate_no_params, True)
1220
1221 def test_fst_ap_initiate_session_invalid_session_id(dev, apdev, test_params):
1222     """FST AP initiate session - invalid session id"""
1223     fst_initiate_session(apdev, test_params,
1224                          bad_param_session_initiate_bad_session_id, True)
1225
1226 def test_fst_ap_initiate_session_no_new_iface(dev, apdev, test_params):
1227     """FST AP initiate session - no new iface"""
1228     fst_initiate_session(apdev, test_params,
1229                          bad_param_session_initiate_with_no_new_iface_set, True)
1230
1231 def test_fst_ap_initiate_session_bad_peer_addr(dev, apdev, test_params):
1232     """FST AP initiate session - bad peer address"""
1233     fst_initiate_session(apdev, test_params,
1234                          bad_param_session_initiate_with_bad_peer_addr_set,
1235                          True)
1236
1237 def test_fst_ap_initiate_session_request_with_bad_stie(dev, apdev, test_params):
1238     """FST AP initiate session - request with bad stie"""
1239     fst_initiate_session(apdev, test_params,
1240                          bad_param_session_initiate_request_with_bad_stie, True)
1241
1242 def test_fst_ap_initiate_session_response_with_reject(dev, apdev, test_params):
1243     """FST AP initiate session - response with reject"""
1244     fst_initiate_session(apdev, test_params,
1245                          bad_param_session_initiate_response_with_reject, True)
1246
1247 def test_fst_ap_initiate_session_response_with_bad_stie(dev, apdev,
1248                                                         test_params):
1249     """FST AP initiate session - response with bad stie"""
1250     fst_initiate_session(apdev, test_params,
1251                          bad_param_session_initiate_response_with_bad_stie,
1252                          True)
1253
1254 def test_fst_ap_initiate_session_response_with_zero_llt(dev, apdev,
1255                                                         test_params):
1256     """FST AP initiate session - zero llt"""
1257     fst_initiate_session(apdev, test_params,
1258                          bad_param_session_initiate_response_with_zero_llt,
1259                          True)
1260
1261 def test_fst_ap_initiate_session_stt_no_response(dev, apdev, test_params):
1262     """FST AP initiate session - stt no response"""
1263     fst_initiate_session(apdev, test_params,
1264                          bad_param_session_initiate_stt_no_response, True)
1265
1266 def test_fst_ap_initiate_session_concurrent_setup_request(dev, apdev,
1267                                                           test_params):
1268     """FST AP initiate session - concurrent setup request"""
1269     fst_initiate_session(apdev, test_params,
1270                          bad_param_session_initiate_concurrent_setup_request,
1271                          True)
1272
1273 def test_fst_ap_session_request_with_no_session(dev, apdev, test_params):
1274     """FST AP session request with no session"""
1275     fst_send_unexpected_frame(apdev, test_params, frame_type_session_request,
1276                               True)
1277
1278 def test_fst_ap_session_response_accept_with_no_session(dev, apdev,
1279                                                         test_params):
1280     """FST AP session response accept with no session"""
1281     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1282                               True, "accept")
1283
1284 def test_fst_ap_session_response_reject_with_no_session(dev, apdev,
1285                                                         test_params):
1286     """FST AP session response reject with no session"""
1287     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1288                               True, "reject")
1289
1290 def test_fst_ap_ack_request_with_no_session(dev, apdev, test_params):
1291     """FST AP ack request with no session"""
1292     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_request, True)
1293
1294 def test_fst_ap_ack_response_with_no_session(dev, apdev, test_params):
1295     """FST AP ack response with no session"""
1296     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_response, True)
1297
1298 def test_fst_ap_tear_down_response_with_no_session(dev, apdev, test_params):
1299     """FST AP tear down response with no session"""
1300     fst_send_unexpected_frame(apdev, test_params, frame_type_tear_down, True)
1301
1302 def test_fst_ap_transfer_session(dev, apdev, test_params):
1303     """FST AP transfer session"""
1304     fst_transfer_session(apdev, test_params, bad_param_none, True)
1305
1306 def test_fst_ap_transfer_session_no_params(dev, apdev, test_params):
1307     """FST AP transfer session - no params"""
1308     fst_transfer_session(apdev, test_params,
1309                          bad_param_session_transfer_no_params, True)
1310
1311 def test_fst_ap_transfer_session_bad_session_id(dev, apdev, test_params):
1312     """FST AP transfer session - bad session id"""
1313     fst_transfer_session(apdev, test_params,
1314                          bad_param_session_transfer_bad_session_id, True)
1315
1316 def test_fst_ap_transfer_session_setup_skipped(dev, apdev, test_params):
1317     """FST AP transfer session - setup skipped"""
1318     fst_transfer_session(apdev, test_params,
1319                          bad_param_session_transfer_setup_skipped, True)
1320
1321 def test_fst_ap_ack_request_with_session_not_set_up(dev, apdev, test_params):
1322     """FST AP ack request with session not set up"""
1323     fst_bad_transfer(apdev, test_params,
1324                      bad_scenario_ack_req_session_not_set_up, True)
1325
1326 def test_fst_ap_ack_request_with_session_not_established_init_side(dev, apdev,
1327                                                                    test_params):
1328     """FST AP ack request with session not established init side"""
1329     fst_bad_transfer(apdev, test_params,
1330                      bad_scenario_ack_req_session_not_established_init_side,
1331                      True)
1332
1333 def test_fst_ap_ack_request_with_session_not_established_resp_side(dev, apdev,
1334                                                                    test_params):
1335     """FST AP ack request with session not established resp side"""
1336     fst_bad_transfer(apdev, test_params,
1337                      bad_scenario_ack_req_session_not_established_resp_side,
1338                      True)
1339
1340 def test_fst_ap_ack_request_with_bad_fsts_id(dev, apdev, test_params):
1341     """FST AP ack request with bad fsts id"""
1342     fst_bad_transfer(apdev, test_params, bad_scenario_ack_req_bad_fsts_id, True)
1343
1344 def test_fst_ap_ack_response_with_session_not_set_up(dev, apdev, test_params):
1345     """FST AP ack response with session not set up"""
1346     fst_bad_transfer(apdev, test_params,
1347                      bad_scenario_ack_resp_session_not_set_up, True)
1348
1349 def test_fst_ap_ack_response_with_session_not_established_init_side(dev, apdev, test_params):
1350     """FST AP ack response with session not established init side"""
1351     fst_bad_transfer(apdev, test_params,
1352                      bad_scenario_ack_resp_session_not_established_init_side,
1353                      True)
1354
1355 def test_fst_ap_ack_response_with_session_not_established_resp_side(dev, apdev, test_params):
1356     """FST AP ack response with session not established resp side"""
1357     fst_bad_transfer(apdev, test_params,
1358                      bad_scenario_ack_resp_session_not_established_resp_side,
1359                      True)
1360
1361 def test_fst_ap_ack_response_with_no_ack_request(dev, apdev, test_params):
1362     """FST AP ack response with no ack request"""
1363     fst_bad_transfer(apdev, test_params, bad_scenario_ack_resp_no_ack_req, True)
1364
1365 def test_fst_ap_tear_down_session(dev, apdev, test_params):
1366     """FST AP tear down session"""
1367     fst_tear_down_session(apdev, test_params, bad_param_none, True)
1368
1369 def test_fst_ap_tear_down_session_no_params(dev, apdev, test_params):
1370     """FST AP tear down session - no params"""
1371     fst_tear_down_session(apdev, test_params,
1372                           bad_param_session_teardown_no_params, True)
1373
1374 def test_fst_ap_tear_down_session_bad_session_id(dev, apdev, test_params):
1375     """FST AP tear down session - bad session id"""
1376     fst_tear_down_session(apdev, test_params,
1377                           bad_param_session_teardown_bad_session_id, True)
1378
1379 def test_fst_ap_tear_down_session_setup_skipped(dev, apdev, test_params):
1380     """FST AP tear down session - setup skipped"""
1381     fst_tear_down_session(apdev, test_params,
1382                           bad_param_session_teardown_setup_skipped, True)
1383
1384 def test_fst_ap_tear_down_session_bad_fsts_id(dev, apdev, test_params):
1385     """FST AP tear down session - bad fsts id"""
1386     fst_tear_down_session(apdev, test_params,
1387                           bad_param_session_teardown_bad_fsts_id, True)
1388
1389 def test_fst_ap_remove_session_not_established(dev, apdev, test_params):
1390     """FST AP remove session - not established"""
1391     fst_remove_session(apdev, test_params,
1392                        remove_scenario_non_established_session, True)
1393
1394 def test_fst_ap_remove_session_established(dev, apdev, test_params):
1395     """FST AP remove session - established"""
1396     fst_remove_session(apdev, test_params,
1397                        remove_scenario_established_session, True)
1398
1399 def test_fst_ap_remove_session_no_params(dev, apdev, test_params):
1400     """FST AP remove session - no params"""
1401     fst_remove_session(apdev, test_params, remove_scenario_no_params, True)
1402
1403 def test_fst_ap_remove_session_bad_session_id(dev, apdev, test_params):
1404     """FST AP remove session - bad session id"""
1405     fst_remove_session(apdev, test_params, remove_scenario_bad_session_id, True)
1406
1407 def test_fst_ap_ctrl_iface(dev, apdev, test_params):
1408     """FST control interface behavior"""
1409     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1410     try:
1411         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1412         initiator = ap1
1413         responder = sta1
1414         initiator.add_peer(responder, None)
1415         initiator.set_fst_parameters(group_id=None)
1416         sid = initiator.add_session()
1417         res = initiator.get_session_params(sid)
1418         logger.info("Initial session params:\n" + str(res))
1419         if res['state'] != 'INITIAL':
1420             raise Exception("Unexpected state: " + res['state'])
1421         initiator.set_fst_parameters(llt=None)
1422         initiator.configure_session(sid, ap2.ifname(), None)
1423         res = initiator.get_session_params(sid)
1424         logger.info("Session params after configuration:\n" + str(res))
1425         res = initiator.iface_peers(initiator.ifname())
1426         logger.info("Interface peers: " + str(res))
1427         if len(res) != 1:
1428             raise Exception("Unexpected number of peers")
1429         res = initiator.get_peer_mbies(initiator.ifname(),
1430                                        initiator.get_new_peer_addr())
1431         logger.info("Peer MB IEs: " + str(res))
1432         res = initiator.list_ifaces()
1433         logger.info("Interfaces: " + str(res))
1434         if len(res) != 2:
1435             raise Exception("Unexpected number of interfaces")
1436         res = initiator.list_groups()
1437         logger.info("Groups: " + str(res))
1438         if len(res) != 1:
1439             raise Exception("Unexpected number of groups")
1440
1441         tests = [ "LIST_IFACES unknown",
1442                   "LIST_IFACES     unknown2",
1443                   "SESSION_GET 12345678",
1444                   "SESSION_SET " + sid + " unknown=foo",
1445                   "SESSION_RESPOND 12345678 foo",
1446                   "SESSION_RESPOND " + sid,
1447                   "SESSION_RESPOND " + sid + " foo",
1448                   "TEST_REQUEST foo",
1449                   "TEST_REQUEST SEND_SETUP_REQUEST",
1450                   "TEST_REQUEST SEND_SETUP_REQUEST foo",
1451                   "TEST_REQUEST SEND_SETUP_RESPONSE",
1452                   "TEST_REQUEST SEND_SETUP_RESPONSE foo",
1453                   "TEST_REQUEST SEND_ACK_REQUEST",
1454                   "TEST_REQUEST SEND_ACK_REQUEST foo",
1455                   "TEST_REQUEST SEND_ACK_RESPONSE",
1456                   "TEST_REQUEST SEND_ACK_RESPONSE foo",
1457                   "TEST_REQUEST SEND_TEAR_DOWN",
1458                   "TEST_REQUEST SEND_TEAR_DOWN foo",
1459                   "TEST_REQUEST GET_FSTS_ID",
1460                   "TEST_REQUEST GET_FSTS_ID foo",
1461                   "TEST_REQUEST GET_LOCAL_MBIES",
1462                   "TEST_REQUEST GET_LOCAL_MBIES foo",
1463                   "GET_PEER_MBIES",
1464                   "GET_PEER_MBIES ",
1465                   "GET_PEER_MBIES unknown",
1466                   "GET_PEER_MBIES unknown unknown",
1467                   "GET_PEER_MBIES unknown  " + initiator.get_new_peer_addr(),
1468                   "GET_PEER_MBIES " + initiator.ifname() + " 01:ff:ff:ff:ff:ff",
1469                   "IFACE_PEERS",
1470                   "IFACE_PEERS ",
1471                   "IFACE_PEERS unknown",
1472                   "IFACE_PEERS unknown unknown",
1473                   "IFACE_PEERS " + initiator.fst_group,
1474                   "IFACE_PEERS " + initiator.fst_group + " unknown" ]
1475         for t in tests:
1476             if "FAIL" not in initiator.grequest("FST-MANAGER " + t):
1477                 raise Exception("Unexpected response for invalid FST-MANAGER command " + t)
1478         if "UNKNOWN FST COMMAND" not in initiator.grequest("FST-MANAGER unknown"):
1479             raise Exception("Unexpected response for unknown FST-MANAGER command")
1480
1481         tests = [ "FST-DETACH", "FST-DETACH ", "FST-DETACH unknown",
1482                   "FST-ATTACH", "FST-ATTACH ", "FST-ATTACH unknown",
1483                   "FST-ATTACH unknown unknown" ]
1484         for t in tests:
1485             if "FAIL" not in initiator.grequest(t):
1486                 raise Exception("Unexpected response for invalid command " + t)
1487
1488         try:
1489             # Trying to add same interface again needs to fail.
1490             ap1.send_iface_attach_request(ap1.iface, ap1.fst_group,
1491                                           ap1.fst_llt, ap1.fst_pri)
1492             raise Exception("Duplicate FST-ATTACH succeeded")
1493         except Exception, e:
1494             if not str(e).startswith("Cannot attach"):
1495                 raise
1496
1497         try:
1498             ap1.get_fsts_id_by_sid("123")
1499         except Exception, e:
1500             if not str(e).startswith("Cannot get fsts_id for sid"):
1501                 raise
1502     finally:
1503         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1504         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1505
1506 def test_fst_ap_start_session_oom(dev, apdev, test_params):
1507     """FST AP setup failing due to OOM"""
1508     ap1 = fst_module_aux.FstAP(apdev[0]['ifname'], 'fst_11a', 'a',
1509                                fst_test_common.fst_test_def_chan_a,
1510                                fst_test_common.fst_test_def_group,
1511                                fst_test_common.fst_test_def_prio_low,
1512                                fst_test_common.fst_test_def_llt)
1513     ap1.start()
1514     with alloc_fail(ap1, 1, "fst_iface_create"):
1515         ap2_started = False
1516         try:
1517             ap2 = fst_module_aux.FstAP(apdev[1]['ifname'], 'fst_11g', 'b',
1518                                        fst_test_common.fst_test_def_chan_g,
1519                                        fst_test_common.fst_test_def_group,
1520                                        fst_test_common.fst_test_def_prio_high,
1521                                        fst_test_common.fst_test_def_llt)
1522             try:
1523                 # This will fail in fst_iface_create() OOM
1524                 ap2.start()
1525             except:
1526                 pass
1527         finally:
1528             ap1.stop()
1529             try:
1530                 ap2.stop()
1531             except:
1532                 pass
1533
1534 # STA side FST module tests
1535
1536 def test_fst_sta_start_session(dev, apdev, test_params):
1537     """FST STA start session"""
1538     fst_start_session(apdev, test_params, bad_param_none, False)
1539
1540 def test_fst_sta_start_session_no_add_params(dev, apdev, test_params):
1541     """FST STA start session - no add params"""
1542     fst_start_session(apdev, test_params, bad_param_session_add_no_params,
1543                       False)
1544
1545 def test_fst_sta_start_session_bad_group_id(dev, apdev, test_params):
1546     """FST STA start session - bad group id"""
1547     fst_start_session(apdev, test_params, bad_param_group_id, False)
1548
1549 def test_fst_sta_start_session_no_set_params(dev, apdev, test_params):
1550     """FST STA start session - no set params"""
1551     fst_start_session(apdev, test_params, bad_param_session_set_no_params,
1552                       False)
1553
1554 def test_fst_sta_start_session_set_unknown_param(dev, apdev, test_params):
1555     """FST STA start session - set unknown param"""
1556     fst_start_session(apdev, test_params, bad_param_session_set_unknown_param,
1557                       False)
1558
1559 def test_fst_sta_start_session_bad_session_id(dev, apdev, test_params):
1560     """FST STA start session - bad session id"""
1561     fst_start_session(apdev, test_params, bad_param_session_id, False)
1562
1563 def test_fst_sta_start_session_bad_new_iface(dev, apdev, test_params):
1564     """FST STA start session - bad new iface"""
1565     fst_start_session(apdev, test_params, bad_param_new_iface, False)
1566
1567 def test_fst_sta_start_session_bad_old_iface(dev, apdev, test_params):
1568     """FST STA start session - bad old iface"""
1569     fst_start_session(apdev, test_params, bad_param_old_iface, False)
1570
1571 def test_fst_sta_start_session_negative_llt(dev, apdev, test_params):
1572     """FST STA start session - negative llt"""
1573     fst_start_session(apdev, test_params, bad_param_negative_llt, False)
1574
1575 def test_fst_sta_start_session_zero_llt(dev, apdev, test_params):
1576     """FST STA start session - zero llt"""
1577     fst_start_session(apdev, test_params, bad_param_zero_llt, False)
1578
1579 def test_fst_sta_start_session_llt_too_big(dev, apdev, test_params):
1580     """FST STA start session - llt too large"""
1581     fst_start_session(apdev, test_params, bad_param_llt_too_big, False)
1582
1583 def test_fst_sta_start_session_invalid_peer_addr(dev, apdev, test_params):
1584     """FST STA start session - invalid peer address"""
1585     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1586                       'GG:GG:GG:GG:GG:GG')
1587
1588 def test_fst_sta_start_session_multicast_peer_addr(dev, apdev, test_params):
1589     """FST STA start session - multicast peer address"""
1590     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1591                       '11:00:11:22:33:44')
1592
1593 def test_fst_sta_start_session_broadcast_peer_addr(dev, apdev, test_params):
1594     """FST STA start session - broadcast peer addr"""
1595     fst_start_session(apdev, test_params, bad_param_peer_addr, False,
1596                       'FF:FF:FF:FF:FF:FF')
1597
1598 def test_fst_sta_initiate_session(dev, apdev, test_params):
1599     """FST STA initiate session"""
1600     fst_initiate_session(apdev, test_params, bad_param_none, False)
1601
1602 def test_fst_sta_initiate_session_no_params(dev, apdev, test_params):
1603     """FST STA initiate session - no params"""
1604     fst_initiate_session(apdev, test_params,
1605                          bad_param_session_initiate_no_params, False)
1606
1607 def test_fst_sta_initiate_session_invalid_session_id(dev, apdev, test_params):
1608     """FST STA initiate session - invalid session id"""
1609     fst_initiate_session(apdev, test_params,
1610                          bad_param_session_initiate_bad_session_id, False)
1611
1612 def test_fst_sta_initiate_session_no_new_iface(dev, apdev, test_params):
1613     """FST STA initiate session - no new iface"""
1614     fst_initiate_session(apdev, test_params,
1615                          bad_param_session_initiate_with_no_new_iface_set,
1616                          False)
1617
1618 def test_fst_sta_initiate_session_bad_peer_addr(dev, apdev, test_params):
1619     """FST STA initiate session - bad peer address"""
1620     fst_initiate_session(apdev, test_params,
1621                          bad_param_session_initiate_with_bad_peer_addr_set,
1622                          False)
1623
1624 def test_fst_sta_initiate_session_request_with_bad_stie(dev, apdev,
1625                                                         test_params):
1626     """FST STA initiate session - request with bad stie"""
1627     fst_initiate_session(apdev, test_params,
1628                          bad_param_session_initiate_request_with_bad_stie,
1629                          False)
1630
1631 def test_fst_sta_initiate_session_response_with_reject(dev, apdev, test_params):
1632     """FST STA initiate session - response with reject"""
1633     fst_initiate_session(apdev, test_params, bad_param_session_initiate_response_with_reject, False)
1634
1635 def test_fst_sta_initiate_session_response_with_bad_stie(dev, apdev, test_params):
1636     """FST STA initiate session - response with bad stie"""
1637     fst_initiate_session(apdev, test_params,
1638                          bad_param_session_initiate_response_with_bad_stie,
1639                          False)
1640
1641 def test_fst_sta_initiate_session_response_with_zero_llt(dev, apdev,
1642                                                          test_params):
1643     """FST STA initiate session - response with zero llt"""
1644     fst_initiate_session(apdev, test_params,
1645                          bad_param_session_initiate_response_with_zero_llt,
1646                          False)
1647
1648 def test_fst_sta_initiate_session_stt_no_response(dev, apdev, test_params):
1649     """FST STA initiate session - stt no response"""
1650     fst_initiate_session(apdev, test_params,
1651                          bad_param_session_initiate_stt_no_response, False)
1652
1653 def test_fst_sta_initiate_session_concurrent_setup_request(dev, apdev,
1654                                                            test_params):
1655     """FST STA initiate session - concurrent setup request"""
1656     fst_initiate_session(apdev, test_params,
1657                          bad_param_session_initiate_concurrent_setup_request,
1658                          False)
1659
1660 def test_fst_sta_session_request_with_no_session(dev, apdev, test_params):
1661     """FST STA session request with no session"""
1662     fst_send_unexpected_frame(apdev, test_params, frame_type_session_request,
1663                               False)
1664
1665 def test_fst_sta_session_response_accept_with_no_session(dev, apdev,
1666                                                          test_params):
1667     """FST STA session response accept with no session"""
1668     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1669                               False, "accept")
1670
1671 def test_fst_sta_session_response_reject_with_no_session(dev, apdev,
1672                                                          test_params):
1673     """FST STA session response reject with no session"""
1674     fst_send_unexpected_frame(apdev, test_params, frame_type_session_response,
1675                               False, "reject")
1676
1677 def test_fst_sta_ack_request_with_no_session(dev, apdev, test_params):
1678     """FST STA ack request with no session"""
1679     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_request, False)
1680
1681 def test_fst_sta_ack_response_with_no_session(dev, apdev, test_params):
1682     """FST STA ack response with no session"""
1683     fst_send_unexpected_frame(apdev, test_params, frame_type_ack_response,
1684                               False)
1685
1686 def test_fst_sta_tear_down_response_with_no_session(dev, apdev, test_params):
1687     """FST STA tear down response with no session"""
1688     fst_send_unexpected_frame(apdev, test_params, frame_type_tear_down, False)
1689
1690 def test_fst_sta_transfer_session(dev, apdev, test_params):
1691     """FST STA transfer session"""
1692     fst_transfer_session(apdev, test_params, bad_param_none, False)
1693
1694 def test_fst_sta_transfer_session_no_params(dev, apdev, test_params):
1695     """FST STA transfer session - no params"""
1696     fst_transfer_session(apdev, test_params,
1697                          bad_param_session_transfer_no_params, False)
1698
1699 def test_fst_sta_transfer_session_bad_session_id(dev, apdev, test_params):
1700     """FST STA transfer session - bad session id"""
1701     fst_transfer_session(apdev, test_params,
1702                          bad_param_session_transfer_bad_session_id, False)
1703
1704 def test_fst_sta_transfer_session_setup_skipped(dev, apdev, test_params):
1705     """FST STA transfer session - setup skipped"""
1706     fst_transfer_session(apdev, test_params,
1707                          bad_param_session_transfer_setup_skipped, False)
1708
1709 def test_fst_sta_ack_request_with_session_not_set_up(dev, apdev, test_params):
1710     """FST STA ack request with session not set up"""
1711     fst_bad_transfer(apdev, test_params,
1712                      bad_scenario_ack_req_session_not_set_up, False)
1713
1714 def test_fst_sta_ack_request_with_session_not_established_init_side(dev, apdev, test_params):
1715     """FST STA ack request with session not established init side"""
1716     fst_bad_transfer(apdev, test_params,
1717                      bad_scenario_ack_req_session_not_established_init_side,
1718                      False)
1719
1720 def test_fst_sta_ack_request_with_session_not_established_resp_side(dev, apdev, test_params):
1721     """FST STA ack request with session not established resp side"""
1722     fst_bad_transfer(apdev, test_params,
1723                      bad_scenario_ack_req_session_not_established_resp_side,
1724                      False)
1725
1726 def test_fst_sta_ack_request_with_bad_fsts_id(dev, apdev, test_params):
1727     """FST STA ack request with bad fsts id"""
1728     fst_bad_transfer(apdev, test_params, bad_scenario_ack_req_bad_fsts_id,
1729                      False)
1730
1731 def test_fst_sta_ack_response_with_session_not_set_up(dev, apdev, test_params):
1732     """FST STA ack response with session not set up"""
1733     fst_bad_transfer(apdev, test_params,
1734                      bad_scenario_ack_resp_session_not_set_up, False)
1735
1736 def test_fst_sta_ack_response_with_session_not_established_init_side(dev, apdev, test_params):
1737     """FST STA ack response with session not established init side"""
1738     fst_bad_transfer(apdev, test_params,
1739                      bad_scenario_ack_resp_session_not_established_init_side,
1740                      False)
1741
1742 def test_fst_sta_ack_response_with_session_not_established_resp_side(dev, apdev, test_params):
1743     """FST STA ack response with session not established resp side"""
1744     fst_bad_transfer(apdev, test_params,
1745                      bad_scenario_ack_resp_session_not_established_resp_side,
1746                      False)
1747
1748 def test_fst_sta_ack_response_with_no_ack_request(dev, apdev, test_params):
1749     """FST STA ack response with no ack request"""
1750     fst_bad_transfer(apdev, test_params, bad_scenario_ack_resp_no_ack_req,
1751                      False)
1752
1753 def test_fst_sta_tear_down_session(dev, apdev, test_params):
1754     """FST STA tear down session"""
1755     fst_tear_down_session(apdev, test_params, bad_param_none, False)
1756
1757 def test_fst_sta_tear_down_session_no_params(dev, apdev, test_params):
1758     """FST STA tear down session - no params"""
1759     fst_tear_down_session(apdev, test_params,
1760                           bad_param_session_teardown_no_params, False)
1761
1762 def test_fst_sta_tear_down_session_bad_session_id(dev, apdev, test_params):
1763     """FST STA tear down session - bad session id"""
1764     fst_tear_down_session(apdev, test_params,
1765                           bad_param_session_teardown_bad_session_id, False)
1766
1767 def test_fst_sta_tear_down_session_setup_skipped(dev, apdev, test_params):
1768     """FST STA tear down session - setup skipped"""
1769     fst_tear_down_session(apdev, test_params,
1770                           bad_param_session_teardown_setup_skipped, False)
1771
1772 def test_fst_sta_tear_down_session_bad_fsts_id(dev, apdev, test_params):
1773     """FST STA tear down session - bad fsts id"""
1774     fst_tear_down_session(apdev, test_params,
1775                           bad_param_session_teardown_bad_fsts_id, False)
1776
1777 def test_fst_sta_remove_session_not_established(dev, apdev, test_params):
1778     """FST STA tear down session - not established"""
1779     fst_remove_session(apdev, test_params,
1780                        remove_scenario_non_established_session, False)
1781
1782 def test_fst_sta_remove_session_established(dev, apdev, test_params):
1783     """FST STA remove session - established"""
1784     fst_remove_session(apdev, test_params,
1785                        remove_scenario_established_session, False)
1786
1787 def test_fst_sta_remove_session_no_params(dev, apdev, test_params):
1788     """FST STA remove session - no params"""
1789     fst_remove_session(apdev, test_params, remove_scenario_no_params, False)
1790
1791 def test_fst_sta_remove_session_bad_session_id(dev, apdev, test_params):
1792     """FST STA remove session - bad session id"""
1793     fst_remove_session(apdev, test_params, remove_scenario_bad_session_id,
1794                        False)
1795
1796 def test_fst_rsn_ap_transfer_session(dev, apdev, test_params):
1797     """FST RSN AP transfer session"""
1798     fst_transfer_session(apdev, test_params, bad_param_none, True, rsn=True)
1799
1800 MGMT_SUBTYPE_ACTION = 13
1801 ACTION_CATEG_FST = 18
1802 FST_ACTION_SETUP_REQUEST = 0
1803 FST_ACTION_SETUP_RESPONSE = 1
1804 FST_ACTION_TEAR_DOWN = 2
1805 FST_ACTION_ACK_REQUEST = 3
1806 FST_ACTION_ACK_RESPONSE = 4
1807 FST_ACTION_ON_CHANNEL_TUNNEL = 5
1808
1809 def hostapd_tx_and_status(hapd, msg):
1810     hapd.set("ext_mgmt_frame_handling", "1")
1811     hapd.mgmt_tx(msg)
1812     ev = hapd.wait_event([ "MGMT-TX-STATUS" ], timeout=1)
1813     if ev is None or "ok=1" not in ev:
1814         raise Exception("No ACK")
1815     hapd.set("ext_mgmt_frame_handling", "0")
1816
1817 def test_fst_proto(dev, apdev, test_params):
1818     """FST protocol testing"""
1819     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1820     try:
1821         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1822         hapd = ap1.get_instance()
1823         sta = sta1.get_instance()
1824         dst = sta.own_addr()
1825         src = apdev[0]['bssid']
1826
1827         msg = {}
1828         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1829         msg['da'] = dst
1830         msg['sa'] = src
1831         msg['bssid'] = src
1832
1833         # unknown FST Action (255) received!
1834         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST, 255)
1835         hostapd_tx_and_status(hapd, msg)
1836
1837         # FST Request dropped: too short
1838         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1839                                      FST_ACTION_SETUP_REQUEST)
1840         hostapd_tx_and_status(hapd, msg)
1841
1842         # FST Request dropped: invalid STIE (EID)
1843         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1844                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1845                                      163, 11, 0, 0, 0, 0, 0, 0, 0, 0)
1846         hostapd_tx_and_status(hapd, msg)
1847
1848         # FST Request dropped: invalid STIE (Len)
1849         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1850                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1851                                      164, 10, 0, 0, 0, 0, 0, 0, 0, 0)
1852         hostapd_tx_and_status(hapd, msg)
1853
1854         # FST Request dropped: new and old band IDs are the same
1855         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1856                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1857                                      164, 11, 0, 0, 0, 0, 0, 0, 0, 0)
1858         hostapd_tx_and_status(hapd, msg)
1859
1860         ifaces = sta1.list_ifaces()
1861         id = int(ifaces[0]['name'].split('|')[1])
1862         # FST Request dropped: new iface not found (new_band_id mismatch)
1863         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1864                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1865                                      164, 11, 0, 0, id + 1, 0, 0, 0, 0, 0)
1866         hostapd_tx_and_status(hapd, msg)
1867
1868         # FST Action 'Setup Response' dropped: no session in progress found
1869         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1870                                      FST_ACTION_SETUP_RESPONSE)
1871         hostapd_tx_and_status(hapd, msg)
1872
1873         # Create session
1874         initiator = ap1
1875         responder = sta1
1876         new_iface = ap2.ifname()
1877         new_peer_addr = ap2.get_actual_peer_addr()
1878         resp_newif = sta2.ifname()
1879         peeraddr = None
1880         initiator.add_peer(responder, peeraddr, new_peer_addr)
1881         sid = initiator.add_session()
1882         initiator.configure_session(sid, new_iface)
1883         initiator.initiate_session(sid, "accept")
1884
1885         # FST Response dropped due to wrong state: SETUP_COMPLETION
1886         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1887                                      FST_ACTION_SETUP_RESPONSE)
1888         hostapd_tx_and_status(hapd, msg)
1889
1890         # Too short FST Tear Down dropped
1891         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1892                                      FST_ACTION_TEAR_DOWN)
1893         hostapd_tx_and_status(hapd, msg)
1894
1895         # tear down for wrong FST Setup ID (0)
1896         msg['payload'] = struct.pack("<BBL", ACTION_CATEG_FST,
1897                                      FST_ACTION_TEAR_DOWN, 0)
1898         hostapd_tx_and_status(hapd, msg)
1899
1900         # Ack received on wrong interface
1901         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1902                                      FST_ACTION_ACK_REQUEST)
1903         hostapd_tx_and_status(hapd, msg)
1904
1905         # Ack Response in inappropriate session state (SETUP_COMPLETION)
1906         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1907                                      FST_ACTION_ACK_RESPONSE)
1908         hostapd_tx_and_status(hapd, msg)
1909
1910         # Unsupported FST Action frame (On channel tunnel)
1911         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1912                                      FST_ACTION_ON_CHANNEL_TUNNEL)
1913         hostapd_tx_and_status(hapd, msg)
1914
1915         # FST Request dropped: new iface not found (new_band_id match)
1916         # FST Request dropped due to MAC comparison
1917         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1918                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1919                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
1920         hostapd_tx_and_status(hapd, msg)
1921
1922         hapd2 = ap2.get_instance()
1923         dst2 = sta2.get_instance().own_addr()
1924         src2 = apdev[1]['bssid']
1925
1926         msg2 = {}
1927         msg2['fc'] = MGMT_SUBTYPE_ACTION << 4
1928         msg2['da'] = dst2
1929         msg2['sa'] = src2
1930         msg2['bssid'] = src2
1931         # FST Response dropped: wlan6 is not the old iface
1932         msg2['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1933                                       FST_ACTION_SETUP_RESPONSE)
1934         hostapd_tx_and_status(hapd2, msg2)
1935
1936         sta.dump_monitor()
1937
1938         group = ap1.fst_group
1939         ap1.send_iface_detach_request(ap1.iface)
1940
1941         sta.flush_scan_cache()
1942         sta.request("REASSOCIATE")
1943         sta.wait_connected()
1944
1945         # FST Request dropped due to no interface connection
1946         msg['payload'] = struct.pack("<BBBLBBLBBBBBBB", ACTION_CATEG_FST,
1947                                      FST_ACTION_SETUP_REQUEST, 0, 0,
1948                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
1949         hostapd_tx_and_status(hapd, msg)
1950     finally:
1951         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1952         try:
1953             fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1954         except:
1955             pass
1956
1957 def test_fst_setup_response_proto(dev, apdev, test_params):
1958     """FST protocol testing for Setup Response"""
1959     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
1960     try:
1961         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
1962         hapd = ap1.get_instance()
1963         sta = sta1.get_instance()
1964         dst = sta.own_addr()
1965         src = apdev[0]['bssid']
1966
1967         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
1968         sta1.set_fst_parameters(llt='0')
1969         sid = sta1.add_session()
1970         sta1.configure_session(sid, sta2.ifname())
1971         sta1.initiate_session(sid, "")
1972
1973         msg = {}
1974         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1975         msg['da'] = dst
1976         msg['sa'] = src
1977         msg['bssid'] = src
1978
1979         # Too short FST Response dropped
1980         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
1981                                      FST_ACTION_SETUP_RESPONSE)
1982         hostapd_tx_and_status(hapd, msg)
1983
1984         # FST Response dropped: invalid STIE (EID)
1985         dialog_token = 1
1986         status_code = 0
1987         id = 0
1988         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
1989                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
1990                                      status_code,
1991                                      163, 11, 0, 0, id, 0, 0, 0, 0, 0)
1992         hostapd_tx_and_status(hapd, msg)
1993
1994         # FST Response dropped: invalid STIE (Len)
1995         dialog_token = 1
1996         status_code = 0
1997         id = 0
1998         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
1999                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2000                                      status_code,
2001                                      164, 10, 0, 0, id, 0, 0, 0, 0, 0)
2002         hostapd_tx_and_status(hapd, msg)
2003
2004         # FST Response dropped due to wrong dialog token
2005         dialog_token = 123
2006         status_code = 0
2007         id = 0
2008         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2009                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2010                                      status_code,
2011                                      164, 11, 0, 0, id, 0, 0, 0, 0, 0)
2012         hostapd_tx_and_status(hapd, msg)
2013
2014         # FST Response dropped due to wrong FST Session ID
2015         dialog_token = 1
2016         status_code = 0
2017         id = 1
2018         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2019                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2020                                      status_code,
2021                                      164, 11, int(sid) + 123456,
2022                                      0, id, 0, 0, 0, 0, 0)
2023         hostapd_tx_and_status(hapd, msg)
2024
2025         # FST Response with non-zero status code
2026         dialog_token = 1
2027         status_code = 1
2028         id = 1
2029         msg['payload'] = struct.pack("<BBBBBBLBBBBBBB", ACTION_CATEG_FST,
2030                                      FST_ACTION_SETUP_RESPONSE, dialog_token,
2031                                      status_code,
2032                                      164, 11, int(sid), 0, id, 0, 0, 0, 0, 0)
2033         hostapd_tx_and_status(hapd, msg)
2034     finally:
2035         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2036         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2037
2038 def test_fst_ack_response_proto(dev, apdev, test_params):
2039     """FST protocol testing for Ack Response"""
2040     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2041     try:
2042         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2043         hapd = ap2.get_instance()
2044         sta = sta2.get_instance()
2045         dst = sta.own_addr()
2046         src = apdev[1]['bssid']
2047
2048         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
2049         sta1.set_fst_parameters(llt='0')
2050         sid = sta1.add_session()
2051         sta1.configure_session(sid, sta2.ifname())
2052
2053         s = sta1.grequest("FST-MANAGER SESSION_INITIATE "+ sid)
2054         if not s.startswith('OK'):
2055             raise Exception("Cannot initiate fst session: %s" % s)
2056         ev = sta1.peer_obj.wait_gevent([ "FST-EVENT-SESSION" ], timeout=5)
2057         if ev is None:
2058             raise Exception("No FST-EVENT-SESSION received")
2059         event = fst_module_aux.parse_fst_session_event(ev)
2060         if event == None:
2061             raise Exception("Unrecognized FST event: " % ev)
2062         if event['type'] != 'EVENT_FST_SETUP':
2063             raise Exception("Expected FST_SETUP event, got: " + event['type'])
2064         ev = sta1.peer_obj.wait_gevent(["FST-EVENT-SESSION"], timeout=5)
2065         if ev is None:
2066             raise Exception("No FST-EVENT-SESSION received")
2067         event = fst_module_aux.parse_fst_session_event(ev)
2068         if event == None:
2069             raise Exception("Unrecognized FST event: " % ev)
2070         if event['type'] != 'EVENT_FST_SESSION_STATE':
2071             raise Exception("Expected EVENT_FST_SESSION_STATE event, got: " + event['type'])
2072         if event['new_state'] != "SETUP_COMPLETION":
2073             raise Exception("Expected new state SETUP_COMPLETION, got: " + event['new_state'])
2074
2075         hapd.set("ext_mgmt_frame_handling", "1")
2076         s = sta1.peer_obj.grequest("FST-MANAGER SESSION_RESPOND "+ event['id'] + " accept")
2077         if not s.startswith('OK'):
2078             raise Exception("Error session_respond: %s" % s)
2079         req = hapd.mgmt_rx()
2080         if req is None:
2081             raise Exception("No Ack Request seen")
2082         msg = {}
2083         msg['fc'] = MGMT_SUBTYPE_ACTION << 4
2084         msg['da'] = dst
2085         msg['sa'] = src
2086         msg['bssid'] = src
2087
2088         # Too short FST Ack Response dropped
2089         msg['payload'] = struct.pack("<BB", ACTION_CATEG_FST,
2090                                      FST_ACTION_ACK_RESPONSE)
2091         hapd.mgmt_tx(msg)
2092         ev = hapd.wait_event([ "MGMT-TX-STATUS" ], timeout=1)
2093         if ev is None or "ok=1" not in ev:
2094             raise Exception("No ACK")
2095
2096         # Ack Response for wrong FSt Setup ID
2097         msg['payload'] = struct.pack("<BBBL", ACTION_CATEG_FST,
2098                                      FST_ACTION_ACK_RESPONSE,
2099                                      0, int(sid) + 123456)
2100         hostapd_tx_and_status(hapd, msg)
2101     finally:
2102         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2103         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2104
2105 def test_fst_ap_config_oom(dev, apdev, test_params):
2106     """FST AP configuration and OOM"""
2107     ap1 = fst_module_aux.FstAP(apdev[0]['ifname'], 'fst_11a', 'a',
2108                                fst_test_common.fst_test_def_chan_a,
2109                                fst_test_common.fst_test_def_group,
2110                                fst_test_common.fst_test_def_prio_low)
2111     hapd = ap1.start(return_early=True)
2112     with alloc_fail(hapd, 1, "fst_group_create"):
2113         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2114         if not res.startswith("FAIL"):
2115             raise Exception("FST-ATTACH succeeded unexpectedly")
2116
2117     with alloc_fail(hapd, 1, "fst_iface_create"):
2118         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2119         if not res.startswith("FAIL"):
2120             raise Exception("FST-ATTACH succeeded unexpectedly")
2121
2122     with alloc_fail(hapd, 1, "fst_group_create_mb_ie"):
2123         res = ap1.grequest("FST-ATTACH %s %s" % (ap1.iface, ap1.fst_group))
2124         # This is allowed to complete currently
2125
2126     ap1.stop()
2127
2128 def test_fst_send_oom(dev, apdev, test_params):
2129     """FST send action OOM"""
2130     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2131     try:
2132         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2133         hapd = ap1.get_instance()
2134         sta = sta1.get_instance()
2135         dst = sta.own_addr()
2136         src = apdev[0]['bssid']
2137
2138         # Create session
2139         initiator = ap1
2140         responder = sta1
2141         new_iface = ap2.ifname()
2142         new_peer_addr = ap2.get_actual_peer_addr()
2143         resp_newif = sta2.ifname()
2144         peeraddr = None
2145         initiator.add_peer(responder, peeraddr, new_peer_addr)
2146         sid = initiator.add_session()
2147         initiator.configure_session(sid, new_iface)
2148         with alloc_fail(hapd, 1, "fst_session_send_action"):
2149             res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2150             if not res.startswith("FAIL"):
2151                 raise Exception("Unexpected SESSION_INITIATE result")
2152
2153         res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2154         if not res.startswith("OK"):
2155             raise Exception("SESSION_INITIATE failed")
2156
2157         tests = [ "", "foo", sid, sid + " foo", sid + " foo=bar" ]
2158         for t in tests:
2159             res = initiator.grequest("FST-MANAGER SESSION_SET " + t)
2160             if not res.startswith("FAIL"):
2161                 raise Exception("Invalid SESSION_SET accepted")
2162
2163         with alloc_fail(hapd, 1, "fst_session_send_action"):
2164             res = initiator.grequest("FST-MANAGER SESSION_TEARDOWN " + sid)
2165             if not res.startswith("FAIL"):
2166                 raise Exception("Unexpected SESSION_TEARDOWN result")
2167     finally:
2168         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2169         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2170
2171 def test_fst_session_oom(dev, apdev, test_params):
2172     """FST session create OOM"""
2173     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2174     try:
2175         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2176         hapd = ap1.get_instance()
2177         sta = sta1.get_instance()
2178         dst = sta.own_addr()
2179         src = apdev[0]['bssid']
2180
2181         # Create session
2182         initiator = ap1
2183         responder = sta1
2184         new_iface = ap2.ifname()
2185         new_peer_addr = ap2.get_actual_peer_addr()
2186         resp_newif = sta2.ifname()
2187         peeraddr = None
2188         initiator.add_peer(responder, peeraddr, new_peer_addr)
2189         with alloc_fail(hapd, 1, "fst_session_create"):
2190             sid = initiator.grequest("FST-MANAGER SESSION_ADD " + initiator.fst_group)
2191             if not sid.startswith("FAIL"):
2192                 raise Exception("Unexpected SESSION_ADD success")
2193         sid = initiator.add_session()
2194         initiator.configure_session(sid, new_iface)
2195         with alloc_fail(sta, 1, "fst_session_create"):
2196             res = initiator.grequest("FST-MANAGER SESSION_INITIATE " + sid)
2197             if not res.startswith("OK"):
2198                 raise Exception("Unexpected SESSION_INITIATE result")
2199     finally:
2200         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2201         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2202
2203 def test_fst_attach_zero_llt(dev, apdev):
2204     """FST attach with llt=0"""
2205     sta1 = fst_module_aux.FstSTA('wlan5', fst_test_common.fst_test_def_group,
2206                                  "100", "0")
2207     sta1.start()
2208     sta1.stop()
2209
2210 def test_fst_session_respond_fail(dev, apdev, test_params):
2211     """FST-MANAGER SESSION_RESPOND failure"""
2212     ap1, ap2, sta1, sta2 = fst_module_aux.start_two_ap_sta_pairs(apdev)
2213     try:
2214         fst_module_aux.connect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2215         sta1.add_peer(ap1, None, sta2.get_actual_peer_addr())
2216         sid = sta1.add_session()
2217         sta1.configure_session(sid, sta2.ifname())
2218         sta1.send_session_setup_request(sid)
2219         sta1.wait_for_session_event(5, [], ["EVENT_FST_SESSION_STATE"])
2220         ev = ap1.wait_for_session_event(5, [], ['EVENT_FST_SETUP'])
2221         if not 'id' in ev:
2222             raise Exception("No session id in FST setup event")
2223         # Disconnect STA to make SESSION_RESPOND fail due to no peer found
2224         sta = sta1.get_instance()
2225         sta.request("DISCONNECT")
2226         sta.wait_disconnected()
2227         req = "FST-MANAGER SESSION_RESPOND %s reject" % ev['id']
2228         s = ap1.grequest(req)
2229         if not s.startswith("FAIL"):
2230             raise Exception("SESSION_RESPOND succeeded unexpectedly")
2231     finally:
2232         fst_module_aux.disconnect_two_ap_sta_pairs(ap1, ap2, sta1, sta2)
2233         fst_module_aux.stop_two_ap_sta_pairs(ap1, ap2, sta1, sta2)