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