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