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