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