Merge "dbus: modify dbus policy configuration" into tizen
authortaesub kim <taesub.kim@samsung.com>
Fri, 18 Aug 2017 02:28:13 +0000 (02:28 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Fri, 18 Aug 2017 02:28:13 +0000 (02:28 +0000)
gsupplicant/gsupplicant.h
gsupplicant/supplicant.c
include/device.h
plugins/wifi.c
src/connman.h
src/device.c
src/manager.c
src/network.c
src/service.c
src/technology.c

index fe693cd..f115c5e 100755 (executable)
@@ -377,6 +377,8 @@ const char *g_supplicant_network_get_eap(GSupplicantNetwork *network);
 const char *g_supplicant_network_get_identity(GSupplicantNetwork *network);
 const char *g_supplicant_network_get_phase2(GSupplicantNetwork *network);
 unsigned int g_supplicant_network_get_keymgmt(GSupplicantNetwork *network);
+const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
+                                               unsigned int *wifi_vsie_len);
 #endif
 
 struct _GSupplicantCallbacks {
index 1c19771..0d5ff3b 100755 (executable)
@@ -211,6 +211,8 @@ struct g_supplicant_bss {
 #if defined TIZEN_EXT
        dbus_bool_t ft_psk;
        dbus_bool_t ft_ieee8021x;
+       char *wifi_vsie;
+       unsigned int wifi_vsie_len;
 #endif
        unsigned int wps_capabilities;
 };
@@ -237,6 +239,8 @@ struct _GSupplicantNetwork {
        char *identity;
        char *phase2;
        unsigned int keymgmt;
+       char *wifi_vsie;
+       unsigned int wifi_vsie_len;
 #endif
 };
 
@@ -641,6 +645,10 @@ static void remove_network(gpointer data)
        g_free(network->identity);
        g_free(network->phase2);
 #endif
+#if defined TIZEN_EXT
+       g_free(network->wifi_vsie);
+#endif
+
        g_free(network);
 }
 
@@ -649,6 +657,9 @@ static void remove_bss(gpointer data)
        struct g_supplicant_bss *bss = data;
 
        g_free(bss->path);
+#if defined TIZEN_EXT
+       g_free(bss->wifi_vsie);
+#endif
        g_free(bss);
 }
 
@@ -1345,6 +1356,17 @@ bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network)
                return false;
 }
 
+const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
+                                               unsigned int *wifi_vsie_len)
+{
+       if (!network) {
+               *wifi_vsie_len = 0;
+               return NULL;
+       }
+
+       *wifi_vsie_len = network->wifi_vsie_len;
+       return network->wifi_vsie;
+}
 #endif
 
 static void merge_network(GSupplicantNetwork *network)
@@ -1639,6 +1661,17 @@ static void add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
 
 #if defined TIZEN_EXT
        network->keymgmt = bss->keymgmt;
+
+       if (bss->wifi_vsie_len > 0) {
+               SUPPLICANT_DBG("vsie len: %d", bss->wifi_vsie_len);
+               network->wifi_vsie = (char *)g_try_malloc0(bss->wifi_vsie_len);
+               if(network->wifi_vsie) {
+                       network->wifi_vsie_len = bss->wifi_vsie_len;
+                       memcpy(network->wifi_vsie, bss->wifi_vsie, network->wifi_vsie_len);
+               } else {
+                       SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
+               }
+       }
 #endif
 
        SUPPLICANT_DBG("New network %s created", network->name);
