# wpa_supplicant D-Bus interface tests
# Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.

import binascii
import logging
logger = logging.getLogger()
import subprocess
import time

try:
    import gobject
    import dbus
    dbus_imported = True
except ImportError:
    dbus_imported = False

import hostapd
from wpasupplicant import WpaSupplicant
from utils import HwsimSkip, alloc_fail, fail_test
from test_ap_tdls import connect_2sta_open

WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1"
WPAS_DBUS_PATH = "/fi/w1/wpa_supplicant1"
WPAS_DBUS_IFACE = "fi.w1.wpa_supplicant1.Interface"
WPAS_DBUS_IFACE_WPS = WPAS_DBUS_IFACE + ".WPS"
WPAS_DBUS_NETWORK = "fi.w1.wpa_supplicant1.Network"
WPAS_DBUS_BSS = "fi.w1.wpa_supplicant1.BSS"
WPAS_DBUS_IFACE_P2PDEVICE = WPAS_DBUS_IFACE + ".P2PDevice"
WPAS_DBUS_P2P_PEER = "fi.w1.wpa_supplicant1.Peer"
WPAS_DBUS_GROUP = "fi.w1.wpa_supplicant1.Group"
WPAS_DBUS_PERSISTENT_GROUP = "fi.w1.wpa_supplicant1.PersistentGroup"

def prepare_dbus(dev):
    if not dbus_imported:
        logger.info("No dbus module available")
        raise HwsimSkip("No dbus module available")
    try:
        from dbus.mainloop.glib import DBusGMainLoop
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        bus = dbus.SystemBus()
        wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH)
        wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE)
        path = wpas.GetInterface(dev.ifname)
        if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
        return (bus,wpas_obj,path,if_obj)
    except Exception, e:
        raise HwsimSkip("Could not connect to D-Bus: %s" % e)

class TestDbus(object):
    def __init__(self, bus):
        self.loop = gobject.MainLoop()
        self.signals = []
        self.bus = bus

    def __exit__(self, type, value, traceback):
        for s in self.signals:
            s.remove()

    def add_signal(self, handler, interface, name, byte_arrays=False):
        s = self.bus.add_signal_receiver(handler, dbus_interface=interface,
                                         signal_name=name,
                                         byte_arrays=byte_arrays)
        self.signals.append(s)

    def timeout(self, *args):
        logger.debug("timeout")
        self.loop.quit()
        return False

class alloc_fail_dbus(object):
    def __init__(self, dev, count, funcs, operation="Operation",
                 expected="NoMemory"):
        self._dev = dev
        self._count = count
        self._funcs = funcs
        self._operation = operation
        self._expected = expected
    def __enter__(self):
        cmd = "TEST_ALLOC_FAIL %d:%s" % (self._count, self._funcs)
        if "OK" not in self._dev.request(cmd):
            raise HwsimSkip("TEST_ALLOC_FAIL not supported")
    def __exit__(self, type, value, traceback):
        if type is None:
            raise Exception("%s succeeded during out-of-memory" % self._operation)
        if type == dbus.exceptions.DBusException and self._expected in str(value):
            return True
        if self._dev.request("GET_ALLOC_FAIL") != "0:%s" % self._funcs:
            raise Exception("%s did not trigger allocation failure" % self._operation)
        return False

def start_ap(ap, ssid="test-wps",
             ap_uuid="27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"):
    params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
               "wpa_passphrase": "12345678", "wpa": "2",
               "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
               "ap_pin": "12345670", "uuid": ap_uuid}
    return hostapd.add_ap(ap['ifname'], params)

def test_dbus_getall(dev, apdev):
    """D-Bus GetAll"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    props = wpas_obj.GetAll(WPAS_DBUS_SERVICE,
                            dbus_interface=dbus.PROPERTIES_IFACE)
    logger.debug("GetAll(fi.w1.wpa.supplicant1, /fi/w1/wpa_supplicant1) ==> " + str(props))

    props = if_obj.GetAll(WPAS_DBUS_IFACE,
                          dbus_interface=dbus.PROPERTIES_IFACE)
    logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_IFACE, path, str(props)))

    props = if_obj.GetAll(WPAS_DBUS_IFACE_WPS,
                          dbus_interface=dbus.PROPERTIES_IFACE)
    logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_IFACE_WPS, path, str(props)))

    res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 0:
        raise Exception("Unexpected BSSs entry: " + str(res))

    res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks',
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 0:
        raise Exception("Unexpected Networks entry: " + str(res))

    hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq=2412)
    id = dev[0].add_network()
    dev[0].set_network(id, "disabled", "0")
    dev[0].set_network_quoted(id, "ssid", "test")

    res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 1:
        raise Exception("Missing BSSs entry: " + str(res))
    bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
    props = bss_obj.GetAll(WPAS_DBUS_BSS, dbus_interface=dbus.PROPERTIES_IFACE)
    logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_BSS, res[0], str(props)))
    bssid_str = ''
    for item in props['BSSID']:
        if len(bssid_str) > 0:
            bssid_str += ':'
        bssid_str += '%02x' % item
    if bssid_str != bssid:
        raise Exception("Unexpected BSSID in BSSs entry")

    res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks',
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 1:
        raise Exception("Missing Networks entry: " + str(res))
    net_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
    props = net_obj.GetAll(WPAS_DBUS_NETWORK,
                           dbus_interface=dbus.PROPERTIES_IFACE)
    logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_NETWORK, res[0], str(props)))
    ssid = props['Properties']['ssid']
    if ssid != '"test"':
        raise Exception("Unexpected SSID in network entry")

def dbus_get(dbus, wpas_obj, prop, expect=None, byte_arrays=False):
    val = wpas_obj.Get(WPAS_DBUS_SERVICE, prop,
                       dbus_interface=dbus.PROPERTIES_IFACE,
                       byte_arrays=byte_arrays)
    if expect is not None and val != expect:
        raise Exception("Unexpected %s: %s (expected: %s)" %
                        (prop, str(val), str(expect)))
    return val

def dbus_set(dbus, wpas_obj, prop, val):
    wpas_obj.Set(WPAS_DBUS_SERVICE, prop, val,
                 dbus_interface=dbus.PROPERTIES_IFACE)

def test_dbus_properties(dev, apdev):
    """D-Bus Get/Set fi.w1.wpa_supplicant1 properties"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    dbus_get(dbus, wpas_obj, "DebugLevel", expect="msgdump")
    dbus_set(dbus, wpas_obj, "DebugLevel", "debug")
    dbus_get(dbus, wpas_obj, "DebugLevel", expect="debug")
    for (val,err) in [ (3, "Error.Failed: wrong property type"),
                       ("foo", "Error.Failed: wrong debug level value") ]:
        try:
            dbus_set(dbus, wpas_obj, "DebugLevel", val)
            raise Exception("Invalid DebugLevel value accepted: " + str(val))
        except dbus.exceptions.DBusException, e:
            if err not in str(e):
                raise Exception("Unexpected error message: " + str(e))
    dbus_set(dbus, wpas_obj, "DebugLevel", "msgdump")
    dbus_get(dbus, wpas_obj, "DebugLevel", expect="msgdump")

    dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=True)
    dbus_set(dbus, wpas_obj, "DebugTimestamp", False)
    dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=False)
    try:
        dbus_set(dbus, wpas_obj, "DebugTimestamp", "foo")
        raise Exception("Invalid DebugTimestamp value accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message: " + str(e))
    dbus_set(dbus, wpas_obj, "DebugTimestamp", True)
    dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=True)

    dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=True)
    dbus_set(dbus, wpas_obj, "DebugShowKeys", False)
    dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=False)
    try:
        dbus_set(dbus, wpas_obj, "DebugShowKeys", "foo")
        raise Exception("Invalid DebugShowKeys value accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message: " + str(e))
    dbus_set(dbus, wpas_obj, "DebugShowKeys", True)
    dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=True)

    res = dbus_get(dbus, wpas_obj, "Interfaces")
    if len(res) != 1:
        raise Exception("Unexpected Interfaces value: " + str(res))

    res = dbus_get(dbus, wpas_obj, "EapMethods")
    if len(res) < 5 or "TTLS" not in res:
        raise Exception("Unexpected EapMethods value: " + str(res))

    res = dbus_get(dbus, wpas_obj, "Capabilities")
    if len(res) < 2 or "p2p" not in res:
        raise Exception("Unexpected Capabilities value: " + str(res))

    dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True)
    val = binascii.unhexlify("010006020304050608")
    dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(val))
    res = dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True)
    if val != res:
        raise Exception("WFDIEs value changed")
    try:
        dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray('\x00'))
        raise Exception("Invalid WFDIEs value accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message: " + str(e))
    dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(''))
    dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(val))
    dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(''))
    res = dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True)
    if len(res) != 0:
        raise Exception("WFDIEs not cleared properly")

    res = dbus_get(dbus, wpas_obj, "EapMethods")
    try:
        dbus_set(dbus, wpas_obj, "EapMethods", res)
        raise Exception("Invalid Set accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs: Property is read-only" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

    try:
        wpas_obj.SetFoo(WPAS_DBUS_SERVICE, "DebugShowKeys", True,
                        dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Unknown method accepted")
    except dbus.exceptions.DBusException, e:
        if "UnknownMethod" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

    try:
        wpas_obj.Get("foo", "DebugShowKeys",
                     dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Get accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs: No such property" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

    test_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH,
                              introspect=False)
    try:
        test_obj.Get(123, "DebugShowKeys",
                     dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Get accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs: Invalid arguments" not in str(e):
            raise Exception("Unexpected error message: " + str(e))
    try:
        test_obj.Get(WPAS_DBUS_SERVICE, 123,
                     dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Get accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs: Invalid arguments" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

    try:
        wpas_obj.Set(WPAS_DBUS_SERVICE, "WFDIEs",
                     dbus.ByteArray('', variant_level=2),
                     dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs: invalid message format" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

def test_dbus_invalid_method(dev, apdev):
    """D-Bus invalid method"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    try:
        wps.Foo()
        raise Exception("Unknown method accepted")
    except dbus.exceptions.DBusException, e:
        if "UnknownMethod" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

    test_obj = bus.get_object(WPAS_DBUS_SERVICE, path, introspect=False)
    test_wps = dbus.Interface(test_obj, WPAS_DBUS_IFACE_WPS)
    try:
        test_wps.Start(123)
        raise Exception("WPS.Start with incorrect signature accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs: Invalid arg" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

def test_dbus_get_set_wps(dev, apdev):
    """D-Bus Get/Set for WPS properties"""
    try:
        _test_dbus_get_set_wps(dev, apdev)
    finally:
        dev[0].request("SET wps_cred_processing 0")
        dev[0].request("SET config_methods display keypad virtual_display nfc_interface p2ps")

def _test_dbus_get_set_wps(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods",
               dbus_interface=dbus.PROPERTIES_IFACE)

    val = "display keypad virtual_display nfc_interface"
    dev[0].request("SET config_methods " + val)

    config = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods",
                        dbus_interface=dbus.PROPERTIES_IFACE)
    if config != val:
        raise Exception("Unexpected Get(ConfigMethods) result: " + config)

    val2 = "push_button display"
    if_obj.Set(WPAS_DBUS_IFACE_WPS, "ConfigMethods", val2,
               dbus_interface=dbus.PROPERTIES_IFACE)
    config = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods",
                        dbus_interface=dbus.PROPERTIES_IFACE)
    if config != val2:
        raise Exception("Unexpected Get(ConfigMethods) result after Set: " + config)

    dev[0].request("SET config_methods " + val)

    for i in range(3):
        dev[0].request("SET wps_cred_processing " + str(i))
        val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
                         dbus_interface=dbus.PROPERTIES_IFACE)
        expected_val = False if i == 1 else True
        if val != expected_val:
            raise Exception("Unexpected Get(ProcessCredentials) result({}): {}".format(i, val))

    class TestDbusGetSet(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.signal_received = False
            self.signal_received_deprecated = False
            self.sets_done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_sets)
            gobject.timeout_add(1000, self.timeout)
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE_WPS,
                            "PropertiesChanged")
            self.add_signal(self.propertiesChanged2, dbus.PROPERTIES_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def propertiesChanged(self, properties):
            logger.debug("PropertiesChanged: " + str(properties))
            if properties.has_key("ProcessCredentials"):
                self.signal_received_deprecated = True
                if self.sets_done and self.signal_received:
                    self.loop.quit()

        def propertiesChanged2(self, interface_name, changed_properties,
                               invalidated_properties):
            logger.debug("propertiesChanged2: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
            if interface_name != WPAS_DBUS_IFACE_WPS:
                return
            if changed_properties.has_key("ProcessCredentials"):
                self.signal_received = True
                if self.sets_done and self.signal_received_deprecated:
                    self.loop.quit()

        def run_sets(self, *args):
            logger.debug("run_sets")
            if_obj.Set(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
                       dbus.Boolean(1),
                       dbus_interface=dbus.PROPERTIES_IFACE)
            if if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
                          dbus_interface=dbus.PROPERTIES_IFACE) != True:
                raise Exception("Unexpected Get(ProcessCredentials) result after Set");
            if_obj.Set(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
                       dbus.Boolean(0),
                       dbus_interface=dbus.PROPERTIES_IFACE)
            if if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
                          dbus_interface=dbus.PROPERTIES_IFACE) != False:
                raise Exception("Unexpected Get(ProcessCredentials) result after Set");

            self.dbus_sets_done = True
            return False

        def success(self):
            return self.signal_received and self.signal_received_deprecated

    with TestDbusGetSet(bus) as t:
        if not t.success():
            raise Exception("No signal received for ProcessCredentials change")

def test_dbus_wps_invalid(dev, apdev):
    """D-Bus invaldi WPS operation"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    failures = [ {'Role': 'foo', 'Type': 'pbc'},
                 {'Role': 123, 'Type': 'pbc'},
                 {'Type': 'pbc'},
                 {'Role': 'enrollee'},
                 {'Role': 'registrar'},
                 {'Role': 'enrollee', 'Type': 123},
                 {'Role': 'enrollee', 'Type': 'foo'},
                 {'Role': 'enrollee', 'Type': 'pbc',
                  'Bssid': '02:33:44:55:66:77'},
                 {'Role': 'enrollee', 'Type': 'pin', 'Pin': 123},
                 {'Role': 'enrollee', 'Type': 'pbc',
                  'Bssid': dbus.ByteArray('12345')},
                 {'Role': 'enrollee', 'Type': 'pbc',
                  'P2PDeviceAddress': 12345},
                 {'Role': 'enrollee', 'Type': 'pbc',
                  'P2PDeviceAddress': dbus.ByteArray('12345')},
                 {'Role': 'enrollee', 'Type': 'pbc', 'Foo': 'bar'} ]
    for args in failures:
        try:
            wps.Start(args)
            raise Exception("Invalid WPS.Start() arguments accepted: " + str(args))
        except dbus.exceptions.DBusException, e:
            if not str(e).startswith("fi.w1.wpa_supplicant1.InvalidArgs"):
                raise Exception("Unexpected error message: " + str(e))

def test_dbus_wps_oom(dev, apdev):
    """D-Bus WPS operation (OOM)"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_getter_state", "Get"):
        if_obj.Get(WPAS_DBUS_IFACE, "State",
                   dbus_interface=dbus.PROPERTIES_IFACE)

    hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq=2412)

    for i in range(1, 3):
        with alloc_fail_dbus(dev[0], i, "=wpas_dbus_getter_bsss", "Get"):
            if_obj.Get(WPAS_DBUS_IFACE, "BSSs",
                       dbus_interface=dbus.PROPERTIES_IFACE)

    res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
                     dbus_interface=dbus.PROPERTIES_IFACE)
    bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
    with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_getter_bss_rates", "Get"):
        bss_obj.Get(WPAS_DBUS_BSS, "Rates",
                    dbus_interface=dbus.PROPERTIES_IFACE)

    id = dev[0].add_network()
    dev[0].set_network(id, "disabled", "0")
    dev[0].set_network_quoted(id, "ssid", "test")

    for i in range(1, 3):
        with alloc_fail_dbus(dev[0], i, "=wpas_dbus_getter_networks", "Get"):
            if_obj.Get(WPAS_DBUS_IFACE, "Networks",
                       dbus_interface=dbus.PROPERTIES_IFACE)

    with alloc_fail_dbus(dev[0], 1, "wpas_dbus_getter_interfaces", "Get"):
        dbus_get(dbus, wpas_obj, "Interfaces")

    for i in range(1, 6):
        with alloc_fail_dbus(dev[0], i, "=eap_get_names_as_string_array;wpas_dbus_getter_eap_methods", "Get"):
            dbus_get(dbus, wpas_obj, "EapMethods")

    with alloc_fail_dbus(dev[0], 1, "wpas_dbus_setter_config_methods", "Set",
                         expected="Error.Failed: Failed to set property"):
        val2 = "push_button display"
        if_obj.Set(WPAS_DBUS_IFACE_WPS, "ConfigMethods", val2,
                   dbus_interface=dbus.PROPERTIES_IFACE)

    with alloc_fail_dbus(dev[0], 1, "=wpa_config_add_network;wpas_dbus_handler_wps_start",
                         "WPS.Start",
                         expected="UnknownError: WPS start failed"):
        wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670'})

def test_dbus_wps_pbc(dev, apdev):
    """D-Bus WPS/PBC operation and signals"""
    try:
        _test_dbus_wps_pbc(dev, apdev)
    finally:
        dev[0].request("SET wps_cred_processing 0")

def _test_dbus_wps_pbc(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    hapd = start_ap(apdev[0])
    hapd.request("WPS_PBC")
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq="2412")
    dev[0].request("SET wps_cred_processing 2")

    res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 1:
        raise Exception("Missing BSSs entry: " + str(res))
    bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
    props = bss_obj.GetAll(WPAS_DBUS_BSS, dbus_interface=dbus.PROPERTIES_IFACE)
    logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_BSS, res[0], str(props)))
    if 'WPS' not in props:
        raise Exception("No WPS information in the BSS entry")
    if 'Type' not in props['WPS']:
        raise Exception("No Type field in the WPS dictionary")
    if props['WPS']['Type'] != 'pbc':
        raise Exception("Unexpected WPS Type: " + props['WPS']['Type'])

    class TestDbusWps(TestDbus):
        def __init__(self, bus, wps):
            TestDbus.__init__(self, bus)
            self.success_seen = False
            self.credentials_received = False
            self.wps = wps

        def __enter__(self):
            gobject.timeout_add(1, self.start_pbc)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
            self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
                            "Credentials")
            self.loop.run()
            return self

        def wpsEvent(self, name, args):
            logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
            if name == "success":
                self.success_seen = True
                if self.credentials_received:
                    self.loop.quit()

        def credentials(self, args):
            logger.debug("credentials: " + str(args))
            self.credentials_received = True
            if self.success_seen:
                self.loop.quit()

        def start_pbc(self, *args):
            logger.debug("start_pbc")
            self.wps.Start({'Role': 'enrollee', 'Type': 'pbc'})
            return False

        def success(self):
            return self.success_seen and self.credentials_received

    with TestDbusWps(bus, wps) as t:
        if not t.success():
            raise Exception("Failure in D-Bus operations")

    dev[0].wait_connected(timeout=10)
    dev[0].request("DISCONNECT")
    hapd.disable()
    dev[0].flush_scan_cache()

def test_dbus_wps_pbc_overlap(dev, apdev):
    """D-Bus WPS/PBC operation and signal for PBC overlap"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    hapd = start_ap(apdev[0])
    hapd2 = start_ap(apdev[1], ssid="test-wps2",
                     ap_uuid="27ea801a-9e5c-4e73-bd82-f89cbcd10d7f")
    hapd.request("WPS_PBC")
    hapd2.request("WPS_PBC")
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq="2412")
    bssid2 = apdev[1]['bssid']
    dev[0].scan_for_bss(bssid2, freq="2412")

    class TestDbusWps(TestDbus):
        def __init__(self, bus, wps):
            TestDbus.__init__(self, bus)
            self.overlap_seen = False
            self.wps = wps

        def __enter__(self):
            gobject.timeout_add(1, self.start_pbc)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
            self.loop.run()
            return self

        def wpsEvent(self, name, args):
            logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
            if name == "pbc-overlap":
                self.overlap_seen = True
                self.loop.quit()

        def start_pbc(self, *args):
            logger.debug("start_pbc")
            self.wps.Start({'Role': 'enrollee', 'Type': 'pbc'})
            return False

        def success(self):
            return self.overlap_seen

    with TestDbusWps(bus, wps) as t:
        if not t.success():
            raise Exception("Failure in D-Bus operations")

    dev[0].request("WPS_CANCEL")
    dev[0].request("DISCONNECT")
    hapd.disable()
    dev[0].flush_scan_cache()

def test_dbus_wps_pin(dev, apdev):
    """D-Bus WPS/PIN operation and signals"""
    try:
        _test_dbus_wps_pin(dev, apdev)
    finally:
        dev[0].request("SET wps_cred_processing 0")

def _test_dbus_wps_pin(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    hapd = start_ap(apdev[0])
    hapd.request("WPS_PIN any 12345670")
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq="2412")
    dev[0].request("SET wps_cred_processing 2")

    class TestDbusWps(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.success_seen = False
            self.credentials_received = False

        def __enter__(self):
            gobject.timeout_add(1, self.start_pin)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
            self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
                            "Credentials")
            self.loop.run()
            return self

        def wpsEvent(self, name, args):
            logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
            if name == "success":
                self.success_seen = True
                if self.credentials_received:
                    self.loop.quit()

        def credentials(self, args):
            logger.debug("credentials: " + str(args))
            self.credentials_received = True
            if self.success_seen:
                self.loop.quit()

        def start_pin(self, *args):
            logger.debug("start_pin")
            bssid_ay = dbus.ByteArray(bssid.replace(':','').decode('hex'))
            wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670',
                       'Bssid': bssid_ay})
            return False

        def success(self):
            return self.success_seen and self.credentials_received

    with TestDbusWps(bus) as t:
        if not t.success():
            raise Exception("Failure in D-Bus operations")

    dev[0].wait_connected(timeout=10)

def test_dbus_wps_pin2(dev, apdev):
    """D-Bus WPS/PIN operation and signals (PIN from wpa_supplicant)"""
    try:
        _test_dbus_wps_pin2(dev, apdev)
    finally:
        dev[0].request("SET wps_cred_processing 0")

def _test_dbus_wps_pin2(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    hapd = start_ap(apdev[0])
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq="2412")
    dev[0].request("SET wps_cred_processing 2")

    class TestDbusWps(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.success_seen = False
            self.failed = False

        def __enter__(self):
            gobject.timeout_add(1, self.start_pin)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
            self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
                            "Credentials")
            self.loop.run()
            return self

        def wpsEvent(self, name, args):
            logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
            if name == "success":
                self.success_seen = True
                if self.credentials_received:
                    self.loop.quit()

        def credentials(self, args):
            logger.debug("credentials: " + str(args))
            self.credentials_received = True
            if self.success_seen:
                self.loop.quit()

        def start_pin(self, *args):
            logger.debug("start_pin")
            bssid_ay = dbus.ByteArray(bssid.replace(':','').decode('hex'))
            res = wps.Start({'Role': 'enrollee', 'Type': 'pin',
                             'Bssid': bssid_ay})
            pin = res['Pin']
            h = hostapd.Hostapd(apdev[0]['ifname'])
            h.request("WPS_PIN any " + pin)
            return False

        def success(self):
            return self.success_seen and self.credentials_received

    with TestDbusWps(bus) as t:
        if not t.success():
            raise Exception("Failure in D-Bus operations")

    dev[0].wait_connected(timeout=10)

def test_dbus_wps_pin_m2d(dev, apdev):
    """D-Bus WPS/PIN operation and signals with M2D"""
    try:
        _test_dbus_wps_pin_m2d(dev, apdev)
    finally:
        dev[0].request("SET wps_cred_processing 0")

def _test_dbus_wps_pin_m2d(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    hapd = start_ap(apdev[0])
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq="2412")
    dev[0].request("SET wps_cred_processing 2")

    class TestDbusWps(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.success_seen = False
            self.credentials_received = False

        def __enter__(self):
            gobject.timeout_add(1, self.start_pin)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
            self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
                            "Credentials")
            self.loop.run()
            return self

        def wpsEvent(self, name, args):
            logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
            if name == "success":
                self.success_seen = True
                if self.credentials_received:
                    self.loop.quit()
            elif name == "m2d":
                h = hostapd.Hostapd(apdev[0]['ifname'])
                h.request("WPS_PIN any 12345670")

        def credentials(self, args):
            logger.debug("credentials: " + str(args))
            self.credentials_received = True
            if self.success_seen:
                self.loop.quit()

        def start_pin(self, *args):
            logger.debug("start_pin")
            bssid_ay = dbus.ByteArray(bssid.replace(':','').decode('hex'))
            wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670',
                       'Bssid': bssid_ay})
            return False

        def success(self):
            return self.success_seen and self.credentials_received

    with TestDbusWps(bus) as t:
        if not t.success():
            raise Exception("Failure in D-Bus operations")

    dev[0].wait_connected(timeout=10)

