Add DPP service based on configuration file
[platform/upstream/connman.git] / gsupplicant / supplicant.c
index 66644c8..431c6e7 100644 (file)
@@ -104,6 +104,7 @@ static struct strvalmap keymgmt_map[] = {
 #if defined TIZEN_EXT
        { "sae",                G_SUPPLICANT_KEYMGMT_SAE                },
        { "owe",                G_SUPPLICANT_KEYMGMT_OWE                },
+       { "dpp",                G_SUPPLICANT_KEYMGMT_DPP                },
 #endif
        { }
 };
@@ -172,6 +173,11 @@ struct added_network_information {
        GSupplicantSecurity security;
        char * passphrase;
        char * private_passphrase;
+#if defined TIZEN_EXT
+       char *connector;
+       char *c_sign_key;
+       char *net_access_key;
+#endif
 };
 
 #if defined TIZEN_EXT_WIFI_MESH
@@ -259,6 +265,7 @@ struct g_supplicant_bss {
 #if defined TIZEN_EXT
        dbus_bool_t sae;
        dbus_bool_t owe;
+       dbus_bool_t dpp;
 #endif
 };
 
@@ -461,6 +468,8 @@ static const char *security2string(GSupplicantSecurity security)
                return "sae";
        case G_SUPPLICANT_SECURITY_OWE:
                return "owe";
+       case G_SUPPLICANT_SECURITY_DPP:
+               return "dpp";
 #endif
        }
 
@@ -524,6 +533,23 @@ static bool compare_network_parameters(GSupplicantInterface *interface,
                return FALSE;
        }
 
+#if defined TIZEN_EXT
+       if (interface->network_info.connector &&
+                       g_strcmp0(interface->network_info.connector,
+                               ssid->connector) != 0) {
+               return FALSE;
+       }
+       if (interface->network_info.c_sign_key &&
+                       g_strcmp0(interface->network_info.c_sign_key,
+                               ssid->c_sign_key) != 0) {
+               return FALSE;
+       }
+       if (interface->network_info.net_access_key &&
+                       g_strcmp0(interface->network_info.net_access_key,
+                               ssid->net_access_key) != 0) {
+               return FALSE;
+       }
+#endif
        return TRUE;
 }
 
@@ -532,9 +558,19 @@ static void remove_network_information(GSupplicantInterface * interface)
        g_free(interface->network_info.ssid);
        g_free(interface->network_info.passphrase);
        g_free(interface->network_info.private_passphrase);
+#if defined TIZEN_EXT
+       g_free(interface->network_info.connector);
+       g_free(interface->network_info.c_sign_key);
+       g_free(interface->network_info.net_access_key);
+#endif
        interface->network_info.ssid = NULL;
        interface->network_info.passphrase = NULL;
        interface->network_info.private_passphrase = NULL;
+#if defined TIZEN_EXT
+       interface->network_info.connector = NULL;
+       interface->network_info.c_sign_key = NULL;
+       interface->network_info.net_access_key = NULL;
+#endif
 }
 
 static int store_network_information(GSupplicantInterface * interface,
@@ -767,6 +803,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)
@@ -920,6 +980,8 @@ static void remove_bss(gpointer data)
 {
        struct g_supplicant_bss *bss = data;
 
+       supplicant_dbus_property_call_cancel_all(bss);
+
        g_free(bss->path);
 #if defined TIZEN_EXT
        g_slist_free_full(bss->vsie_list, g_free);
@@ -1660,6 +1722,7 @@ const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
 #if defined TIZEN_EXT
            network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
            network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
+           network->best_bss->security == G_SUPPLICANT_SECURITY_DPP ||
 #endif /* TIZEN_EXT */
            network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
                unsigned int pairwise;
@@ -1690,7 +1753,8 @@ bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network)
 
 #if defined TIZEN_EXT
        if (network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
-                       network->best_bss->security == G_SUPPLICANT_SECURITY_OWE)
+                       network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
+                       network->best_bss->security == G_SUPPLICANT_SECURITY_DPP)
                return false;
 #endif /* TIZEN_EXT */
 