@@ -1818,6 +1851,9 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 {
        struct g_supplicant_bss *bss = user_data;
        const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
+#if defined TIZEN_EXT
+       const unsigned char WIFI_OUI[] = {0x00, 0x16, 0x32};
+#endif
        unsigned char *ie, *ie_end;
        DBusMessageIter array;
        unsigned int value;
@@ -1833,6 +1869,9 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 #define WPS_PBC           0x04
 #define WPS_PIN           0x00
 #define WPS_CONFIGURED    0x02
+#if defined TIZEN_EXT
+#define VENDOR_SPECIFIC_INFO 0xDD
+#endif
 
        dbus_message_iter_recurse(iter, &array);
        dbus_message_iter_get_fixed_array(&array, &ie, &ie_len);
@@ -1845,7 +1884,19 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 
        for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
                                                        ie += ie[1] + 2) {
-
+#if defined TIZEN_EXT
+               if((ie[0] == VENDOR_SPECIFIC_INFO) && (memcmp(ie+2, WIFI_OUI, sizeof(WIFI_OUI)) == 0)) {
+                               SUPPLICANT_DBG("IE: match WIFI_OUI");
+                               bss->wifi_vsie = (char *)g_try_malloc0(ie[1] + 2);   // tag number size(1), tag length size(1)
+                               if (bss->wifi_vsie) {
+                                       bss->wifi_vsie_len = ie[1] + 2;
+                                       memcpy(bss->wifi_vsie, ie, bss->wifi_vsie_len);
+                               } else {
+                                       SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
+                               }
+                               continue;
+               }
+#endif
                if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN ||
                        memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0)
                        continue;
index 57b925c..dafdca2 100755 (executable)
@@ -130,6 +130,11 @@ struct connman_device_driver {
                        const char *security, void *user_data);
        int (*set_regdom) (struct connman_device *device,
                                                const char *alpha2);
+#if defined TIZEN_EXT
+       int (*specific_scan) (enum connman_service_type type,
+                       struct connman_device *device, int scan_type,
+                       GSList *specific_scan_list, void *user_data);
+#endif
 };
 
 int connman_device_driver_register(struct connman_device_driver *driver);
index fd046e9..7f99ace 100755 (executable)
@@ -1831,6 +1831,125 @@ static int p2p_find(struct connman_device *device)
        return ret;
 }
 
