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