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