+#if defined TIZEN_EXT
+static void specific_scan_callback(int result, GSupplicantInterface *interface,
+                                               void *user_data)
+{
+       struct connman_device *device = user_data;
+       struct wifi_data *wifi = connman_device_get_data(device);
+       bool scanning;
+
+       DBG("result %d wifi %p", result, wifi);
+
+       if (wifi && wifi->scan_params) {
+               g_supplicant_free_scan_params(wifi->scan_params);
+               wifi->scan_params = NULL;
+       }
+
+       scanning = connman_device_get_scanning(device);
+       if (scanning) {
+               connman_device_set_scanning(device,
+                               CONNMAN_SERVICE_TYPE_WIFI, false);
+               connman_device_unref(device);
+       }
+}
+
+static int wifi_specific_scan(enum connman_service_type type,
+                       struct connman_device *device, int scan_type,
+                       GSList *specific_scan_list, void *user_data)
+{
+       GSList *list = NULL;
+       char *ssid = NULL;
+       struct wifi_data *wifi = connman_device_get_data(device);
+       GSupplicantScanParams *scan_params = NULL;
+       struct scan_ssid *scan_ssid;
+       bool scanning;
+       int ret;
+       int freq;
+       int count = 0;
+
+       if (!wifi)
+               return -ENODEV;
+
+       if (wifi->p2p_device)
+               return 0;
+
+       if (type == CONNMAN_SERVICE_TYPE_P2P)
+               return p2p_find(device);
+
+       if (wifi->tethering)
+               return 0;
+
+       scanning = connman_device_get_scanning(device);
+       if (scanning)
+               return -EALREADY;
+
+       DBG("scan_type: %d", scan_type);
+       if (scan_type == 1) { /* ssid based scan */
+               scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
+               if (!scan_params)
+                       return -ENOMEM;
+
+               scan_ssid = g_try_new0(struct scan_ssid, 1);
+               if (!scan_ssid) {
+                       g_free(scan_params);
+                       return -ENOMEM;
+               }
+               for (list = specific_scan_list; list; list = list->next) {
+                       ssid = (char *)list->data;
+                       int ssid_len = strlen(ssid);
+
+                       memcpy(scan_ssid->ssid, ssid, (ssid_len + 1));
+                       DBG("scan ssid %s len: %d", scan_ssid->ssid, ssid_len);
+                       scan_ssid->ssid_len = ssid_len;
+                       scan_params->ssids = g_slist_prepend(scan_params->ssids, scan_ssid);
+                       count++;
+               }
+               scan_params->num_ssids = count;
+
+       } else if (scan_type == 2) { /* frequency based scan */
+
+               scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
+               if (!scan_params)
+                       return -ENOMEM;
+
+               scan_params->freqs = g_try_new0(uint16_t, 1);
+               if (!scan_params->freqs) {
+                       g_free(scan_params);
+                       return -ENOMEM;
+               }
+               count = 0;
+               for (list = specific_scan_list; list; list = list->next) {
+                       freq = (int)list->data;
+                       DBG("freq: %d", freq);
+                       scan_params->freqs[count] = freq;
+                       count++;
+               }
+               scan_params->num_freqs = count;
+
+       } else {
+               DBG("Invalid scan");
+               return -EINVAL;
+       }
+
+       reset_autoscan(device);
+       connman_device_ref(device);
+
+       ret = g_supplicant_interface_scan(wifi->interface, scan_params,
+                                               specific_scan_callback, device);
+
+       if (ret == 0) {
+               connman_device_set_scanning(device,
+                               CONNMAN_SERVICE_TYPE_WIFI, true);
+       } else {
+               g_supplicant_free_scan_params(scan_params);
+               connman_device_unref(device);
+       }
+
+       return ret;
+}
+#endif
+
 /*
  * Note that the hidden scan is only used when connecting to this specific
  * hidden AP first time. It is not used when system autoconnects to hidden AP.
@@ -2009,6 +2128,9 @@ static struct connman_device_driver wifi_ng_driver = {
        .disable        = wifi_disable,
        .scan           = wifi_scan,
        .set_regdom     = wifi_set_regdom,
+#if defined TIZEN_EXT
+       .specific_scan  = wifi_specific_scan,
+#endif
 };
 
 static void system_ready(void)
@@ -2928,6 +3050,11 @@ static void network_added(GSupplicantNetwork *supplicant_network)
        bool wps_ready;
        bool wps_advertizing;
 
+#if defined TIZEN_EXT
+       const char *wifi_vsie;
+       unsigned int wifi_vsie_len;
+#endif
+
        mode = g_supplicant_network_get_mode(supplicant_network);
        identifier = g_supplicant_network_get_identifier(supplicant_network);
 
@@ -2952,6 +3079,9 @@ static void network_added(GSupplicantNetwork *supplicant_network)
 
        ssid = g_supplicant_network_get_ssid(supplicant_network, &ssid_len);
 
+#if defined TIZEN_EXT
+       wifi_vsie = g_supplicant_network_get_wifi_vsie(supplicant_network, &wifi_vsie_len);
+#endif
        network = connman_device_get_network(wifi->device, identifier);
 
        if (!network) {
@@ -2975,6 +3105,11 @@ static void network_added(GSupplicantNetwork *supplicant_network)
 
        connman_network_set_blob(network, "WiFi.SSID",
                                                ssid, ssid_len);
+#if defined TIZEN_EXT
+       if(wifi_vsie_len > 0 && wifi_vsie)
+               connman_network_set_blob(network, "WiFi.Vsie",
+                                                       wifi_vsie, wifi_vsie_len);
+#endif
        connman_network_set_string(network, "WiFi.Security", security);
        connman_network_set_strength(network,
                                calculate_strength(supplicant_network));
index 237c1ec..5e257bf 100755 (executable)
@@ -576,6 +576,10 @@ int __connman_device_request_hidden_scan(struct connman_device *device,
                                const char *ssid, unsigned int ssid_len,
                                const char *identity, const char *passphrase,
                                const char *security, void *user_data);
+#if defined TIZEN_EXT
+int __connman_device_request_specific_scan(enum connman_service_type type,
+                               int scan_type, GSList *specific_scan_list);
+#endif
 
 bool __connman_device_isfiltered(const char *devname);
 
@@ -917,6 +921,10 @@ int __connman_rtnl_init(void);
 void __connman_rtnl_start(void);
 void __connman_rtnl_cleanup(void);
 
+#if defined TIZEN_EXT
+void __connman_wifi_vsie_list_struct(DBusMessageIter *iter);
+#endif
+
 enum connman_device_type __connman_rtnl_get_device_type(int index);
 unsigned int __connman_rtnl_update_interval_add(unsigned int interval);
 unsigned int __connman_rtnl_update_interval_remove(unsigned int interval);
index aff0fa9..acd68da 100755 (executable)
@@ -1077,6 +1077,73 @@ void connman_device_regdom_notify(struct connman_device *device,
        __connman_technology_notify_regdom_by_device(device, result, alpha2);
 }
 
+#if defined TIZEN_EXT
+static int device_specific_scan(enum connman_service_type type,
+                               struct connman_device *device,
+                               int scan_type, GSList *specific_scan_list)
+{
+       if (!device->driver || !device->driver->specific_scan)
+               return -EOPNOTSUPP;
+
+       if (!device->powered)
+               return -ENOLINK;
+
+       return device->driver->specific_scan(type, device, scan_type,
+                       specific_scan_list, NULL);
+}
+
+int __connman_device_request_specific_scan(enum connman_service_type type,
+                               int scan_type, GSList *specific_scan_list)
+{
+       bool success = false;
+       int last_err = -ENOSYS;
+       GSList *list;
+       int err;
+
+       switch (type) {
+       case CONNMAN_SERVICE_TYPE_UNKNOWN:
+       case CONNMAN_SERVICE_TYPE_SYSTEM:
+       case CONNMAN_SERVICE_TYPE_ETHERNET:
+       case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+       case CONNMAN_SERVICE_TYPE_CELLULAR:
+       case CONNMAN_SERVICE_TYPE_GPS:
+       case CONNMAN_SERVICE_TYPE_VPN:
+       case CONNMAN_SERVICE_TYPE_GADGET:
+               return -EOPNOTSUPP;
+       case CONNMAN_SERVICE_TYPE_WIFI:
+       case CONNMAN_SERVICE_TYPE_P2P:
+               break;
+       }
+
+       for (list = device_list; list; list = list->next) {
+               struct connman_device *device = list->data;
+               enum connman_service_type service_type =
+                       __connman_device_get_service_type(device);
+
+               if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
+                       if (type == CONNMAN_SERVICE_TYPE_P2P) {
+                               if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
+                                       continue;
+                       } else if (service_type != type)
+                               continue;
+               }
+
+               err = device_specific_scan(type, device, scan_type, specific_scan_list);
+               if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
+                       success = true;
+               } else {
+                       last_err = err;
+                       DBG("device %p err %d", device, err);
+               }
+       }
+
+       if (success)
+               return 0;
+
+       return last_err;
+}
+#endif
+
 int __connman_device_request_scan(enum connman_service_type type)
 {
        bool success = false;
index 32705e4..622ed59 100755 (executable)
 static bool connman_state_idle;
 static dbus_bool_t sessionmode;
 
+#if defined TIZEN_EXT
+static void append_wifi_vsies_structs(DBusMessageIter *iter, void *user_data)
+{
+       __connman_wifi_vsie_list_struct(iter);
+}
+
+static DBusMessage *get_wifi_vsies(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       DBusMessage *reply;
+
+       DBG("ConnMan, get_wifi_vsies API called");
+
+       reply = dbus_message_new_method_return(msg);
+       if (!reply)
+               return NULL;
+
+       __connman_dbus_append_objpath_dict_array(reply,
+                       append_wifi_vsies_structs, NULL);
+
+       return reply;
+}
+#endif
+
 static DBusMessage *get_properties(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
@@ -575,6 +599,11 @@ static const GDBusMethodTable manager_methods[] = {
        { GDBUS_METHOD("UnregisterPeerService",
                        GDBUS_ARGS({ "specification", "a{sv}" }), NULL,
                        unregister_peer_service) },
+#if defined TIZEN_EXT
+       { GDBUS_METHOD("GetVsies",
+                       NULL, GDBUS_ARGS({ "Vsie", "a(oa{sv})" }),
+                       get_wifi_vsies) },
+#endif
        { },
 };
 
index 8a6b906..546479c 100755 (executable)
@@ -101,6 +101,8 @@ struct connman_network {
                char *keymgmt_type;
                bool rsn_mode;
                int disconnect_reason;
+               void *wifi_vsie;
+               unsigned int wifi_vsie_len;
 #endif
        } wifi;
 
@@ -975,7 +977,9 @@ static void network_destruct(struct connman_network *network)
        g_free(network->wifi.private_key_passphrase);
        g_free(network->wifi.phase2_auth);
        g_free(network->wifi.pin_wps);
-
+#if defined TIZEN_EXT
+       g_free(network->wifi.wifi_vsie);
+#endif
        g_free(network->path);
        g_free(network->group);
        g_free(network->node);
@@ -2424,6 +2428,16 @@ int connman_network_set_blob(struct connman_network *network,
                        network->wifi.ssid_len = size;
                } else
                        network->wifi.ssid_len = 0;
+#if defined TIZEN_EXT
+       } else if (g_str_equal(key, "WiFi.Vsie")){
+               g_free(network->wifi.wifi_vsie);
+               network->wifi.wifi_vsie = g_try_malloc(size);
+               if (network->wifi.wifi_vsie) {
+                       memcpy(network->wifi.wifi_vsie, data, size);
+                       network->wifi.wifi_vsie_len = size;
+               } else
+                       network->wifi.wifi_vsie_len = 0;
+#endif
        } else {
                return -EINVAL;
        }
@@ -2450,6 +2464,17 @@ const void *connman_network_get_blob(struct connman_network *network,
                return network->wifi.ssid;
        }
 
+#if defined TIZEN_EXT
+       if (g_str_equal(key, "WiFi.Vsie")) {
+               if (size) {
+                       *size = network->wifi.wifi_vsie_len;
+                       DBG("network %p key %s size=%d", network, key, *size);
+               }
+
+               return network->wifi.wifi_vsie;
+       }
+#endif
+
        return NULL;
 }
 
index a5a7f39..4497b39 100755 (executable)
@@ -3381,6 +3381,53 @@ void __connman_service_list_struct(DBusMessageIter *iter)
        g_list_foreach(service_list, append_struct, iter);
 }
 
+#if defined TIZEN_EXT
+static void append_wifi_vsie_properties(DBusMessageIter *iter,
+                                       struct connman_service *service)
+{
+       DBusMessageIter dict;
+       const void *wifi_vsie;
+       unsigned int wifi_vsie_len;
+
+       connman_dbus_dict_open(iter, &dict);
+
+       wifi_vsie = connman_network_get_blob(service->network, "WiFi.Vsie", &wifi_vsie_len);
+
+       if(wifi_vsie_len > 0) {
+               DBG("ConnMan, service->path=%s vsie length=%d", service->path, wifi_vsie_len);
+       }
+
+       connman_dbus_dict_append_fixed_array(&dict, "Vsie", DBUS_TYPE_BYTE,
+                       &wifi_vsie, wifi_vsie_len);
+
+       connman_dbus_dict_close(iter, &dict);
+}
+
+void __connman_wifi_vsie_list_struct(DBusMessageIter *iter)
+{
+       GList *list;
+       DBusMessageIter entry;
+
+       DBG("ConnMan, __connman_wifi_vsie_list_struct API called");
+
+       for (list = service_list; list; list = list->next) {
+               struct connman_service *service = list->data;
+
+               if (!service->path ||
+                               service->type !=  CONNMAN_SERVICE_TYPE_WIFI ||
+                               service->network == NULL)
+                       continue;
+
+               dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT,
+                               NULL, &entry);
+               dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
+                               &service->path);
+               append_wifi_vsie_properties(&entry, service);
+               dbus_message_iter_close_container(iter, &entry);
+       }
+}
+#endif
+
 bool __connman_service_is_hidden(struct connman_service *service)
 {
        return service->hidden;
index c43fc32..fb39d34 100755 (executable)
@@ -1173,6 +1173,77 @@ static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
 }
 
 #if defined TIZEN_EXT
+static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+       struct connman_technology *technology = data;
+       GSList *specific_scan_list = NULL;
+       int scan_type = 0;
+       const char *name = NULL;
+       unsigned int freq = 0;
+       DBusMessageIter iter, dict;
+       int err;
+
+       DBG("technology %p request from %s", technology,
+                       dbus_message_get_sender(msg));
+
+       if (!dbus_message_iter_init(msg, &iter))
+               return __connman_error_invalid_arguments(msg);
+
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+               return __connman_error_invalid_arguments(msg);
+
+       dbus_message_iter_recurse(&iter, &dict);
+       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+               DBusMessageIter entry, value2;
+               const char *key;
+               int type;
+
+               dbus_message_iter_recurse(&dict, &entry);
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+                       return __connman_error_invalid_arguments(msg);
+
+               dbus_message_iter_get_basic(&entry, &key);
+               dbus_message_iter_next(&entry);
+
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+                       return __connman_error_invalid_arguments(msg);
+
+               dbus_message_iter_recurse(&entry, &value2);
+               type = dbus_message_iter_get_arg_type(&value2);
+               if (g_str_equal(key, "SSID")) {
+                       if (type != DBUS_TYPE_STRING)
+                               return __connman_error_invalid_arguments(msg);
+
+                       scan_type = 1; /* SSID based scan */
+                       dbus_message_iter_get_basic(&value2, &name);
+                       DBG("name %s", name);
+                       specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name));
+               } else if (g_str_equal(key, "Frequency")) {
+                       if (type != DBUS_TYPE_UINT16) {
+                               g_slist_free_full(specific_scan_list, g_free);
+                               return __connman_error_invalid_arguments(msg);
+                       }
+
+                       scan_type = 2; /* Frequency based scan */
+                       dbus_message_iter_get_basic(&value2, &freq);
+                       DBG("freq %d", freq);
+                       specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(freq));
+               }
+               dbus_message_iter_next(&dict);
+       }
+
+       dbus_message_ref(msg);
+       technology->scan_pending =
+               g_slist_prepend(technology->scan_pending, msg);
+
+       err = __connman_device_request_specific_scan(technology->type, scan_type, specific_scan_list);
+       if (err < 0)
+               reply_scan_pending(technology, err);
+
+       g_slist_free_full(specific_scan_list, g_free);
+       return NULL;
+}
+
 static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
 {
        DBusMessage *reply;
@@ -1216,6 +1287,8 @@ static const GDBusMethodTable technology_methods[] = {
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
                        NULL, set_property) },
        { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
+       { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }),
+                       NULL, specific_scan) },
 #if defined TIZEN_EXT
        { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
                        get_scan_state) },
@@ -1857,6 +1930,10 @@ int __connman_technology_add_rfkill(unsigned int index,
        g_hash_table_insert(rfkill_list, GINT_TO_POINTER(index), rfkill);
 
 done:
+#if defined TIZEN_EXT
+       /* Fix Svace Issue [WGID: 1348]. */
+       g_free(rfkill);
+#endif
        technology = technology_get(type);
        /* If there is no driver for this type, ignore it. */
        if (!technology)