Fixed: Coding rule issues.
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-manager.c
index c869fc0..02f0375 100644 (file)
 #include <glib-object.h>
 
 #include <wifi-direct.h>
-#include <wifi-direct-internal.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-oem.h"
 #include "wifi-direct-session.h"
 #include "wifi-direct-group.h"
 #include "wifi-direct-peer.h"
 #include "wifi-direct-state.h"
-#include "wifi-direct-client.h"
 #include "wifi-direct-event.h"
 #include "wifi-direct-util.h"
+#include "wifi-direct-log.h"
+#include "wifi-direct-error.h"
+#include "wifi-direct-iface.h"
+#include "wifi-direct-dbus.h"
+
+#if defined TIZEN_ENABLE_PRD
+#include "wifi-direct-prd.h"
+#endif /* TIZEN_ENABLE_PRD */
 
 wfd_manager_s *g_manager;
 
@@ -55,6 +62,9 @@ wfd_manager_s *wfd_get_manager()
        return g_manager;
 }
 
+#ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
+/* Stop wfd-manager services, If no client
+   exists and state is deactivated. */
 static gboolean _wfd_exit_timeout_cb(void *user_data)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -73,14 +83,87 @@ static gboolean _wfd_exit_timeout_cb(void *user_data)
        if (manager->state == WIFI_DIRECT_STATE_DEACTIVATED) {
                WDS_LOGD("Terminate Wi-Fi Direct Manager");
                g_main_quit(manager->main_loop);
+               manager->exit_timer = 0;
+               WDS_LOGD("Stop exit timer. State [%d]", manager->state);
+               __WDS_LOG_FUNC_EXIT__;
+               return FALSE;
        }
-       manager->exit_timer = 0;
-       WDS_LOGD( "Stop exit timer. State [%d]", manager->state);
 
        __WDS_LOG_FUNC_EXIT__;
-       return FALSE;
+       return TRUE;
+}
+
+void wfd_manager_free_active_client_list(void)
+{
+       GSList *list;
+       wfd_manager_s *manager = wfd_get_manager();
+
+       if (!manager || !manager->client_list)
+               return;
+
+       for (list = manager->client_list; list; list = list->next)
+               g_free(list->data);
+
+       g_slist_free(manager->client_list);
+}
+
+void wfd_manager_add_active_client(const char *client_id)
+{
+       GSList *list = NULL;
+       gboolean if_exists = FALSE;
+       gchar *str = NULL;
+       wfd_manager_s *manager = wfd_get_manager();
+       if (!manager || !client_id)
+               return;
+
+       for (list = manager->client_list; list; list = list->next) {
+               str = list->data;
+               if (str && !g_strcmp0(client_id, str)) {
+                       if_exists = TRUE;
+                       break;
+               }
+       }
+
+       // If not exists in list, add the sender
+       if (if_exists == FALSE) {
+               manager->client_list = g_slist_prepend(manager->client_list,
+                                        g_strdup(client_id));
+               manager->client_count++;
+               WDS_LOGD("Added DBus sender id[%s] count[%d]", client_id,
+                                        manager->client_count);
+       }
 }
 
+void wfd_manager_remove_active_client(const gchar *name,
+                                     const char *old_owner,
+                                     const char *new_owner)
+{
+       GSList *list = NULL;
+       gchar *str = NULL;
+       wfd_manager_s *manager = wfd_get_manager();
+
+       if (!manager)
+               return;
+
+       if (!g_strcmp0(new_owner, "")) {
+               if (manager->client_count > 0) {
+                       for (list = manager->client_list; list; list = list->next) {
+                               str = list->data;
+                               if (str && !g_strcmp0(old_owner, str)) {
+                                       manager->client_list =
+                                                g_slist_remove(manager->client_list, str);
+                                       g_free(str);
+                                       manager->client_count--;
+                                       WDS_LOGD("Removed name[%s] old[%s] new[%s] count[%d]",
+                                                name, old_owner, new_owner, manager->client_count);
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+#endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
+
 static int _wfd_local_init_device(wfd_manager_s *manager)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -93,7 +176,7 @@ static int _wfd_local_init_device(wfd_manager_s *manager)
        }
 
        errno = 0;
-       local = (wfd_device_s*) calloc(1, sizeof(wfd_device_s));
+       local = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
        if (!local) {
                WDS_LOGE("Failed to allocate memory for local device [%s]", strerror(errno));
                return -1;
@@ -102,24 +185,27 @@ static int _wfd_local_init_device(wfd_manager_s *manager)
        res = wfd_util_get_phone_name(local->dev_name);
        if (res < 0) {
                WDS_LOGE("Failed to get phone name of local device. Use default device name");
-               strncpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN);
-               local->dev_name[DEV_NAME_LEN] = '\0';
+               g_strlcpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN + 1);
        }
        WDS_LOGD("Local Device name [%s]", local->dev_name);
        wfd_util_set_dev_name_notification();
 
        res = wfd_util_get_local_dev_mac(local->dev_addr);
-       if (res < 0) {
+       if (res < 0)
                WDS_LOGE("Failed to get local device MAC address");
-       }
 
        memcpy(local->intf_addr, local->dev_addr, MACADDR_LEN);
        local->intf_addr[4] ^= 0x80;
-       WDS_LOGD("Local Interface MAC address [" MACSTR "]", MAC2STR(local->intf_addr));
+       WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
+                                       MAC2SECSTR(local->intf_addr));
 
        local->config_methods = WFD_WPS_MODE_PBC | WFD_WPS_MODE_DISPLAY | WFD_WPS_MODE_KEYPAD;
        local->wps_mode = WFD_WPS_MODE_PBC;
-       // TODO: initialize other local device datas
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       local->services = NULL;
+       local->service_count = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+       /* TODO: initialize other local device datas */
        manager->local = local;
 
        __WDS_LOG_FUNC_EXIT__;
@@ -137,8 +223,8 @@ static int _wfd_local_deinit_device(wfd_manager_s *manager)
 
        wfd_util_unset_dev_name_notification();
 
-       if (manager->local)
-               free(manager->local);
+       /* TODO: free member of local device */
+       g_free(manager->local);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -147,12 +233,21 @@ static int _wfd_local_deinit_device(wfd_manager_s *manager)
 int wfd_local_reset_data(wfd_manager_s *manager)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s *local = manager->local;
+       wfd_device_s *local = NULL;
+
+       if (!manager) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
 
+       local = manager->local;
        /* init local device data */
        local->dev_role = WFD_DEV_ROLE_NONE;
        local->wps_mode = WFD_WPS_MODE_PBC;
        memset(local->go_dev_addr, 0x0, MACADDR_LEN);
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       memset(&(local->display), 0x0, sizeof(wfd_display_s));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
        memset(local->ip_addr, 0x0, IPADDR_LEN);
 
        __WDS_LOG_FUNC_EXIT__;
@@ -170,8 +265,7 @@ int wfd_local_get_dev_name(char *dev_name)
                return -1;
        }
 
-       strncpy(dev_name, local->dev_name, DEV_NAME_LEN);
-       dev_name[DEV_NAME_LEN-1] = '\0';
+       g_strlcpy(dev_name, local->dev_name, DEV_NAME_LEN + 1);
        WDS_LOGD("Local device name [%s]", dev_name);
 
        __WDS_LOG_FUNC_EXIT__;
@@ -189,27 +283,20 @@ int wfd_local_set_dev_name(char *dev_name)
                return -1;
        }
 
