]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_wpas_wmm_ac.py
tests: Convert kernel-config to defconfig
[thirdparty/hostap.git] / tests / hwsim / test_wpas_wmm_ac.py
CommitLineData
76133458
EP
1# Test cases for wpa_supplicant WMM-AC operations
2# Copyright (c) 2014, Intel Corporation
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
9fd6804d 7from remotehost import remote_compatible
76133458
EP
8import logging
9logger = logging.getLogger()
ceb767d5 10import struct
c45b969d 11import sys
76133458
EP
12
13import hwsim_utils
14import hostapd
f603c320 15from utils import fail_test
76133458
EP
16
17def add_wmm_ap(apdev, acm_list):
fab49f61
JM
18 params = {"ssid": "wmm_ac",
19 "hw_mode": "g",
20 "channel": "11",
21 "wmm_enabled": "1"}
76133458
EP
22
23 for ac in acm_list:
24 params["wmm_ac_%s_acm" % (ac.lower())] = "1"
25
afc26df2 26 return hostapd.add_ap(apdev, params)
76133458
EP
27
28def test_tspec(dev, apdev):
29 """Basic addts/delts tests"""
30 # configure ap with VO and VI requiring admission-control
bc32f830 31 hapd = add_wmm_ap(apdev[0], ["VO", "VI"])
76133458
EP
32 dev[0].connect("wmm_ac", key_mgmt="NONE", scan_freq="2462")
33 hwsim_utils.test_connectivity(dev[0], hapd)
34 status = dev[0].request("WMM_AC_STATUS")
35 if "WMM AC is Enabled" not in status:
36 raise Exception("WMM-AC not enabled")
37 if "TSID" in status:
38 raise Exception("Unexpected TSID info")
39 if "BK: acm=0 uapsd=0" not in status:
40 raise Exception("Unexpected BK info" + status)
41 if "BE: acm=0 uapsd=0" not in status:
42 raise Exception("Unexpected BE info" + status)
43 if "VI: acm=1 uapsd=0" not in status:
44 raise Exception("Unexpected VI info" + status)
45 if "VO: acm=1 uapsd=0" not in status:
46 raise Exception("Unexpected VO info" + status)
47
ceb767d5
JM
48 # no tsid --> tsid out of range
49 if "FAIL" not in dev[0].request("WMM_AC_ADDTS downlink"):
50 raise Exception("Invalid WMM_AC_ADDTS accepted")
51 # no direction
52 if "FAIL" not in dev[0].request("WMM_AC_ADDTS tsid=5"):
53 raise Exception("Invalid WMM_AC_ADDTS accepted")
54 # param out of range
55 if "FAIL" not in dev[0].request("WMM_AC_ADDTS tsid=5 downlink"):
56 raise Exception("Invalid WMM_AC_ADDTS accepted")
57
76133458
EP
58 tsid = 5
59
60 # make sure we fail when the ac is not configured for acm
61 try:
62 dev[0].add_ts(tsid, 3)
63 raise Exception("ADDTS succeeded although it should have failed")
bab493b9 64 except Exception as e:
76133458
EP
65 if not str(e).startswith("ADDTS failed"):
66 raise
67 status = dev[0].request("WMM_AC_STATUS")
68 if "TSID" in status:
69 raise Exception("Unexpected TSID info")
70
71 # add tspec for UP=6
72 dev[0].add_ts(tsid, 6)
73 status = dev[0].request("WMM_AC_STATUS")
74 if "TSID" not in status:
75 raise Exception("Missing TSID info")
76
77 # using the same tsid for a different ac is invalid
78 try:
79 dev[0].add_ts(tsid, 5)
80 raise Exception("ADDTS succeeded although it should have failed")
bab493b9 81 except Exception as e:
76133458
EP
82 if not str(e).startswith("ADDTS failed"):
83 raise
84
85 # update the tspec for a different UP of the same ac
ceb767d5 86 dev[0].add_ts(tsid, 7, extra="fixed_nominal_msdu")
76133458
EP
87 dev[0].del_ts(tsid)
88 status = dev[0].request("WMM_AC_STATUS")
89 if "TSID" in status:
90 raise Exception("Unexpected TSID info")
ceb767d5
JM
91
92 # verify failure on uplink/bidi without driver support
93 tsid = 6
94 try:
95 dev[0].add_ts(tsid, 7, direction="uplink")
96 raise Exception("ADDTS succeeded although it should have failed")
bab493b9 97 except Exception as e:
ceb767d5
JM
98 if not str(e).startswith("ADDTS failed"):
99 raise
100 try:
101 dev[0].add_ts(tsid, 7, direction="bidi")
102 raise Exception("ADDTS succeeded although it should have failed")
bab493b9 103 except Exception as e:
ceb767d5
JM
104 if not str(e).startswith("ADDTS failed"):
105 raise
106
107 # attempt to delete non-existing tsid
108 try:
109 dev[0].del_ts(tsid)
110 raise Exception("DELTS succeeded although it should have failed")
bab493b9 111 except Exception as e:
ceb767d5
JM
112 if not str(e).startswith("DELTS failed"):
113 raise
114
765c15d5
JM
115 # "CTRL: Invalid WMM_AC_ADDTS parameter: 'foo'
116 if "FAIL" not in dev[0].request("WMM_AC_ADDTS foo"):
117 raise Exception("Invalid WMM_AC_ADDTS command accepted")
118
ceb767d5
JM
119def test_tspec_protocol(dev, apdev):
120 """Protocol tests for addts/delts"""
121 # configure ap with VO and VI requiring admission-control
bc32f830 122 hapd = add_wmm_ap(apdev[0], ["VO", "VI"])
ceb767d5
JM
123 dev[0].connect("wmm_ac", key_mgmt="NONE", scan_freq="2462")
124
125 dev[0].dump_monitor()
126 hapd.set("ext_mgmt_frame_handling", "1")
127
128 tsid = 6
129
130 # timeout on ADDTS response
131 dev[0].add_ts(tsid, 7, expect_failure=True)
132
133 hapd.dump_monitor()
134 req = "WMM_AC_ADDTS downlink tsid=6 up=7 nominal_msdu_size=1500 sba=9000 mean_data_rate=1500 min_phy_rate=6000000"
135 if "OK" not in dev[0].request(req):
136 raise Exception("WMM_AC_ADDTS failed")
137 # a new request while previous is still pending
138 if "FAIL" not in dev[0].request(req):
139 raise Exception("WMM_AC_ADDTS accepted while oen was still pending")
140 msg = hapd.mgmt_rx()
141 payload = msg['payload']
142 (categ, action, dialog, status) = struct.unpack('BBBB', payload[0:4])
143 if action != 0:
144 raise Exception("Unexpected Action code: %d" % action)
145
146 msg['da'] = msg['sa']
147 msg['sa'] = apdev[0]['bssid']
148
149 # unexpected dialog token
150 msg['payload'] = struct.pack('BBBB', 17, 1, (dialog + 1) & 0xff, 0) + payload[4:]
151 hapd.mgmt_tx(msg)
152
153 # valid response
154 msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:]
155 hapd.mgmt_tx(msg)
156 ev = dev[0].wait_event(["TSPEC-ADDED"], timeout=10)
157 if ev is None:
158 raise Exception("Timeout on TSPEC-ADDED")
159 if "tsid=%d" % tsid not in ev:
160 raise Exception("Unexpected TSPEC-ADDED contents: " + ev)
161
162 # duplicated response
163 msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:]
164 hapd.mgmt_tx(msg)
165
166 # too short ADDTS
167 msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0)
168 hapd.mgmt_tx(msg)
169
170 # invalid IE
171 msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:] + struct.pack('BB', 0xdd, 100)
172 hapd.mgmt_tx(msg)
173
174 # too short WMM element
15dfcb69 175 msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 0) + payload[4:] + b'\xdd\x06\x00\x50\xf2\x02\x02\x01'
ceb767d5
JM
176 hapd.mgmt_tx(msg)
177
178 # DELTS
179 dev[0].dump_monitor()
180 msg['payload'] = struct.pack('BBBB', 17, 2, 0, 0) + payload[4:]
181 hapd.mgmt_tx(msg)
182 ev = dev[0].wait_event(['TSPEC-REMOVED'], timeout=6)
183 if ev is None:
184 raise Exception("Timeout on TSPEC-REMOVED event")
185 if "tsid=%d" % tsid not in ev:
186 raise Exception("Unexpected TSPEC-REMOVED contents: " + ev)
187 # DELTS duplicated
188 msg['payload'] = struct.pack('BBBB', 17, 2, 0, 0) + payload[4:]
189 hapd.mgmt_tx(msg)
190
191 # start a new request
192 hapd.dump_monitor()
193 if "OK" not in dev[0].request(req):
194 raise Exception("WMM_AC_ADDTS failed")
195 msg = hapd.mgmt_rx()
196 payload = msg['payload']
197 (categ, action, dialog, status) = struct.unpack('BBBB', payload[0:4])
198 if action != 0:
199 raise Exception("Unexpected Action code: %d" % action)
200
201 msg['da'] = msg['sa']
202 msg['sa'] = apdev[0]['bssid']
203
204 # modified parameters
c45b969d
JM
205 p12int = payload[12] if sys.version_info[0] > 2 else ord(payload[12])
206 msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 1) + payload[4:12] + struct.pack('B', p12int & ~0x60) + payload[13:]
ceb767d5
JM
207 hapd.mgmt_tx(msg)
208
209 # reject request
210 msg['payload'] = struct.pack('BBBB', 17, 1, dialog, 1) + payload[4:]
211 hapd.mgmt_tx(msg)
212 ev = dev[0].wait_event(["TSPEC-REQ-FAILED"], timeout=10)
213 if ev is None:
214 raise Exception("Timeout on TSPEC-REQ-FAILED")
215 if "tsid=%d" % tsid not in ev:
216 raise Exception("Unexpected TSPEC-REQ-FAILED contents: " + ev)
217
218 hapd.set("ext_mgmt_frame_handling", "0")
219
9fd6804d 220@remote_compatible
ceb767d5
JM
221def test_tspec_not_enabled(dev, apdev):
222 """addts failing if AP does not support WMM"""
fab49f61
JM
223 params = {"ssid": "wmm_no_ac",
224 "hw_mode": "g",
225 "channel": "11",
226 "wmm_enabled": "0"}
8b8a1864 227 hapd = hostapd.add_ap(apdev[0], params)
ceb767d5
JM
228 dev[0].connect("wmm_no_ac", key_mgmt="NONE", scan_freq="2462")
229 status = dev[0].request("WMM_AC_STATUS")
230 if "Not associated to a WMM AP, WMM AC is Disabled" not in status:
231 raise Exception("Unexpected WMM_AC_STATUS: " + status)
232
233 try:
234 dev[0].add_ts(5, 6)
235 raise Exception("ADDTS succeeded although it should have failed")
bab493b9 236 except Exception as e:
ceb767d5
JM
237 if not str(e).startswith("ADDTS failed"):
238 raise
239
240 # attempt to delete non-existing tsid
241 try:
242 dev[0].del_ts(5)
243 raise Exception("DELTS succeeded although it should have failed")
bab493b9 244 except Exception as e:
ceb767d5
JM
245 if not str(e).startswith("DELTS failed"):
246 raise
247
248 # unexpected Action frame when WMM is disabled
249 MGMT_SUBTYPE_ACTION = 13
250 msg = {}
251 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
252 msg['da'] = dev[0].p2p_interface_addr()
253 msg['sa'] = apdev[0]['bssid']
254 msg['bssid'] = apdev[0]['bssid']
255 msg['payload'] = struct.pack('BBBB', 17, 2, 0, 0)
256 hapd.mgmt_tx(msg)
bc32f830 257
9fd6804d 258@remote_compatible
bc32f830
EP
259def test_tspec_ap_roam_open(dev, apdev):
260 """Roam between two open APs while having tspecs"""
261 hapd0 = add_wmm_ap(apdev[0], ["VO", "VI"])
262 dev[0].connect("wmm_ac", key_mgmt="NONE")
263 hwsim_utils.test_connectivity(dev[0], hapd0)
264 dev[0].add_ts(5, 6)
265
266 hapd1 = add_wmm_ap(apdev[1], ["VO", "VI"])
267 dev[0].scan_for_bss(apdev[1]['bssid'], freq=2462)
268 dev[0].roam(apdev[1]['bssid'])
269 hwsim_utils.test_connectivity(dev[0], hapd1)
270 if dev[0].tspecs():
271 raise Exception("TSPECs weren't deleted on roaming")
272
273 dev[0].scan_for_bss(apdev[0]['bssid'], freq=2462)
274 dev[0].roam(apdev[0]['bssid'])
275 hwsim_utils.test_connectivity(dev[0], hapd0)
41bf7644 276
9fd6804d 277@remote_compatible
41bf7644
EP
278def test_tspec_reassoc(dev, apdev):
279 """Reassociation to same BSS while having tspecs"""
280 hapd0 = add_wmm_ap(apdev[0], ["VO", "VI"])
281 dev[0].connect("wmm_ac", key_mgmt="NONE")
282 hwsim_utils.test_connectivity(dev[0], hapd0)
283 dev[0].add_ts(5, 6)
284 last_tspecs = dev[0].tspecs()
285
286 dev[0].request("REASSOCIATE")
287 dev[0].wait_connected()
288
289 hwsim_utils.test_connectivity(dev[0], hapd0)
290 if dev[0].tspecs() != last_tspecs:
291 raise Exception("TSPECs weren't saved on reassociation")
f603c320
JM
292
293def test_wmm_element(dev, apdev):
294 """hostapd FTM range request timeout"""
295 try:
296 run_wmm_element(dev, apdev)
297 finally:
298 dev[0].request("VENDOR_ELEM_REMOVE 13 *")
299
300def run_wmm_element(dev, apdev):
fab49f61 301 params = {"ssid": "wmm"}
f603c320
JM
302 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
303 bssid = hapd.own_addr()
304
305 # Too short WMM IE
306 dev[0].request("VENDOR_ELEM_ADD 13 dd060050f2020001")
307 dev[0].scan_for_bss(bssid, freq=2412)
308 dev[0].connect("wmm", key_mgmt="NONE", scan_freq="2412", wait_connect=False)
309 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
310 if ev is None:
311 raise Exception("Association not rejected")
312 dev[0].request("REMOVE_NETWORK all")
313
314 # Unsupported WMM IE Subtype/Version
315 dev[0].request("VENDOR_ELEM_ADD 13 dd070050f202000000")
316 dev[0].connect("wmm", key_mgmt="NONE", scan_freq="2412", wait_connect=False)
317 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
318 if ev is None:
319 raise Exception("Association not rejected")
320 dev[0].request("REMOVE_NETWORK all")
321
322 # Unsupported WMM IE Subtype/Version
323 dev[0].request("VENDOR_ELEM_ADD 13 dd070050f202010100")
324 dev[0].connect("wmm", key_mgmt="NONE", scan_freq="2412", wait_connect=False)
325 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
326 if ev is None:
327 raise Exception("Association not rejected")
328 dev[0].request("REMOVE_NETWORK all")
329
330def test_tspec_ap_fail(dev, apdev):
331 """AP failing to send tspec response"""
332 # configure ap with VO and VI requiring admission-control
333 hapd = add_wmm_ap(apdev[0], ["VO", "VI"])
334 dev[0].connect("wmm_ac", key_mgmt="NONE", scan_freq="2462")
335 tsid = 5
336
337 with fail_test(hapd, 1, "wmm_send_action"):
338 try:
339 # add tspec for UP=6
340 dev[0].add_ts(tsid, 6)
341 except:
342 pass
343
344def test_tspec_ap_parsing(dev, apdev):
345 """TSPEC AP parsing tests"""
346 # configure ap with VO and VI requiring admission-control
347 hapd = add_wmm_ap(apdev[0], ["VO", "VI"])
348 bssid = hapd.own_addr()
349 dev[0].connect("wmm_ac", key_mgmt="NONE", scan_freq="2462")
350 addr = dev[0].own_addr()
351
fab49f61
JM
352 tests = ["WMM_AC_ADDTS downlink tsid=5 up=6 nominal_msdu_size=1500 sba=9000 mean_data_rate=1500 min_phy_rate=600000",
353 "WMM_AC_ADDTS downlink tsid=5 up=6 nominal_msdu_size=1500 sba=8192 mean_data_rate=1500 min_phy_rate=6000000",
354 "WMM_AC_ADDTS downlink tsid=5 up=6 nominal_msdu_size=32767 sba=65535 mean_data_rate=1500 min_phy_rate=1000000",
355 "WMM_AC_ADDTS downlink tsid=5 up=6 nominal_msdu_size=10000 sba=65535 mean_data_rate=2147483647 min_phy_rate=1000000"]
f603c320
JM
356 for t in tests:
357 if "OK" not in dev[0].request(t):
358 raise Exception("WMM_AC_ADDTS failed")
359 ev = dev[0].wait_event(["TSPEC-REQ-FAILED"], timeout=1)
360 if ev is None:
361 raise Exception("No response")
362
363 tests = []
364 # WMM: Invalid Nominal MSDU Size (0)
fab49f61 365 tests += ["11000400dd3d0050f2020201aa300000000000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000"]
f603c320 366 # hostapd_wmm_action - missing or wrong length tspec
fab49f61 367 tests += ["11000400dd3e0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff000000"]
f603c320 368 # hostapd_wmm_action - could not parse wmm action
fab49f61 369 tests += ["11000400dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff00"]
f603c320 370 # valid form
fab49f61 371 tests += ["11000400dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000"]
f603c320
JM
372
373 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
374 hapd.set("ext_mgmt_frame_handling", "1")
375 for t in tests:
376 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
377 raise Exception("MGMT_RX_PROCESS failed")
378
379 hapd.set("ext_mgmt_frame_handling", "0")
380
381def test_wmm_disabled(dev, apdev):
382 """WMM disabled and unexpected TSPEC"""
fab49f61 383 params = {"ssid": "no-wmm", "ieee80211n": "0", "wmm_enabled": "0"}
f603c320
JM
384 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
385 bssid = hapd.own_addr()
386 dev[0].connect("no-wmm", key_mgmt="NONE", scan_freq="2412")
387 addr = dev[0].own_addr()
388
389 # wmm action received is not from associated wmm station
390 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
391 hapd.set("ext_mgmt_frame_handling", "1")
392 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "11000400dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000"):
393 raise Exception("MGMT_RX_PROCESS failed")
394
395 # IEEE 802.11: Ignored Action frame (category=17) from unassociated STA
396 hdr = "d0003a01" + bssid.replace(':', '') + "112233445566" + bssid.replace(':', '') + "1000"
397 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "11000400dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000"):
398 raise Exception("MGMT_RX_PROCESS failed")
399
400 hapd.set("ext_mgmt_frame_handling", "0")