Imported Upstream version 1.24
[platform/upstream/connman.git] / gsupplicant / supplicant.c
index 30f0660..2674298 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  WPA supplicant library with GLib integration
  *
- *  Copyright (C) 2012  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2012-2013  Intel Corporation. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <syslog.h>
 #include <ctype.h>
+#include <stdbool.h>
 
 #include <glib.h>
 #include <gdbus.h>
@@ -152,6 +153,9 @@ struct _GSupplicantInterface {
        unsigned int scan_capa;
        unsigned int mode_capa;
        unsigned int max_scan_ssids;
+       bool p2p_checked;
+       bool p2p_support;
+       bool p2p_finding;
        dbus_bool_t ready;
        GSupplicantState state;
        dbus_bool_t scanning;
@@ -164,6 +168,7 @@ struct _GSupplicantInterface {
        struct _GSupplicantWpsCredentials wps_cred;
        GSupplicantWpsState wps_state;
        GHashTable *network_table;
+       GHashTable *peer_table;
        GHashTable *net_mapping;
        GHashTable *bss_mapping;
        void *data;
@@ -212,12 +217,20 @@ struct _GSupplicantNetwork {
        GHashTable *config_table;
 };
 
+struct _GSupplicantPeer {
+       GSupplicantInterface *interface;
+       char *path;
+       unsigned char device_address[6];
+       char *name;
+       char *identifier;
+};
+
 static inline void debug(const char *format, ...)
 {
        char str[256];
        va_list ap;
 
-       if (callbacks_pointer->debug == NULL)
+       if (!callbacks_pointer->debug)
                return;
 
        va_start(ap, format);
@@ -233,12 +246,12 @@ static inline void debug(const char *format, ...)
 
 static GSupplicantMode string2mode(const char *mode)
 {
-       if (mode == NULL)
+       if (!mode)
                return G_SUPPLICANT_MODE_UNKNOWN;
 
-       if (g_str_equal(mode, "infrastructure") == TRUE)
+       if (g_str_equal(mode, "infrastructure"))
                return G_SUPPLICANT_MODE_INFRA;
-       else if (g_str_equal(mode, "ad-hoc") == TRUE)
+       else if (g_str_equal(mode, "ad-hoc"))
                return G_SUPPLICANT_MODE_IBSS;
 
        return G_SUPPLICANT_MODE_UNKNOWN;
@@ -280,30 +293,30 @@ static const char *security2string(GSupplicantSecurity security)
 
 static GSupplicantState string2state(const char *state)
 {
-       if (state == NULL)
+       if (!state)
                return G_SUPPLICANT_STATE_UNKNOWN;
 
-       if (g_str_equal(state, "unknown") == TRUE)
+       if (g_str_equal(state, "unknown"))
                return G_SUPPLICANT_STATE_UNKNOWN;
-       else if (g_str_equal(state, "interface_disabled") == TRUE)
+       else if (g_str_equal(state, "interface_disabled"))
                return G_SUPPLICANT_STATE_DISABLED;
-       else if (g_str_equal(state, "disconnected") == TRUE)
+       else if (g_str_equal(state, "disconnected"))
                return G_SUPPLICANT_STATE_DISCONNECTED;
-       else if (g_str_equal(state, "inactive") == TRUE)
+       else if (g_str_equal(state, "inactive"))
                return G_SUPPLICANT_STATE_INACTIVE;
-       else if (g_str_equal(state, "scanning") == TRUE)
+       else if (g_str_equal(state, "scanning"))
                return G_SUPPLICANT_STATE_SCANNING;
-       else if (g_str_equal(state, "authenticating") == TRUE)
+       else if (g_str_equal(state, "authenticating"))
                return G_SUPPLICANT_STATE_AUTHENTICATING;
-       else if (g_str_equal(state, "associating") == TRUE)
+       else if (g_str_equal(state, "associating"))
                return G_SUPPLICANT_STATE_ASSOCIATING;
-       else if (g_str_equal(state, "associated") == TRUE)
+       else if (g_str_equal(state, "associated"))
                return G_SUPPLICANT_STATE_ASSOCIATED;
-       else if (g_str_equal(state, "group_handshake") == TRUE)
+       else if (g_str_equal(state, "group_handshake"))
                return G_SUPPLICANT_STATE_GROUP_HANDSHAKE;
-       else if (g_str_equal(state, "4way_handshake") == TRUE)
+       else if (g_str_equal(state, "4way_handshake"))
                return G_SUPPLICANT_STATE_4WAY_HANDSHAKE;
-       else if (g_str_equal(state, "completed") == TRUE)
+       else if (g_str_equal(state, "completed"))
                return G_SUPPLICANT_STATE_COMPLETED;
 
        return G_SUPPLICANT_STATE_UNKNOWN;
@@ -311,15 +324,15 @@ static GSupplicantState string2state(const char *state)
 
 static void callback_system_ready(void)
 {
-       if (system_ready == TRUE)
+       if (system_ready)
                return;
 
        system_ready = TRUE;
 
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->system_ready == NULL)
+       if (!callbacks_pointer->system_ready)
                return;
 
        callbacks_pointer->system_ready();
@@ -329,10 +342,10 @@ static void callback_system_killed(void)
 {
        system_ready = FALSE;
 
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->system_killed == NULL)
+       if (!callbacks_pointer->system_killed)
                return;
 
        callbacks_pointer->system_killed();
@@ -342,10 +355,10 @@ static void callback_interface_added(GSupplicantInterface *interface)
 {
        SUPPLICANT_DBG("");
 
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->interface_added == NULL)
+       if (!callbacks_pointer->interface_added)
                return;
 
        callbacks_pointer->interface_added(interface);
@@ -353,10 +366,10 @@ static void callback_interface_added(GSupplicantInterface *interface)
 
 static void callback_interface_state(GSupplicantInterface *interface)
 {
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->interface_state == NULL)
+       if (!callbacks_pointer->interface_state)
                return;
 
        callbacks_pointer->interface_state(interface);
@@ -364,21 +377,34 @@ static void callback_interface_state(GSupplicantInterface *interface)
 
 static void callback_interface_removed(GSupplicantInterface *interface)
 {
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->interface_removed == NULL)
+       if (!callbacks_pointer->interface_removed)
                return;
 
        callbacks_pointer->interface_removed(interface);
 }
 
+static void callback_p2p_support(GSupplicantInterface *interface)
+{
+       SUPPLICANT_DBG("");
+
+       if (interface->p2p_checked)
+               return;
+
+       interface->p2p_checked = true;
+
+       if (callbacks_pointer && callbacks_pointer->p2p_support)
+               callbacks_pointer->p2p_support(interface);
+}
+
 static void callback_scan_started(GSupplicantInterface *interface)
 {
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->scan_started == NULL)
+       if (!callbacks_pointer->scan_started)
                return;
 
        callbacks_pointer->scan_started(interface);
@@ -386,10 +412,10 @@ static void callback_scan_started(GSupplicantInterface *interface)
 
 static void callback_scan_finished(GSupplicantInterface *interface)
 {
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->scan_finished == NULL)
+       if (!callbacks_pointer->scan_finished)
                return;
 
        callbacks_pointer->scan_finished(interface);
@@ -397,10 +423,10 @@ static void callback_scan_finished(GSupplicantInterface *interface)
 
 static void callback_network_added(GSupplicantNetwork *network)
 {
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->network_added == NULL)
+       if (!callbacks_pointer->network_added)
                return;
 
        callbacks_pointer->network_added(network);
@@ -408,10 +434,10 @@ static void callback_network_added(GSupplicantNetwork *network)
 
 static void callback_network_removed(GSupplicantNetwork *network)
 {
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->network_removed == NULL)
+       if (!callbacks_pointer->network_removed)
                return;
 
        callbacks_pointer->network_removed(network);
@@ -420,15 +446,37 @@ static void callback_network_removed(GSupplicantNetwork *network)
 static void callback_network_changed(GSupplicantNetwork *network,
                                        const char *property)
 {
-       if (callbacks_pointer == NULL)
+       if (!callbacks_pointer)
                return;
 
-       if (callbacks_pointer->network_changed == NULL)
+       if (!callbacks_pointer->network_changed)
                return;
 
        callbacks_pointer->network_changed(network, property);
 }
 
+static void callback_peer_found(GSupplicantPeer *peer)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->peer_found)
+               return;
+
+       callbacks_pointer->peer_found(peer);
+}
+
+static void callback_peer_lost(GSupplicantPeer *peer)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->peer_lost)
+               return;
+
+       callbacks_pointer->peer_lost(peer);
+}
+
 static void remove_interface(gpointer data)
 {
        GSupplicantInterface *interface = data;
@@ -436,8 +484,9 @@ static void remove_interface(gpointer data)
        g_hash_table_destroy(interface->bss_mapping);
        g_hash_table_destroy(interface->net_mapping);
        g_hash_table_destroy(interface->network_table);
+       g_hash_table_destroy(interface->peer_table);
 
-       if (interface->scan_callback != NULL) {
+       if (interface->scan_callback) {
                SUPPLICANT_DBG("call interface %p callback %p scanning %d",
                                interface, interface->scan_callback,
                                interface->scanning);
@@ -446,7 +495,7 @@ static void remove_interface(gpointer data)
                 interface->scan_callback = NULL;
                 interface->scan_data = NULL;
 
-               if (interface->scanning == TRUE) {
+               if (interface->scanning) {
                        interface->scanning = FALSE;
                        callback_scan_finished(interface);
                }
@@ -487,12 +536,23 @@ static void remove_bss(gpointer data)
        g_free(bss);
 }
 
+static void remove_peer(gpointer data)
+{
+       GSupplicantPeer *peer = data;
+
+       g_free(peer->path);
+       g_free(peer->name);
+       g_free(peer->identifier);
+
+       g_free(peer);
+}
+
 static void debug_strvalmap(const char *label, struct strvalmap *map,
                                                        unsigned int val)
 {
        int i;
 
-       for (i = 0; map[i].str != NULL; i++) {
+       for (i = 0; map[i].str; i++) {
                if (val & map[i].val)
                        SUPPLICANT_DBG("%s: %s", label, map[i].str);
        }
@@ -505,10 +565,10 @@ static void interface_capability_keymgmt(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; keymgmt_map[i].str != NULL; i++)
+       for (i = 0; keymgmt_map[i].str; i++)
                if (strcmp(str, keymgmt_map[i].str) == 0) {
                        interface->keymgmt_capa |= keymgmt_map[i].val;
                        break;
@@ -522,10 +582,10 @@ static void interface_capability_authalg(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; authalg_capa_map[i].str != NULL; i++)
+       for (i = 0; authalg_capa_map[i].str; i++)
                if (strcmp(str, authalg_capa_map[i].str) == 0) {
                        interface->authalg_capa |= authalg_capa_map[i].val;
                        break;
@@ -539,10 +599,10 @@ static void interface_capability_proto(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; proto_capa_map[i].str != NULL; i++)
+       for (i = 0; proto_capa_map[i].str; i++)
                if (strcmp(str, proto_capa_map[i].str) == 0) {
                        interface->proto_capa |= proto_capa_map[i].val;
                        break;
@@ -557,10 +617,10 @@ static void interface_capability_pairwise(DBusMessageIter *iter,
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; pairwise_map[i].str != NULL; i++)
+       for (i = 0; pairwise_map[i].str; i++)
                if (strcmp(str, pairwise_map[i].str) == 0) {
                        interface->pairwise_capa |= pairwise_map[i].val;
                        break;
@@ -574,10 +634,10 @@ static void interface_capability_group(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; group_map[i].str != NULL; i++)
+       for (i = 0; group_map[i].str; i++)
                if (strcmp(str, group_map[i].str) == 0) {
                        interface->group_capa |= group_map[i].val;
                        break;
@@ -591,10 +651,10 @@ static void interface_capability_scan(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; scan_capa_map[i].str != NULL; i++)
+       for (i = 0; scan_capa_map[i].str; i++)
                if (strcmp(str, scan_capa_map[i].str) == 0) {
                        interface->scan_capa |= scan_capa_map[i].val;
                        break;
@@ -608,10 +668,10 @@ static void interface_capability_mode(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; mode_capa_map[i].str != NULL; i++)
+       for (i = 0; mode_capa_map[i].str; i++)
                if (strcmp(str, mode_capa_map[i].str) == 0) {
                        interface->mode_capa |= mode_capa_map[i].val;
                        break;
@@ -623,7 +683,7 @@ static void interface_capability(const char *key, DBusMessageIter *iter,
 {
        GSupplicantInterface *interface = user_data;
 
-       if (key == NULL)
+       if (!key)
                return;
 
        if (g_strcmp0(key, "KeyMgmt") == 0)
@@ -679,15 +739,18 @@ int g_supplicant_interface_set_apscan(GSupplicantInterface *interface,
 void g_supplicant_interface_set_data(GSupplicantInterface *interface,
                                                                void *data)
 {
-       if (interface == NULL)
+       if (!interface)
                return;
 
        interface->data = data;
+
+       if (!data)
+               interface->scan_callback = NULL;
 }
 
 void *g_supplicant_interface_get_data(GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return NULL;
 
        return interface->data;
@@ -695,7 +758,7 @@ void *g_supplicant_interface_get_data(GSupplicantInterface *interface)
 
 const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return NULL;
 
        return interface->ifname;
@@ -703,7 +766,7 @@ const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface)
 
 const char *g_supplicant_interface_get_driver(GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return NULL;
 
        return interface->driver;
@@ -712,7 +775,7 @@ const char *g_supplicant_interface_get_driver(GSupplicantInterface *interface)
 GSupplicantState g_supplicant_interface_get_state(
                                        GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return G_SUPPLICANT_STATE_UNKNOWN;
 
        return interface->state;
@@ -720,7 +783,7 @@ GSupplicantState g_supplicant_interface_get_state(
 
 const char *g_supplicant_interface_get_wps_key(GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return NULL;
 
        return (const char *)interface->wps_cred.key;
@@ -729,10 +792,10 @@ const char *g_supplicant_interface_get_wps_key(GSupplicantInterface *interface)
 const void *g_supplicant_interface_get_wps_ssid(GSupplicantInterface *interface,
                                                        unsigned int *ssid_len)
 {
-       if (ssid_len == NULL)
+       if (!ssid_len)
                return NULL;
 
-       if (interface == NULL || interface->wps_cred.ssid == NULL) {
+       if (!interface || interface->wps_cred.ssid_len == 0) {
                *ssid_len = 0;
                return NULL;
        }
@@ -744,7 +807,7 @@ const void *g_supplicant_interface_get_wps_ssid(GSupplicantInterface *interface,
 GSupplicantWpsState g_supplicant_interface_get_wps_state(
                                        GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return G_SUPPLICANT_WPS_STATE_UNKNOWN;
 
        return interface->wps_state;
@@ -752,7 +815,7 @@ GSupplicantWpsState g_supplicant_interface_get_wps_state(
 
 unsigned int g_supplicant_interface_get_mode(GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return 0;
 
        return interface->mode_capa;
@@ -761,7 +824,7 @@ unsigned int g_supplicant_interface_get_mode(GSupplicantInterface *interface)
 unsigned int g_supplicant_interface_get_max_scan_ssids(
                                GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return 0;
 
        return interface->max_scan_ssids;
@@ -777,10 +840,10 @@ static void set_network_enabled(DBusMessageIter *iter, void *user_data)
 int g_supplicant_interface_enable_selected_network(GSupplicantInterface *interface,
                                                        dbus_bool_t enable)
 {
-       if (interface == NULL)
+       if (!interface)
                return -1;
 
-       if (interface->network_path == NULL)
+       if (!interface->network_path)
                return -1;
 
        SUPPLICANT_DBG(" ");
@@ -792,7 +855,7 @@ int g_supplicant_interface_enable_selected_network(GSupplicantInterface *interfa
 
 dbus_bool_t g_supplicant_interface_get_ready(GSupplicantInterface *interface)
 {
-       if (interface == NULL)
+       if (!interface)
                return FALSE;
 
        return interface->ready;
@@ -801,7 +864,7 @@ dbus_bool_t g_supplicant_interface_get_ready(GSupplicantInterface *interface)
 GSupplicantInterface *g_supplicant_network_get_interface(
                                        GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return NULL;
 
        return network->interface;
@@ -809,7 +872,7 @@ GSupplicantInterface *g_supplicant_network_get_interface(
 
 const char *g_supplicant_network_get_name(GSupplicantNetwork *network)
 {
-       if (network == NULL || network->name == NULL)
+       if (!network || !network->name)
                return "";
 
        return network->name;
@@ -817,7 +880,7 @@ const char *g_supplicant_network_get_name(GSupplicantNetwork *network)
 
 const char *g_supplicant_network_get_identifier(GSupplicantNetwork *network)
 {
-       if (network == NULL || network->group == NULL)
+       if (!network || !network->group)
                return "";
 
        return network->group;
@@ -825,7 +888,7 @@ const char *g_supplicant_network_get_identifier(GSupplicantNetwork *network)
 
 const char *g_supplicant_network_get_path(GSupplicantNetwork *network)
 {
-       if (network == NULL || network->path == NULL)
+       if (!network || !network->path)
                return NULL;
 
        return network->path;
@@ -833,7 +896,7 @@ const char *g_supplicant_network_get_path(GSupplicantNetwork *network)
 
 const char *g_supplicant_network_get_mode(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return G_SUPPLICANT_MODE_UNKNOWN;
 
        return mode2string(network->mode);
@@ -841,7 +904,7 @@ const char *g_supplicant_network_get_mode(GSupplicantNetwork *network)
 
 const char *g_supplicant_network_get_security(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return G_SUPPLICANT_SECURITY_UNKNOWN;
 
        return security2string(network->security);
@@ -850,7 +913,7 @@ const char *g_supplicant_network_get_security(GSupplicantNetwork *network)
 const void *g_supplicant_network_get_ssid(GSupplicantNetwork *network,
                                                unsigned int *ssid_len)
 {
-       if (network == NULL || network->ssid == NULL) {
+       if (!network) {
                *ssid_len = 0;
                return NULL;
        }
@@ -861,7 +924,7 @@ const void *g_supplicant_network_get_ssid(GSupplicantNetwork *network,
 
 dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return 0;
 
        return network->signal;
@@ -869,7 +932,7 @@ dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network)
 
 dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return 0;
 
        return network->frequency;
@@ -877,7 +940,7 @@ dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network)
 
 dbus_bool_t g_supplicant_network_get_wps(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return FALSE;
 
        return network->wps;
@@ -885,7 +948,7 @@ dbus_bool_t g_supplicant_network_get_wps(GSupplicantNetwork *network)
 
 dbus_bool_t g_supplicant_network_is_wps_active(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return FALSE;
 
        if (network->wps_capabilities & G_SUPPLICANT_WPS_CONFIGURED)
@@ -896,7 +959,7 @@ dbus_bool_t g_supplicant_network_is_wps_active(GSupplicantNetwork *network)
 
 dbus_bool_t g_supplicant_network_is_wps_pbc(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return FALSE;
 
        if (network->wps_capabilities & G_SUPPLICANT_WPS_PBC)
@@ -907,7 +970,7 @@ dbus_bool_t g_supplicant_network_is_wps_pbc(GSupplicantNetwork *network)
 
 dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network)
 {
-       if (network == NULL)
+       if (!network)
                return FALSE;
 
        if (network->wps_capabilities & G_SUPPLICANT_WPS_REGISTRAR)
@@ -916,6 +979,38 @@ dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network)
        return FALSE;
 }
 
+GSupplicantInterface *g_supplicant_peer_get_interface(GSupplicantPeer *peer)
+{
+       if (!peer)
+               return NULL;
+
+       return peer->interface;
+}
+
+const char *g_supplicant_peer_get_identifier(GSupplicantPeer *peer)
+{
+       if (!peer)
+               return NULL;
+
+       return peer->identifier;
+}
+
+const void *g_supplicant_peer_get_device_address(GSupplicantPeer *peer)
+{
+       if (!peer)
+               return NULL;
+
+       return peer->device_address;
+}
+
+const char *g_supplicant_peer_get_name(GSupplicantPeer *peer)
+{
+       if (!peer)
+               return NULL;
+
+       return peer->name;
+}
+
 static void merge_network(GSupplicantNetwork *network)
 {
        GString *str;
@@ -929,13 +1024,13 @@ static void merge_network(GSupplicantNetwork *network)
 
        SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
 
-       if (ssid != NULL)
+       if (ssid)
                ssid_len = strlen(ssid);
        else
                ssid_len = 0;
 
        str = g_string_sized_new((ssid_len * 2) + 24);
-       if (str == NULL)
+       if (!str)
                return;
 
        for (i = 0; i < ssid_len; i++)
@@ -966,10 +1061,10 @@ static void network_property(const char *key, DBusMessageIter *iter,
 {
        GSupplicantNetwork *network = user_data;
 
-       if (network->interface == NULL)
+       if (!network->interface)
                return;
 
-       if (key == NULL) {
+       if (!key) {
                merge_network(network);
                return;
        }
@@ -982,7 +1077,7 @@ static void network_property(const char *key, DBusMessageIter *iter,
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL) {
+               if (str) {
                        g_hash_table_replace(network->config_table,
                                                g_strdup(key), g_strdup(str));
                }
@@ -1000,18 +1095,18 @@ static void interface_network_added(DBusMessageIter *iter, void *user_data)
        SUPPLICANT_DBG("");
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL)
+       if (!path)
                return;
 
        if (g_strcmp0(path, "/") == 0)
                return;
 
        network = g_hash_table_lookup(interface->net_mapping, path);
-       if (network != NULL)
+       if (network)
                return;
 
        network = g_try_new0(GSupplicantNetwork, 1);
-       if (network == NULL)
+       if (!network)
                return;
 
        network->interface = interface;
@@ -1040,11 +1135,11 @@ static void interface_network_removed(DBusMessageIter *iter, void *user_data)
        const char *path = NULL;
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL)
+       if (!path)
                return;
 
        network = g_hash_table_lookup(interface->net_mapping, path);
-       if (network == NULL)
+       if (!network)
                return;
 
        g_hash_table_remove(interface->net_mapping, path);
@@ -1065,13 +1160,13 @@ static char *create_name(unsigned char *ssid, int ssid_len)
 
        while (remaining_bytes != 0) {
                if (g_utf8_validate(remainder, remaining_bytes,
-                                       &invalid) == TRUE) {
+                                       &invalid)) {
                        break;
                }
 
                valid_bytes = invalid - remainder;
 
-               if (string == NULL)
+               if (!string)
                        string = g_string_sized_new(remaining_bytes);
 
                g_string_append_len(string, remainder, valid_bytes);
@@ -1083,7 +1178,7 @@ static char *create_name(unsigned char *ssid, int ssid_len)
                remainder = invalid + 1;
        }
 
-       if (string == NULL)
+       if (!string)
                return g_strndup((const gchar *)ssid, ssid_len + 1);
 
        g_string_append(string, remainder);
@@ -1098,7 +1193,7 @@ static char *create_group(struct g_supplicant_bss *bss)
        const char *mode, *security;
 
        str = g_string_sized_new((bss->ssid_len * 2) + 24);
-       if (str == NULL)
+       if (!str)
                return NULL;
 
        if (bss->ssid_len > 0 && bss->ssid[0] != '\0') {
@@ -1108,11 +1203,11 @@ static char *create_group(struct g_supplicant_bss *bss)
                g_string_append_printf(str, "hidden");
 
        mode = mode2string(bss->mode);
-       if (mode != NULL)
+       if (mode)
                g_string_append_printf(str, "_%s", mode);
 
        security = security2string(bss->security);
-       if (security != NULL)
+       if (security)
                g_string_append_printf(str, "_%s", security);
 
        return g_string_free(str, FALSE);
@@ -1127,11 +1222,11 @@ static void add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
        group = create_group(bss);
        SUPPLICANT_DBG("New group created: %s", group);
 
-       if (group == NULL)
+       if (!group)
                return;
 
        network = g_hash_table_lookup(interface->network_table, group);
-       if (network != NULL) {
+       if (network) {
                g_free(group);
                SUPPLICANT_DBG("Network %s already exist", network->name);
 
@@ -1139,13 +1234,13 @@ static void add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
        }
 
        network = g_try_new0(GSupplicantNetwork, 1);
-       if (network == NULL) {
+       if (!network) {
                g_free(group);
                return;
        }
 
        network->interface = interface;
-       if (network->path == NULL)
+       if (!network->path)
                network->path = g_strdup(bss->path);
        network->group = group;
        network->name = create_name(bss->ssid, bss->ssid_len);
@@ -1209,10 +1304,10 @@ static void bss_keymgmt(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; keymgmt_map[i].str != NULL; i++)
+       for (i = 0; keymgmt_map[i].str; i++)
                if (strcmp(str, keymgmt_map[i].str) == 0) {
                        SUPPLICANT_DBG("Keymgmt: %s", str);
                        *keymgmt |= keymgmt_map[i].val;
@@ -1227,10 +1322,10 @@ static void bss_group(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; group_map[i].str != NULL; i++)
+       for (i = 0; group_map[i].str; i++)
                if (strcmp(str, group_map[i].str) == 0) {
                        SUPPLICANT_DBG("Group: %s", str);
                        *group |= group_map[i].val;
@@ -1245,10 +1340,10 @@ static void bss_pairwise(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; pairwise_map[i].str != NULL; i++)
+       for (i = 0; pairwise_map[i].str; i++)
                if (strcmp(str, pairwise_map[i].str) == 0) {
                        SUPPLICANT_DBG("Pairwise: %s", str);
                        *pairwise |= pairwise_map[i].val;
@@ -1267,21 +1362,21 @@ static void bss_wpa(const char *key, DBusMessageIter *iter,
        if (g_strcmp0(key, "KeyMgmt") == 0) {
                supplicant_dbus_array_foreach(iter, bss_keymgmt, &value);
 
-               if (bss->rsn_selected == TRUE)
+               if (bss->rsn_selected)
                        bss->rsn_keymgmt = value;
                else
                        bss->wpa_keymgmt = value;
        } else if (g_strcmp0(key, "Group") == 0) {
                supplicant_dbus_array_foreach(iter, bss_group, &value);
 
-               if (bss->rsn_selected == TRUE)
+               if (bss->rsn_selected)
                        bss->rsn_group = value;
                else
                        bss->wpa_group = value;
        } else if (g_strcmp0(key, "Pairwise") == 0) {
                supplicant_dbus_array_foreach(iter, bss_pairwise, &value);
 
-               if (bss->rsn_selected == TRUE)
+               if (bss->rsn_selected)
                        bss->rsn_pairwise = value;
                else
                        bss->wpa_pairwise = value;
@@ -1353,7 +1448,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
        dbus_message_iter_recurse(iter, &array);
        dbus_message_iter_get_fixed_array(&array, &ie, &ie_len);
 
-       if (ie == NULL || ie_len < 2)
+       if (!ie || ie_len < 2)
                return;
 
        bss->wps_capabilities = 0;
@@ -1420,11 +1515,11 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
                                G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
                bss->psk = TRUE;
 
-       if (bss->ieee8021x == TRUE)
+       if (bss->ieee8021x)
                bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
-       else if (bss->psk == TRUE)
+       else if (bss->psk)
                bss->security = G_SUPPLICANT_SECURITY_PSK;
-       else if (bss->privacy == TRUE)
+       else if (bss->privacy)
                bss->security = G_SUPPLICANT_SECURITY_WEP;
        else
                bss->security = G_SUPPLICANT_SECURITY_NONE;
@@ -1436,12 +1531,12 @@ static void bss_property(const char *key, DBusMessageIter *iter,
 {
        struct g_supplicant_bss *bss = user_data;
 
-       if (bss->interface == NULL)
+       if (!bss->interface)
                return;
 
        SUPPLICANT_DBG("key %s", key);
 
-       if (key == NULL)
+       if (!key)
                return;
 
        if (g_strcmp0(key, "BSSID") == 0) {
@@ -1540,7 +1635,7 @@ static struct g_supplicant_bss *interface_bss_added(DBusMessageIter *iter,
        SUPPLICANT_DBG("");
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL)
+       if (!path)
                return NULL;
 
        if (g_strcmp0(path, "/") == 0)
@@ -1549,14 +1644,14 @@ static struct g_supplicant_bss *interface_bss_added(DBusMessageIter *iter,
        SUPPLICANT_DBG("%s", path);
 
        network = g_hash_table_lookup(interface->bss_mapping, path);
-       if (network != NULL) {
+       if (network) {
                bss = g_hash_table_lookup(network->bss_table, path);
-               if (bss != NULL)
+               if (bss)
                        return NULL;
        }
 
        bss = g_try_new0(struct g_supplicant_bss, 1);
-       if (bss == NULL)
+       if (!bss)
                return NULL;
 
        bss->interface = interface;
@@ -1573,7 +1668,7 @@ static void interface_bss_added_with_keys(DBusMessageIter *iter,
        SUPPLICANT_DBG("");
 
        bss = interface_bss_added(iter, user_data);
-       if (bss == NULL)
+       if (!bss)
                return;
 
        dbus_message_iter_next(iter);
@@ -1595,7 +1690,7 @@ static void interface_bss_added_without_keys(DBusMessageIter *iter,
        SUPPLICANT_DBG("");
 
        bss = interface_bss_added(iter, user_data);
-       if (bss == NULL)
+       if (!bss)
                return;
 
        supplicant_dbus_property_get_all(bss->path,
@@ -1636,11 +1731,11 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data)
        const char *path = NULL;
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL)
+       if (!path)
                return;
 
        network = g_hash_table_lookup(interface->bss_mapping, path);
-       if (network == NULL)
+       if (!network)
                return;
 
        g_hash_table_remove(bss_mapping, path);
@@ -1659,12 +1754,12 @@ static void interface_property(const char *key, DBusMessageIter *iter,
 {
        GSupplicantInterface *interface = user_data;
 
-       if (interface == NULL)
+       if (!interface)
                return;
 
        SUPPLICANT_DBG("%s", key);
 
-       if (key == NULL) {
+       if (!key) {
                debug_strvalmap("KeyMgmt capability", keymgmt_map,
                                                interface->keymgmt_capa);
                debug_strvalmap("AuthAlg capability", authalg_capa_map,
@@ -1680,7 +1775,9 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                debug_strvalmap("Mode capability", mode_capa_map,
                                                interface->mode_capa);
 
-               callback_interface_added(interface);
+               if (interface->ready)
+                       callback_interface_added(interface);
+
                return;
        }
 
@@ -1691,7 +1788,7 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL)
+               if (str)
                        if (string2state(str) != interface->state) {
                                interface->state = string2state(str);
                                callback_interface_state(interface);
@@ -1708,8 +1805,8 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                dbus_message_iter_get_basic(iter, &scanning);
                interface->scanning = scanning;
 
-               if (interface->ready == TRUE) {
-                       if (interface->scanning == TRUE)
+               if (interface->ready) {
+                       if (interface->scanning)
                                callback_scan_started(interface);
                        else
                                callback_scan_finished(interface);
@@ -1723,7 +1820,7 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL) {
+               if (str) {
                        g_free(interface->ifname);
                        interface->ifname = g_strdup(str);
                }
@@ -1731,7 +1828,7 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL) {
+               if (str) {
                        g_free(interface->driver);
                        interface->driver = g_strdup(str);
                }
@@ -1739,7 +1836,7 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL) {
+               if (str) {
                        g_free(interface->bridge);
                        interface->bridge = g_strdup(str);
                }
@@ -1748,8 +1845,9 @@ static void interface_property(const char *key, DBusMessageIter *iter,
        } else if (g_strcmp0(key, "CurrentNetwork") == 0) {
                interface_network_added(iter, interface);
        } else if (g_strcmp0(key, "BSSs") == 0) {
-               supplicant_dbus_array_foreach(iter, interface_bss_added_without_keys,
-                                                               interface);
+               supplicant_dbus_array_foreach(iter,
+                                       interface_bss_added_without_keys,
+                                       interface);
        } else if (g_strcmp0(key, "Blobs") == 0) {
                /* Nothing */
        } else if (g_strcmp0(key, "Networks") == 0) {
@@ -1766,12 +1864,12 @@ static void scan_network_update(DBusMessageIter *iter, void *user_data)
        GSupplicantNetwork *network;
        char *path;
 
-       if (iter == NULL)
+       if (!iter)
                return;
 
        dbus_message_iter_get_basic(iter, &path);
 
-       if (path == NULL)
+       if (!path)
                return;
 
        if (g_strcmp0(path, "/") == 0)
@@ -1779,7 +1877,7 @@ static void scan_network_update(DBusMessageIter *iter, void *user_data)
 
        /* Update the network details based on scan BSS data */
        network = g_hash_table_lookup(interface->bss_mapping, path);
-       if (network != NULL)
+       if (network)
                callback_network_added(network);
 }
 
@@ -1792,7 +1890,7 @@ static void scan_bss_data(const char *key, DBusMessageIter *iter,
                supplicant_dbus_array_foreach(iter, scan_network_update,
                                                interface);
 
-       if (interface->scan_callback != NULL)
+       if (interface->scan_callback)
                interface->scan_callback(0, interface, interface->scan_data);
 
        interface->scan_callback = NULL;
@@ -1804,14 +1902,15 @@ static GSupplicantInterface *interface_alloc(const char *path)
        GSupplicantInterface *interface;
 
        interface = g_try_new0(GSupplicantInterface, 1);
-       if (interface == NULL)
+       if (!interface)
                return NULL;
 
        interface->path = g_strdup(path);
 
        interface->network_table = g_hash_table_new_full(g_str_hash,
                                        g_str_equal, NULL, remove_network);
-
+       interface->peer_table = g_hash_table_new_full(g_str_hash,
+                                       g_str_equal, NULL, remove_peer);
        interface->net_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                                NULL, NULL);
        interface->bss_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -1822,6 +1921,25 @@ static GSupplicantInterface *interface_alloc(const char *path)
        return interface;
 }
 
+static void interface_p2p_flush(const char *error,
+                               DBusMessageIter *iter, void *user_data)
+{
+       GSupplicantInterface *interface = user_data;
+
+       if (error) {
+               if (!g_strcmp0(error,
+                               "org.freedesktop.DBus.Error.UnknownMethod")) {
+                       SUPPLICANT_DBG("wpa_supplicant does not support P2P");
+               } else {
+                       SUPPLICANT_DBG("interface %s does not support P2P",
+                                                       interface->ifname);
+               }
+       } else
+               interface->p2p_support = true;
+
+       callback_p2p_support(interface);
+}
+
 static void interface_added(DBusMessageIter *iter, void *user_data)
 {
        GSupplicantInterface *interface;
@@ -1830,20 +1948,24 @@ static void interface_added(DBusMessageIter *iter, void *user_data)
        SUPPLICANT_DBG("");
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL)
+       if (!path)
                return;
 
        if (g_strcmp0(path, "/") == 0)
                return;
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface != NULL)
+       if (interface)
                return;
 
        interface = interface_alloc(path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
+       supplicant_dbus_method_call(path,
+                       SUPPLICANT_INTERFACE ".Interface.P2PDevice", "Flush",
+                       NULL, interface_p2p_flush, interface, NULL);
+
        dbus_message_iter_next(iter);
        if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
                supplicant_dbus_property_foreach(iter, interface_property,
@@ -1860,11 +1982,16 @@ static void interface_added(DBusMessageIter *iter, void *user_data)
 static void interface_removed(DBusMessageIter *iter, void *user_data)
 {
        const char *path = NULL;
+       GSupplicantInterface *interface = user_data;
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL)
+       if (!path)
                return;
 
+       interface = g_hash_table_lookup(interface_table, path);
+       SUPPLICANT_DBG("Cancelling any pending DBus calls");
+       supplicant_dbus_method_call_cancel_all(interface);
+
        g_hash_table_remove(interface_table, path);
 }
 
@@ -1874,10 +2001,10 @@ static void eap_method(DBusMessageIter *iter, void *user_data)
        int i;
 
        dbus_message_iter_get_basic(iter, &str);
-       if (str == NULL)
+       if (!str)
                return;
 
-       for (i = 0; eap_method_map[i].str != NULL; i++)
+       for (i = 0; eap_method_map[i].str; i++)
                if (strcmp(str, eap_method_map[i].str) == 0) {
                        eap_methods |= eap_method_map[i].val;
                        break;
@@ -1887,7 +2014,7 @@ static void eap_method(DBusMessageIter *iter, void *user_data)
 static void service_property(const char *key, DBusMessageIter *iter,
                                                        void *user_data)
 {
-       if (key == NULL) {
+       if (!key) {
                callback_system_ready();
                return;
        }
@@ -1897,7 +2024,7 @@ static void service_property(const char *key, DBusMessageIter *iter,
                int i;
 
                dbus_message_iter_get_basic(iter, &str);
-               for (i = 0; debug_strings[i] != NULL; i++)
+               for (i = 0; debug_strings[i]; i++)
                        if (g_strcmp0(debug_strings[i], str) == 0) {
                                debug_level = i;
                                break;
@@ -1934,7 +2061,7 @@ static void signal_name_owner_changed(const char *path, DBusMessageIter *iter)
                return;
 
        dbus_message_iter_get_basic(iter, &name);
-       if (name == NULL)
+       if (!name)
                return;
 
        if (g_strcmp0(name, SUPPLICANT_SERVICE) != 0)
@@ -1945,7 +2072,7 @@ static void signal_name_owner_changed(const char *path, DBusMessageIter *iter)
        dbus_message_iter_next(iter);
        dbus_message_iter_get_basic(iter, &new);
 
-       if (old == NULL || new == NULL)
+       if (!old || !new)
                return;
 
        if (strlen(old) > 0 && strlen(new) == 0) {
@@ -1996,7 +2123,7 @@ static void signal_interface_changed(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        supplicant_dbus_property_foreach(iter, interface_property, interface);
@@ -2010,17 +2137,22 @@ static void signal_scan_done(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        dbus_message_iter_get_basic(iter, &success);
 
+       if (interface->scanning) {
+               callback_scan_finished(interface);
+               interface->scanning = FALSE;
+       }
+
        /*
         * If scan is unsuccessful return -EIO else get the scanned BSSs
         * and update the network details accordingly
         */
-       if (success == FALSE) {
-               if (interface->scan_callback != NULL)
+       if (!success) {
+               if (interface->scan_callback)
                        interface->scan_callback(-EIO, interface,
                                                interface->scan_data);
 
@@ -2041,7 +2173,7 @@ static void signal_bss_added(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        interface_bss_added_with_keys(iter, interface);
@@ -2054,7 +2186,7 @@ static void signal_bss_removed(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        interface_bss_removed(iter, interface);
@@ -2067,7 +2199,7 @@ static void signal_network_added(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        interface_network_added(iter, interface);
@@ -2080,7 +2212,7 @@ static void signal_network_removed(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        interface_network_removed(iter, interface);
@@ -2096,15 +2228,15 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(bss_mapping, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        network = g_hash_table_lookup(interface->bss_mapping, path);
-       if (network == NULL)
+       if (!network)
                return;
 
        bss = g_hash_table_lookup(network->bss_table, path);
-       if (bss == NULL)
+       if (!bss)
                return;
 
        supplicant_dbus_property_foreach(iter, bss_property, bss);
@@ -2129,7 +2261,7 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
                 * plugin about it. */
 
                new_bss = g_try_new0(struct g_supplicant_bss, 1);
-               if (new_bss == NULL)
+               if (!new_bss)
                        return;
 
                memcpy(new_bss, bss, sizeof(struct g_supplicant_bss));
@@ -2159,7 +2291,8 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
                network->best_bss = bss;
        }
 
-       SUPPLICANT_DBG("New network signal for %s %d dBm", network->ssid, network->signal);
+       SUPPLICANT_DBG("New network signal for %s %d dBm", network->ssid,
+                       network->signal);
 
        callback_network_changed(network, "Signal");
 }
@@ -2169,7 +2302,7 @@ static void wps_credentials(const char *key, DBusMessageIter *iter,
 {
        GSupplicantInterface *interface = user_data;
 
-       if (key == NULL)
+       if (!key)
                return;
 
        SUPPLICANT_DBG("key %s", key);
@@ -2186,7 +2319,7 @@ static void wps_credentials(const char *key, DBusMessageIter *iter,
                interface->wps_cred.key = g_try_malloc0(
                                                sizeof(char) * key_len + 1);
 
-               if (interface->wps_cred.key == NULL)
+               if (!interface->wps_cred.key)
                        return;
 
                memcpy(interface->wps_cred.key, key_val,
@@ -2218,7 +2351,7 @@ static void signal_wps_credentials(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        supplicant_dbus_property_foreach(iter, wps_credentials, interface);
@@ -2229,7 +2362,7 @@ static void wps_event_args(const char *key, DBusMessageIter *iter,
 {
        GSupplicantInterface *interface = user_data;
 
-       if (key == NULL || interface == NULL)
+       if (!key || !interface)
                return;
 
        SUPPLICANT_DBG("Arg Key %s", key);
@@ -2243,7 +2376,7 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
        SUPPLICANT_DBG("");
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
+       if (!interface)
                return;
 
        dbus_message_iter_get_basic(iter, &name);
@@ -2252,7 +2385,7 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
 
        if (g_strcmp0(name, "success") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
-       else if (g_strcmp0(name, "failed") == 0)
+       else if (g_strcmp0(name, "fail") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
        else
                interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
@@ -2265,6 +2398,129 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
        supplicant_dbus_property_foreach(iter, wps_event_args, interface);
 }
 
+static void create_peer_identifier(GSupplicantPeer *peer)
+{
+       const unsigned char test[6] = {};
+
+       if (!peer)
+               return;
+
+       if (!memcmp(peer->device_address, test, 6)) {
+               peer->identifier = g_strdup(peer->name);
+               return;
+       }
+
+       peer->identifier = g_malloc0(19);
+       snprintf(peer->identifier, 19, "%02x%02x%02x%02x%02x%02x",
+                                               peer->device_address[0],
+                                               peer->device_address[1],
+                                               peer->device_address[2],
+                                               peer->device_address[3],
+                                               peer->device_address[4],
+                                               peer->device_address[5]);
+}
+
+static void peer_property(const char *key, DBusMessageIter *iter,
+                                                       void *user_data)
+{
+       GSupplicantPeer *peer = user_data;
+
+       SUPPLICANT_DBG("key: %s", key);
+
+       if (!peer->interface)
+               return;
+
+       if (!key) {
+               if (peer->name) {
+                       create_peer_identifier(peer);
+                       callback_peer_found(peer);
+               }
+
+               return;
+       }
+
+       if (g_strcmp0(key, "DeviceAddress") == 0) {
+               unsigned char *dev_addr;
+               DBusMessageIter array;
+               int len;
+
+               dbus_message_iter_recurse(iter, &array);
+               dbus_message_iter_get_fixed_array(&array, &dev_addr, &len);
+
+               if (len == 6)
+                       memcpy(peer->device_address, dev_addr, len);
+       } else if (g_strcmp0(key, "DeviceName") == 0) {
+               const char *str = NULL;
+
+               dbus_message_iter_get_basic(iter, &str);
+               if (str)
+                       peer->name = g_strdup(str);
+       }
+}
+
+static void signal_peer_found(const char *path, DBusMessageIter *iter)
+{
+       GSupplicantInterface *interface;
+       const char *obj_path = NULL;
+       GSupplicantPeer *peer;
+
+       SUPPLICANT_DBG("");
+
+       interface = g_hash_table_lookup(interface_table, path);
+       if (!interface)
+               return;
+
+       dbus_message_iter_get_basic(iter, &obj_path);
+       if (!obj_path || g_strcmp0(obj_path, "/") == 0)
+               return;
+
+       peer = g_hash_table_lookup(interface->peer_table, obj_path);
+       if (peer)
+               return;
+
+       peer = g_try_new0(GSupplicantPeer, 1);
+       if (!peer)
+               return;
+
+       peer->interface = interface;
+       peer->path = g_strdup(obj_path);
+       g_hash_table_insert(interface->peer_table, peer->path, peer);
+
+       dbus_message_iter_next(iter);
+       if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
+               supplicant_dbus_property_foreach(iter, peer_property, peer);
+               peer_property(NULL, NULL, peer);
+               return;
+       }
+
+       supplicant_dbus_property_get_all(obj_path,
+                       SUPPLICANT_INTERFACE ".Peer", peer_property, peer);
+}
+
+static void signal_peer_lost(const char *path, DBusMessageIter *iter)
+{
+       GSupplicantInterface *interface;
+       const char *obj_path = NULL;
+       GSupplicantPeer *peer;
+
+       SUPPLICANT_DBG("");
+
+       interface = g_hash_table_lookup(interface_table, path);
+       if (!interface)
+               return;
+
+       dbus_message_iter_get_basic(iter, &obj_path);
+       if (!obj_path || g_strcmp0(obj_path, "/") == 0)
+               return;
+
+       peer = g_hash_table_lookup(interface->peer_table, obj_path);
+       if (!peer)
+               return;
+
+       callback_peer_lost(peer);
+       g_hash_table_remove(interface->peer_table, obj_path);
+}
+
 static struct {
        const char *interface;
        const char *member;
@@ -2289,6 +2545,9 @@ static struct {
        { SUPPLICANT_INTERFACE ".Interface.WPS", "Credentials", signal_wps_credentials },
        { SUPPLICANT_INTERFACE ".Interface.WPS", "Event",       signal_wps_event       },
 
+       { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceFound", signal_peer_found },
+       { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceLost",  signal_peer_lost  },
+
        { }
 };
 
@@ -2300,19 +2559,17 @@ static DBusHandlerResult g_supplicant_filter(DBusConnection *conn,
        int i;
 
        path = dbus_message_get_path(message);
-       if (path == NULL)
+       if (!path)
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-       if (dbus_message_iter_init(message, &iter) == FALSE)
+       if (!dbus_message_iter_init(message, &iter))
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-       for (i = 0; signal_map[i].interface != NULL; i++) {
-               if (dbus_message_has_interface(message,
-                                       signal_map[i].interface) == FALSE)
+       for (i = 0; signal_map[i].interface; i++) {
+               if (!dbus_message_has_interface(message, signal_map[i].interface))
                        continue;
 
-               if (dbus_message_has_member(message,
-                                       signal_map[i].member) == FALSE)
+               if (!dbus_message_has_member(message, signal_map[i].member))
                        continue;
 
                signal_map[i].function(path, &iter);
@@ -2336,10 +2593,10 @@ static void country_result(const char *error,
 
        SUPPLICANT_DBG("Country setting result");
 
-       if (user_data == NULL)
+       if (!user_data)
                return;
 
-       if (error != NULL) {
+       if (error) {
                SUPPLICANT_DBG("Country setting failure %s", error);
                result = -EINVAL;
        }
@@ -2367,11 +2624,11 @@ int g_supplicant_set_country(const char *alpha2,
 
        SUPPLICANT_DBG("Country setting %s", alpha2);
 
-       if (system_available == FALSE)
+       if (!system_available)
                return -EFAULT;
 
        regdom = dbus_malloc0(sizeof(*regdom));
-       if (regdom == NULL)
+       if (!regdom)
                return -ENOMEM;
 
        regdom->callback = callback;
@@ -2392,7 +2649,7 @@ int g_supplicant_interface_set_country(GSupplicantInterface *interface,
        struct supplicant_regdom *regdom;
 
        regdom = dbus_malloc0(sizeof(*regdom));
-       if (regdom == NULL)
+       if (!regdom)
                return -ENOMEM;
 
        regdom->callback = callback;
@@ -2406,16 +2663,24 @@ int g_supplicant_interface_set_country(GSupplicantInterface *interface,
                                        regdom);
 }
 
+bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface)
+{
+       return interface->p2p_support;
+}
+
 struct interface_data {
        GSupplicantInterface *interface;
+       char *path; /* Interface path cannot be taken from interface (above) as
+                    * it might have been freed already.
+                    */
        GSupplicantInterfaceCallback callback;
        void *user_data;
 };
 
 struct interface_create_data {
-       const char *ifname;
-       const char *driver;
-       const char *bridge;
+       char *ifname;
+       char *driver;
+       char *bridge;
        GSupplicantInterface *interface;
        GSupplicantInterfaceCallback callback;
        void *user_data;
@@ -2423,6 +2688,7 @@ struct interface_create_data {
 
 struct interface_connect_data {
        GSupplicantInterface *interface;
+       char *path;
        GSupplicantInterfaceCallback callback;
        GSupplicantSSID *ssid;
        void *user_data;
@@ -2430,6 +2696,7 @@ struct interface_connect_data {
 
 struct interface_scan_data {
        GSupplicantInterface *interface;
+       char *path;
        GSupplicantInterfaceCallback callback;
        GSupplicantScanParams *scan_params;
        void *user_data;
@@ -2437,22 +2704,43 @@ struct interface_scan_data {
 
 struct interface_autoscan_data {
        GSupplicantInterface *interface;
+       char *path;
        GSupplicantInterfaceCallback callback;
        const char *autoscan_params;
        void *user_data;
 };
 
+static void interface_create_data_free(struct interface_create_data *data)
+{
+       g_free(data->ifname);
+       g_free(data->driver);
+       g_free(data->bridge);
+       dbus_free(data);
+}
+
+static bool interface_exists(GSupplicantInterface *interface,
+                               const char *path)
+{
+       GSupplicantInterface *tmp;
+
+       tmp = g_hash_table_lookup(interface_table, path);
+       if (tmp && tmp == interface)
+               return true;
+
+       return false;
+}
+
 static void interface_create_property(const char *key, DBusMessageIter *iter,
                                                        void *user_data)
 {
        struct interface_create_data *data = user_data;
        GSupplicantInterface *interface = data->interface;
 
-       if (key == NULL) {
-               if (data->callback != NULL)
+       if (!key) {
+               if (data->callback)
                        data->callback(0, data->interface, data->user_data);
 
-               dbus_free(data);
+               interface_create_data_free(data);
        }
 
        interface_property(key, iter, interface);
@@ -2467,27 +2755,27 @@ static void interface_create_result(const char *error,
 
        SUPPLICANT_DBG("");
 
-       if (error != NULL) {
+       if (error) {
                g_warning("error %s", error);
                err = -EIO;
                goto done;
        }
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL) {
+       if (!path) {
                err = -EINVAL;
                goto done;
        }
 
-       if (system_available == FALSE) {
+       if (!system_available) {
                err = -EFAULT;
                goto done;
        }
 
        data->interface = g_hash_table_lookup(interface_table, path);
-       if (data->interface == NULL) {
+       if (!data->interface) {
                data->interface = interface_alloc(path);
-               if (data->interface == NULL) {
+               if (!data->interface) {
                        err = -ENOMEM;
                        goto done;
                }
@@ -2500,10 +2788,10 @@ static void interface_create_result(const char *error,
                return;
 
 done:
-       if (data->callback != NULL)
+       if (data->callback)
                data->callback(err, NULL, data->user_data);
 
-       dbus_free(data);
+       interface_create_data_free(data);
 }
 
 static void interface_create_params(DBusMessageIter *iter, void *user_data)
@@ -2518,11 +2806,11 @@ static void interface_create_params(DBusMessageIter *iter, void *user_data)
        supplicant_dbus_dict_append_basic(&dict, "Ifname",
                                        DBUS_TYPE_STRING, &data->ifname);
 
-       if (data->driver != NULL)
+       if (data->driver)
                supplicant_dbus_dict_append_basic(&dict, "Driver",
                                        DBUS_TYPE_STRING, &data->driver);
 
-       if (data->bridge != NULL)
+       if (data->bridge)
                supplicant_dbus_dict_append_basic(&dict, "BridgeIfname",
                                        DBUS_TYPE_STRING, &data->bridge);
 
@@ -2539,32 +2827,32 @@ static void interface_get_result(const char *error,
 
        SUPPLICANT_DBG("");
 
-       if (error != NULL) {
+       if (error) {
                SUPPLICANT_DBG("Interface not created yet");
                goto create;
        }
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL) {
+       if (!path) {
                err = -EINVAL;
                goto done;
        }
 
        interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL) {
+       if (!interface) {
                err = -ENOENT;
                goto done;
        }
 
-       if (data->callback != NULL)
+       if (data->callback)
                data->callback(0, interface, data->user_data);
 
-       dbus_free(data);
+       interface_create_data_free(data);
 
        return;
 
 create:
-       if (system_available == FALSE) {
+       if (!system_available) {
                err = -EFAULT;
                goto done;
        }
@@ -2575,15 +2863,16 @@ create:
                                                SUPPLICANT_INTERFACE,
                                                "CreateInterface",
                                                interface_create_params,
-                                               interface_create_result, data);
+                                               interface_create_result, data,
+                                               NULL);
        if (err == 0)
                return;
 
 done:
-       if (data->callback != NULL)
+       if (data->callback)
                data->callback(err, NULL, data->user_data);
 
-       dbus_free(data);
+       interface_create_data_free(data);
 }
 
 static void interface_get_params(DBusMessageIter *iter, void *user_data)
@@ -2601,30 +2890,36 @@ int g_supplicant_interface_create(const char *ifname, const char *driver,
                                                        void *user_data)
 {
        struct interface_create_data *data;
+       int ret;
 
        SUPPLICANT_DBG("ifname %s", ifname);
 
-       if (ifname == NULL)
+       if (!ifname)
                return -EINVAL;
 
-       if (system_available == FALSE)
+       if (!system_available)
                return -EFAULT;
 
        data = dbus_malloc0(sizeof(*data));
-       if (data == NULL)
+       if (!data)
                return -ENOMEM;
 
-       data->ifname = ifname;
-       data->driver = driver;
-       data->bridge = bridge;
+       data->ifname = g_strdup(ifname);
+       data->driver = g_strdup(driver);
+       data->bridge = g_strdup(bridge);
        data->callback = callback;
        data->user_data = user_data;
 
-       return supplicant_dbus_method_call(SUPPLICANT_PATH,
+       ret = supplicant_dbus_method_call(SUPPLICANT_PATH,
                                                SUPPLICANT_INTERFACE,
                                                "GetInterface",
                                                interface_get_params,
-                                               interface_get_result, data);
+                                               interface_get_result, data,
+                                               NULL);
+       if (ret < 0)
+               interface_create_data_free(data);
+
+       return ret;
 }
 
 static void interface_remove_result(const char *error,
@@ -2633,12 +2928,12 @@ static void interface_remove_result(const char *error,
        struct interface_data *data = user_data;
        int err;
 
-       if (error != NULL) {
+       if (error) {
                err = -EIO;
                goto done;
        }
 
-       if (system_available == FALSE) {
+       if (!system_available) {
                err = -EFAULT;
                goto done;
        }
@@ -2650,7 +2945,9 @@ static void interface_remove_result(const char *error,
        err = 0;
 
 done:
-       if (data->callback != NULL)
+       g_free(data->path);
+
+       if (data->callback)
                data->callback(err, NULL, data->user_data);
 
        dbus_free(data);
@@ -2671,26 +2968,37 @@ int g_supplicant_interface_remove(GSupplicantInterface *interface,
                                                        void *user_data)
 {
        struct interface_data *data;
+       int ret;
 
-       if (interface == NULL)
+       if (!interface)
                return -EINVAL;
 
-       if (system_available == FALSE)
+       if (!system_available)
                return -EFAULT;
 
+       SUPPLICANT_DBG("Cancelling any pending DBus calls");
+       supplicant_dbus_method_call_cancel_all(interface);
+
        data = dbus_malloc0(sizeof(*data));
-       if (data == NULL)
+       if (!data)
                return -ENOMEM;
 
        data->interface = interface;
+       data->path = g_strdup(interface->path);
        data->callback = callback;
        data->user_data = user_data;
 
-       return supplicant_dbus_method_call(SUPPLICANT_PATH,
+       ret = supplicant_dbus_method_call(SUPPLICANT_PATH,
                                                SUPPLICANT_INTERFACE,
                                                "RemoveInterface",
                                                interface_remove_params,
-                                               interface_remove_result, data);
+                                               interface_remove_result, data,
+                                               NULL);
+       if (ret < 0) {
+               g_free(data->path);
+               dbus_free(data);
+       }
+       return ret;
 }
 
 static void interface_scan_result(const char *error,
@@ -2699,24 +3007,28 @@ static void interface_scan_result(const char *error,
        struct interface_scan_data *data = user_data;
        int err = 0;
 
-       if (error != NULL) {
+       if (error) {
                SUPPLICANT_DBG("error %s", error);
                err = -EIO;
        }
 
        /* A non ready interface cannot send/receive anything */
-       if (data->interface->ready == FALSE)
-               err = -ENOLINK;
+       if (interface_exists(data->interface, data->path)) {
+               if (!data->interface->ready)
+                       err = -ENOLINK;
+       }
+
+       g_free(data->path);
 
        if (err != 0) {
-               if (data->callback != NULL)
+               if (data->callback)
                        data->callback(err, data->interface, data->user_data);
        } else {
                data->interface->scan_callback = data->callback;
                data->interface->scan_data = data->user_data;
        }
 
-       if (data != NULL && data->scan_params != NULL)
+       if (data->scan_params)
                g_supplicant_free_scan_params(data->scan_params);
 
        dbus_free(data);
@@ -2842,21 +3154,15 @@ static void interface_scan_params(DBusMessageIter *iter, void *user_data)
        supplicant_dbus_dict_close(iter, &dict);
 }
 
-int g_supplicant_interface_scan(GSupplicantInterface *interface,
-                               GSupplicantScanParams *scan_data,
-                               GSupplicantInterfaceCallback callback,
-                                                       void *user_data)
+static int interface_ready_to_scan(GSupplicantInterface *interface)
 {
-       struct interface_scan_data *data;
-       int ret;
-
-       if (interface == NULL)
+       if (!interface)
                return -EINVAL;
 
-       if (system_available == FALSE)
+       if (!system_available)
                return -EFAULT;
 
-       if (interface->scanning == TRUE)
+       if (interface->scanning)
                return -EALREADY;
 
        switch (interface->state) {
@@ -2875,11 +3181,27 @@ int g_supplicant_interface_scan(GSupplicantInterface *interface,
                break;
        }
 
+       return 0;
+}
+
+int g_supplicant_interface_scan(GSupplicantInterface *interface,
+                               GSupplicantScanParams *scan_data,
+                               GSupplicantInterfaceCallback callback,
+                                                       void *user_data)
+{
+       struct interface_scan_data *data;
+       int ret;
+
+       ret = interface_ready_to_scan(interface);
+       if (ret)
+               return ret;
+
        data = dbus_malloc0(sizeof(*data));
-       if (data == NULL)
+       if (!data)
                return -ENOMEM;
 
        data->interface = interface;
+       data->path = g_strdup(interface->path);
        data->callback = callback;
        data->user_data = user_data;
        data->scan_params = scan_data;
@@ -2889,10 +3211,13 @@ int g_supplicant_interface_scan(GSupplicantInterface *interface,
 
        ret = supplicant_dbus_method_call(interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "Scan",
-                       interface_scan_params, interface_scan_result, data);
+                       interface_scan_params, interface_scan_result, data,
+                       interface);
 
-       if (ret < 0)
+       if (ret < 0) {
+               g_free(data->path);
                dbus_free(data);
+       }
 
        return ret;
 }
@@ -2903,12 +3228,14 @@ static void interface_autoscan_result(const char *error,
        struct interface_autoscan_data *data = user_data;
        int err = 0;
 
-       if (error != NULL) {
+       if (error) {
                SUPPLICANT_DBG("error %s", error);
                err = -EIO;
        }
 
-       if (data != NULL && data->callback != NULL)
+       g_free(data->path);
+
+       if (data->callback)
                data->callback(err, data->interface, data->user_data);
 
        dbus_free(data);
@@ -2931,10 +3258,11 @@ int g_supplicant_interface_autoscan(GSupplicantInterface *interface,
        int ret;
 
        data = dbus_malloc0(sizeof(*data));
-       if (data == NULL)
+       if (!data)
                return -ENOMEM;
 
        data->interface = interface;
+       data->path = g_strdup(interface->path);
        data->callback = callback;
        data->autoscan_params = autoscan_data;
        data->user_data = user_data;
@@ -2942,9 +3270,12 @@ int g_supplicant_interface_autoscan(GSupplicantInterface *interface,
        ret = supplicant_dbus_method_call(interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "AutoScan",
                        interface_autoscan_params,
-                       interface_autoscan_result, data);
-       if (ret < 0)
+                       interface_autoscan_result, data,
+                       interface);
+       if (ret < 0) {
+               g_free(data->path);
                dbus_free(data);
+       }
 
        return ret;
 }
@@ -2981,12 +3312,14 @@ static void interface_select_network_result(const char *error,
        SUPPLICANT_DBG("");
 
        err = 0;
-       if (error != NULL) {
+       if (error) {
                SUPPLICANT_DBG("SelectNetwork error %s", error);
                err = parse_supplicant_error(iter);
        }
 
-       if (data->callback != NULL)
+       g_free(data->path);
+
+       if (data->callback)
                data->callback(err, data->interface, data->user_data);
 
        g_free(data->ssid);
@@ -3011,11 +3344,11 @@ static void interface_add_network_result(const char *error,
        const char *path;
        int err;
 
-       if (error != NULL)
+       if (error)
                goto error;
 
        dbus_message_iter_get_basic(iter, &path);
-       if (path == NULL)
+       if (!path)
                goto error;
 
        SUPPLICANT_DBG("PATH: %s", path);
@@ -3026,18 +3359,24 @@ static void interface_add_network_result(const char *error,
        supplicant_dbus_method_call(data->interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "SelectNetwork",
                        interface_select_network_params,
-                       interface_select_network_result, data);
+                       interface_select_network_result, data,
+                       interface);
 
        return;
 
 error:
        SUPPLICANT_DBG("AddNetwork error %s", error);
-       err = parse_supplicant_error(iter);
-       if (data->callback != NULL)
-               data->callback(err, data->interface, data->user_data);
 
-       g_free(interface->network_path);
-       interface->network_path = NULL;
+       if (interface_exists(data->interface, data->interface->path)) {
+               err = parse_supplicant_error(iter);
+               if (data->callback)
+                       data->callback(err, data->interface, data->user_data);
+
+               g_free(interface->network_path);
+               interface->network_path = NULL;
+       }
+
+       g_free(data->path);
        g_free(data->ssid);
        g_free(data);
 }
@@ -3046,7 +3385,7 @@ static void add_network_security_wep(DBusMessageIter *dict,
                                        GSupplicantSSID *ssid)
 {
        const char *auth_alg = "OPEN SHARED";
-       const char *key_index = "0";
+       dbus_uint32_t key_index = 0;
 
        supplicant_dbus_dict_append_basic(dict, "auth_alg",
                                        DBUS_TYPE_STRING, &auth_alg);
@@ -3059,7 +3398,7 @@ static void add_network_security_wep(DBusMessageIter *dict,
                        int i;
 
                        memset(tmp, 0, sizeof(tmp));
-                       if (key == NULL)
+                       if (!key)
                                size = 0;
 
                        for (i = 0; i < size / 2; i++) {
@@ -3076,7 +3415,7 @@ static void add_network_security_wep(DBusMessageIter *dict,
                        unsigned char *key = g_try_malloc(13);
                        int i;
 
-                       if (key == NULL)
+                       if (!key)
                                size = 0;
 
                        for (i = 0; i < size; i++)
@@ -3094,7 +3433,7 @@ static void add_network_security_wep(DBusMessageIter *dict,
                                                        &ssid->passphrase);
 
                supplicant_dbus_dict_append_basic(dict, "wep_tx_keyidx",
-                                       DBUS_TYPE_STRING, &key_index);
+                                       DBUS_TYPE_UINT32, &key_index);
        }
 }
 
@@ -3126,7 +3465,8 @@ static unsigned char hexchar2bin(char c)
                return c;
 }
 
-static void hexstring2bin(const char *string, unsigned char *data, size_t data_len)
+static void hexstring2bin(const char *string, unsigned char *data,
+                               size_t data_len)
 {
        size_t i;
 
@@ -3141,7 +3481,7 @@ static void add_network_security_psk(DBusMessageIter *dict,
        if (ssid->passphrase && strlen(ssid->passphrase) > 0) {
                const char *key = "psk";
 
-               if (is_psk_raw_key(ssid->passphrase) == TRUE) {
+               if (is_psk_raw_key(ssid->passphrase)) {
                        unsigned char data[32];
                        unsigned char *datap = data;
 
@@ -3172,13 +3512,13 @@ static void add_network_security_tls(DBusMessageIter *dict,
         *
         * The Authority certificate is optional.
         */
-       if (ssid->client_cert_path == NULL)
+       if (!ssid->client_cert_path)
                return;
 
-       if (ssid->private_key_path == NULL)
+       if (!ssid->private_key_path)
                return;
 
-       if (ssid->private_key_passphrase == NULL)
+       if (!ssid->private_key_passphrase)
                return;
 
        if (ssid->ca_cert_path)
@@ -3212,17 +3552,17 @@ static void add_network_security_peap(DBusMessageIter *dict,
         *              The Client private key file
         *              The Client private key file password
         */
-       if (ssid->passphrase == NULL)
+       if (!ssid->passphrase)
                return;
 
-       if (ssid->phase2_auth == NULL)
+       if (!ssid->phase2_auth)
                return;
 
        if (ssid->client_cert_path) {
-               if (ssid->private_key_path == NULL)
+               if (!ssid->private_key_path)
                        return;
 
-               if (ssid->private_key_passphrase == NULL)
+               if (!ssid->private_key_passphrase)
                        return;
 
                supplicant_dbus_dict_append_basic(dict, "client_cert",
@@ -3239,7 +3579,7 @@ static void add_network_security_peap(DBusMessageIter *dict,
 
        }
 
-       if (g_str_has_prefix(ssid->phase2_auth, "EAP-") == TRUE) {
+       if (g_str_has_prefix(ssid->phase2_auth, "EAP-")) {
                phase2_auth = g_strdup_printf("autheap=%s",
                                        ssid->phase2_auth + strlen("EAP-"));
        } else
@@ -3266,7 +3606,7 @@ static void add_network_security_eap(DBusMessageIter *dict,
 {
        char *eap_value;
 
-       if (ssid->eap == NULL || ssid->identity == NULL)
+       if (!ssid->eap || !ssid->identity)
                return;
 
        if (g_strcmp0(ssid->eap, "tls") == 0) {
@@ -3448,7 +3788,7 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
                supplicant_dbus_dict_append_basic(&dict, "frequency",
                                         DBUS_TYPE_UINT32, &ssid->freq);
 
-       if (ssid->bgscan != NULL)
+       if (ssid->bgscan)
                supplicant_dbus_dict_append_basic(&dict, "bgscan",
                                        DBUS_TYPE_STRING, &ssid->bgscan);
 
@@ -3469,9 +3809,10 @@ static void interface_wps_start_result(const char *error,
        struct interface_connect_data *data = user_data;
 
        SUPPLICANT_DBG("");
-       if (error != NULL)
+       if (error)
                SUPPLICANT_DBG("error: %s", error);
 
+       g_free(data->path);
        g_free(data->ssid);
        dbus_free(data);
 }
@@ -3491,7 +3832,7 @@ static void interface_add_wps_params(DBusMessageIter *iter, void *user_data)
                                                DBUS_TYPE_STRING, &role);
 
        type = "pbc";
-       if (ssid->pin_wps != NULL) {
+       if (ssid->pin_wps) {
                type = "pin";
                supplicant_dbus_dict_append_basic(&dict, "Pin",
                                        DBUS_TYPE_STRING, &ssid->pin_wps);
@@ -3509,8 +3850,9 @@ static void wps_start(const char *error, DBusMessageIter *iter, void *user_data)
 
        SUPPLICANT_DBG("");
 
-       if (error != NULL) {
+       if (error) {
                SUPPLICANT_DBG("error: %s", error);
+               g_free(data->path);
                g_free(data->ssid);
                dbus_free(data);
                return;
@@ -3519,7 +3861,7 @@ static void wps_start(const char *error, DBusMessageIter *iter, void *user_data)
        supplicant_dbus_method_call(data->interface->path,
                        SUPPLICANT_INTERFACE ".Interface.WPS", "Start",
                        interface_add_wps_params,
-                       interface_wps_start_result, data);
+                       interface_wps_start_result, data, NULL);
 }
 
 static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
@@ -3540,24 +3882,25 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
        struct interface_connect_data *data;
        int ret;
 
-       if (interface == NULL)
+       if (!interface)
                return -EINVAL;
 
-       if (system_available == FALSE)
+       if (!system_available)
                return -EFAULT;
 
        /* TODO: Check if we're already connected and switch */
 
        data = dbus_malloc0(sizeof(*data));
-       if (data == NULL)
+       if (!data)
                return -ENOMEM;
 
        data->interface = interface;
+       data->path = g_strdup(interface->path);
        data->callback = callback;
        data->ssid = ssid;
        data->user_data = user_data;
 
-       if (ssid->use_wps == TRUE) {
+       if (ssid->use_wps) {
                g_free(interface->wps_cred.key);
                memset(&interface->wps_cred, 0,
                                sizeof(struct _GSupplicantWpsCredentials));
@@ -3570,10 +3913,14 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                ret = supplicant_dbus_method_call(interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
                        interface_add_network_params,
-                       interface_add_network_result, data);
+                       interface_add_network_result, data,
+                       interface);
 
-       if (ret < 0)
+       if (ret < 0) {
+               g_free(data->path);
+               dbus_free(data);
                return ret;
+       }
 
        return -EINPROGRESS;
 }
@@ -3586,14 +3933,16 @@ static void network_remove_result(const char *error,
 
        SUPPLICANT_DBG("");
 
-       if (error != NULL) {
+       if (error) {
                result = -EIO;
                if (g_strcmp0("org.freedesktop.DBus.Error.UnknownMethod",
                                                error) == 0)
                        result = -ECONNABORTED;
        }
 
-       if (data->callback != NULL)
+       g_free(data->path);
+
+       if (data->callback)
                data->callback(result, data->interface, data->user_data);
 
        dbus_free(data);
@@ -3617,7 +3966,8 @@ static int network_remove(struct interface_data *data)
 
        return supplicant_dbus_method_call(interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "RemoveNetwork",
-                       network_remove_params, network_remove_result, data);
+                       network_remove_params, network_remove_result, data,
+                       interface);
 }
 
 static void interface_disconnect_result(const char *error,
@@ -3628,14 +3978,14 @@ static void interface_disconnect_result(const char *error,
 
        SUPPLICANT_DBG("");
 
-       if (error != NULL) {
+       if (error) {
                result = -EIO;
                if (g_strcmp0("org.freedesktop.DBus.Error.UnknownMethod",
                                                error) == 0)
                        result = -ECONNABORTED;
        }
 
-       if (result < 0 && data->callback != NULL) {
+       if (result < 0 && data->callback) {
                data->callback(result, data->interface, data->user_data);
                data->callback = NULL;
        }
@@ -3643,15 +3993,21 @@ static void interface_disconnect_result(const char *error,
        /* If we are disconnecting from previous WPS successful
         * association. i.e.: it did not went through AddNetwork,
         * and interface->network_path was never set. */
-       if (data->interface->network_path == NULL) {
+       if (!data->interface->network_path) {
+               g_free(data->path);
                dbus_free(data);
                return;
        }
 
-       if (result != -ECONNABORTED)
-               network_remove(data);
-       else
+       if (result != -ECONNABORTED) {
+               if (network_remove(data) < 0) {
+                       g_free(data->path);
+                       dbus_free(data);
+               }
+       } else {
+               g_free(data->path);
                dbus_free(data);
+       }
 }
 
 int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
@@ -3659,28 +4015,119 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
                                                        void *user_data)
 {
        struct interface_data *data;
+       int ret;
 
        SUPPLICANT_DBG("");
 
-       if (interface == NULL)
+       if (!interface)
                return -EINVAL;
 
-       if (system_available == FALSE)
+       if (!system_available)
                return -EFAULT;
 
        data = dbus_malloc0(sizeof(*data));
-       if (data == NULL)
+       if (!data)
                return -ENOMEM;
 
        data->interface = interface;
+       data->path = g_strdup(interface->path);
        data->callback = callback;
        data->user_data = user_data;
 
-       return supplicant_dbus_method_call(interface->path,
+       ret = supplicant_dbus_method_call(interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "Disconnect",
-                               NULL, interface_disconnect_result, data);
+                       NULL, interface_disconnect_result, data,
+                       interface);
+
+       if (ret < 0) {
+               g_free(data->path);
+               dbus_free(data);
+       }
+
+       return ret;
 }
 
+static void interface_p2p_find_result(const char *error,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct interface_scan_data *data = user_data;
+       int err = 0;
+
+       SUPPLICANT_DBG("error %s", error);
+
+       if (error)
+               err = -EIO;
+
+       if (interface_exists(data->interface, data->path)) {
+               if (!data->interface->ready)
+                       err = -ENOLINK;
+               if (!err)
+                       data->interface->p2p_finding = true;
+       }
+
+       if (data->callback)
+               data->callback(err, data->interface, data->user_data);
+
+       g_free(data->path);
+       dbus_free(data);
+}
+
+static void interface_p2p_find_params(DBusMessageIter *iter, void *user_data)
+{
+       DBusMessageIter dict;
+
+       supplicant_dbus_dict_open(iter, &dict);
+       supplicant_dbus_dict_close(iter, &dict);
+}
+
+int g_supplicant_interface_p2p_find(GSupplicantInterface *interface,
+                                       GSupplicantInterfaceCallback callback,
+                                                       void *user_data)
+{
+       struct interface_scan_data *data;
+       int ret;
+
+       if (!interface->p2p_support)
+               return -ENOTSUP;
+
+       ret = interface_ready_to_scan(interface);
+       if (ret)
+               return ret;
+
+       data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
+
+       data->interface = interface;
+       data->path = g_strdup(interface->path);
+       data->callback = callback;
+       data->user_data = user_data;
+
+       ret = supplicant_dbus_method_call(interface->path,
+                       SUPPLICANT_INTERFACE ".Interface.P2PDevice", "Find",
+                       interface_p2p_find_params, interface_p2p_find_result,
+                       data, interface);
+       if (ret < 0) {
+               g_free(data->path);
+               dbus_free(data);
+       }
+
+       return ret;
+}
+
+int g_supplicant_interface_p2p_stop_find(GSupplicantInterface *interface)
+{
+       if (!interface->p2p_finding)
+               return 0;
+
+       SUPPLICANT_DBG("");
+
+       interface->p2p_finding = false;
+
+       return supplicant_dbus_method_call(interface->path,
+               SUPPLICANT_INTERFACE ".Interface.P2PDevice", "StopFind",
+               NULL, NULL, NULL, NULL);
+}
 
 static const char *g_supplicant_rule0 = "type=signal,"
                                        "path=" DBUS_PATH_DBUS ","
@@ -3698,6 +4145,8 @@ static const char *g_supplicant_rule4 = "type=signal,"
                        "interface=" SUPPLICANT_INTERFACE ".BSS";
 static const char *g_supplicant_rule5 = "type=signal,"
                        "interface=" SUPPLICANT_INTERFACE ".Network";
+static const char *g_supplicant_rule6 = "type=signal,"
+               "interface=" SUPPLICANT_INTERFACE ".Interface.P2PDevice";
 
 static void invoke_introspect_method(void)
 {
@@ -3708,7 +4157,7 @@ static void invoke_introspect_method(void)
                                        DBUS_INTERFACE_INTROSPECTABLE,
                                        "Introspect");
 
-       if (message == NULL)
+       if (!message)
                return;
 
        dbus_message_set_no_reply(message, TRUE);
@@ -3719,11 +4168,11 @@ static void invoke_introspect_method(void)
 int g_supplicant_register(const GSupplicantCallbacks *callbacks)
 {
        connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-       if (connection == NULL)
+       if (!connection)
                return -EIO;
 
-       if (dbus_connection_add_filter(connection,
-                               g_supplicant_filter, NULL, NULL) == FALSE) {
+       if (!dbus_connection_add_filter(connection, g_supplicant_filter,
+                                               NULL, NULL)) {
                dbus_connection_unref(connection);
                connection = NULL;
                return -EIO;
@@ -3746,10 +4195,11 @@ int g_supplicant_register(const GSupplicantCallbacks *callbacks)
        dbus_bus_add_match(connection, g_supplicant_rule3, NULL);
        dbus_bus_add_match(connection, g_supplicant_rule4, NULL);
        dbus_bus_add_match(connection, g_supplicant_rule5, NULL);
+       dbus_bus_add_match(connection, g_supplicant_rule6, NULL);
        dbus_connection_flush(connection);
 
        if (dbus_bus_name_has_owner(connection,
-                                       SUPPLICANT_SERVICE, NULL) == TRUE) {
+                                       SUPPLICANT_SERVICE, NULL)) {
                system_available = TRUE;
                supplicant_dbus_property_get_all(SUPPLICANT_PATH,
                                                SUPPLICANT_INTERFACE,
@@ -3779,14 +4229,14 @@ static void unregister_remove_interface(gpointer key, gpointer value,
                                        SUPPLICANT_INTERFACE,
                                        "RemoveInterface",
                                        unregister_interface_remove_params,
-                                               NULL, interface->path);
+                                       NULL, interface->path, NULL);
 }
 
 void g_supplicant_unregister(const GSupplicantCallbacks *callbacks)
 {
        SUPPLICANT_DBG("");
 
-       if (connection != NULL) {
+       if (connection) {
                dbus_bus_remove_match(connection, g_supplicant_rule5, NULL);
                dbus_bus_remove_match(connection, g_supplicant_rule4, NULL);
                dbus_bus_remove_match(connection, g_supplicant_rule3, NULL);
@@ -3799,22 +4249,22 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks)
                                                g_supplicant_filter, NULL);
        }
 
-       if (bss_mapping != NULL) {
+       if (bss_mapping) {
                g_hash_table_destroy(bss_mapping);
                bss_mapping = NULL;
        }
 
-       if (system_available == TRUE)
+       if (system_available)
                callback_system_killed();
 
-       if (interface_table != NULL) {
+       if (interface_table) {
                g_hash_table_foreach(interface_table,
                                        unregister_remove_interface, NULL);
                g_hash_table_destroy(interface_table);
                interface_table = NULL;
        }
 
-       if (connection != NULL) {
+       if (connection) {
                dbus_connection_unref(connection);
                connection = NULL;
        }