--- 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