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