tests: WNM BSS Transition Management request getting rejected
[mech_eap.git] / tests / hwsim / test_wnm.py
index 216066b..ffdbcbe 100644 (file)
@@ -4,6 +4,7 @@
 # This software may be distributed under the terms of the BSD license.
 # See README for more details.
 
+from remotehost import remote_compatible
 import binascii
 import struct
 import time
@@ -12,9 +13,11 @@ logger = logging.getLogger()
 import subprocess
 
 import hostapd
+from wpasupplicant import WpaSupplicant
 from utils import alloc_fail, wait_fail_trigger
 from wlantest import Wlantest
 
+@remote_compatible
 def test_wnm_bss_transition_mgmt(dev, apdev):
     """WNM BSS Transition Management"""
     params = { "ssid": "test-wnm",
@@ -22,11 +25,12 @@ def test_wnm_bss_transition_mgmt(dev, apdev):
                "time_zone": "EST5",
                "wnm_sleep_mode": "1",
                "bss_transition": "1" }
-    hostapd.add_ap(apdev[0]['ifname'], params)
+    hostapd.add_ap(apdev[0], params)
 
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
     dev[0].request("WNM_BSS_QUERY 0")
 
+@remote_compatible
 def test_wnm_disassoc_imminent(dev, apdev):
     """WNM Disassociation Imminent"""
     params = { "ssid": "test-wnm",
@@ -34,8 +38,7 @@ def test_wnm_disassoc_imminent(dev, apdev):
                "time_zone": "EST5",
                "wnm_sleep_mode": "1",
                "bss_transition": "1" }
-    hostapd.add_ap(apdev[0]['ifname'], params)
-    hapd = hostapd.Hostapd(apdev[0]['ifname'])
+    hapd = hostapd.add_ap(apdev[0], params)
 
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
     addr = dev[0].p2p_interface_addr()
@@ -49,6 +52,7 @@ def test_wnm_disassoc_imminent(dev, apdev):
     if ev is None:
         raise Exception("Timeout while waiting for re-connection scan")
 
+@remote_compatible
 def test_wnm_ess_disassoc_imminent(dev, apdev):
     """WNM ESS Disassociation Imminent"""
     params = { "ssid": "test-wnm",
@@ -56,8 +60,7 @@ def test_wnm_ess_disassoc_imminent(dev, apdev):
                "time_zone": "EST5",
                "wnm_sleep_mode": "1",
                "bss_transition": "1" }
-    hostapd.add_ap(apdev[0]['ifname'], params)
-    hapd = hostapd.Hostapd(apdev[0]['ifname'])
+    hapd = hostapd.add_ap(apdev[0], params)
 
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
     addr = dev[0].p2p_interface_addr()
@@ -71,14 +74,34 @@ def test_wnm_ess_disassoc_imminent(dev, apdev):
     if ev is None:
         raise Exception("Timeout while waiting for re-connection scan")
 
+def test_wnm_ess_disassoc_imminent_reject(dev, apdev):
+    """WNM ESS Disassociation Imminent getting rejected"""
+    params = { "ssid": "test-wnm",
+               "bss_transition": "1" }
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
+    addr = dev[0].own_addr()
+    if "OK" not in dev[0].request("SET reject_btm_req_reason 123"):
+        raise Exception("Failed to set reject_btm_req_reason")
+
+    hapd.request("ESS_DISASSOC " + addr + " 1 http://example.com/session-info")
+    ev = hapd.wait_event(["BSS-TM-RESP"], timeout=10)
+    if ev is None:
+        raise Exception("BSS-TM-RESP not seen")
+    if "status_code=123" not in ev:
+        raise Exception("Unexpected response status: " + ev)
+    dev[0].wait_disconnected()
+    dev[0].request("DISCONNECT")
+
+@remote_compatible
 def test_wnm_ess_disassoc_imminent_pmf(dev, apdev):
     """WNM ESS Disassociation Imminent"""
     params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
-    params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
-    params["ieee80211w"] = "2";
+    params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+    params["ieee80211w"] = "2"
     params["bss_transition"] = "1"
-    hostapd.add_ap(apdev[0]['ifname'], params)
-    hapd = hostapd.Hostapd(apdev[0]['ifname'])
+    hapd = hostapd.add_ap(apdev[0], params)
 
     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
@@ -129,6 +152,7 @@ def check_wnm_sleep_mode_enter_exit(hapd, dev, interval=None, tfs_req=None):
     if not ok:
         raise Exception("Station failed to exit WNM-Sleep Mode")
 
