diff --git a/tests/hwsim/hwsim_utils.py b/tests/hwsim/hwsim_utils.py index ab2f767d0..85f54a2ec 100644 --- a/tests/hwsim/hwsim_utils.py +++ b/tests/hwsim/hwsim_utils.py @@ -150,3 +150,11 @@ def test_connectivity_p2p_sta(dev1, dev2, dscp=None, tos=None): def test_connectivity_sta(dev1, dev2, dscp=None, tos=None): test_connectivity(dev1, dev2, dscp, tos) + +(PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL) = range(4) + +def set_powersave(dev, val): + phy = dev.get_driver_status_field("phyname") + psf = open('/sys/kernel/debug/ieee80211/%s/hwsim/ps' % phy, 'w') + psf.write('%d\n' % val) + psf.close() diff --git a/tests/hwsim/test_ap_open.py b/tests/hwsim/test_ap_open.py index bc328fb9a..ebada4c3b 100644 --- a/tests/hwsim/test_ap_open.py +++ b/tests/hwsim/test_ap_open.py @@ -9,9 +9,11 @@ logger = logging.getLogger() import struct import subprocess import time +import os import hostapd import hwsim_utils +from tshark import run_tshark from utils import alloc_fail from wpasupplicant import WpaSupplicant @@ -346,3 +348,45 @@ def test_ap_open_ifdown(dev, apdev): raise Exception("No INTERFACE-ENABLED event") dev[0].wait_connected() hwsim_utils.test_connectivity(dev[0], hapd) + +def test_ap_open_disconnect_in_ps(dev, apdev, params): + """Disconnect with the client in PS to regression-test a kernel bug""" + hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" }) + dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", + bg_scan_period="0") + ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5) + if ev is None: + raise Exception("No connection event received from hostapd") + + time.sleep(0.2) + hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_MANUAL_POLL) + try: + # inject some traffic + sa = hapd.own_addr() + da = dev[0].own_addr() + hapd.request('DATA_TEST_CONFIG 1') + hapd.request('DATA_TEST_TX {} {} 0'.format(da, sa)) + hapd.request('DATA_TEST_CONFIG 0') + + # let the AP send couple of Beacon frames + time.sleep(0.3) + + # disconnect - with traffic pending - shouldn't cause kernel warnings + dev[0].request("DISCONNECT") + finally: + hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_DISABLED) + + time.sleep(0.2) + out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"), + "wlan_mgt.tim.partial_virtual_bitmap", + ["wlan_mgt.tim.partial_virtual_bitmap"]) + if out is not None: + state = 0 + for l in out.splitlines(): + pvb = int(l, 16) + if pvb > 0 and state == 0: + state = 1 + elif pvb == 0 and state == 1: + state = 2 + if state != 2: + raise Exception("Didn't observe TIM bit getting set and unset (state=%d)" % state)