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    check_connectivity(dev[0], dev[1], hapd)
26
27def connect_2sta(dev, ssid, hapd, sae=False):
28    key_mgmt = "SAE" if sae else "WPA-PSK"
29    ieee80211w = "2" if sae else "1"
30    dev[0].connect(ssid, key_mgmt=key_mgmt, psk="12345678",
31                   ieee80211w=ieee80211w, scan_freq="2412")
32    dev[1].connect(ssid, key_mgmt=key_mgmt, psk="12345678",
33                   ieee80211w=ieee80211w, scan_freq="2412")
34    hapd.wait_sta()
35    hapd.wait_sta()
36    connectivity(dev, hapd)
37
38def connect_2sta_wpa2_psk(dev, hapd):
39    connect_2sta(dev, "test-wpa2-psk", hapd)
40
41def connect_2sta_wpa_psk(dev, hapd):
42    connect_2sta(dev, "test-wpa-psk", hapd)
43
44def connect_2sta_wpa_psk_mixed(dev, hapd):
45    dev[0].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA",
46                   scan_freq="2412")
47    dev[1].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA2",
48                   scan_freq="2412")
49    hapd.wait_sta()
50    hapd.wait_sta()
51    connectivity(dev, hapd)
52
53def connect_2sta_wep(dev, hapd):
54    dev[0].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
55                   scan_freq="2412")
56    dev[1].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
57                   scan_freq="2412")
58    hapd.wait_sta()
59    hapd.wait_sta()
60    connectivity(dev, hapd)
61
62def connect_2sta_open(dev, hapd, scan_freq="2412"):
63    dev[0].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
64    dev[1].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
65    hapd.wait_sta()
66    hapd.wait_sta()
67    connectivity(dev, hapd)
68
69def wlantest_setup(hapd):
70    Wlantest.setup(hapd)
71    wt = Wlantest()
72    wt.flush()
73    wt.add_passphrase("12345678")
74    wt.add_wepkey("68656c6c6f")
75
76def wlantest_tdls_packet_counters(bssid, addr0, addr1):
77    wt = Wlantest()
78    dl = wt.get_tdls_counter("valid_direct_link", bssid, addr0, addr1)
79    inv_dl = wt.get_tdls_counter("invalid_direct_link", bssid, addr0, addr1)
80    ap = wt.get_tdls_counter("valid_ap_path", bssid, addr0, addr1)
81    inv_ap = wt.get_tdls_counter("invalid_ap_path", bssid, addr0, addr1)
82    return [dl, inv_dl, ap, inv_ap]
83
84def tdls_check_dl(sta0, sta1, bssid, addr0, addr1):
85    wt = Wlantest()
86    wt.tdls_clear(bssid, addr0, addr1)
87    hwsim_utils.test_connectivity_sta(sta0, sta1)
88    [dl, inv_dl, ap, inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
89    if dl == 0:
90        raise Exception("No valid frames through direct link")
91    if inv_dl > 0:
92        raise Exception("Invalid frames through direct link")
93    if ap > 0:
94        raise Exception("Unexpected frames through AP path")
95    if inv_ap > 0:
96        raise Exception("Invalid frames through AP path")
97
98def tdls_check_ap(sta0, sta1, bssid, addr0, addr1):
99    wt = Wlantest()
100    wt.tdls_clear(bssid, addr0, addr1)
101    hwsim_utils.test_connectivity_sta(sta0, sta1)
102    [dl, inv_dl, ap, inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
103    if dl > 0:
104        raise Exception("Unexpected frames through direct link")
105    if inv_dl > 0:
106        raise Exception("Invalid frames through direct link")
107    if ap == 0:
108        raise Exception("No valid frames through AP path")
109    if inv_ap > 0:
110        raise Exception("Invalid frames through AP path")
111
112def check_connectivity(sta0, sta1, hapd):
113    # give a bit of time for all sides to mark kernel STAs authorized
114    time.sleep(0.1)
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        # give a bit of time for all sides to mark kernel STAs authorized
362        time.sleep(0.1)
363        hwsim_utils.test_connectivity_sta(dev[0], dev[1])
364        hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
365        hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0")
366
367        addr0 = dev[0].p2p_interface_addr()
368        dev[1].tdls_setup(addr0)
369        time.sleep(1)
370        hwsim_utils.test_connectivity_sta(dev[0], dev[1])
371    finally:
372        subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
373        subprocess.call(['brctl', 'delbr', 'ap-br0'])
374
375def test_ap_wpa2_tdls_responder_teardown(dev, apdev):
376    """TDLS teardown from responder with WPA2-PSK AP"""
377    hapd = start_ap_wpa2_psk(apdev[0])
378    wlantest_setup(hapd)
379    connect_2sta_wpa2_psk(dev, hapd)
380    setup_tdls(dev[0], dev[1], hapd)
381    teardown_tdls(dev[0], dev[1], hapd, responder=True)
382
383def tdls_clear_reg(hapd, dev):
384    if hapd:
385        hapd.request("DISABLE")
386    dev[1].request("DISCONNECT")
387    dev[0].disconnect_and_stop_scan()
388    dev[1].disconnect_and_stop_scan()
389    subprocess.call(['iw', 'reg', 'set', '00'])
390    dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
391    dev[0].flush_scan_cache()
392    dev[1].flush_scan_cache()
393
394def test_ap_open_tdls_vht(dev, apdev):
395    """Open AP and two stations using TDLS"""
396    params = {"ssid": "test-open",
397              "country_code": "DE",
398              "hw_mode": "a",
399              "channel": "36",
400              "ieee80211n": "1",
401              "ieee80211ac": "1",
402              "ht_capab": "",
403              "vht_capab": "",
404              "vht_oper_chwidth": "0",
405              "vht_oper_centr_freq_seg0_idx": "0"}
406    hapd = None
407    try:
408        hapd = hostapd.add_ap(apdev[0], params)
409        wlantest_setup(hapd)
410        connect_2sta_open(dev, hapd, scan_freq="5180")
411        setup_tdls(dev[0], dev[1], hapd)
412        teardown_tdls(dev[0], dev[1], hapd)
413        setup_tdls(dev[1], dev[0], hapd)
414        teardown_tdls(dev[1], dev[0], hapd, wildcard=True)
415    finally:
416        tdls_clear_reg(hapd, dev)
417
418def test_ap_open_tdls_vht80(dev, apdev):
419    """Open AP and two stations using TDLS with VHT 80"""
420    clear_scan_cache(apdev[0])
421    params = {"ssid": "test-open",
422              "country_code": "US",
423              "hw_mode": "a",
424              "channel": "36",
425              "ht_capab": "[HT40+]",
426              "vht_capab": "[VHT160]",
427              "ieee80211n": "1",
428              "ieee80211ac": "1",
429              "vht_capab": "",
430              "vht_oper_chwidth": "1",
431              "vht_oper_centr_freq_seg0_idx": "42"}
432    try:
433        hapd = None
434        hapd = hostapd.add_ap(apdev[0], params)
435        wlantest_setup(hapd)
436        connect_2sta_open(dev, hapd, scan_freq="5180")
437        sig = dev[0].request("SIGNAL_POLL").splitlines()
438        if "WIDTH=80 MHz" not in sig:
439            raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
440        setup_tdls(dev[0], dev[1], hapd)
441        for i in range(10):
442            check_connectivity(dev[0], dev[1], hapd)
443        for i in range(2):
444            cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
445                                   stdout=subprocess.PIPE)
446            res = cmd.stdout.read()
447            cmd.stdout.close()
448            logger.info("Station dump on dev[%d]:\n%s" % (i, res.decode()))
449    except Exception as e:
450        if isinstance(e, Exception) and str(e) == "AP startup failed":
451            if not vht_supported():
452                raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
453        raise
454    finally:
455        tdls_clear_reg(hapd, dev)
456
457def test_ap_open_tdls_vht80plus80(dev, apdev):
458    """Open AP and two stations using TDLS with VHT 80+80"""
459    clear_scan_cache(apdev[0])
460    params = {"ssid": "test-open",
461              "country_code": "US",
462              "hw_mode": "a",
463              "channel": "36",
464              "ht_capab": "[HT40+]",
465              "ieee80211n": "1",
466              "ieee80211ac": "1",
467              "vht_capab": "[VHT160-80PLUS80]",
468              "vht_oper_chwidth": "3",
469              "vht_oper_centr_freq_seg0_idx": "42",
470              "vht_oper_centr_freq_seg1_idx": "155"}
471    try:
472        hapd = None
473        hapd = hostapd.add_ap(apdev[0], params)
474        wlantest_setup(hapd)
475        connect_2sta_open(dev, hapd, scan_freq="5180")
476        sig = dev[0].request("SIGNAL_POLL").splitlines()
477        if "FREQUENCY=5180" not in sig:
478            raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
479        if "WIDTH=80+80 MHz" not in sig:
480            raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
481        if "CENTER_FRQ1=5210" not in sig:
482            raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
483        if "CENTER_FRQ2=5775" not in sig:
484            raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
485        setup_tdls(dev[0], dev[1], hapd)
486        for i in range(10):
487            check_connectivity(dev[0], dev[1], hapd)
488        for i in range(2):
489            cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
490                                   stdout=subprocess.PIPE)
491            res = cmd.stdout.read()
492            cmd.stdout.close()
493            logger.info("Station dump on dev[%d]:\n%s" % (i, res.decode()))
494    except Exception as e:
495        if isinstance(e, Exception) and str(e) == "AP startup failed":
496            if not vht_supported():
497                raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
498        raise
499    finally:
500        tdls_clear_reg(hapd, dev)
501
502def test_ap_open_tdls_vht160(dev, apdev):
503    """Open AP and two stations using TDLS with VHT 160"""
504    params = {"ssid": "test-open",
505              "country_code": "ZA",
506              "hw_mode": "a",
507              "channel": "104",
508              "ht_capab": "[HT40-]",
509              "vht_capab": "[VHT160]",
510              "ieee80211n": "1",
511              "ieee80211ac": "1",
512              "vht_oper_chwidth": "2",
513              "vht_oper_centr_freq_seg0_idx": "114"}
514    try:
515        hapd = None
516        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
517        ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
518        if not ev:
519            cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
520            reg = cmd.stdout.readlines()
521            for r in reg:
522                if "5490" in r and "DFS" in r:
523                    raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
524            raise Exception("AP setup timed out")
525        wlantest_setup(hapd)
526        connect_2sta_open(dev, hapd, scan_freq="5520")
527        sig = dev[0].request("SIGNAL_POLL").splitlines()
528        if "WIDTH=160 MHz" not in sig:
529            raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
530        setup_tdls(dev[0], dev[1], hapd)
531        for i in range(10):
532            check_connectivity(dev[0], dev[1], hapd)
533        for i in range(2):
534            cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
535                                   stdout=subprocess.PIPE)
536            res = cmd.stdout.read()
537            cmd.stdout.close()
538            logger.info("Station dump on dev[%d]:\n%s" % (i, res.decode()))
539    except Exception as e:
540        if isinstance(e, Exception) and str(e) == "AP startup failed":
541            if not vht_supported():
542                raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
543        raise
544    finally:
545        tdls_clear_reg(hapd, dev)
546
547def test_tdls_chan_switch(dev, apdev):
548    """Open AP and two stations using TDLS"""
549    flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
550    if flags & 0x800000000 == 0:
551        raise HwsimSkip("Driver does not support TDLS channel switching")
552
553    hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
554    wlantest_setup(hapd)
555    connect_2sta_open(dev, hapd)
556    setup_tdls(dev[0], dev[1], hapd)
557    if "OK" not in dev[0].request("TDLS_CHAN_SWITCH " + dev[1].own_addr() + " 81 2462"):
558        raise Exception("Failed to enable TDLS channel switching")
559    if "OK" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
560        raise Exception("Could not disable TDLS channel switching")
561    if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
562        raise Exception("TDLS_CANCEL_CHAN_SWITCH accepted even though channel switching was already disabled")
563    if "FAIL" not in dev[0].request("TDLS_CHAN_SWITCH foo 81 2462"):
564        raise Exception("Invalid TDLS channel switching command accepted")
565
566def test_ap_tdls_link_status(dev, apdev):
567    """Check TDLS link status between two stations"""
568    hapd = start_ap_wpa2_psk(apdev[0])
569    wlantest_setup(hapd)
570    connect_2sta_wpa2_psk(dev, hapd)
571    check_tdls_link(dev[0], dev[1], connected=False)
572    setup_tdls(dev[0], dev[1], hapd)
573    check_tdls_link(dev[0], dev[1], connected=True)
574    teardown_tdls(dev[0], dev[1], hapd)
575    check_tdls_link(dev[0], dev[1], connected=False)
576    if "FAIL" not in dev[0].request("TDLS_LINK_STATUS foo"):
577        raise Exception("Unexpected TDLS_LINK_STATUS response for invalid argument")
578
579def test_ap_tdls_prohibit(dev, apdev):
580    """Open AP and TDLS prohibited"""
581    hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open",
582                                     "tdls_prohibit": "1"})
583    connect_2sta_open(dev, hapd)
584    if "FAIL" not in dev[0].request("TDLS_SETUP " + dev[1].own_addr()):
585        raise Exception("TDLS_SETUP accepted unexpectedly")
586
587def test_ap_tdls_chan_switch_prohibit(dev, apdev):
588    """Open AP and TDLS channel switch prohibited"""
589    hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open",
590                                     "tdls_prohibit_chan_switch": "1"})
591    wlantest_setup(hapd)
592    connect_2sta_open(dev, hapd)
593    setup_tdls(dev[0], dev[1], hapd)
594
595def test_ap_open_tdls_external_control(dev, apdev):
596    """TDLS and tdls_external_control"""
597    try:
598        _test_ap_open_tdls_external_control(dev, apdev)
599    finally:
600        dev[0].set("tdls_external_control", "0")
601
602def _test_ap_open_tdls_external_control(dev, apdev):
603    hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
604    dev[0].connect("test-open", key_mgmt="NONE", scan_freq="2412")
605    dev[1].connect("test-open", key_mgmt="NONE", scan_freq="2412")
606    addr0 = dev[0].own_addr()
607    addr1 = dev[1].own_addr()
608
609    dev[0].set("tdls_external_control", "1")
610    if "FAIL" in dev[0].request("TDLS_SETUP " + 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_SETUP " + addr1):
614            raise Exception("TDLS_SETUP failed")
615    connected = False
616    for i in range(50):
617        res0 = dev[0].request("TDLS_LINK_STATUS " + addr1)
618        res1 = dev[1].request("TDLS_LINK_STATUS " + addr0)
619        if "TDLS link status: connected" in res0 and "TDLS link status: connected" in res1:
620            connected = True
621            break
622        time.sleep(0.1)
623    if not connected:
624        raise Exception("TDLS setup did not complete")
625
626    dev[0].set("tdls_external_control", "1")
627    if "FAIL" in dev[0].request("TDLS_TEARDOWN " + addr1):
628        # tdls_external_control not supported; try without it
629        dev[0].set("tdls_external_control", "0")
630        if "FAIL" in dev[0].request("TDLS_TEARDOWN " + addr1):
631            raise Exception("TDLS_TEARDOWN failed")
632    for i in range(50):
633        res0 = dev[0].request("TDLS_LINK_STATUS " + addr1)
634        res1 = dev[1].request("TDLS_LINK_STATUS " + addr0)
635        if "TDLS link status: connected" not in res0 and "TDLS link status: connected" not in res1:
636            connected = False
637            break
638        time.sleep(0.1)
639    if connected:
640        raise Exception("TDLS teardown did not complete")
641
642def test_ap_sae_tdls(dev, apdev):
643    """SAE AP and two stations using TDLS"""
644    check_sae_capab(dev[0])
645    check_sae_capab(dev[1])
646    dev[0].request("SET sae_groups ")
647    dev[1].request("SET sae_groups ")
648    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
649    params['wpa_key_mgmt'] = 'SAE'
650    params["ieee80211w"] = "2"
651    hapd = hostapd.add_ap(apdev[0], params)
652    wlantest_setup(hapd)
653    connect_2sta(dev, "test-wpa2-psk", hapd, sae=True)
654    setup_tdls(dev[0], dev[1], hapd, sae=True)
655    teardown_tdls(dev[0], dev[1], hapd, sae=True)
656    setup_tdls(dev[1], dev[0], hapd, sae=True)
657