+@remote_compatible
 def test_wnm_sleep_mode_open(dev, apdev):
     """WNM Sleep Mode - open"""
     params = { "ssid": "test-wnm",
@@ -136,8 +160,7 @@ def test_wnm_sleep_mode_open(dev, apdev):
                "time_zone": "EST5",
                "wnm_sleep_mode": "1",
                "bss_transition": "1" }
-    hostapd.add_ap(apdev[0]['ifname'], params)
-    hapd = hostapd.Hostapd(apdev[0]['ifname'])
+    hapd = hostapd.add_ap(apdev[0], params)
 
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
     ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
@@ -154,6 +177,7 @@ def test_wnm_sleep_mode_open(dev, apdev):
         if "FAIL" not in dev[0].request("WNM_SLEEP " + cmd):
             raise Exception("Invalid WNM_SLEEP accepted")
 
+@remote_compatible
 def test_wnm_sleep_mode_rsn(dev, apdev):
     """WNM Sleep Mode - RSN"""
     params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
@@ -161,8 +185,7 @@ def test_wnm_sleep_mode_rsn(dev, apdev):
     params["time_zone"] = "EST5"
     params["wnm_sleep_mode"] = "1"
     params["bss_transition"] = "1"
-    hostapd.add_ap(apdev[0]['ifname'], params)
-    hapd = hostapd.Hostapd(apdev[0]['ifname'])
+    hapd = hostapd.add_ap(apdev[0], params)
 
     dev[0].connect("test-wnm-rsn", psk="12345678", scan_freq="2412")
     ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
@@ -170,11 +193,12 @@ def test_wnm_sleep_mode_rsn(dev, apdev):
         raise Exception("No connection event received from hostapd")
     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
 
+@remote_compatible
 def test_wnm_sleep_mode_ap_oom(dev, apdev):
     """WNM Sleep Mode - AP side OOM"""
     params = { "ssid": "test-wnm",
                "wnm_sleep_mode": "1" }
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
 
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
     ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
@@ -187,20 +211,22 @@ def test_wnm_sleep_mode_ap_oom(dev, apdev):
         dev[0].request("WNM_SLEEP exit")
         wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
 
+@remote_compatible
 def test_wnm_sleep_mode_rsn_pmf(dev, apdev):
     """WNM Sleep Mode - RSN with PMF"""
-    wt = Wlantest()
-    wt.flush()
-    wt.add_passphrase("12345678")
     params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
-    params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
-    params["ieee80211w"] = "2";
+    params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+    params["ieee80211w"] = "2"
     params["time_advertisement"] = "2"
     params["time_zone"] = "EST5"
     params["wnm_sleep_mode"] = "1"
     params["bss_transition"] = "1"
-    hostapd.add_ap(apdev[0]['ifname'], params)
-    hapd = hostapd.Hostapd(apdev[0]['ifname'])
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    Wlantest.setup(hapd)
+    wt = Wlantest()
+    wt.flush()
+    wt.add_passphrase("12345678")
 
     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
@@ -283,12 +309,13 @@ def expect_ack(hapd):
     if "ok=1" not in ev:
         raise Exception("Action frame not acknowledged")
 
+@remote_compatible
 def test_wnm_bss_tm_req(dev, apdev):
     """BSS Transition Management Request"""
     params = { "ssid": "test-wnm", "bss_transition": "1" }
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
-    hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+    hapd2 = hostapd.add_ap(apdev[1], params)
 
     hapd.set("ext_mgmt_frame_handling", "1")
 
@@ -430,11 +457,12 @@ def test_wnm_bss_tm_req(dev, apdev):
     hapd.mgmt_tx(req)
     resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
 
+@remote_compatible
 def test_wnm_bss_keep_alive(dev, apdev):
     """WNM keep-alive"""
     params = { "ssid": "test-wnm",
                "ap_max_inactivity": "1" }
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
 
     addr = dev[0].p2p_interface_addr()
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
@@ -473,7 +501,7 @@ def test_wnm_bss_tm(dev, apdev):
                    "hw_mode": "g",
                    "channel": "1",
                    "bss_transition": "1" }
-        hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+        hapd = hostapd.add_ap(apdev[0], params)
 
         id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
         dev[0].set_network(id, "scan_freq", "")
@@ -484,7 +512,7 @@ def test_wnm_bss_tm(dev, apdev):
                    "hw_mode": "a",
                    "channel": "36",
                    "bss_transition": "1" }
-        hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+        hapd2 = hostapd.add_ap(apdev[1], params)
 
         addr = dev[0].p2p_interface_addr()
         dev[0].dump_monitor()
@@ -557,7 +585,7 @@ def test_wnm_bss_tm(dev, apdev):
             raise Exception("Unexpected scan started")
         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
         if ev is not None:
