service: Add a new property 'SecurityList'
[platform/upstream/connman.git] / plugins / wifi.c
index 1610211..53bcc8b 100755 (executable)
 
 #include <gsupplicant/gsupplicant.h>
 
+#include "src/shared/util.h"
+
 #define CLEANUP_TIMEOUT   8    /* in seconds */
 #define INACTIVE_TIMEOUT  12   /* in seconds */
 #define FAVORITE_MAXIMUM_RETRIES 2
 
-#define BGSCAN_DEFAULT "simple:30:-45:300"
+#define BGSCAN_DEFAULT "simple:30:-65:300"
 #define AUTOSCAN_EXPONENTIAL "exponential:3:300"
 #define AUTOSCAN_SINGLE "single:3"
 
@@ -173,6 +175,9 @@ struct wifi_data {
        bool allow_full_scan;
        unsigned int automaxspeed_timeout;
        GSupplicantScanParams *hidden_scan_params;
+       unsigned int mac_policy;
+       unsigned int preassoc_mac_policy;
+       unsigned int mac_lifetime;
 #endif
        int disconnect_code;
        int assoc_code;
@@ -2406,7 +2411,7 @@ static void setup_autoscan(struct wifi_data *wifi)
 
                return;
        }
-#endif
+#else
 
        /*
         * On the contrary, if BackgroundScanning is disabled, update autoscan
@@ -2430,6 +2435,7 @@ static void setup_autoscan(struct wifi_data *wifi)
                wifi->autoscan = parse_autoscan_params(AUTOSCAN_SINGLE);
                break;
        }
+#endif
 }
 
 static void finalize_interface_creation(struct wifi_data *wifi)
@@ -2493,6 +2499,11 @@ static int wifi_enable(struct connman_device *device)
 
        interface = connman_inet_ifname(index);
        ret = g_supplicant_interface_create(interface, driver, NULL,
+#ifdef TIZEN_EXT
+                       connman_device_get_mac_policy(device),
+                       connman_device_get_preassoc_mac_policy(device),
+                       connman_device_get_random_mac_lifetime(device),
+#endif /* TIZEN_EXT */
                                                interface_create_callback,
                                                        wifi);
        g_free(interface);
@@ -2618,7 +2629,7 @@ static int get_latest_connections(int max_ssids,
                        g_key_file_free(keyfile);
                        continue;
                }
