diff options
author | Nishant Chaprana <n.chaprana@samsung.com> | 2019-07-04 17:41:09 +0530 |
---|---|---|
committer | Nishant Chaprana <n.chaprana@samsung.com> | 2019-07-04 17:41:17 +0530 |
commit | 6b2381a2adabea7d8309ff158ef675ff88184305 (patch) | |
tree | 2c9b2bb6d8b214acc18b8e784e6841f468a5a040 /gsupplicant/supplicant.c | |
parent | 9362752a471a5c892d679548fbf2828d5fc5684b (diff) | |
download | connman-6b2381a2adabea7d8309ff158ef675ff88184305.tar.gz connman-6b2381a2adabea7d8309ff158ef675ff88184305.tar.bz2 connman-6b2381a2adabea7d8309ff158ef675ff88184305.zip |
Imported Upstream version 1.37upstream/1.37
Change-Id: Ib5957e7ee3a9315ee86a331189bc3e9e71751ee8
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
Diffstat (limited to 'gsupplicant/supplicant.c')
-rw-r--r-- | gsupplicant/supplicant.c | 161 |
1 files changed, 135 insertions, 26 deletions
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 4f790122..6052f7b6 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -614,6 +614,30 @@ static void callback_network_associated(GSupplicantNetwork *network) callbacks_pointer->network_associated(network); } +static void callback_sta_authorized(GSupplicantInterface *interface, + const char *addr) +{ + if (!callbacks_pointer) + return; + + if (!callbacks_pointer->sta_authorized) + return; + + callbacks_pointer->sta_authorized(interface, addr); +} + +static void callback_sta_deauthorized(GSupplicantInterface *interface, + const char *addr) +{ + if (!callbacks_pointer) + return; + + if (!callbacks_pointer->sta_deauthorized) + return; + + callbacks_pointer->sta_deauthorized(interface, addr); +} + static void callback_peer_found(GSupplicantPeer *peer) { if (!callbacks_pointer) @@ -755,6 +779,8 @@ static void remove_bss(gpointer data) { struct g_supplicant_bss *bss = data; + supplicant_dbus_property_call_cancel_all(bss); + g_free(bss->path); g_free(bss); } @@ -1499,7 +1525,6 @@ static void interface_network_added(DBusMessageIter *iter, void *user_data) static void interface_network_removed(DBusMessageIter *iter, void *user_data) { SUPPLICANT_DBG(""); - return; } static char *create_name(unsigned char *ssid, int ssid_len) @@ -1575,6 +1600,7 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss) GSupplicantInterface *interface = bss->interface; GSupplicantNetwork *network; char *group; + bool is_new_network; group = create_group(bss); SUPPLICANT_DBG("New group created: %s", group); @@ -1586,10 +1612,13 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss) if (network) { g_free(group); SUPPLICANT_DBG("Network %s already exist", network->name); + is_new_network = false; goto done; } + is_new_network = true; + network = g_try_new0(GSupplicantNetwork, 1); if (!network) { g_free(group); @@ -1609,6 +1638,11 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss) network->frequency = bss->frequency; network->best_bss = bss; + if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) { + network->wps = TRUE; + network->wps_capabilities = bss->wps_capabilities; + } + SUPPLICANT_DBG("New network %s created", network->name); network->bss_table = g_hash_table_new_full(g_str_hash, g_str_equal, @@ -1626,7 +1660,10 @@ done: /* We update network's WPS properties if only bss provides WPS. */ if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) { network->wps = TRUE; - network->wps_capabilities |= bss->wps_capabilities; + network->wps_capabilities = bss->wps_capabilities; + + if (!is_new_network) + callback_network_changed(network, "WPSCapabilities"); } /* @@ -2064,7 +2101,7 @@ static void interface_bss_added_without_keys(DBusMessageIter *iter, supplicant_dbus_property_get_all(bss->path, SUPPLICANT_INTERFACE ".BSS", - bss_property, bss, NULL); + bss_property, bss, bss); bss_compute_security(bss); if (add_or_replace_bss_to_network(bss) < 0) @@ -2169,6 +2206,7 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data) GSupplicantNetwork *network; struct g_supplicant_bss *bss = NULL; const char *path = NULL; + bool is_current_network_bss = false; dbus_message_iter_get_basic(iter, &path); if (!path) @@ -2182,6 +2220,7 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data) if (network->best_bss == bss) { network->best_bss = NULL; network->signal = BSS_UNKNOWN_STRENGTH; + is_current_network_bss = true; } g_hash_table_remove(bss_mapping, path); @@ -2191,8 +2230,12 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data) update_network_signal(network); - if (g_hash_table_size(network->bss_table) == 0) + if (g_hash_table_size(network->bss_table) == 0) { g_hash_table_remove(interface->network_table, network->group); + } else { + if (is_current_network_bss && network->best_bss) + callback_network_changed(network, ""); + } } static void set_config_methods(DBusMessageIter *iter, void *user_data) @@ -2718,11 +2761,48 @@ static void signal_network_removed(const char *path, DBusMessageIter *iter) interface_network_removed(iter, interface); } +static void signal_sta_authorized(const char *path, DBusMessageIter *iter) +{ + GSupplicantInterface *interface; + const char *addr = NULL; + + SUPPLICANT_DBG(""); + + interface = g_hash_table_lookup(interface_table, path); + if (!interface) + return; + + dbus_message_iter_get_basic(iter, &addr); + if (!addr) + return; + + callback_sta_authorized(interface, addr); +} + +static void signal_sta_deauthorized(const char *path, DBusMessageIter *iter) +{ + GSupplicantInterface *interface; + const char *addr = NULL; + + SUPPLICANT_DBG(""); + + interface = g_hash_table_lookup(interface_table, path); + if (!interface) + return; + + dbus_message_iter_get_basic(iter, &addr); + if (!addr) + return; + + callback_sta_deauthorized(interface, addr); +} + static void signal_bss_changed(const char *path, DBusMessageIter *iter) { GSupplicantInterface *interface; GSupplicantNetwork *network; GSupplicantSecurity old_security; + unsigned int old_wps_capabilities; struct g_supplicant_bss *bss; SUPPLICANT_DBG(""); @@ -2747,18 +2827,18 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter) if (old_security != bss->security) { struct g_supplicant_bss *new_bss; - SUPPLICANT_DBG("New network security for %s", bss->ssid); + SUPPLICANT_DBG("New network security for %s with path %s", + bss->ssid, bss->path); - /* Security change policy: - * - we first copy the current bss into a new one with - * its own pointer (path) - * - we remove the current bss related network which will - * tell the plugin about such removal. This is done due - * to the fact that a security change means a group change - * so a complete network change. - * (current bss becomes invalid as well) - * - we add the new bss: it adds new network and tell the - * plugin about it. */ + /* + * Security change policy: + * - We first copy the current bss into a new one with + * its own pointer (path) + * - Clear the old bss pointer and remove the network completely + * if there are no more BSSs in the bss table. + * - The new bss will be added either to an existing network + * or an additional network will be created + */ new_bss = g_try_new0(struct g_supplicant_bss, 1); if (!new_bss) @@ -2767,20 +2847,43 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter) memcpy(new_bss, bss, sizeof(struct g_supplicant_bss)); new_bss->path = g_strdup(bss->path); - g_hash_table_remove(interface->network_table, network->group); + if (network->best_bss == bss) { + network->best_bss = NULL; + network->signal = BSS_UNKNOWN_STRENGTH; + } + + g_hash_table_remove(bss_mapping, path); + + g_hash_table_remove(interface->bss_mapping, path); + g_hash_table_remove(network->bss_table, path); + + update_network_signal(network); + + if (g_hash_table_size(network->bss_table) == 0) + g_hash_table_remove(interface->network_table, + network->group); if (add_or_replace_bss_to_network(new_bss) < 0) { - /* Remove entries in hash tables to handle the - * failure in add_or_replace_bss_to_network + /* + * Prevent a memory leak on failure in + * add_or_replace_bss_to_network */ - g_hash_table_remove(bss_mapping, path); - g_hash_table_remove(interface->bss_mapping, path); - g_hash_table_remove(network->bss_table, path); + SUPPLICANT_DBG("Failed to add bss %s to network table", + new_bss->path); + g_free(new_bss->path); + g_free(new_bss); } return; } + old_wps_capabilities = network->wps_capabilities; + + if (old_wps_capabilities != bss->wps_capabilities) { + network->wps_capabilities = bss->wps_capabilities; + callback_network_changed(network, "WPSCapabilities"); + } + /* Consider only property changes of the connected BSS */ if (network == interface->current_network && bss != network->best_bss) return; @@ -3468,6 +3571,8 @@ static struct { { SUPPLICANT_INTERFACE ".Interface", "BSSRemoved", signal_bss_removed }, { SUPPLICANT_INTERFACE ".Interface", "NetworkAdded", signal_network_added }, { SUPPLICANT_INTERFACE ".Interface", "NetworkRemoved", signal_network_removed }, + { SUPPLICANT_INTERFACE ".Interface", "StaAuthorized", signal_sta_authorized }, + { SUPPLICANT_INTERFACE ".Interface", "StaDeauthorized", signal_sta_deauthorized }, { SUPPLICANT_INTERFACE ".BSS", "PropertiesChanged", signal_bss_changed }, @@ -4204,11 +4309,13 @@ static void interface_scan_params(DBusMessageIter *iter, void *user_data) supplicant_dbus_dict_append_basic(&dict, "Type", DBUS_TYPE_STRING, &type); - supplicant_dbus_dict_append_array(&dict, "SSIDs", - DBUS_TYPE_STRING, - append_ssids, - data->scan_params); + if (data->scan_params->ssids) { + supplicant_dbus_dict_append_array(&dict, "SSIDs", + DBUS_TYPE_STRING, + append_ssids, + data->scan_params); + } supplicant_add_scan_frequency(&dict, add_scan_frequencies, data->scan_params); } else @@ -4597,7 +4704,9 @@ static void add_network_security_peap(DBusMessageIter *dict, } - if (g_str_has_prefix(ssid->phase2_auth, "EAP-")) { + if(g_strcmp0(ssid->phase2_auth, "GTC") == 0 && g_strcmp0(ssid->eap, "ttls") == 0) + phase2_auth = g_strdup_printf("autheap=%s", ssid->phase2_auth); + else if (g_str_has_prefix(ssid->phase2_auth, "EAP-")) { phase2_auth = g_strdup_printf("autheap=%s", ssid->phase2_auth + strlen("EAP-")); } else |