-            raise Exception("Unexpected reassociation");
+            raise Exception("Unexpected reassociation")
     finally:
         dev[0].request("DISCONNECT")
         if hapd:
@@ -569,6 +597,29 @@ def test_wnm_bss_tm(dev, apdev):
 
 def test_wnm_bss_tm_scan_not_needed(dev, apdev):
     """WNM BSS Transition Management and scan not needed"""
+    run_wnm_bss_tm_scan_not_needed(dev, apdev)
+
+def test_wnm_bss_tm_nei_vht(dev, apdev):
+    """WNM BSS Transition Management and VHT neighbor"""
+    run_wnm_bss_tm_scan_not_needed(dev, apdev, vht=True, nei_info="115,36,9")
+
+def test_wnm_bss_tm_nei_11a(dev, apdev):
+    """WNM BSS Transition Management and 11a neighbor"""
+    run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, nei_info="115,36,4")
+
+def test_wnm_bss_tm_nei_11g(dev, apdev):
+    """WNM BSS Transition Management and 11g neighbor"""
+    run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='g',
+                                   channel='2', freq=2417, nei_info="81,2,6")
+
+def test_wnm_bss_tm_nei_11b(dev, apdev):
+    """WNM BSS Transition Management and 11g neighbor"""
+    run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='b',
+                                   channel='3', freq=2422, nei_info="81,2,5")
+
+def run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=True, vht=False, hwmode='a',
+                                   channel='36', freq=5180,
+                                   nei_info="115,36,7,0301ff"):
     try:
         hapd = None
         hapd2 = None
@@ -578,17 +629,24 @@ def test_wnm_bss_tm_scan_not_needed(dev, apdev):
                    "hw_mode": "g",
                    "channel": "1",
                    "bss_transition": "1" }
-        hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+        hapd = hostapd.add_ap(apdev[0], params)
 
         params = { "ssid": "test-wnm",
                    "country_code": "FI",
                    "ieee80211d": "1",
-                   "hw_mode": "a",
-                   "channel": "36",
+                   "hw_mode": hwmode,
+                   "channel": channel,
                    "bss_transition": "1" }
-        hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+        if not ht:
+            params['ieee80211n'] = '0'
+        if vht:
+            params['ieee80211ac'] = "1"
+            params["vht_oper_chwidth"] = "0"
+            params["vht_oper_centr_freq_seg0_idx"] = "0"
 
-        dev[0].scan_for_bss(apdev[1]['bssid'], 5180)
+        hapd2 = hostapd.add_ap(apdev[1], params)
+
+        dev[0].scan_for_bss(apdev[1]['bssid'], freq)
 
         id = dev[0].connect("test-wnm", key_mgmt="NONE",
                             bssid=apdev[0]['bssid'], scan_freq="2412")
@@ -599,7 +657,7 @@ def test_wnm_bss_tm_scan_not_needed(dev, apdev):
         dev[0].dump_monitor()
 
         logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
-        if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
+        if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000," + nei_info):
             raise Exception("BSS_TM_REQ command failed")
         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
         if ev is None:
@@ -635,7 +693,7 @@ def test_wnm_bss_tm_scan_needed(dev, apdev):
                    "hw_mode": "g",
                    "channel": "1",
                    "bss_transition": "1" }
-        hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+        hapd = hostapd.add_ap(apdev[0], params)
 
         params = { "ssid": "test-wnm",
                    "country_code": "FI",
@@ -643,7 +701,7 @@ def test_wnm_bss_tm_scan_needed(dev, apdev):
                    "hw_mode": "a",
                    "channel": "36",
                    "bss_transition": "1" }
-        hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+        hapd2 = hostapd.add_ap(apdev[1], params)
 
         dev[0].scan_for_bss(apdev[1]['bssid'], 5180)
 
@@ -690,7 +748,7 @@ def start_wnm_tm(ap, country, dev):
                "hw_mode": "g",
                "channel": "1",
                "bss_transition": "1" }
-    hapd = hostapd.add_ap(ap['ifname'], params)
+    hapd = hostapd.add_ap(ap, params)
     id = dev.connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
     dev.dump_monitor()
     dev.set_network(id, "scan_freq", "")
@@ -832,7 +890,7 @@ def test_wnm_action_proto(dev, apdev):
     """WNM Action protocol testing"""
     params = { "ssid": "test-wnm" }
     params['wnm_sleep_mode'] = '1'
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
     bssid = apdev[0]['bssid']
     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
     dev[0].request("WNM_SLEEP enter")
