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