def test_dbus_wps_reg(dev, apdev):
    """D-Bus WPS/Registrar operation and signals"""
    try:
        _test_dbus_wps_reg(dev, apdev)
    finally:
        dev[0].request("SET wps_cred_processing 0")

def _test_dbus_wps_reg(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    hapd = start_ap(apdev[0])
    hapd.request("WPS_PIN any 12345670")
    bssid = apdev[0]['bssid']
    dev[0].scan_for_bss(bssid, freq="2412")
    dev[0].request("SET wps_cred_processing 2")

    class TestDbusWps(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.credentials_received = False

        def __enter__(self):
            gobject.timeout_add(100, self.start_reg)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
            self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
                            "Credentials")
            self.loop.run()
            return self

        def wpsEvent(self, name, args):
            logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))

        def credentials(self, args):
            logger.debug("credentials: " + str(args))
            self.credentials_received = True
            self.loop.quit()

        def start_reg(self, *args):
            logger.debug("start_reg")
            bssid_ay = dbus.ByteArray(bssid.replace(':','').decode('hex'))
            wps.Start({'Role': 'registrar', 'Type': 'pin',
                       'Pin': '12345670', 'Bssid': bssid_ay})
            return False

        def success(self):
            return self.credentials_received

    with TestDbusWps(bus) as t:
        if not t.success():
            raise Exception("Failure in D-Bus operations")

    dev[0].wait_connected(timeout=10)

def test_dbus_wps_cancel(dev, apdev):
    """D-Bus WPS Cancel operation"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)

    hapd = start_ap(apdev[0])
    bssid = apdev[0]['bssid']

    wps.Cancel()
    dev[0].scan_for_bss(bssid, freq="2412")
    bssid_ay = dbus.ByteArray(bssid.replace(':','').decode('hex'))
    wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670',
               'Bssid': bssid_ay})
    wps.Cancel()
    dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 1)

def test_dbus_scan_invalid(dev, apdev):
    """D-Bus invalid scan method"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    tests = [ ({}, "InvalidArgs"),
              ({'Type': 123}, "InvalidArgs"),
              ({'Type': 'foo'}, "InvalidArgs"),
              ({'Type': 'active', 'Foo': 'bar'}, "InvalidArgs"),
              ({'Type': 'active', 'SSIDs': 'foo'}, "InvalidArgs"),
              ({'Type': 'active', 'SSIDs': ['foo']}, "InvalidArgs"),
              ({'Type': 'active',
                'SSIDs': [ dbus.ByteArray("1"), dbus.ByteArray("2"),
                           dbus.ByteArray("3"), dbus.ByteArray("4"),
                           dbus.ByteArray("5"), dbus.ByteArray("6"),
                           dbus.ByteArray("7"), dbus.ByteArray("8"),
                           dbus.ByteArray("9"), dbus.ByteArray("10"),
                           dbus.ByteArray("11"), dbus.ByteArray("12"),
                           dbus.ByteArray("13"), dbus.ByteArray("14"),
                           dbus.ByteArray("15"), dbus.ByteArray("16"),
                           dbus.ByteArray("17") ]},
               "InvalidArgs"),
              ({'Type': 'active',
                'SSIDs': [ dbus.ByteArray("1234567890abcdef1234567890abcdef1") ]},
               "InvalidArgs"),
              ({'Type': 'active', 'IEs': 'foo'}, "InvalidArgs"),
              ({'Type': 'active', 'IEs': ['foo']}, "InvalidArgs"),
              ({'Type': 'active', 'Channels': 2412 }, "InvalidArgs"),
              ({'Type': 'active', 'Channels': [ 2412 ] }, "InvalidArgs"),
              ({'Type': 'active',
                'Channels': [ (dbus.Int32(2412), dbus.UInt32(20)) ] },
               "InvalidArgs"),
              ({'Type': 'active',
                'Channels': [ (dbus.UInt32(2412), dbus.Int32(20)) ] },
               "InvalidArgs"),
              ({'Type': 'active', 'AllowRoam': "yes" }, "InvalidArgs"),
              ({'Type': 'passive', 'IEs': [ dbus.ByteArray("\xdd\x00") ]},
               "InvalidArgs"),
              ({'Type': 'passive', 'SSIDs': [ dbus.ByteArray("foo") ]},
               "InvalidArgs")]
    for (t,err) in tests:
        try:
            iface.Scan(t)
            raise Exception("Invalid Scan() arguments accepted: " + str(t))
        except dbus.exceptions.DBusException, e:
            if err not in str(e):
                raise Exception("Unexpected error message for invalid Scan(%s): %s" % (str(t), str(e)))