@@ -1027,6 +1085,7 @@ def test_wnm_action_proto(dev, apdev):
     hapd.mgmt_tx(msg)
     expect_ack(hapd)
 
+@remote_compatible
 def test_wnm_action_proto_pmf(dev, apdev):
     """WNM Action protocol testing (PMF enabled)"""
     ssid = "test-wnm-pmf"
@@ -1034,7 +1093,7 @@ def test_wnm_action_proto_pmf(dev, apdev):
     params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
     params["ieee80211w"] = "2"
     params['wnm_sleep_mode'] = '1'
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
     bssid = apdev[0]['bssid']
     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256",
                    proto="WPA2", ieee80211w="2", scan_freq="2412")
@@ -1131,12 +1190,13 @@ def test_wnm_action_proto_pmf(dev, apdev):
     hapd.mgmt_tx(msg)
     expect_ack(hapd)
 
+@remote_compatible
 def test_wnm_action_proto_no_pmf(dev, apdev):
     """WNM Action protocol testing (PMF disabled)"""
     ssid = "test-wnm-no-pmf"
     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
     params['wnm_sleep_mode'] = '1'
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
     bssid = apdev[0]['bssid']
     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
                    proto="WPA2", ieee80211w="0", scan_freq="2412")
@@ -1176,68 +1236,69 @@ def test_wnm_bss_tm_req_with_mbo_ie(dev, apdev):
     """WNM BSS transition request with MBO IE and reassociation delay attribute"""
     ssid = "test-wnm-mbo"
     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
     bssid = apdev[0]['bssid']
     if "OK" not in dev[0].request("SET mbo_cell_capa 1"):
-       raise Exception("Failed to set STA as cellular data capable")
+        raise Exception("Failed to set STA as cellular data capable")
 
     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
                    proto="WPA2", ieee80211w="0", scan_freq="2412")
 
     logger.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
     if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=3:2:1"):
-       raise Exception("BSS transition management succeeded unexpectedly")
+        raise Exception("BSS transition management succeeded unexpectedly")
 
     logger.debug("BTM request with invalid MBO transition reason code")
     if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=10:2:1"):
-       raise Exception("BSS transition management succeeded unexpectedly")
+        raise Exception("BSS transition management succeeded unexpectedly")
 
     logger.debug("BTM request with MBO reassociation retry delay of 5 seconds")
     if 'OK' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
-       raise Exception("BSS transition management command failed")
+        raise Exception("BSS transition management command failed")
 
     ev = dev[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
     if ev is None or "preference=1" not in ev:
-       raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
+        raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
 
     ev = dev[0].wait_event(['MBO-TRANSITION-REASON'], 1)
     if ev is None or "reason=3" not in ev:
-       raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
+        raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
 
     ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
     if ev is None:
-       raise Exception("No BSS Transition Management Response")
+        raise Exception("No BSS Transition Management Response")
     if dev[0].own_addr() not in ev:
-       raise Exception("Unexpected BSS Transition Management Response address")
+        raise Exception("Unexpected BSS Transition Management Response address")
 
     ev = dev[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
     if ev is None:
-           raise Exception("Station did not disconnect although disassoc imminent was set")
+        raise Exception("Station did not disconnect although disassoc imminent was set")
 
     # Set the scan interval to make dev[0] look for connections
     if 'OK' not in dev[0].request("SCAN_INTERVAL 1"):
-           raise Exception("Failed to set scan interval")
+        raise Exception("Failed to set scan interval")
 
     # Make sure no connection is made during the retry delay
     ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
     if ev is not None:
-           raise Exception("Station connected before assoc retry delay was over")
+        raise Exception("Station connected before assoc retry delay was over")
 
     # After the assoc retry delay is over, we can reconnect
     ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
     if ev is None:
-           raise Exception("Station did not connect after assoc retry delay is over")
+        raise Exception("Station did not connect after assoc retry delay is over")
 
     if "OK" not in dev[0].request("SET mbo_cell_capa 3"):
-       raise Exception("Failed to set STA as cellular data not-capable")
+        raise Exception("Failed to set STA as cellular data not-capable")
 
+@remote_compatible
 def test_wnm_bss_transition_mgmt_query(dev, apdev):
     """WNM BSS Transition Management query"""
     params = { "ssid": "test-wnm",
                "bss_transition": "1" }
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
     params = { "ssid": "another" }
-    hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+    hapd2 = hostapd.add_ap(apdev[1], params)
 
     dev[0].scan_for_bss(apdev[1]['bssid'], 2412)
     dev[0].scan_for_bss(apdev[0]['bssid'], 2412)
@@ -1254,6 +1315,7 @@ def test_wnm_bss_transition_mgmt_query(dev, apdev):
     if ev is None:
         raise Exception("No BSS Transition Management Response frame seen")
 
+@remote_compatible
 def test_wnm_bss_tm_security_mismatch(dev, apdev):
     """WNM BSS Transition Management and security mismatch"""
     params = { "ssid": "test-wnm",
@@ -1264,13 +1326,13 @@ def test_wnm_bss_tm_security_mismatch(dev, apdev):
                "hw_mode": "g",
                "channel": "1",
                "bss_transition": "1" }
-    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0], params)
 
     params = { "ssid": "test-wnm",
                "hw_mode": "g",
                "channel": "11",
                "bss_transition": "1" }