-               g_time_val_from_iso8601(str, &modified);
+               util_iso8601_to_timeval(str, &modified);
                g_free(str);
 
                ssid = g_key_file_get_string(keyfile,
@@ -2632,6 +2643,9 @@ static int get_latest_connections(int max_ssids,
                                g_sequence_free(latest_list);
                                g_key_file_free(keyfile);
                                g_free(ssid);
+#if defined TIZEN_EXT
+                               g_strfreev(services);
+#endif
                                return -ENOMEM;
                        }
 
@@ -2954,6 +2968,99 @@ static int wifi_specific_scan(enum connman_service_type type,
 
        return ret;
 }
+
+static void wifi_mac_policy_callback(int result,
+                                       unsigned int policy,
+                                               void *user_data)
+{
+       struct connman_device *device = user_data;
+
+       if (result == 0)
+               connman_device_mac_policy_notify(device, result, policy);
+
+       connman_device_unref(device);
+}
+
+int wifi_set_mac_policy(struct connman_device *device, unsigned int policy)
+{
+       struct wifi_data *wifi = connman_device_get_data(device);
+       int ret;
+
+       if (!wifi)
+               return -EINVAL;
+
+       connman_device_ref(device);
+
+       ret = g_supplicant_interface_set_mac_policy(wifi->interface,
+                                       wifi_mac_policy_callback,
+                                       policy, device);
+       if (ret != 0)
+               connman_device_unref(device);
+
+       return ret;
+}
+
+static void wifi_preassoc_mac_policy_callback(int result,
+                                       unsigned int policy,
+                                               void *user_data)
+{
+       struct connman_device *device = user_data;
+
+       if (result == 0)
+               connman_device_preassoc_mac_policy_notify(device, result, policy);
+
+       connman_device_unref(device);
+}
+
+int wifi_set_preassoc_mac_policy(struct connman_device *device, unsigned int policy)
+{
+       struct wifi_data *wifi = connman_device_get_data(device);
+       int ret;
+
+       if (!wifi)
+               return -EINVAL;
+
+       connman_device_ref(device);
+
+       ret = g_supplicant_interface_set_preassoc_mac_policy(wifi->interface,
+                                       wifi_preassoc_mac_policy_callback,
+                                       policy, device);
+       if (ret != 0)
+               connman_device_unref(device);
+
+       return ret;
+}
+
+static void wifi_random_mac_lifetime_callback(int result,
+                                       unsigned int lifetime,
+                                               void *user_data)
+{
+       struct connman_device *device = user_data;
+
+       if (result == 0)
+               connman_device_random_mac_lifetime_notify(device, result, lifetime);
+
+       connman_device_unref(device);
+}
+
+int wifi_set_random_mac_lifetime(struct connman_device *device, unsigned int lifetime)
+{
+       struct wifi_data *wifi = connman_device_get_data(device);
+       int ret;
+
+       if (!wifi)
+               return -EINVAL;
+
+       connman_device_ref(device);
+
+       ret = g_supplicant_interface_set_random_mac_lifetime(wifi->interface,
+                                       wifi_random_mac_lifetime_callback,
+                                       lifetime, device);
+       if (ret != 0)
+               connman_device_unref(device);
+
+       return ret;
+}
 #endif
 
 #if defined TIZEN_EXT_WIFI_MESH
@@ -2986,7 +3093,7 @@ static int mesh_scan(struct connman_device *device)
 
        wifi = connman_device_get_data(device);
 
-       if (!wifi->mesh_interface)
+       if (!wifi || !wifi->mesh_interface)
                return -ENOTSUP;
 
        mesh_info = wifi->mesh_info;
@@ -3329,6 +3436,9 @@ static struct connman_device_driver wifi_ng_driver = {
        .set_regdom     = wifi_set_regdom,
 #if defined TIZEN_EXT
        .specific_scan  = wifi_specific_scan,
+       .set_mac_policy           = wifi_set_mac_policy,
+       .set_preassoc_mac_policy  = wifi_set_preassoc_mac_policy,
+       .set_random_mac_lifetime  = wifi_set_random_mac_lifetime,
 #endif
 #if defined TIZEN_EXT_WIFI_MESH
        .abort_scan     = mesh_abort_scan,
@@ -3353,6 +3463,9 @@ static void system_killed(void)
 
 static int network_probe(struct connman_network *network)
 {
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        DBG("network %p", network);
 
        return 0;
@@ -3397,7 +3510,8 @@ static void connect_callback(int result, GSupplicantInterface *interface,
        DBG("network %p result %d", network, result);
 
 #if defined TIZEN_EXT
-       set_connman_bssid(RESET_BSSID, NULL);
+       const char *ifname = g_supplicant_interface_get_ifname(interface);
+       set_connman_bssid(RESET_BSSID, NULL, ifname);
 
        for (list = iface_list; list; list = list->next) {
                wifi = list->data;
@@ -3550,9 +3664,11 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
 #endif
 
 #if defined TIZEN_EXT
-       if (set_connman_bssid(CHECK_BSSID, NULL) == 6) {
+       const char *ifname = connman_device_get_string(
+                       connman_network_get_device(network), "Interface");
+       if (set_connman_bssid(CHECK_BSSID, NULL, ifname) == 6) {
                ssid->bssid_for_connect_len = 6;
-               set_connman_bssid(GET_BSSID, (char *)ssid->bssid_for_connect);
+               set_connman_bssid(GET_BSSID, (char *)ssid->bssid_for_connect, ifname);
                DBG("BSSID : %02x:%02x:%02x:%02x:%02x:%02x",
                        ssid->bssid_for_connect[0], ssid->bssid_for_connect[1],
                        ssid->bssid_for_connect[2], ssid->bssid_for_connect[3],
@@ -3568,8 +3684,8 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
                 * the user-specified bssid is tried only once at the beginning.
                 * After that, the bssids in the list are tried in order.
                 */
-               if (set_connman_bssid(CHECK_BSSID, NULL) == 6) {
-                       set_connman_bssid(RESET_BSSID, NULL);
+               if (set_connman_bssid(CHECK_BSSID, NULL, ifname) == 6) {
+                       set_connman_bssid(RESET_BSSID, NULL, ifname);
                        goto done;
                }
 
@@ -3613,6 +3729,8 @@ done:
 
        if(g_strcmp0(ssid->eap, "fast") == 0)
                ssid->pac_file = g_strdup(WIFI_EAP_FAST_PAC_FILE);
+
+       ssid->keymgmt = connman_network_get_keymgmt(network);
 #endif
 
        if (connman_setting_get_bool("BackgroundScanning"))
@@ -3699,7 +3817,7 @@ found:
                return;
        }
 
-       if (wifi->network != wifi->pending_network)
+       if (wifi->network && wifi->network != wifi->pending_network)
                connman_network_set_connected(wifi->network, false);
        wifi->network = NULL;
 
@@ -3852,6 +3970,7 @@ static void signalpoll_callback(int result, int maxspeed, int strength,
 
        if (result != 0) {
                DBG("Failed to get maxspeed from signalpoll !");
+               connman_network_unref(network);
                return;
        }
 
@@ -3860,11 +3979,12 @@ static void signalpoll_callback(int result, int maxspeed, int strength,
                strength = 100;
 
        DBG("maxspeed = %d, strength = %d", maxspeed, strength);
-       if (network) {
-               connman_network_set_strength(network, (uint8_t)strength);
-               connman_network_set_maxspeed(network, maxspeed);
-               set_connection_mode(network, maxspeed);
-       }
+
+       connman_network_set_strength(network, (uint8_t)strength);
+       connman_network_set_maxspeed(network, maxspeed);
+       set_connection_mode(network, maxspeed);
+
+       connman_network_unref(network);
 }
 
 static int network_signalpoll(struct wifi_data *wifi)
@@ -3875,6 +3995,8 @@ static int network_signalpoll(struct wifi_data *wifi)
        if (!wifi || !wifi->network)
                return -ENODEV;
 
+       wifi->network = connman_network_ref(wifi->network);
+
        interface = wifi->interface;
        network = wifi->network;
 
@@ -3896,6 +4018,9 @@ static gboolean autosignalpoll_timeout(gpointer data)
        if (ret < 0) {
                DBG("Fail to get max speed !!");
                wifi->automaxspeed_timeout = 0;
+
+               if (wifi->network)
+                       connman_network_unref(wifi->network);
                return FALSE;
        }
 
@@ -3954,10 +4079,10 @@ static void interface_added(GSupplicantInterface *interface)
 
        connman_device_set_powered(wifi->device, true);
 #if defined TIZEN_EXT
-       connman_techonology_wifi_set_5ghz_supported(wifi_technology, is_5_0_ghz_supported);
+       connman_device_set_wifi_5ghz_supported(wifi->device, is_5_0_ghz_supported);
        /* Max number of SSIDs supported by wlan chipset that can be scanned */
        int max_scan_ssids = g_supplicant_interface_get_max_scan_ssids(interface);
-       connman_techonology_set_max_scan_ssids(wifi_technology, max_scan_ssids);
+       connman_device_set_max_scan_ssids(wifi->device, max_scan_ssids);
 #endif
 }
 
@@ -4334,9 +4459,9 @@ static void interface_state(GSupplicantInterface *interface)
 
 #if defined TIZEN_EXT
                if (handle_assoc_status_code(interface, wifi)) {
-                       GSList *bssid_list = (GSList *)connman_network_get_bssid_list(network);
                        const char *group = connman_network_get_group(network);
                        GSupplicantNetwork *supplicant_network;
+                       GSList *bssid_list = NULL;
                        guint bssid_length = 0;
 
                        if (group) {
@@ -4348,6 +4473,7 @@ static void interface_state(GSupplicantInterface *interface)
                                g_supplicant_network_update_assoc_reject(interface, supplicant_network);
                        }
 
+                       bssid_list = (GSList *)connman_network_get_bssid_list(network);
                        if (bssid_list)
                                bssid_length = g_slist_length(bssid_list);
 
@@ -4782,6 +4908,59 @@ static void mesh_peer_removed(GSupplicantNetwork *supplicant_network)
 }
 #endif
 
+
+#if defined TIZEN_EXT
+static GSList *get_supported_security_list(unsigned int keymgmt,
+                                       bool owe_transition_mode,
+                                       GSupplicantNetwork *supplicant_network)
+{
+       GSList *sec_list = NULL;
+       dbus_bool_t privacy = g_supplicant_network_get_privacy(supplicant_network);
+       const char *enc_mode = g_supplicant_network_get_enc_mode(supplicant_network);
+
+       if (keymgmt &
+                       (G_SUPPLICANT_KEYMGMT_WPA_EAP |
+                                       G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
+               sec_list = g_slist_prepend (sec_list, "ieee8021x");
+       else if (keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_EAP)
+               sec_list = g_slist_prepend (sec_list, "ft_ieee8021x");
+
+       if (sec_list)
+               return sec_list;
+
+       if (keymgmt &
+                       (G_SUPPLICANT_KEYMGMT_WPA_PSK |
+                                       G_SUPPLICANT_KEYMGMT_WPA_PSK_256)) {
+               if (!g_strcmp0(enc_mode, "aes"))
+                       sec_list = g_slist_prepend (sec_list, "rsn");
+               else if (!g_strcmp0(enc_mode, "tkip"))
+                       sec_list = g_slist_prepend (sec_list, "psk");
+               else if (!g_strcmp0(enc_mode, "mixed")) {
+                       sec_list = g_slist_prepend (sec_list, "psk");
+                       sec_list = g_slist_prepend (sec_list, "rsn");
+               }
+       } else if (keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
+               sec_list = g_slist_prepend (sec_list, "ft_psk");
+
+       if (keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
+               sec_list = g_slist_prepend (sec_list, "sae");
+       if (keymgmt & G_SUPPLICANT_KEYMGMT_OWE || owe_transition_mode)
+               sec_list = g_slist_prepend (sec_list, "owe");
+       if (keymgmt & G_SUPPLICANT_KEYMGMT_DPP)
+               sec_list = g_slist_prepend (sec_list, "dpp");
+
+       if (sec_list)
+               return sec_list;
+
+       if (privacy)
+               sec_list = g_slist_prepend (sec_list, "wep");
+       else
+               sec_list = g_slist_prepend (sec_list, "none");
+
+       return sec_list;
+}
+#endif
+
 static void network_added(GSupplicantNetwork *supplicant_network)
 {
        struct connman_network *network;
@@ -4796,14 +4975,22 @@ static void network_added(GSupplicantNetwork *supplicant_network)
        bool wps_advertizing;
 
 #if defined TIZEN_EXT
+       bool owe_transition_mode;
+       const unsigned char *transition_mode_ssid;
+       const unsigned char *transition_mode_bssid;
+       unsigned int transition_mode_ssid_len;
+       unsigned int keymgmt;
        GSList *vsie_list = NULL;
+       GSList *sec_list = NULL;
        const unsigned char *country_code;
        ieee80211_modes_e phy_mode;
 #endif
 
        mode = g_supplicant_network_get_mode(supplicant_network);
        identifier = g_supplicant_network_get_identifier(supplicant_network);
-
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        DBG("%s", identifier);
 
        if (!g_strcmp0(mode, "adhoc"))
@@ -4898,16 +5085,30 @@ static void network_added(GSupplicantNetwork *supplicant_network)
                        g_supplicant_network_get_frequency(supplicant_network));
 
 #if defined TIZEN_EXT
+       keymgmt = g_supplicant_network_get_keymgmt(supplicant_network);
        connman_network_set_bssid(network,
                        g_supplicant_network_get_bssid(supplicant_network));
+       owe_transition_mode = (bool)g_supplicant_network_get_transition_mode(supplicant_network);
+       connman_network_set_bool(network, "WiFi.TRANSITION_MODE", owe_transition_mode);
+       if (owe_transition_mode) {
+               transition_mode_ssid = (unsigned char *)g_supplicant_network_get_transition_mode_ssid(supplicant_network, &transition_mode_ssid_len);
+               connman_network_set_blob(network, "WiFi.TRANSITION_MODE_SSID",
+                                                       transition_mode_ssid, transition_mode_ssid_len);
+               transition_mode_bssid = g_supplicant_network_get_transition_mode_bssid(supplicant_network);
+               connman_network_set_transition_mode_bssid(network, transition_mode_bssid);
+       }
+
+       sec_list = get_supported_security_list(keymgmt,
+                       owe_transition_mode, supplicant_network);
+
+       connman_network_set_sec_list(network, sec_list);
        connman_network_set_maxrate(network,
                        g_supplicant_network_get_maxrate(supplicant_network));
        connman_network_set_enc_mode(network,
                        g_supplicant_network_get_enc_mode(supplicant_network));
        connman_network_set_rsn_mode(network,
                        g_supplicant_network_get_rsn_mode(supplicant_network));
-       connman_network_set_keymgmt(network,
-                       g_supplicant_network_get_keymgmt(supplicant_network));
+       connman_network_set_keymgmt(network, keymgmt);
        connman_network_set_bool(network, "WiFi.HS20AP",
                        g_supplicant_network_is_hs20AP(supplicant_network));
        connman_network_set_bssid_list(network,
@@ -5047,7 +5248,8 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
        name = g_supplicant_network_get_name(network);
 
 #if defined TIZEN_EXT
-       DBG("name %s property %s", name, property);
+       if (!simplified_log)
+               DBG("name %s property %s", name, property);
 #else
        DBG("name %s", name);
 #endif
@@ -5091,7 +5293,7 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
                                        calculate_strength(network));
                update_needed = true;
        }
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
        else if (g_str_equal(property, "LastConnectedBSSID")) {
                const char *ident, *group;
                char *service_ident;
@@ -5106,13 +5308,18 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
                        need_save = connman_device_set_last_connected_ident(wifi->device, service_ident);
                        if (need_save)
                                connman_device_save_last_connected(wifi->device);
+
+                       g_free(service_ident);
                }
 
                connman_network_set_last_connected_bssid(connman_network,
                                        g_supplicant_network_get_last_connected_bssid(network));
 
                update_needed = true;
-       } else if (g_str_equal(property, "UpdateAssocReject")) {
+       }
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#if defined TIZEN_EXT
+       else if (g_str_equal(property, "UpdateAssocReject")) {
                connman_network_set_assoc_reject_table(connman_network,
                                        g_supplicant_network_get_assoc_reject_table(network));
                update_needed = true;
@@ -5186,7 +5393,22 @@ static void network_associated(GSupplicantNetwork *network)
        if (wifi->network) {
                if (wifi->network == connman_network)
                        return;
-
+#if TIZEN_EXT
+               unsigned int ssid_len;
+               DBG("network1 ssid[%s] , OWE[%d],ssid[%s]",
+                       (char *)connman_network_get_blob(wifi->network,"WiFi.SSID", &ssid_len),
+                       connman_network_get_bool(wifi->network,"WiFi.TRANSITION_MODE"),
+                       (char *)connman_network_get_blob(wifi->network,"WiFi.TRANSITION_MODE_SSID", &ssid_len));
+
+               DBG("network1 ssid[%s], OWE[%d], ssid[%s]",
+                       (char *)connman_network_get_blob(connman_network,"WiFi.SSID",&ssid_len),
+                       connman_network_get_bool(connman_network,"WiFi.TRANSITION_MODE"),
+                       (char *)connman_network_get_blob(connman_network,"WiFi.TRANSITION_MODE_SSID", &ssid_len));
+               if (connman_network_check_transition_mode(wifi->network, connman_network)) {//OWE trasition mode check
+                       DBG("OWE transition mode is TRUE");
+                       return;
+               }
+#endif
                /*
                 * This should never happen, we got associated with
                 * a network different than the one we were expecting.
@@ -5570,7 +5792,8 @@ static void scan_done(GSupplicantInterface *interface)
                        scanning = connman_device_get_scanning(wifi->device,
                                        CONNMAN_SERVICE_TYPE_WIFI);
                        if (!scanning)
-                               __connman_technology_notify_scan_done(scan_type);
+                               __connman_technology_notify_scan_done(
+                                               connman_device_get_string(wifi->device, "Interface"), scan_type);
                        break;
                }
        }
@@ -5800,6 +6023,9 @@ static void sta_remove_callback(int result,
        info->wifi->interface = NULL;
 
        g_supplicant_interface_create(info->ifname, driver, info->wifi->bridge,
+#ifdef TIZEN_EXT
+                       0, 0, 60,
+#endif /* TIZEN_EXT */
                                                ap_create_callback,
                                                        info);
 }
@@ -5966,7 +6192,7 @@ static int tech_set_regdom(struct connman_technology *technology, const char *al
        return g_supplicant_set_country(alpha2, regdom_callback, NULL);
 }
 
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
 static void supp_ins_init(void)
 {
        const char *string;
@@ -5991,7 +6217,7 @@ static void supp_ins_init(void)
                connman_setting_get_int("INSSignalLevel3_24GHz")
        );
 }
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
 
 static struct connman_technology_driver tech_driver = {
        .name           = "wifi",
@@ -6027,9 +6253,9 @@ static int wifi_init(void)
        failed_bssids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 #endif
 
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
        supp_ins_init();
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
        return 0;
 }