def test_dbus_scan_oom(dev, apdev):
    """D-Bus scan method and OOM"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    with alloc_fail_dbus(dev[0], 1,
                         "wpa_scan_clone_params;wpas_dbus_handler_scan",
                         "Scan", expected="ScanError: Scan request rejected"):
        iface.Scan({ 'Type': 'passive',
                     'Channels': [ (dbus.UInt32(2412), dbus.UInt32(20)) ] })

    with alloc_fail_dbus(dev[0], 1,
                         "=wpas_dbus_get_scan_channels;wpas_dbus_handler_scan",
                         "Scan"):
        iface.Scan({ 'Type': 'passive',
                     'Channels': [ (dbus.UInt32(2412), dbus.UInt32(20)) ] })

    with alloc_fail_dbus(dev[0], 1,
                         "=wpas_dbus_get_scan_ies;wpas_dbus_handler_scan",
                         "Scan"):
        iface.Scan({ 'Type': 'active',
                     'IEs': [ dbus.ByteArray("\xdd\x00") ],
                     'Channels': [ (dbus.UInt32(2412), dbus.UInt32(20)) ] })

    with alloc_fail_dbus(dev[0], 1,
                         "=wpas_dbus_get_scan_ssids;wpas_dbus_handler_scan",
                         "Scan"):
        iface.Scan({ 'Type': 'active',
                     'SSIDs': [ dbus.ByteArray("open"),
                                dbus.ByteArray() ],
                     'Channels': [ (dbus.UInt32(2412), dbus.UInt32(20)) ] })

def test_dbus_scan(dev, apdev):
    """D-Bus scan and related signals"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })

    class TestDbusScan(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.scan_completed = 0
            self.bss_added = False
            self.fail_reason = None

        def __enter__(self):
            gobject.timeout_add(1, self.run_scan)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.scanDone, WPAS_DBUS_IFACE, "ScanDone")
            self.add_signal(self.bssAdded, WPAS_DBUS_IFACE, "BSSAdded")
            self.add_signal(self.bssRemoved, WPAS_DBUS_IFACE, "BSSRemoved")
            self.loop.run()
            return self

        def scanDone(self, success):
            logger.debug("scanDone: success=%s" % success)
            self.scan_completed += 1
            if self.scan_completed == 1:
                iface.Scan({'Type': 'passive',
                            'AllowRoam': True,
                            'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
            elif self.scan_completed == 2:
                iface.Scan({'Type': 'passive',
                            'AllowRoam': False})
            elif self.bss_added and self.scan_completed == 3:
                self.loop.quit()

        def bssAdded(self, bss, properties):
            logger.debug("bssAdded: %s" % bss)
            logger.debug(str(properties))
            if 'WPS' in properties:
                if 'Type' in properties['WPS']:
                    self.fail_reason = "Unexpected WPS dictionary entry in non-WPS BSS"
                    self.loop.quit()
            self.bss_added = True
            if self.scan_completed == 3:
                self.loop.quit()

        def bssRemoved(self, bss):
            logger.debug("bssRemoved: %s" % bss)

        def run_scan(self, *args):
            logger.debug("run_scan")
            iface.Scan({'Type': 'active',
                        'SSIDs': [ dbus.ByteArray("open"),
                                   dbus.ByteArray() ],
                        'IEs': [ dbus.ByteArray("\xdd\x00"),
                                 dbus.ByteArray() ],
                        'AllowRoam': False,
                        'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
            return False

        def success(self):
            return self.scan_completed == 3 and self.bss_added

    with TestDbusScan(bus) as t:
        if t.fail_reason:
            raise Exception(t.fail_reason)
        if not t.success():
            raise Exception("Expected signals not seen")

    res = if_obj.Get(WPAS_DBUS_IFACE, "BSSs",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) < 1:
        raise Exception("Scan result not in BSSs property")
    iface.FlushBSS(0)
    res = if_obj.Get(WPAS_DBUS_IFACE, "BSSs",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 0:
        raise Exception("FlushBSS() did not remove scan results from BSSs property")
    iface.FlushBSS(1)

def test_dbus_scan_busy(dev, apdev):
    """D-Bus scan trigger rejection when busy with previous scan"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    if "OK" not in dev[0].request("SCAN freq=2412-2462"):
        raise Exception("Failed to start scan")
    ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], 15)
    if ev is None:
        raise Exception("Scan start timed out")

    try:
        iface.Scan({'Type': 'active', 'AllowRoam': False})
        raise Exception("Scan() accepted when busy")
    except dbus.exceptions.DBusException, e:
        if "ScanError: Scan request reject" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

    ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
    if ev is None:
        raise Exception("Scan timed out")

def test_dbus_connect(dev, apdev):
    """D-Bus AddNetwork and connect"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    ssid = "test-wpa2-psk"
    passphrase = 'qwertyuiop'
    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
    hapd = hostapd.add_ap(apdev[0]['ifname'], params)

    class TestDbusConnect(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.network_added = False
            self.network_selected = False
            self.network_removed = False
            self.state = 0

        def __enter__(self):
            gobject.timeout_add(1, self.run_connect)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded")
            self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE,
                            "NetworkRemoved")
            self.add_signal(self.networkSelected, WPAS_DBUS_IFACE,
                            "NetworkSelected")
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def networkAdded(self, network, properties):
            logger.debug("networkAdded: %s" % str(network))
            logger.debug(str(properties))
            self.network_added = True

        def networkRemoved(self, network):
            logger.debug("networkRemoved: %s" % str(network))
            self.network_removed = True

        def networkSelected(self, network):
            logger.debug("networkSelected: %s" % str(network))
            self.network_selected = True

        def propertiesChanged(self, properties):
            logger.debug("propertiesChanged: %s" % str(properties))
            if 'State' in properties and properties['State'] == "completed":
                if self.state == 0:
                    self.state = 1
                    iface.Disconnect()
                elif self.state == 2:
                    self.state = 3
                    iface.Disconnect()
                elif self.state == 4:
                    self.state = 5
                    iface.Reattach()
                elif self.state == 5:
                    self.state = 6
                    iface.Disconnect()
                elif self.state == 7:
                    self.state = 8
                    res = iface.SignalPoll()
                    logger.debug("SignalPoll: " + str(res))
                    if 'frequency' not in res or res['frequency'] != 2412:
                        self.state = -1
                        logger.info("Unexpected SignalPoll result")
                    iface.RemoveNetwork(self.netw)
            if 'State' in properties and properties['State'] == "disconnected":
                if self.state == 1:
                    self.state = 2
                    iface.SelectNetwork(self.netw)
                elif self.state == 3:
                    self.state = 4
                    iface.Reassociate()
                elif self.state == 6:
                    self.state = 7
                    iface.Reconnect()
                elif self.state == 8:
                    self.state = 9
                    self.loop.quit()

        def run_connect(self, *args):
            logger.debug("run_connect")
            args = dbus.Dictionary({ 'ssid': ssid,
                                     'key_mgmt': 'WPA-PSK',
                                     'psk': passphrase,
                                     'scan_freq': 2412 },
                                   signature='sv')
            self.netw = iface.AddNetwork(args)
            iface.SelectNetwork(self.netw)
            return False

        def success(self):
            if not self.network_added or \
               not self.network_removed or \
               not self.network_selected:
                return False
            return self.state == 9

    with TestDbusConnect(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_connect_psk_mem(dev, apdev):
    """D-Bus AddNetwork and connect with memory-only PSK"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    ssid = "test-wpa2-psk"
    passphrase = 'qwertyuiop'
    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
    hapd = hostapd.add_ap(apdev[0]['ifname'], params)

    class TestDbusConnect(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.connected = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_connect)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
                            "PropertiesChanged")
            self.add_signal(self.networkRequest, WPAS_DBUS_IFACE,
                            "NetworkRequest")
            self.loop.run()
            return self

        def propertiesChanged(self, properties):
            logger.debug("propertiesChanged: %s" % str(properties))
            if 'State' in properties and properties['State'] == "completed":
                self.connected = True
                self.loop.quit()

        def networkRequest(self, path, field, txt):
            logger.debug("networkRequest: %s %s %s" % (path, field, txt))
            if field == "PSK_PASSPHRASE":
                iface.NetworkReply(path, field, '"' + passphrase + '"')

        def run_connect(self, *args):
            logger.debug("run_connect")
            args = dbus.Dictionary({ 'ssid': ssid,
                                     'key_mgmt': 'WPA-PSK',
                                     'mem_only_psk': 1,
                                     'scan_freq': 2412 },
                                   signature='sv')
            self.netw = iface.AddNetwork(args)
            iface.SelectNetwork(self.netw)
            return False

        def success(self):
            return self.connected

    with TestDbusConnect(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_connect_oom(dev, apdev):
    """D-Bus AddNetwork and connect when out-of-memory"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    if "OK" not in dev[0].request("TEST_ALLOC_FAIL 0:"):
        raise HwsimSkip("TEST_ALLOC_FAIL not supported in the build")

    ssid = "test-wpa2-psk"
    passphrase = 'qwertyuiop'
    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
    hapd = hostapd.add_ap(apdev[0]['ifname'], params)

    class TestDbusConnect(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.network_added = False
            self.network_selected = False
            self.network_removed = False
            self.state = 0

        def __enter__(self):
            gobject.timeout_add(1, self.run_connect)
            gobject.timeout_add(1500, self.timeout)
            self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded")
            self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE,
                            "NetworkRemoved")
            self.add_signal(self.networkSelected, WPAS_DBUS_IFACE,
                            "NetworkSelected")
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def networkAdded(self, network, properties):
            logger.debug("networkAdded: %s" % str(network))
            logger.debug(str(properties))
            self.network_added = True

        def networkRemoved(self, network):
            logger.debug("networkRemoved: %s" % str(network))
            self.network_removed = True

        def networkSelected(self, network):
            logger.debug("networkSelected: %s" % str(network))
            self.network_selected = True

        def propertiesChanged(self, properties):
            logger.debug("propertiesChanged: %s" % str(properties))
            if 'State' in properties and properties['State'] == "completed":
                if self.state == 0:
                    self.state = 1
                    iface.Disconnect()
                elif self.state == 2:
                    self.state = 3
                    iface.Disconnect()
                elif self.state == 4:
                    self.state = 5
                    iface.Reattach()
                elif self.state == 5:
                    self.state = 6
                    res = iface.SignalPoll()
                    logger.debug("SignalPoll: " + str(res))
                    if 'frequency' not in res or res['frequency'] != 2412:
                        self.state = -1
                        logger.info("Unexpected SignalPoll result")
                    iface.RemoveNetwork(self.netw)
            if 'State' in properties and properties['State'] == "disconnected":
                if self.state == 1:
                    self.state = 2
                    iface.SelectNetwork(self.netw)
                elif self.state == 3:
                    self.state = 4
                    iface.Reassociate()
                elif self.state == 6:
                    self.state = 7
                    self.loop.quit()

        def run_connect(self, *args):
            logger.debug("run_connect")
            args = dbus.Dictionary({ 'ssid': ssid,
                                     'key_mgmt': 'WPA-PSK',
                                     'psk': passphrase,
                                     'scan_freq': 2412 },
                                   signature='sv')
            try:
                self.netw = iface.AddNetwork(args)
            except Exception, e:
                logger.info("Exception on AddNetwork: " + str(e))
                self.loop.quit()
                return False
            try:
                iface.SelectNetwork(self.netw)
            except Exception, e:
                logger.info("Exception on SelectNetwork: " + str(e))
                self.loop.quit()

            return False

        def success(self):
            if not self.network_added or \
               not self.network_removed or \
               not self.network_selected:
                return False
            return self.state == 7

    count = 0
    for i in range(1, 1000):
        for j in range(3):
            dev[j].dump_monitor()
        dev[0].request("TEST_ALLOC_FAIL %d:main" % i)
        try:
            with TestDbusConnect(bus) as t:
                if not t.success():
                    logger.info("Iteration %d - Expected signals not seen" % i)
                else:
                    logger.info("Iteration %d - success" % i)

            state = dev[0].request('GET_ALLOC_FAIL')
            logger.info("GET_ALLOC_FAIL: " + state)
            dev[0].dump_monitor()
            dev[0].request("TEST_ALLOC_FAIL 0:")
            if i < 3:
                raise Exception("Connection succeeded during out-of-memory")
            if not state.startswith('0:'):
                count += 1
                if count == 5:
                    break
        except:
            pass

def test_dbus_while_not_connected(dev, apdev):
    """D-Bus invalid operations while not connected"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    try:
        iface.Disconnect()
        raise Exception("Disconnect() accepted when not connected")
    except dbus.exceptions.DBusException, e:
        if "NotConnected" not in str(e):
            raise Exception("Unexpected error message for invalid Disconnect: " + str(e))

    try:
        iface.Reattach()
        raise Exception("Reattach() accepted when not connected")
    except dbus.exceptions.DBusException, e:
        if "NotConnected" not in str(e):
            raise Exception("Unexpected error message for invalid Reattach: " + str(e))

def test_dbus_connect_eap(dev, apdev):
    """D-Bus AddNetwork and connect to EAP network"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    ssid = "ieee8021x-open"
    params = hostapd.radius_params()
    params["ssid"] = ssid
    params["ieee8021x"] = "1"
    hapd = hostapd.add_ap(apdev[0]['ifname'], params)

    class TestDbusConnect(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.certification_received = False
            self.eap_status = False
            self.state = 0

        def __enter__(self):
            gobject.timeout_add(1, self.run_connect)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
                            "PropertiesChanged")
            self.add_signal(self.certification, WPAS_DBUS_IFACE,
                            "Certification", byte_arrays=True)
            self.add_signal(self.networkRequest, WPAS_DBUS_IFACE,
                            "NetworkRequest")
            self.add_signal(self.eap, WPAS_DBUS_IFACE, "EAP")
            self.loop.run()
            return self

        def propertiesChanged(self, properties):
            logger.debug("propertiesChanged: %s" % str(properties))
            if 'State' in properties and properties['State'] == "completed":
                if self.state == 0:
                    self.state = 1
                    iface.EAPLogoff()
                    logger.info("Set dNSName constraint")
                    net_obj = bus.get_object(WPAS_DBUS_SERVICE, self.netw)
                    args = dbus.Dictionary({ 'altsubject_match':
                                             self.server_dnsname },
                                           signature='sv')
                    net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args,
                                dbus_interface=dbus.PROPERTIES_IFACE)
                elif self.state == 2:
                    self.state = 3
                    iface.Disconnect()
                    logger.info("Set non-matching dNSName constraint")
                    net_obj = bus.get_object(WPAS_DBUS_SERVICE, self.netw)
                    args = dbus.Dictionary({ 'altsubject_match':
                                             self.server_dnsname + "FOO" },
                                           signature='sv')
                    net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args,
                                dbus_interface=dbus.PROPERTIES_IFACE)
            if 'State' in properties and properties['State'] == "disconnected":
                if self.state == 1:
                    self.state = 2
                    iface.EAPLogon()
                    iface.SelectNetwork(self.netw)
                if self.state == 3:
                    self.state = 4
                    iface.SelectNetwork(self.netw)

        def certification(self, args):
            logger.debug("certification: %s" % str(args))
            self.certification_received = True
            if args['depth'] == 0:
                # The test server certificate is supposed to have dNSName
                if len(args['altsubject']) < 1:
                    raise Exception("Missing dNSName")
                dnsname = args['altsubject'][0]
                if not dnsname.startswith("DNS:"):
                    raise Exception("Expected dNSName not found: " + dnsname)
                logger.info("altsubject: " + dnsname)
                self.server_dnsname = dnsname

        def eap(self, status, parameter):
            logger.debug("EAP: status=%s parameter=%s" % (status, parameter))
            if status == 'completion' and parameter == 'success':
                self.eap_status = True
            if self.state == 4 and status == 'remote certificate verification' and parameter == 'AltSubject mismatch':
                self.state = 5
                self.loop.quit()

        def networkRequest(self, path, field, txt):
            logger.debug("networkRequest: %s %s %s" % (path, field, txt))
            if field == "PASSWORD":
                iface.NetworkReply(path, field, "password")

        def run_connect(self, *args):
            logger.debug("run_connect")
            args = dbus.Dictionary({ 'ssid': ssid,
                                     'key_mgmt': 'IEEE8021X',
                                     'eapol_flags': 0,
                                     'eap': 'TTLS',
                                     'anonymous_identity': 'ttls',
                                     'identity': 'pap user',
                                     'ca_cert': 'auth_serv/ca.pem',
                                     'phase2': 'auth=PAP',
                                     'scan_freq': 2412 },
                                   signature='sv')
            self.netw = iface.AddNetwork(args)
            iface.SelectNetwork(self.netw)
            return False

        def success(self):
            if not self.eap_status or not self.certification_received:
                return False
            return self.state == 5

    with TestDbusConnect(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_network(dev, apdev):
    """D-Bus AddNetwork/RemoveNetwork parameters and error cases"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    args = dbus.Dictionary({ 'ssid': "foo",
                             'key_mgmt': 'WPA-PSK',
                             'psk': "12345678",
                             'identity': dbus.ByteArray([ 1, 2 ]),
                             'priority': dbus.Int32(0),
                             'scan_freq': dbus.UInt32(2412) },
                           signature='sv')
    netw = iface.AddNetwork(args)
    id = int(dev[0].list_networks()[0]['id'])
    val = dev[0].get_network(id, "scan_freq")
    if val != "2412":
        raise Exception("Invalid scan_freq value: " + str(val))
    iface.RemoveNetwork(netw)

    args = dbus.Dictionary({ 'ssid': "foo",
                             'key_mgmt': 'NONE',
                             'scan_freq': "2412 2432",
                             'freq_list': "2412 2417 2432" },
                           signature='sv')
    netw = iface.AddNetwork(args)
    id = int(dev[0].list_networks()[0]['id'])
    val = dev[0].get_network(id, "scan_freq")
    if val != "2412 2432":
        raise Exception("Invalid scan_freq value (2): " + str(val))
    val = dev[0].get_network(id, "freq_list")
    if val != "2412 2417 2432":
        raise Exception("Invalid freq_list value: " + str(val))
    iface.RemoveNetwork(netw)
    try:
        iface.RemoveNetwork(netw)
        raise Exception("Invalid RemoveNetwork() accepted")
    except dbus.exceptions.DBusException, e:
        if "NetworkUnknown" not in str(e):
            raise Exception("Unexpected error message for invalid RemoveNetwork: " + str(e))
    try:
        iface.SelectNetwork(netw)
        raise Exception("Invalid SelectNetwork() accepted")
    except dbus.exceptions.DBusException, e:
        if "NetworkUnknown" not in str(e):
            raise Exception("Unexpected error message for invalid RemoveNetwork: " + str(e))

    args = dbus.Dictionary({ 'ssid': "foo1", 'key_mgmt': 'NONE',
                             'identity': "testuser", 'scan_freq': '2412' },
                           signature='sv')
    netw1 = iface.AddNetwork(args)
    args = dbus.Dictionary({ 'ssid': "foo2", 'key_mgmt': 'NONE' },
                           signature='sv')
    netw2 = iface.AddNetwork(args)
    res = if_obj.Get(WPAS_DBUS_IFACE, "Networks",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 2:
        raise Exception("Unexpected number of networks")

    net_obj = bus.get_object(WPAS_DBUS_SERVICE, netw1)
    res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled",
                      dbus_interface=dbus.PROPERTIES_IFACE)
    if res != False:
        raise Exception("Added network was unexpectedly enabled by default")
    net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.Boolean(True),
                dbus_interface=dbus.PROPERTIES_IFACE)
    res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled",
                      dbus_interface=dbus.PROPERTIES_IFACE)
    if res != True:
        raise Exception("Set(Enabled,True) did not seem to change property value")
    net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.Boolean(False),
                dbus_interface=dbus.PROPERTIES_IFACE)
    res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled",
                      dbus_interface=dbus.PROPERTIES_IFACE)
    if res != False:
        raise Exception("Set(Enabled,False) did not seem to change property value")
    try:
        net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.UInt32(1),
                    dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(Enabled,1) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message for invalid Set(Enabled,1): " + str(e))

    args = dbus.Dictionary({ 'ssid': "foo1new" }, signature='sv')
    net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args,
                dbus_interface=dbus.PROPERTIES_IFACE)
    res = net_obj.Get(WPAS_DBUS_NETWORK, "Properties",
                      dbus_interface=dbus.PROPERTIES_IFACE)
    if res['ssid'] != '"foo1new"':
        raise Exception("Set(Properties) failed to update ssid")
    if res['identity'] != '"testuser"':
        raise Exception("Set(Properties) unexpectedly changed unrelated parameter")

    iface.RemoveAllNetworks()
    res = if_obj.Get(WPAS_DBUS_IFACE, "Networks",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != 0:
        raise Exception("Unexpected number of networks")
    iface.RemoveAllNetworks()

    tests = [ dbus.Dictionary({ 'psk': "1234567" }, signature='sv'),
              dbus.Dictionary({ 'identity': dbus.ByteArray() },
                              signature='sv'),
              dbus.Dictionary({ 'identity': dbus.Byte(1) }, signature='sv'),
              dbus.Dictionary({ 'identity': "" }, signature='sv') ]
    for args in tests:
        try:
            iface.AddNetwork(args)
            raise Exception("Invalid AddNetwork args accepted: " + str(args))
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid AddNetwork: " + str(e))

def test_dbus_network_oom(dev, apdev):
    """D-Bus AddNetwork/RemoveNetwork parameters and OOM error cases"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    args = dbus.Dictionary({ 'ssid': "foo1", 'key_mgmt': 'NONE',
                             'identity': "testuser", 'scan_freq': '2412' },
                           signature='sv')
    netw1 = iface.AddNetwork(args)
    net_obj = bus.get_object(WPAS_DBUS_SERVICE, netw1)

    with alloc_fail_dbus(dev[0], 1,
                         "wpa_config_get_all;wpas_dbus_getter_network_properties",
                         "Get"):
        net_obj.Get(WPAS_DBUS_NETWORK, "Properties",
                    dbus_interface=dbus.PROPERTIES_IFACE)

    iface.RemoveAllNetworks()

    with alloc_fail_dbus(dev[0], 1,
                         "wpas_dbus_new_decompose_object_path;wpas_dbus_handler_remove_network",
                         "RemoveNetwork", "InvalidArgs"):
        iface.RemoveNetwork(dbus.ObjectPath("/fi/w1/wpa_supplicant1/Interfaces/1234/Networks/1234"))

    with alloc_fail(dev[0], 1, "wpa_dbus_register_object_per_iface;wpas_dbus_register_network"):
        args = dbus.Dictionary({ 'ssid': "foo2", 'key_mgmt': 'NONE' },
                               signature='sv')
        try:
            netw = iface.AddNetwork(args)
            # Currently, AddNetwork() succeeds even if os_strdup() for path
            # fails, so remove the network if that occurs.
            iface.RemoveNetwork(netw)
        except dbus.exceptions.DBusException, e:
            pass

    for i in range(1, 3):
        with alloc_fail(dev[0], i, "=wpas_dbus_register_network"):
            try:
                netw = iface.AddNetwork(args)
                # Currently, AddNetwork() succeeds even if network registration
                # fails, so remove the network if that occurs.
                iface.RemoveNetwork(netw)
            except dbus.exceptions.DBusException, e:
                pass

    with alloc_fail_dbus(dev[0], 1,
                         "=wpa_config_add_network;wpas_dbus_handler_add_network",
                         "AddNetwork",
                         "UnknownError: wpa_supplicant could not add a network"):
        args = dbus.Dictionary({ 'ssid': "foo2", 'key_mgmt': 'NONE' },
                               signature='sv')
        netw = iface.AddNetwork(args)

    tests = [ (1,
               'wpa_dbus_dict_get_entry;set_network_properties;wpas_dbus_handler_add_network',
               dbus.Dictionary({ 'ssid': dbus.ByteArray(' ') },
                               signature='sv')),
              (1, '=set_network_properties;wpas_dbus_handler_add_network',
               dbus.Dictionary({ 'ssid': 'foo' }, signature='sv')),
              (1, '=set_network_properties;wpas_dbus_handler_add_network',
               dbus.Dictionary({ 'eap': 'foo' }, signature='sv')),
              (1, '=set_network_properties;wpas_dbus_handler_add_network',
               dbus.Dictionary({ 'priority': dbus.UInt32(1) },
                               signature='sv')),
              (1, '=set_network_properties;wpas_dbus_handler_add_network',
               dbus.Dictionary({ 'priority': dbus.Int32(1) },
                               signature='sv')),
              (1, '=set_network_properties;wpas_dbus_handler_add_network',
               dbus.Dictionary({ 'ssid': dbus.ByteArray(' ') },
                               signature='sv')) ]
    for (count,funcs,args) in tests:
        with alloc_fail_dbus(dev[0], count, funcs, "AddNetwork", "InvalidArgs"):
            netw = iface.AddNetwork(args)

    if len(if_obj.Get(WPAS_DBUS_IFACE, 'Networks',
                      dbus_interface=dbus.PROPERTIES_IFACE)) > 0:
        raise Exception("Unexpected network block added")
    if len(dev[0].list_networks()) > 0:
        raise Exception("Unexpected network block visible")

def test_dbus_interface(dev, apdev):
    """D-Bus CreateInterface/GetInterface/RemoveInterface parameters and error cases"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE)

    params = dbus.Dictionary({ 'Ifname': 'lo', 'Driver': 'none' },
                             signature='sv')
    path = wpas.CreateInterface(params)
    logger.debug("New interface path: " + str(path))
    path2 = wpas.GetInterface("lo")
    if path != path2:
        raise Exception("Interface object mismatch")

    params = dbus.Dictionary({ 'Ifname': 'lo',
                               'Driver': 'none',
                               'ConfigFile': 'foo',
                               'BridgeIfname': 'foo', },
                             signature='sv')
    try:
        wpas.CreateInterface(params)
        raise Exception("Invalid CreateInterface() accepted")
    except dbus.exceptions.DBusException, e:
        if "InterfaceExists" not in str(e):
            raise Exception("Unexpected error message for invalid CreateInterface: " + str(e))

    wpas.RemoveInterface(path)
    try:
        wpas.RemoveInterface(path)
        raise Exception("Invalid RemoveInterface() accepted")
    except dbus.exceptions.DBusException, e:
        if "InterfaceUnknown" not in str(e):
            raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e))

    params = dbus.Dictionary({ 'Ifname': 'lo', 'Driver': 'none',
                               'Foo': 123 },
                             signature='sv')
    try:
        wpas.CreateInterface(params)
        raise Exception("Invalid CreateInterface() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid CreateInterface: " + str(e))

    params = dbus.Dictionary({ 'Driver': 'none' }, signature='sv')
    try:
        wpas.CreateInterface(params)
        raise Exception("Invalid CreateInterface() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid CreateInterface: " + str(e))

    try:
        wpas.GetInterface("lo")
        raise Exception("Invalid GetInterface() accepted")
    except dbus.exceptions.DBusException, e:
        if "InterfaceUnknown" not in str(e):
            raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e))

def test_dbus_interface_oom(dev, apdev):
    """D-Bus CreateInterface/GetInterface/RemoveInterface OOM error cases"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE)

    with alloc_fail_dbus(dev[0], 1, "wpa_dbus_dict_get_entry;wpas_dbus_handler_create_interface", "CreateInterface", "InvalidArgs"):
        params = dbus.Dictionary({ 'Ifname': 'lo', 'Driver': 'none' },
                                 signature='sv')
        wpas.CreateInterface(params)

    for i in range(1, 1000):
        dev[0].request("TEST_ALLOC_FAIL %d:wpa_supplicant_add_iface;wpas_dbus_handler_create_interface" % i)
        params = dbus.Dictionary({ 'Ifname': 'lo', 'Driver': 'none' },
                                 signature='sv')
        try:
            npath = wpas.CreateInterface(params)
            wpas.RemoveInterface(npath)
            logger.info("CreateInterface succeeds after %d allocation failures" % i)
            state = dev[0].request('GET_ALLOC_FAIL')
            logger.info("GET_ALLOC_FAIL: " + state)
            dev[0].dump_monitor()
            dev[0].request("TEST_ALLOC_FAIL 0:")
            if i < 5:
                raise Exception("CreateInterface succeeded during out-of-memory")
            if not state.startswith('0:'):
                break
        except dbus.exceptions.DBusException, e:
            pass

    for arg in [ 'Driver', 'Ifname', 'ConfigFile', 'BridgeIfname' ]:
        with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_handler_create_interface",
                             "CreateInterface"):
            params = dbus.Dictionary({ arg: 'foo' }, signature='sv')
            wpas.CreateInterface(params)

def test_dbus_blob(dev, apdev):
    """D-Bus AddNetwork/RemoveNetwork parameters and error cases"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    blob = dbus.ByteArray("\x01\x02\x03")
    iface.AddBlob('blob1', blob)
    try:
        iface.AddBlob('blob1', dbus.ByteArray("\x01\x02\x04"))
        raise Exception("Invalid AddBlob() accepted")
    except dbus.exceptions.DBusException, e:
        if "BlobExists" not in str(e):
            raise Exception("Unexpected error message for invalid AddBlob: " + str(e))
    res = iface.GetBlob('blob1')
    if len(res) != len(blob):
        raise Exception("Unexpected blob data length")
    for i in range(len(res)):
        if res[i] != dbus.Byte(blob[i]):
            raise Exception("Unexpected blob data")
    res = if_obj.Get(WPAS_DBUS_IFACE, "Blobs",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if 'blob1' not in res:
        raise Exception("Added blob missing from Blobs property")
    iface.RemoveBlob('blob1')
    try:
        iface.RemoveBlob('blob1')
        raise Exception("Invalid RemoveBlob() accepted")
    except dbus.exceptions.DBusException, e:
        if "BlobUnknown" not in str(e):
            raise Exception("Unexpected error message for invalid RemoveBlob: " + str(e))
    try:
        iface.GetBlob('blob1')
        raise Exception("Invalid GetBlob() accepted")
    except dbus.exceptions.DBusException, e:
        if "BlobUnknown" not in str(e):
            raise Exception("Unexpected error message for invalid GetBlob: " + str(e))

    class TestDbusBlob(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.blob_added = False
            self.blob_removed = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_blob)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.blobAdded, WPAS_DBUS_IFACE, "BlobAdded")
            self.add_signal(self.blobRemoved, WPAS_DBUS_IFACE, "BlobRemoved")
            self.loop.run()
            return self

        def blobAdded(self, blobName):
            logger.debug("blobAdded: %s" % blobName)
            if blobName == 'blob2':
                self.blob_added = True

        def blobRemoved(self, blobName):
            logger.debug("blobRemoved: %s" % blobName)
            if blobName == 'blob2':
                self.blob_removed = True
                self.loop.quit()

        def run_blob(self, *args):
            logger.debug("run_blob")
            iface.AddBlob('blob2', dbus.ByteArray("\x01\x02\x04"))
            iface.RemoveBlob('blob2')
            return False

        def success(self):
            return self.blob_added and self.blob_removed

    with TestDbusBlob(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_blob_oom(dev, apdev):
    """D-Bus AddNetwork/RemoveNetwork OOM error cases"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    for i in range(1, 4):
        with alloc_fail_dbus(dev[0], i, "wpas_dbus_handler_add_blob",
                             "AddBlob"):
            iface.AddBlob('blob_no_mem', dbus.ByteArray("\x01\x02\x03\x04"))

def test_dbus_autoscan(dev, apdev):
    """D-Bus Autoscan()"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    iface.AutoScan("foo")
    iface.AutoScan("periodic:1")
    iface.AutoScan("")
    dev[0].request("AUTOSCAN ")

def test_dbus_autoscan_oom(dev, apdev):
    """D-Bus Autoscan() OOM"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    with alloc_fail_dbus(dev[0], 1, "wpas_dbus_handler_autoscan", "AutoScan"):
        iface.AutoScan("foo")
    dev[0].request("AUTOSCAN ")

def test_dbus_tdls_invalid(dev, apdev):
    """D-Bus invalid TDLS operations"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-open" })
    connect_2sta_open(dev, hapd)
    addr1 = dev[1].p2p_interface_addr()

    try:
        iface.TDLSDiscover("foo")
        raise Exception("Invalid TDLSDiscover() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid TDLSDiscover: " + str(e))

    try:
        iface.TDLSStatus("foo")
        raise Exception("Invalid TDLSStatus() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid TDLSStatus: " + str(e))

    res = iface.TDLSStatus(addr1)
    if res != "peer does not exist":
        raise Exception("Unexpected TDLSStatus response")

    try:
        iface.TDLSSetup("foo")
        raise Exception("Invalid TDLSSetup() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid TDLSSetup: " + str(e))

    try:
        iface.TDLSTeardown("foo")
        raise Exception("Invalid TDLSTeardown() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid TDLSTeardown: " + str(e))

    try:
        iface.TDLSTeardown("00:11:22:33:44:55")
        raise Exception("TDLSTeardown accepted for unknown peer")
    except dbus.exceptions.DBusException, e:
        if "UnknownError: error performing TDLS teardown" not in str(e):
            raise Exception("Unexpected error message: " + str(e))

def test_dbus_tdls_oom(dev, apdev):
    """D-Bus TDLS operations during OOM"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    with alloc_fail_dbus(dev[0], 1, "wpa_tdls_add_peer", "TDLSSetup",
                         "UnknownError: error performing TDLS setup"):
        iface.TDLSSetup("00:11:22:33:44:55")

def test_dbus_tdls(dev, apdev):
    """D-Bus TDLS"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-open" })
    connect_2sta_open(dev, hapd)

    addr1 = dev[1].p2p_interface_addr()

    class TestDbusTdls(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.tdls_setup = False
            self.tdls_teardown = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_tdls)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def propertiesChanged(self, properties):
            logger.debug("propertiesChanged: %s" % str(properties))

        def run_tdls(self, *args):
            logger.debug("run_tdls")
            iface.TDLSDiscover(addr1)
            gobject.timeout_add(100, self.run_tdls2)
            return False

        def run_tdls2(self, *args):
            logger.debug("run_tdls2")
            iface.TDLSSetup(addr1)
            gobject.timeout_add(500, self.run_tdls3)
            return False

        def run_tdls3(self, *args):
            logger.debug("run_tdls3")
            res = iface.TDLSStatus(addr1)
            if res == "connected":
                self.tdls_setup = True
            else:
                logger.info("Unexpected TDLSStatus: " + res)
            iface.TDLSTeardown(addr1)
            gobject.timeout_add(200, self.run_tdls4)
            return False

        def run_tdls4(self, *args):
            logger.debug("run_tdls4")
            res = iface.TDLSStatus(addr1)
            if res == "peer does not exist":
                self.tdls_teardown = True
            else:
                logger.info("Unexpected TDLSStatus: " + res)
            self.loop.quit()
            return False

        def success(self):
            return self.tdls_setup and self.tdls_teardown

    with TestDbusTdls(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_pkcs11(dev, apdev):
    """D-Bus SetPKCS11EngineAndModulePath()"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    try:
        iface.SetPKCS11EngineAndModulePath("foo", "bar")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: Reinit of the EAPOL" not in str(e):
            raise Exception("Unexpected error message for invalid SetPKCS11EngineAndModulePath: " + str(e))

    try:
        iface.SetPKCS11EngineAndModulePath("foo", "")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: Reinit of the EAPOL" not in str(e):
            raise Exception("Unexpected error message for invalid SetPKCS11EngineAndModulePath: " + str(e))

    iface.SetPKCS11EngineAndModulePath("", "bar")
    res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11EnginePath",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != "":
        raise Exception("Unexpected PKCS11EnginePath value: " + res)
    res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11ModulePath",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != "bar":
        raise Exception("Unexpected PKCS11ModulePath value: " + res)

    iface.SetPKCS11EngineAndModulePath("", "")
    res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11EnginePath",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != "":
        raise Exception("Unexpected PKCS11EnginePath value: " + res)
    res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11ModulePath",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != "":
        raise Exception("Unexpected PKCS11ModulePath value: " + res)

def test_dbus_apscan(dev, apdev):
    """D-Bus Get/Set ApScan"""
    try:
        _test_dbus_apscan(dev, apdev)
    finally:
        dev[0].request("AP_SCAN 1")

def _test_dbus_apscan(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    res = if_obj.Get(WPAS_DBUS_IFACE, "ApScan",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != 1:
        raise Exception("Unexpected initial ApScan value: %d" % res)

    for i in range(3):
        if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(i),
                     dbus_interface=dbus.PROPERTIES_IFACE)
        res = if_obj.Get(WPAS_DBUS_IFACE, "ApScan",
                         dbus_interface=dbus.PROPERTIES_IFACE)
        if res != i:
            raise Exception("Unexpected ApScan value %d (expected %d)" % (res, i))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.Int16(-1),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(ApScan,-1) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message for invalid Set(ApScan,-1): " + str(e))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(123),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(ApScan,123) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: ap_scan must be 0, 1, or 2" not in str(e):
            raise Exception("Unexpected error message for invalid Set(ApScan,123): " + str(e))

    if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(1),
               dbus_interface=dbus.PROPERTIES_IFACE)

def test_dbus_fastreauth(dev, apdev):
    """D-Bus Get/Set FastReauth"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    res = if_obj.Get(WPAS_DBUS_IFACE, "FastReauth",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != True:
        raise Exception("Unexpected initial FastReauth value: " + str(res))

    for i in [ False, True ]:
        if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Boolean(i),
                     dbus_interface=dbus.PROPERTIES_IFACE)
        res = if_obj.Get(WPAS_DBUS_IFACE, "FastReauth",
                         dbus_interface=dbus.PROPERTIES_IFACE)
        if res != i:
            raise Exception("Unexpected FastReauth value %d (expected %d)" % (res, i))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Int16(-1),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(FastReauth,-1) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message for invalid Set(ApScan,-1): " + str(e))

    if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Boolean(True),
               dbus_interface=dbus.PROPERTIES_IFACE)

def test_dbus_bss_expire(dev, apdev):
    """D-Bus Get/Set BSSExpireAge and BSSExpireCount"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(179),
               dbus_interface=dbus.PROPERTIES_IFACE)
    res = if_obj.Get(WPAS_DBUS_IFACE, "BSSExpireAge",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != 179:
        raise Exception("Unexpected BSSExpireAge value %d (expected %d)" % (res, i))

    if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(3),
               dbus_interface=dbus.PROPERTIES_IFACE)
    res = if_obj.Get(WPAS_DBUS_IFACE, "BSSExpireCount",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != 3:
        raise Exception("Unexpected BSSExpireCount value %d (expected %d)" % (res, i))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.Int16(-1),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(BSSExpireAge,-1) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message for invalid Set(BSSExpireAge,-1): " + str(e))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(9),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(BSSExpireAge,9) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: BSSExpireAge must be >= 10" not in str(e):
            raise Exception("Unexpected error message for invalid Set(BSSExpireAge,9): " + str(e))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.Int16(-1),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(BSSExpireCount,-1) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message for invalid Set(BSSExpireCount,-1): " + str(e))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(0),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(BSSExpireCount,0) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: BSSExpireCount must be > 0" not in str(e):
            raise Exception("Unexpected error message for invalid Set(BSSExpireCount,0): " + str(e))

    if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(180),
               dbus_interface=dbus.PROPERTIES_IFACE)
    if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(2),
               dbus_interface=dbus.PROPERTIES_IFACE)

