[wifi-direct-manager]Add compile flag for 64 Bit architecture
[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 #include <wifi-direct.h>
38
39 #include "wifi-direct-ipc.h"
40 #include "wifi-direct-manager.h"
41 #include "wifi-direct-oem.h"
42 #include "wifi-direct-session.h"
43 #include "wifi-direct-group.h"
44 #include "wifi-direct-peer.h"
45 #include "wifi-direct-state.h"
46 #include "wifi-direct-client.h"
47 #include "wifi-direct-event.h"
48 #include "wifi-direct-util.h"
49
50 wfd_manager_s *g_manager;
51
52 wfd_manager_s *wfd_get_manager()
53 {
54         return g_manager;
55 }
56
57 static gboolean _wfd_exit_timeout_cb(void *user_data)
58 {
59         __WDS_LOG_FUNC_ENTER__;
60         wfd_manager_s *manager = (wfd_manager_s*) user_data;
61
62         if (!manager) {
63                 WDS_LOGE("Invalid parameter");
64                 return TRUE;
65         }
66
67         if (manager->client_count > 0) {
68                 WDS_LOGD("Client count [%d]", manager->client_count);
69                 return TRUE;
70         }
71
72         if (manager->state == WIFI_DIRECT_STATE_DEACTIVATED) {
73                 WDS_LOGD("Terminate Wi-Fi Direct Manager");
74                 g_main_quit(manager->main_loop);
75         }
76         manager->exit_timer = 0;
77         WDS_LOGD( "Stop exit timer. State [%d]", manager->state);
78
79         __WDS_LOG_FUNC_EXIT__;
80         return FALSE;
81 }
82
83 static int _wfd_local_init_device(wfd_manager_s *manager)
84 {
85         __WDS_LOG_FUNC_ENTER__;
86         wfd_device_s *local = NULL;
87         int res = 0;
88
89         if (!manager) {
90                 WDS_LOGE("Invalid parameter");
91                 return -1;
92         }
93
94         errno = 0;
95         local = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
96         if (!local) {
97                 WDS_LOGE("Failed to allocate memory for local device [%s]", strerror(errno));
98                 return -1;
99         }
100
101         res = wfd_util_get_phone_name(local->dev_name);
102         if (res < 0) {
103                 WDS_LOGE("Failed to get phone name of local device. Use default device name");
104                 g_strlcpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN + 1);
105         }
106         WDS_LOGD("Local Device name [%s]", local->dev_name);
107         wfd_util_set_dev_name_notification();
108
109         res = wfd_util_get_local_dev_mac(local->dev_addr);
110         if (res < 0) {
111                 WDS_LOGE("Failed to get local device MAC address");
112         }
113
114         memcpy(local->intf_addr, local->dev_addr, MACADDR_LEN);
115         local->intf_addr[4] ^= 0x80;
116         WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
117                                         MAC2SECSTR(local->intf_addr));
118
119         local->config_methods = WFD_WPS_MODE_PBC | WFD_WPS_MODE_DISPLAY | WFD_WPS_MODE_KEYPAD;
120         local->wps_mode = WFD_WPS_MODE_PBC;
121 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
122         local->services = NULL;
123         local->service_count = 0;
124 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
125         // TODO: initialize other local device datas
126         manager->local = local;
127
128         __WDS_LOG_FUNC_EXIT__;
129         return 0;
130 }
131
132 static int _wfd_local_deinit_device(wfd_manager_s *manager)
133 {
134         __WDS_LOG_FUNC_ENTER__;
135
136         if (!manager) {
137                 WDS_LOGE("Invalid parameter");
138                 return -1;
139         }
140
141         wfd_util_unset_dev_name_notification();
142
143         // TODO: free member of local device
144         g_free(manager->local);
145
146         __WDS_LOG_FUNC_EXIT__;
147         return 0;
148 }
149
150 int wfd_local_reset_data(wfd_manager_s *manager)
151 {
152         __WDS_LOG_FUNC_ENTER__;
153         wfd_device_s *local = NULL;
154
155         if (!manager) {
156                 WDS_LOGE("Invalid parameter");
157                 return -1;
158         }
159
160         local = manager->local;
161         /* init local device data */
162         local->dev_role = WFD_DEV_ROLE_NONE;
163         local->wps_mode = WFD_WPS_MODE_PBC;
164         memset(local->go_dev_addr, 0x0, MACADDR_LEN);
165 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
166         memset(&(local->display), 0x0, sizeof(wfd_display_s));
167 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
168         memset(local->ip_addr, 0x0, IPADDR_LEN);
169
170         __WDS_LOG_FUNC_EXIT__;
171         return 0;
172 }
173
174 int wfd_local_get_dev_name(char *dev_name)
175 {
176         __WDS_LOG_FUNC_ENTER__;
177         wfd_device_s *local = g_manager->local;
178
179         if (!dev_name) {
180                 WDS_LOGE("Invalid parameter");
181                 __WDS_LOG_FUNC_EXIT__;
182                 return -1;
183         }
184
185         g_strlcpy(dev_name, local->dev_name, DEV_NAME_LEN + 1);
186         WDS_LOGD("Local device name [%s]", dev_name);
187
188         __WDS_LOG_FUNC_EXIT__;
189         return 0;
190 }
191
192 int wfd_local_set_dev_name(char *dev_name)
193 {
194         __WDS_LOG_FUNC_ENTER__;
195         wfd_device_s *local = g_manager->local;
196
197         if (!dev_name) {
198                 WDS_LOGE("Invalid parameter");
199                 __WDS_LOG_FUNC_EXIT__;
200                 return -1;
201         }
202
203         g_strlcpy(local->dev_name, dev_name, DEV_NAME_LEN + 1);
204
205         if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED) {
206                 wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
207                 WDS_LOGD("Device name changed.");
208         } else {
209                 WDS_LOGE("Device name can't changed: state is %d",g_manager->state);
210         }
211
212         __WDS_LOG_FUNC_EXIT__;
213         return 0;
214 }
215
216 int wfd_local_get_dev_mac(char *dev_mac)
217 {
218         __WDS_LOG_FUNC_ENTER__;
219         wfd_device_s *local = g_manager->local;
220
221         if (!dev_mac) {
222                 WDS_LOGE("Invalid parameter");
223                 __WDS_LOG_FUNC_EXIT__;
224                 return -1;
225         }
226
227         g_snprintf(dev_mac, MACSTR_LEN, MACSTR, MAC2STR(local->dev_addr));
228         WDS_SECLOGD("Local device MAC address [%s]", dev_mac);
229
230         __WDS_LOG_FUNC_EXIT__;
231         return 0;
232 }
233
234 #if 0
235 int wfd_local_get_intf_mac(unsigned char *intf_mac)
236 {
237         __WDS_LOG_FUNC_ENTER__;
238         wfd_device_s *local = g_manager->local;
239
240         if (!intf_mac) {
241                 WDS_LOGE("Invalid parameter");
242                 __WDS_LOG_FUNC_EXIT__;
243                 return -1;
244         }
245
246         g_snprintf(intf_mac, MACSTR_LEN, MACSTR, MAC2STR(local->intf_addr));
247         WDS_SECLOGD("Local interface MAC address [%s]", intf_mac);
248
249         __WDS_LOG_FUNC_EXIT__;
250         return 0;
251 }
252 #endif
253
254 int wfd_local_get_ip_addr(char *ip_str)
255 {
256         __WDS_LOG_FUNC_ENTER__;
257         wfd_device_s *local = g_manager->local;
258
259         if (!ip_str) {
260                 WDS_LOGE("Invalid parameter");
261                 __WDS_LOG_FUNC_EXIT__;
262                 return -1;
263         }
264
265         snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(local->ip_addr));
266         WDS_SECLOGD("Local IP address [" IPSECSTR "]", IP2SECSTR(local->ip_addr));
267
268         __WDS_LOG_FUNC_EXIT__;
269         return 0;
270 }
271
272 int wfd_local_get_supported_wps_mode(int *config_methods)
273 {
274         __WDS_LOG_FUNC_ENTER__;
275         wfd_device_s *local = g_manager->local;
276
277         if (!config_methods) {
278                 WDS_LOGE("Invalid parameter");
279                 __WDS_LOG_FUNC_EXIT__;
280                 return -1;
281         }
282
283         *config_methods = local->config_methods;
284         WDS_LOGD("Local config method [0x%x]", *config_methods);
285
286         __WDS_LOG_FUNC_EXIT__;
287         return 0;
288 }
289
290 int wfd_local_get_wps_mode(int *wps_mode)
291 {
292         __WDS_LOG_FUNC_ENTER__;
293         wfd_device_s *local = g_manager->local;
294
295         if (!wps_mode) {
296                 WDS_LOGE("Invalid parameter");
297                 __WDS_LOG_FUNC_EXIT__;
298                 return -1;
299         }
300
301         *wps_mode = local->wps_mode;
302         WDS_LOGD("Local wps mode [0x%x]", *wps_mode);
303
304         __WDS_LOG_FUNC_EXIT__;
305         return 0;
306 }
307
308 #if 0
309 int wfd_local_set_wps_mode(int wps_mode)
310 {
311         __WDS_LOG_FUNC_ENTER__;
312         wfd_device_s *local = g_manager->local;
313
314         if (!wps_mode) {
315                 WDS_LOGE("Invalid parameter");
316                 __WDS_LOG_FUNC_EXIT__;
317                 return -1;
318         }
319
320         local->wps_mode = wps_mode;
321         WDS_LOGD("Local wps mode [0x%x]", wps_mode);
322
323         __WDS_LOG_FUNC_EXIT__;
324         return 0;
325 }
326 #endif
327
328 int wfd_manager_get_go_intent(int *go_intent)
329 {
330         __WDS_LOG_FUNC_ENTER__;
331         if (!go_intent) {
332                 WDS_LOGE("Invalid parameter");
333                 __WDS_LOG_FUNC_EXIT__;
334                 return -1;
335         }
336
337         *go_intent = g_manager->go_intent;
338         WDS_LOGD("Local GO intent [%d]", *go_intent);
339
340         __WDS_LOG_FUNC_EXIT__;
341         return 0;
342 }
343
344 int wfd_manager_set_go_intent(int go_intent)
345 {
346         __WDS_LOG_FUNC_ENTER__;
347
348         if (go_intent < 0 || go_intent > 15) {
349                 WDS_LOGE("Invalid parameter");
350                 __WDS_LOG_FUNC_EXIT__;
351                 return -1;
352         }
353
354         g_manager->go_intent = go_intent;
355         if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED)
356                 wfd_oem_set_go_intent(g_manager->oem_ops, go_intent);
357
358         __WDS_LOG_FUNC_EXIT__;
359         return 0;
360 }
361
362 int wfd_manager_get_max_station(int *max_station)
363 {
364         __WDS_LOG_FUNC_ENTER__;
365
366         if (!max_station) {
367                 WDS_LOGE("Invalid parameter");
368                 __WDS_LOG_FUNC_EXIT__;
369                 return -1;
370         }
371
372         *max_station = g_manager->max_station;
373         WDS_LOGD("Local max station[%d]", *max_station);
374
375         __WDS_LOG_FUNC_EXIT__;
376         return 0;
377 }
378
379 int wfd_manager_set_max_station(int max_station)
380 {
381         __WDS_LOG_FUNC_ENTER__;
382
383         if (max_station < 1) {
384                 WDS_LOGE("Invalid parameter");
385                 __WDS_LOG_FUNC_EXIT__;
386                 return -1;
387         }
388
389         g_manager->max_station = max_station;
390
391         __WDS_LOG_FUNC_EXIT__;
392         return 0;
393 }
394
395 int wfd_manager_get_autoconnection(int *autoconnection)
396 {
397         __WDS_LOG_FUNC_ENTER__;
398         if (!autoconnection) {
399                 WDS_LOGE("Invalid parameter");
400                 __WDS_LOG_FUNC_EXIT__;
401                 return -1;
402         }
403
404         *autoconnection = g_manager->autoconnection;
405         WDS_LOGD("Local autoconnection [%s]", *autoconnection ? "TRUE":"FALSE");
406
407         __WDS_LOG_FUNC_EXIT__;
408         return 0;
409 }
410
411 int wfd_manager_set_autoconnection(int autoconnection)
412 {
413         __WDS_LOG_FUNC_ENTER__;
414         if (autoconnection < 0) {
415                 WDS_LOGE("Invalid parameter");
416                 __WDS_LOG_FUNC_EXIT__;
417                 return -1;
418         }
419
420         g_manager->autoconnection = autoconnection;
421
422         __WDS_LOG_FUNC_EXIT__;
423         return 0;
424 }
425
426 int wfd_manager_get_req_wps_mode(int *req_wps_mode)
427 {
428         __WDS_LOG_FUNC_ENTER__;
429
430         if (!req_wps_mode) {
431                 WDS_LOGE("Invalid parameter");
432                 __WDS_LOG_FUNC_EXIT__;
433                 return -1;
434         }
435
436         *req_wps_mode = g_manager->req_wps_mode;
437         WDS_LOGD("Requested wps mode [0x%x]", *req_wps_mode);
438
439         __WDS_LOG_FUNC_EXIT__;
440         return 0;
441 }
442
443 int wfd_manager_set_req_wps_mode(int req_wps_mode)
444 {
445         __WDS_LOG_FUNC_ENTER__;
446         wfd_device_s *local = g_manager->local;
447
448         if (req_wps_mode != WIFI_DIRECT_WPS_TYPE_PBC &&
449                         req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY &&
450                         req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD) {
451                 WDS_LOGE("Invalid parameter");
452                 __WDS_LOG_FUNC_EXIT__;
453                 return -1;
454         }
455
456         g_manager->req_wps_mode = req_wps_mode;
457         WDS_LOGD("Requested wps mode [0x%x]", req_wps_mode);
458         if (req_wps_mode == WFD_WPS_MODE_DISPLAY)
459                 local->wps_mode = WFD_WPS_MODE_KEYPAD;
460         else if (req_wps_mode == WFD_WPS_MODE_KEYPAD)
461                 local->wps_mode = WFD_WPS_MODE_DISPLAY;
462         else
463                 local->wps_mode = req_wps_mode;
464
465         __WDS_LOG_FUNC_EXIT__;
466         return 0;
467 }
468
469 int wfd_manager_local_config_set(wfd_manager_s *manager)
470 {
471         __WDS_LOG_FUNC_ENTER__;
472         wfd_device_s *local = NULL;
473         int res = 0;
474
475         if (!manager) {
476                 WDS_LOGE("Invalid parameter");
477                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
478         }
479
480         local = manager->local;
481
482         local->wps_mode = WFD_WPS_MODE_PBC;
483         WDS_LOGD("Device name set as %s", local->dev_name);
484         res = wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
485         if (res < 0) {
486                 WDS_LOGE("Failed to set device name");
487                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
488         }
489
490         res = wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
491         if (res < 0) {
492                 WDS_LOGE("Failed to set device type");
493                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
494         }
495
496         res = wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
497         if (res < 0) {
498                 WDS_LOGE("Failed to set go intent");
499                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
500         }
501
502         return WIFI_DIRECT_ERROR_NONE;
503 }
504
505 int wfd_manager_activate(wfd_manager_s *manager)
506 {
507         __WDS_LOG_FUNC_ENTER__;
508         int prev_state = 0;
509         int res = 0;
510
511         if (!manager) {
512                 WDS_LOGE("Invalid parameter");
513                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
514         }
515
516         if (manager->state > WIFI_DIRECT_STATE_ACTIVATING) {
517                 WDS_LOGE("Already activated");
518                 return 1;
519         }
520
521         wfd_state_get(manager, &prev_state);
522         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
523 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_MOBILE)
524         res = wfd_util_check_wifi_state();
525         if (res < 0) {
526                 WDS_LOGE("Failed to get wifi state");
527                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
528         } else if (res == 0) {
529 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_MOBILE */
530         res = wfd_oem_activate(manager->oem_ops, 0);
531         if (res < 0) {
532                 WDS_LOGE("Failed to activate");
533                 wfd_state_set(manager, prev_state);
534                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
535         }
536 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_MOBILE)
537         } else {
538                 res = wfd_oem_activate(manager->oem_ops, res);
539                 if (res < 0) {
540                         WDS_LOGE("Failed to activate");
541                         wfd_state_set(manager, prev_state);
542                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
543                 }
544         }
545 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_MOBILE */
546         WDS_LOGE("Succeeded to activate");
547
548         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
549         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
550
551         wfd_manager_local_config_set(manager);
552         wfd_util_set_country();
553
554         wfd_util_start_wifi_direct_popup();
555
556         res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
557         if (res < 0) {
558                 WDS_LOGE("Failed to get local device MAC address");
559         }
560
561         memcpy(manager->local->intf_addr, manager->local->dev_addr, MACADDR_LEN);
562         manager->local->intf_addr[4] ^= 0x80;
563         WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
564                                         MAC2SECSTR(manager->local->intf_addr));
565
566         __WDS_LOG_FUNC_EXIT__;
567         return WIFI_DIRECT_ERROR_NONE;
568 }
569
570 int wfd_manager_deactivate(wfd_manager_s *manager)
571 {
572         __WDS_LOG_FUNC_ENTER__;
573         int prev_state = 0;
574         int res = 0;
575
576         if (!manager) {
577                 WDS_LOGE("Invalid parameter");
578                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
579         }
580
581         if (manager->state < WIFI_DIRECT_STATE_ACTIVATING) {
582                 WDS_LOGE("Already deactivated");
583                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
584         }
585
586         wfd_state_get(manager, &prev_state);
587         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
588
589 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
590         res = wfd_oem_miracast_init(manager->oem_ops, false);
591         if (res < 0)
592                 WDS_LOGE("Failed to initialize miracast");
593 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
594
595         res = wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
596         if (res < 0)
597                 WDS_LOGE("Failed to destroy group before deactivation");
598
599 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_MOBILE)
600         res = wfd_util_check_wifi_state();
601         if (res < 0) {
602                 WDS_LOGE("Failed to get wifi state");
603                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
604         } else if (res == 0) {
605 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_MOBILE */
606                 res = wfd_oem_deactivate(manager->oem_ops, 0);
607                 if (res < 0) {
608                         WDS_LOGE("Failed to deactivate");
609                         wfd_state_set(manager, prev_state);
610                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
611                 }
612 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_MOBILE)
613         } else {
614                 // FIXME: We should do something to stop p2p feature of Driver
615                 res = wfd_oem_deactivate(manager->oem_ops, res);
616                 if (res < 0) {
617                         WDS_LOGE("Failed to deactivate");
618                         wfd_state_set(manager, prev_state);
619                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
620                 }
621                 WDS_LOGE("Do not need to deactivate Wi-Fi");
622         }
623 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_MOBILE */
624         WDS_LOGE("Succeeded to deactivate");
625
626         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
627         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
628
629         manager->req_wps_mode = WFD_WPS_MODE_PBC;
630
631         wfd_destroy_group(manager, GROUP_IFNAME);
632         wfd_destroy_session(manager);
633         wfd_peer_clear_all(manager);
634         wfd_local_reset_data(manager);
635
636         __WDS_LOG_FUNC_EXIT__;
637         return WIFI_DIRECT_ERROR_NONE;
638 }
639
640 int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
641 {
642         __WDS_LOG_FUNC_ENTER__;
643         wfd_session_s *session = NULL;
644         int res = 0;
645
646         if (!manager || !peer_addr) {
647                 WDS_LOGE("Invalid parameter");
648                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
649         }
650
651         session = (wfd_session_s*) manager->session;
652         if (session && session->type != SESSION_TYPE_INVITE) {
653                 WDS_LOGE("Session already exist and it's not an invitation session");
654                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
655         }
656
657         if (!session) {
658                 session = wfd_create_session(manager, peer_addr,
659                                         manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
660                 if (!session) {
661                         WDS_LOGE("Failed to create new session");
662                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
663                 }
664         }
665
666         if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
667                         session->type != SESSION_TYPE_INVITE) {
668                 session->type = SESSION_TYPE_INVITE;
669                 res = wfd_session_invite(session);
670         } else {
671                 res = wfd_session_start(session);
672         }
673         if (res < 0) {
674                 WDS_LOGE("Failed to start session");
675                 wfd_destroy_session(manager);
676                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
677         }
678         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
679
680         __WDS_LOG_FUNC_EXIT__;
681         return WIFI_DIRECT_ERROR_NONE;
682 }
683
684 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
685 {
686         __WDS_LOG_FUNC_ENTER__;
687         wfd_session_s *session = NULL;
688         wfd_device_s *peer = NULL;
689         int res = 0;
690
691         if (!manager || !peer_addr) {
692                 WDS_LOGE("Invalid parameter");
693                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
694         }
695
696         session = (wfd_session_s*) manager->session;
697         if (!session) {
698                 WDS_LOGE("Session not found");
699                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
700         }
701
702         peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
703         if (!peer) {
704                 WDS_LOGE("Peer is NULL");
705                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
706         }
707
708         // TODO: check peer_addr with session's peer_addr
709
710         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
711                 WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
712                 res = wfd_session_wps(session);
713         } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
714                 WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");
715                 if (session->type == SESSION_TYPE_INVITE) {
716                         if (session->state == SESSION_STATE_CREATED) {
717                                 WDS_LOGD("Invitation session. PD will be started");
718                                 res = wfd_session_start(session);
719                         } else {
720                                 WDS_LOGD("Invitation session. Join will be started");
721                                 res = wfd_session_join(session);
722                         }
723                 } else {
724                         if (manager->autoconnection && (manager->auto_pin[0] != 0))
725                                 g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
726
727                         WDS_LOGD("Peer device is GO, so WPS will be started");
728                         res = wfd_session_connect(session);
729                 }
730         } else {
731                 /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
732                 /* Otherwise, GO Nego is sometimes failed. */
733                 if (manager->autoconnection == FALSE) {
734                         WDS_LOGD("My device is Device, so Negotiation will be started");
735                         res = wfd_session_connect(session);
736                 }
737         }
738         if (res < 0) {
739                 WDS_LOGE("Failed to start session");
740                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
741                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
742                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
743                 } else {
744                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
745                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
746                 }
747                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
748         }
749         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
750
751         __WDS_LOG_FUNC_EXIT__;
752         return WIFI_DIRECT_ERROR_NONE;
753 }
754
755
756 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
757 {
758         __WDS_LOG_FUNC_ENTER__;
759         wfd_group_s *group = NULL;
760         int res = 0;
761
762         if (!manager || !peer_addr) {
763                 WDS_LOGE("Invalid parameter");
764                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
765         }
766
767         res = wfd_session_cancel(manager->session, peer_addr);
768         if (res < 0) {
769                 WDS_LOGE("Failed to cancel session");
770                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
771         }
772
773         if (manager->local->dev_role != WFD_DEV_ROLE_GO)
774                 wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
775
776         group = (wfd_group_s*) manager->group;
777         if (group) {
778                 wfd_group_remove_member(group, peer_addr);
779                 if ((wfd_group_is_autonomous(manager->group) != TRUE) && !group->member_count) {
780                         wfd_oem_destroy_group(manager->oem_ops, group->ifname);
781                         wfd_destroy_group(manager, group->ifname);
782                 } else {
783                         wfd_oem_disconnect(manager->oem_ops, peer_addr);
784                 }
785         }
786
787         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
788                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
789                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
790         } else {
791                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
792                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
793         }
794
795         __WDS_LOG_FUNC_EXIT__;
796         return WIFI_DIRECT_ERROR_NONE;
797 }
798
799
800 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
801 {
802         __WDS_LOG_FUNC_ENTER__;
803         wfd_session_s *session = NULL;
804         int res = 0;
805
806         if (!manager || !peer_addr) {
807                 WDS_LOGE("Invalid parameter");
808                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
809         }
810
811         session = (wfd_session_s*) manager->session;
812         if (!session) {
813                 WDS_LOGE("Session not found");
814                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
815         }
816
817         res = wfd_session_reject(session, peer_addr);
818         if (res < 0) {
819                 WDS_LOGE("Failed to reject connection");
820                 // TODO: check whether set state and break
821         }
822         wfd_destroy_session(manager);
823
824         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
825                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
826                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
827         } else {
828                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
829                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
830         }
831
832         __WDS_LOG_FUNC_EXIT__;
833         return WIFI_DIRECT_ERROR_NONE;
834 }
835
836
837 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
838 {
839         __WDS_LOG_FUNC_ENTER__;
840         wfd_group_s *group = NULL;
841         wfd_device_s *peer = NULL;
842         int res = 0;
843
844         if (!manager) {
845                 WDS_LOGE("Invalid parameter");
846                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
847         }
848
849         if (!peer_addr) {
850                 WDS_LOGE("Invalid parameter");
851                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
852         }
853
854         group = (wfd_group_s*) manager->group;
855         if (!group) {
856                 WDS_LOGE("Group not found");
857                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
858         }
859
860         peer = wfd_group_find_member_by_addr(group, peer_addr);
861         if (!peer) {
862                 WDS_LOGE("Connected peer not found");
863                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
864         }
865
866         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
867
868         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
869 #ifdef CTRL_IFACE_DBUS
870                 /* dbus using device address to identify the peer */
871                 res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr);
872 #else /* CTRL_IFACE_DBUS */
873                 res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr);
874 #endif /* CTRL_IFACE_DBUS */
875         } else {
876                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
877         }
878         if (res < 0) {
879                 WDS_LOGE("Failed to disconnect peer");
880                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
881                 goto failed;
882         }
883         WDS_LOGE("Succeeded to disconnect peer");
884
885         wfd_group_remove_member(group, peer_addr);
886         if (!group->member_count) {
887                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
888                 wfd_destroy_group(manager, group->ifname);
889         }
890
891         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
892                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
893                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
894         } else {
895                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
896                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
897         }
898
899         __WDS_LOG_FUNC_EXIT__;
900         return WIFI_DIRECT_ERROR_NONE;
901
902 failed:
903         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
904                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
905                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
906         } else {
907                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
908                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
909         }
910
911         __WDS_LOG_FUNC_EXIT__;
912         return res;
913 }
914
915 int wfd_manager_disconnect_all(wfd_manager_s *manager)
916 {
917         __WDS_LOG_FUNC_ENTER__;
918         wfd_group_s *group = NULL;
919         int res = 0;
920
921         if (!manager) {
922                 WDS_LOGE("Invalid parameter");
923                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
924         }
925
926         group = (wfd_group_s*) manager->group;
927         if (!group) {
928                 WDS_LOGE("Group not found");
929                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
930         }
931
932         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
933
934         res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
935         if (res < 0) {
936                 WDS_LOGE("Failed to destroy group");
937                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
938                 goto failed;
939         }
940         WDS_LOGE("Succeeded to disconnect all peer");
941
942         wfd_destroy_group(manager, group->ifname);
943
944         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
945         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
946
947         __WDS_LOG_FUNC_EXIT__;
948         return WIFI_DIRECT_ERROR_NONE;
949
950 failed:
951         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
952                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
953                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
954         } else {
955                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
956                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
957         }
958
959         __WDS_LOG_FUNC_EXIT__;
960         return res;
961 }
962
963 int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
964 {
965         __WDS_LOG_FUNC_ENTER__;
966         wfd_device_s *peer_dev = NULL;
967         wfd_discovery_entry_s *peer_info;
968         wfd_oem_device_s *oem_dev = NULL;
969         int res = 0;
970
971         if (!manager || !addr) {
972                 WDS_LOGE("Invalid parameter");
973                 return -1;
974         }
975
976         unsigned long time = 0;
977 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
978         wfd_util_get_current_time(&time);
979 #else
980         struct timeval tval;
981         gettimeofday(&tval, NULL);
982         time = tval.tv_sec;
983 #endif
984         WDS_LOGI("Current time [%ld]", time);
985
986         res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
987         if (res < 0 || !oem_dev) {
988                 WDS_LOGE("Failed to get peer information");
989                 return -1;
990         }
991
992         peer_dev = wfd_peer_find_by_addr(manager, addr);
993         if(!peer_dev) {
994                 peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
995                 if (!peer_dev) {
996                         WDS_LOGE("Failed to allocate memory for peer device. [%s]", strerror(errno));
997                         free(oem_dev);
998                         return -1;
999                 }
1000                 memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
1001                 manager->peers = g_list_prepend(manager->peers, peer_dev);
1002                 manager->peer_count++;
1003                 peer_dev->time = time;
1004                 WDS_LOGD("peer_count[%d]", manager->peer_count);
1005         } else {
1006                 if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
1007                         WDS_LOGE("Too old age to update peer");
1008                         free(oem_dev);
1009                         return -1;
1010                 }
1011         }
1012
1013         g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
1014         memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
1015         memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
1016         peer_dev->dev_role = oem_dev->dev_role;
1017         peer_dev->config_methods = oem_dev->config_methods;
1018         peer_dev->pri_dev_type = oem_dev->pri_dev_type;
1019         peer_dev->sec_dev_type = oem_dev->sec_dev_type;
1020         peer_dev->dev_flags = oem_dev->dev_flags;
1021         peer_dev->group_flags = oem_dev->group_flags;
1022         peer_dev->wps_mode =  oem_dev->wps_mode;
1023
1024 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1025         memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
1026 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1027
1028         peer_dev->time = time;
1029         peer_dev->channel = oem_dev->channel;
1030
1031         free(oem_dev);
1032
1033         peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
1034         if (!(peer_info)) {
1035                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
1036                 return -1;
1037         }
1038
1039         g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
1040         memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
1041         memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
1042         peer_info->channel = peer_dev->channel;
1043 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1044         peer_info->services = 0;
1045 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1046         peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
1047         peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1048         peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
1049         peer_info->wps_device_pwd_id = 0;
1050         peer_info->wps_cfg_methods = peer_dev->config_methods;
1051         peer_info->category = peer_dev->pri_dev_type;
1052         peer_info->subcategory = peer_dev->sec_dev_type;
1053
1054 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1055         if (peer_dev->display.availablity && peer_dev->display.port)
1056                 peer_info->is_wfd_device = 1;
1057 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1058
1059         *peer = peer_info;
1060
1061         __WDS_LOG_FUNC_EXIT__;
1062         return res;
1063 }
1064
1065
1066 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
1067 {
1068         __WDS_LOG_FUNC_ENTER__;
1069         GList *temp = NULL;
1070         wfd_device_s *peer = NULL;
1071         wfd_discovery_entry_s *peers = NULL;
1072         int peer_count = 0;
1073         int count = 0;
1074         int res = 0;
1075
1076         if (!manager || !peers_data) {
1077                 WDS_LOGE("Invalid parameter");
1078                 return -1;
1079         }
1080
1081         unsigned long time = 0;
1082 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1083         wfd_util_get_current_time(&time);
1084 #else
1085         struct timeval tval;
1086         gettimeofday(&tval, NULL);
1087         time = tval.tv_sec;
1088 #endif
1089         WDS_LOGI("Current time [%ld]", time);
1090
1091         peer_count = manager->peer_count;
1092         WDS_LOGI("peer count [%ld]", peer_count);
1093         if (peer_count < 0)
1094                 return -1;
1095         else if (peer_count == 0)
1096                 return 0;
1097
1098         errno = 0;
1099         peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
1100         if (!peers) {
1101                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
1102                 return -1;
1103         }
1104
1105         temp = g_list_first(manager->peers);
1106         while (temp && count < peer_count) {
1107                 peer = temp->data;
1108                 if (!peer)
1109                         goto next;
1110                 if (peer->time + 8 < time) {
1111                         WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
1112                         res = wfd_update_peer(manager, peer);
1113                         if (res < 0) {
1114                                 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
1115                                 temp = g_list_next(temp);
1116                                 manager->peers = g_list_remove(manager->peers, peer);
1117                                 manager->peer_count--;
1118                                 g_free(peer);
1119                                 peer = NULL;
1120                                 continue;
1121                         }
1122                 }
1123
1124                 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1125                 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1126                 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1127                 peers[count].channel = peer->channel;
1128 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1129                 peers[count].services = 0;
1130 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1131                 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1132                 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1133                 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1134                 peers[count].wps_device_pwd_id = 0;
1135                 peers[count].wps_cfg_methods = peer->config_methods;
1136                 peers[count].category = peer->pri_dev_type;
1137                 peers[count].subcategory = peer->sec_dev_type;
1138
1139 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1140                 if (peer->display.availablity && peer->display.port)
1141                         peers[count].is_wfd_device = 1;
1142 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1143                 count++;
1144                 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1145 next:
1146                 temp = g_list_next(temp);
1147                 peer = NULL;
1148         }
1149         WDS_LOGD("%d peers converted", count);
1150         WDS_LOGD("Final peer count is %d", manager->peer_count);
1151
1152         *peers_data = peers;
1153
1154         __WDS_LOG_FUNC_EXIT__;
1155         return count;
1156 }
1157
1158 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1159 {
1160         __WDS_LOG_FUNC_ENTER__;
1161         wfd_connected_peer_info_s *peers = NULL;
1162         wfd_group_s *group = NULL;
1163         wfd_device_s *peer = NULL;
1164         GList *temp = NULL;
1165         int peer_count = 0;
1166         int count = 0;
1167
1168         if (!manager || !peers_data) {
1169                 WDS_LOGE("Invalid parameter");
1170                 return -1;
1171         }
1172
1173         group = manager->group;
1174         if (!group) {
1175                 WDS_LOGE("Group not exist");
1176                 return -1;
1177         }
1178
1179         peer_count = group->member_count;
1180         if (peer_count == 0) {
1181                 WDS_LOGD("Member not exist");
1182                 return 0;
1183         }
1184
1185         errno = 0;
1186         peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
1187         if (!peers) {
1188                 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", strerror(errno));
1189                 return -1;
1190         }
1191
1192         temp = g_list_first(group->members);
1193         while (temp && count < group->member_count) {
1194                 peer = temp->data;
1195                 {
1196                         g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1197                         memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1198                         memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1199                         memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1200                         peers[count].category = peer->pri_dev_type;
1201                         peers[count].subcategory = peer->sec_dev_type;
1202                         peers[count].channel = peer->channel;
1203                         peers[count].is_p2p = 1;
1204 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1205                         peers[count].services = 0;
1206 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1207
1208 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1209                         if (peer->display.availablity && peer->display.port)
1210                                 peers[count].is_wfd_device = 1;
1211
1212 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1213
1214                         WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1215                         count++;
1216                 }
1217                 temp = g_list_next(temp);
1218                 peer = NULL;
1219         }
1220         WDS_LOGD("%d members converted", count);
1221
1222         *peers_data = peers;
1223
1224         __WDS_LOG_FUNC_EXIT__;
1225         return count;
1226 }
1227
1228 #if 0
1229 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1230 {
1231         __WDS_LOG_FUNC_ENTER__;
1232         wfd_device_s *peer = NULL;
1233
1234         if (!manager || !peer_addr) {
1235                 WDS_LOGE("Invalid parameter");
1236                 return NULL;
1237         }
1238
1239         peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1240
1241         __WDS_LOG_FUNC_EXIT__;
1242         return peer;
1243 }
1244 #endif
1245
1246 int wfd_manager_get_goup_ifname(char **ifname)
1247 {
1248         __WDS_LOG_FUNC_ENTER__;
1249         wfd_group_s *group = g_manager->group;
1250
1251         if (!ifname) {
1252                 WDS_LOGE("Invalid parameter");
1253                 __WDS_LOG_FUNC_EXIT__;
1254                 return -1;
1255         }
1256
1257         if (!group) {
1258                 WDS_LOGE("Group not exist");
1259                 return -1;
1260         }
1261
1262         *ifname = group->ifname;
1263
1264         __WDS_LOG_FUNC_EXIT__;
1265         return 0;
1266 }
1267
1268 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1269 int wfd_manager_set_display_device(int type, int port, int hdcp)
1270 {
1271         __WDS_LOG_FUNC_ENTER__;
1272         wfd_device_s * device = g_manager->local;
1273         wfd_oem_display_s display;
1274         int res = 0;
1275
1276         if (!device) {
1277                 WDS_LOGE("Invalid parameter");
1278                 __WDS_LOG_FUNC_EXIT__;
1279                 return -1;
1280         }
1281
1282         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1283
1284         display.type = type;
1285         display.port = port;
1286         display.hdcp_support = hdcp;
1287
1288         display.availablity = device->display.availablity;
1289         display.max_tput = device->display.max_tput;
1290
1291         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1292         if (res < 0) {
1293                 WDS_LOGE("Failed to set wifi display");
1294                 return -1;
1295         }
1296
1297         device->display.type = type;
1298         device->display.port = port;
1299         device->display.hdcp_support = hdcp;
1300
1301         __WDS_LOG_FUNC_EXIT__;
1302         return res;
1303 }
1304
1305 int wfd_manager_set_session_availability(int availability)
1306 {
1307         __WDS_LOG_FUNC_ENTER__;
1308         wfd_device_s * device = g_manager->local;
1309         wfd_oem_display_s display;
1310         int res = 0;
1311
1312         if (!device) {
1313                 WDS_LOGE("Invalid parameter");
1314                 __WDS_LOG_FUNC_EXIT__;
1315                 return -1;
1316         }
1317
1318         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1319
1320         display.availablity = availability;
1321
1322         display.type = device->display.type;
1323         display.hdcp_support = device->display.hdcp_support;
1324         display.port = device->display.port;
1325         display.max_tput = device->display.max_tput;
1326
1327         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1328         if (res < 0) {
1329                 WDS_LOGE("Failed to set wifi display session availability");
1330                 return -1;
1331         }
1332
1333         device->display.availablity = availability;
1334
1335         __WDS_LOG_FUNC_EXIT__;
1336         return res;
1337 }
1338
1339 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1340
1341 wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1342 {
1343         __WDS_LOG_FUNC_ENTER__;
1344         wfd_device_s *peer = NULL;
1345         if(manager->group) {
1346                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1347         }
1348
1349         if(peer) {
1350                 return peer;
1351         }
1352
1353         peer = wfd_peer_find_by_addr(manager, peer_addr);
1354
1355         return peer;
1356         __WDS_LOG_FUNC_EXIT__;
1357 }
1358
1359 static wfd_manager_s *wfd_manager_init()
1360 {
1361         __WDS_LOG_FUNC_ENTER__;
1362         wfd_manager_s *manager = NULL;
1363         int res = 0;
1364
1365         manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
1366         if (!manager) {
1367                 WDS_LOGE("Failed to allocate memory for wfd_manager structure");
1368                 return NULL;
1369         }
1370
1371         manager->go_intent = 7;
1372         manager->req_wps_mode = WFD_WPS_MODE_PBC;
1373         manager->max_station = 8;
1374         res = _wfd_local_init_device(manager);
1375         if (res < 0) {
1376                 WDS_LOGE("Failed to initialize local device");
1377                 g_free(manager);
1378                 return NULL;            // really stop manager?
1379         }
1380         WDS_LOGD("Succeeded to initialize local device");
1381
1382         manager->exit_timer = g_timeout_add(120000,
1383                                                 (GSourceFunc) _wfd_exit_timeout_cb, manager);
1384         WDS_LOGD("Exit timer started");
1385
1386         __WDS_LOG_FUNC_EXIT__;
1387         return manager;
1388 }
1389
1390 int wfd_manager_deinit(wfd_manager_s *manager)
1391 {
1392         __WDS_LOG_FUNC_ENTER__;
1393
1394         if (!manager) {
1395                 WDS_LOGE("Invalid parameter");
1396                 __WDS_LOG_FUNC_EXIT__;
1397                 return -1;
1398         }
1399
1400         if (manager->exit_timer > 0)
1401                 g_source_remove(manager->exit_timer);
1402         manager->exit_timer = 0;
1403
1404         _wfd_local_deinit_device(manager);
1405
1406         g_free(manager);
1407
1408         __WDS_LOG_FUNC_EXIT__;
1409         return 0;
1410 }
1411
1412 static void *wfd_plugin_init(wfd_manager_s *manager)
1413 {
1414         __WDS_LOG_FUNC_ENTER__;
1415         void *handle;
1416         struct utsname kernel_info;
1417         int res;
1418
1419         if (!manager) {
1420                 WDS_LOGE("Invalid parameter");
1421                 __WDS_LOG_FUNC_EXIT__;
1422                 return NULL;
1423         }
1424
1425         res = uname(&kernel_info);
1426         if (res) {
1427                 WDS_LOGE("Failed to detect target type");
1428                 __WDS_LOG_FUNC_EXIT__;
1429                 return NULL;
1430         }
1431         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
1432
1433         errno = 0;
1434
1435 #if defined(TIZEN_ARCH_64)
1436                 handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
1437 #else
1438                 handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
1439 #endif
1440         if (!handle) {
1441                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
1442                 __WDS_LOG_FUNC_EXIT__;
1443                 return NULL;
1444         }
1445
1446         errno = 0;
1447         int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
1448         plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
1449         if (!plugin_load) {
1450                 WDS_LOGE( "Failed to load symbol. Error = [%s]", strerror(errno));
1451                 dlclose(handle);
1452                 __WDS_LOG_FUNC_EXIT__;
1453                 return NULL;
1454         }
1455
1456         wfd_oem_ops_s *temp_ops;
1457         (*plugin_load)(&temp_ops);
1458         manager->oem_ops = temp_ops;
1459
1460         res = wfd_oem_init(temp_ops, (wfd_oem_event_cb) wfd_process_event, manager);
1461         if (res < 0) {
1462                 WDS_LOGE("Failed to initialize OEM");
1463                 dlclose(handle);
1464                 __WDS_LOG_FUNC_EXIT__;
1465                 return NULL;
1466         }
1467         WDS_LOGD("Succeeded to initialize OEM");
1468
1469         __WDS_LOG_FUNC_EXIT__;
1470         return handle;
1471 }
1472
1473 static int wfd_plugin_deinit(wfd_manager_s *manager)
1474 {
1475         __WDS_LOG_FUNC_ENTER__;
1476
1477         if (!manager || !manager->plugin_handle) {
1478                 WDS_LOGE("Invalid parameter");
1479                 __WDS_LOG_FUNC_EXIT__;
1480                 return -1;
1481         }
1482
1483         dlclose(manager->plugin_handle);
1484         manager->plugin_handle = NULL;
1485
1486         __WDS_LOG_FUNC_EXIT__;
1487         return 0;
1488 }
1489
1490 int main(int argc, char *argv[])
1491 {
1492         __WDS_LOG_FUNC_ENTER__;
1493         GMainLoop *main_loop = NULL;
1494         int res = 0;
1495
1496 #if !GLIB_CHECK_VERSION(2,32,0)
1497         if (!g_thread_supported())
1498                 g_thread_init(NULL);
1499 #endif
1500
1501 #if !GLIB_CHECK_VERSION(2,36,0)
1502         g_type_init();
1503 #endif
1504
1505         // TODO: Parsing argument
1506         /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1507
1508         g_manager = wfd_manager_init();
1509         if (!g_manager) {
1510                 WDS_LOGE("Failed to initialize wifi-direct manager");
1511                 __WDS_LOG_FUNC_EXIT__;
1512                 return -1;
1513         }
1514         WDS_LOGD("Succeeded to initialize manager");
1515
1516         g_manager->plugin_handle = wfd_plugin_init(g_manager);
1517         if (!g_manager->plugin_handle) {
1518                 WDS_LOGE("Failed to initialize plugin");
1519                 wfd_manager_deinit(g_manager);
1520                 __WDS_LOG_FUNC_EXIT__;
1521                 return -1;
1522         }
1523         WDS_LOGD("Succeeded to load plugin");
1524
1525         res = wfd_client_handler_init(g_manager);
1526         if (res < 0) {
1527                 WDS_LOGE("Failed to initialize client handler");
1528                 wfd_plugin_deinit(g_manager);
1529                 wfd_manager_deinit(g_manager);
1530                 __WDS_LOG_FUNC_EXIT__;
1531                 return -1;
1532         }
1533         WDS_LOGD("Succeeded to initialize client handler");
1534
1535         main_loop = g_main_loop_new(NULL, FALSE);
1536         if (main_loop == NULL) {
1537                 WDS_LOGE("Failed to create GMainLoop structure");
1538                 __WDS_LOG_FUNC_EXIT__;
1539                 return -1;
1540         }
1541         g_manager->main_loop = main_loop;
1542
1543         g_main_loop_run(main_loop);
1544
1545         wfd_client_handler_deinit(g_manager);
1546         wfd_plugin_deinit(g_manager);
1547         wfd_manager_deinit(g_manager);
1548
1549         __WDS_LOG_FUNC_EXIT__;
1550         return 0;
1551 }