Added getters for primary and secondary device type.
[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         local->pri_dev_type = DEFAULT_PRIMARY_DEVICE_TYPE;
468         local->sec_dev_type = DEFAULT_SECONDARY_DEVICE_TYPE;
469         res = wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
470         if (res < 0) {
471                 WDS_LOGE("Failed to set device type");
472                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
473         }
474
475         res = wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
476         if (res < 0) {
477                 WDS_LOGE("Failed to set go intent");
478                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
479         }
480
481         return WIFI_DIRECT_ERROR_NONE;
482 }
483
484 int wfd_manager_activate(wfd_manager_s *manager)
485 {
486         __WDS_LOG_FUNC_ENTER__;
487         int prev_state = 0;
488         int res = 0;
489
490         if (!manager) {
491                 WDS_LOGE("Invalid parameter");
492                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
493         }
494
495         if (manager->state > WIFI_DIRECT_STATE_ACTIVATING) {
496                 WDS_LOGE("Already activated");
497                 return 1;
498         }
499
500         if (manager->state == WIFI_DIRECT_STATE_ACTIVATING) {
501                 WDS_LOGE("In progress");
502                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
503         }
504
505         res = wfd_util_wifi_direct_activatable();
506         if (res < 0)
507                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
508
509         wfd_state_get(manager, &prev_state);
510         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
511 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE)
512         res = wfd_util_check_wifi_state();
513         if (res < 0) {
514                 WDS_LOGE("Failed to get wifi state");
515                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
516         } else if (res == 0) {
517 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE */
518         res = wfd_oem_activate(manager->oem_ops, 0);
519         if (res < 0) {
520                 WDS_LOGE("Failed to activate");
521                 wfd_state_set(manager, prev_state);
522                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
523         }
524 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE)
525         } else {
526                 res = wfd_oem_activate(manager->oem_ops, res);
527                 if (res < 0) {
528                         WDS_LOGE("Failed to activate");
529                         wfd_state_set(manager, prev_state);
530                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
531                 }
532         }
533 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE */
534         WDS_LOGE("Succeeded to activate");
535
536         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
537         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
538
539         wfd_manager_local_config_set(manager);
540         wfd_util_set_country();
541 #ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
542         wfd_util_start_wifi_direct_popup();
543 #endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
544
545         res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
546         if (res < 0)
547                 WDS_LOGE("Failed to get local device MAC address");
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         wfd_group_s *group = NULL;
564
565         if (!manager) {
566                 WDS_LOGE("Invalid parameter");
567                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
568         }
569
570         wfd_state_get(manager, &prev_state);
571         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
572
573 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
574         res = wfd_oem_miracast_init(manager->oem_ops, false);
575         if (res < 0)
576                 WDS_LOGE("Failed to initialize miracast");
577 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
578
579         group = (wfd_group_s*) manager->group;
580         if (group && group->pending == FALSE) {
581                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
582                 if (res < 0)
583                         WDS_LOGE("Failed to destroy group before deactivation");
584         }
585
586 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
587         res = wfd_util_check_wifi_state();
588         if (res < 0) {
589                 WDS_LOGE("Failed to get wifi state");
590                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
591         } else if (res == 0) {
592 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_PROFILE_MOBILE */
593                 res = wfd_oem_deactivate(manager->oem_ops, 0);
594                 if (res < 0) {
595                         WDS_LOGE("Failed to deactivate");
596                         wfd_state_set(manager, prev_state);
597                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
598                 }
599 #if defined(TIZEN_WLAN_CONCURRENT_ENABLE) && defined(TIZEN_PROFILE_MOBILE)
600         } else {
601                 /* FIXME: We should do something to stop p2p feature of Driver */
602                 res = wfd_oem_deactivate(manager->oem_ops, res);
603                 if (res < 0) {
604                         WDS_LOGE("Failed to deactivate");
605                         wfd_state_set(manager, prev_state);
606                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
607                 }
608                 WDS_LOGE("Do not need to deactivate Wi-Fi");
609         }
610 #endif /* TIZEN_WLAN_CONCURRENT_ENABLE && TIZEN_PROFILE_MOBILE */
611         WDS_LOGE("Succeeded to deactivate");
612
613         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
614         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
615
616         manager->req_wps_mode = WFD_WPS_MODE_PBC;
617
618         wfd_destroy_group(manager);
619         wfd_destroy_session(manager);
620         wfd_peer_clear_all(manager);
621         wfd_local_reset_data(manager);
622
623 #ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
624         wfd_util_stop_wifi_direct_popup();
625 #endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
626         __WDS_LOG_FUNC_EXIT__;
627         return WIFI_DIRECT_ERROR_NONE;
628 }
629
630 int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
631 {
632         __WDS_LOG_FUNC_ENTER__;
633         wfd_session_s *session = NULL;
634         int res = 0;
635
636         if (!manager || !peer_addr) {
637                 WDS_LOGE("Invalid parameter");
638                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
639         }
640
641         if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
642                         manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
643                         manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
644                 __WDS_LOG_FUNC_EXIT__;
645                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
646         }
647
648         wfd_group_s *group = (wfd_group_s*) manager->group;
649         if (group && group->member_count >= manager->max_station) {
650                 __WDS_LOG_FUNC_EXIT__;
651                 return WIFI_DIRECT_ERROR_TOO_MANY_CLIENT;
652         }
653
654         session = (wfd_session_s*) manager->session;
655         if (session && session->type != SESSION_TYPE_INVITE) {
656                 WDS_LOGE("Session already exist and it's not an invitation session");
657                 __WDS_LOG_FUNC_EXIT__;
658                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
659         }
660
661         if (!session) {
662                 session = wfd_create_session(manager, peer_addr,
663                                         manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
664                 if (!session) {
665                         WDS_LOGE("Failed to create new session");
666                         __WDS_LOG_FUNC_EXIT__;
667                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
668                 }
669         }
670
671         if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
672                         session->type != SESSION_TYPE_INVITE) {
673                 session->type = SESSION_TYPE_INVITE;
674                 res = wfd_session_invite(session);
675         } else {
676                 res = wfd_session_start(session);
677         }
678         if (res < 0) {
679                 WDS_LOGE("Failed to start session");
680                 wfd_destroy_session(manager);
681                 __WDS_LOG_FUNC_EXIT__;
682                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
683         }
684         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
685
686         __WDS_LOG_FUNC_EXIT__;
687         return WIFI_DIRECT_ERROR_NONE;
688 }
689
690 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
691 {
692         __WDS_LOG_FUNC_ENTER__;
693         wfd_session_s *session = NULL;
694         wfd_device_s *peer = NULL;
695         int res = 0;
696
697         if (!manager || !peer_addr) {
698                 WDS_LOGE("Invalid parameter");
699                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
700         }
701
702         session = (wfd_session_s*) manager->session;
703         if (!session) {
704                 WDS_LOGE("Session not found");
705                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
706         }
707
708         peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
709         if (!peer) {
710                 WDS_LOGE("Peer is NULL");
711                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
712         }
713
714         if (memcmp(session->peer->dev_addr, peer_addr, MACADDR_LEN) != 0) {
715                 WDS_LOGE("Peer and ongoing session peer are different");
716                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
717         }
718
719         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
720                 WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
721                 res = wfd_session_wps(session);
722         } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
723                 WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");
724                 if (session->type == SESSION_TYPE_INVITE) {
725                         if (session->state == SESSION_STATE_CREATED) {
726                                 WDS_LOGD("Invitation session. PD will be started");
727                                 res = wfd_session_start(session);
728                         } else {
729                                 WDS_LOGD("Invitation session. Join will be started");
730                                 res = wfd_session_join(session);
731                         }
732                 } else {
733                         if (manager->autoconnection && (manager->auto_pin[0] != 0))
734                                 g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
735
736                         WDS_LOGD("Peer device is GO, so WPS will be started");
737                         res = wfd_session_connect(session);
738                 }
739         } else {
740                 /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
741                 /* Otherwise, GO Nego is sometimes failed. */
742                 if (manager->autoconnection == FALSE) {
743                         WDS_LOGD("My device is Device, so Negotiation will be started");
744                         res = wfd_session_connect(session);
745                 }
746         }
747         if (res < 0) {
748                 WDS_LOGE("Failed to start session");
749                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
750                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
751                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
752                 } else {
753                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
754                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
755                 }
756                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
757         }
758         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
759
760         __WDS_LOG_FUNC_EXIT__;
761         return WIFI_DIRECT_ERROR_NONE;
762 }
763
764
765 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
766 {
767         __WDS_LOG_FUNC_ENTER__;
768         wfd_group_s *group = NULL;
769         int res = 0;
770
771         if (!manager || !peer_addr) {
772                 WDS_LOGE("Invalid parameter");
773                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
774         }
775
776         if (!manager->session && manager->state != WIFI_DIRECT_STATE_CONNECTING) {
777                 WDS_LOGE("It's not CONNECTING state");
778                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
779         }
780
781         res = wfd_session_cancel(manager->session, peer_addr);
782         if (res < 0) {
783                 WDS_LOGE("Failed to cancel session");
784                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
785         }
786
787         group = (wfd_group_s*) manager->group;
788         if (group)
789                 wfd_group_remove_member(group, peer_addr);
790
791         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
792                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
793                 if (group && group->member_count)
794                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
795         } else {
796                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
797                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
798         }
799
800         __WDS_LOG_FUNC_EXIT__;
801         return WIFI_DIRECT_ERROR_NONE;
802 }
803
804
805 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
806 {
807         __WDS_LOG_FUNC_ENTER__;
808         wfd_session_s *session = NULL;
809         int res = 0;
810
811         if (!manager || !peer_addr) {
812                 WDS_LOGE("Invalid parameter");
813                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
814         }
815
816         session = (wfd_session_s*) manager->session;
817         if (!session) {
818                 WDS_LOGE("Session not found");
819                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
820         }
821
822         if (manager->state != WIFI_DIRECT_STATE_CONNECTING) {
823                 WDS_LOGE("It's not permitted with this state [%d]", manager->state);
824                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
825         }
826
827         if (session->direction != SESSION_DIRECTION_INCOMING) {
828                 WDS_LOGE("Only incomming session can be rejected");
829                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
830         }
831
832         res = wfd_session_reject(session, peer_addr);
833         if (res < 0) {
834                 WDS_LOGE("Failed to reject connection");
835                 /* TODO: check whether set state and break */
836         }
837         wfd_destroy_session(manager);
838
839         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
840                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
841                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
842         } else {
843                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
844                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
845         }
846
847         __WDS_LOG_FUNC_EXIT__;
848         return WIFI_DIRECT_ERROR_NONE;
849 }
850
851
852 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
853 {
854         __WDS_LOG_FUNC_ENTER__;
855         wfd_group_s *group = NULL;
856         wfd_device_s *peer = NULL;
857         int res = 0;
858
859         if (!manager) {
860                 WDS_LOGE("Invalid parameter");
861                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
862         }
863
864         if (!peer_addr) {
865                 WDS_LOGE("Invalid parameter");
866                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
867         }
868
869         group = (wfd_group_s*) manager->group;
870         if (!group) {
871                 WDS_LOGE("Group not found");
872                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
873         }
874
875         peer = wfd_group_find_member_by_addr(group, peer_addr);
876         if (!peer) {
877                 WDS_LOGE("Connected peer not found");
878                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
879         }
880
881         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
882
883         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
884                 if (peer->is_p2p)
885                         res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr, 0);
886                 else
887                         res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr, 1);
888         } else {
889                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
890         }
891
892         if (res < 0) {
893                 WDS_LOGE("Failed to disconnect peer");
894                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
895                 goto failed;
896         }
897         WDS_LOGE("Succeeded to disconnect peer");
898
899         wfd_group_remove_member(group, peer_addr);
900         if (!group->member_count) {
901                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
902                 wfd_destroy_group(manager);
903         }
904
905         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
906                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
907                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
908         } else {
909                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
910                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
911         }
912
913         __WDS_LOG_FUNC_EXIT__;
914         return WIFI_DIRECT_ERROR_NONE;
915
916 failed:
917         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
918                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
919                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
920         } else {
921                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
922                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
923         }
924
925         __WDS_LOG_FUNC_EXIT__;
926         return res;
927 }
928
929 int wfd_manager_disconnect_all(wfd_manager_s *manager)
930 {
931         __WDS_LOG_FUNC_ENTER__;
932         wfd_group_s *group = NULL;
933         int res = 0;
934
935         if (!manager) {
936                 WDS_LOGE("Invalid parameter");
937                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
938         }
939
940         group = (wfd_group_s*) manager->group;
941         if (!group) {
942                 WDS_LOGE("Group not found");
943                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
944         }
945
946         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
947
948         res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
949         if (res < 0) {
950                 WDS_LOGE("Failed to destroy group");
951                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
952                 goto failed;
953         }
954         WDS_LOGE("Succeeded to disconnect all peer");
955
956         wfd_destroy_group(manager);
957
958         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
959         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
960
961         __WDS_LOG_FUNC_EXIT__;
962         return WIFI_DIRECT_ERROR_NONE;
963
964 failed:
965         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
966                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
967                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
968         } else {
969                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
970                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
971         }
972
973         __WDS_LOG_FUNC_EXIT__;
974         return res;
975 }
976
977 int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
978 {
979         __WDS_LOG_FUNC_ENTER__;
980         wfd_device_s *peer_dev = NULL;
981         wfd_discovery_entry_s *peer_info;
982         wfd_oem_device_s *oem_dev = NULL;
983         int res = 0;
984
985         if (!manager || !addr) {
986                 WDS_LOGE("Invalid parameter");
987                 return -1;
988         }
989
990         unsigned long time = 0;
991 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
992         wfd_util_get_current_time(&time);
993 #else
994         struct timeval tval;
995         gettimeofday(&tval, NULL);
996         time = tval.tv_sec;
997 #endif
998         WDS_LOGI("Current time [%ld]", time);
999
1000         res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
1001         if (res < 0 || !oem_dev) {
1002                 WDS_LOGE("Failed to get peer information");
1003                 return -1;
1004         }
1005
1006         peer_dev = wfd_peer_find_by_addr(manager, addr);
1007         if (!peer_dev) {
1008                 peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
1009                 if (!peer_dev) {
1010                         WDS_LOGE("Failed to allocate memory for peer device. [%s]", strerror(errno));
1011                         free(oem_dev);
1012                         return -1;
1013                 }
1014                 memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
1015                 manager->peers = g_list_prepend(manager->peers, peer_dev);
1016                 manager->peer_count++;
1017                 peer_dev->time = time;
1018                 WDS_LOGD("peer_count[%d]", manager->peer_count);
1019         } else {
1020                 if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
1021                         WDS_LOGE("Too old age to update peer");
1022                         free(oem_dev);
1023                         return -1;
1024                 }
1025         }
1026
1027         g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
1028         memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
1029         memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
1030         peer_dev->dev_role = oem_dev->dev_role;
1031         peer_dev->config_methods = oem_dev->config_methods;
1032         peer_dev->pri_dev_type = oem_dev->pri_dev_type;
1033         peer_dev->sec_dev_type = oem_dev->sec_dev_type;
1034         peer_dev->dev_flags = oem_dev->dev_flags;
1035         peer_dev->group_flags = oem_dev->group_flags;
1036         peer_dev->wps_mode =  oem_dev->wps_mode;
1037
1038 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1039         memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
1040 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1041
1042         peer_dev->time = time;
1043         peer_dev->channel = oem_dev->channel;
1044
1045         free(oem_dev);
1046
1047         peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
1048         if (!(peer_info)) {
1049                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
1050                 return -1;
1051         }
1052
1053         g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
1054         memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
1055         memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
1056         peer_info->channel = peer_dev->channel;
1057 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1058         peer_info->services = 0;
1059 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1060         peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
1061         peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1062         peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
1063         peer_info->wps_device_pwd_id = 0;
1064         peer_info->wps_cfg_methods = peer_dev->config_methods;
1065         peer_info->category = peer_dev->pri_dev_type;
1066         peer_info->subcategory = peer_dev->sec_dev_type;
1067
1068 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1069         if (peer_dev->display.availability && peer_dev->display.port)
1070                 peer_info->is_wfd_device = 1;
1071 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1072
1073         *peer = peer_info;
1074
1075         __WDS_LOG_FUNC_EXIT__;
1076         return res;
1077 }
1078
1079
1080 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
1081 {
1082         __WDS_LOG_FUNC_ENTER__;
1083         GList *temp = NULL;
1084         wfd_device_s *peer = NULL;
1085         wfd_discovery_entry_s *peers = NULL;
1086         int peer_count = 0;
1087         int count = 0;
1088         int res = 0;
1089
1090         if (!manager || !peers_data) {
1091                 WDS_LOGE("Invalid parameter");
1092                 return -1;
1093         }
1094
1095         unsigned long time = 0;
1096 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1097         wfd_util_get_current_time(&time);
1098 #else
1099         struct timeval tval;
1100         gettimeofday(&tval, NULL);
1101         time = tval.tv_sec;
1102 #endif
1103         WDS_LOGI("Current time [%ld]", time);
1104
1105         peer_count = manager->peer_count;
1106         WDS_LOGI("peer count [%ld]", peer_count);
1107         if (peer_count < 0)
1108                 return -1;
1109         else if (peer_count == 0)
1110                 return 0;
1111
1112         errno = 0;
1113         peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
1114         if (!peers) {
1115                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
1116                 return -1;
1117         }
1118
1119         temp = g_list_first(manager->peers);
1120         while (temp && count < peer_count) {
1121                 peer = temp->data;
1122                 if (!peer)
1123                         goto next;
1124                 if (peer->time + 8 < time) {
1125                         WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
1126                         res = wfd_update_peer(manager, peer);
1127                         if (res < 0) {
1128                                 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
1129                                 temp = g_list_next(temp);
1130                                 manager->peers = g_list_remove(manager->peers, peer);
1131                                 manager->peer_count--;
1132                                 g_free(peer);
1133                                 peer = NULL;
1134                                 continue;
1135                         }
1136                 }
1137
1138                 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1139                 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1140                 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1141                 peers[count].channel = peer->channel;
1142 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1143                 peers[count].services = 0;
1144 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1145                 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1146                 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1147                 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1148                 peers[count].wps_device_pwd_id = 0;
1149                 peers[count].wps_cfg_methods = peer->config_methods;
1150                 peers[count].category = peer->pri_dev_type;
1151                 peers[count].subcategory = peer->sec_dev_type;
1152
1153 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1154                 if (peer->display.availability && peer->display.port)
1155                         peers[count].is_wfd_device = 1;
1156 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1157                 count++;
1158                 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1159 next:
1160                 temp = g_list_next(temp);
1161                 peer = NULL;
1162         }
1163         WDS_LOGD("%d peers converted", count);
1164         WDS_LOGD("Final peer count is %d", manager->peer_count);
1165
1166         *peers_data = peers;
1167
1168         __WDS_LOG_FUNC_EXIT__;
1169         return count;
1170 }
1171
1172 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1173 {
1174         __WDS_LOG_FUNC_ENTER__;
1175         wfd_connected_peer_info_s *peers = NULL;
1176         wfd_group_s *group = NULL;
1177         wfd_device_s *peer = NULL;
1178         GList *temp = NULL;
1179         int peer_count = 0;
1180         int count = 0;
1181
1182         if (!manager || !peers_data) {
1183                 WDS_LOGE("Invalid parameter");
1184                 return -1;
1185         }
1186
1187         group = manager->group;
1188         if (!group) {
1189                 WDS_LOGE("Group not exist");
1190                 return -1;
1191         }
1192
1193         peer_count = group->member_count;
1194         if (peer_count == 0) {
1195                 WDS_LOGD("Member not exist");
1196                 return 0;
1197         }
1198
1199         errno = 0;
1200         peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
1201         if (!peers) {
1202                 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", strerror(errno));
1203                 return -1;
1204         }
1205
1206         temp = g_list_first(group->members);
1207         while (temp && count < group->member_count) {
1208                 peer = temp->data;
1209                 {
1210                         g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1211                         memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1212                         memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1213                         memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1214                         peers[count].category = peer->pri_dev_type;
1215                         peers[count].subcategory = peer->sec_dev_type;
1216                         peers[count].channel = peer->channel;
1217                         peers[count].is_p2p = peer->is_p2p;
1218 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1219                         peers[count].services = 0;
1220 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1221
1222 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1223                         if (peer->display.availability && peer->display.port)
1224                                 peers[count].is_wfd_device = 1;
1225
1226 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1227
1228                         WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1229                         count++;
1230                 }
1231                 temp = g_list_next(temp);
1232                 peer = NULL;
1233         }
1234         WDS_LOGD("%d members converted", count);
1235
1236         *peers_data = peers;
1237
1238         __WDS_LOG_FUNC_EXIT__;
1239         return count;
1240 }
1241
1242 #if 0
1243 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1244 {
1245         __WDS_LOG_FUNC_ENTER__;
1246         wfd_device_s *peer = NULL;
1247
1248         if (!manager || !peer_addr) {
1249                 WDS_LOGE("Invalid parameter");
1250                 return NULL;
1251         }
1252
1253         peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1254
1255         __WDS_LOG_FUNC_EXIT__;
1256         return peer;
1257 }
1258 #endif
1259
1260 int wfd_manager_get_goup_ifname(char **ifname)
1261 {
1262         __WDS_LOG_FUNC_ENTER__;
1263         wfd_group_s *group = g_manager->group;
1264
1265         if (!ifname) {
1266                 WDS_LOGE("Invalid parameter");
1267                 __WDS_LOG_FUNC_EXIT__;
1268                 return -1;
1269         }
1270
1271         if (!group) {
1272                 WDS_LOGE("Group not exist");
1273                 return -1;
1274         }
1275
1276         *ifname = group->ifname;
1277
1278         __WDS_LOG_FUNC_EXIT__;
1279         return 0;
1280 }
1281
1282 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1283 int wfd_manager_set_display_device(int type, int port, int hdcp)
1284 {
1285         __WDS_LOG_FUNC_ENTER__;
1286         wfd_device_s * device = g_manager->local;
1287         wfd_oem_display_s display;
1288         int res = 0;
1289
1290         if (!device) {
1291                 WDS_LOGE("Invalid parameter");
1292                 __WDS_LOG_FUNC_EXIT__;
1293                 return -1;
1294         }
1295
1296         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1297
1298         display.type = type;
1299         display.port = port;
1300         display.hdcp_support = hdcp;
1301
1302         display.availability = device->display.availability;
1303         display.max_tput = device->display.max_tput;
1304
1305         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1306         if (res < 0) {
1307                 WDS_LOGE("Failed to set wifi display");
1308                 return -1;
1309         }
1310
1311         device->display.type = type;
1312         device->display.port = port;
1313         device->display.hdcp_support = hdcp;
1314
1315         __WDS_LOG_FUNC_EXIT__;
1316         return res;
1317 }
1318
1319 int wfd_manager_set_session_availability(int availability)
1320 {
1321         __WDS_LOG_FUNC_ENTER__;
1322         wfd_device_s * device = g_manager->local;
1323         wfd_oem_display_s display;
1324         int res = 0;
1325
1326         if (!device) {
1327                 WDS_LOGE("Invalid parameter");
1328                 __WDS_LOG_FUNC_EXIT__;
1329                 return -1;
1330         }
1331
1332         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1333
1334         display.availability = availability;
1335
1336         display.type = device->display.type;
1337         display.hdcp_support = device->display.hdcp_support;
1338         display.port = device->display.port;
1339         display.max_tput = device->display.max_tput;
1340
1341         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1342         if (res < 0) {
1343                 WDS_LOGE("Failed to set wifi display session availability");
1344                 return -1;
1345         }
1346
1347         device->display.availability = availability;
1348
1349         __WDS_LOG_FUNC_EXIT__;
1350         return res;
1351 }
1352
1353 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1354
1355 int wfd_manager_start_discovery(wfd_manager_s *manager, int mode, int timeout,
1356                                 const char* type, int channel)
1357 {
1358         __WDS_LOG_FUNC_ENTER__;
1359         int res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1360         wfd_oem_scan_param_s param;
1361         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
1362
1363         WDS_LOGI("Mode: [%d], Timeout: [%d], type: [%s]", mode, timeout, type, channel);
1364
1365         if (manager->local->dev_role == WFD_DEV_ROLE_GO)
1366                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1367
1368         if (channel == WFD_DISCOVERY_FULL_SCAN) {
1369                 param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
1370         } else if (channel == WFD_DISCOVERY_SOCIAL_CHANNEL) {
1371                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1372         } else if (channel == WFD_DISCOVERY_CHANNEL1) {
1373                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL1;
1374                 param.freq = 2412;
1375         } else if (channel == WFD_DISCOVERY_CHANNEL6) {
1376                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL6;
1377                 param.freq = 2437;
1378         } else if (channel == WFD_DISCOVERY_CHANNEL11) {
1379                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL11;
1380                 param.freq = 2462;
1381         } else {
1382                 param.scan_type = WFD_OEM_SCAN_TYPE_SPECIFIC;
1383                 param.freq = wfd_util_channel_to_freq(channel);
1384         }
1385
1386         if (mode)
1387                 param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
1388         else
1389                 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
1390
1391         param.scan_time = timeout;
1392
1393         res = wfd_oem_start_scan(manager->oem_ops, &param);
1394         if (res < 0) {
1395                 WDS_LOGE("Failed to start scan");
1396                 __WDS_LOG_FUNC_EXIT__;
1397                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1398         }
1399
1400         if (mode)
1401                 manager->scan_mode = WFD_SCAN_MODE_PASSIVE;
1402         else
1403                 manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
1404
1405         if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
1406                 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
1407                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
1408         }
1409
1410         WDS_LOGD("Succeeded to start scan");
1411         __WDS_LOG_FUNC_EXIT__;
1412         return WIFI_DIRECT_ERROR_NONE;
1413 }
1414
1415 int wfd_manager_cancel_discovery(wfd_manager_s *manager)
1416 {
1417         __WDS_LOG_FUNC_ENTER__;
1418         int res = 0;
1419
1420         res = wfd_oem_stop_scan(manager->oem_ops);
1421         if (res < 0) {
1422                 WDS_LOGE("Failed to stop scan");
1423                 __WDS_LOG_FUNC_EXIT__;
1424                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1425         }
1426
1427         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1428                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1429                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1430         } else {
1431                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1432                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1433         }
1434
1435         WDS_LOGD("Succeeded to stop scan");
1436         __WDS_LOG_FUNC_EXIT__;
1437         return WIFI_DIRECT_ERROR_NONE;
1438 }
1439
1440 wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1441 {
1442         __WDS_LOG_FUNC_ENTER__;
1443         wfd_device_s *peer = NULL;
1444         if (manager->group)
1445                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1446
1447         if (peer)
1448                 return peer;
1449
1450         peer = wfd_peer_find_by_addr(manager, peer_addr);
1451
1452         __WDS_LOG_FUNC_EXIT__;
1453         return peer;
1454 }
1455
1456 static wfd_manager_s *wfd_manager_init()
1457 {
1458         __WDS_LOG_FUNC_ENTER__;
1459         wfd_manager_s *manager = NULL;
1460         int res = 0;
1461
1462         manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
1463         if (!manager) {
1464                 WDS_LOGE("Failed to allocate memory for wfd_manager structure");
1465                 return NULL;
1466         }
1467
1468         manager->go_intent = 7;
1469         manager->req_wps_mode = WFD_WPS_MODE_PBC;
1470         manager->max_station = 8;
1471         manager->session_timer = 120;
1472         manager->auto_group_remove_enable = TRUE;
1473         res = _wfd_local_init_device(manager);
1474         if (res < 0) {
1475                 WDS_LOGE("Failed to initialize local device");
1476                 g_free(manager);
1477                 return NULL;            /* really stop manager? */
1478         }
1479         WDS_LOGD("Succeeded to initialize local device");
1480
1481         __WDS_LOG_FUNC_EXIT__;
1482         return manager;
1483 }
1484
1485 int wfd_manager_deinit(wfd_manager_s *manager)
1486 {
1487         __WDS_LOG_FUNC_ENTER__;
1488
1489         if (!manager) {
1490                 WDS_LOGE("Invalid parameter");
1491                 __WDS_LOG_FUNC_EXIT__;
1492                 return -1;
1493         }
1494
1495         _wfd_local_deinit_device(manager);
1496
1497         g_free(manager);
1498
1499         __WDS_LOG_FUNC_EXIT__;
1500         return 0;
1501 }
1502
1503 static void *wfd_plugin_init(wfd_manager_s *manager)
1504 {
1505         __WDS_LOG_FUNC_ENTER__;
1506         void *handle;
1507         struct utsname kernel_info;
1508         int res;
1509
1510         if (!manager) {
1511                 WDS_LOGE("Invalid parameter");
1512                 __WDS_LOG_FUNC_EXIT__;
1513                 return NULL;
1514         }
1515
1516         res = uname(&kernel_info);
1517         if (res) {
1518                 WDS_LOGE("Failed to detect target type");
1519                 __WDS_LOG_FUNC_EXIT__;
1520                 return NULL;
1521         }
1522         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
1523
1524         errno = 0;
1525
1526 #if defined(TIZEN_ARCH_64)
1527                 handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
1528 #else
1529                 handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
1530 #endif
1531         if (!handle) {
1532                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
1533                 __WDS_LOG_FUNC_EXIT__;
1534                 return NULL;
1535         }
1536
1537         errno = 0;
1538         int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
1539         plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
1540         if (!plugin_load) {
1541                 WDS_LOGE("Failed to load symbol. Error = [%s]", strerror(errno));
1542                 dlclose(handle);
1543                 __WDS_LOG_FUNC_EXIT__;
1544                 return NULL;
1545         }
1546
1547         wfd_oem_ops_s *temp_ops;
1548         (*plugin_load)(&temp_ops);
1549         manager->oem_ops = temp_ops;
1550
1551         res = wfd_oem_init(temp_ops, (wfd_oem_event_cb) wfd_process_event, manager);
1552         if (res < 0) {
1553                 WDS_LOGE("Failed to initialize OEM");
1554                 dlclose(handle);
1555                 __WDS_LOG_FUNC_EXIT__;
1556                 return NULL;
1557         }
1558         WDS_LOGD("Succeeded to initialize OEM");
1559
1560         __WDS_LOG_FUNC_EXIT__;
1561         return handle;
1562 }
1563
1564 static int wfd_plugin_deinit(wfd_manager_s *manager)
1565 {
1566         __WDS_LOG_FUNC_ENTER__;
1567
1568         if (!manager || !manager->plugin_handle) {
1569                 WDS_LOGE("Invalid parameter");
1570                 __WDS_LOG_FUNC_EXIT__;
1571                 return -1;
1572         }
1573
1574         dlclose(manager->plugin_handle);
1575         manager->plugin_handle = NULL;
1576
1577         __WDS_LOG_FUNC_EXIT__;
1578         return 0;
1579 }
1580
1581 int main(int argc, char *argv[])
1582 {
1583         __WDS_LOG_FUNC_ENTER__;
1584         GMainLoop *main_loop = NULL;
1585
1586 #if !GLIB_CHECK_VERSION(2, 32, 0)
1587         if (!g_thread_supported())
1588                 g_thread_init(NULL);
1589 #endif
1590
1591 #if !GLIB_CHECK_VERSION(2, 36, 0)
1592         g_type_init();
1593 #endif
1594
1595         /* TODO: Parsing argument */
1596         /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1597
1598         /**
1599          * wfd-manager initialization
1600          */
1601         g_manager = wfd_manager_init();
1602         if (!g_manager) {
1603                 WDS_LOGE("Failed to initialize wifi-direct manager");
1604                 __WDS_LOG_FUNC_EXIT__;
1605                 return -1;
1606         }
1607         WDS_LOGD("Succeeded to initialize manager");
1608
1609         /**
1610          * wfd_manager_plugin initialization
1611          */
1612         g_manager->plugin_handle = wfd_plugin_init(g_manager);
1613         if (!g_manager->plugin_handle) {
1614                 WDS_LOGE("Failed to initialize plugin");
1615                 wfd_manager_deinit(g_manager);
1616                 __WDS_LOG_FUNC_EXIT__;
1617                 return -1;
1618         }
1619         WDS_LOGD("Succeeded to load plugin");
1620
1621         if (!wfd_manager_dbus_init()) {
1622                 WDS_LOGE("Failed to DBus");
1623                 wfd_plugin_deinit(g_manager);
1624                 wfd_manager_deinit(g_manager);
1625                 __WDS_LOG_FUNC_EXIT__;
1626                 return -1;
1627         }
1628
1629         main_loop = g_main_loop_new(NULL, FALSE);
1630         if (main_loop == NULL) {
1631                 WDS_LOGE("Failed to create GMainLoop structure");
1632                 __WDS_LOG_FUNC_EXIT__;
1633                 return -1;
1634         }
1635         g_manager->main_loop = main_loop;
1636         g_main_loop_run(main_loop);
1637
1638         wfd_manager_dbus_unregister();
1639         wfd_manager_dbus_deinit();
1640
1641         wfd_plugin_deinit(g_manager);
1642         wfd_manager_deinit(g_manager);
1643
1644         __WDS_LOG_FUNC_EXIT__;
1645         return 0;
1646 }