c0b9ad3933ee10210f14e97d58434cec227fd6db
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-manager.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /**
21  * This file implements wifi direct manager functions.
22  *
23  * @file                wifi-direct-manager.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <dlfcn.h>
31 #include <sys/utsname.h>
32 #include <time.h>
33 #include <errno.h>
34
35 #include <glib.h>
36 #include <glib-object.h>
37
38 #include <wifi-direct.h>
39
40 #include "wifi-direct-ipc.h"
41 #include "wifi-direct-manager.h"
42 #include "wifi-direct-oem.h"
43 #include "wifi-direct-session.h"
44 #include "wifi-direct-group.h"
45 #include "wifi-direct-peer.h"
46 #include "wifi-direct-state.h"
47 #include "wifi-direct-event.h"
48 #include "wifi-direct-util.h"
49 #include "wifi-direct-log.h"
50 #include "wifi-direct-error.h"
51 #include "wifi-direct-iface.h"
52 #include "wifi-direct-dbus.h"
53
54 #if defined TIZEN_ENABLE_PRD
55 #include "wifi-direct-prd.h"
56 #endif /* TIZEN_ENABLE_PRD */
57
58 wfd_manager_s *g_manager;
59
60 wfd_manager_s *wfd_get_manager()
61 {
62         return g_manager;
63 }
64
65 #ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
66 /* Stop wfd-manager services, If no client
67    exists and state is deactivated. */
68 static gboolean _wfd_exit_timeout_cb(void *user_data)
69 {
70         __WDS_LOG_FUNC_ENTER__;
71         wfd_manager_s *manager = (wfd_manager_s*) user_data;
72
73         if (!manager) {
74                 WDS_LOGE("Invalid parameter");
75                 return TRUE;
76         }
77
78         if (manager->client_count > 0) {
79                 WDS_LOGD("Client count [%d]", manager->client_count);
80                 return TRUE;
81         }
82
83         if (manager->state == WIFI_DIRECT_STATE_DEACTIVATED) {
84                 WDS_LOGD("Terminate Wi-Fi Direct Manager");
85                 g_main_quit(manager->main_loop);
86                 manager->exit_timer = 0;
87                 WDS_LOGD("Stop exit timer. State [%d]", manager->state);
88                 __WDS_LOG_FUNC_EXIT__;
89                 return FALSE;
90         }
91
92         __WDS_LOG_FUNC_EXIT__;
93         return TRUE;
94 }
95
96 void wfd_manager_free_active_client_list(void)
97 {
98         GSList *list;
99         wfd_manager_s *manager = wfd_get_manager();
100
101         if (!manager || !manager->client_list)
102                 return;
103
104         for (list = manager->client_list; list; list = list->next)
105                 g_free(list->data);
106
107         g_slist_free(manager->client_list);
108 }
109
110 void wfd_manager_add_active_client(const char *client_id)
111 {
112         GSList *list = NULL;
113         gboolean if_exists = FALSE;
114         gchar *str = NULL;
115         wfd_manager_s *manager = wfd_get_manager();
116         if (!manager || !client_id)
117                 return;
118
119         for (list = manager->client_list; list; list = list->next) {
120                 str = list->data;
121                 if (str && !g_strcmp0(client_id, str)) {
122                         if_exists = TRUE;
123                         break;
124                 }
125         }
126
127         // If not exists in list, add the sender
128         if (if_exists == FALSE) {
129                 manager->client_list = g_slist_prepend(manager->client_list,
130                                          g_strdup(client_id));
131                 manager->client_count++;
132                 WDS_LOGD("Added DBus sender id[%s] count[%d]", client_id,
133                                          manager->client_count);
134         }
135 }
136
137 void wfd_manager_remove_active_client(const gchar *name,
138                                       const char *old_owner,
139                                       const char *new_owner)
140 {
141         GSList *list = NULL;
142         gchar *str = NULL;
143         wfd_manager_s *manager = wfd_get_manager();
144
145         if (!manager)
146                 return;
147
148         if (!g_strcmp0(new_owner, "")) {
149                 if (manager->client_count > 0) {
150                         for (list = manager->client_list; list; list = list->next) {
151                                 str = list->data;
152                                 if (str && !g_strcmp0(old_owner, str)) {
153                                         manager->client_list =
154                                                  g_slist_remove(manager->client_list, str);
155                                         g_free(str);
156                                         manager->client_count--;
157                                         WDS_LOGD("Removed name[%s] old[%s] new[%s] count[%d]",
158                                                  name, old_owner, new_owner, manager->client_count);
159                                         break;
160                                 }
161                         }
162                 }
163         }
164 }
165 #endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
166
167 static int _wfd_local_init_device(wfd_manager_s *manager)
168 {
169         __WDS_LOG_FUNC_ENTER__;
170         wfd_device_s *local = NULL;
171         int res = 0;
172         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
173
174         if (!manager) {
175                 WDS_LOGE("Invalid parameter");
176                 return -1;
177         }
178
179         errno = 0;
180         local = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
181         if (!local) {
182                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
183                 WDS_LOGE("Failed to allocate memory for local device [%s]", error_buf);
184                 return -1;
185         }
186
187         res = wfd_util_get_phone_name(local->dev_name);
188         if (res < 0) {
189                 WDS_LOGE("Failed to get phone name of local device. Use default device name");
190                 g_strlcpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN + 1);
191         }
192         WDS_LOGD("Local Device name [%s]", local->dev_name);
193         wfd_util_set_dev_name_notification();
194
195         res = wfd_util_get_local_dev_mac(local->dev_addr);
196         if (res < 0)
197                 WDS_LOGE("Failed to get local device MAC address");
198
199         memcpy(local->intf_addr, local->dev_addr, MACADDR_LEN);
200         local->intf_addr[4] ^= 0x80;
201         WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
202                                         MAC2SECSTR(local->intf_addr));
203
204         local->config_methods = WFD_WPS_MODE_PBC | WFD_WPS_MODE_DISPLAY | WFD_WPS_MODE_KEYPAD;
205         local->wps_mode = WFD_WPS_MODE_PBC;
206 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
207         local->services = NULL;
208         local->service_count = 0;
209 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
210         /* TODO: initialize other local device datas */
211         manager->local = local;
212
213         __WDS_LOG_FUNC_EXIT__;
214         return 0;
215 }
216
217 static int _wfd_local_deinit_device(wfd_manager_s *manager)
218 {
219         __WDS_LOG_FUNC_ENTER__;
220
221         if (!manager) {
222                 WDS_LOGE("Invalid parameter");
223                 return -1;
224         }
225
226         wfd_util_unset_dev_name_notification();
227
228         /* TODO: free member of local device */
229         g_free(manager->local);
230
231         __WDS_LOG_FUNC_EXIT__;
232         return 0;
233 }
234
235 int wfd_local_reset_data(wfd_manager_s *manager)
236 {
237         __WDS_LOG_FUNC_ENTER__;
238         wfd_device_s *local = NULL;
239
240         if (!manager) {
241                 WDS_LOGE("Invalid parameter");
242                 return -1;
243         }
244
245         local = manager->local;
246         /* init local device data */
247         local->dev_role = WFD_DEV_ROLE_NONE;
248         local->wps_mode = WFD_WPS_MODE_PBC;
249         memset(local->go_dev_addr, 0x0, MACADDR_LEN);
250 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
251         memset(&(local->display), 0x0, sizeof(wfd_display_s));
252 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
253         memset(local->ip_addr, 0x0, IPADDR_LEN);
254
255         __WDS_LOG_FUNC_EXIT__;
256         return 0;
257 }
258
259 int wfd_local_get_dev_name(char *dev_name)
260 {
261         __WDS_LOG_FUNC_ENTER__;
262         wfd_device_s *local = g_manager->local;
263
264         if (!dev_name) {
265                 WDS_LOGE("Invalid parameter");
266                 __WDS_LOG_FUNC_EXIT__;
267                 return -1;
268         }
269
270         g_strlcpy(dev_name, local->dev_name, DEV_NAME_LEN + 1);
271         WDS_LOGD("Local device name [%s]", dev_name);
272
273         __WDS_LOG_FUNC_EXIT__;
274         return 0;
275 }
276
277 int wfd_local_set_dev_name(char *dev_name)
278 {
279         __WDS_LOG_FUNC_ENTER__;
280         wfd_device_s *local = g_manager->local;
281
282         if (!dev_name) {
283                 WDS_LOGE("Invalid parameter");
284                 __WDS_LOG_FUNC_EXIT__;
285                 return -1;
286         }
287
288         g_strlcpy(local->dev_name, dev_name, DEV_NAME_LEN + 1);
289
290         if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED) {
291                 wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
292                 WDS_LOGD("Device name changed.");
293         } else {
294                 WDS_LOGE("Device name can't changed: state is %d", g_manager->state);
295         }
296
297         __WDS_LOG_FUNC_EXIT__;
298         return 0;
299 }
300
301 int wfd_local_get_dev_mac(char *dev_mac)
302 {
303         __WDS_LOG_FUNC_ENTER__;
304         wfd_device_s *local = g_manager->local;
305
306         if (!dev_mac) {
307                 WDS_LOGE("Invalid parameter");
308                 __WDS_LOG_FUNC_EXIT__;
309                 return -1;
310         }
311
312         g_snprintf(dev_mac, MACSTR_LEN, MACSTR, MAC2STR(local->dev_addr));
313         WDS_SECLOGD("Local device MAC address [%s]", dev_mac);
314
315         __WDS_LOG_FUNC_EXIT__;
316         return 0;
317 }
318
319 #if 0
320 int wfd_local_get_intf_mac(unsigned char *intf_mac)
321 {
322         __WDS_LOG_FUNC_ENTER__;
323         wfd_device_s *local = g_manager->local;
324
325         if (!intf_mac) {
326                 WDS_LOGE("Invalid parameter");
327                 __WDS_LOG_FUNC_EXIT__;
328                 return -1;
329         }
330
331         g_snprintf(intf_mac, MACSTR_LEN, MACSTR, MAC2STR(local->intf_addr));
332         WDS_SECLOGD("Local interface MAC address [%s]", intf_mac);
333
334         __WDS_LOG_FUNC_EXIT__;
335         return 0;
336 }
337 #endif
338
339 int wfd_local_get_ip_addr(char *ip_str)
340 {
341         __WDS_LOG_FUNC_ENTER__;
342         wfd_device_s *local = g_manager->local;
343
344         if (!ip_str) {
345                 WDS_LOGE("Invalid parameter");
346                 __WDS_LOG_FUNC_EXIT__;
347                 return -1;
348         }
349
350         snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(local->ip_addr));
351         WDS_SECLOGD("Local IP address [" IPSECSTR "]", IP2SECSTR(local->ip_addr));
352
353         __WDS_LOG_FUNC_EXIT__;
354         return 0;
355 }
356
357 int wfd_local_get_supported_wps_mode(int *config_methods)
358 {
359         __WDS_LOG_FUNC_ENTER__;
360         wfd_device_s *local = g_manager->local;
361
362         if (!config_methods) {
363                 WDS_LOGE("Invalid parameter");
364                 __WDS_LOG_FUNC_EXIT__;
365                 return -1;
366         }
367
368         *config_methods = local->config_methods;
369         WDS_LOGD("Local config method [0x%x]", *config_methods);
370
371         __WDS_LOG_FUNC_EXIT__;
372         return 0;
373 }
374
375 int wfd_local_get_wps_mode(int *wps_mode)
376 {
377         __WDS_LOG_FUNC_ENTER__;
378         wfd_device_s *local = g_manager->local;
379
380         if (!wps_mode) {
381                 WDS_LOGE("Invalid parameter");
382                 __WDS_LOG_FUNC_EXIT__;
383                 return -1;
384         }
385
386         *wps_mode = local->wps_mode;
387         WDS_LOGD("Local wps mode [0x%x]", *wps_mode);
388
389         __WDS_LOG_FUNC_EXIT__;
390         return 0;
391 }
392
393 #if 0
394 int wfd_local_set_wps_mode(int wps_mode)
395 {
396         __WDS_LOG_FUNC_ENTER__;
397         wfd_device_s *local = g_manager->local;
398
399         if (!wps_mode) {
400                 WDS_LOGE("Invalid parameter");
401                 __WDS_LOG_FUNC_EXIT__;
402                 return -1;
403         }
404
405         local->wps_mode = wps_mode;
406         WDS_LOGD("Local wps mode [0x%x]", wps_mode);
407
408         __WDS_LOG_FUNC_EXIT__;
409         return 0;
410 }
411 #endif
412
413 int wfd_manager_get_go_intent(int *go_intent)
414 {
415         __WDS_LOG_FUNC_ENTER__;
416         if (!go_intent) {
417                 WDS_LOGE("Invalid parameter");
418                 __WDS_LOG_FUNC_EXIT__;
419                 return -1;
420         }
421
422         *go_intent = g_manager->go_intent;
423         WDS_LOGD("Local GO intent [%d]", *go_intent);
424
425         __WDS_LOG_FUNC_EXIT__;
426         return 0;
427 }
428
429 int wfd_manager_set_go_intent(int go_intent)
430 {
431         __WDS_LOG_FUNC_ENTER__;
432
433         if (go_intent < 0 || go_intent > 15) {
434                 WDS_LOGE("Invalid parameter");
435                 __WDS_LOG_FUNC_EXIT__;
436                 return -1;
437         }
438
439         g_manager->go_intent = go_intent;
440         if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED)
441                 wfd_oem_set_go_intent(g_manager->oem_ops, go_intent);
442
443         __WDS_LOG_FUNC_EXIT__;
444         return 0;
445 }
446
447 int wfd_manager_get_max_station(int *max_station)
448 {
449         __WDS_LOG_FUNC_ENTER__;
450
451         if (!max_station) {
452                 WDS_LOGE("Invalid parameter");
453                 __WDS_LOG_FUNC_EXIT__;
454                 return -1;
455         }
456
457         *max_station = g_manager->max_station;
458         WDS_LOGD("Local max station[%d]", *max_station);
459
460         __WDS_LOG_FUNC_EXIT__;
461         return 0;
462 }
463
464 int wfd_manager_set_max_station(int max_station)
465 {
466         __WDS_LOG_FUNC_ENTER__;
467
468         if (max_station < 1) {
469                 WDS_LOGE("Invalid parameter");
470                 __WDS_LOG_FUNC_EXIT__;
471                 return -1;
472         }
473
474         g_manager->max_station = max_station;
475
476         __WDS_LOG_FUNC_EXIT__;
477         return 0;
478 }
479
480 int wfd_manager_get_autoconnection(int *autoconnection)
481 {
482         __WDS_LOG_FUNC_ENTER__;
483         if (!autoconnection) {
484                 WDS_LOGE("Invalid parameter");
485                 __WDS_LOG_FUNC_EXIT__;
486                 return -1;
487         }
488
489         *autoconnection = g_manager->autoconnection;
490         WDS_LOGD("Local autoconnection [%s]", *autoconnection ? "TRUE" : "FALSE");
491
492         __WDS_LOG_FUNC_EXIT__;
493         return 0;
494 }
495
496 int wfd_manager_set_autoconnection(int autoconnection)
497 {
498         __WDS_LOG_FUNC_ENTER__;
499         if (autoconnection < 0) {
500                 WDS_LOGE("Invalid parameter");
501                 __WDS_LOG_FUNC_EXIT__;
502                 return -1;
503         }
504
505         g_manager->autoconnection = autoconnection;
506
507         __WDS_LOG_FUNC_EXIT__;
508         return 0;
509 }
510
511 int wfd_manager_get_req_wps_mode(int *req_wps_mode)
512 {
513         __WDS_LOG_FUNC_ENTER__;
514
515         if (!req_wps_mode) {
516                 WDS_LOGE("Invalid parameter");
517                 __WDS_LOG_FUNC_EXIT__;
518                 return -1;
519         }
520
521         *req_wps_mode = g_manager->req_wps_mode;
522         WDS_LOGD("Requested wps mode [0x%x]", *req_wps_mode);
523
524         __WDS_LOG_FUNC_EXIT__;
525         return 0;
526 }
527
528 int wfd_manager_set_req_wps_mode(int req_wps_mode)
529 {
530         __WDS_LOG_FUNC_ENTER__;
531         wfd_device_s *local = g_manager->local;
532
533         if (req_wps_mode != WIFI_DIRECT_WPS_TYPE_PBC &&
534                         req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY &&
535                         req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD) {
536                 WDS_LOGE("Invalid parameter");
537                 __WDS_LOG_FUNC_EXIT__;
538                 return -1;
539         }
540
541         g_manager->req_wps_mode = req_wps_mode;
542         WDS_LOGD("Requested wps mode [0x%x]", req_wps_mode);
543         if (req_wps_mode == WFD_WPS_MODE_DISPLAY)
544                 local->wps_mode = WFD_WPS_MODE_KEYPAD;
545         else if (req_wps_mode == WFD_WPS_MODE_KEYPAD)
546                 local->wps_mode = WFD_WPS_MODE_DISPLAY;
547         else
548                 local->wps_mode = req_wps_mode;
549
550         __WDS_LOG_FUNC_EXIT__;
551         return 0;
552 }
553
554 int wfd_manager_local_config_set(wfd_manager_s *manager)
555 {
556         __WDS_LOG_FUNC_ENTER__;
557         wfd_device_s *local = NULL;
558         int res = 0;
559
560         if (!manager) {
561                 WDS_LOGE("Invalid parameter");
562                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
563         }
564
565         local = manager->local;
566
567         local->wps_mode = WFD_WPS_MODE_PBC;
568         WDS_LOGD("Device name set as %s", local->dev_name);
569         res = wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
570         if (res < 0) {
571                 WDS_LOGE("Failed to set device name");
572                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
573         }
574
575         local->pri_dev_type = DEFAULT_PRIMARY_DEVICE_TYPE;
576         local->sec_dev_type = DEFAULT_SECONDARY_DEVICE_TYPE;
577         res = wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
578         if (res < 0) {
579                 WDS_LOGE("Failed to set device type");
580                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
581         }
582
583         res = wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
584         if (res < 0) {
585                 WDS_LOGE("Failed to set go intent");
586                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
587         }
588
589         return WIFI_DIRECT_ERROR_NONE;
590 }
591
592 int wfd_manager_activate(wfd_manager_s *manager)
593 {
594         __WDS_LOG_FUNC_ENTER__;
595         int prev_state = 0;
596         int res = 0;
597
598         if (!manager) {
599                 WDS_LOGE("Invalid parameter");
600                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
601         }
602
603         if (manager->state > WIFI_DIRECT_STATE_ACTIVATING) {
604                 WDS_LOGE("Already activated");
605                 return 1;
606         }
607
608         if (manager->state == WIFI_DIRECT_STATE_ACTIVATING) {
609                 WDS_LOGE("In progress");
610                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
611         }
612
613         res = wfd_util_wifi_direct_activatable();
614         if (res < 0)
615                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
616
617         wfd_state_get(manager, &prev_state);
618         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
619         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATING);
620 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE)
621         res = wfd_util_check_wifi_state();
622         if (res < 0) {
623                 WDS_LOGE("Failed to get wifi state");
624                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
625         } else if (res == 0) {
626 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE */
627         res = wfd_oem_activate(manager->oem_ops, 0);
628         if (res < 0) {
629                 WDS_LOGE("Failed to activate");
630                 wfd_state_set(manager, prev_state);
631                 wfd_util_set_wifi_direct_state(prev_state);
632                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
633         }
634 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE)
635         } else {
636                 res = wfd_oem_activate(manager->oem_ops, res);
637                 if (res < 0) {
638                         WDS_LOGE("Failed to activate");
639                         wfd_state_set(manager, prev_state);
640                         wfd_util_set_wifi_direct_state(prev_state);
641                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
642                 }
643         }
644 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE */
645         WDS_LOGE("Succeeded to activate");
646
647         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
648         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
649
650         wfd_manager_local_config_set(manager);
651         wfd_util_set_country();
652 #ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
653         wfd_util_start_wifi_direct_popup();
654 #endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
655
656         res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
657         if (res < 0)
658                 WDS_LOGE("Failed to get local device MAC address");
659
660         memcpy(manager->local->intf_addr, manager->local->dev_addr, MACADDR_LEN);
661         manager->local->intf_addr[4] ^= 0x80;
662         WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
663                                         MAC2SECSTR(manager->local->intf_addr));
664
665         __WDS_LOG_FUNC_EXIT__;
666         return WIFI_DIRECT_ERROR_NONE;
667 }
668
669 int wfd_manager_deactivate(wfd_manager_s *manager)
670 {
671         __WDS_LOG_FUNC_ENTER__;
672         int prev_state = 0;
673         int res = 0;
674         wfd_group_s *group = NULL;
675
676         if (!manager) {
677                 WDS_LOGE("Invalid parameter");
678                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
679         }
680
681         wfd_state_get(manager, &prev_state);
682         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
683         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATING);
684
685 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
686         res = wfd_oem_miracast_init(manager->oem_ops, false);
687         if (res < 0)
688                 WDS_LOGE("Failed to initialize miracast");
689 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
690
691         group = (wfd_group_s*) manager->group;
692         if (group && group->pending == FALSE) {
693                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
694                 if (res < 0)
695                         WDS_LOGE("Failed to destroy group before deactivation");
696         }
697
698 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
699         res = wfd_util_check_wifi_state();
700         if (res < 0) {
701                 WDS_LOGE("Failed to get wifi state");
702                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
703         } else if (res == 0) {
704 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_PROFILE_MOBILE */
705                 res = wfd_oem_deactivate(manager->oem_ops, 0);
706                 if (res < 0) {
707                         WDS_LOGE("Failed to deactivate");
708                         wfd_state_set(manager, prev_state);
709                         wfd_util_set_wifi_direct_state(prev_state);
710                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
711                 }
712 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
713         } else {
714                 /* FIXME: We should do something to stop p2p feature of Driver */
715                 res = wfd_oem_deactivate(manager->oem_ops, res);
716                 if (res < 0) {
717                         WDS_LOGE("Failed to deactivate");
718                         wfd_state_set(manager, prev_state);
719                         wfd_util_set_wifi_direct_state(prev_state);
720                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
721                 }
722                 WDS_LOGE("Do not need to deactivate Wi-Fi");
723         }
724 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_PROFILE_MOBILE */
725         WDS_LOGE("Succeeded to deactivate");
726
727         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
728         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
729
730         manager->req_wps_mode = WFD_WPS_MODE_PBC;
731
732         wfd_destroy_group(manager);
733         wfd_destroy_session(manager);
734         wfd_peer_clear_all(manager);
735         wfd_local_reset_data(manager);
736
737 #ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
738         wfd_util_stop_wifi_direct_popup();
739 #endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
740         __WDS_LOG_FUNC_EXIT__;
741         return WIFI_DIRECT_ERROR_NONE;
742 }
743
744 int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
745 {
746         __WDS_LOG_FUNC_ENTER__;
747         wfd_session_s *session = NULL;
748         int res = 0;
749
750         if (!manager || !peer_addr) {
751                 WDS_LOGE("Invalid parameter");
752                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
753         }
754
755         if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
756                         manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
757                         manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
758                 __WDS_LOG_FUNC_EXIT__;
759                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
760         }
761
762         wfd_group_s *group = (wfd_group_s*) manager->group;
763         if (group && group->member_count >= manager->max_station) {
764                 __WDS_LOG_FUNC_EXIT__;
765                 return WIFI_DIRECT_ERROR_TOO_MANY_CLIENT;
766         }
767
768         session = (wfd_session_s*) manager->session;
769         if (session && session->type != SESSION_TYPE_INVITE) {
770                 WDS_LOGE("Session already exist and it's not an invitation session");
771                 __WDS_LOG_FUNC_EXIT__;
772                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
773         }
774
775         if (!session) {
776                 session = wfd_create_session(manager, peer_addr,
777                                         manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
778                 if (!session) {
779                         WDS_LOGE("Failed to create new session");
780                         __WDS_LOG_FUNC_EXIT__;
781                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
782                 }
783         }
784
785         if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
786                         session->type != SESSION_TYPE_INVITE) {
787                 session->type = SESSION_TYPE_INVITE;
788                 res = wfd_session_invite(session);
789         } else {
790                 res = wfd_session_start(session);
791         }
792         if (res < 0) {
793                 WDS_LOGE("Failed to start session");
794                 wfd_destroy_session(manager);
795                 __WDS_LOG_FUNC_EXIT__;
796                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
797         }
798         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
799         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
800
801         __WDS_LOG_FUNC_EXIT__;
802         return WIFI_DIRECT_ERROR_NONE;
803 }
804
805 #if defined(TIZEN_FEATURE_ASP)
806 int wfd_manager_asp_connect_session(wfd_manager_s *manager, void *params)
807 {
808         __WDS_LOG_FUNC_ENTER__;
809         wfd_session_s *session = NULL;
810         wfd_oem_asp_prov_s *prov_params = NULL;
811         int req_wps_mode = WFD_WPS_MODE_P2PS;
812         int res = 0;
813
814         prov_params = (wfd_oem_asp_prov_s *)params;
815         if (!manager || !prov_params) {
816                 WDS_LOGE("Invalid parameter");
817                 __WDS_LOG_FUNC_EXIT__;
818                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
819         }
820
821         session = (wfd_session_s*) manager->session;
822         if (session) {
823                 WDS_LOGE("Session already exists");
824                 __WDS_LOG_FUNC_EXIT__;
825                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
826         }
827
828         if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
829                 req_wps_mode = WFD_WPS_MODE_DISPLAY;
830         else if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
831                 req_wps_mode = WFD_WPS_MODE_KEYPAD;
832         else
833                 req_wps_mode = WFD_WPS_MODE_P2PS;
834
835         session = wfd_create_session(manager, prov_params->service_mac,
836                         req_wps_mode, SESSION_DIRECTION_OUTGOING);
837         if (!session) {
838                 WDS_LOGE("Failed to create new session");
839                 __WDS_LOG_FUNC_EXIT__;
840                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
841         }
842
843         res = wfd_session_asp_session_start(session, prov_params);
844         if (res < 0) {
845                 WDS_LOGE("Failed to start session");
846                 wfd_destroy_session(manager);
847                 __WDS_LOG_FUNC_EXIT__;
848                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
849         }
850
851         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
852         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
853
854         __WDS_LOG_FUNC_EXIT__;
855         return WIFI_DIRECT_ERROR_NONE;
856 }
857
858 int wfd_manager_asp_confirm_session(wfd_manager_s *manager, void *params, int confirmed)
859 {
860         __WDS_LOG_FUNC_ENTER__;
861         wfd_session_s *session = NULL;
862         wfd_oem_asp_prov_s *prov_params = NULL;
863         int res = 0;
864
865         prov_params = (wfd_oem_asp_prov_s *)params;
866         if (!manager || !prov_params) {
867                 WDS_LOGE("Invalid parameter");
868                 __WDS_LOG_FUNC_EXIT__;
869                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
870         }
871
872         session = (wfd_session_s*) manager->session;
873         if (!session) {
874                 WDS_LOGE("Session not exists");
875                 __WDS_LOG_FUNC_EXIT__;
876                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
877         }
878
879
880         WDS_LOGD("confirm session [%u] with peer [" MACSTR "]", prov_params->session_id,
881                         MAC2STR(prov_params->session_mac));
882
883         WDS_LOGD("created session [%u] with peer [" MACSTR "]", session->session_id,
884                         MAC2STR(session->session_mac));
885
886         if (session->session_id != prov_params->session_id ||
887                         memcmp(&(session->session_mac), prov_params->session_mac, MACADDR_LEN) != 0) {
888                 WDS_LOGE("Session MAC or ID not matched");
889                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
890         }
891
892         if (confirmed)
893                 prov_params->status = 12;
894         else
895                 prov_params->status = 11;
896         prov_params->deferring = 1;
897
898         res = wfd_oem_asp_prov_disc_req(manager->oem_ops, prov_params);
899         if (res < 0) {
900                 WDS_LOGE("Failed to start session");
901                 wfd_destroy_session(manager);
902                 __WDS_LOG_FUNC_EXIT__;
903                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
904         }
905         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
906         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
907
908         __WDS_LOG_FUNC_EXIT__;
909         return WIFI_DIRECT_ERROR_NONE;
910 }
911 #endif
912
913 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
914 {
915         __WDS_LOG_FUNC_ENTER__;
916         wfd_session_s *session = NULL;
917         wfd_device_s *peer = NULL;
918         int res = 0;
919
920         if (!manager || !peer_addr) {
921                 WDS_LOGE("Invalid parameter");
922                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
923         }
924
925         session = (wfd_session_s*) manager->session;
926         if (!session) {
927                 WDS_LOGE("Session not found");
928                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
929         }
930
931         peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
932         if (!peer) {
933                 WDS_LOGE("Peer is NULL");
934                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
935         }
936
937         if (memcmp(session->peer->dev_addr, peer_addr, MACADDR_LEN) != 0) {
938                 WDS_LOGE("Peer and ongoing session peer are different");
939                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
940         }
941
942         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
943                 WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
944                 res = wfd_session_wps(session);
945         } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
946                 WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");
947                 if (session->type == SESSION_TYPE_INVITE) {
948                         if (session->state == SESSION_STATE_CREATED) {
949                                 WDS_LOGD("Invitation session. PD will be started");
950                                 res = wfd_session_start(session);
951                         } else {
952                                 WDS_LOGD("Invitation session. Join will be started");
953                                 res = wfd_session_join(session);
954                         }
955                 } else {
956                         if (manager->autoconnection && (manager->auto_pin[0] != 0))
957                                 g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
958
959                         WDS_LOGD("Peer device is GO, so WPS will be started");
960                         res = wfd_session_connect(session);
961                 }
962         } else {
963                 /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
964                 /* Otherwise, GO Nego is sometimes failed. */
965                 if (manager->autoconnection == FALSE) {
966                         WDS_LOGD("My device is Device, so Negotiation will be started");
967                         res = wfd_session_connect(session);
968                 }
969         }
970         if (res < 0) {
971                 WDS_LOGE("Failed to start session");
972                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
973                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
974                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
975                 } else {
976                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
977                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
978                 }
979                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
980         }
981         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
982         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
983
984         __WDS_LOG_FUNC_EXIT__;
985         return WIFI_DIRECT_ERROR_NONE;
986 }
987
988
989 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
990 {
991         __WDS_LOG_FUNC_ENTER__;
992         wfd_group_s *group = NULL;
993         int res = 0;
994
995         if (!manager || !peer_addr) {
996                 WDS_LOGE("Invalid parameter");
997                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
998         }
999
1000         if (!manager->session && manager->state != WIFI_DIRECT_STATE_CONNECTING) {
1001                 WDS_LOGE("It's not CONNECTING state");
1002                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1003         }
1004
1005         res = wfd_session_cancel(manager->session, peer_addr);
1006         if (res < 0) {
1007                 WDS_LOGE("Failed to cancel session");
1008                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1009         }
1010
1011         group = (wfd_group_s*) manager->group;
1012         if (group)
1013                 wfd_group_remove_member(group, peer_addr);
1014         else
1015                 manager->local->dev_role = WFD_DEV_ROLE_NONE;
1016
1017         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1018                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1019                 if (group->member_count)
1020                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1021         } else {
1022                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1023                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1024         }
1025
1026         __WDS_LOG_FUNC_EXIT__;
1027         return WIFI_DIRECT_ERROR_NONE;
1028 }
1029
1030
1031 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
1032 {
1033         __WDS_LOG_FUNC_ENTER__;
1034         wfd_session_s *session = NULL;
1035         int res = 0;
1036
1037         if (!manager || !peer_addr) {
1038                 WDS_LOGE("Invalid parameter");
1039                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1040         }
1041
1042         session = (wfd_session_s*) manager->session;
1043         if (!session) {
1044                 WDS_LOGE("Session not found");
1045                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1046         }
1047
1048         if (manager->state != WIFI_DIRECT_STATE_CONNECTING) {
1049                 WDS_LOGE("It's not permitted with this state [%d]", manager->state);
1050                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1051         }
1052
1053         if (session->direction != SESSION_DIRECTION_INCOMING) {
1054                 WDS_LOGE("Only incomming session can be rejected");
1055                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1056         }
1057
1058         res = wfd_session_reject(session, peer_addr);
1059         if (res < 0) {
1060                 WDS_LOGE("Failed to reject connection");
1061                 /* TODO: check whether set state and break */
1062         }
1063         wfd_destroy_session(manager);
1064
1065         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1066                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1067                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1068         } else {
1069                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1070                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1071         }
1072
1073         __WDS_LOG_FUNC_EXIT__;
1074         return WIFI_DIRECT_ERROR_NONE;
1075 }
1076
1077
1078 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
1079 {
1080         __WDS_LOG_FUNC_ENTER__;
1081         wfd_group_s *group = NULL;
1082         wfd_device_s *peer = NULL;
1083         int res = 0;
1084
1085         if (!manager) {
1086                 WDS_LOGE("Invalid parameter");
1087                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1088         }
1089
1090         if (!peer_addr) {
1091                 WDS_LOGE("Invalid parameter");
1092                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1093         }
1094
1095         group = (wfd_group_s*) manager->group;
1096         if (!group) {
1097                 WDS_LOGE("Group not found");
1098                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1099         }
1100
1101         peer = wfd_group_find_member_by_addr(group, peer_addr);
1102         if (!peer) {
1103                 WDS_LOGE("Connected peer not found");
1104                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1105         }
1106
1107         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
1108         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCONNECTING);
1109
1110         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1111                 if (peer->is_p2p)
1112                         res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr, 0);
1113                 else
1114                         res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr, 1);
1115         } else {
1116                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1117         }
1118
1119         if (res < 0) {
1120                 WDS_LOGE("Failed to disconnect peer");
1121                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1122                 goto failed;
1123         }
1124         WDS_LOGE("Succeeded to disconnect peer");
1125
1126         wfd_group_remove_member(group, peer_addr);
1127         if (!group->member_count) {
1128                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1129                 wfd_destroy_group(manager);
1130         }
1131
1132         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1133                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1134                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1135         } else {
1136                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1137                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1138         }
1139
1140         __WDS_LOG_FUNC_EXIT__;
1141         return WIFI_DIRECT_ERROR_NONE;
1142
1143 failed:
1144         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1145                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1146                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1147         } else {
1148                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1149                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1150         }
1151
1152         __WDS_LOG_FUNC_EXIT__;
1153         return res;
1154 }
1155
1156 int wfd_manager_disconnect_all(wfd_manager_s *manager)
1157 {
1158         __WDS_LOG_FUNC_ENTER__;
1159         wfd_group_s *group = NULL;
1160         int res = 0;
1161
1162         if (!manager) {
1163                 WDS_LOGE("Invalid parameter");
1164                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1165         }
1166
1167         group = (wfd_group_s*) manager->group;
1168         if (!group) {
1169                 WDS_LOGE("Group not found");
1170                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1171         }
1172
1173         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
1174         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCONNECTING);
1175
1176         res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1177         if (res < 0) {
1178                 WDS_LOGE("Failed to destroy group");
1179                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1180                 goto failed;
1181         }
1182         WDS_LOGE("Succeeded to disconnect all peer");
1183
1184         wfd_destroy_group(manager);
1185
1186         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1187         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1188
1189         __WDS_LOG_FUNC_EXIT__;
1190         return WIFI_DIRECT_ERROR_NONE;
1191
1192 failed:
1193         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1194                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1195                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1196         } else {
1197                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1198                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1199         }
1200
1201         __WDS_LOG_FUNC_EXIT__;
1202         return res;
1203 }
1204
1205 int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
1206 {
1207         __WDS_LOG_FUNC_ENTER__;
1208         wfd_device_s *peer_dev = NULL;
1209         wfd_discovery_entry_s *peer_info;
1210         wfd_oem_device_s *oem_dev = NULL;
1211         int res = 0;
1212         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1213
1214         if (!manager || !addr) {
1215                 WDS_LOGE("Invalid parameter");
1216                 return -1;
1217         }
1218
1219         unsigned long time = 0;
1220 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1221         wfd_util_get_current_time(&time);
1222 #else
1223         struct timeval tval;
1224         gettimeofday(&tval, NULL);
1225         time = tval.tv_sec;
1226 #endif
1227         WDS_LOGI("Current time [%ld]", time);
1228
1229         res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
1230         if (res < 0 || !oem_dev) {
1231                 WDS_LOGE("Failed to get peer information");
1232                 return -1;
1233         }
1234
1235         peer_dev = wfd_peer_find_by_addr(manager, addr);
1236         if (!peer_dev) {
1237                 peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
1238                 if (!peer_dev) {
1239                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1240                         WDS_LOGE("Failed to allocate memory for peer device. [%s]", error_buf);
1241                         free(oem_dev);
1242                         return -1;
1243                 }
1244                 memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
1245                 manager->peers = g_list_prepend(manager->peers, peer_dev);
1246                 manager->peer_count++;
1247                 peer_dev->time = time;
1248                 WDS_LOGD("peer_count[%d]", manager->peer_count);
1249         } else {
1250                 if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
1251                         WDS_LOGE("Too old age to update peer");
1252                         free(oem_dev);
1253                         return -1;
1254                 }
1255         }
1256
1257         g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
1258         memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
1259         memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
1260         peer_dev->dev_role = oem_dev->dev_role;
1261         peer_dev->config_methods = oem_dev->config_methods;
1262         peer_dev->pri_dev_type = oem_dev->pri_dev_type;
1263         peer_dev->sec_dev_type = oem_dev->sec_dev_type;
1264         peer_dev->dev_flags = oem_dev->dev_flags;
1265         peer_dev->group_flags = oem_dev->group_flags;
1266         peer_dev->wps_mode =  oem_dev->wps_mode;
1267
1268 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1269         memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
1270 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1271
1272         peer_dev->time = time;
1273         peer_dev->channel = oem_dev->channel;
1274
1275         free(oem_dev);
1276
1277         peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
1278         if (!(peer_info)) {
1279                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1280                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1281                 return -1;
1282         }
1283
1284         g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
1285         memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
1286         memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
1287         peer_info->channel = peer_dev->channel;
1288 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1289         peer_info->services = 0;
1290 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1291         peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
1292         peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1293         peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
1294         peer_info->wps_device_pwd_id = 0;
1295         peer_info->wps_cfg_methods = peer_dev->config_methods;
1296         peer_info->category = peer_dev->pri_dev_type;
1297         peer_info->subcategory = peer_dev->sec_dev_type;
1298
1299 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1300         if (peer_dev->display.availability && peer_dev->display.port)
1301                 peer_info->is_wfd_device = 1;
1302 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1303
1304         *peer = peer_info;
1305
1306         __WDS_LOG_FUNC_EXIT__;
1307         return res;
1308 }
1309
1310
1311 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
1312 {
1313         __WDS_LOG_FUNC_ENTER__;
1314         GList *temp = NULL;
1315         wfd_device_s *peer = NULL;
1316         wfd_discovery_entry_s *peers = NULL;
1317         int peer_count = 0;
1318         int count = 0;
1319         int res = 0;
1320         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1321
1322         if (!manager || !peers_data) {
1323                 WDS_LOGE("Invalid parameter");
1324                 return -1;
1325         }
1326
1327         unsigned long time = 0;
1328 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1329         wfd_util_get_current_time(&time);
1330 #else
1331         struct timeval tval;
1332         gettimeofday(&tval, NULL);
1333         time = tval.tv_sec;
1334 #endif
1335         WDS_LOGI("Current time [%ld]", time);
1336
1337         peer_count = manager->peer_count;
1338         WDS_LOGI("peer count [%ld]", peer_count);
1339         if (peer_count < 0)
1340                 return -1;
1341         else if (peer_count == 0)
1342                 return 0;
1343
1344         errno = 0;
1345         peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
1346         if (!peers) {
1347                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1348                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1349                 return -1;
1350         }
1351
1352         temp = g_list_first(manager->peers);
1353         while (temp && count < peer_count) {
1354                 peer = temp->data;
1355                 if (!peer)
1356                         goto next;
1357                 if (peer->time + 8 < time) {
1358                         WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
1359                         res = wfd_update_peer(manager, peer);
1360                         if (res < 0) {
1361                                 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
1362                                 temp = g_list_next(temp);
1363                                 manager->peers = g_list_remove(manager->peers, peer);
1364                                 manager->peer_count--;
1365                                 g_free(peer);
1366                                 peer = NULL;
1367                                 continue;
1368                         }
1369                 }
1370
1371                 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1372                 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1373                 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1374                 peers[count].channel = peer->channel;
1375 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1376                 peers[count].services = 0;
1377 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1378                 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1379                 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1380                 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1381                 peers[count].wps_device_pwd_id = 0;
1382                 peers[count].wps_cfg_methods = peer->config_methods;
1383                 peers[count].category = peer->pri_dev_type;
1384                 peers[count].subcategory = peer->sec_dev_type;
1385
1386 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1387                 if (peer->display.availability && peer->display.port)
1388                         peers[count].is_wfd_device = 1;
1389 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1390                 count++;
1391                 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1392 next:
1393                 temp = g_list_next(temp);
1394                 peer = NULL;
1395         }
1396         WDS_LOGD("%d peers converted", count);
1397         WDS_LOGD("Final peer count is %d", manager->peer_count);
1398
1399         *peers_data = peers;
1400
1401         __WDS_LOG_FUNC_EXIT__;
1402         return count;
1403 }
1404
1405 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1406 {
1407         __WDS_LOG_FUNC_ENTER__;
1408         wfd_connected_peer_info_s *peers = NULL;
1409         wfd_group_s *group = NULL;
1410         wfd_device_s *peer = NULL;
1411         GList *temp = NULL;
1412         int peer_count = 0;
1413         int count = 0;
1414         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1415
1416         if (!manager || !peers_data) {
1417                 WDS_LOGE("Invalid parameter");
1418                 return -1;
1419         }
1420
1421         group = manager->group;
1422         if (!group) {
1423                 WDS_LOGE("Group not exist");
1424                 return -1;
1425         }
1426
1427         peer_count = group->member_count;
1428         if (peer_count == 0) {
1429                 WDS_LOGD("Member not exist");
1430                 return 0;
1431         }
1432
1433         errno = 0;
1434         peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
1435         if (!peers) {
1436                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1437                 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", error_buf);
1438                 return -1;
1439         }
1440
1441         temp = g_list_first(group->members);
1442         while (temp && count < group->member_count) {
1443                 peer = temp->data;
1444                 {
1445                         g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1446                         memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1447                         memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1448                         memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1449                         peers[count].category = peer->pri_dev_type;
1450                         peers[count].subcategory = peer->sec_dev_type;
1451                         peers[count].channel = peer->channel;
1452                         peers[count].is_p2p = peer->is_p2p;
1453 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1454                         peers[count].services = 0;
1455 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1456
1457 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1458                         if (peer->display.availability && peer->display.port)
1459                                 peers[count].is_wfd_device = 1;
1460
1461 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1462
1463                         WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1464                         count++;
1465                 }
1466                 temp = g_list_next(temp);
1467                 peer = NULL;
1468         }
1469         WDS_LOGD("%d members converted", count);
1470
1471         *peers_data = peers;
1472
1473         __WDS_LOG_FUNC_EXIT__;
1474         return count;
1475 }
1476
1477 #ifdef TIZEN_FEATURE_ASP
1478 wfd_device_s *wfd_manager_get_connected_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1479 {
1480         __WDS_LOG_FUNC_ENTER__;
1481         wfd_device_s *peer = NULL;
1482
1483         if (peer_addr == NULL) {
1484                 WDS_LOGE("Invalid parameter");
1485                 __WDS_LOG_FUNC_EXIT__;
1486                 return peer;
1487         }
1488
1489         if (manager->group)
1490                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1491
1492         __WDS_LOG_FUNC_EXIT__;
1493         return peer;
1494 }
1495 #endif /* TIZEN_FEATURE_ASP */
1496
1497 #if 0
1498 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1499 {
1500         __WDS_LOG_FUNC_ENTER__;
1501         wfd_device_s *peer = NULL;
1502
1503         if (!manager || !peer_addr) {
1504                 WDS_LOGE("Invalid parameter");
1505                 return NULL;
1506         }
1507
1508         peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1509
1510         __WDS_LOG_FUNC_EXIT__;
1511         return peer;
1512 }
1513 #endif
1514
1515 int wfd_manager_get_goup_ifname(char **ifname)
1516 {
1517         __WDS_LOG_FUNC_ENTER__;
1518         wfd_group_s *group = g_manager->group;
1519
1520         if (!ifname) {
1521                 WDS_LOGE("Invalid parameter");
1522                 __WDS_LOG_FUNC_EXIT__;
1523                 return -1;
1524         }
1525
1526         if (!group) {
1527                 WDS_LOGE("Group not exist");
1528                 return -1;
1529         }
1530
1531         *ifname = group->ifname;
1532
1533         __WDS_LOG_FUNC_EXIT__;
1534         return 0;
1535 }
1536
1537 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1538 int wfd_manager_set_display_device(int type, int port, int hdcp)
1539 {
1540         __WDS_LOG_FUNC_ENTER__;
1541         wfd_device_s * device = g_manager->local;
1542         wfd_oem_display_s display;
1543         int res = 0;
1544
1545         if (!device) {
1546                 WDS_LOGE("Invalid parameter");
1547                 __WDS_LOG_FUNC_EXIT__;
1548                 return -1;
1549         }
1550
1551         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1552
1553         display.type = type;
1554         display.port = port;
1555         display.hdcp_support = hdcp;
1556
1557         display.availability = device->display.availability;
1558         display.max_tput = device->display.max_tput;
1559
1560         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1561         if (res < 0) {
1562                 WDS_LOGE("Failed to set wifi display");
1563                 return -1;
1564         }
1565
1566         device->display.type = type;
1567         device->display.port = port;
1568         device->display.hdcp_support = hdcp;
1569
1570         __WDS_LOG_FUNC_EXIT__;
1571         return res;
1572 }
1573
1574 int wfd_manager_set_session_availability(int availability)
1575 {
1576         __WDS_LOG_FUNC_ENTER__;
1577         wfd_device_s * device = g_manager->local;
1578         wfd_oem_display_s display;
1579         int res = 0;
1580
1581         if (!device) {
1582                 WDS_LOGE("Invalid parameter");
1583                 __WDS_LOG_FUNC_EXIT__;
1584                 return -1;
1585         }
1586
1587         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1588
1589         display.availability = availability;
1590
1591         display.type = device->display.type;
1592         display.hdcp_support = device->display.hdcp_support;
1593         display.port = device->display.port;
1594         display.max_tput = device->display.max_tput;
1595
1596         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1597         if (res < 0) {
1598                 WDS_LOGE("Failed to set wifi display session availability");
1599                 return -1;
1600         }
1601
1602         device->display.availability = availability;
1603
1604         __WDS_LOG_FUNC_EXIT__;
1605         return res;
1606 }
1607
1608 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1609
1610 int wfd_manager_start_discovery(wfd_manager_s *manager, int mode, int timeout,
1611                                 const char* type, int channel)
1612 {
1613         __WDS_LOG_FUNC_ENTER__;
1614         int res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1615         wfd_oem_scan_param_s param;
1616         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
1617
1618         WDS_LOGI("Mode: [%d], Timeout: [%d], type: [%s], channel: [%d]", mode, timeout, type, channel);
1619
1620         if (manager->local->dev_role == WFD_DEV_ROLE_GO)
1621                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1622
1623         if (channel == WFD_DISCOVERY_FULL_SCAN) {
1624                 param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
1625         } else if (channel == WFD_DISCOVERY_SOCIAL_CHANNEL) {
1626                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1627         } else if (channel == WFD_DISCOVERY_CHANNEL1) {
1628                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL1;
1629                 param.freq = 2412;
1630         } else if (channel == WFD_DISCOVERY_CHANNEL6) {
1631                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL6;
1632                 param.freq = 2437;
1633         } else if (channel == WFD_DISCOVERY_CHANNEL11) {
1634                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL11;
1635                 param.freq = 2462;
1636         } else {
1637                 param.scan_type = WFD_OEM_SCAN_TYPE_SPECIFIC;
1638                 param.freq = wfd_util_channel_to_freq(channel);
1639         }
1640
1641         if (mode)
1642                 param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
1643         else
1644                 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
1645
1646         param.scan_time = timeout;
1647
1648         res = wfd_oem_start_scan(manager->oem_ops, &param);
1649         if (res < 0) {
1650                 WDS_LOGE("Failed to start scan");
1651                 __WDS_LOG_FUNC_EXIT__;
1652                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1653         }
1654
1655         if (mode)
1656                 manager->scan_mode = WFD_SCAN_MODE_PASSIVE;
1657         else
1658                 manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
1659
1660         if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
1661                 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
1662                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
1663         }
1664
1665         WDS_LOGD("Succeeded to start scan");
1666         __WDS_LOG_FUNC_EXIT__;
1667         return WIFI_DIRECT_ERROR_NONE;
1668 }
1669
1670 int wfd_manager_cancel_discovery(wfd_manager_s *manager)
1671 {
1672         __WDS_LOG_FUNC_ENTER__;
1673         int res = 0;
1674
1675         res = wfd_oem_stop_scan(manager->oem_ops);
1676         if (res < 0) {
1677                 WDS_LOGE("Failed to stop scan");
1678                 __WDS_LOG_FUNC_EXIT__;
1679                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1680         }
1681
1682         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1683                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1684                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1685         } else {
1686                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1687                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1688         }
1689
1690         WDS_LOGD("Succeeded to stop scan");
1691         __WDS_LOG_FUNC_EXIT__;
1692         return WIFI_DIRECT_ERROR_NONE;
1693 }
1694
1695 wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1696 {
1697         __WDS_LOG_FUNC_ENTER__;
1698         wfd_device_s *peer = NULL;
1699         if (manager->group)
1700                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1701
1702         if (peer)
1703                 return peer;
1704
1705         peer = wfd_peer_find_by_addr(manager, peer_addr);
1706
1707         __WDS_LOG_FUNC_EXIT__;
1708         return peer;
1709 }
1710
1711 static wfd_manager_s *wfd_manager_init()
1712 {
1713         __WDS_LOG_FUNC_ENTER__;
1714         wfd_manager_s *manager = NULL;
1715         int res = 0;
1716
1717         manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
1718         if (!manager) {
1719                 WDS_LOGE("Failed to allocate memory for wfd_manager structure");
1720                 return NULL;
1721         }
1722
1723         manager->go_intent = 7;
1724         manager->req_wps_mode = WFD_WPS_MODE_PBC;
1725         manager->max_station = 8;
1726         manager->session_timer = 120;
1727         manager->auto_group_remove_enable = TRUE;
1728         res = _wfd_local_init_device(manager);
1729         if (res < 0) {
1730                 WDS_LOGE("Failed to initialize local device");
1731                 g_free(manager);
1732                 return NULL;            /* really stop manager? */
1733         }
1734         WDS_LOGD("Succeeded to initialize local device");
1735
1736 #ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
1737         manager->client_count = 0;
1738         manager->client_list = NULL;
1739         manager->exit_timer = g_timeout_add(120000,
1740                                                 (GSourceFunc) _wfd_exit_timeout_cb, manager);
1741         WDS_LOGD("Exit timer started");
1742 #endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
1743
1744         __WDS_LOG_FUNC_EXIT__;
1745         return manager;
1746 }
1747
1748 int wfd_manager_deinit(wfd_manager_s *manager)
1749 {
1750         __WDS_LOG_FUNC_ENTER__;
1751
1752         if (!manager) {
1753                 WDS_LOGE("Invalid parameter");
1754                 __WDS_LOG_FUNC_EXIT__;
1755                 return -1;
1756         }
1757
1758 #ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
1759         if (manager->exit_timer > 0)
1760                 g_source_remove(manager->exit_timer);
1761         manager->exit_timer = 0;
1762 #endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
1763
1764         _wfd_local_deinit_device(manager);
1765
1766         g_free(manager);
1767
1768         __WDS_LOG_FUNC_EXIT__;
1769         return 0;
1770 }
1771
1772 static void *wfd_plugin_init(wfd_manager_s *manager)
1773 {
1774         __WDS_LOG_FUNC_ENTER__;
1775         void *handle;
1776         struct utsname kernel_info;
1777         int res;
1778         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1779
1780         if (!manager) {
1781                 WDS_LOGE("Invalid parameter");
1782                 __WDS_LOG_FUNC_EXIT__;
1783                 return NULL;
1784         }
1785
1786         res = uname(&kernel_info);
1787         if (res) {
1788                 WDS_LOGE("Failed to detect target type");
1789                 __WDS_LOG_FUNC_EXIT__;
1790                 return NULL;
1791         }
1792         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
1793
1794         errno = 0;
1795
1796 #if defined(TIZEN_ARCH_64)
1797         handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
1798 #else
1799         handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
1800 #endif
1801         if (!handle) {
1802                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
1803                 __WDS_LOG_FUNC_EXIT__;
1804                 return NULL;
1805         }
1806
1807         errno = 0;
1808         int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
1809         plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
1810         if (!plugin_load) {
1811                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1812                 WDS_LOGE("Failed to load symbol. Error = [%s]", error_buf);
1813                 dlclose(handle);
1814                 __WDS_LOG_FUNC_EXIT__;
1815                 return NULL;
1816         }
1817
1818         wfd_oem_ops_s *temp_ops;
1819         (*plugin_load)(&temp_ops);
1820         manager->oem_ops = temp_ops;
1821
1822         res = wfd_oem_init(temp_ops);
1823         if (res < 0) {
1824                 WDS_LOGE("Failed to initialize OEM");
1825                 dlclose(handle);
1826                 __WDS_LOG_FUNC_EXIT__;
1827                 return NULL;
1828         }
1829         WDS_LOGD("Succeeded to initialize OEM");
1830
1831         __WDS_LOG_FUNC_EXIT__;
1832         return handle;
1833 }
1834
1835 static int wfd_plugin_deinit(wfd_manager_s *manager)
1836 {
1837         __WDS_LOG_FUNC_ENTER__;
1838
1839         if (!manager || !manager->plugin_handle) {
1840                 WDS_LOGE("Invalid parameter");
1841                 __WDS_LOG_FUNC_EXIT__;
1842                 return -1;
1843         }
1844
1845         dlclose(manager->plugin_handle);
1846         manager->plugin_handle = NULL;
1847
1848         __WDS_LOG_FUNC_EXIT__;
1849         return 0;
1850 }
1851
1852 #if defined TIZEN_ENABLE_PRD
1853 static void *wfd_prd_plugin_init(wfd_manager_s *manager)
1854 {
1855         __WDS_LOG_FUNC_ENTER__;
1856         void *handle;
1857         struct utsname kernel_info;
1858         int res;
1859
1860         if (!manager) {
1861                 WDS_LOGE("Invalid parameter");
1862                 __WDS_LOG_FUNC_EXIT__;
1863                 return NULL;
1864         }
1865
1866         res = uname(&kernel_info);
1867         if (res) {
1868                 WDS_LOGE("Failed to detect target type");
1869                 __WDS_LOG_FUNC_EXIT__;
1870                 return NULL;
1871         }
1872         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
1873
1874         errno = 0;
1875
1876 #if defined(TIZEN_ARCH_64)
1877         handle = dlopen(SUPPL_PRD_PLUGIN_64BIT_PATH, RTLD_NOW);
1878 #else
1879         handle = dlopen(SUPPL_PRD_PLUGIN_PATH, RTLD_NOW);
1880 #endif
1881         if (!handle) {
1882                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
1883                 __WDS_LOG_FUNC_EXIT__;
1884                 return NULL;
1885         }
1886
1887         errno = 0;
1888         int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
1889         plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_prd_plugin_load");
1890         if (!plugin_load) {
1891                 WDS_LOGE("Failed to load symbol. Error = [%s]", strerror(errno));
1892                 dlclose(handle);
1893                 __WDS_LOG_FUNC_EXIT__;
1894                 return NULL;
1895         }
1896
1897         (*plugin_load)((wfd_oem_ops_s **)&manager->oem_ops);
1898
1899         res = wfd_oem_prd_init((wfd_oem_ops_s *)manager->oem_ops);
1900         if (res < 0) {
1901                 WDS_LOGE("Failed to initialize PRD OEM");
1902                 dlclose(handle);
1903                 __WDS_LOG_FUNC_EXIT__;
1904                 return NULL;
1905         }
1906         WDS_LOGD("Succeeded to initialize PRD OEM");
1907
1908         __WDS_LOG_FUNC_EXIT__;
1909         return handle;
1910 }
1911
1912 static int wfd_prd_plugin_deinit(wfd_manager_s *manager)
1913 {
1914         __WDS_LOG_FUNC_ENTER__;
1915
1916         if (!manager || !manager->prd_plugin_handle) {
1917                 WDS_LOGE("Invalid parameter");
1918                 __WDS_LOG_FUNC_EXIT__;
1919                 return -1;
1920         }
1921
1922         dlclose(manager->prd_plugin_handle);
1923         manager->prd_plugin_handle = NULL;
1924
1925         __WDS_LOG_FUNC_EXIT__;
1926         return 0;
1927 }
1928 #endif /* TIZEN_ENABLE_PRD */
1929
1930 int main(int argc, char *argv[])
1931 {
1932         __WDS_LOG_FUNC_ENTER__;
1933         GMainLoop *main_loop = NULL;
1934
1935 #if !GLIB_CHECK_VERSION(2, 32, 0)
1936         if (!g_thread_supported())
1937                 g_thread_init(NULL);
1938 #endif
1939
1940 #if !GLIB_CHECK_VERSION(2, 36, 0)
1941         g_type_init();
1942 #endif
1943
1944         /* TODO: Parsing argument */
1945         /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1946
1947         /**
1948          * wfd-manager initialization
1949          */
1950         g_manager = wfd_manager_init();
1951         if (!g_manager) {
1952                 WDS_LOGE("Failed to initialize wifi-direct manager");
1953                 __WDS_LOG_FUNC_EXIT__;
1954                 return -1;
1955         }
1956         WDS_LOGD("Succeeded to initialize manager");
1957
1958         /**
1959          * wfd_manager_plugin initialization
1960          */
1961         g_manager->plugin_handle = wfd_plugin_init(g_manager);
1962         if (!g_manager->plugin_handle) {
1963                 WDS_LOGE("Failed to initialize plugin");
1964                 wfd_manager_deinit(g_manager);
1965                 __WDS_LOG_FUNC_EXIT__;
1966                 return -1;
1967         }
1968         WDS_LOGD("Succeeded to load plugin");
1969
1970 #if defined TIZEN_ENABLE_PRD
1971         /**
1972          * wfd_manager_prd_plugin initialization
1973          */
1974         g_manager->prd_plugin_handle = wfd_prd_plugin_init(g_manager);
1975         if (!g_manager->prd_plugin_handle)
1976                 WDS_LOGW("Failed to initialize prd plugin");
1977         else
1978                 WDS_LOGD("Succeeded to load plugin");
1979 #endif /* TIZEN_ENABLE_PRD */
1980
1981         if (!wfd_manager_dbus_init()) {
1982                 WDS_LOGE("Failed to DBus");
1983                 wfd_plugin_deinit(g_manager);
1984                 wfd_manager_deinit(g_manager);
1985                 __WDS_LOG_FUNC_EXIT__;
1986                 return -1;
1987         }
1988
1989         main_loop = g_main_loop_new(NULL, FALSE);
1990         if (main_loop == NULL) {
1991                 WDS_LOGE("Failed to create GMainLoop structure");
1992                 __WDS_LOG_FUNC_EXIT__;
1993                 return -1;
1994         }
1995         g_manager->main_loop = main_loop;
1996         g_main_loop_run(main_loop);
1997
1998 #ifdef TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND
1999         wfd_manager_dbus_unregister_nameowner_signal();
2000 #endif/* TIZEN_FEATURE_WIFI_DIRECT_ON_DEMAND */
2001
2002         wfd_manager_dbus_unregister();
2003         wfd_manager_dbus_deinit();
2004
2005 #if defined TIZEN_ENABLE_PRD
2006         wfd_prd_plugin_deinit(g_manager);
2007 #endif /* TIZEN_ENABLE_PRD */
2008
2009         wfd_plugin_deinit(g_manager);
2010         wfd_manager_deinit(g_manager);
2011
2012         __WDS_LOG_FUNC_EXIT__;
2013         return 0;
2014 }