Fixed: Coding rule issues.
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-manager.c
old mode 100755 (executable)
new mode 100644 (file)
index 2e11712..02f0375
 #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;
 
 wfd_manager_s *wfd_get_manager()
@@ -58,6 +62,108 @@ 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__;
+       wfd_manager_s *manager = (wfd_manager_s*) user_data;
+
+       if (!manager) {
+               WDS_LOGE("Invalid parameter");
+               return TRUE;
+       }
+
+       if (manager->client_count > 0) {
+               WDS_LOGD("Client count [%d]", manager->client_count);
+               return TRUE;
+       }
+
+       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;
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       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__;
@@ -85,9 +191,8 @@ static int _wfd_local_init_device(wfd_manager_s *manager)
        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;
@@ -100,7 +205,7 @@ static int _wfd_local_init_device(wfd_manager_s *manager)
        local->services = NULL;
        local->service_count = 0;
 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
-       // TODO: initialize other local device datas
+       /* TODO: initialize other local device datas */
        manager->local = local;
 
        __WDS_LOG_FUNC_EXIT__;
@@ -118,7 +223,7 @@ static int _wfd_local_deinit_device(wfd_manager_s *manager)
 
        wfd_util_unset_dev_name_notification();
 
-       // TODO: free member of local device
+       /* TODO: free member of local device */
        g_free(manager->local);
 
        __WDS_LOG_FUNC_EXIT__;
@@ -184,7 +289,7 @@ int wfd_local_set_dev_name(char *dev_name)
                wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
                WDS_LOGD("Device name changed.");
        } else {
-               WDS_LOGE("Device name can't changed: state is %d",g_manager->state);
+               WDS_LOGE("Device name can't changed: state is %d", g_manager->state);
        }
 
        __WDS_LOG_FUNC_EXIT__;
@@ -380,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;
@@ -465,6 +570,8 @@ int wfd_manager_local_config_set(wfd_manager_s *manager)
                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");
@@ -542,9 +649,8 @@ int wfd_manager_activate(wfd_manager_s *manager)
 #endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
 
        res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
-       if (res < 0) {
+       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;
@@ -560,6 +666,7 @@ 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");
@@ -575,26 +682,29 @@ int wfd_manager_deactivate(wfd_manager_s *manager)
                WDS_LOGE("Failed to initialize miracast");
 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
-       res = wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
-       if (res < 0)
-               WDS_LOGE("Failed to destroy group before deactivation");
+       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_MOBILE)
+#if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
        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 && TIZEN_MOBILE */
+#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_MOBILE)
+#if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
        } else {
-               // FIXME: We should do something to stop p2p feature of Driver
+               /* 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");
@@ -603,7 +713,7 @@ int wfd_manager_deactivate(wfd_manager_s *manager)
                }
                WDS_LOGE("Do not need to deactivate Wi-Fi");
        }
-#endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_MOBILE */
+#endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_PROFILE_MOBILE */
        WDS_LOGE("Succeeded to deactivate");
 
        wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
@@ -611,7 +721,7 @@ int wfd_manager_deactivate(wfd_manager_s *manager)
 
        manager->req_wps_mode = WFD_WPS_MODE_PBC;
 
-       wfd_destroy_group(manager, GROUP_IFNAME);
+       wfd_destroy_group(manager);
        wfd_destroy_session(manager);
        wfd_peer_clear_all(manager);
        wfd_local_reset_data(manager);
@@ -683,6 +793,111 @@ int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
        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);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+#endif