-       strncpy(local->dev_name, dev_name, DEV_NAME_LEN);
-       local->dev_name[DEV_NAME_LEN-1] = '\0';
+       g_strlcpy(local->dev_name, dev_name, DEV_NAME_LEN + 1);
 
        if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED) {
                wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
-
-               wfd_oem_scan_param_s param;
-               param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
-               param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
-               param.scan_time = 5;
-               param.refresh = TRUE;
-               wfd_oem_start_scan(g_manager->oem_ops, &param);
-               g_manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
-               WDS_LOGD("Device name changed. Active scan started");
+               WDS_LOGD("Device name changed.");
+       } else {
+               WDS_LOGE("Device name can't changed: state is %d", g_manager->state);
        }
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int wfd_local_get_dev_mac(unsigned char *dev_mac)
+int wfd_local_get_dev_mac(char *dev_mac)
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_device_s *local = g_manager->local;
@@ -220,13 +307,14 @@ int wfd_local_get_dev_mac(unsigned char *dev_mac)
                return -1;
        }
 
-       memcpy(dev_mac, local->dev_addr, MACADDR_LEN);
-       WDS_LOGD("Local device MAC address [" MACSTR "]", MAC2STR(dev_mac));
+       g_snprintf(dev_mac, MACSTR_LEN, MACSTR, MAC2STR(local->dev_addr));
+       WDS_SECLOGD("Local device MAC address [%s]", dev_mac);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
+#if 0
 int wfd_local_get_intf_mac(unsigned char *intf_mac)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -238,12 +326,13 @@ int wfd_local_get_intf_mac(unsigned char *intf_mac)
                return -1;
        }
 
-       memcpy(intf_mac, local->intf_addr, MACADDR_LEN);
-       WDS_LOGD("Local interface MAC address [" MACSTR "]", MAC2STR(intf_mac));
+       g_snprintf(intf_mac, MACSTR_LEN, MACSTR, MAC2STR(local->intf_addr));
+       WDS_SECLOGD("Local interface MAC address [%s]", intf_mac);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif
 
 int wfd_local_get_ip_addr(char *ip_str)
 {
@@ -257,7 +346,7 @@ int wfd_local_get_ip_addr(char *ip_str)
        }
 
        snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(local->ip_addr));
-       WDS_LOGD("Local IP address [" IPSTR "]", IP2STR(local->ip_addr));
+       WDS_SECLOGD("Local IP address [" IPSECSTR "]", IP2SECSTR(local->ip_addr));
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -299,6 +388,7 @@ int wfd_local_get_wps_mode(int *wps_mode)
        return 0;
 }
 
+#if 0
 int wfd_local_set_wps_mode(int wps_mode)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -316,6 +406,7 @@ int wfd_local_set_wps_mode(int wps_mode)
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif
 
 int wfd_manager_get_go_intent(int *go_intent)
 {
@@ -394,7 +485,7 @@ int wfd_manager_get_autoconnection(int *autoconnection)
        }
 
        *autoconnection = g_manager->autoconnection;
-       WDS_LOGD("Local autoconnection [%s]", *autoconnection ? "TRUE":"FALSE");
+       WDS_LOGD("Local autoconnection [%s]", *autoconnection ? "TRUE" : "FALSE");
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -473,9 +564,25 @@ int wfd_manager_local_config_set(wfd_manager_s *manager)
 
        local->wps_mode = WFD_WPS_MODE_PBC;
        WDS_LOGD("Device name set as %s", local->dev_name);
