Send connman mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."


Today's Topics:

   1. [PATCH v2 3/4] wps: add new interface to communicate
      wpa_supplicant ([email protected])


----------------------------------------------------------------------

Message: 1
Date: Fri, 31 Aug 2018 11:14:07 +0000
From: <[email protected]>
To: <[email protected]>
Cc: <[email protected]>, <[email protected]>,
        <[email protected]>
Subject: [PATCH v2 3/4] wps: add new interface to communicate
        wpa_supplicant
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="us-ascii"

Add new WPS start/cancel interface.
Add wpa_supplicant wps event callback for WPS state tracing.
Add wps credential callback to hand over into wifi plugin.

Signed-off-by: n-itaya <[email protected]>
---
 gsupplicant/gsupplicant.h |  35 +++
 gsupplicant/supplicant.c  | 485 ++++++++++++++++++++++++++++++--------
 2 files changed, 424 insertions(+), 96 deletions(-)

diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index db61595b..e525d1c3 100644
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -84,6 +84,18 @@ extern "C" {
 #define G_SUPPLICANT_GROUP_ROLE_CLIENT (1 << 0)
 #define G_SUPPLICANT_GROUP_ROLE_GO      (1 << 1)
 
+#define G_SUPPLICANT_WPS_AUTH_OPEN             (1 << 0)
+#define G_SUPPLICANT_WPS_AUTH_WPA_PSK  (1 << 1)
+#define G_SUPPLICANT_WPS_AUTH_SHARED   (1 << 2) /* Depricated */
+#define G_SUPPLICANT_WPS_AUTH_WPA_EAP  (1 << 3)
+#define G_SUPPLICANT_WPS_AUTH_WPA2_EAP (1 << 4)
+#define G_SUPPLICANT_WPS_AUTH_WPA2_PSK (1 << 5)
+
+#define G_SUPPLICANT_WPS_ENCR_NONE             (1 << 0)
+#define G_SUPPLICANT_WPS_ENCR_WEP              (1 << 1)
+#define G_SUPPLICANT_WPS_ENCR_TKIP             (1 << 2)
+#define G_SUPPLICANT_WPS_ENCR_AES              (1 << 3)
+
 typedef enum {
        G_SUPPLICANT_MODE_UNKNOWN,
        G_SUPPLICANT_MODE_INFRA,
@@ -159,6 +171,13 @@ struct _GSupplicantSSID {
 
 typedef struct _GSupplicantSSID GSupplicantSSID;
 
+struct _GSupplicantWPSParams {
+       GSupplicantMode mode;
+       const char *pin;
+};
+
+typedef struct _GSupplicantWPSParams GSupplicantWPSParams;
+
 struct scan_ssid {
        unsigned char ssid[32];
        uint8_t ssid_len;
@@ -259,6 +278,15 @@ int g_supplicant_set_widi_ies(GSupplicantP2PServiceParams 
*p2p_service_params,
                                        GSupplicantInterfaceCallback callback,
                                        void *user_data);
 
+int g_supplicant_interface_wps_cancel(GSupplicantInterface *interface,
+                                     GSupplicantInterfaceCallback callback,
+                                     void *user_data);
+
+int g_supplicant_interface_wps_start(GSupplicantInterface *interface,
+                                       GSupplicantWPSParams *wps,
+                                       GSupplicantInterfaceCallback callback,
+                                       void *user_data);
+
 int g_supplicant_interface_connect(GSupplicantInterface *interface,
                                        GSupplicantSSID *ssid,
                                        GSupplicantInterfaceCallback callback,
@@ -292,6 +320,7 @@ int g_supplicant_interface_set_country(GSupplicantInterface 
*interface,
                                        GSupplicantCountryCallback callback,
                                                        const char *alpha2,
                                                        void *user_data);
+bool g_supplicant_interface_support_wps(GSupplicantInterface *interface);
 bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface);
 int g_supplicant_interface_set_p2p_device_config(GSupplicantInterface 
*interface,
                                                const char *device_name,
@@ -299,6 +328,8 @@ int 
g_supplicant_interface_set_p2p_device_config(GSupplicantInterface *interface
 GSupplicantPeer *g_supplicant_interface_peer_lookup(GSupplicantInterface 
*interface,
                                                const char *identifier);
 bool g_supplicant_interface_is_p2p_finding(GSupplicantInterface *interface);
+void g_supplicant_interface_flushBSS(GSupplicantInterface *interface,
+                                    unsigned int age);
 
 /* Network and Peer API */
 struct _GSupplicantNetwork;
@@ -352,6 +383,8 @@ struct _GSupplicantCallbacks {
        void (*network_changed) (GSupplicantNetwork *network,
                                        const char *property);
        void (*network_associated) (GSupplicantNetwork *network);
+       void (*wps_event)(GSupplicantInterface *interface,
+                                       GSupplicantWpsState event, int error);
        void (*peer_found) (GSupplicantPeer *peer);
        void (*peer_lost) (GSupplicantPeer *peer);
        void (*peer_changed) (GSupplicantPeer *peer,
@@ -362,6 +395,8 @@ struct _GSupplicantCallbacks {
                                int reasoncode);
        void (*assoc_status_code)(GSupplicantInterface *interface,
                                int reasoncode);
+       void (*wps_credential)(GSupplicantInterface *interface,
+                              const char *group);
 };
 
 typedef struct _GSupplicantCallbacks GSupplicantCallbacks;
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 5246c80b..2883e03e 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -138,6 +138,24 @@ static struct strvalmap mode_capa_map[] = {
        { }
 };
 
+static struct strvalmap wps_auth_map[] = {
+       { "open",               G_SUPPLICANT_WPS_AUTH_OPEN              },
+       { "shared",             G_SUPPLICANT_WPS_AUTH_SHARED    },
+       { "wpa-psk",    G_SUPPLICANT_WPS_AUTH_WPA_PSK   },
+       { "wpa-eap",    G_SUPPLICANT_WPS_AUTH_WPA_EAP   },
+       { "wpa2-eap",   G_SUPPLICANT_WPS_AUTH_WPA2_EAP  },
+       { "wpa2-psk",   G_SUPPLICANT_WPS_AUTH_WPA2_PSK  },
+       { }
+};
+
+static struct strvalmap wps_encr_map[] = {
+       { "none",               G_SUPPLICANT_WPS_ENCR_NONE              },
+       { "wep",                G_SUPPLICANT_WPS_ENCR_WEP               },
+       { "tkip",               G_SUPPLICANT_WPS_ENCR_TKIP              },
+       { "aes",                G_SUPPLICANT_WPS_ENCR_AES               },
+       { }
+};
+
 static GHashTable *interface_table;
 static GHashTable *bss_mapping;
 static GHashTable *peer_mapping;
@@ -146,9 +164,14 @@ static GHashTable *pending_peer_connection;
 static GHashTable *config_file_table;
 
 struct _GSupplicantWpsCredentials {
+       unsigned char bssid[6];
        unsigned char ssid[32];
        unsigned int ssid_len;
+
        char *key;
+
+       unsigned int authtype;
+       unsigned int encrtype;
 };
 
 struct added_network_information {
@@ -181,6 +204,7 @@ struct _GSupplicantInterface {
        char *ifname;
        char *driver;
        char *bridge;
+       bool wps_support;
        struct _GSupplicantWpsCredentials wps_cred;
        GSupplicantWpsState wps_state;
        GHashTable *network_table;
@@ -287,6 +311,7 @@ struct interface_connect_data {
        union {
                GSupplicantSSID *ssid;
                GSupplicantPeerParams *peer;
+               GSupplicantWPSParams *wps;
        };
 };
 
@@ -298,6 +323,12 @@ struct interface_scan_data {
        void *user_data;
 };
 
+struct wps_event_args {
+       int msg; /* enum wps_msg_type */
+       int config_error; /* enum wps_config_error */
+       int error_indication; /* enum wps_error_indication */
+};
+
 static int network_remove(struct interface_data *data);
 
 static inline void debug(const char *format, ...)
@@ -614,6 +645,19 @@ static void callback_network_associated(GSupplicantNetwork 
*network)
        callbacks_pointer->network_associated(network);
 }
 
+static void callback_wps_event(GSupplicantInterface *interface,
+                                       GSupplicantWpsState state, int error)
+{
+       SUPPLICANT_DBG("");
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->wps_event)
+               return;
+
+       callbacks_pointer->wps_event(interface, state, error);
+}
+
 static void callback_peer_found(GSupplicantPeer *peer)
 {
        if (!callbacks_pointer)
@@ -688,6 +732,18 @@ static void 
callback_assoc_status_code(GSupplicantInterface *interface,
 
 }
 
+static void callback_wps_credential(GSupplicantInterface *interface,
+                                   const char *group)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->assoc_status_code)
+               return;
+
+       callbacks_pointer->wps_credential(interface, group);
+}
+
 static void remove_group(gpointer data)
 {
        GSupplicantGroup *group = data;
@@ -863,8 +919,8 @@ static void interface_capability_pairwise(DBusMessageIter 
*iter,
                        break;
                }
 }
-
 static void interface_capability_group(DBusMessageIter *iter, void *user_data)
+
 {
        GSupplicantInterface *interface = user_data;
        const char *str = NULL;
@@ -2209,6 +2265,15 @@ static void interface_bss_removed(DBusMessageIter *iter, 
void *user_data)
                g_hash_table_remove(interface->network_table, network->group);
 }
 
+static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
+{
+       dbus_bool_t credentials = FALSE;
+
+       SUPPLICANT_DBG("");
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
+}
+
 static void set_config_methods(DBusMessageIter *iter, void *user_data)
 {
        dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
@@ -2285,6 +2350,16 @@ static void interface_property(const char *key, 
DBusMessageIter *iter,
                                                                interface);
                if (interface->mode_capa & G_SUPPLICANT_CAPABILITY_MODE_P2P)
                        interface->p2p_support = true;
+
+               if (interface->keymgmt_capa & G_SUPPLICANT_KEYMGMT_WPS) {
+                       interface->wps_support = true;
+
+                       supplicant_dbus_property_set(interface->path,
+                               SUPPLICANT_INTERFACE ".Interface.WPS",
+                               "ProcessCredentials",
+                               DBUS_TYPE_BOOLEAN_AS_STRING,
+                               wps_process_credentials, NULL, NULL, NULL);
+               }
        } else if (g_strcmp0(key, "State") == 0) {
                const char *str = NULL;
 
@@ -2846,6 +2921,42 @@ static void signal_bss_changed(const char *path, 
DBusMessageIter *iter)
        callback_network_changed(network, "Signal");
 }
 
+static void wps_credentials_encrtype(DBusMessageIter *iter, void *user_data)
+{
+       unsigned int *encrtype = user_data;
+       const char *str = NULL;
+       int i;
+
+       dbus_message_iter_get_basic(iter, &str);
+       if (!str)
+               return;
+
+       for (i = 0; wps_encr_map[i].str; i++) {
+               if (strcmp(str, wps_encr_map[i].str) == 0) {
+                       *encrtype |= wps_encr_map[i].val;
+                       break;
+               }
+       }
+}
+
+static void wps_credentials_authtype(DBusMessageIter *iter, void *user_data)
+{
+       unsigned int *authtype = user_data;
+       const char *str = NULL;
+       int i;
+
+       dbus_message_iter_get_basic(iter, &str);
+       if (!str)
+               return;
+
+       for (i = 0; wps_auth_map[i].str; i++) {
+               if (strcmp(str, wps_auth_map[i].str) == 0) {
+                       *authtype |= wps_auth_map[i].val;
+                       break;
+               }
+       }
+}
+
 static void wps_credentials(const char *key, DBusMessageIter *iter,
                        void *user_data)
 {
@@ -2890,12 +3001,34 @@ static void wps_credentials(const char *key, 
DBusMessageIter *iter,
                        memset(interface->wps_cred.ssid, 0, 32);
                        interface->wps_cred.ssid_len = 0;
                }
+               SUPPLICANT_DBG("WPS SSID present : %s",
+                              interface->wps_cred.ssid);
+       } else if (g_strcmp0(key, "AuthType") == 0) {
+               DBusMessageIter array;
+
+               dbus_message_iter_recurse(iter, &array);
+               supplicant_dbus_array_foreach(iter,
+                                             wps_credentials_authtype,
+                                             &interface->wps_cred.authtype);
+               SUPPLICANT_DBG("WPS AuthType=0x%04x",
+                              interface->wps_cred.authtype);
+       } else if (g_strcmp0(key, "EncrType") == 0) {
+               DBusMessageIter array;
+
+               dbus_message_iter_recurse(iter, &array);
+               supplicant_dbus_array_foreach(iter,
+                                             wps_credentials_encrtype,
+                                             &interface->wps_cred.encrtype);
+               SUPPLICANT_DBG("WPS EncrType=0x%04x",
+                              interface->wps_cred.encrtype);
        }
 }
 
 static void signal_wps_credentials(const char *path, DBusMessageIter *iter)
 {
        GSupplicantInterface *interface;
+       struct g_supplicant_bss bss;
+       char *group;
 
        SUPPLICANT_DBG("");
 
@@ -2904,23 +3037,59 @@ static void signal_wps_credentials(const char *path, 
DBusMessageIter *iter)
                return;
 
        supplicant_dbus_property_foreach(iter, wps_credentials, interface);
+
+       memset(&bss, 0, sizeof(struct g_supplicant_bss));
+       memcpy(bss.ssid, interface->wps_cred.ssid,
+              interface->wps_cred.ssid_len);
+       bss.ssid_len = interface->wps_cred.ssid_len;
+       bss.mode = G_SUPPLICANT_MODE_INFRA;
+       bss.security = G_SUPPLICANT_SECURITY_UNKNOWN;
+       if (interface->wps_cred.encrtype &
+           (G_SUPPLICANT_WPS_ENCR_AES | G_SUPPLICANT_WPS_ENCR_TKIP)) {
+               bss.security = G_SUPPLICANT_SECURITY_PSK;
+       } else if (interface->wps_cred.encrtype & G_SUPPLICANT_WPS_ENCR_WEP) {
+               bss.security = G_SUPPLICANT_SECURITY_WEP;
+       } else if (interface->wps_cred.encrtype & G_SUPPLICANT_WPS_ENCR_NONE) {
+               bss.security = G_SUPPLICANT_SECURITY_NONE;
+       }
+
+       group = create_group(&bss);
+       callback_wps_credential(interface, group);
+       g_free(group);
 }
 
 static void wps_event_args(const char *key, DBusMessageIter *iter,
                        void *user_data)
 {
-       GSupplicantInterface *interface = user_data;
+       struct wps_event_args *args = user_data;
 
-       if (!key || !interface)
+       if (!key)
                return;
 
        SUPPLICANT_DBG("Arg Key %s", key);
+
+       if (g_strcmp0(key, "config_error") == 0) {
+               dbus_message_iter_get_basic(iter, &args->config_error);
+               SUPPLICANT_DBG("Configuration Error %d", args->config_error);
+       } else if (g_strcmp0(key, "msg") == 0) {
+               dbus_message_iter_get_basic(iter, &args->msg);
+               SUPPLICANT_DBG("Msg %d", args->msg);
+       } else if (g_strcmp0(key, "error_indication") == 0) {
+               dbus_message_iter_get_basic(iter, &args->error_indication);
+               SUPPLICANT_DBG("Error Indication %d", args->error_indication);
+       }
 }
 
 static void signal_wps_event(const char *path, DBusMessageIter *iter)
 {
        GSupplicantInterface *interface;
        const char *name = NULL;
+       struct wps_event_args args;
+       int error;
+
+       static const int WPS_CFG_MSG_TIMEOUT = 16;
+       static const int WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18;
+       static const int WPS_EI_SECURITY_WEP_PROHIBITED = 2;
 
        SUPPLICANT_DBG("");
 
@@ -2932,19 +3101,43 @@ static void signal_wps_event(const char *path, 
DBusMessageIter *iter)
 
        SUPPLICANT_DBG("Name: %s", name);
 
-       if (g_strcmp0(name, "success") == 0)
-               interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
-       else if (g_strcmp0(name, "fail") == 0)
-               interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
-       else
-               interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
-
-       if (!dbus_message_iter_has_next(iter))
+       if (dbus_message_iter_has_next(iter)) {
+               dbus_message_iter_next(iter);
+               memset(&args, 0, sizeof(args));
+               supplicant_dbus_property_foreach(iter, wps_event_args, &args);
+       } else {
                return;
+       }
 
-       dbus_message_iter_next(iter);
+       if (g_strcmp0(name, "success") == 0) {
+               interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
+               error = 0;
+       } else if (g_strcmp0(name, "fail") == 0) {
+               interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
+               SUPPLICANT_DBG("WPS: Failed. msg = %d config_error = %d"
+                              " error_indication %d",
+                              args.msg, args.config_error,
+                              args.error_indication);
+
+               if (args.config_error == WPS_CFG_MSG_TIMEOUT)
+                       error = -ETIMEDOUT;
+               else if (args.config_error == WPS_CFG_DEV_PASSWORD_AUTH_FAILURE)
+                       error = -EKEYREJECTED;
+               else if (args.error_indication ==
+                        WPS_EI_SECURITY_WEP_PROHIBITED)
+                       error = -EACCES;
+               else
+                       error = -ECONNREFUSED;
+       } else if (g_strcmp0(name, "pbc-overlap") == 0) {
+               interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
+               error = -EAGAIN;
+       } else {
+               // M2D Events are not forwarded
+               interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
+               error = -ECONNREFUSED;
+       }
 
-       supplicant_dbus_property_foreach(iter, wps_event_args, interface);
+       callback_wps_event(interface, interface->wps_state, error);
 }
 
 static void create_peer_identifier(GSupplicantPeer *peer)
@@ -3661,6 +3854,14 @@ int 
g_supplicant_interface_set_country(GSupplicantInterface *interface,
        return ret;
 }
 
+bool g_supplicant_interface_support_wps(GSupplicantInterface *interface)
+{
+       if (!interface)
+               return false;
+
+       return interface->wps_support;
+}
+
 bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface)
 {
        if (!interface)
@@ -4887,6 +5088,61 @@ static void interface_add_network_params(DBusMessageIter 
*iter, void *user_data)
        supplicant_dbus_dict_close(iter, &dict);
 }
 
+static void interface_wps_cancel_result(const char *error,
+                               DBusMessageIter *iter, void *user_data)
+{
+       int err;
+       struct interface_connect_data *data = user_data;
+
+       SUPPLICANT_DBG("");
+
+       err = 0;
+       if (error) {
+               SUPPLICANT_DBG("WPS-Error: %s", error);
+
+               if (g_strcmp0(SUPPLICANT_INTERFACE ".InvalidArgs", error) == 0)
+                       err = -EINVAL;
+       }
+
+       if (!data) {
+               SUPPLICANT_DBG("data is NULL");
+               return;
+       }
+
+       if (data->callback)
+               data->callback(err, data->interface, data->user_data);
+
+       g_free(data->path);
+       dbus_free(data);
+}
+
+int g_supplicant_interface_wps_cancel(GSupplicantInterface *interface,
+                                     GSupplicantInterfaceCallback callback,
+                                     void *user_data)
+{
+       struct interface_connect_data *data;
+       int ret;
+
+       data = dbus_malloc0(sizeof(*data));
+       data->interface = interface;
+       data->path = g_strdup(interface->path);
+       data->callback = callback;
+       data->user_data = user_data;
+
+       ret = supplicant_dbus_method_call(data->path,
+                       SUPPLICANT_INTERFACE ".Interface.WPS", "Cancel",
+                       NULL, interface_wps_cancel_result, data, NULL);
+
+       if (ret < 0) {
+               SUPPLICANT_DBG("WPS-Error: %d", ret);
+               g_free(data->path);
+               dbus_free(data);
+               return ret;
+       }
+
+       return -EINPROGRESS;
+}
+
 static void interface_wps_start_result(const char *error,
                                DBusMessageIter *iter, void *user_data)
 {
@@ -4905,29 +5161,33 @@ static void interface_wps_start_result(const char 
*error,
                data->callback(err, data->interface, data->user_data);
 
        g_free(data->path);
-       g_free(data->ssid);
+       g_free(data->wps);
        dbus_free(data);
 }
 
 static void interface_add_wps_params(DBusMessageIter *iter, void *user_data)
 {
        struct interface_connect_data *data = user_data;
-       GSupplicantSSID *ssid = data->ssid;
-       const char *role = "enrollee", *type;
+       GSupplicantWPSParams *wps = data->wps;
+       const char *role, *type;
        DBusMessageIter dict;
 
        SUPPLICANT_DBG("");
 
        supplicant_dbus_dict_open(iter, &dict);
 
+       role = "enrollee";
+       if (wps->mode == G_SUPPLICANT_MODE_MASTER)
+               role = "registrar";
+
        supplicant_dbus_dict_append_basic(&dict, "Role",
                                                DBUS_TYPE_STRING, &role);
 
        type = "pbc";
-       if (ssid->pin_wps) {
+       if (wps->pin) {
                type = "pin";
                supplicant_dbus_dict_append_basic(&dict, "Pin",
-                                       DBUS_TYPE_STRING, &ssid->pin_wps);
+                                       DBUS_TYPE_STRING, &wps->pin);
        }
 
        supplicant_dbus_dict_append_basic(&dict, "Type",
@@ -4936,36 +5196,43 @@ static void interface_add_wps_params(DBusMessageIter 
*iter, void *user_data)
        supplicant_dbus_dict_close(iter, &dict);
 }
 
-static void wps_start(const char *error, DBusMessageIter *iter, void 
*user_data)
+int g_supplicant_interface_wps_start(GSupplicantInterface *interface,
+                                    GSupplicantWPSParams *wps,
+                                    GSupplicantInterfaceCallback callback,
+                                    void *user_data)
 {
-       struct interface_connect_data *data = user_data;
+       struct interface_connect_data *data;
+       int ret;
 
        SUPPLICANT_DBG("");
 
-       if (error) {
-               SUPPLICANT_DBG("error: %s", error);
-               g_free(data->path);
-               g_free(data->ssid);
-               dbus_free(data);
-               return;
-       }
+       data = dbus_malloc0(sizeof(*data));
+       data->interface = interface;
+       data->path = g_strdup(interface->path);
+       data->callback = callback;
+       data->wps = wps;
+       data->user_data = user_data;
 
-       supplicant_dbus_method_call(data->interface->path,
+       g_free(interface->wps_cred.key);
+       memset(&interface->wps_cred, 0,
+              sizeof(struct _GSupplicantWpsCredentials));
+
+       ret = supplicant_dbus_method_call(data->interface->path,
                        SUPPLICANT_INTERFACE ".Interface.WPS", "Start",
                        interface_add_wps_params,
                        interface_wps_start_result, data, NULL);
-}
-
-static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
-{
-       dbus_bool_t credentials = TRUE;
 
-       SUPPLICANT_DBG("");
+       if (ret < 0) {
+               SUPPLICANT_DBG("Error: WPS Session could not be started");
+               g_free(wps);
+               g_free(data->path);
+               dbus_free(data);
+               return ret;
+       }
 
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
+       return -EINPROGRESS;
 }
 
-
 int g_supplicant_interface_connect(GSupplicantInterface *interface,
                                GSupplicantSSID *ssid,
                                GSupplicantInterfaceCallback callback,
@@ -4973,6 +5240,7 @@ int g_supplicant_interface_connect(GSupplicantInterface 
*interface,
 {
        struct interface_connect_data *data;
        struct interface_data *intf_data;
+       GSupplicantWPSParams *wps;
        int ret = 0;
 
        SUPPLICANT_DBG("");
@@ -4985,6 +5253,21 @@ int g_supplicant_interface_connect(GSupplicantInterface 
*interface,
 
        /* TODO: Check if we're already connected and switch */
 
+       if (ssid->use_wps) {
+               wps = g_try_malloc0(sizeof(GSupplicantWPSParams));
+               if (!wps)
+                       return -ENOMEM;
+
+               memset(wps, 0, sizeof(*wps));
+               wps->mode = G_SUPPLICANT_MODE_INFRA;
+               wps->pin = ssid->pin_wps;
+
+               g_free(ssid);
+               return g_supplicant_interface_wps_start(interface,
+                                                       wps, callback,
+                                                       user_data);
+       }
+
        data = dbus_malloc0(sizeof(*data));
        if (!data)
                return -ENOMEM;
@@ -4995,72 +5278,61 @@ int g_supplicant_interface_connect(GSupplicantInterface 
*interface,
        data->ssid = ssid;
        data->user_data = user_data;
 
-       if (ssid->use_wps) {
-               g_free(interface->wps_cred.key);
-               memset(&interface->wps_cred, 0,
-                               sizeof(struct _GSupplicantWpsCredentials));
+       /* By the time there is a request for connect and the network
+        * path is not NULL it means that connman has not removed the
+        * previous network pointer. This can happen in the case AP
+        * deauthenticated client and connman does not remove the
+        * previously connected network pointer. This causes supplicant
+        * to reallocate the memory for struct wpa_ssid again even if it
+        * is the same SSID. This causes memory usage of wpa_supplicnat
+        * to go high. The idea here is that if the previously connected
+        * network is not removed at the time of next connection attempt
+        * check if the network path is not NULL. In case it is non-NULL
+        * first remove the network and then once removal is successful, add
+        * the network.
+        */
 
-               ret = supplicant_dbus_property_set(interface->path,
-                       SUPPLICANT_INTERFACE ".Interface.WPS",
-                       "ProcessCredentials", DBUS_TYPE_BOOLEAN_AS_STRING,
-                       wps_process_credentials, wps_start, data, interface);
-       } else {
-               /* By the time there is a request for connect and the network
-                * path is not NULL it means that connman has not removed the
-                * previous network pointer. This can happen in the case AP
-                * deauthenticated client and connman does not remove the
-                * previously connected network pointer. This causes supplicant
-                * to reallocate the memory for struct wpa_ssid again even if it
-                * is the same SSID. This causes memory usage of wpa_supplicnat
-                * to go high. The idea here is that if the previously connected
-                * network is not removed at the time of next connection attempt
-                * check if the network path is not NULL. In case it is non-NULL
-                * first remove the network and then once removal is 
successful, add
-                * the network.
+       if (interface->network_path != NULL) {
+               g_free(data->path);
+               dbus_free(data);
+
+               /*
+                * If this add network is for the same network for
+                * which wpa_supplicant already has a profile then do
+                * not need to add another profile. Only if the
+                * profile that needs to get added is different from
+                * what is there in wpa_s delete the current one. A
+                * network is identified by its SSID, security_type
+                * and passphrase (private passphrase in case security
+                * type is 802.11x).
                 */
+               if (compare_network_parameters(interface, ssid))
+                       return -EALREADY;
+
+               intf_data = dbus_malloc0(sizeof(*intf_data));
+               if (!intf_data)
+                       return -ENOMEM;
+
+               intf_data->interface = interface;
+               intf_data->path = g_strdup(interface->path);
+               intf_data->callback = callback;
+               intf_data->ssid = ssid;
+               intf_data->user_data = user_data;
+               intf_data->network_remove_in_progress = TRUE;
+               network_remove(intf_data);
+       } else {
+               ret = supplicant_dbus_method_call(interface->path,
+                               SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+                               interface_add_network_params,
+                               interface_add_network_result, data,
+                               interface);
 
-               if (interface->network_path != NULL) {
+               if (ret < 0) {
                        g_free(data->path);
+                       g_free(data->ssid);
                        dbus_free(data);
-
-                       /*
-                        * If this add network is for the same network for
-                        * which wpa_supplicant already has a profile then do
-                        * not need to add another profile. Only if the
-                        * profile that needs to get added is different from
-                        * what is there in wpa_s delete the current one. A
-                        * network is identified by its SSID, security_type
-                        * and passphrase (private passphrase in case security
-                        * type is 802.11x).
-                        */
-                       if (compare_network_parameters(interface, ssid)) {
-                               return -EALREADY;
-                       }
-
-                       intf_data = dbus_malloc0(sizeof(*intf_data));
-                       if (!intf_data)
-                               return -ENOMEM;
-
-                       intf_data->interface = interface;
-                       intf_data->path = g_strdup(interface->path);
-                       intf_data->callback = callback;
-                       intf_data->ssid = ssid;
-                       intf_data->user_data = user_data;
-                       intf_data->network_remove_in_progress = TRUE;
-                       network_remove(intf_data);
-               } else {
-                       ret = supplicant_dbus_method_call(interface->path,
-                                       SUPPLICANT_INTERFACE ".Interface", 
"AddNetwork",
-                                       interface_add_network_params,
-                                       interface_add_network_result, data,
-                                       interface);
+                       return ret;
                }
-        }
-
-       if (ret < 0) {
-               g_free(data->path);
-               dbus_free(data);
-               return ret;
        }
 
        return -EINPROGRESS;
@@ -5847,3 +6119,24 @@ void g_supplicant_unregister(const GSupplicantCallbacks 
*callbacks)
        callbacks_pointer = NULL;
        eap_methods = 0;
 }
+
+static void interface_flushBSS_params(DBusMessageIter *iter, void *user_data)
+{
+       unsigned int *age = user_data;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, age);
+}
+
+void g_supplicant_interface_flushBSS(GSupplicantInterface *interface,
+                                    unsigned int age)
+{
+       if (!interface)
+               return;
+
+       SUPPLICANT_DBG("");
+
+       supplicant_dbus_method_call(interface->path,
+               SUPPLICANT_INTERFACE ".Interface", "FlushBSS",
+               interface_flushBSS_params, NULL,
+               &age, interface);
+}
-- 
2.17.1



------------------------------

Subject: Digest Footer

_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman


------------------------------

End of connman Digest, Vol 34, Issue 24
***************************************

Reply via email to