---
 plugins/wifi.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/plugins/wifi.c b/plugins/wifi.c
index 040d2f9..7d87235 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -70,6 +70,10 @@ struct wifi_data {
        unsigned int watch;
 };
 
+static void disconnect_callback(int result, GSupplicantInterface *interface,
+                                                       void *user_data);
+
+
 static int get_bssid(struct connman_device *device,
                                unsigned char *bssid, unsigned int *bssid_len)
 {
@@ -342,6 +346,31 @@ static connman_bool_t is_idle(struct wifi_data *wifi)
        return FALSE;
 }
 
+static connman_bool_t is_idle_wps(GSupplicantInterface *interface,
+                                               struct wifi_data *wifi)
+{
+       if (g_supplicant_interface_get_wps_state(interface) ==
+               G_SUPPLICANT_WPS_STATE_FAIL)
+               return FALSE;
+
+       switch (wifi->state) {
+       case G_SUPPLICANT_STATE_UNKNOWN:
+       case G_SUPPLICANT_STATE_DISCONNECTED:
+       case G_SUPPLICANT_STATE_INACTIVE:
+       case G_SUPPLICANT_STATE_SCANNING:
+       case G_SUPPLICANT_STATE_ASSOCIATED:
+               return TRUE;
+       case G_SUPPLICANT_STATE_AUTHENTICATING:
+       case G_SUPPLICANT_STATE_ASSOCIATING:
+       case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
+       case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
+       case G_SUPPLICANT_STATE_COMPLETED:
+               return FALSE;
+       }
+
+       return FALSE;
+}
+
 static void interface_state(GSupplicantInterface *interface)
 {
        struct connman_network *network;
@@ -350,6 +379,7 @@ static void interface_state(GSupplicantInterface *interface)
        GSupplicantState state = g_supplicant_interface_get_state(interface);
        unsigned char bssid[ETH_ALEN];
        unsigned int bssid_len;
+       connman_bool_t wps;
 
        wifi = g_supplicant_interface_get_data(interface);
 
@@ -375,6 +405,35 @@ static void interface_state(GSupplicantInterface 
*interface)
                break;
 
        case G_SUPPLICANT_STATE_COMPLETED:
+               wps = connman_network_get_bool(network, "WiFi.UseWPS");
+               if (wps == TRUE) {
+                       const unsigned char *ssid, *wps_ssid;
+                       unsigned int ssid_len, wps_ssid_len;
+                       const char *wps_key;
+
+                       /*Checking if we got associated with requested network*/
+                       ssid = connman_network_get_blob(network, "WiFi.SSID",
+                                                               &ssid_len);
+
+                       wps_ssid = g_supplicant_interface_get_wps_ssid(
+                                               interface, &wps_ssid_len);
+
+                       if (wps_ssid == NULL || wps_ssid_len != ssid_len ||
+                                       memcmp(ssid, wps_ssid, ssid_len) != 0) {
+                               connman_network_set_associating(network, FALSE);
+                               g_supplicant_interface_disconnect(
+                                               wifi->interface,
+                                               disconnect_callback, wifi);
+                               break;
+                       }
+
+                       wps_key = g_supplicant_interface_get_wps_key(interface);
+                       connman_network_set_string(network, "WiFi.Passphrase",
+                                                               wps_key);
+
+                       connman_network_set_string(network, "WiFi.PinWPS", 
NULL);
+               }
+
                /* reset scan trigger and schedule background scan */
                connman_device_schedule_scan(device);
 
@@ -391,6 +450,11 @@ static void interface_state(GSupplicantInterface 
*interface)
                 * those ones to FALSE could cancel an association
                 * in progress.
                 */
+               wps = connman_network_get_bool(network, "WiFi.UseWPS");
+               if (wps == TRUE)
+                       if (is_idle_wps(interface, wifi) == TRUE)
+                               break;
+
                if (is_idle(wifi))
                        break;
                connman_network_set_associating(network, FALSE);
@@ -476,6 +540,7 @@ static void network_added(GSupplicantNetwork 
*supplicant_network)
        const char *name, *identifier, *mode, *security, *group;
        const unsigned char *ssid;
        unsigned int ssid_len;
+       connman_bool_t wps;
 
        DBG("");
 
@@ -486,6 +551,7 @@ static void network_added(GSupplicantNetwork 
*supplicant_network)
        mode = g_supplicant_network_get_mode(supplicant_network);
        security = g_supplicant_network_get_security(supplicant_network);
        group = g_supplicant_network_get_identifier(supplicant_network);
+       wps = g_supplicant_network_get_wps(supplicant_network);
 
        if (wifi == NULL)
                return;
@@ -517,6 +583,7 @@ static void network_added(GSupplicantNetwork 
*supplicant_network)
        connman_network_set_string(network, "WiFi.Security", security);
        connman_network_set_strength(network,
                                calculate_strength(supplicant_network));
+       connman_network_set_bool(network, "WiFi.WPS", wps);
 
        connman_network_set_available(network, TRUE);
 
@@ -638,6 +705,9 @@ static void ssid_init(GSupplicantSSID *ssid, struct 
connman_network *network)
                                                "WiFi.PrivateKeyPassphrase");
        ssid->phase2_auth = connman_network_get_string(network, "WiFi.Phase2");
 
+       ssid->use_wps = connman_network_get_bool(network, "WiFi.UseWPS");
+       ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
+
 }
 
 static int network_connect(struct connman_network *network)
-- 
1.7.2.3

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to