-       wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
-       wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
-       wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
+       res = wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
+       if (res < 0) {
+               WDS_LOGE("Failed to set device name");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       local->pri_dev_type = DEFAULT_PRIMARY_DEVICE_TYPE;
+       local->sec_dev_type = DEFAULT_SECONDARY_DEVICE_TYPE;
+       res = wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
+       if (res < 0) {
+               WDS_LOGE("Failed to set device type");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       res = wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
+       if (res < 0) {
+               WDS_LOGE("Failed to set go intent");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
 
        return WIFI_DIRECT_ERROR_NONE;
 }
@@ -483,6 +590,7 @@ int wfd_manager_local_config_set(wfd_manager_s *manager)
 int wfd_manager_activate(wfd_manager_s *manager)
 {
        __WDS_LOG_FUNC_ENTER__;
+       int prev_state = 0;
        int res = 0;
 
        if (!manager) {
@@ -495,19 +603,60 @@ int wfd_manager_activate(wfd_manager_s *manager)
                return 1;
        }
 
-       wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
+       if (manager->state == WIFI_DIRECT_STATE_ACTIVATING) {
+               WDS_LOGE("In progress");
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       res = wfd_util_wifi_direct_activatable();
+       if (res < 0)
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
 
-       res = wfd_oem_activate(manager->oem_ops);
+       wfd_state_get(manager, &prev_state);
+       wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
+#if defined(TIZEN_WLAN_CONCURRENT_ENABLE)
+       res = wfd_util_check_wifi_state();
+       if (res < 0) {
+               WDS_LOGE("Failed to get wifi state");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       } else if (res == 0) {
+#endif /* TIZEN_WLAN_CONCURRENT_ENABLE */
+       res = wfd_oem_activate(manager->oem_ops, 0);
        if (res < 0) {
                WDS_LOGE("Failed to activate");
-               wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
+               wfd_state_set(manager, prev_state);
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
+#if defined(TIZEN_WLAN_CONCURRENT_ENABLE)
+       } else {
+               res = wfd_oem_activate(manager->oem_ops, res);
+               if (res < 0) {
+                       WDS_LOGE("Failed to activate");
+                       wfd_state_set(manager, prev_state);
+                       return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               }
+       }
+#endif /* TIZEN_WLAN_CONCURRENT_ENABLE */
        WDS_LOGE("Succeeded to activate");
 
        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
 
+       wfd_manager_local_config_set(manager);
+       wfd_util_set_country();
+#ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
+       wfd_util_start_wifi_direct_popup();
+#endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
+
+       res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
+       if (res < 0)
+               WDS_LOGE("Failed to get local device MAC address");
+
+       memcpy(manager->local->intf_addr, manager->local->dev_addr, MACADDR_LEN);
+       manager->local->intf_addr[4] ^= 0x80;
+       WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
+                                       MAC2SECSTR(manager->local->intf_addr));
+
        __WDS_LOG_FUNC_EXIT__;
        return WIFI_DIRECT_ERROR_NONE;
 }
@@ -515,27 +664,56 @@ int wfd_manager_activate(wfd_manager_s *manager)
 int wfd_manager_deactivate(wfd_manager_s *manager)
 {
        __WDS_LOG_FUNC_ENTER__;
+       int prev_state = 0;
        int res = 0;
+       wfd_group_s *group = NULL;
 
        if (!manager) {
                WDS_LOGE("Invalid parameter");
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
-       if (manager->state < WIFI_DIRECT_STATE_ACTIVATING) {
-               WDS_LOGE("Already deactivated");
-               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
-       }
-
+       wfd_state_get(manager, &prev_state);
        wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
 
-       res = wfd_oem_deactivate(manager->oem_ops);
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       res = wfd_oem_miracast_init(manager->oem_ops, false);
+       if (res < 0)
+               WDS_LOGE("Failed to initialize miracast");
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       group = (wfd_group_s*) manager->group;
+       if (group && group->pending == FALSE) {
+               res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
+               if (res < 0)
+                       WDS_LOGE("Failed to destroy group before deactivation");
+       }
+
+#if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
+       res = wfd_util_check_wifi_state();
        if (res < 0) {
-               WDS_LOGE("Failed to deactivate");
-               // TODO: check state setting is correct
-               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+               WDS_LOGE("Failed to get wifi state");
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       } else if (res == 0) {
+#endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_PROFILE_MOBILE */
+               res = wfd_oem_deactivate(manager->oem_ops, 0);
+               if (res < 0) {
+                       WDS_LOGE("Failed to deactivate");
+                       wfd_state_set(manager, prev_state);
+                       return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               }
+#if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
+       } else {
+               /* FIXME: We should do something to stop p2p feature of Driver */
+               res = wfd_oem_deactivate(manager->oem_ops, res);
+               if (res < 0) {
+                       WDS_LOGE("Failed to deactivate");
+                       wfd_state_set(manager, prev_state);
+                       return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               }
+               WDS_LOGE("Do not need to deactivate Wi-Fi");
        }
+#endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_PROFILE_MOBILE */
        WDS_LOGE("Succeeded to deactivate");
 
        wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
@@ -543,6 +721,14 @@ int wfd_manager_deactivate(wfd_manager_s *manager)
 
        manager->req_wps_mode = WFD_WPS_MODE_PBC;
 
+       wfd_destroy_group(manager);
+       wfd_destroy_session(manager);
+       wfd_peer_clear_all(manager);
+       wfd_local_reset_data(manager);
+
+#ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
+       wfd_util_stop_wifi_direct_popup();
+#endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
        __WDS_LOG_FUNC_EXIT__;
        return WIFI_DIRECT_ERROR_NONE;
 }
@@ -558,9 +744,23 @@ int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
+       if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
+                       manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
+                       manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       wfd_group_s *group = (wfd_group_s*) manager->group;
+       if (group && group->member_count >= manager->max_station) {
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_TOO_MANY_CLIENT;
+       }
+
        session = (wfd_session_s*) manager->session;
-       if (session && !session->invitation) {
-               WDS_LOGE("Session already exist or not an invitaion session");
+       if (session && session->type != SESSION_TYPE_INVITE) {
+               WDS_LOGE("Session already exist and it's not an invitation session");
+               __WDS_LOG_FUNC_EXIT__;
                return WIFI_DIRECT_ERROR_NOT_PERMITTED;
        }
 
@@ -569,25 +769,126 @@ int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
                                        manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
                if (!session) {
                        WDS_LOGE("Failed to create new session");
+                       __WDS_LOG_FUNC_EXIT__;
                        return WIFI_DIRECT_ERROR_OPERATION_FAILED;
                }
        }
 
-       if (manager->local->dev_role == WFD_DEV_ROLE_GO && !session->invitation) {
-               session->invitation = 1;
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
+                       session->type != SESSION_TYPE_INVITE) {
+               session->type = SESSION_TYPE_INVITE;
                res = wfd_session_invite(session);
        } else {
-               /* joining to group or starting connection with PD */
-               /* In case of invitation session PD should be started
-                * peer->dev_role == WFD_DEV_ROLE_GO
-                * session->direction == SESSION_DIRECTION_INCOMING
-                * session->invitation == TRUE;
-                */
                res = wfd_session_start(session);
        }
        if (res < 0) {
                WDS_LOGE("Failed to start session");
                wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+       wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+
+#if defined(TIZEN_FEATURE_ASP)
+int wfd_manager_asp_connect_session(wfd_manager_s *manager, void *params)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_session_s *session = NULL;
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       int req_wps_mode = WFD_WPS_MODE_P2PS;
+       int res = 0;
+
+       prov_params = (wfd_oem_asp_prov_s *)params;
+       if (!manager || !prov_params) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       session = (wfd_session_s*) manager->session;
+       if (session) {
+               WDS_LOGE("Session already exists");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
+               req_wps_mode = WFD_WPS_MODE_DISPLAY;
+       else if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
+               req_wps_mode = WFD_WPS_MODE_KEYPAD;
+       else
+               req_wps_mode = WFD_WPS_MODE_P2PS;
+
+       session = wfd_create_session(manager, prov_params->service_mac,
+                       req_wps_mode, SESSION_DIRECTION_OUTGOING);
+       if (!session) {
+               WDS_LOGE("Failed to create new session");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       res = wfd_session_asp_session_start(session, prov_params);
+       if (res < 0) {
+               WDS_LOGE("Failed to start session");
+               wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+
+int wfd_manager_asp_confirm_session(wfd_manager_s *manager, void *params, int confirmed)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_session_s *session = NULL;
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       int res = 0;
+
+       prov_params = (wfd_oem_asp_prov_s *)params;
+       if (!manager || !prov_params) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       session = (wfd_session_s*) manager->session;
+       if (!session) {
+               WDS_LOGE("Session not exists");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+
+       WDS_LOGD("confirm session [%u] with peer [" MACSTR "]", prov_params->session_id,
+                       MAC2STR(prov_params->session_mac));
+
+       WDS_LOGD("created session [%u] with peer [" MACSTR "]", session->session_id,
+                       MAC2STR(session->session_mac));
+
+       if (session->session_id != prov_params->session_id ||
+                       memcmp(&(session->session_mac), prov_params->session_mac, MACADDR_LEN) != 0) {
+               WDS_LOGE("Session MAC or ID not matched");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       if (confirmed)
+               prov_params->status = 12;
+       else
+               prov_params->status = 11;
+
+       res = wfd_oem_asp_prov_disc_req(manager->oem_ops, prov_params);
+       if (res < 0) {
+               WDS_LOGE("Failed to start session");
+               wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
        wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
@@ -595,6 +896,7 @@ int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
        __WDS_LOG_FUNC_EXIT__;
        return WIFI_DIRECT_ERROR_NONE;
 }
+#endif
 
 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
 {
@@ -620,32 +922,48 @@ int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_ad
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
-       // TODO: check peer_addr with session's peer_addr
+       if (memcmp(session->peer->dev_addr, peer_addr, MACADDR_LEN) != 0) {
+               WDS_LOGE("Peer and ongoing session peer are different");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
-               /* Peer want to join my group(Peer sent PD) */
                WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
                res = wfd_session_wps(session);
        } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
-               /* FIX ME: When Enter PIN or Display event comes up from supplicant
-                * manager send Connection WPS Req event to client.
-                * So, application use accept_connection API.
-                * This is odd situation. We need new client event such as WPS_KEYPAD/WPS_DISPLAY for application.
-                * We can correct alien code below with new client event */
-               if (session->direction == SESSION_DIRECTION_OUTGOING) {
-                       WDS_LOGD("Peer device is GO, WPS_Enrollee will be started");
-                       wfd_session_wps(manager->session);
+               WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");
+               if (session->type == SESSION_TYPE_INVITE) {
+                       if (session->state == SESSION_STATE_CREATED) {
+                               WDS_LOGD("Invitation session. PD will be started");
+                               res = wfd_session_start(session);
+                       } else {
+                               WDS_LOGD("Invitation session. Join will be started");
+                               res = wfd_session_join(session);
+                       }
                } else {
-                       WDS_LOGD("Peer device is GO, so Prov_Disc will be started");
-                       wfd_session_start(session);
+                       if (manager->autoconnection && (manager->auto_pin[0] != 0))
+                               g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
+
+                       WDS_LOGD("Peer device is GO, so WPS will be started");
+                       res = wfd_session_connect(session);
                }
        } else {
-               /* Prov_disc_req received. GO Negotiation will be started */
-               WDS_LOGD("My device is Device, so Negotiation will be started");
-               res = wfd_session_connect(session);
+               /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
+               /* Otherwise, GO Nego is sometimes failed. */
+               if (manager->autoconnection == FALSE) {
+                       WDS_LOGD("My device is Device, so Negotiation will be started");
+                       res = wfd_session_connect(session);
+               }
        }
        if (res < 0) {
                WDS_LOGE("Failed to start session");
+               if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+               } else {
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+               }
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
        wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
@@ -655,119 +973,442 @@ int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_ad
 }
 
 
-int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
+int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
-       GList *temp = NULL;
-       wfd_device_s *peer = NULL;
-       wfd_discovery_entry_s *peers = NULL;
-       int peer_count = 0;
-       int count = 0;
+       wfd_group_s *group = NULL;
        int res = 0;
 
-       if (!manager || !peers_data) {
+       if (!manager || !peer_addr) {
                WDS_LOGE("Invalid parameter");
-               return -1;
+               return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
        }
 
-       unsigned long time = 0;
-       struct timeval tval;
-       gettimeofday(&tval, NULL);
-       time = tval.tv_sec;
-       WDS_LOGI("Current time [%ld]", time);
-
-       peer_count = manager->peer_count;
-       if (peer_count < 0)
-               return -1;
-       else if (peer_count == 0)
-               return 0;
-
-       errno = 0;
-       peers = (wfd_discovery_entry_s*) calloc(peer_count, sizeof(wfd_discovery_entry_s));
-       if (!peers) {
-               WDS_LOGF("Failed to allocate memory for peer data. [%s]", strerror(errno));
-               return -1;
+       if (!manager->session && manager->state != WIFI_DIRECT_STATE_CONNECTING) {
+               WDS_LOGE("It's not CONNECTING state");
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
        }
 
-       temp = g_list_first(manager->peers);
-       while (temp && count < peer_count) {
-               peer = temp->data;
-               if (!peer)
-                       goto next;
-               if (peer->time + 4 < time) {
-                       WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
-                       res = wfd_update_peer(manager, peer);
-                       if (res < 0) {
-                               WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
-                               temp = g_list_next(temp);
-                               manager->peers = g_list_remove(manager->peers, peer);
-                               manager->peer_count--;
-                               if (peer->display)
-                                       free(peer->display);
-                               free(peer);
-                               peer = NULL;
-                               continue;
-                       }
-               }
+       res = wfd_session_cancel(manager->session, peer_addr);
+       if (res < 0) {
+               WDS_LOGE("Failed to cancel session");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
 
-               strncpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN);
-               peers[count].device_name[DEV_NAME_LEN] = '\0';
-               memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
-               memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
-               peers[count].channel = peer->channel;
-               peers[count].services = 0;
-               peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
-               peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
-               peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
-               peers[count].wps_device_pwd_id = 0;
-               peers[count].wps_cfg_methods = peer->config_methods;
-               peers[count].category = peer->pri_dev_type;
-               peers[count].subcategory = peer->sec_dev_type;
+       group = (wfd_group_s*) manager->group;
+       if (group)
+               wfd_group_remove_member(group, peer_addr);
 
-               count++;
-               WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
-next:
-               temp = g_list_next(temp);
-               peer = NULL;
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+               if (group && group->member_count)
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+       } else {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
        }
-       WDS_LOGD("%d peers converted", count);
-       WDS_LOGD("Final peer count is %d", manager->peer_count);
-
-       *peers_data = peers;
 
        __WDS_LOG_FUNC_EXIT__;
-       return count;
+       return WIFI_DIRECT_ERROR_NONE;
 }
 
-int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
+
+int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_connected_peer_info_s *peers = NULL;
-       wfd_group_s *group = NULL;
-       wfd_device_s *peer = NULL;
-       GList *temp = NULL;
-       int peer_count = 0;
-       int count = 0;
+       wfd_session_s *session = NULL;
+       int res = 0;
 
-       if (!manager || !peers_data) {
+       if (!manager || !peer_addr) {
                WDS_LOGE("Invalid parameter");
-               return -1;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
-       group = manager->group;
-       if (!group) {
-               WDS_LOGE("Group not exist");
-               return -1;
+       session = (wfd_session_s*) manager->session;
+       if (!session) {
+               WDS_LOGE("Session not found");
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
        }
 
-       peer_count = group->member_count;
+       if (manager->state != WIFI_DIRECT_STATE_CONNECTING) {
+               WDS_LOGE("It's not permitted with this state [%d]", manager->state);
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       if (session->direction != SESSION_DIRECTION_INCOMING) {
+               WDS_LOGE("Only incomming session can be rejected");
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       res = wfd_session_reject(session, peer_addr);
+       if (res < 0) {
+               WDS_LOGE("Failed to reject connection");
+               /* TODO: check whether set state and break */
+       }
+       wfd_destroy_session(manager);
+
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+       } else {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+
+
+int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_group_s *group = NULL;
+       wfd_device_s *peer = NULL;
+       int res = 0;
+
+       if (!manager) {
+               WDS_LOGE("Invalid parameter");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       if (!peer_addr) {
+               WDS_LOGE("Invalid parameter");
+               return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+       }
+
+       group = (wfd_group_s*) manager->group;
+       if (!group) {
+               WDS_LOGE("Group not found");
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       peer = wfd_group_find_member_by_addr(group, peer_addr);
+       if (!peer) {
+               WDS_LOGE("Connected peer not found");
+               return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+       }
+
+       wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
+
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               if (peer->is_p2p)
+                       res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr, 0);
+               else
+                       res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr, 1);
+       } else {
+               res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
+       }
+
+       if (res < 0) {
+               WDS_LOGE("Failed to disconnect peer");
+               res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               goto failed;
+       }
+       WDS_LOGE("Succeeded to disconnect peer");
+
+       wfd_group_remove_member(group, peer_addr);
+       if (!group->member_count) {
+               wfd_oem_destroy_group(manager->oem_ops, group->ifname);
+               wfd_destroy_group(manager);
+       }
+
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+       } else {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+
+failed:
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+       } else {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int wfd_manager_disconnect_all(wfd_manager_s *manager)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_group_s *group = NULL;
+       int res = 0;
+
+       if (!manager) {
+               WDS_LOGE("Invalid parameter");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       group = (wfd_group_s*) manager->group;
+       if (!group) {
+               WDS_LOGE("Group not found");
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
+
+       res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
+       if (res < 0) {
+               WDS_LOGE("Failed to destroy group");
+               res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               goto failed;
+       }
+       WDS_LOGE("Succeeded to disconnect all peer");
+
+       wfd_destroy_group(manager);
+
+       wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+
+failed:
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+       } else {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_device_s *peer_dev = NULL;
+       wfd_discovery_entry_s *peer_info;
+       wfd_oem_device_s *oem_dev = NULL;
+       int res = 0;
+
+       if (!manager || !addr) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       unsigned long time = 0;
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+       wfd_util_get_current_time(&time);
+#else
+       struct timeval tval;
+       gettimeofday(&tval, NULL);
+       time = tval.tv_sec;
+#endif
+       WDS_LOGI("Current time [%ld]", time);
+
+       res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
+       if (res < 0 || !oem_dev) {
+               WDS_LOGE("Failed to get peer information");
+               return -1;
+       }
+
+       peer_dev = wfd_peer_find_by_addr(manager, addr);
+       if (!peer_dev) {
+               peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
+               if (!peer_dev) {
+                       WDS_LOGE("Failed to allocate memory for peer device. [%s]", strerror(errno));
+                       free(oem_dev);
+                       return -1;
+               }
+               memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
+               manager->peers = g_list_prepend(manager->peers, peer_dev);
+               manager->peer_count++;
+               peer_dev->time = time;
+               WDS_LOGD("peer_count[%d]", manager->peer_count);
+       } else {
+               if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
+                       WDS_LOGE("Too old age to update peer");
+                       free(oem_dev);
+                       return -1;
+               }
+       }
+
+       g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
+       memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
+       memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
+       peer_dev->dev_role = oem_dev->dev_role;
+       peer_dev->config_methods = oem_dev->config_methods;
+       peer_dev->pri_dev_type = oem_dev->pri_dev_type;
+       peer_dev->sec_dev_type = oem_dev->sec_dev_type;
+       peer_dev->dev_flags = oem_dev->dev_flags;
+       peer_dev->group_flags = oem_dev->group_flags;
+       peer_dev->wps_mode =  oem_dev->wps_mode;
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       peer_dev->time = time;
+       peer_dev->channel = oem_dev->channel;
+
+       free(oem_dev);
+
+       peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
+       if (!(peer_info)) {
+               WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
+               return -1;
+       }
+
+       g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
+       memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
+       memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
+       peer_info->channel = peer_dev->channel;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       peer_info->services = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+       peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
+       peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
+       peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
+       peer_info->wps_device_pwd_id = 0;
+       peer_info->wps_cfg_methods = peer_dev->config_methods;
+       peer_info->category = peer_dev->pri_dev_type;
+       peer_info->subcategory = peer_dev->sec_dev_type;
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       if (peer_dev->display.availability && peer_dev->display.port)
+               peer_info->is_wfd_device = 1;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       *peer = peer_info;
+
+       __WDS_LOG_FUNC_EXIT__;
+       return res;
+}
+
+
+int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       GList *temp = NULL;
+       wfd_device_s *peer = NULL;
+       wfd_discovery_entry_s *peers = NULL;
+       int peer_count = 0;
+       int count = 0;
+       int res = 0;
+
+       if (!manager || !peers_data) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       unsigned long time = 0;
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+       wfd_util_get_current_time(&time);
+#else
+       struct timeval tval;
+       gettimeofday(&tval, NULL);
+       time = tval.tv_sec;
+#endif
+       WDS_LOGI("Current time [%ld]", time);
+
+       peer_count = manager->peer_count;
+       WDS_LOGI("peer count [%ld]", peer_count);
+       if (peer_count < 0)
+               return -1;
+       else if (peer_count == 0)
+               return 0;
+
+       errno = 0;
+       peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
+       if (!peers) {
+               WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
+               return -1;
+       }
+
+       temp = g_list_first(manager->peers);
+       while (temp && count < peer_count) {
+               peer = temp->data;
+               if (!peer)
+                       goto next;
+               if (peer->time + 8 < time) {
+                       WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
+                       res = wfd_update_peer(manager, peer);
+                       if (res < 0) {
+                               WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
+                               temp = g_list_next(temp);
+                               manager->peers = g_list_remove(manager->peers, peer);
+                               manager->peer_count--;
+                               g_free(peer);
+                               peer = NULL;
+                               continue;
+                       }
+               }
+
+               g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
+               memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
+               memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
+               peers[count].channel = peer->channel;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+               peers[count].services = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+               peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
+               peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
+               peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
+               peers[count].wps_device_pwd_id = 0;
+               peers[count].wps_cfg_methods = peer->config_methods;
+               peers[count].category = peer->pri_dev_type;
+               peers[count].subcategory = peer->sec_dev_type;
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+               if (peer->display.availability && peer->display.port)
+                       peers[count].is_wfd_device = 1;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+               count++;
+               WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
+next:
+               temp = g_list_next(temp);
+               peer = NULL;
+       }
+       WDS_LOGD("%d peers converted", count);
+       WDS_LOGD("Final peer count is %d", manager->peer_count);
+
+       *peers_data = peers;
+
+       __WDS_LOG_FUNC_EXIT__;
+       return count;
+}
+
+int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_connected_peer_info_s *peers = NULL;
+       wfd_group_s *group = NULL;
+       wfd_device_s *peer = NULL;
+       GList *temp = NULL;
+       int peer_count = 0;
+       int count = 0;
+
+       if (!manager || !peers_data) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       group = manager->group;
+       if (!group) {
+               WDS_LOGE("Group not exist");
+               return -1;
+       }
+
+       peer_count = group->member_count;
        if (peer_count == 0) {
                WDS_LOGD("Member not exist");
                return 0;
        }
 
        errno = 0;
-       peers = (wfd_connected_peer_info_s*) calloc(peer_count, sizeof(wfd_connected_peer_info_s));
+       peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
        if (!peers) {
                WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", strerror(errno));
                return -1;
@@ -777,16 +1418,24 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
        while (temp && count < group->member_count) {
                peer = temp->data;
                {
-                       strncpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN);
-                       peers[count].device_name[DEV_NAME_LEN] = '\0';
+                       g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
                        memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
                        memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
                        memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
                        peers[count].category = peer->pri_dev_type;
                        peers[count].subcategory = peer->sec_dev_type;
                        peers[count].channel = peer->channel;
-                       peers[count].is_p2p = 1;
+                       peers[count].is_p2p = peer->is_p2p;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
                        peers[count].services = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+                       if (peer->display.availability && peer->display.port)
+                               peers[count].is_wfd_device = 1;
+
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
                        WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
                        count++;
                }
@@ -801,42 +1450,43 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
        return count;
 }
 
-wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
+#ifdef TIZEN_FEATURE_ASP
+wfd_device_s *wfd_manager_get_connected_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_device_s *peer = NULL;
 
-       if (!manager || !peer_addr) {
+       if (peer_addr == NULL) {
                WDS_LOGE("Invalid parameter");
-               return NULL;
+               __WDS_LOG_FUNC_EXIT__;
+               return peer;
        }
 
-       peer = wfd_group_find_peer_by_dev_addr(manager->group, peer_addr);
+       if (manager->group)
+               peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
 
        __WDS_LOG_FUNC_EXIT__;
        return peer;
 }
+#endif /* TIZEN_FEATURE_ASP */
 
-wfd_device_s *wfd_manager_get_current_peer(wfd_manager_s *manager)
+#if 0
+wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_session_s *session = NULL;
+       wfd_device_s *peer = NULL;
 
-       if (!manager) {
+       if (!manager || !peer_addr) {
                WDS_LOGE("Invalid parameter");
-               __WDS_LOG_FUNC_EXIT__;
                return NULL;
        }
 
-       session = manager->session;
-       if (session && session->peer) {
-               __WDS_LOG_FUNC_EXIT__;
-               return session->peer;
-       }
+       peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
 
        __WDS_LOG_FUNC_EXIT__;
-       return NULL;
+       return peer;
 }
+#endif
 
 int wfd_manager_get_goup_ifname(char **ifname)
 {
@@ -860,13 +1510,187 @@ int wfd_manager_get_goup_ifname(char **ifname)
        return 0;
 }
 
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int wfd_manager_set_display_device(int type, int port, int hdcp)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_device_s * device = g_manager->local;
+       wfd_oem_display_s display;
+       int res = 0;
+
+       if (!device) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       memset(&display, 0x0, sizeof(wfd_oem_display_s));
+
+       display.type = type;
+       display.port = port;
+       display.hdcp_support = hdcp;
+
+       display.availability = device->display.availability;
+       display.max_tput = device->display.max_tput;
+
+       res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
+       if (res < 0) {
+               WDS_LOGE("Failed to set wifi display");
+               return -1;
+       }
+
+       device->display.type = type;
+       device->display.port = port;
+       device->display.hdcp_support = hdcp;
+
+       __WDS_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int wfd_manager_set_session_availability(int availability)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_device_s * device = g_manager->local;
+       wfd_oem_display_s display;
+       int res = 0;
+
+       if (!device) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       memset(&display, 0x0, sizeof(wfd_oem_display_s));
+
+       display.availability = availability;
+
+       display.type = device->display.type;
+       display.hdcp_support = device->display.hdcp_support;
+       display.port = device->display.port;
+       display.max_tput = device->display.max_tput;
+
+       res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
+       if (res < 0) {
+               WDS_LOGE("Failed to set wifi display session availability");
+               return -1;
+       }
+
+       device->display.availability = availability;
+
+       __WDS_LOG_FUNC_EXIT__;
+       return res;
+}
+
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+int wfd_manager_start_discovery(wfd_manager_s *manager, int mode, int timeout,
+                               const char* type, int channel)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       int res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       wfd_oem_scan_param_s param;
+       memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
+
+       WDS_LOGI("Mode: [%d], Timeout: [%d], type: [%s]", mode, timeout, type, channel);
+
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO)
+               param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
+
+       if (channel == WFD_DISCOVERY_FULL_SCAN) {
+               param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
+       } else if (channel == WFD_DISCOVERY_SOCIAL_CHANNEL) {
+               param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
+       } else if (channel == WFD_DISCOVERY_CHANNEL1) {
+               param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL1;
+               param.freq = 2412;
+       } else if (channel == WFD_DISCOVERY_CHANNEL6) {
+               param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL6;
+               param.freq = 2437;
+       } else if (channel == WFD_DISCOVERY_CHANNEL11) {
+               param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL11;
+               param.freq = 2462;
+       } else {
+               param.scan_type = WFD_OEM_SCAN_TYPE_SPECIFIC;
+               param.freq = wfd_util_channel_to_freq(channel);
+       }
+
+       if (mode)
+               param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
+       else
+               param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
+
+       param.scan_time = timeout;
+
+       res = wfd_oem_start_scan(manager->oem_ops, &param);
+       if (res < 0) {
+               WDS_LOGE("Failed to start scan");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       if (mode)
+               manager->scan_mode = WFD_SCAN_MODE_PASSIVE;
+       else
+               manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
+
+       if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
+       }
+
+       WDS_LOGD("Succeeded to start scan");
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+
+int wfd_manager_cancel_discovery(wfd_manager_s *manager)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       int res = 0;
+
+       res = wfd_oem_stop_scan(manager->oem_ops);
+       if (res < 0) {
+               WDS_LOGE("Failed to stop scan");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+       } else {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+       }
+
+       WDS_LOGD("Succeeded to stop scan");
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+
+wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_device_s *peer = NULL;
+       if (manager->group)
+               peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
+
+       if (peer)
+               return peer;
+
+       peer = wfd_peer_find_by_addr(manager, peer_addr);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return peer;
+}
+
 static wfd_manager_s *wfd_manager_init()
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_manager_s *manager = NULL;
        int res = 0;
 
-       manager = (wfd_manager_s*) calloc(1, sizeof(wfd_manager_s));
+       manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
        if (!manager) {
                WDS_LOGE("Failed to allocate memory for wfd_manager structure");
                return NULL;
@@ -875,18 +1699,23 @@ static wfd_manager_s *wfd_manager_init()
        manager->go_intent = 7;
        manager->req_wps_mode = WFD_WPS_MODE_PBC;
        manager->max_station = 8;
-
+       manager->session_timer = 120;
+       manager->auto_group_remove_enable = TRUE;
        res = _wfd_local_init_device(manager);
        if (res < 0) {
                WDS_LOGE("Failed to initialize local device");
-               free(manager);
-               return NULL;            // really stop manager?
+               g_free(manager);
+               return NULL;            /* really stop manager? */
        }
        WDS_LOGD("Succeeded to initialize local device");
 
+#ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
+       manager->client_count = 0;
+       manager->client_list = NULL;
        manager->exit_timer = g_timeout_add(120000,
                                                (GSourceFunc) _wfd_exit_timeout_cb, manager);
        WDS_LOGD("Exit timer started");
+#endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
 
        __WDS_LOG_FUNC_EXIT__;
        return manager;
@@ -902,14 +1731,15 @@ int wfd_manager_deinit(wfd_manager_s *manager)
                return -1;
        }
 
+#ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
        if (manager->exit_timer > 0)
                g_source_remove(manager->exit_timer);
        manager->exit_timer = 0;
+#endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
 
        _wfd_local_deinit_device(manager);
 
-       if (manager)
-               free(manager);
+       g_free(manager);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -937,7 +1767,12 @@ static void *wfd_plugin_init(wfd_manager_s *manager)
        WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
 
        errno = 0;
+
+#if defined(TIZEN_ARCH_64)
+       handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
+#else
        handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
+#endif
        if (!handle) {
                WDS_LOGE("Failed to open shared object. [%s]", dlerror());
                __WDS_LOG_FUNC_EXIT__;
@@ -948,7 +1783,7 @@ static void *wfd_plugin_init(wfd_manager_s *manager)
        int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
        plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
        if (!plugin_load) {
-               WDS_LOGE( "Failed to load symbol. Error = [%s]", strerror(errno));
+               WDS_LOGE("Failed to load symbol. Error = [%s]", strerror(errno));
                dlclose(handle);
                __WDS_LOG_FUNC_EXIT__;
                return NULL;
@@ -958,7 +1793,7 @@ static void *wfd_plugin_init(wfd_manager_s *manager)
        (*plugin_load)(&temp_ops);
        manager->oem_ops = temp_ops;
 
-       res = wfd_oem_init(temp_ops, (wfd_oem_event_cb) wfd_process_event, manager);
+       res = wfd_oem_init(temp_ops);
        if (res < 0) {
                WDS_LOGE("Failed to initialize OEM");
                dlclose(handle);
@@ -988,20 +1823,104 @@ static int wfd_plugin_deinit(wfd_manager_s *manager)
        return 0;
 }
 
+#if defined TIZEN_ENABLE_PRD
+static void *wfd_prd_plugin_init(wfd_manager_s *manager)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       void *handle;
+       struct utsname kernel_info;
+       int res;
+
+       if (!manager) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return NULL;
+       }
+
+       res = uname(&kernel_info);
+       if (res) {
+               WDS_LOGE("Failed to detect target type");
+               __WDS_LOG_FUNC_EXIT__;
+               return NULL;
+       }
+       WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
+
+       errno = 0;
+
+#if defined(TIZEN_ARCH_64)
+       handle = dlopen(SUPPL_PRD_PLUGIN_64BIT_PATH, RTLD_NOW);
+#else
+       handle = dlopen(SUPPL_PRD_PLUGIN_PATH, RTLD_NOW);
+#endif
+       if (!handle) {
+               WDS_LOGE("Failed to open shared object. [%s]", dlerror());
+               __WDS_LOG_FUNC_EXIT__;
+               return NULL;
+       }
+
+       errno = 0;
+       int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
+       plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_prd_plugin_load");
+       if (!plugin_load) {
+               WDS_LOGE("Failed to load symbol. Error = [%s]", strerror(errno));
+               dlclose(handle);
+               __WDS_LOG_FUNC_EXIT__;
+               return NULL;
+       }
+
+       (*plugin_load)((wfd_oem_ops_s **)&manager->oem_ops);
+
+       res = wfd_oem_prd_init((wfd_oem_ops_s *)manager->oem_ops);
+       if (res < 0) {
+               WDS_LOGE("Failed to initialize PRD OEM");
+               dlclose(handle);
+               __WDS_LOG_FUNC_EXIT__;
+               return NULL;
+       }
+       WDS_LOGD("Succeeded to initialize PRD OEM");
+
+       __WDS_LOG_FUNC_EXIT__;
+       return handle;
+}
+
+static int wfd_prd_plugin_deinit(wfd_manager_s *manager)
+{
+       __WDS_LOG_FUNC_ENTER__;
+
+       if (!manager || !manager->prd_plugin_handle) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       dlclose(manager->prd_plugin_handle);
+       manager->prd_plugin_handle = NULL;
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif /* TIZEN_ENABLE_PRD */
+
 int main(int argc, char *argv[])
 {
        __WDS_LOG_FUNC_ENTER__;
        GMainLoop *main_loop = NULL;
-       int res = 0;
 
+#if !GLIB_CHECK_VERSION(2, 32, 0)
        if (!g_thread_supported())
                g_thread_init(NULL);
+#endif
 
+#if !GLIB_CHECK_VERSION(2, 36, 0)
        g_type_init();
+#endif
 
-       // TODO: Parsing argument
+       /* TODO: Parsing argument */
        /* Wi-Fi direct connection for S-Beam can be optimized using argument */
 
+       /**
+        * wfd-manager initialization
+        */
        g_manager = wfd_manager_init();
        if (!g_manager) {
                WDS_LOGE("Failed to initialize wifi-direct manager");
@@ -1010,6 +1929,9 @@ int main(int argc, char *argv[])
        }
        WDS_LOGD("Succeeded to initialize manager");
 
+       /**
+        * wfd_manager_plugin initialization
+        */
        g_manager->plugin_handle = wfd_plugin_init(g_manager);
        if (!g_manager->plugin_handle) {
                WDS_LOGE("Failed to initialize plugin");
@@ -1019,15 +1941,24 @@ int main(int argc, char *argv[])
        }
        WDS_LOGD("Succeeded to load plugin");
 
-       res = wfd_client_handler_init(g_manager);
-       if (res < 0) {
-               WDS_LOGE("Failed to initialize client handler");
+#if defined TIZEN_ENABLE_PRD
+       /**
+        * wfd_manager_prd_plugin initialization
+        */
+       g_manager->prd_plugin_handle = wfd_prd_plugin_init(g_manager);
+       if (!g_manager->prd_plugin_handle)
+               WDS_LOGW("Failed to initialize prd plugin");
+       else
+               WDS_LOGD("Succeeded to load plugin");
+#endif /* TIZEN_ENABLE_PRD */
+
+       if (!wfd_manager_dbus_init()) {
+               WDS_LOGE("Failed to DBus");
                wfd_plugin_deinit(g_manager);
                wfd_manager_deinit(g_manager);
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDS_LOGD("Succeeded to initialize client handler");
 
        main_loop = g_main_loop_new(NULL, FALSE);
        if (main_loop == NULL) {
@@ -1036,10 +1967,19 @@ int main(int argc, char *argv[])
                return -1;
        }
        g_manager->main_loop = main_loop;
-
        g_main_loop_run(main_loop);
 
-       wfd_client_handler_deinit(g_manager);
+#ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
+       wfd_manager_dbus_unregister_nameowner_signal();
+#endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
+
+       wfd_manager_dbus_unregister();
+       wfd_manager_dbus_deinit();
+
+#if defined TIZEN_ENABLE_PRD
+       wfd_prd_plugin_deinit(g_manager);
+#endif /* TIZEN_ENABLE_PRD */
+
        wfd_plugin_deinit(g_manager);
        wfd_manager_deinit(g_manager);