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