def test_dbus_country(dev, apdev):
    """D-Bus Get/Set Country"""
    try:
        _test_dbus_country(dev, apdev)
    finally:
        dev[0].request("SET country 00")
        subprocess.call(['iw', 'reg', 'set', '00'])

def _test_dbus_country(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    # work around issues with possible pending regdom event from the end of
    # the previous test case
    time.sleep(0.2)
    dev[0].dump_monitor()

    if_obj.Set(WPAS_DBUS_IFACE, "Country", "FI",
               dbus_interface=dbus.PROPERTIES_IFACE)
    res = if_obj.Get(WPAS_DBUS_IFACE, "Country",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != "FI":
        raise Exception("Unexpected Country value %s (expected FI)" % res)

    ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"])
    if ev is None:
        # For now, work around separate P2P Device interface event delivery
        ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
        if ev is None:
            raise Exception("regdom change event not seen")
    if "init=USER type=COUNTRY alpha2=FI" not in ev:
        raise Exception("Unexpected event contents: " + ev)

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "Country", dbus.Int16(-1),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(Country,-1) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message for invalid Set(Country,-1): " + str(e))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "Country", "F",
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(Country,F) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: invalid country code" not in str(e):
            raise Exception("Unexpected error message for invalid Set(Country,F): " + str(e))

    if_obj.Set(WPAS_DBUS_IFACE, "Country", "00",
               dbus_interface=dbus.PROPERTIES_IFACE)

    ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"])
    if ev is None:
        # For now, work around separate P2P Device interface event delivery
        ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
        if ev is None:
            raise Exception("regdom change event not seen")
    if "init=CORE type=WORLD" not in ev:
        raise Exception("Unexpected event contents: " + ev)

def test_dbus_scan_interval(dev, apdev):
    """D-Bus Get/Set ScanInterval"""
    try:
        _test_dbus_scan_interval(dev, apdev)
    finally:
        dev[0].request("SCAN_INTERVAL 5")

def _test_dbus_scan_interval(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(3),
               dbus_interface=dbus.PROPERTIES_IFACE)
    res = if_obj.Get(WPAS_DBUS_IFACE, "ScanInterval",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if res != 3:
        raise Exception("Unexpected ScanInterval value %d (expected %d)" % (res, i))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.UInt16(100),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(ScanInterval,100) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: wrong property type" not in str(e):
            raise Exception("Unexpected error message for invalid Set(ScanInterval,100): " + str(e))

    try:
        if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(-1),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(ScanInterval,-1) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: scan_interval must be >= 0" not in str(e):
            raise Exception("Unexpected error message for invalid Set(ScanInterval,-1): " + str(e))

    if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(5),
               dbus_interface=dbus.PROPERTIES_IFACE)

def test_dbus_probe_req_reporting(dev, apdev):
    """D-Bus Probe Request reporting"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    dev[1].p2p_find(social=True)

    class TestDbusProbe(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.reported = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.probeRequest, WPAS_DBUS_IFACE, "ProbeRequest",
                            byte_arrays=True)
            self.loop.run()
            return self

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            self.iface = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE)
            self.iface.SubscribeProbeReq()
            self.group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

        def probeRequest(self, args):
            logger.debug("probeRequest: args=%s" % str(args))
            self.reported = True
            self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
            params = dbus.Dictionary({ 'frequency': 2412 })
            p2p.GroupAdd(params)
            return False

        def success(self):
            return self.reported

    with TestDbusProbe(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")
        t.iface.UnsubscribeProbeReq()
        try:
            t.iface.UnsubscribeProbeReq()
            raise Exception("Invalid UnsubscribeProbeReq() accepted")
        except dbus.exceptions.DBusException, e:
            if "NoSubscription" not in str(e):
                raise Exception("Unexpected error message for invalid UnsubscribeProbeReq(): " + str(e))
        t.group_p2p.Disconnect()

    with TestDbusProbe(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")
        # On purpose, leave ProbeReq subscription in place to test automatic
        # cleanup.

    dev[1].p2p_stop_find()

def test_dbus_probe_req_reporting_oom(dev, apdev):
    """D-Bus Probe Request reporting (OOM)"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    # Need to make sure this process has not already subscribed to avoid false
    # failures due to the operation succeeding due to os_strdup() not even
    # getting called.
    try:
        iface.UnsubscribeProbeReq()
        was_subscribed = True
    except dbus.exceptions.DBusException, e:
        was_subscribed = False
        pass

    with alloc_fail_dbus(dev[0], 1, "wpas_dbus_handler_subscribe_preq",
                         "SubscribeProbeReq"):
        iface.SubscribeProbeReq()

    if was_subscribed:
        # On purpose, leave ProbeReq subscription in place to test automatic
        # cleanup.
        iface.SubscribeProbeReq()

def test_dbus_p2p_invalid(dev, apdev):
    """D-Bus invalid P2P operations"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    try:
        p2p.RejectPeer(path + "/Peers/00112233445566")
        raise Exception("Invalid RejectPeer accepted")
    except dbus.exceptions.DBusException, e:
        if "UnknownError: Failed to call wpas_p2p_reject" not in str(e):
            raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e))

    try:
        p2p.RejectPeer("/foo")
        raise Exception("Invalid RejectPeer accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e))

    tests = [ { },
              { 'peer': 'foo' },
              { 'foo': "bar" },
              { 'iface': "abc" },
              { 'iface': 123 } ]
    for t in tests:
        try:
            p2p.RemoveClient(t)
            raise Exception("Invalid RemoveClient accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid RemoveClient(): " + str(e))

    tests = [ {'DiscoveryType': 'foo'},
              {'RequestedDeviceTypes': 'foo'},
              {'RequestedDeviceTypes': ['foo']},
              {'RequestedDeviceTypes': ['1','2','3','4','5','6','7','8','9',
                                        '10','11','12','13','14','15','16',
                                        '17']},
              {'RequestedDeviceTypes': dbus.Array([], signature="s")},
              {'RequestedDeviceTypes': dbus.Array([['foo']], signature="as")},
              {'RequestedDeviceTypes': dbus.Array([], signature="i")},
              {'RequestedDeviceTypes': [dbus.ByteArray('12345678'),
                                        dbus.ByteArray('1234567')]},
              {'Foo': dbus.Int16(1)},
              {'Foo': dbus.UInt16(1)},
              {'Foo': dbus.Int64(1)},
              {'Foo': dbus.UInt64(1)},
              {'Foo': dbus.Double(1.23)},
              {'Foo': dbus.Signature('s')},
              {'Foo': 'bar'}]
    for t in tests:
        try:
            p2p.Find(dbus.Dictionary(t))
            raise Exception("Invalid Find accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid Find(): " + str(e))

    for p in [ "/foo",
               "/fi/w1/wpa_supplicant1/Interfaces/1234",
               "/fi/w1/wpa_supplicant1/Interfaces/1234/Networks/1234" ]:
        try:
            p2p.RemovePersistentGroup(dbus.ObjectPath(p))
            raise Exception("Invalid RemovePersistentGroup accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid RemovePersistentGroup: " + str(e))

    try:
        dev[0].request("P2P_SET disabled 1")
        p2p.Listen(5)
        raise Exception("Invalid Listen accepted")
    except dbus.exceptions.DBusException, e:
        if "UnknownError: Could not start P2P listen" not in str(e):
            raise Exception("Unexpected error message for invalid Listen: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    test_obj = bus.get_object(WPAS_DBUS_SERVICE, path, introspect=False)
    test_p2p = dbus.Interface(test_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    try:
        test_p2p.Listen("foo")
        raise Exception("Invalid Listen accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid Listen: " + str(e))

    try:
        dev[0].request("P2P_SET disabled 1")
        p2p.ExtendedListen(dbus.Dictionary({}))
        raise Exception("Invalid ExtendedListen accepted")
    except dbus.exceptions.DBusException, e:
        if "UnknownError: failed to initiate a p2p_ext_listen" not in str(e):
            raise Exception("Unexpected error message for invalid ExtendedListen: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    try:
        dev[0].request("P2P_SET disabled 1")
        args = { 'duration1': 30000, 'interval1': 102400,
                 'duration2': 20000, 'interval2': 102400 }
        p2p.PresenceRequest(args)
        raise Exception("Invalid PresenceRequest accepted")
    except dbus.exceptions.DBusException, e:
        if "UnknownError: Failed to invoke presence request" not in str(e):
            raise Exception("Unexpected error message for invalid PresenceRequest: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    try:
        params = dbus.Dictionary({'frequency': dbus.Int32(-1)})
        p2p.GroupAdd(params)
        raise Exception("Invalid GroupAdd accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid GroupAdd: " + str(e))

    try:
        params = dbus.Dictionary({'persistent_group_object':
                                  dbus.ObjectPath(path),
                                  'frequency': 2412})
        p2p.GroupAdd(params)
        raise Exception("Invalid GroupAdd accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid GroupAdd: " + str(e))

    try:
        p2p.Disconnect()
        raise Exception("Invalid Disconnect accepted")
    except dbus.exceptions.DBusException, e:
        if "UnknownError: failed to disconnect" not in str(e):
            raise Exception("Unexpected error message for invalid Disconnect: " + str(e))

    try:
        dev[0].request("P2P_SET disabled 1")
        p2p.Flush()
        raise Exception("Invalid Flush accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: P2P is not available for this interface" not in str(e):
            raise Exception("Unexpected error message for invalid Flush: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    try:
        dev[0].request("P2P_SET disabled 1")
        args = { 'peer': path,
                 'join': True,
                 'wps_method': 'pbc',
                 'frequency': 2412 }
        pin = p2p.Connect(args)
        raise Exception("Invalid Connect accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: P2P is not available for this interface" not in str(e):
            raise Exception("Unexpected error message for invalid Connect: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    tests = [ { 'frequency': dbus.Int32(-1) },
              { 'wps_method': 'pbc' },
              { 'wps_method': 'foo' } ]
    for args in tests:
        try:
            pin = p2p.Connect(args)
            raise Exception("Invalid Connect accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid Connect: " + str(e))

    try:
        dev[0].request("P2P_SET disabled 1")
        args = { 'peer': path }
        pin = p2p.Invite(args)
        raise Exception("Invalid Invite accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: P2P is not available for this interface" not in str(e):
            raise Exception("Unexpected error message for invalid Invite: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    try:
        args = { 'foo': 'bar' }
        pin = p2p.Invite(args)
        raise Exception("Invalid Invite accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid Connect: " + str(e))

    tests = [ (path, 'display', "InvalidArgs"),
              (dbus.ObjectPath(path + "/Peers/00112233445566"),
               'display',
               "UnknownError: Failed to send provision discovery request"),
              (dbus.ObjectPath(path + "/Peers/00112233445566"),
               'keypad',
               "UnknownError: Failed to send provision discovery request"),
              (dbus.ObjectPath(path + "/Peers/00112233445566"),
               'pbc',
               "UnknownError: Failed to send provision discovery request"),
              (dbus.ObjectPath(path + "/Peers/00112233445566"),
               'pushbutton',
               "UnknownError: Failed to send provision discovery request"),
              (dbus.ObjectPath(path + "/Peers/00112233445566"),
               'foo', "InvalidArgs") ]
    for (p,method,err) in tests:
        try:
            p2p.ProvisionDiscoveryRequest(p, method)
            raise Exception("Invalid ProvisionDiscoveryRequest accepted")
        except dbus.exceptions.DBusException, e:
            if err not in str(e):
                raise Exception("Unexpected error message for invalid ProvisionDiscoveryRequest: " + str(e))

    try:
        dev[0].request("P2P_SET disabled 1")
        if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Peers",
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Get(Peers) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: P2P is not available for this interface" not in str(e):
            raise Exception("Unexpected error message for invalid Get(Peers): " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

def test_dbus_p2p_oom(dev, apdev):
    """D-Bus P2P operations and OOM"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_string_array",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': [ 'bar' ] }))

    with alloc_fail_dbus(dev[0], 2, "_wpa_dbus_dict_entry_get_string_array",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': [ 'bar' ] }))

    with alloc_fail_dbus(dev[0], 10, "_wpa_dbus_dict_entry_get_string_array",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': [ '1','2','3','4','5','6','7','8','9' ] }))

    with alloc_fail_dbus(dev[0], 1, ":=_wpa_dbus_dict_entry_get_binarray",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': [ dbus.ByteArray('123') ] }))

    with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_byte_array;_wpa_dbus_dict_entry_get_binarray",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': [ dbus.ByteArray('123') ] }))

    with alloc_fail_dbus(dev[0], 2, "=_wpa_dbus_dict_entry_get_binarray",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': [ dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123'),
                                            dbus.ByteArray('123') ] }))

    with alloc_fail_dbus(dev[0], 1, "wpabuf_alloc_ext_data;_wpa_dbus_dict_entry_get_binarray",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': [ dbus.ByteArray('123') ] }))

    with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_fill_value_from_variant;wpas_dbus_handler_p2p_find",
                         "Find", "InvalidArgs"):
        p2p.Find(dbus.Dictionary({ 'Foo': path }))

    with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_byte_array",
                         "AddService", "InvalidArgs"):
        args = { 'service_type': 'bonjour',
                 'response': dbus.ByteArray(500*'b') }
        p2p.AddService(args)

    with alloc_fail_dbus(dev[0], 2, "_wpa_dbus_dict_entry_get_byte_array",
                         "AddService", "InvalidArgs"):
        p2p.AddService(args)

