]>
Commit | Line | Data |
---|---|---|
9f46d57f | 1 | # TDLS tests |
538da4f4 | 2 | # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi> |
81266da7 JM |
3 | # |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
9fd6804d | 7 | from remotehost import remote_compatible |
81266da7 | 8 | import time |
81266da7 | 9 | import logging |
c9aa4308 | 10 | logger = logging.getLogger() |
538da4f4 | 11 | import subprocess |
81266da7 JM |
12 | |
13 | import hwsim_utils | |
b8cd4c54 JM |
14 | from hostapd import HostapdGlobal |
15 | from hostapd import Hostapd | |
e259d186 | 16 | import hostapd |
a1eabc74 | 17 | from utils import HwsimSkip, skip_with_fips |
835a546b | 18 | from wlantest import Wlantest |
d386a9ac | 19 | from test_ap_vht import vht_supported |
b8cd4c54 | 20 | |
4a264a6f | 21 | def start_ap_wpa2_psk(ap): |
e259d186 | 22 | params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678") |
4a264a6f | 23 | return hostapd.add_ap(ap, params) |
0165c4be | 24 | |
a8375c94 | 25 | def connectivity(dev, hapd): |
e492837b | 26 | hwsim_utils.test_connectivity_sta(dev[0], dev[1]) |
a8375c94 JM |
27 | hwsim_utils.test_connectivity(dev[0], hapd) |
28 | hwsim_utils.test_connectivity(dev[1], hapd) | |
e492837b | 29 | |
a8375c94 | 30 | def connect_2sta(dev, ssid, hapd): |
c65f23ab JM |
31 | dev[0].connect(ssid, psk="12345678", scan_freq="2412") |
32 | dev[1].connect(ssid, psk="12345678", scan_freq="2412") | |
f0825655 JM |
33 | hapd.wait_sta() |
34 | hapd.wait_sta() | |
a8375c94 | 35 | connectivity(dev, hapd) |
b61e418c | 36 | |
a8375c94 JM |
37 | def connect_2sta_wpa2_psk(dev, hapd): |
38 | connect_2sta(dev, "test-wpa2-psk", hapd) | |
e492837b | 39 | |
a8375c94 JM |
40 | def connect_2sta_wpa_psk(dev, hapd): |
41 | connect_2sta(dev, "test-wpa-psk", hapd) | |
e492837b | 42 | |
a8375c94 | 43 | def connect_2sta_wpa_psk_mixed(dev, hapd): |
c65f23ab JM |
44 | dev[0].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA", |
45 | scan_freq="2412") | |
46 | dev[1].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA2", | |
47 | scan_freq="2412") | |
f0825655 JM |
48 | hapd.wait_sta() |
49 | hapd.wait_sta() | |
a8375c94 | 50 | connectivity(dev, hapd) |
0165c4be | 51 | |
a8375c94 | 52 | def connect_2sta_wep(dev, hapd): |
c65f23ab JM |
53 | dev[0].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"', |
54 | scan_freq="2412") | |
55 | dev[1].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"', | |
56 | scan_freq="2412") | |
f0825655 JM |
57 | hapd.wait_sta() |
58 | hapd.wait_sta() | |
a8375c94 | 59 | connectivity(dev, hapd) |
0165c4be | 60 | |
8916857d JM |
61 | def connect_2sta_open(dev, hapd, scan_freq="2412"): |
62 | dev[0].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq) | |
63 | dev[1].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq) | |
f0825655 JM |
64 | hapd.wait_sta() |
65 | hapd.wait_sta() | |
a8375c94 | 66 | connectivity(dev, hapd) |
81266da7 | 67 | |
8efc83d4 JA |
68 | def wlantest_setup(hapd): |
69 | Wlantest.setup(hapd) | |
835a546b JM |
70 | wt = Wlantest() |
71 | wt.flush() | |
72 | wt.add_passphrase("12345678") | |
73 | wt.add_wepkey("68656c6c6f") | |
81266da7 | 74 | |
dc4e222c | 75 | def wlantest_tdls_packet_counters(bssid, addr0, addr1): |
835a546b JM |
76 | wt = Wlantest() |
77 | dl = wt.get_tdls_counter("valid_direct_link", bssid, addr0, addr1) | |
78 | inv_dl = wt.get_tdls_counter("invalid_direct_link", bssid, addr0, addr1) | |
79 | ap = wt.get_tdls_counter("valid_ap_path", bssid, addr0, addr1) | |
80 | inv_ap = wt.get_tdls_counter("invalid_ap_path", bssid, addr0, addr1) | |
fab49f61 | 81 | return [dl, inv_dl, ap, inv_ap] |
dc4e222c JM |
82 | |
83 | def tdls_check_dl(sta0, sta1, bssid, addr0, addr1): | |
835a546b JM |
84 | wt = Wlantest() |
85 | wt.tdls_clear(bssid, addr0, addr1) | |
dc4e222c | 86 | hwsim_utils.test_connectivity_sta(sta0, sta1) |
fab49f61 | 87 | [dl, inv_dl, ap, inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1) |
dc4e222c JM |
88 | if dl == 0: |
89 | raise Exception("No valid frames through direct link") | |
90 | if inv_dl > 0: | |
91 | raise Exception("Invalid frames through direct link") | |
92 | if ap > 0: | |
93 | raise Exception("Unexpected frames through AP path") | |
94 | if inv_ap > 0: | |
95 | raise Exception("Invalid frames through AP path") | |
96 | ||
97 | def tdls_check_ap(sta0, sta1, bssid, addr0, addr1): | |
835a546b | 98 | wt = Wlantest() |
bc6e3288 | 99 | wt.tdls_clear(bssid, addr0, addr1) |
dc4e222c | 100 | hwsim_utils.test_connectivity_sta(sta0, sta1) |
fab49f61 | 101 | [dl, inv_dl, ap, inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1) |
dc4e222c JM |
102 | if dl > 0: |
103 | raise Exception("Unexpected frames through direct link") | |
104 | if inv_dl > 0: | |
105 | raise Exception("Invalid frames through direct link") | |
106 | if ap == 0: | |
107 | raise Exception("No valid frames through AP path") | |
108 | if inv_ap > 0: | |
109 | raise Exception("Invalid frames through AP path") | |
110 | ||
a8375c94 | 111 | def check_connectivity(sta0, sta1, hapd): |
9d86f37f | 112 | hwsim_utils.test_connectivity_sta(sta0, sta1) |
a8375c94 JM |
113 | hwsim_utils.test_connectivity(sta0, hapd) |
114 | hwsim_utils.test_connectivity(sta1, hapd) | |
9d86f37f | 115 | |
63e6e62f | 116 | def setup_tdls(sta0, sta1, hapd, reverse=False, expect_fail=False): |
81266da7 | 117 | logger.info("Setup TDLS") |
a8375c94 | 118 | check_connectivity(sta0, sta1, hapd) |
63e6e62f | 119 | bssid = hapd.own_addr() |
81266da7 JM |
120 | addr0 = sta0.p2p_interface_addr() |
121 | addr1 = sta1.p2p_interface_addr() | |
835a546b | 122 | wt = Wlantest() |
bc6e3288 JM |
123 | wt.tdls_clear(bssid, addr0, addr1) |
124 | wt.tdls_clear(bssid, addr1, addr0) | |
81266da7 JM |
125 | sta0.tdls_setup(addr1) |
126 | time.sleep(1) | |
a9bdfd49 JM |
127 | if expect_fail: |
128 | tdls_check_ap(sta0, sta1, bssid, addr0, addr1) | |
129 | return | |
81266da7 JM |
130 | if reverse: |
131 | addr1 = sta0.p2p_interface_addr() | |
132 | addr0 = sta1.p2p_interface_addr() | |
bc6e3288 | 133 | conf = wt.get_tdls_counter("setup_conf_ok", bssid, addr0, addr1) |
81266da7 JM |
134 | if conf == 0: |
135 | raise Exception("No TDLS Setup Confirm (success) seen") | |
dc4e222c | 136 | tdls_check_dl(sta0, sta1, bssid, addr0, addr1) |
a8375c94 | 137 | check_connectivity(sta0, sta1, hapd) |
81266da7 | 138 | |
63e6e62f | 139 | def teardown_tdls(sta0, sta1, hapd, responder=False, wildcard=False): |
81266da7 | 140 | logger.info("Teardown TDLS") |
a8375c94 | 141 | check_connectivity(sta0, sta1, hapd) |
63e6e62f | 142 | bssid = hapd.own_addr() |
81266da7 JM |
143 | addr0 = sta0.p2p_interface_addr() |
144 | addr1 = sta1.p2p_interface_addr() | |
77835ae9 AN |
145 | if responder: |
146 | sta1.tdls_teardown(addr0) | |
7fd5fd03 JM |
147 | elif wildcard: |
148 | sta0.tdls_teardown("*") | |
77835ae9 AN |
149 | else: |
150 | sta0.tdls_teardown(addr1) | |
81266da7 | 151 | time.sleep(1) |
835a546b | 152 | wt = Wlantest() |
bc6e3288 | 153 | teardown = wt.get_tdls_counter("teardown", bssid, addr0, addr1) |
81266da7 JM |
154 | if teardown == 0: |
155 | raise Exception("No TDLS Setup Teardown seen") | |
dc4e222c | 156 | tdls_check_ap(sta0, sta1, bssid, addr0, addr1) |
a8375c94 | 157 | check_connectivity(sta0, sta1, hapd) |
81266da7 | 158 | |
2380d804 OG |
159 | def check_tdls_link(sta0, sta1, connected=True): |
160 | addr0 = sta0.own_addr() | |
161 | addr1 = sta1.own_addr() | |
162 | status0 = sta0.tdls_link_status(addr1).rstrip() | |
163 | status1 = sta1.tdls_link_status(addr0).rstrip() | |
164 | logger.info("%s: %s" % (sta0.ifname, status0)) | |
165 | logger.info("%s: %s" % (sta1.ifname, status1)) | |
166 | if status0 != status1: | |
167 | raise Exception("TDLS link status differs between stations") | |
168 | if "status: connected" in status0: | |
169 | if not connected: | |
170 | raise Exception("Expected TDLS link status NOT to be connected") | |
171 | else: | |
172 | if connected: | |
173 | raise Exception("Expected TDLS link status to be connected") | |
174 | ||
9fd6804d | 175 | @remote_compatible |
77b4a711 JM |
176 | def test_ap_tdls_discovery(dev, apdev): |
177 | """WPA2-PSK AP and two stations using TDLS discovery""" | |
4a264a6f | 178 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 179 | wlantest_setup(hapd) |
a8375c94 | 180 | connect_2sta_wpa2_psk(dev, hapd) |
77b4a711 JM |
181 | dev[0].request("TDLS_DISCOVER " + dev[1].p2p_interface_addr()) |
182 | time.sleep(0.2) | |
183 | ||
ae3ad328 | 184 | def test_ap_wpa2_tdls(dev, apdev): |
81266da7 | 185 | """WPA2-PSK AP and two stations using TDLS""" |
4a264a6f | 186 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 187 | wlantest_setup(hapd) |
a8375c94 | 188 | connect_2sta_wpa2_psk(dev, hapd) |
63e6e62f JD |
189 | setup_tdls(dev[0], dev[1], hapd) |
190 | teardown_tdls(dev[0], dev[1], hapd) | |
191 | setup_tdls(dev[1], dev[0], hapd) | |
192 | #teardown_tdls(dev[0], dev[1], hapd) | |
81266da7 | 193 | |
ae3ad328 | 194 | def test_ap_wpa2_tdls_concurrent_init(dev, apdev): |
81266da7 | 195 | """Concurrent TDLS setup initiation""" |
4a264a6f | 196 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 197 | wlantest_setup(hapd) |
a8375c94 | 198 | connect_2sta_wpa2_psk(dev, hapd) |
81266da7 | 199 | dev[0].request("SET tdls_testing 0x80") |
63e6e62f | 200 | setup_tdls(dev[1], dev[0], hapd, reverse=True) |
81266da7 | 201 | |
ae3ad328 | 202 | def test_ap_wpa2_tdls_concurrent_init2(dev, apdev): |
81266da7 | 203 | """Concurrent TDLS setup initiation (reverse)""" |
4a264a6f | 204 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 205 | wlantest_setup(hapd) |
a8375c94 | 206 | connect_2sta_wpa2_psk(dev, hapd) |
81266da7 | 207 | dev[1].request("SET tdls_testing 0x80") |
63e6e62f | 208 | setup_tdls(dev[0], dev[1], hapd) |
81266da7 | 209 | |
ae3ad328 | 210 | def test_ap_wpa2_tdls_decline_resp(dev, apdev): |
a9bdfd49 | 211 | """Decline TDLS Setup Response""" |
4a264a6f | 212 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 213 | wlantest_setup(hapd) |
a8375c94 | 214 | connect_2sta_wpa2_psk(dev, hapd) |
a9bdfd49 | 215 | dev[1].request("SET tdls_testing 0x200") |
63e6e62f | 216 | setup_tdls(dev[1], dev[0], hapd, expect_fail=True) |
a9bdfd49 | 217 | |
ae3ad328 | 218 | def test_ap_wpa2_tdls_long_lifetime(dev, apdev): |
a9bdfd49 | 219 | """TDLS with long TPK lifetime""" |
4a264a6f | 220 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 221 | wlantest_setup(hapd) |
a8375c94 | 222 | connect_2sta_wpa2_psk(dev, hapd) |
a9bdfd49 | 223 | dev[1].request("SET tdls_testing 0x40") |
63e6e62f | 224 | setup_tdls(dev[1], dev[0], hapd) |
a9bdfd49 | 225 | |
ae3ad328 | 226 | def test_ap_wpa2_tdls_long_frame(dev, apdev): |
a9bdfd49 | 227 | """TDLS with long setup/teardown frames""" |
4a264a6f | 228 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 229 | wlantest_setup(hapd) |
a8375c94 | 230 | connect_2sta_wpa2_psk(dev, hapd) |
a9bdfd49 JM |
231 | dev[0].request("SET tdls_testing 0x1") |
232 | dev[1].request("SET tdls_testing 0x1") | |
63e6e62f JD |
233 | setup_tdls(dev[1], dev[0], hapd) |
234 | teardown_tdls(dev[1], dev[0], hapd) | |
235 | setup_tdls(dev[0], dev[1], hapd) | |
a9bdfd49 | 236 | |
ae3ad328 | 237 | def test_ap_wpa2_tdls_reneg(dev, apdev): |
a9bdfd49 | 238 | """Renegotiate TDLS link""" |
4a264a6f | 239 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 240 | wlantest_setup(hapd) |
a8375c94 | 241 | connect_2sta_wpa2_psk(dev, hapd) |
63e6e62f JD |
242 | setup_tdls(dev[1], dev[0], hapd) |
243 | setup_tdls(dev[0], dev[1], hapd) | |
a9bdfd49 | 244 | |
ae3ad328 | 245 | def test_ap_wpa2_tdls_wrong_lifetime_resp(dev, apdev): |
a9bdfd49 | 246 | """Incorrect TPK lifetime in TDLS Setup Response""" |
4a264a6f | 247 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 248 | wlantest_setup(hapd) |
a8375c94 | 249 | connect_2sta_wpa2_psk(dev, hapd) |
a9bdfd49 | 250 | dev[1].request("SET tdls_testing 0x10") |
63e6e62f | 251 | setup_tdls(dev[0], dev[1], hapd, expect_fail=True) |
a9bdfd49 | 252 | |
ae3ad328 | 253 | def test_ap_wpa2_tdls_diff_rsnie(dev, apdev): |
a9bdfd49 | 254 | """TDLS with different RSN IEs""" |
4a264a6f | 255 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 256 | wlantest_setup(hapd) |
a8375c94 | 257 | connect_2sta_wpa2_psk(dev, hapd) |
a9bdfd49 | 258 | dev[1].request("SET tdls_testing 0x2") |
63e6e62f JD |
259 | setup_tdls(dev[1], dev[0], hapd) |
260 | teardown_tdls(dev[1], dev[0], hapd) | |
a9bdfd49 | 261 | |
67935bc3 JM |
262 | def test_ap_wpa2_tdls_wrong_tpk_m2_mic(dev, apdev): |
263 | """Incorrect MIC in TDLS Setup Response""" | |
4a264a6f | 264 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 265 | wlantest_setup(hapd) |
a8375c94 | 266 | connect_2sta_wpa2_psk(dev, hapd) |
67935bc3 JM |
267 | dev[0].request("SET tdls_testing 0x800") |
268 | addr0 = dev[0].p2p_interface_addr() | |
269 | dev[1].tdls_setup(addr0) | |
270 | time.sleep(1) | |
271 | ||
272 | def test_ap_wpa2_tdls_wrong_tpk_m3_mic(dev, apdev): | |
273 | """Incorrect MIC in TDLS Setup Confirm""" | |
4a264a6f | 274 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 275 | wlantest_setup(hapd) |
a8375c94 | 276 | connect_2sta_wpa2_psk(dev, hapd) |
67935bc3 JM |
277 | dev[1].request("SET tdls_testing 0x800") |
278 | addr0 = dev[0].p2p_interface_addr() | |
279 | dev[1].tdls_setup(addr0) | |
280 | time.sleep(1) | |
281 | ||
951fc8df JM |
282 | def test_ap_wpa2_tdls_double_tpk_m2(dev, apdev): |
283 | """Double TPK M2 during TDLS setup initiation""" | |
284 | hapd = start_ap_wpa2_psk(apdev[0]) | |
285 | wlantest_setup(hapd) | |
286 | connect_2sta_wpa2_psk(dev, hapd) | |
287 | dev[0].request("SET tdls_testing 0x1000") | |
288 | setup_tdls(dev[1], dev[0], hapd) | |
289 | ||
ae3ad328 | 290 | def test_ap_wpa_tdls(dev, apdev): |
e492837b | 291 | """WPA-PSK AP and two stations using TDLS""" |
a1eabc74 | 292 | skip_with_fips(dev[0]) |
8b8a1864 | 293 | hapd = hostapd.add_ap(apdev[0], |
a8375c94 JM |
294 | hostapd.wpa_params(ssid="test-wpa-psk", |
295 | passphrase="12345678")) | |
8efc83d4 | 296 | wlantest_setup(hapd) |
a8375c94 | 297 | connect_2sta_wpa_psk(dev, hapd) |
63e6e62f JD |
298 | setup_tdls(dev[0], dev[1], hapd) |
299 | teardown_tdls(dev[0], dev[1], hapd) | |
300 | setup_tdls(dev[1], dev[0], hapd) | |
e492837b | 301 | |
ae3ad328 | 302 | def test_ap_wpa_mixed_tdls(dev, apdev): |
e492837b | 303 | """WPA+WPA2-PSK AP and two stations using TDLS""" |
a1eabc74 | 304 | skip_with_fips(dev[0]) |
8b8a1864 | 305 | hapd = hostapd.add_ap(apdev[0], |
a8375c94 JM |
306 | hostapd.wpa_mixed_params(ssid="test-wpa-mixed-psk", |
307 | passphrase="12345678")) | |
8efc83d4 | 308 | wlantest_setup(hapd) |
a8375c94 | 309 | connect_2sta_wpa_psk_mixed(dev, hapd) |
63e6e62f JD |
310 | setup_tdls(dev[0], dev[1], hapd) |
311 | teardown_tdls(dev[0], dev[1], hapd) | |
312 | setup_tdls(dev[1], dev[0], hapd) | |
e492837b | 313 | |
ae3ad328 | 314 | def test_ap_wep_tdls(dev, apdev): |
0165c4be | 315 | """WEP AP and two stations using TDLS""" |
8b8a1864 | 316 | hapd = hostapd.add_ap(apdev[0], |
fab49f61 | 317 | {"ssid": "test-wep", "wep_key0": '"hello"'}) |
8efc83d4 | 318 | wlantest_setup(hapd) |
a8375c94 | 319 | connect_2sta_wep(dev, hapd) |
63e6e62f JD |
320 | setup_tdls(dev[0], dev[1], hapd) |
321 | teardown_tdls(dev[0], dev[1], hapd) | |
322 | setup_tdls(dev[1], dev[0], hapd) | |
0165c4be | 323 | |
ae3ad328 | 324 | def test_ap_open_tdls(dev, apdev): |
0165c4be | 325 | """Open AP and two stations using TDLS""" |
fab49f61 | 326 | hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"}) |
8efc83d4 | 327 | wlantest_setup(hapd) |
a8375c94 | 328 | connect_2sta_open(dev, hapd) |
63e6e62f JD |
329 | setup_tdls(dev[0], dev[1], hapd) |
330 | teardown_tdls(dev[0], dev[1], hapd) | |
331 | setup_tdls(dev[1], dev[0], hapd) | |
332 | teardown_tdls(dev[1], dev[0], hapd, wildcard=True) | |
538da4f4 JM |
333 | |
334 | def test_ap_wpa2_tdls_bssid_mismatch(dev, apdev): | |
335 | """TDLS failure due to BSSID mismatch""" | |
336 | try: | |
337 | ssid = "test-wpa2-psk" | |
338 | passphrase = "12345678" | |
339 | params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) | |
340 | params['bridge'] = 'ap-br0' | |
8b8a1864 JD |
341 | hapd = hostapd.add_ap(apdev[0], params) |
342 | hostapd.add_ap(apdev[1], params) | |
8efc83d4 | 343 | wlantest_setup(hapd) |
c4668009 JM |
344 | subprocess.call(['brctl', 'setfd', 'ap-br0', '0']) |
345 | subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up']) | |
538da4f4 JM |
346 | dev[0].connect(ssid, psk=passphrase, scan_freq="2412", |
347 | bssid=apdev[0]['bssid']) | |
348 | dev[1].connect(ssid, psk=passphrase, scan_freq="2412", | |
349 | bssid=apdev[1]['bssid']) | |
a8375c94 | 350 | hwsim_utils.test_connectivity_sta(dev[0], dev[1]) |
1131a1c8 JM |
351 | hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0") |
352 | hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0") | |
a8375c94 | 353 | |
538da4f4 JM |
354 | addr0 = dev[0].p2p_interface_addr() |
355 | dev[1].tdls_setup(addr0) | |
356 | time.sleep(1) | |
357 | hwsim_utils.test_connectivity_sta(dev[0], dev[1]) | |
358 | finally: | |
c4668009 JM |
359 | subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down']) |
360 | subprocess.call(['brctl', 'delbr', 'ap-br0']) | |
77835ae9 AN |
361 | |
362 | def test_ap_wpa2_tdls_responder_teardown(dev, apdev): | |
363 | """TDLS teardown from responder with WPA2-PSK AP""" | |
4a264a6f | 364 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 365 | wlantest_setup(hapd) |
a8375c94 | 366 | connect_2sta_wpa2_psk(dev, hapd) |
63e6e62f JD |
367 | setup_tdls(dev[0], dev[1], hapd) |
368 | teardown_tdls(dev[0], dev[1], hapd, responder=True) | |
8916857d | 369 | |
cd803b6c JM |
370 | def tdls_clear_reg(hapd, dev): |
371 | if hapd: | |
372 | hapd.request("DISABLE") | |
cd803b6c | 373 | dev[1].request("DISCONNECT") |
e01a492c JM |
374 | dev[0].disconnect_and_stop_scan() |
375 | dev[1].disconnect_and_stop_scan() | |
cd803b6c JM |
376 | subprocess.call(['iw', 'reg', 'set', '00']) |
377 | dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) | |
378 | dev[0].flush_scan_cache() | |
379 | dev[1].flush_scan_cache() | |
380 | ||
8916857d JM |
381 | def test_ap_open_tdls_vht(dev, apdev): |
382 | """Open AP and two stations using TDLS""" | |
fab49f61 JM |
383 | params = {"ssid": "test-open", |
384 | "country_code": "DE", | |
385 | "hw_mode": "a", | |
386 | "channel": "36", | |
387 | "ieee80211n": "1", | |
388 | "ieee80211ac": "1", | |
389 | "ht_capab": "", | |
390 | "vht_capab": "", | |
391 | "vht_oper_chwidth": "0", | |
392 | "vht_oper_centr_freq_seg0_idx": "0"} | |
f8b9e61e | 393 | hapd = None |
8916857d | 394 | try: |
8b8a1864 | 395 | hapd = hostapd.add_ap(apdev[0], params) |
8efc83d4 | 396 | wlantest_setup(hapd) |
8916857d | 397 | connect_2sta_open(dev, hapd, scan_freq="5180") |
63e6e62f JD |
398 | setup_tdls(dev[0], dev[1], hapd) |
399 | teardown_tdls(dev[0], dev[1], hapd) | |
400 | setup_tdls(dev[1], dev[0], hapd) | |
401 | teardown_tdls(dev[1], dev[0], hapd, wildcard=True) | |
8916857d | 402 | finally: |
cd803b6c | 403 | tdls_clear_reg(hapd, dev) |
5434f07c | 404 | |
d386a9ac JM |
405 | def test_ap_open_tdls_vht80(dev, apdev): |
406 | """Open AP and two stations using TDLS with VHT 80""" | |
fab49f61 JM |
407 | params = {"ssid": "test-open", |
408 | "country_code": "US", | |
409 | "hw_mode": "a", | |
410 | "channel": "36", | |
411 | "ht_capab": "[HT40+]", | |
412 | "ieee80211n": "1", | |
413 | "ieee80211ac": "1", | |
414 | "vht_capab": "", | |
415 | "vht_oper_chwidth": "1", | |
416 | "vht_oper_centr_freq_seg0_idx": "42"} | |
d386a9ac JM |
417 | try: |
418 | hapd = None | |
8b8a1864 | 419 | hapd = hostapd.add_ap(apdev[0], params) |
8efc83d4 | 420 | wlantest_setup(hapd) |
d386a9ac JM |
421 | connect_2sta_open(dev, hapd, scan_freq="5180") |
422 | sig = dev[0].request("SIGNAL_POLL").splitlines() | |
423 | if "WIDTH=80 MHz" not in sig: | |
424 | raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) | |
63e6e62f | 425 | setup_tdls(dev[0], dev[1], hapd) |
d386a9ac JM |
426 | for i in range(10): |
427 | check_connectivity(dev[0], dev[1], hapd) | |
428 | for i in range(2): | |
429 | cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'], | |
430 | stdout=subprocess.PIPE) | |
431 | res = cmd.stdout.read() | |
432 | cmd.stdout.close() | |
32e4ad44 | 433 | logger.info("Station dump on dev[%d]:\n%s" % (i, res.decode())) |
bab493b9 | 434 | except Exception as e: |
d386a9ac JM |
435 | if isinstance(e, Exception) and str(e) == "AP startup failed": |
436 | if not vht_supported(): | |
437 | raise HwsimSkip("80/160 MHz channel not supported in regulatory information") | |
438 | raise | |
439 | finally: | |
cd803b6c | 440 | tdls_clear_reg(hapd, dev) |
d386a9ac JM |
441 | |
442 | def test_ap_open_tdls_vht80plus80(dev, apdev): | |
443 | """Open AP and two stations using TDLS with VHT 80+80""" | |
fab49f61 JM |
444 | params = {"ssid": "test-open", |
445 | "country_code": "US", | |
446 | "hw_mode": "a", | |
447 | "channel": "36", | |
448 | "ht_capab": "[HT40+]", | |
449 | "ieee80211n": "1", | |
450 | "ieee80211ac": "1", | |
451 | "vht_capab": "", | |
452 | "vht_oper_chwidth": "3", | |
453 | "vht_oper_centr_freq_seg0_idx": "42", | |
454 | "vht_oper_centr_freq_seg1_idx": "155"} | |
d386a9ac JM |
455 | try: |
456 | hapd = None | |
8b8a1864 | 457 | hapd = hostapd.add_ap(apdev[0], params) |
8efc83d4 | 458 | wlantest_setup(hapd) |
d386a9ac JM |
459 | connect_2sta_open(dev, hapd, scan_freq="5180") |
460 | sig = dev[0].request("SIGNAL_POLL").splitlines() | |
461 | if "FREQUENCY=5180" not in sig: | |
462 | raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) | |
463 | if "WIDTH=80+80 MHz" not in sig: | |
464 | raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) | |
465 | if "CENTER_FRQ1=5210" not in sig: | |
466 | raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig)) | |
467 | if "CENTER_FRQ2=5775" not in sig: | |
468 | raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig)) | |
63e6e62f | 469 | setup_tdls(dev[0], dev[1], hapd) |
d386a9ac JM |
470 | for i in range(10): |
471 | check_connectivity(dev[0], dev[1], hapd) | |
472 | for i in range(2): | |
473 | cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'], | |
474 | stdout=subprocess.PIPE) | |
475 | res = cmd.stdout.read() | |
476 | cmd.stdout.close() | |
32e4ad44 | 477 | logger.info("Station dump on dev[%d]:\n%s" % (i, res.decode())) |
bab493b9 | 478 | except Exception as e: |
d386a9ac JM |
479 | if isinstance(e, Exception) and str(e) == "AP startup failed": |
480 | if not vht_supported(): | |
481 | raise HwsimSkip("80/160 MHz channel not supported in regulatory information") | |
482 | raise | |
483 | finally: | |
cd803b6c | 484 | tdls_clear_reg(hapd, dev) |
d386a9ac JM |
485 | |
486 | def test_ap_open_tdls_vht160(dev, apdev): | |
487 | """Open AP and two stations using TDLS with VHT 160""" | |
fab49f61 JM |
488 | params = {"ssid": "test-open", |
489 | "country_code": "ZA", | |
490 | "hw_mode": "a", | |
491 | "channel": "104", | |
492 | "ht_capab": "[HT40-]", | |
493 | "ieee80211n": "1", | |
494 | "ieee80211ac": "1", | |
495 | "vht_oper_chwidth": "2", | |
496 | "vht_oper_centr_freq_seg0_idx": "114"} | |
d386a9ac JM |
497 | try: |
498 | hapd = None | |
8b8a1864 | 499 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
d386a9ac JM |
500 | ev = hapd.wait_event(["AP-ENABLED"], timeout=2) |
501 | if not ev: | |
502 | cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE) | |
503 | reg = cmd.stdout.readlines() | |
504 | for r in reg: | |
505 | if "5490" in r and "DFS" in r: | |
506 | raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed") | |
507 | raise Exception("AP setup timed out") | |
8efc83d4 | 508 | wlantest_setup(hapd) |
d386a9ac JM |
509 | connect_2sta_open(dev, hapd, scan_freq="5520") |
510 | sig = dev[0].request("SIGNAL_POLL").splitlines() | |
511 | if "WIDTH=160 MHz" not in sig: | |
512 | raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) | |
63e6e62f | 513 | setup_tdls(dev[0], dev[1], hapd) |
d386a9ac JM |
514 | for i in range(10): |
515 | check_connectivity(dev[0], dev[1], hapd) | |
516 | for i in range(2): | |
517 | cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'], | |
518 | stdout=subprocess.PIPE) | |
519 | res = cmd.stdout.read() | |
520 | cmd.stdout.close() | |
32e4ad44 | 521 | logger.info("Station dump on dev[%d]:\n%s" % (i, res.decode())) |
bab493b9 | 522 | except Exception as e: |
d386a9ac JM |
523 | if isinstance(e, Exception) and str(e) == "AP startup failed": |
524 | if not vht_supported(): | |
525 | raise HwsimSkip("80/160 MHz channel not supported in regulatory information") | |
526 | raise | |
527 | finally: | |
cd803b6c | 528 | tdls_clear_reg(hapd, dev) |
d386a9ac | 529 | |
5434f07c JM |
530 | def test_tdls_chan_switch(dev, apdev): |
531 | """Open AP and two stations using TDLS""" | |
532 | flags = int(dev[0].get_driver_status_field('capa.flags'), 16) | |
533 | if flags & 0x800000000 == 0: | |
81e787b7 | 534 | raise HwsimSkip("Driver does not support TDLS channel switching") |
5434f07c | 535 | |
fab49f61 | 536 | hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"}) |
cbd4e92b | 537 | wlantest_setup(hapd) |
5434f07c | 538 | connect_2sta_open(dev, hapd) |
63e6e62f | 539 | setup_tdls(dev[0], dev[1], hapd) |
5434f07c JM |
540 | if "OK" not in dev[0].request("TDLS_CHAN_SWITCH " + dev[1].own_addr() + " 81 2462"): |
541 | raise Exception("Failed to enable TDLS channel switching") | |
542 | if "OK" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()): | |
543 | raise Exception("Could not disable TDLS channel switching") | |
544 | if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()): | |
545 | raise Exception("TDLS_CANCEL_CHAN_SWITCH accepted even though channel switching was already disabled") | |
f241a260 JM |
546 | if "FAIL" not in dev[0].request("TDLS_CHAN_SWITCH foo 81 2462"): |
547 | raise Exception("Invalid TDLS channel switching command accepted") | |
2380d804 OG |
548 | |
549 | def test_ap_tdls_link_status(dev, apdev): | |
550 | """Check TDLS link status between two stations""" | |
4a264a6f | 551 | hapd = start_ap_wpa2_psk(apdev[0]) |
8efc83d4 | 552 | wlantest_setup(hapd) |
2380d804 OG |
553 | connect_2sta_wpa2_psk(dev, hapd) |
554 | check_tdls_link(dev[0], dev[1], connected=False) | |
63e6e62f | 555 | setup_tdls(dev[0], dev[1], hapd) |
2380d804 | 556 | check_tdls_link(dev[0], dev[1], connected=True) |
63e6e62f | 557 | teardown_tdls(dev[0], dev[1], hapd) |
2380d804 OG |
558 | check_tdls_link(dev[0], dev[1], connected=False) |
559 | if "FAIL" not in dev[0].request("TDLS_LINK_STATUS foo"): | |
560 | raise Exception("Unexpected TDLS_LINK_STATUS response for invalid argument") | |
8618b3c2 JM |
561 | |
562 | def test_ap_tdls_prohibit(dev, apdev): | |
563 | """Open AP and TDLS prohibited""" | |
fab49f61 JM |
564 | hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open", |
565 | "tdls_prohibit": "1"}) | |
8618b3c2 JM |
566 | connect_2sta_open(dev, hapd) |
567 | if "FAIL" not in dev[0].request("TDLS_SETUP " + dev[1].own_addr()): | |
568 | raise Exception("TDLS_SETUP accepted unexpectedly") | |
569 | ||
570 | def test_ap_tdls_chan_switch_prohibit(dev, apdev): | |
571 | """Open AP and TDLS channel switch prohibited""" | |
fab49f61 JM |
572 | hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open", |
573 | "tdls_prohibit_chan_switch": "1"}) | |
8618b3c2 JM |
574 | wlantest_setup(hapd) |
575 | connect_2sta_open(dev, hapd) | |
576 | setup_tdls(dev[0], dev[1], hapd) | |
c1c93833 JM |
577 | |
578 | def test_ap_open_tdls_external_control(dev, apdev): | |
579 | """TDLS and tdls_external_control""" | |
580 | try: | |
581 | _test_ap_open_tdls_external_control(dev, apdev) | |
582 | finally: | |
583 | dev[0].set("tdls_external_control", "0") | |
584 | ||
585 | def _test_ap_open_tdls_external_control(dev, apdev): | |
fab49f61 | 586 | hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"}) |
c1c93833 JM |
587 | dev[0].connect("test-open", key_mgmt="NONE", scan_freq="2412") |
588 | dev[1].connect("test-open", key_mgmt="NONE", scan_freq="2412") | |
589 | addr0 = dev[0].own_addr() | |
590 | addr1 = dev[1].own_addr() | |
591 | ||
592 | dev[0].set("tdls_external_control", "1") | |
593 | if "FAIL" in dev[0].request("TDLS_SETUP " + addr1): | |
594 | # tdls_external_control not supported; try without it | |
595 | dev[0].set("tdls_external_control", "0") | |
596 | if "FAIL" in dev[0].request("TDLS_SETUP " + addr1): | |
597 | raise Exception("TDLS_SETUP failed") | |
598 | connected = False | |
599 | for i in range(50): | |
600 | res0 = dev[0].request("TDLS_LINK_STATUS " + addr1) | |
601 | res1 = dev[1].request("TDLS_LINK_STATUS " + addr0) | |
602 | if "TDLS link status: connected" in res0 and "TDLS link status: connected" in res1: | |
603 | connected = True | |
604 | break | |
605 | time.sleep(0.1) | |
606 | if not connected: | |
607 | raise Exception("TDLS setup did not complete") | |
608 | ||
609 | dev[0].set("tdls_external_control", "1") | |
610 | if "FAIL" in dev[0].request("TDLS_TEARDOWN " + addr1): | |
611 | # tdls_external_control not supported; try without it | |
612 | dev[0].set("tdls_external_control", "0") | |
613 | if "FAIL" in dev[0].request("TDLS_TEARDOWN " + addr1): | |
614 | raise Exception("TDLS_TEARDOWN failed") | |
615 | for i in range(50): | |
616 | res0 = dev[0].request("TDLS_LINK_STATUS " + addr1) | |
617 | res1 = dev[1].request("TDLS_LINK_STATUS " + addr0) | |
618 | if "TDLS link status: connected" not in res0 and "TDLS link status: connected" not in res1: | |
619 | connected = False | |
620 | break | |
621 | time.sleep(0.1) | |
622 | if connected: | |
623 | raise Exception("TDLS teardown did not complete") |