-    hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
+    hapd2 = hostapd.add_ap(apdev[1], params)
 
     dev[0].scan_for_bss(apdev[1]['bssid'], 2462)
 
@@ -1290,3 +1352,91 @@ def test_wnm_bss_tm_security_mismatch(dev, apdev):
         raise Exception("No BSS Transition Management Response")
     if "status_code=7" not in ev:
         raise Exception("Unexpected BSS transition request response: " + ev)
+
+def test_wnm_bss_tm_connect_cmd(dev, apdev):
+    """WNM BSS Transition Management and cfg80211 connect command"""
+    params = { "ssid": "test-wnm",
+               "hw_mode": "g",
+               "channel": "1",
+               "bss_transition": "1" }
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    params = { "ssid": "test-wnm",
+               "hw_mode": "g",
+               "channel": "11",
+               "bss_transition": "1" }
+    hapd2 = hostapd.add_ap(apdev[1], params)
+
+    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
+
+    wpas.scan_for_bss(apdev[1]['bssid'], 2462)
+
+    id = wpas.connect("test-wnm", key_mgmt="NONE",
+                      bssid=apdev[0]['bssid'], scan_freq="2412")
+    wpas.set_network(id, "scan_freq", "")
+    wpas.set_network(id, "bssid", "")
+
+    addr = wpas.own_addr()
+    wpas.dump_monitor()
+
+    logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
+    if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
+        raise Exception("BSS_TM_REQ command failed")
+    ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
+    if ev is None:
+        raise Exception("No BSS Transition Management Response")
+    if "status_code=0" not in ev:
+        raise Exception("BSS transition request was not accepted: " + ev)
+    if "target_bssid=" + apdev[1]['bssid'] not in ev:
+        raise Exception("Unexpected target BSS: " + ev)
+    ev = wpas.wait_event(["CTRL-EVENT-CONNECTED",
+                          "CTRL-EVENT-DISCONNECTED"], timeout=10)
+    if ev is None:
+        raise Exception("No reassociation seen")
+    if "CTRL-EVENT-DISCONNECTED" in ev:
+        #TODO: Uncomment this once kernel side changes for Connect command
+        #reassociation are in upstream.
+        #raise Exception("Unexpected disconnection reported")
+        logger.info("Unexpected disconnection reported")
+        ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
+        if ev is None:
+            raise Exception("No reassociation seen")
+    if apdev[1]['bssid'] not in ev:
+        raise Exception("Unexpected reassociation target: " + ev)
+
+def test_wnm_bss_tm_reject(dev, apdev):
+    """WNM BSS Transition Management request getting rejected"""
+    try:
+        hapd = None
+        params = { "ssid": "test-wnm",
+                   "country_code": "FI",
+                   "ieee80211d": "1",
+                   "hw_mode": "g",
+                   "channel": "1",
+                   "bss_transition": "1" }
+        hapd = hostapd.add_ap(apdev[0], params)
+
+        id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
+        addr = dev[0].own_addr()
+        dev[0].dump_monitor()
+
+        if "OK" not in dev[0].request("SET reject_btm_req_reason 123"):
+            raise Exception("Failed to set reject_btm_req_reason")
+
+        if "OK" not in hapd.request("BSS_TM_REQ " + addr + " disassoc_timer=1"):
+            raise Exception("BSS_TM_REQ command failed")
+        ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
+        if ev is None:
+            raise Exception("No BSS Transition Management Response")
+        if addr not in ev:
+            raise Exception("Unexpected BSS Transition Management Response address")
+        if "status_code=123" not in ev:
+            raise Exception("Unexpected BSS Transition Management Response status: " + ev)
+        dev[0].wait_disconnected()
+    finally:
+        dev[0].request("DISCONNECT")
+        if hapd:
+            hapd.request("DISABLE")
+        subprocess.call(['iw', 'reg', 'set', '00'])
+        dev[0].flush_scan_cache()