@@ -1948,7 +2012,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)
@@ -2024,6 +2087,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);
@@ -2035,10 +2099,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);
@@ -2058,6 +2125,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;
+       }
+
 #if defined TIZEN_EXT
        network->keymgmt = bss->keymgmt;
 
@@ -2098,7 +2170,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");
        }
 
        /*
@@ -2346,7 +2421,6 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 
        bss->wps_capabilities = 0;
        bss->keymgmt = 0;
-       memset(bss->country_code, 0, COUNTRY_CODE_LENGTH);
 
        for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
                                                        ie += ie[1] + 2) {
@@ -2505,6 +2579,8 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
                bss->sae = TRUE;
        if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_OWE)
                bss->owe = TRUE;
+       if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_DPP)
+               bss->dpp = TRUE;
 #endif
 
        if (bss->ieee8021x)
@@ -2516,12 +2592,12 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
                bss->security = G_SUPPLICANT_SECURITY_FT_PSK;
        else if (bss->ft_ieee8021x == TRUE)
                bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
-#endif
-#if defined TIZEN_EXT
        else if (bss->sae)
                bss->security = G_SUPPLICANT_SECURITY_SAE;
        else if (bss->owe)
                bss->security = G_SUPPLICANT_SECURITY_OWE;
+       else if (bss->dpp)
+               bss->security = G_SUPPLICANT_SECURITY_DPP;
 #endif
        else if (bss->privacy)
                bss->security = G_SUPPLICANT_SECURITY_WEP;
@@ -2710,7 +2786,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)
@@ -3405,11 +3481,48 @@ void *copy_vsie_list(gconstpointer src, gpointer data)
 #endif
 
 
+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("");
@@ -3427,6 +3540,7 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
                return;
 
        supplicant_dbus_property_foreach(iter, bss_property, bss);
+
 #if defined TIZEN_EXT
        network->frequency = bss->frequency;
        network->phy_mode = bss->phy_mode;
@@ -3437,18 +3551,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)
@@ -3460,20 +3574,43 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
                new_bss->vsie_list = g_slist_copy_deep(bss->vsie_list, copy_vsie_list, NULL);
 #endif
 
-               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");
+       }
+
 #if defined TIZEN_EXT
        if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
                network->wps = TRUE;
@@ -3611,7 +3748,7 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
 
        if (g_strcmp0(name, "success") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
-       else if (g_strcmp0(name, "failed") == 0)
+       else if (g_strcmp0(name, "fail") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
        else
                interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
@@ -3647,56 +3784,6 @@ static void signal_power_off(const char *path, DBusMessageIter *iter)
 }
 #endif
 
-static void signal_station_connected(const char *path, DBusMessageIter *iter)
-{
-       GSupplicantInterface *interface;
-       const char *sta_mac = NULL;
-
-       SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
-
-       if (callbacks_pointer->add_station == NULL)
-               return;
-
-       if (g_strcmp0(path, "/") == 0)
-               return;
-
-       interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
-               return;
-
-       dbus_message_iter_get_basic(iter, &sta_mac);
-       if (sta_mac == NULL)
-               return;
-
-       SUPPLICANT_DBG("New station %s connected", sta_mac);
-       callbacks_pointer->add_station(sta_mac);
-}
-
-static void signal_station_disconnected(const char *path, DBusMessageIter *iter)
-{
-       GSupplicantInterface *interface;
-       const char *sta_mac = NULL;
-
-       SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
-
-       if (callbacks_pointer->remove_station == NULL)
-               return;
-
-       if (g_strcmp0(path, "/") == 0)
-               return;
-
-       interface = g_hash_table_lookup(interface_table, path);
-       if (interface == NULL)
-               return;
-
-       dbus_message_iter_get_basic(iter, &sta_mac);
-       if (sta_mac == NULL)
-               return;
-
-       SUPPLICANT_DBG("Station %s disconnected", sta_mac);
-       callbacks_pointer->remove_station(sta_mac);
-}
-
 static void create_peer_identifier(GSupplicantPeer *peer)
 {
        const unsigned char test[ETH_ALEN] = {};
@@ -4464,6 +4551,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   },
 
@@ -4473,9 +4562,6 @@ static struct {
        { "org.tizen.system.deviced.PowerOff", "ChangeState", signal_power_off },
 #endif
 
-       { SUPPLICANT_INTERFACE".Interface", "StaAuthorized", signal_station_connected      },
-       { SUPPLICANT_INTERFACE".Interface", "StaDeauthorized", signal_station_disconnected },
-
        { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceFound", signal_peer_found },
        { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceLost",  signal_peer_lost  },
 
@@ -5030,7 +5116,7 @@ struct interface_mesh_peer_data {
 };
 
 static void interface_mesh_change_peer_params(DBusMessageIter *iter,
-                                                                                  void *user_data)
+                                               void *user_data)
 {
        struct interface_mesh_peer_data *data = user_data;
 
@@ -5352,14 +5438,16 @@ static void interface_scan_params(DBusMessageIter *iter, void *user_data)
                                        DBUS_TYPE_STRING, &type);
 
 #if defined TIZEN_EXT
-               SUPPLICANT_DBG("[specific_scan] num_ssids %d", data->scan_params->num_ssids);
-               if (data->scan_params->num_ssids != 0)
+               SUPPLICANT_DBG("[specific_scan] num_ssids %d",
+                              data->scan_params->num_ssids);
 #endif
-                       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
@@ -5506,6 +5594,7 @@ static void interface_signalpoll_result(const char *error,
        struct interface_signalpoll_data *data = user_data;
        int err = 0;
        dbus_int32_t maxspeed = 0;
+       unsigned char strength = 0;
        DBusMessageIter sub_iter, dict;
 
        if (error) {
@@ -5534,13 +5623,19 @@ static void interface_signalpoll_result(const char *error,
                                SUPPLICANT_DBG("linkspeed = %d", maxspeed);
                                break;
                        }
+               case DBUS_TYPE_BYTE:
+                       if (g_strcmp0(key, "rssi") == 0) {
+                               dbus_message_iter_get_basic(&value, &strength);
+                               SUPPLICANT_DBG("Strength = %d", strength);
+                               break;
+                       }
                }
                dbus_message_iter_next(&dict);
        }
 
 out:
        if(data->callback)
-               data->callback(err, maxspeed, data->user_data);
+               data->callback(err, maxspeed, strength, data->user_data);
 
        g_free(data->path);
        dbus_free(data);
@@ -5634,6 +5729,9 @@ static void interface_select_network_result(const char *error,
 #if defined TIZEN_EXT
        g_free(data->ssid->ssid);
        g_free((char *)data->ssid->passphrase);
+       g_free((char *)data->ssid->connector);
+       g_free((char *)data->ssid->c_sign_key);
+       g_free((char *)data->ssid->net_access_key);
 #endif
        g_free(data->ssid);
        dbus_free(data);
@@ -5723,6 +5821,9 @@ error:
 #if defined TIZEN_EXT
        g_free(data->ssid->ssid);
        g_free((char *)data->ssid->passphrase);
+       g_free((char *)data->ssid->connector);
+       g_free((char *)data->ssid->c_sign_key);
+       g_free((char *)data->ssid->net_access_key);
 #endif
        g_free(data->ssid);
        g_free(data);
@@ -5942,7 +6043,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
@@ -6185,12 +6288,77 @@ static void add_network_security_proto(DBusMessageIter *dict,
 static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid)
 {
        if (ssid->security != G_SUPPLICANT_SECURITY_SAE
-                       && ssid->security != G_SUPPLICANT_SECURITY_OWE)
+                       && ssid->security != G_SUPPLICANT_SECURITY_OWE
+                       && ssid->security != G_SUPPLICANT_SECURITY_DPP)
                return;
 
        supplicant_dbus_dict_append_basic(dict, "ieee80211w", DBUS_TYPE_UINT32,
                                          &ssid->ieee80211w);
 }
+
+static void add_network_security_connector(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+       if (ssid->connector && strlen(ssid->connector) > 0) {
+               const char *key = "dpp_connector";
+
+               supplicant_dbus_dict_append_basic(dict,
+                               key, DBUS_TYPE_STRING,
+                               &ssid->connector);
+       }
+}
+
+static size_t convert_hexstr_to_bin(const char *hex_str, unsigned char **bin)
+{
+       unsigned char *bin_res = NULL;
+       unsigned int i, j, hex;
+       size_t hex_str_len;
+
+       if (!hex_str || strlen(hex_str) == 0)
+               return 0;
+
+       hex_str_len = strlen(hex_str);
+       bin_res = g_try_malloc0(hex_str_len / 2);
+       if (!bin_res)
+               return 0;
+
+       j = 0;
+       for (i = 0; i < hex_str_len; i+=2) {
+               sscanf(hex_str + i, "%02x", &hex);
+               bin_res[j++] = hex;
+       }
+
+       *bin = bin_res;
+       return hex_str_len / 2;
+}
+
+static void add_network_security_c_sign_key(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+       if (ssid->c_sign_key && strlen(ssid->c_sign_key) > 0) {
+               const char *key = "dpp_csign";
+               unsigned char *bin_csign = NULL;
+               size_t bin_csign_len = convert_hexstr_to_bin(ssid->c_sign_key, &bin_csign);
+               if  (bin_csign_len != 0)
+                       supplicant_dbus_dict_append_fixed_array(dict,
+                                       key, DBUS_TYPE_BYTE,
+                                       &bin_csign, bin_csign_len);
+               g_free(bin_csign);
+       }
+}
+
+static void add_network_security_net_access_key(DBusMessageIter *dict, GSupplicantSSID *ssid)
+{
+       if (ssid->net_access_key && strlen(ssid->net_access_key) > 0) {
+               const char *key = "dpp_netaccesskey";
+               unsigned char *bin_netaccesskey = NULL;
+               size_t bin_netaccesskey_len = convert_hexstr_to_bin(ssid->net_access_key, &bin_netaccesskey);
+               if  (bin_netaccesskey_len != 0)
+                       supplicant_dbus_dict_append_fixed_array(dict,
+                                       key, DBUS_TYPE_BYTE,
+                                       &bin_netaccesskey, bin_netaccesskey_len);
+               g_free(bin_netaccesskey);
+       }
+}
+
 #endif
 
 static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
@@ -6243,6 +6411,12 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
                add_network_security_ciphers(dict, ssid);
                add_network_security_proto(dict, ssid);
                break;
+       case G_SUPPLICANT_SECURITY_DPP:
+               key_mgmt = "DPP";
+               add_network_security_connector(dict, ssid);
+               add_network_security_c_sign_key(dict, ssid);
+               add_network_security_net_access_key(dict, ssid);
+               break;
 #endif
        }
 
@@ -6308,10 +6482,6 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
                                        DBUS_TYPE_BYTE, &ssid->ssid,
                                                ssid->ssid_len);
 
-       supplicant_dbus_dict_append_basic(&dict, "ignore_broadcast_ssid",
-                                       DBUS_TYPE_INT32,
-                                       &ssid->ignore_broadcast_ssid);
-
 #if defined TIZEN_EXT
        if (ssid->bssid) {
                char *bssid = NULL;
@@ -6408,6 +6578,7 @@ static void wps_start(const char *error, DBusMessageIter *iter, void *user_data)
                dbus_free(data);
                return;
        }
+
 #if defined TIZEN_EXT
        GSupplicantSSID *ssid = data->ssid;
        if (ssid->pin_wps != NULL) {
@@ -6505,6 +6676,9 @@ done:
                g_free(data->path);
                g_free(data->ssid->ssid);
                g_free((char *)data->ssid->passphrase);
+               g_free((char *)data->ssid->connector);
+               g_free((char *)data->ssid->c_sign_key);
+               g_free((char *)data->ssid->net_access_key);
                g_free(data->ssid);
                dbus_free(data);
        }
@@ -6561,6 +6735,146 @@ static int send_decryption_request(const char *passphrase,
 
        return 0;
 }
+
+static void decrypt_conf_obj_reply(DBusPendingCall *call,
+                                               void *user_data)
+{
+       DBusMessage *reply;
+       DBusError error;
+       DBusMessageIter iter, dict;
+       char *out_data;
+       int ret;
+       struct interface_connect_data *data = user_data;
+
+       reply = dbus_pending_call_steal_reply(call);
+
+       dbus_error_init(&error);
+       if (dbus_set_error_from_message(&error, reply)) {
+               SUPPLICANT_DBG("decryption_conf_obj_reply() %s %s", error.name, error.message);
+               dbus_error_free(&error);
+               ret = -EINVAL;
+               goto done;
+       }
+
+       if (dbus_message_iter_init(reply, &iter) == FALSE) {
+               SUPPLICANT_DBG("dbus_message_iter_init() failed");
+               ret = -EINVAL;
+               goto done;
+       }
+
+       dbus_message_iter_recurse(&iter, &dict);
+
+       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+               DBusMessageIter entry, value;
+               const char *key;
+
+               dbus_message_iter_recurse(&dict, &entry);
+               dbus_message_iter_get_basic(&entry, &key);
+               dbus_message_iter_next(&entry);
+               dbus_message_iter_recurse(&entry, &value);
+               if (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) {
+                       if (g_strcmp0(key, "connector") == 0) {
+                               dbus_message_iter_get_basic(&value, &out_data);
+                               data->ssid->connector = g_strdup((const gchar *)out_data);
+                               SUPPLICANT_DBG("connector %s", data->ssid->connector);
+                       } else if (g_strcmp0(key, "c_sign_key") == 0) {
+                               dbus_message_iter_get_basic(&value, &out_data);
+                               data->ssid->c_sign_key = g_strdup((const gchar *)out_data);
+                               SUPPLICANT_DBG("c_sign_key %s", data->ssid->c_sign_key);
+                       } else if (g_strcmp0(key, "net_access_key") == 0) {
+                               dbus_message_iter_get_basic(&value, &out_data);
+                               data->ssid->net_access_key = g_strdup((const gchar *)out_data);
+                               SUPPLICANT_DBG("net_access_key %s", data->ssid->net_access_key);
+                       }
+               }
+               dbus_message_iter_next(&dict);
+       }
+
+       ret = supplicant_dbus_method_call(data->interface->path,
+               SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+               interface_add_network_params,
+               interface_add_network_result, data,
+               data->interface);
+
+done:
+       if (ret < 0) {
+               SUPPLICANT_DBG("AddNetwork failed %d", ret);
+               callback_assoc_failed(decrypt_request_data.data->user_data);
+               g_free(data->path);
+               g_free(data->ssid->ssid);
+               g_free((char *)data->ssid->connector);
+               g_free((char *)data->ssid->c_sign_key);
+               g_free((char *)data->ssid->net_access_key);
+               g_free(data->ssid);
+               dbus_free(data);
+       }
+
+       dbus_message_unref(reply);
+       dbus_pending_call_unref(call);
+
+       decrypt_request_data.pending_call = NULL;
+       decrypt_request_data.data = NULL;
+}
+
+static int send_decryption_conf_obj_request(GSupplicantSSID *ssid,
+                       struct interface_connect_data *data)
+{
+       DBusMessage *msg = NULL;
+       DBusPendingCall *call;
+
+       SUPPLICANT_DBG("Decryption configuration object request");
+
+       if (!ssid) {
+               SUPPLICANT_DBG("Invalid parameter");
+               return -EINVAL;
+       }
+
+       if (!connection)
+               return -EINVAL;
+
+       msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
+                       NETCONFIG_WIFI_INTERFACE, "DecryptConfObj");
+       if (!msg)
+               return -EINVAL;
+
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->connector,
+                                                       DBUS_TYPE_INVALID);
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->c_sign_key,
+                                                       DBUS_TYPE_INVALID);
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &ssid->net_access_key,
+                                                       DBUS_TYPE_INVALID);
+
+       if (!dbus_connection_send_with_reply(connection, msg,
+                               &call, DBUS_TIMEOUT_USE_DEFAULT)) {
+               dbus_message_unref(msg);
+               return -EIO;
+       }
+
+       if (!call) {
+               dbus_message_unref(msg);
+               return -EIO;
+       }
+
+       decrypt_request_data.pending_call = call;
+       decrypt_request_data.data = data;
+
+       dbus_pending_call_set_notify(call, decrypt_conf_obj_reply, data, NULL);
+       dbus_message_unref(msg);
+
+       SUPPLICANT_DBG("Decrypt Conf Obj request succeeded");
+
+       return 0;
+}
+
+static bool is_valid_config_object(GSupplicantSSID *ssid)
+{
+       return ((ssid->connector &&
+                       g_strcmp0(ssid->connector, "") != 0) &&
+                       (ssid->c_sign_key &&
+                       g_strcmp0(ssid->c_sign_key, "") != 0) &&
+                       (ssid->net_access_key &&
+                       g_strcmp0(ssid->net_access_key, "") != 0));
+}
 #endif
 
 int g_supplicant_interface_connect(GSupplicantInterface *interface,
@@ -6645,7 +6959,7 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                        intf_data->user_data = user_data;
                        intf_data->network_remove_in_progress = TRUE;
                        network_remove(intf_data);
-               } else
+               } else {
 #if defined TIZEN_EXT
                        if (ssid->passphrase &&
                            g_strcmp0(ssid->passphrase, "") != 0 &&
@@ -6656,14 +6970,20 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                                ret = send_decryption_request(ssid->passphrase, data);
                                if (ret < 0)
                                        SUPPLICANT_DBG("Decryption request failed %d", ret);
+                       } else if (is_valid_config_object(ssid)) {
+                               ret = send_decryption_conf_obj_request(ssid, data);
+                               if (ret < 0)
+                                       SUPPLICANT_DBG("Decryption Conf Obj request failed %d", ret);
+
                        } else
 #endif
-                               ret = supplicant_dbus_method_call(interface->path,
-                                               SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
-                                               interface_add_network_params,
-                                               interface_add_network_result, data,
-                                               interface);
-       }
+                       ret = supplicant_dbus_method_call(interface->path,
+                                       SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+                                       interface_add_network_params,
+                                       interface_add_network_result, data,
+                                       interface);
+               }
+        }
 
        if (ret < 0) {
                g_free(data->path);
@@ -6720,6 +7040,14 @@ static void network_remove_result(const char *error,
                                g_free(connect_data->path);
                                dbus_free(connect_data);
                        }
+               } else if (is_valid_config_object(data->ssid)) {
+                       ret = send_decryption_conf_obj_request(data->ssid, connect_data);
+                       if (ret < 0) {
+                               SUPPLICANT_DBG("Decryption Conf Obj request failed %d", ret);
+                               g_free(connect_data->ssid);
+                               g_free(connect_data->path);
+                               dbus_free(connect_data);
+                       }
                } else
 #endif
                supplicant_dbus_method_call(data->interface->path,
@@ -7312,6 +7640,7 @@ int g_supplicant_set_widi_ies(GSupplicantP2PServiceParams *p2p_service_params,
        return -EINPROGRESS;
 }
 
+
 static const char *g_supplicant_rule0 = "type=signal,"
                                        "path=" DBUS_PATH_DBUS ","
                                        "sender=" DBUS_SERVICE_DBUS ","