+
 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -707,7 +922,10 @@ 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) {
                WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
@@ -777,25 +995,13 @@ int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_ad
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
-       if (manager->local->dev_role != WFD_DEV_ROLE_GO)
-               wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
-
        group = (wfd_group_s*) manager->group;
-       if (group) {
+       if (group)
                wfd_group_remove_member(group, peer_addr);
-               if (!group->member_count) {
-                       if (wfd_util_is_remove_group_allowed()) {
-                               wfd_oem_destroy_group(manager->oem_ops, group->ifname);
-                               wfd_destroy_group(manager, group->ifname);
-                       }
-               } else {
-                       wfd_oem_disconnect(manager->oem_ops, peer_addr);
-               }
-       }
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
                wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
-               if (group && group->member_count > 0)
+               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);
@@ -837,7 +1043,7 @@ int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_ad
        res = wfd_session_reject(session, peer_addr);
        if (res < 0) {
                WDS_LOGE("Failed to reject connection");
-               // TODO: check whether set state and break
+               /* TODO: check whether set state and break */
        }
        wfd_destroy_session(manager);
 
@@ -886,15 +1092,14 @@ int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
        wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
-#ifdef CTRL_IFACE_DBUS
-               /* dbus using device address to identify the peer */
-               res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr);
-#else /* CTRL_IFACE_DBUS */
-               res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr);
-#endif /* CTRL_IFACE_DBUS */
+               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;
@@ -905,7 +1110,7 @@ int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
        wfd_group_remove_member(group, peer_addr);
        if (!group->member_count) {
                wfd_oem_destroy_group(manager->oem_ops, group->ifname);
-               wfd_destroy_group(manager, group->ifname);
+               wfd_destroy_group(manager);
        }
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
@@ -959,7 +1164,7 @@ int wfd_manager_disconnect_all(wfd_manager_s *manager)
        }
        WDS_LOGE("Succeeded to disconnect all peer");
 
-       wfd_destroy_group(manager, group->ifname);
+       wfd_destroy_group(manager);
 
        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
@@ -1010,7 +1215,7 @@ int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_d
        }
 
        peer_dev = wfd_peer_find_by_addr(manager, addr);
-       if(!peer_dev) {
+       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));
@@ -1220,7 +1425,7 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
                        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 */
@@ -1245,6 +1450,26 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
        return count;
 }
 
+#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 (peer_addr == NULL) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return peer;
+       }
+
+       if (manager->group)
+               peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return peer;
+}
+#endif /* TIZEN_FEATURE_ASP */
+
 #if 0
 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
 {
@@ -1447,13 +1672,11 @@ wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_device_s *peer = NULL;
-       if(manager->group) {
+       if (manager->group)
                peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
-       }
 
-       if(peer) {
+       if (peer)
                return peer;
-       }
 
        peer = wfd_peer_find_by_addr(manager, peer_addr);
 
@@ -1482,10 +1705,18 @@ static wfd_manager_s *wfd_manager_init()
        if (res < 0) {
                WDS_LOGE("Failed to initialize local device");
                g_free(manager);
-               return NULL;            // really stop 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;
 }
@@ -1500,6 +1731,12 @@ 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);
 
        g_free(manager);
@@ -1532,9 +1769,9 @@ static void *wfd_plugin_init(wfd_manager_s *manager)
        errno = 0;
 
 #if defined(TIZEN_ARCH_64)
-               handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
+       handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
 #else
-               handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
+       handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
 #endif
        if (!handle) {
                WDS_LOGE("Failed to open shared object. [%s]", dlerror());
@@ -1546,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;
@@ -1556,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);
@@ -1586,21 +1823,99 @@ 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;
 
-#if !GLIB_CHECK_VERSION(2,32,0)
+#if !GLIB_CHECK_VERSION(2, 32, 0)
        if (!g_thread_supported())
                g_thread_init(NULL);
 #endif
 
-#if !GLIB_CHECK_VERSION(2,36,0)
+#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 */
 
        /**
@@ -1626,6 +1941,17 @@ int main(int argc, char *argv[])
        }
        WDS_LOGD("Succeeded to load plugin");
 
+#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);
@@ -1643,9 +1969,17 @@ int main(int argc, char *argv[])
        g_manager->main_loop = main_loop;
        g_main_loop_run(main_loop);
 
+#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);