tests: Pass full apdev to add_ap() function (1)
[mech_eap.git] / tests / hwsim / test_dfs.py
1 # Test cases for DFS
2 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import os
8 import subprocess
9 import time
10 import logging
11 logger = logging.getLogger()
12
13 import hwsim_utils
14 import hostapd
15 from utils import HwsimSkip
16
17 def wait_dfs_event(hapd, event, timeout):
18     dfs_events = [ "DFS-RADAR-DETECTED", "DFS-NEW-CHANNEL",
19                    "DFS-CAC-START", "DFS-CAC-COMPLETED",
20                    "DFS-NOP-FINISHED", "AP-ENABLED", "AP-CSA-FINISHED" ]
21     ev = hapd.wait_event(dfs_events, timeout=timeout)
22     if not ev:
23         raise Exception("DFS event timed out")
24     if event and event not in ev:
25         raise Exception("Unexpected DFS event")
26     return ev
27
28 def start_dfs_ap(ap, allow_failure=False, ssid="dfs", ht=True, ht40=False,
29                  ht40minus=False, vht80=False, vht20=False, chanlist=None,
30                  channel=None):
31     ifname = ap['ifname']
32     logger.info("Starting AP " + ifname + " on DFS channel")
33     hapd_global = hostapd.HostapdGlobal()
34     hapd_global.remove(ifname)
35     hapd_global.add(ifname)
36     hapd = hostapd.Hostapd(ifname)
37     if not hapd.ping():
38         raise Exception("Could not ping hostapd")
39     hapd.set_defaults()
40     hapd.set("ssid", ssid)
41     hapd.set("country_code", "FI")
42     hapd.set("ieee80211d", "1")
43     hapd.set("ieee80211h", "1")
44     hapd.set("hw_mode", "a")
45     hapd.set("channel", "52")
46     if not ht:
47         hapd.set("ieee80211n", "0")
48     if ht40:
49         hapd.set("ht_capab", "[HT40+]")
50     elif ht40minus:
51         hapd.set("ht_capab", "[HT40-]")
52         hapd.set("channel", "56")
53     if vht80:
54         hapd.set("ieee80211ac", "1")
55         hapd.set("vht_oper_chwidth", "1")
56         hapd.set("vht_oper_centr_freq_seg0_idx", "58")
57     if vht20:
58         hapd.set("ieee80211ac", "1")
59         hapd.set("vht_oper_chwidth", "0")
60         hapd.set("vht_oper_centr_freq_seg0_idx", "0")
61     if chanlist:
62         hapd.set("chanlist", chanlist)
63     if channel:
64         hapd.set("channel", str(channel))
65     hapd.enable()
66
67     ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
68     if "DFS-CAC-START" not in ev:
69         raise Exception("Unexpected DFS event")
70
71     state = hapd.get_status_field("state")
72     if state != "DFS":
73         if allow_failure:
74             logger.info("Interface state not DFS: " + state)
75             if not os.path.exists("dfs"):
76                 raise HwsimSkip("Assume DFS testing not supported")
77             raise Exception("Failed to start DFS AP")
78         raise Exception("Unexpected interface state: " + state)
79
80     return hapd
81
82 def dfs_simulate_radar(hapd):
83     logger.info("Trigger a simulated radar event")
84     phyname = hapd.get_driver_status_field("phyname")
85     radar_file = '/sys/kernel/debug/ieee80211/' + phyname + '/hwsim/dfs_simulate_radar'
86     with open(radar_file, 'w') as f:
87         f.write('1')
88
89 def test_dfs(dev, apdev):
90     """DFS CAC functionality on clear channel"""
91     try:
92         hapd = None
93         hapd = start_dfs_ap(apdev[0], allow_failure=True)
94
95         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
96         if "success=1" not in ev:
97             raise Exception("CAC failed")
98         if "freq=5260" not in ev:
99             raise Exception("Unexpected DFS freq result")
100
101         ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
102         if not ev:
103             raise Exception("AP setup timed out")
104
105         state = hapd.get_status_field("state")
106         if state != "ENABLED":
107             raise Exception("Unexpected interface state")
108
109         freq = hapd.get_status_field("freq")
110         if freq != "5260":
111             raise Exception("Unexpected frequency")
112
113         dev[0].connect("dfs", key_mgmt="NONE")
114         hwsim_utils.test_connectivity(dev[0], hapd)
115
116         hapd.request("RADAR DETECTED freq=5260 ht_enabled=1 chan_width=1")
117         ev = hapd.wait_event(["DFS-RADAR-DETECTED"], timeout=10)
118         if ev is None:
119             raise Exception("DFS-RADAR-DETECTED event not reported")
120         if "freq=5260" not in ev:
121             raise Exception("Incorrect frequency in radar detected event: " + ev);
122         ev = hapd.wait_event(["DFS-NEW-CHANNEL"], timeout=70)
123         if ev is None:
124             raise Exception("DFS-NEW-CHANNEL event not reported")
125         if "freq=5260" in ev:
126             raise Exception("Channel did not change after radar was detected");
127
128         ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=70)
129         if ev is None:
130             raise Exception("AP-CSA-FINISHED event not reported")
131         if "freq=5260" in ev:
132             raise Exception("Channel did not change after radar was detected(2)");
133         time.sleep(1)
134         hwsim_utils.test_connectivity(dev[0], hapd)
135     finally:
136         dev[0].request("DISCONNECT")
137         if hapd:
138             hapd.request("DISABLE")
139         subprocess.call(['iw', 'reg', 'set', '00'])
140         dev[0].flush_scan_cache()
141
142 def test_dfs_radar(dev, apdev):
143     """DFS CAC functionality with radar detected"""
144     try:
145         hapd = None
146         hapd2 = None
147         hapd = start_dfs_ap(apdev[0], allow_failure=True)
148         time.sleep(1)
149
150         dfs_simulate_radar(hapd)
151
152         hapd2 = start_dfs_ap(apdev[1], ssid="dfs2", ht40=True)
153
154         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
155         if ev is None:
156             raise Exception("Timeout on DFS aborted event")
157         if "success=0 freq=5260" not in ev:
158             raise Exception("Unexpected DFS aborted event contents: " + ev)
159
160         ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
161         if "freq=5260" not in ev:
162             raise Exception("Unexpected DFS radar detection freq")
163
164         ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
165         if "freq=5260" in ev:
166             raise Exception("Unexpected DFS new freq")
167
168         ev = wait_dfs_event(hapd, None, 5)
169         if "AP-ENABLED" in ev:
170             logger.info("Started AP on non-DFS channel")
171         else:
172             logger.info("Trying to start AP on another DFS channel")
173             if "DFS-CAC-START" not in ev:
174                 raise Exception("Unexpected DFS event")
175             if "freq=5260" in ev:
176                 raise Exception("Unexpected DFS CAC freq")
177
178             ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
179             if "success=1" not in ev:
180                 raise Exception("CAC failed")
181             if "freq=5260" in ev:
182                 raise Exception("Unexpected DFS freq result - radar channel")
183
184             ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
185             if not ev:
186                 raise Exception("AP setup timed out")
187
188             state = hapd.get_status_field("state")
189             if state != "ENABLED":
190                 raise Exception("Unexpected interface state")
191
192             freq = hapd.get_status_field("freq")
193             if freq == "5260":
194                 raise Exception("Unexpected frequency: " + freq)
195
196         dev[0].connect("dfs", key_mgmt="NONE")
197
198         ev = hapd2.wait_event(["AP-ENABLED"], timeout=70)
199         if not ev:
200             raise Exception("AP2 setup timed out")
201
202         dfs_simulate_radar(hapd2)
203
204         ev = wait_dfs_event(hapd2, "DFS-RADAR-DETECTED", 5)
205         if "freq=5260 ht_enabled=1 chan_offset=1 chan_width=2" not in ev:
206             raise Exception("Unexpected DFS radar detection freq from AP2")
207
208         ev = wait_dfs_event(hapd2, "DFS-NEW-CHANNEL", 5)
209         if "freq=5260" in ev:
210             raise Exception("Unexpected DFS new freq for AP2")
211
212         wait_dfs_event(hapd2, None, 5)
213     finally:
214         dev[0].request("DISCONNECT")
215         if hapd:
216             hapd.request("DISABLE")
217         if hapd2:
218             hapd2.request("DISABLE")
219         subprocess.call(['iw', 'reg', 'set', '00'])
220         dev[0].flush_scan_cache()
221
222 def test_dfs_radar_on_non_dfs_channel(dev, apdev):
223     """DFS radar detection test code on non-DFS channel"""
224     params = { "ssid": "radar" }
225     hapd = hostapd.add_ap(apdev[0], params)
226
227     hapd.request("RADAR DETECTED freq=5260 ht_enabled=1 chan_width=1")
228     hapd.request("RADAR DETECTED freq=2412 ht_enabled=1 chan_width=1")
229
230 def test_dfs_radar_chanlist(dev, apdev):
231     """DFS chanlist when radar is detected"""
232     try:
233         hapd = None
234         hapd = start_dfs_ap(apdev[0], chanlist="40 44", allow_failure=True)
235         time.sleep(1)
236
237         dfs_simulate_radar(hapd)
238
239         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
240         if ev is None:
241             raise Exception("Timeout on DFS aborted event")
242         if "success=0 freq=5260" not in ev:
243             raise Exception("Unexpected DFS aborted event contents: " + ev)
244
245         ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
246         if "freq=5260" not in ev:
247             raise Exception("Unexpected DFS radar detection freq")
248
249         ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
250         if "freq=5200 chan=40" not in ev and "freq=5220 chan=44" not in ev:
251             raise Exception("Unexpected DFS new freq: " + ev)
252
253         ev = wait_dfs_event(hapd, None, 5)
254         if "AP-ENABLED" not in ev:
255             raise Exception("Unexpected DFS event")
256         dev[0].connect("dfs", key_mgmt="NONE")
257     finally:
258         dev[0].request("DISCONNECT")
259         if hapd:
260             hapd.request("DISABLE")
261         subprocess.call(['iw', 'reg', 'set', '00'])
262         dev[0].flush_scan_cache()
263
264 def test_dfs_radar_chanlist_vht80(dev, apdev):
265     """DFS chanlist when radar is detected and VHT80 configured"""
266     try:
267         hapd = None
268         hapd = start_dfs_ap(apdev[0], chanlist="36", ht40=True, vht80=True,
269                             allow_failure=True)
270         time.sleep(1)
271
272         dfs_simulate_radar(hapd)
273
274         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
275         if ev is None:
276             raise Exception("Timeout on DFS aborted event")
277         if "success=0 freq=5260" not in ev:
278             raise Exception("Unexpected DFS aborted event contents: " + ev)
279
280         ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
281         if "freq=5260" not in ev:
282             raise Exception("Unexpected DFS radar detection freq")
283
284         ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
285         if "freq=5180 chan=36 sec_chan=1" not in ev:
286             raise Exception("Unexpected DFS new freq: " + ev)
287
288         ev = wait_dfs_event(hapd, None, 5)
289         if "AP-ENABLED" not in ev:
290             raise Exception("Unexpected DFS event")
291         dev[0].connect("dfs", key_mgmt="NONE")
292
293         if hapd.get_status_field('vht_oper_centr_freq_seg0_idx') != "42":
294             raise Exception("Unexpected seg0 idx")
295     finally:
296         dev[0].request("DISCONNECT")
297         if hapd:
298             hapd.request("DISABLE")
299         subprocess.call(['iw', 'reg', 'set', '00'])
300         dev[0].flush_scan_cache()
301
302 def test_dfs_radar_chanlist_vht20(dev, apdev):
303     """DFS chanlist when radar is detected and VHT40 configured"""
304     try:
305         hapd = None
306         hapd = start_dfs_ap(apdev[0], chanlist="36", vht20=True,
307                             allow_failure=True)
308         time.sleep(1)
309
310         dfs_simulate_radar(hapd)
311
312         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
313         if ev is None:
314             raise Exception("Timeout on DFS aborted event")
315         if "success=0 freq=5260" not in ev:
316             raise Exception("Unexpected DFS aborted event contents: " + ev)
317
318         ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
319         if "freq=5260" not in ev:
320             raise Exception("Unexpected DFS radar detection freq")
321
322         ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
323         if "freq=5180 chan=36 sec_chan=0" not in ev:
324             raise Exception("Unexpected DFS new freq: " + ev)
325
326         ev = wait_dfs_event(hapd, None, 5)
327         if "AP-ENABLED" not in ev:
328             raise Exception("Unexpected DFS event")
329         dev[0].connect("dfs", key_mgmt="NONE")
330     finally:
331         dev[0].request("DISCONNECT")
332         if hapd:
333             hapd.request("DISABLE")
334         subprocess.call(['iw', 'reg', 'set', '00'])
335         dev[0].flush_scan_cache()
336
337 def test_dfs_radar_no_ht(dev, apdev):
338     """DFS chanlist when radar is detected and no HT configured"""
339     try:
340         hapd = None
341         hapd = start_dfs_ap(apdev[0], chanlist="36", ht=False,
342                             allow_failure=True)
343         time.sleep(1)
344
345         dfs_simulate_radar(hapd)
346
347         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
348         if ev is None:
349             raise Exception("Timeout on DFS aborted event")
350         if "success=0 freq=5260" not in ev:
351             raise Exception("Unexpected DFS aborted event contents: " + ev)
352
353         ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
354         if "freq=5260 ht_enabled=0" not in ev:
355             raise Exception("Unexpected DFS radar detection freq: " + ev)
356
357         ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
358         if "freq=5180 chan=36 sec_chan=0" not in ev:
359             raise Exception("Unexpected DFS new freq: " + ev)
360
361         ev = wait_dfs_event(hapd, None, 5)
362         if "AP-ENABLED" not in ev:
363             raise Exception("Unexpected DFS event")
364         dev[0].connect("dfs", key_mgmt="NONE")
365     finally:
366         dev[0].request("DISCONNECT")
367         if hapd:
368             hapd.request("DISABLE")
369         subprocess.call(['iw', 'reg', 'set', '00'])
370         dev[0].flush_scan_cache()
371
372 def test_dfs_radar_ht40minus(dev, apdev):
373     """DFS chanlist when radar is detected and HT40- configured"""
374     try:
375         hapd = None
376         hapd = start_dfs_ap(apdev[0], chanlist="36", ht40minus=True,
377                             allow_failure=True)
378         time.sleep(1)
379
380         dfs_simulate_radar(hapd)
381
382         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
383         if ev is None:
384             raise Exception("Timeout on DFS aborted event")
385         if "success=0 freq=5280 ht_enabled=1 chan_offset=-1" not in ev:
386             raise Exception("Unexpected DFS aborted event contents: " + ev)
387
388         ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
389         if "freq=5280 ht_enabled=1 chan_offset=-1" not in ev:
390             raise Exception("Unexpected DFS radar detection freq: " + ev)
391
392         ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
393         if "freq=5180 chan=36 sec_chan=1" not in ev:
394             raise Exception("Unexpected DFS new freq: " + ev)
395
396         ev = wait_dfs_event(hapd, None, 5)
397         if "AP-ENABLED" not in ev:
398             raise Exception("Unexpected DFS event")
399         dev[0].connect("dfs", key_mgmt="NONE")
400     finally:
401         dev[0].request("DISCONNECT")
402         if hapd:
403             hapd.request("DISABLE")
404         subprocess.call(['iw', 'reg', 'set', '00'])
405         dev[0].flush_scan_cache()
406
407 def test_dfs_ht40_minus(dev, apdev, params):
408     """DFS CAC functionality on channel 104 HT40- [long]"""
409     if not params['long']:
410         raise HwsimSkip("Skip test case with long duration due to --long not specified")
411     try:
412         hapd = None
413         hapd = start_dfs_ap(apdev[0], allow_failure=True, ht40minus=True,
414                             channel=104)
415
416         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
417         if "success=1" not in ev:
418             raise Exception("CAC failed")
419         if "freq=5520" not in ev:
420             raise Exception("Unexpected DFS freq result")
421
422         ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
423         if not ev:
424             raise Exception("AP setup timed out")
425
426         state = hapd.get_status_field("state")
427         if state != "ENABLED":
428             raise Exception("Unexpected interface state")
429
430         freq = hapd.get_status_field("freq")
431         if freq != "5520":
432             raise Exception("Unexpected frequency")
433
434         dev[0].connect("dfs", key_mgmt="NONE", scan_freq="5520")
435         hwsim_utils.test_connectivity(dev[0], hapd)
436     finally:
437         dev[0].request("DISCONNECT")
438         if hapd:
439             hapd.request("DISABLE")
440         subprocess.call(['iw', 'reg', 'set', '00'])
441         dev[0].flush_scan_cache()