def test_dbus_p2p_discovery(dev, apdev):
    """D-Bus P2P discovery"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()

    dev[1].request("SET sec_device_type 1-0050F204-2")
    dev[1].request("VENDOR_ELEM_ADD 1 dd0c0050f2041049000411223344")
    dev[1].p2p_listen()
    addr1 = dev[1].p2p_dev_addr()
    a1 = binascii.unhexlify(addr1.replace(':',''))

    wfd_devinfo = "00001c440028"
    dev[2].request("SET wifi_display 1")
    dev[2].request("WFD_SUBELEM_SET 0 0006" + wfd_devinfo)
    wfd = binascii.unhexlify('000006' + wfd_devinfo)
    dev[2].p2p_listen()
    addr2 = dev[2].p2p_dev_addr()
    a2 = binascii.unhexlify(addr2.replace(':',''))

    res = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE,
                        dbus_interface=dbus.PROPERTIES_IFACE)
    if 'Peers' not in res:
        raise Exception("GetAll result missing Peers")
    if len(res['Peers']) != 0:
        raise Exception("Unexpected peer(s) in the list")

    args = {'DiscoveryType': 'social',
            'RequestedDeviceTypes': [dbus.ByteArray('12345678')],
            'Timeout': dbus.Int32(1) }
    p2p.Find(dbus.Dictionary(args))
    p2p.StopFind()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.found = False
            self.found2 = False
            self.lost = False
            self.find_stopped = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.deviceLost, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceLost")
            self.add_signal(self.provisionDiscoveryResponseEnterPin,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "ProvisionDiscoveryResponseEnterPin")
            self.add_signal(self.findStopped, WPAS_DBUS_IFACE_P2PDEVICE,
                            "FindStopped")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            res = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Peers",
                             dbus_interface=dbus.PROPERTIES_IFACE)
            if len(res) < 1:
                raise Exception("Unexpected number of peers")
            if path not in res:
                raise Exception("Mismatch in peer object path")
            peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
            res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
                                  dbus_interface=dbus.PROPERTIES_IFACE,
                                  byte_arrays=True)
            logger.debug("peer properties: " + str(res))

            if res['DeviceAddress'] == a1:
                if 'SecondaryDeviceTypes' not in res:
                    raise Exception("Missing SecondaryDeviceTypes")
                sec = res['SecondaryDeviceTypes']
                if len(sec) < 1:
                    raise Exception("Secondary device type missing")
                if "\x00\x01\x00\x50\xF2\x04\x00\x02" not in sec:
                    raise Exception("Secondary device type mismatch")

                if 'VendorExtension' not in res:
                    raise Exception("Missing VendorExtension")
                vendor = res['VendorExtension']
                if len(vendor) < 1:
                    raise Exception("Vendor extension missing")
                if "\x11\x22\x33\x44" not in vendor:
                    raise Exception("Secondary device type mismatch")

                self.found = True
            elif res['DeviceAddress'] == a2:
                if 'IEs' not in res:
                    raise Exception("IEs missing")
                if res['IEs'] != wfd:
                    raise Exception("IEs mismatch")
                self.found2 = True
            else:
                raise Exception("Unexpected peer device address")

            if self.found and self.found2:
                p2p.StopFind()
                p2p.RejectPeer(path)
                p2p.ProvisionDiscoveryRequest(path, 'display')

        def deviceLost(self, path):
            logger.debug("deviceLost: path=%s" % path)
            self.lost = True
            try:
                p2p.RejectPeer(path)
                raise Exception("Invalid RejectPeer accepted")
            except dbus.exceptions.DBusException, e:
                if "UnknownError: Failed to call wpas_p2p_reject" not in str(e):
                    raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e))
            self.loop.quit()

        def provisionDiscoveryResponseEnterPin(self, peer_object):
            logger.debug("provisionDiscoveryResponseEnterPin - peer=%s" % peer_object)
            p2p.Flush()

        def findStopped(self):
            logger.debug("findStopped")
            self.find_stopped = True

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social',
                                      'Timeout': dbus.Int32(10)}))
            return False

        def success(self):
            return self.found and self.lost and self.found2 and self.find_stopped

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

    dev[1].request("VENDOR_ELEM_REMOVE 1 *")
    dev[1].p2p_stop_find()

    p2p.Listen(1)
    dev[2].p2p_stop_find()
    dev[2].request("P2P_FLUSH")
    if not dev[2].discover_peer(addr0):
        raise Exception("Peer not found")
    p2p.StopFind()
    dev[2].p2p_stop_find()

    try:
        p2p.ExtendedListen(dbus.Dictionary({'foo': 100}))
        raise Exception("Invalid ExtendedListen accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid ExtendedListen(): " + str(e))

    p2p.ExtendedListen(dbus.Dictionary({'period': 100, 'interval': 1000}))
    p2p.ExtendedListen(dbus.Dictionary({}))
    dev[0].global_request("P2P_EXT_LISTEN")

def test_dbus_p2p_service_discovery(dev, apdev):
    """D-Bus P2P service discovery"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()
    addr1 = dev[1].p2p_dev_addr()

    bonjour_query = dbus.ByteArray(binascii.unhexlify('0b5f6166706f766572746370c00c000c01'))
    bonjour_response = dbus.ByteArray(binascii.unhexlify('074578616d706c65c027'))
                                   
    args = { 'service_type': 'bonjour',
             'query': bonjour_query,
             'response': bonjour_response }
    p2p.AddService(args)
    p2p.FlushService()
    p2p.AddService(args)

    try:
        p2p.DeleteService(args)
        raise Exception("Invalid DeleteService() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))

    args = { 'service_type': 'bonjour',
             'query': bonjour_query }
    p2p.DeleteService(args)
    try:
        p2p.DeleteService(args)
        raise Exception("Invalid DeleteService() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))

    args = { 'service_type': 'upnp',
             'version': 0x10,
             'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice' }
    p2p.AddService(args)
    p2p.DeleteService(args)
    try:
        p2p.DeleteService(args)
        raise Exception("Invalid DeleteService() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))

    tests = [ { 'service_type': 'foo' },
              { 'service_type': 'foo', 'query': bonjour_query },
              { 'service_type': 'upnp' },
              { 'service_type': 'upnp', 'version': 0x10 },
              { 'service_type': 'upnp',
                'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice' },
              { 'version': 0x10,
                'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice' },
              { 'service_type': 'upnp', 'foo': 'bar' },
              { 'service_type': 'bonjour' },
              { 'service_type': 'bonjour', 'query': 'foo' },
              { 'service_type': 'bonjour', 'foo': 'bar' } ]
    for args in tests:
        try:
            p2p.DeleteService(args)
            raise Exception("Invalid DeleteService() accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))

    tests = [ { 'service_type': 'foo' },
              { 'service_type': 'upnp' },
              { 'service_type': 'upnp', 'version': 0x10 },
              { 'service_type': 'upnp',
                'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice' },
              { 'version': 0x10,
                'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice' },
              { 'service_type': 'upnp', 'foo': 'bar' },
              { 'service_type': 'bonjour' },
              { 'service_type': 'bonjour', 'query': 'foo' },
              { 'service_type': 'bonjour', 'response': 'foo' },
              { 'service_type': 'bonjour', 'query': bonjour_query },
              { 'service_type': 'bonjour', 'response': bonjour_response },
              { 'service_type': 'bonjour', 'query': dbus.ByteArray(500*'a') },
              { 'service_type': 'bonjour', 'foo': 'bar' } ]
    for args in tests:
        try:
            p2p.AddService(args)
            raise Exception("Invalid AddService() accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid AddService(): " + str(e))

    args = { 'tlv': dbus.ByteArray("\x02\x00\x00\x01") }
    ref = p2p.ServiceDiscoveryRequest(args)
    p2p.ServiceDiscoveryCancelRequest(ref)
    try:
        p2p.ServiceDiscoveryCancelRequest(ref)
        raise Exception("Invalid ServiceDiscoveryCancelRequest() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid AddService(): " + str(e))
    try:
        p2p.ServiceDiscoveryCancelRequest(dbus.UInt64(0))
        raise Exception("Invalid ServiceDiscoveryCancelRequest() accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid AddService(): " + str(e))

    args = { 'service_type': 'upnp',
             'version': 0x10,
             'service': 'ssdp:foo' }
    ref = p2p.ServiceDiscoveryRequest(args)
    p2p.ServiceDiscoveryCancelRequest(ref)

    tests =  [ { 'service_type': 'foo' },
               { 'foo': 'bar' },
               { 'tlv': 'foo' },
               { },
               { 'version': 0 },
               { 'service_type': 'upnp',
                 'service': 'ssdp:foo' },
               { 'service_type': 'upnp',
                 'version': 0x10 },
               { 'service_type': 'upnp',
                 'version': 0x10,
                 'service': 'ssdp:foo',
                 'peer_object': dbus.ObjectPath(path + "/Peers") },
               { 'service_type': 'upnp',
                 'version': 0x10,
                 'service': 'ssdp:foo',
                 'peer_object': path + "/Peers" },
               { 'service_type': 'upnp',
                 'version': 0x10,
                 'service': 'ssdp:foo',
                 'peer_object': dbus.ObjectPath(path + "/Peers/00112233445566") } ]
    for args in tests:
        try:
            p2p.ServiceDiscoveryRequest(args)
            raise Exception("Invalid ServiceDiscoveryRequest accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid ServiceDiscoveryRequest(): " + str(e))

    args = { 'foo': 'bar' }
    try:
        p2p.ServiceDiscoveryResponse(dbus.Dictionary(args, signature='sv'))
        raise Exception("Invalid ServiceDiscoveryResponse accepted")
    except dbus.exceptions.DBusException, e:
        if "InvalidArgs" not in str(e):
            raise Exception("Unexpected error message for invalid ServiceDiscoveryResponse(): " + str(e))

def test_dbus_p2p_service_discovery_query(dev, apdev):
    """D-Bus P2P service discovery query"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()
    dev[1].request("P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027")
    dev[1].p2p_listen()
    addr1 = dev[1].p2p_dev_addr()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.serviceDiscoveryResponse,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "ServiceDiscoveryResponse", byte_arrays=True)
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            args = { 'peer_object': path,
                     'tlv': dbus.ByteArray("\x02\x00\x00\x01") }
            p2p.ServiceDiscoveryRequest(args)

        def serviceDiscoveryResponse(self, sd_request):
            logger.debug("serviceDiscoveryResponse: sd_request=%s" % str(sd_request))
            self.done = True
            self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social',
                                      'Timeout': dbus.Int32(10)}))
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

    dev[1].p2p_stop_find()

def test_dbus_p2p_service_discovery_external(dev, apdev):
    """D-Bus P2P service discovery with external response"""
    try:
        _test_dbus_p2p_service_discovery_external(dev, apdev)
    finally:
        dev[0].request("P2P_SERV_DISC_EXTERNAL 0")

def _test_dbus_p2p_service_discovery_external(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()
    addr1 = dev[1].p2p_dev_addr()
    resp = "0300000101"

    dev[1].request("P2P_FLUSH")
    dev[1].request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
    dev[1].p2p_find(social=True)

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.sd = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.serviceDiscoveryRequest,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "ServiceDiscoveryRequest")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)

        def serviceDiscoveryRequest(self, sd_request):
            logger.debug("serviceDiscoveryRequest: sd_request=%s" % str(sd_request))
            self.sd = True
            args = { 'peer_object': sd_request['peer_object'],
                     'frequency': sd_request['frequency'],
                     'dialog_token': sd_request['dialog_token'],
                     'tlvs': dbus.ByteArray(binascii.unhexlify(resp)) }
            p2p.ServiceDiscoveryResponse(dbus.Dictionary(args, signature='sv'))
            self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.ServiceDiscoveryExternal(1)
            p2p.ServiceUpdate()
            p2p.Listen(15)
            return False

        def success(self):
            return self.sd

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

    ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=5)
    if ev is None:
        raise Exception("Service discovery timed out")
    if addr0 not in ev:
        raise Exception("Unexpected address in SD Response: " + ev)
    if ev.split(' ')[4] != resp:
        raise Exception("Unexpected response data SD Response: " + ev)
    dev[1].p2p_stop_find()

    p2p.StopFind()
    p2p.ServiceDiscoveryExternal(0)

def test_dbus_p2p_autogo(dev, apdev):
    """D-Bus P2P autonomous GO"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.first = True
            self.waiting_end = False
            self.exceptions = False
            self.deauthorized = False
            self.done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.persistentGroupAdded,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "PersistentGroupAdded")
            self.add_signal(self.persistentGroupRemoved,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "PersistentGroupRemoved")
            self.add_signal(self.provisionDiscoveryRequestDisplayPin,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "ProvisionDiscoveryRequestDisplayPin")
            self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
                            "StaAuthorized")
            self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE,
                            "StaDeauthorized")
            self.loop.run()
            return self

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            self.group = properties['group_object']
            self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                           properties['interface_object'])
            role = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Role",
                                     dbus_interface=dbus.PROPERTIES_IFACE)
            if role != "GO":
                self.exceptions = True
                raise Exception("Unexpected role reported: " + role)
            group = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Group",
                                      dbus_interface=dbus.PROPERTIES_IFACE)
            if group != properties['group_object']:
                self.exceptions = True
                raise Exception("Unexpected Group reported: " + str(group))
            go = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PeerGO",
                                   dbus_interface=dbus.PROPERTIES_IFACE)
            if go != '/':
                self.exceptions = True
                raise Exception("Unexpected PeerGO value: " + str(go))
            if self.first:
                self.first = False
                logger.info("Remove persistent group instance")
                group_p2p = dbus.Interface(self.g_if_obj,
                                           WPAS_DBUS_IFACE_P2PDEVICE)
                group_p2p.Disconnect()
            else:
                dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
                dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 join")

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            if self.waiting_end:
                logger.info("Remove persistent group")
                p2p.RemovePersistentGroup(self.persistent)
            else:
                logger.info("Re-start persistent group")
                params = dbus.Dictionary({'persistent_group_object':
                                          self.persistent,
                                          'frequency': 2412})
                p2p.GroupAdd(params)

        def persistentGroupAdded(self, path, properties):
            logger.debug("persistentGroupAdded: %s %s" % (path, str(properties)))
            self.persistent = path

        def persistentGroupRemoved(self, path):
            logger.debug("persistentGroupRemoved: %s" % path)
            self.done = True
            self.loop.quit()

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
            self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
                                        dbus_interface=dbus.PROPERTIES_IFACE,
                                        byte_arrays=True)
            logger.debug('peer properties: ' + str(self.peer))

        def provisionDiscoveryRequestDisplayPin(self, peer_object, pin):
            logger.debug("provisionDiscoveryRequestDisplayPin - peer=%s pin=%s" % (peer_object, pin))
            self.peer_path = peer_object
            peer = binascii.unhexlify(peer_object.split('/')[-1])
            addr = ""
            for p in peer:
                if len(addr) > 0:
                    addr += ':'
                addr += '%02x' % ord(p)

            params = { 'Role': 'registrar',
                       'P2PDeviceAddress': self.peer['DeviceAddress'],
                       'Bssid': self.peer['DeviceAddress'],
                       'Type': 'pin' }
            wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS)
            try:
                wps.Start(params)
                self.exceptions = True
                raise Exception("Invalid WPS.Start() accepted")
            except dbus.exceptions.DBusException, e:
                if "InvalidArgs" not in str(e):
                    self.exceptions = True
                    raise Exception("Unexpected error message: " + str(e))
            params = { 'Role': 'registrar',
                       'P2PDeviceAddress': self.peer['DeviceAddress'],
                       'Type': 'pin',
                       'Pin': '12345670' }
            logger.info("Authorize peer to connect to the group")
            wps.Start(params)

        def staAuthorized(self, name):
            logger.debug("staAuthorized: " + name)
            peer_obj = bus.get_object(WPAS_DBUS_SERVICE, self.peer_path)
            res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
                                  dbus_interface=dbus.PROPERTIES_IFACE,
                                  byte_arrays=True)
            logger.debug("Peer properties: " + str(res))
            if 'Groups' not in res or len(res['Groups']) != 1:
                self.exceptions = True
                raise Exception("Unexpected number of peer Groups entries")
            if res['Groups'][0] != self.group:
                self.exceptions = True
                raise Exception("Unexpected peer Groups[0] value")

            g_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group)
            res = g_obj.GetAll(WPAS_DBUS_GROUP,
                               dbus_interface=dbus.PROPERTIES_IFACE,
                               byte_arrays=True)
            logger.debug("Group properties: " + str(res))
            if 'Members' not in res or len(res['Members']) != 1:
                self.exceptions = True
                raise Exception("Unexpected number of group members")

            ext = dbus.ByteArray("\x11\x22\x33\x44")
            # Earlier implementation of this interface was a bit strange. The
            # property is defined to have aay signature and that is what the
            # getter returned. However, the setter expected there to be a
            # dictionary with 'WPSVendorExtensions' as the key surrounding these
            # values.. The current implementations maintains support for that
            # for backwards compability reasons. Verify that encoding first.
            vals = dbus.Dictionary({ 'WPSVendorExtensions': [ ext ]},
                                   signature='sv')
            g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
                      dbus_interface=dbus.PROPERTIES_IFACE)
            res = g_obj.Get(WPAS_DBUS_GROUP, 'WPSVendorExtensions',
                               dbus_interface=dbus.PROPERTIES_IFACE,
                               byte_arrays=True)
            if len(res) != 1:
                self.exceptions = True
                raise Exception("Unexpected number of vendor extensions")
            if res[0] != ext:
                self.exceptions = True
                raise Exception("Vendor extension value changed")

            # And now verify that the more appropriate encoding is accepted as
            # well.
            res.append(dbus.ByteArray('\xaa\xbb\xcc\xdd\xee\xff'))
            g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res,
                      dbus_interface=dbus.PROPERTIES_IFACE)
            res2 = g_obj.Get(WPAS_DBUS_GROUP, 'WPSVendorExtensions',
                             dbus_interface=dbus.PROPERTIES_IFACE,
                             byte_arrays=True)
            if len(res) != 2:
                self.exceptions = True
                raise Exception("Unexpected number of vendor extensions")
            if res[0] != res2[0] or res[1] != res2[1]:
                self.exceptions = True
                raise Exception("Vendor extension value changed")

            for i in range(10):
                res.append(dbus.ByteArray('\xaa\xbb'))
            try:
                g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res,
                          dbus_interface=dbus.PROPERTIES_IFACE)
                self.exceptions = True
                raise Exception("Invalid Set(WPSVendorExtensions) accepted")
            except dbus.exceptions.DBusException, e:
                if "Error.Failed" not in str(e):
                    self.exceptions = True
                    raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))

            vals = dbus.Dictionary({ 'Foo': [ ext ]}, signature='sv')
            try:
                g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
                          dbus_interface=dbus.PROPERTIES_IFACE)
                self.exceptions = True
                raise Exception("Invalid Set(WPSVendorExtensions) accepted")
            except dbus.exceptions.DBusException, e:
                if "InvalidArgs" not in str(e):
                    self.exceptions = True
                    raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))

            vals = [ "foo" ]
            try:
                g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
                          dbus_interface=dbus.PROPERTIES_IFACE)
                self.exceptions = True
                raise Exception("Invalid Set(WPSVendorExtensions) accepted")
            except dbus.exceptions.DBusException, e:
                if "Error.Failed" not in str(e):
                    self.exceptions = True
                    raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))

            vals = [ [ "foo" ] ]
            try:
                g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
                          dbus_interface=dbus.PROPERTIES_IFACE)
                self.exceptions = True
                raise Exception("Invalid Set(WPSVendorExtensions) accepted")
            except dbus.exceptions.DBusException, e:
                if "Error.Failed" not in str(e):
                    self.exceptions = True
                    raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))

            p2p.RemoveClient({ 'peer': self.peer_path })

            self.waiting_end = True
            group_p2p = dbus.Interface(self.g_if_obj,
                                       WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()

        def staDeauthorized(self, name):
            logger.debug("staDeauthorized: " + name)
            self.deauthorized = True

        def run_test(self, *args):
            logger.debug("run_test")
            params = dbus.Dictionary({'persistent': True,
                                      'frequency': 2412})
            logger.info("Add a persistent group")
            p2p.GroupAdd(params)
            return False

        def success(self):
            return self.done and self.deauthorized and not self.exceptions

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

    dev[1].wait_go_ending_session()

def test_dbus_p2p_autogo_pbc(dev, apdev):
    """D-Bus P2P autonomous GO and PBC"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.first = True
            self.waiting_end = False
            self.done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.provisionDiscoveryPBCRequest,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "ProvisionDiscoveryPBCRequest")
            self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
                            "StaAuthorized")
            self.loop.run()
            return self

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            self.group = properties['group_object']
            self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                           properties['interface_object'])
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.global_request("P2P_CONNECT " + addr0 + " pbc join")

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True
            self.loop.quit()

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
            self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
                                        dbus_interface=dbus.PROPERTIES_IFACE,
                                        byte_arrays=True)
            logger.debug('peer properties: ' + str(self.peer))

        def provisionDiscoveryPBCRequest(self, peer_object):
            logger.debug("provisionDiscoveryPBCRequest - peer=%s" % peer_object)
            self.peer_path = peer_object
            peer = binascii.unhexlify(peer_object.split('/')[-1])
            addr = ""
            for p in peer:
                if len(addr) > 0:
                    addr += ':'
                addr += '%02x' % ord(p)
            params = { 'Role': 'registrar',
                       'P2PDeviceAddress': self.peer['DeviceAddress'],
                       'Type': 'pbc' }
            logger.info("Authorize peer to connect to the group")
            wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS)
            wps.Start(params)

        def staAuthorized(self, name):
            logger.debug("staAuthorized: " + name)
            group_p2p = dbus.Interface(self.g_if_obj,
                                       WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()

        def run_test(self, *args):
            logger.debug("run_test")
            params = dbus.Dictionary({'frequency': 2412})
            p2p.GroupAdd(params)
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

    dev[1].wait_go_ending_session()
    dev[1].flush_scan_cache()

def test_dbus_p2p_autogo_legacy(dev, apdev):
    """D-Bus P2P autonomous GO and legacy STA"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
                            "StaAuthorized")
            self.loop.run()
            return self

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                   properties['group_object'])
            res = g_obj.GetAll(WPAS_DBUS_GROUP,
                               dbus_interface=dbus.PROPERTIES_IFACE,
                               byte_arrays=True)
            bssid = ':'.join([binascii.hexlify(l) for l in res['BSSID']])

            pin = '12345670'
            params = { 'Role': 'enrollee',
                       'Type': 'pin',
                       'Pin': pin }
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            wps = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_WPS)
            wps.Start(params)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.scan_for_bss(bssid, freq=2412)
            dev1.request("WPS_PIN " + bssid + " " + pin)
            self.group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True
            self.loop.quit()

        def staAuthorized(self, name):
            logger.debug("staAuthorized: " + name)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.request("DISCONNECT")
            self.group_p2p.Disconnect()

        def run_test(self, *args):
            logger.debug("run_test")
            params = dbus.Dictionary({'frequency': 2412})
            p2p.GroupAdd(params)
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_join(dev, apdev):
    """D-Bus P2P join an autonomous GO"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr1 = dev[1].p2p_dev_addr()
    addr2 = dev[2].p2p_dev_addr()
    dev[1].p2p_start_go(freq=2412)
    dev1_group_ifname = dev[1].group_ifname
    dev[2].p2p_listen()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False
            self.peer = None
            self.go = None

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.invitationResult, WPAS_DBUS_IFACE_P2PDEVICE,
                            "InvitationResult")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
            res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
                                  dbus_interface=dbus.PROPERTIES_IFACE,
                                  byte_arrays=True)
            logger.debug('peer properties: ' + str(res))
            if addr2.replace(':','') in path:
                self.peer = path
            elif addr1.replace(':','') in path:
                self.go = path
            if self.peer and self.go:
                logger.info("Join the group")
                p2p.StopFind()
                args = { 'peer': self.go,
                         'join': True,
                         'wps_method': 'pin',
                         'frequency': 2412 }
                pin = p2p.Connect(args)

                dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
                dev1.group_ifname = dev1_group_ifname
                dev1.group_request("WPS_PIN any " + pin)

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            role = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Role",
                                dbus_interface=dbus.PROPERTIES_IFACE)
            if role != "client":
                raise Exception("Unexpected role reported: " + role)
            group = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Group",
                                 dbus_interface=dbus.PROPERTIES_IFACE)
            if group != properties['group_object']:
                raise Exception("Unexpected Group reported: " + str(group))
            go = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PeerGO",
                              dbus_interface=dbus.PROPERTIES_IFACE)
            if go != self.go:
                raise Exception("Unexpected PeerGO value: " + str(go))

            g_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                   properties['group_object'])
            res = g_obj.GetAll(WPAS_DBUS_GROUP,
                               dbus_interface=dbus.PROPERTIES_IFACE,
                               byte_arrays=True)
            logger.debug("Group properties: " + str(res))

            ext = dbus.ByteArray("\x11\x22\x33\x44")
            try:
                # Set(WPSVendorExtensions) not allowed for P2P Client
                g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res,
                          dbus_interface=dbus.PROPERTIES_IFACE)
                raise Exception("Invalid Set(WPSVendorExtensions) accepted")
            except dbus.exceptions.DBusException, e:
                if "Error.Failed: Failed to set property" not in str(e):
                    raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))

            group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
            args = { 'duration1': 30000, 'interval1': 102400,
                     'duration2': 20000, 'interval2': 102400 }
            group_p2p.PresenceRequest(args)

            args = { 'peer': self.peer }
            group_p2p.Invite(args)

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True
            self.loop.quit()

        def invitationResult(self, result):
            logger.debug("invitationResult: " + str(result))
            if result['status'] != 1:
                raise Exception("Unexpected invitation result: " + str(result))
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.group_ifname = dev1_group_ifname
            dev1.remove_group()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

    dev[2].p2p_stop_find()

def test_dbus_p2p_config(dev, apdev):
    """D-Bus Get/Set P2PDeviceConfig"""
    try:
        _test_dbus_p2p_config(dev, apdev)
    finally:
        dev[0].request("P2P_SET ssid_postfix ")

def _test_dbus_p2p_config(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    res = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
                     dbus_interface=dbus.PROPERTIES_IFACE,
                     byte_arrays=True)
    if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", res,
               dbus_interface=dbus.PROPERTIES_IFACE)
    res2 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
                      dbus_interface=dbus.PROPERTIES_IFACE,
                      byte_arrays=True)

    if len(res) != len(res2):
        raise Exception("Different number of parameters")
    for k in res:
        if res[k] != res2[k]:
            raise Exception("Parameter %s value changes" % k)

    changes = { 'SsidPostfix': 'foo',
                'VendorExtension': [ dbus.ByteArray('\x11\x22\x33\x44') ],
                'SecondaryDeviceTypes': [ dbus.ByteArray('\x11\x22\x33\x44\x55\x66\x77\x88') ]}
    if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
               dbus.Dictionary(changes, signature='sv'),
               dbus_interface=dbus.PROPERTIES_IFACE)

    res2 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
                      dbus_interface=dbus.PROPERTIES_IFACE,
                      byte_arrays=True)
    logger.debug("P2PDeviceConfig: " + str(res2))
    if 'VendorExtension' not in res2 or len(res2['VendorExtension']) != 1:
        raise Exception("VendorExtension does not match")
    if 'SecondaryDeviceTypes' not in res2 or len(res2['SecondaryDeviceTypes']) != 1:
        raise Exception("SecondaryDeviceType does not match")

    changes = { 'SsidPostfix': '',
                'VendorExtension': dbus.Array([], signature="ay"),
                'SecondaryDeviceTypes': dbus.Array([], signature="ay") }
    if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
               dbus.Dictionary(changes, signature='sv'),
               dbus_interface=dbus.PROPERTIES_IFACE)

    res3 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
                      dbus_interface=dbus.PROPERTIES_IFACE,
                      byte_arrays=True)
    logger.debug("P2PDeviceConfig: " + str(res3))
    if 'VendorExtension' in res3:
        raise Exception("VendorExtension not removed")
    if 'SecondaryDeviceTypes' in res3:
        raise Exception("SecondaryDeviceType not removed")

    try:
        dev[0].request("P2P_SET disabled 1")
        if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
                   dbus_interface=dbus.PROPERTIES_IFACE,
                   byte_arrays=True)
        raise Exception("Invalid Get(P2PDeviceConfig) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: P2P is not available for this interface" not in str(e):
            raise Exception("Unexpected error message for invalid Invite: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    try:
        dev[0].request("P2P_SET disabled 1")
        changes = { 'SsidPostfix': 'foo' }
        if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
                   dbus.Dictionary(changes, signature='sv'),
                   dbus_interface=dbus.PROPERTIES_IFACE)
        raise Exception("Invalid Set(P2PDeviceConfig) accepted")
    except dbus.exceptions.DBusException, e:
        if "Error.Failed: P2P is not available for this interface" not in str(e):
            raise Exception("Unexpected error message for invalid Invite: " + str(e))
    finally:
        dev[0].request("P2P_SET disabled 0")

    tests = [ { 'DeviceName': 123 },
              { 'SsidPostfix': 123 },
              { 'Foo': 'Bar' } ]
    for changes in tests:
        try:
            if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
                       dbus.Dictionary(changes, signature='sv'),
                       dbus_interface=dbus.PROPERTIES_IFACE)
            raise Exception("Invalid Set(P2PDeviceConfig) accepted")
        except dbus.exceptions.DBusException, e:
            if "InvalidArgs" not in str(e):
                raise Exception("Unexpected error message for invalid Invite: " + str(e))

def test_dbus_p2p_persistent(dev, apdev):
    """D-Bus P2P persistent group"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.persistentGroupAdded,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "PersistentGroupAdded")
            self.loop.run()
            return self

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.loop.quit()

        def persistentGroupAdded(self, path, properties):
            logger.debug("persistentGroupAdded: %s %s" % (path, str(properties)))
            self.persistent = path

        def run_test(self, *args):
            logger.debug("run_test")
            params = dbus.Dictionary({'persistent': True,
                                      'frequency': 2412})
            logger.info("Add a persistent group")
            p2p.GroupAdd(params)
            return False

        def success(self):
            return True

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")
        persistent = t.persistent

    p_obj = bus.get_object(WPAS_DBUS_SERVICE, persistent)
    res = p_obj.Get(WPAS_DBUS_PERSISTENT_GROUP, "Properties",
                    dbus_interface=dbus.PROPERTIES_IFACE, byte_arrays=True)
    logger.info("Persistent group Properties: " + str(res))
    vals = dbus.Dictionary({ 'ssid': 'DIRECT-foo' }, signature='sv')
    p_obj.Set(WPAS_DBUS_PERSISTENT_GROUP, "Properties", vals,
              dbus_interface=dbus.PROPERTIES_IFACE)
    res2 = p_obj.Get(WPAS_DBUS_PERSISTENT_GROUP, "Properties",
                     dbus_interface=dbus.PROPERTIES_IFACE)
    if len(res) != len(res2):
        raise Exception("Different number of parameters")
    for k in res:
        if k != 'ssid' and res[k] != res2[k]:
            raise Exception("Parameter %s value changes" % k)
    if res2['ssid'] != '"DIRECT-foo"':
        raise Exception("Unexpected ssid")

    args = dbus.Dictionary({ 'ssid': 'DIRECT-testing',
                             'psk': '1234567890' }, signature='sv')
    group = p2p.AddPersistentGroup(args)

    groups = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PersistentGroups",
                        dbus_interface=dbus.PROPERTIES_IFACE)
    if len(groups) != 2:
        raise Exception("Unexpected number of persistent groups: " + str(groups))

    p2p.RemoveAllPersistentGroups()

    groups = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PersistentGroups",
                        dbus_interface=dbus.PROPERTIES_IFACE)
    if len(groups) != 0:
        raise Exception("Unexpected number of persistent groups: " + str(groups))

    try:
        p2p.RemovePersistentGroup(persistent)
        raise Exception("Invalid RemovePersistentGroup accepted")
    except dbus.exceptions.DBusException, e:
        if "NetworkUnknown: There is no such persistent group" not in str(e):
            raise Exception("Unexpected error message for invalid RemovePersistentGroup: " + str(e))

def test_dbus_p2p_reinvoke_persistent(dev, apdev):
    """D-Bus P2P reinvoke persistent group"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    addr0 = dev[0].p2p_dev_addr()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.first = True
            self.waiting_end = False
            self.done = False
            self.invited = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.persistentGroupAdded,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "PersistentGroupAdded")
            self.add_signal(self.provisionDiscoveryRequestDisplayPin,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "ProvisionDiscoveryRequestDisplayPin")
            self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
                            "StaAuthorized")
            self.loop.run()
            return self

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                           properties['interface_object'])
            if not self.invited:
                g_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                       properties['group_object'])
                res = g_obj.GetAll(WPAS_DBUS_GROUP,
                                   dbus_interface=dbus.PROPERTIES_IFACE,
                                   byte_arrays=True)
                bssid = ':'.join([binascii.hexlify(l) for l in res['BSSID']])
                dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
                dev1.scan_for_bss(bssid, freq=2412)
                dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 join")

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            if self.invited:
                self.done = True
                self.loop.quit()
            else:
                dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
                dev1.global_request("SET persistent_reconnect 1")
                dev1.p2p_listen()

                args = { 'persistent_group_object': dbus.ObjectPath(path),
                         'peer': self.peer_path }
                try:
                    pin = p2p.Invite(args)
                    raise Exception("Invalid Invite accepted")
                except dbus.exceptions.DBusException, e:
                    if "InvalidArgs" not in str(e):
                        raise Exception("Unexpected error message for invalid Invite: " + str(e))

                args = { 'persistent_group_object': self.persistent,
                         'peer': self.peer_path }
                pin = p2p.Invite(args)
                self.invited = True

                self.sta_group_ev = dev1.wait_global_event(["P2P-GROUP-STARTED"],
                                                           timeout=15)
                if self.sta_group_ev is None:
                    raise Exception("P2P-GROUP-STARTED event not seen")

        def persistentGroupAdded(self, path, properties):
            logger.debug("persistentGroupAdded: %s %s" % (path, str(properties)))
            self.persistent = path

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
            self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
                                        dbus_interface=dbus.PROPERTIES_IFACE,
                                        byte_arrays=True)

        def provisionDiscoveryRequestDisplayPin(self, peer_object, pin):
            logger.debug("provisionDiscoveryRequestDisplayPin - peer=%s pin=%s" % (peer_object, pin))
            self.peer_path = peer_object
            peer = binascii.unhexlify(peer_object.split('/')[-1])
            addr = ""
            for p in peer:
                if len(addr) > 0:
                    addr += ':'
                addr += '%02x' % ord(p)
            params = { 'Role': 'registrar',
                       'P2PDeviceAddress': self.peer['DeviceAddress'],
                       'Bssid': self.peer['DeviceAddress'],
                       'Type': 'pin',
                       'Pin': '12345670' }
            logger.info("Authorize peer to connect to the group")
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS)
            wps.Start(params)
            self.sta_group_ev = dev1.wait_global_event(["P2P-GROUP-STARTED"],
                                                       timeout=15)
            if self.sta_group_ev is None:
                raise Exception("P2P-GROUP-STARTED event not seen")

        def staAuthorized(self, name):
            logger.debug("staAuthorized: " + name)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.group_form_result(self.sta_group_ev)
            dev1.remove_group()
            ev = dev1.wait_global_event(["P2P-GROUP-REMOVED"], timeout=10)
            if ev is None:
                raise Exception("Group removal timed out")
            group_p2p = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()

        def run_test(self, *args):
            logger.debug("run_test")
            params = dbus.Dictionary({'persistent': True,
                                      'frequency': 2412})
            logger.info("Add a persistent group")
            p2p.GroupAdd(params)
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_go_neg_rx(dev, apdev):
    """D-Bus P2P GO Negotiation receive"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    addr0 = dev[0].p2p_dev_addr()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.goNegotiationRequest,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationRequest",
                            byte_arrays=True)
            self.add_signal(self.goNegotiationSuccess,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationSuccess",
                            byte_arrays=True)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)

        def goNegotiationRequest(self, path, dev_passwd_id, go_intent=0):
            logger.debug("goNegotiationRequest: path=%s dev_passwd_id=%d go_intent=%d" % (path, dev_passwd_id, go_intent))
            if dev_passwd_id != 1:
                raise Exception("Unexpected dev_passwd_id=%d" % dev_passwd_id)
            args = { 'peer': path, 'wps_method': 'display', 'pin': '12345670',
                     'go_intent': 15, 'persistent': False, 'frequency': 5175 }
            try:
                p2p.Connect(args)
                raise Exception("Invalid Connect accepted")
            except dbus.exceptions.DBusException, e:
                if "ConnectChannelUnsupported" not in str(e):
                    raise Exception("Unexpected error message for invalid Connect: " + str(e))

            args = { 'peer': path, 'wps_method': 'display', 'pin': '12345670',
                     'go_intent': 15, 'persistent': False }
            p2p.Connect(args)

        def goNegotiationSuccess(self, properties):
            logger.debug("goNegotiationSuccess: properties=%s" % str(properties))

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True
            self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Listen(10)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            if not dev1.discover_peer(addr0):
                raise Exception("Peer not found")
            dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 enter")
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_go_neg_auth(dev, apdev):
    """D-Bus P2P GO Negotiation authorized"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    addr0 = dev[0].p2p_dev_addr()
    dev[1].p2p_listen()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False
            self.peer_joined = False
            self.peer_disconnected = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.goNegotiationSuccess,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationSuccess",
                            byte_arrays=True)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE,
                            "StaDeauthorized")
            self.add_signal(self.peerJoined, WPAS_DBUS_GROUP,
                            "PeerJoined")
            self.add_signal(self.peerDisconnected, WPAS_DBUS_GROUP,
                            "PeerDisconnected")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            args = { 'peer': path, 'wps_method': 'keypad',
                     'go_intent': 15, 'authorize_only': True }
            try:
                p2p.Connect(args)
                raise Exception("Invalid Connect accepted")
            except dbus.exceptions.DBusException, e:
                if "InvalidArgs" not in str(e):
                    raise Exception("Unexpected error message for invalid Connect: " + str(e))

            args = { 'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
                     'go_intent': 15, 'authorize_only': True }
            p2p.Connect(args)
            p2p.Listen(10)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            if not dev1.discover_peer(addr0):
                raise Exception("Peer not found")
            dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=0")
            ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15);
            if ev is None:
                raise Exception("Group formation timed out")
            self.sta_group_ev = ev

        def goNegotiationSuccess(self, properties):
            logger.debug("goNegotiationSuccess: properties=%s" % str(properties))

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                           properties['interface_object'])
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.group_form_result(self.sta_group_ev)
            dev1.remove_group()

        def staDeauthorized(self, name):
            logger.debug("staDeuthorized: " + name)
            group_p2p = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()

        def peerJoined(self, peer):
            logger.debug("peerJoined: " + peer)
            self.peer_joined = True

        def peerDisconnected(self, peer):
            logger.debug("peerDisconnected: " + peer)
            self.peer_disconnected = True

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True
            self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
            return False

        def success(self):
            return self.done and self.peer_joined and self.peer_disconnected

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_go_neg_init(dev, apdev):
    """D-Bus P2P GO Negotiation initiation"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    addr0 = dev[0].p2p_dev_addr()
    dev[1].p2p_listen()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False
            self.peer_group_added = False
            self.peer_group_removed = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.goNegotiationSuccess,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationSuccess",
                            byte_arrays=True)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            args = { 'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
                     'go_intent': 0 }
            p2p.Connect(args)

            ev = dev1.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
            if ev is None:
                raise Exception("Timeout while waiting for GO Neg Request")
            dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15")
            ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15);
            if ev is None:
                raise Exception("Group formation timed out")
            self.sta_group_ev = ev

        def goNegotiationSuccess(self, properties):
            logger.debug("goNegotiationSuccess: properties=%s" % str(properties))

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.group_form_result(self.sta_group_ev)
            dev1.remove_group()

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True

        def propertiesChanged(self, interface_name, changed_properties,
                              invalidated_properties):
            logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
            if interface_name != WPAS_DBUS_P2P_PEER:
                return
            if "Groups" not in changed_properties:
                return
            if len(changed_properties["Groups"]) > 0:
                self.peer_group_added = True
            if len(changed_properties["Groups"]) == 0:
                self.peer_group_removed = True
                self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
            return False

        def success(self):
            return self.done and self.peer_group_added and self.peer_group_removed

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_group_termination_by_go(dev, apdev):
    """D-Bus P2P group removal on GO terminating the group"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    addr0 = dev[0].p2p_dev_addr()
    dev[1].p2p_listen()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False
            self.peer_group_added = False
            self.peer_group_removed = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.goNegotiationSuccess,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationSuccess",
                            byte_arrays=True)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            args = { 'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
                     'go_intent': 0 }
            p2p.Connect(args)

            ev = dev1.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
            if ev is None:
                raise Exception("Timeout while waiting for GO Neg Request")
            dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15")
            ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15);
            if ev is None:
                raise Exception("Group formation timed out")
            self.sta_group_ev = ev

        def goNegotiationSuccess(self, properties):
            logger.debug("goNegotiationSuccess: properties=%s" % str(properties))

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.group_form_result(self.sta_group_ev)
            dev1.remove_group()

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True

        def propertiesChanged(self, interface_name, changed_properties,
                              invalidated_properties):
            logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
            if interface_name != WPAS_DBUS_P2P_PEER:
                return
            if "Groups" not in changed_properties:
                return
            if len(changed_properties["Groups"]) > 0:
                self.peer_group_added = True
            if len(changed_properties["Groups"]) == 0 and self.peer_group_added:
                self.peer_group_removed = True
                self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
            return False

        def success(self):
            return self.done and self.peer_group_added and self.peer_group_removed

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_group_idle_timeout(dev, apdev):
    """D-Bus P2P group removal on idle timeout"""
    try:
        dev[0].global_request("SET p2p_group_idle 1")
        _test_dbus_p2p_group_idle_timeout(dev, apdev)
    finally:
        dev[0].global_request("SET p2p_group_idle 0")

def _test_dbus_p2p_group_idle_timeout(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    addr0 = dev[0].p2p_dev_addr()
    dev[1].p2p_listen()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False
            self.peer_group_added = False
            self.peer_group_removed = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.goNegotiationSuccess,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationSuccess",
                            byte_arrays=True)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            args = { 'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
                     'go_intent': 0 }
            p2p.Connect(args)

            ev = dev1.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
            if ev is None:
                raise Exception("Timeout while waiting for GO Neg Request")
            dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15")
            ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15);
            if ev is None:
                raise Exception("Group formation timed out")
            self.sta_group_ev = ev

        def goNegotiationSuccess(self, properties):
            logger.debug("goNegotiationSuccess: properties=%s" % str(properties))

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                      properties['interface_object'])
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            dev1.group_form_result(self.sta_group_ev)
            ifaddr = dev1.group_request("STA-FIRST").splitlines()[0]
            # Force disassociation with different reason code so that the
            # P2P Client using D-Bus does not get normal group termination event
            # from the GO.
            dev1.group_request("DEAUTHENTICATE " + ifaddr + " reason=0 test=0")
            dev1.remove_group()

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))
            self.done = True

        def propertiesChanged(self, interface_name, changed_properties,
                              invalidated_properties):
            logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
            if interface_name != WPAS_DBUS_P2P_PEER:
                return
            if "Groups" not in changed_properties:
                return
            if len(changed_properties["Groups"]) > 0:
                self.peer_group_added = True
            if len(changed_properties["Groups"]) == 0:
                self.peer_group_removed = True
                self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
            return False

        def success(self):
            return self.done and self.peer_group_added and self.peer_group_removed

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_wps_failure(dev, apdev):
    """D-Bus P2P WPS failure"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    addr0 = dev[0].p2p_dev_addr()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.wps_failed = False
            self.formation_failure = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.goNegotiationRequest,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationRequest",
                            byte_arrays=True)
            self.add_signal(self.goNegotiationSuccess,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GONegotiationSuccess",
                            byte_arrays=True)
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.wpsFailed, WPAS_DBUS_IFACE_P2PDEVICE,
                            "WpsFailed")
            self.add_signal(self.groupFormationFailure,
                            WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFormationFailure")
            self.loop.run()
            return self

        def goNegotiationRequest(self, path, dev_passwd_id, go_intent=0):
            logger.debug("goNegotiationRequest: path=%s dev_passwd_id=%d go_intent=%d" % (path, dev_passwd_id, go_intent))
            if dev_passwd_id != 1:
                raise Exception("Unexpected dev_passwd_id=%d" % dev_passwd_id)
            args = { 'peer': path, 'wps_method': 'display', 'pin': '12345670',
                     'go_intent': 15 }
            p2p.Connect(args)

        def goNegotiationSuccess(self, properties):
            logger.debug("goNegotiationSuccess: properties=%s" % str(properties))

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            raise Exception("Unexpected GroupStarted")

        def wpsFailed(self, name, args):
            logger.debug("wpsFailed - name=%s args=%s" % (name, str(args)))
            self.wps_failed = True
            if self.formation_failure:
                self.loop.quit()

        def groupFormationFailure(self, reason):
            logger.debug("groupFormationFailure - reason=%s" % reason)
            self.formation_failure = True
            if self.wps_failed:
                self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Listen(10)
            dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
            if not dev1.discover_peer(addr0):
                raise Exception("Peer not found")
            dev1.global_request("P2P_CONNECT " + addr0 + " 87654321 enter")
            return False

        def success(self):
            return self.wps_failed and self.formation_failure

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_p2p_two_groups(dev, apdev):
    """D-Bus P2P with two concurrent groups"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)

    dev[0].request("SET p2p_no_group_iface 0")
    addr0 = dev[0].p2p_dev_addr()
    addr1 = dev[1].p2p_dev_addr()
    addr2 = dev[2].p2p_dev_addr()
    dev[1].p2p_start_go(freq=2412)
    dev1_group_ifname = dev[1].group_ifname

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False
            self.peer = None
            self.go = None
            self.group1 = None
            self.group2 = None
            self.groups_removed = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
                            "PropertiesChanged", byte_arrays=True)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupStarted")
            self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
                            "GroupFinished")
            self.add_signal(self.peerJoined, WPAS_DBUS_GROUP,
                            "PeerJoined")
            self.loop.run()
            return self

        def propertiesChanged(self, interface_name, changed_properties,
                              invalidated_properties):
            logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            if addr2.replace(':','') in path:
                self.peer = path
            elif addr1.replace(':','') in path:
                self.go = path
            if self.go and not self.group1:
                logger.info("Join the group")
                p2p.StopFind()
                pin = '12345670'
                dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
                dev1.group_ifname = dev1_group_ifname
                dev1.group_request("WPS_PIN any " + pin)
                args = { 'peer': self.go,
                         'join': True,
                         'wps_method': 'pin',
                         'pin': pin,
                         'frequency': 2412 }
                p2p.Connect(args)

        def groupStarted(self, properties):
            logger.debug("groupStarted: " + str(properties))
            prop = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE,
                                 dbus_interface=dbus.PROPERTIES_IFACE)
            logger.debug("p2pdevice properties: " + str(prop))

            g_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                   properties['group_object'])
            res = g_obj.GetAll(WPAS_DBUS_GROUP,
                               dbus_interface=dbus.PROPERTIES_IFACE,
                               byte_arrays=True)
            logger.debug("Group properties: " + str(res))

            if not self.group1:
                self.group1 = properties['group_object']
                self.group1iface = properties['interface_object']
                self.g1_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                                self.group1iface)

                logger.info("Start autonomous GO")
                params = dbus.Dictionary({ 'frequency': 2412 })
                p2p.GroupAdd(params)
            elif not self.group2:
                self.group2 = properties['group_object']
                self.group2iface = properties['interface_object']
                self.g2_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
                                                self.group2iface)
                self.g2_bssid = res['BSSID']

            if self.group1 and self.group2:
                logger.info("Authorize peer to join the group")
                a2 = binascii.unhexlify(addr2.replace(':',''))
                params = { 'Role': 'enrollee',
                           'P2PDeviceAddress': dbus.ByteArray(a2),
                           'Bssid': dbus.ByteArray(a2),
                           'Type': 'pin',
                           'Pin': '12345670' }
                g_wps = dbus.Interface(self.g2_if_obj, WPAS_DBUS_IFACE_WPS)
                g_wps.Start(params)

                bssid = ':'.join([binascii.hexlify(l) for l in self.g2_bssid])
                dev2 = WpaSupplicant('wlan2', '/tmp/wpas-wlan2')
                dev2.scan_for_bss(bssid, freq=2412)
                dev2.global_request("P2P_CONNECT " + bssid + " 12345670 join freq=2412")
                ev = dev2.wait_global_event(["P2P-GROUP-STARTED"], timeout=15);
                if ev is None:
                    raise Exception("Group join timed out")
                self.dev2_group_ev = ev

        def groupFinished(self, properties):
            logger.debug("groupFinished: " + str(properties))

            if self.group1 == properties['group_object']:
                self.group1 = None
            elif self.group2 == properties['group_object']:
                self.group2 = None

            if not self.group1 and not self.group2:
                self.done = True
                self.loop.quit()

        def peerJoined(self, peer):
            logger.debug("peerJoined: " + peer)
            if self.groups_removed:
                return
            self.check_results()

            dev2 = WpaSupplicant('wlan2', '/tmp/wpas-wlan2')
            dev2.group_form_result(self.dev2_group_ev)
            dev2.remove_group()

            logger.info("Disconnect group2")
            group_p2p = dbus.Interface(self.g2_if_obj,
                                       WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()

            logger.info("Disconnect group1")
            group_p2p = dbus.Interface(self.g1_if_obj,
                                       WPAS_DBUS_IFACE_P2PDEVICE)
            group_p2p.Disconnect()
            self.groups_removed = True

        def check_results(self):
            logger.info("Check results with two concurrent groups in operation")

            g1_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group1)
            res1 = g1_obj.GetAll(WPAS_DBUS_GROUP,
                                 dbus_interface=dbus.PROPERTIES_IFACE,
                                 byte_arrays=True)

            g2_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group2)
            res2 = g2_obj.GetAll(WPAS_DBUS_GROUP,
                                 dbus_interface=dbus.PROPERTIES_IFACE,
                                 byte_arrays=True)

            logger.info("group1 = " + self.group1)
            logger.debug("Group properties: " + str(res1))

            logger.info("group2 = " + self.group2)
            logger.debug("Group properties: " + str(res2))

            prop = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE,
                                 dbus_interface=dbus.PROPERTIES_IFACE)
            logger.debug("p2pdevice properties: " + str(prop))

            if res1['Role'] != 'client':
                raise Exception("Group1 role reported incorrectly: " + res1['Role'])
            if res2['Role'] != 'GO':
                raise Exception("Group2 role reported incorrectly: " + res2['Role'])
            if prop['Role'] != 'device':
                raise Exception("p2pdevice role reported incorrectly: " + prop['Role'])

            if len(res2['Members']) != 1:
                   raise Exception("Unexpected Members value for group 2")

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

    dev[1].remove_group()

def test_dbus_p2p_cancel(dev, apdev):
    """D-Bus P2P Cancel"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
    try:
        p2p.Cancel()
        raise Exception("Unexpected p2p.Cancel() success")
    except dbus.exceptions.DBusException, e:
        pass

    addr0 = dev[0].p2p_dev_addr()
    dev[1].p2p_listen()

    class TestDbusP2p(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_test)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
                            "DeviceFound")
            self.loop.run()
            return self

        def deviceFound(self, path):
            logger.debug("deviceFound: path=%s" % path)
            args = { 'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
                     'go_intent': 0 }
            p2p.Connect(args)
            p2p.Cancel()
            self.done = True
            self.loop.quit()

        def run_test(self, *args):
            logger.debug("run_test")
            p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
            return False

        def success(self):
            return self.done

    with TestDbusP2p(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_introspect(dev, apdev):
    """D-Bus introspection"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])

    res = if_obj.Introspect(WPAS_DBUS_IFACE,
                            dbus_interface=dbus.INTROSPECTABLE_IFACE)
    logger.info("Initial Introspect: " + str(res))
    if res is None or "Introspectable" not in res or "GroupStarted" not in res:
        raise Exception("Unexpected initial Introspect response: " + str(res))

    with alloc_fail(dev[0], 1, "wpa_dbus_introspect"):
        res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
                                 dbus_interface=dbus.INTROSPECTABLE_IFACE)
        logger.info("Introspect: " + str(res2))
        if res2 is not None:
            raise Exception("Unexpected Introspect response")

    with alloc_fail(dev[0], 1, "=add_interface;wpa_dbus_introspect"):
        res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
                                 dbus_interface=dbus.INTROSPECTABLE_IFACE)
        logger.info("Introspect: " + str(res2))
        if res2 is None:
            raise Exception("No Introspect response")
        if len(res2) >= len(res):
            raise Exception("Unexpected Introspect response")

    with alloc_fail(dev[0], 1, "wpabuf_alloc;add_interface;wpa_dbus_introspect"):
        res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
                                 dbus_interface=dbus.INTROSPECTABLE_IFACE)
        logger.info("Introspect: " + str(res2))
        if res2 is None:
            raise Exception("No Introspect response")
        if len(res2) >= len(res):
            raise Exception("Unexpected Introspect response")

    with alloc_fail(dev[0], 2, "=add_interface;wpa_dbus_introspect"):
        res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
                                 dbus_interface=dbus.INTROSPECTABLE_IFACE)
        logger.info("Introspect: " + str(res2))
        if res2 is None:
            raise Exception("No Introspect response")
        if len(res2) >= len(res):
            raise Exception("Unexpected Introspect response")

def test_dbus_ap(dev, apdev):
    """D-Bus AddNetwork for AP mode"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    ssid = "test-wpa2-psk"
    passphrase = 'qwertyuiop'

    class TestDbusConnect(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.started = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_connect)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded")
            self.add_signal(self.networkSelected, WPAS_DBUS_IFACE,
                            "NetworkSelected")
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
                            "PropertiesChanged")
            self.loop.run()
            return self

        def networkAdded(self, network, properties):
            logger.debug("networkAdded: %s" % str(network))
            logger.debug(str(properties))

        def networkSelected(self, network):
            logger.debug("networkSelected: %s" % str(network))
            self.network_selected = True

        def propertiesChanged(self, properties):
            logger.debug("propertiesChanged: %s" % str(properties))
            if 'State' in properties and properties['State'] == "completed":
                self.started = True
                self.loop.quit()

        def run_connect(self, *args):
            logger.debug("run_connect")
            args = dbus.Dictionary({ 'ssid': ssid,
                                     'key_mgmt': 'WPA-PSK',
                                     'psk': passphrase,
                                     'mode': 2,
                                     'frequency': 2412 },
                                   signature='sv')
            self.netw = iface.AddNetwork(args)
            iface.SelectNetwork(self.netw)
            return False

        def success(self):
            return self.started

    with TestDbusConnect(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")
        dev[1].connect(ssid, psk=passphrase, scan_freq="2412")

def test_dbus_connect_wpa_eap(dev, apdev):
    """D-Bus AddNetwork and connection with WPA+WPA2-Enterprise AP"""
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    ssid = "test-wpa-eap"
    params = hostapd.wpa_eap_params(ssid=ssid)
    params["wpa"] = "3"
    params["rsn_pairwise"] = "CCMP"
    hapd = hostapd.add_ap(apdev[0]['ifname'], params)

    class TestDbusConnect(TestDbus):
        def __init__(self, bus):
            TestDbus.__init__(self, bus)
            self.done = False

        def __enter__(self):
            gobject.timeout_add(1, self.run_connect)
            gobject.timeout_add(15000, self.timeout)
            self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
                            "PropertiesChanged")
            self.add_signal(self.eap, WPAS_DBUS_IFACE, "EAP")
            self.loop.run()
            return self

        def propertiesChanged(self, properties):
            logger.debug("propertiesChanged: %s" % str(properties))
            if 'State' in properties and properties['State'] == "completed":
                self.done = True
                self.loop.quit()

        def eap(self, status, parameter):
            logger.debug("EAP: status=%s parameter=%s" % (status, parameter))

        def run_connect(self, *args):
            logger.debug("run_connect")
            args = dbus.Dictionary({ 'ssid': ssid,
                                     'key_mgmt': 'WPA-EAP',
                                     'eap': 'PEAP',
                                     'identity': 'user',
                                     'password': 'password',
                                     'ca_cert': 'auth_serv/ca.pem',
                                     'phase2': 'auth=MSCHAPV2',
                                     'scan_freq': 2412 },
                                   signature='sv')
            self.netw = iface.AddNetwork(args)
            iface.SelectNetwork(self.netw)
            return False

        def success(self):
            return self.done

    with TestDbusConnect(bus) as t:
        if not t.success():
            raise Exception("Expected signals not seen")

def test_dbus_ap_scan_2_ap_mode_scan(dev, apdev):
    """AP_SCAN 2 AP mode and D-Bus Scan()"""
    try:
        _test_dbus_ap_scan_2_ap_mode_scan(dev, apdev)
    finally:
        dev[0].request("AP_SCAN 1")

def _test_dbus_ap_scan_2_ap_mode_scan(dev, apdev):
    (bus,wpas_obj,path,if_obj) = prepare_dbus(dev[0])
    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)

    if "OK" not in dev[0].request("AP_SCAN 2"):
        raise Exception("Failed to set AP_SCAN 2")

    id = dev[0].add_network()
    dev[0].set_network(id, "mode", "2")
    dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
    dev[0].set_network(id, "key_mgmt", "NONE")
    dev[0].set_network(id, "frequency", "2412")
    dev[0].set_network(id, "scan_freq", "2412")
    dev[0].set_network(id, "disabled", "0")
    dev[0].select_network(id)
    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5)
    if ev is None:
        raise Exception("AP failed to start")

    with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"):
        iface.Scan({'Type': 'active',
                    'AllowRoam': True,
                    'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
        ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED",
                                "AP-DISABLED"], timeout=5)
        if ev is None:
            raise Exception("CTRL-EVENT-SCAN-FAILED not seen")
        if "AP-DISABLED" in ev:
            raise Exception("Unexpected AP-DISABLED event")
        if "retry=1" in ev:
            # Wait for the retry to scan happen
            ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED",
                                    "AP-DISABLED"], timeout=5)
            if ev is None:
                raise Exception("CTRL-EVENT-SCAN-FAILED not seen - retry")
            if "AP-DISABLED" in ev:
                raise Exception("Unexpected AP-DISABLED event - retry")

    dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
    dev[1].request("DISCONNECT")
    dev[1].wait_disconnected()
    dev[0].request("DISCONNECT")
    dev[0].wait_disconnected()
