a9042dd76e35ea32e46cb5af081c2a334dc5d88e
[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 <time.h>
31 #include <errno.h>
32 #include <string.h>
33
34 #include <glib.h>
35 #include <glib-object.h>
36
37 #include <wifi-direct.h>
38
39 #include "wifi-direct-ipc.h"
40 #include "wifi-direct-manager.h"
41 #include "wifi-direct-oem.h"
42 #include "wifi-direct-session.h"
43 #include "wifi-direct-group.h"
44 #include "wifi-direct-peer.h"
45 #include "wifi-direct-state.h"
46 #include "wifi-direct-event.h"
47 #include "wifi-direct-util.h"
48 #include "wifi-direct-log.h"
49 #include "wifi-direct-error.h"
50 #include "wifi-direct-iface.h"
51 #include "wifi-direct-dbus.h"
52
53 #if defined TIZEN_ENABLE_PRD
54 #include "wifi-direct-prd.h"
55 #endif /* TIZEN_ENABLE_PRD */
56
57 wfd_manager_s *g_manager = NULL;
58
59 wfd_manager_s *wfd_get_manager()
60 {
61         return g_manager;
62 }
63 //LCOV_EXCL_START
64 /* Stop wfd-manager services, If no client
65    exists and state is deactivated. */
66 static gboolean _wfd_exit_timeout_cb(void *user_data)
67 {
68         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
69         wfd_manager_s *manager = (wfd_manager_s*) user_data;
70
71         if (!manager) {
72                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
73                 return TRUE;
74         }
75
76         if (manager->client_count > 0) {
77                 WDS_LOGD("Client count [%d]", manager->client_count);
78                 return TRUE;
79         }
80
81         if (manager->state == WIFI_DIRECT_STATE_DEACTIVATED) {
82                 WDS_LOGD("Terminate Wi-Fi Direct Manager");//LCOV_EXCL_LINE
83                 g_main_loop_quit(manager->main_loop);
84                 manager->exit_timer = 0;
85                 WDS_LOGD("Stop exit timer. State [%d]", manager->state);
86                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
87                 return FALSE;
88         }
89
90         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
91         return TRUE;
92 }
93
94 void wfd_manager_free_active_client_list(void)
95 {
96         GSList *list;
97         wfd_manager_s *manager = wfd_get_manager();
98
99         if (!manager || !manager->client_list)
100                 return;
101
102         for (list = manager->client_list; list; list = list->next)
103                 g_free(list->data);
104
105         g_slist_free(manager->client_list);
106 }
107
108 void wfd_manager_add_active_client(const char *client_id)
109 {
110         GSList *list = NULL;
111         gboolean if_exists = FALSE;
112         gchar *str = NULL;
113         wfd_manager_s *manager = wfd_get_manager();
114         if (!manager || !client_id)
115                 return;
116
117         for (list = manager->client_list; list; list = list->next) {
118                 str = list->data;
119                 if (str && !g_strcmp0(client_id, str)) {
120                         if_exists = TRUE;
121                         break;
122                 }
123         }
124
125         // If not exists in list, add the sender
126         if (if_exists == FALSE) {
127                 manager->client_list = g_slist_prepend(manager->client_list,
128                                          g_strdup(client_id));
129                 manager->client_count++;
130                 WDS_LOGD("Added DBus sender id[%s] count[%d]", client_id,
131                                          manager->client_count);
132         }
133 }
134
135 void wfd_manager_remove_active_client(const gchar *name,
136                                       const char *old_owner,
137                                       const char *new_owner)
138 {
139         GSList *list = NULL;
140         gchar *str = NULL;
141         wfd_manager_s *manager = wfd_get_manager();
142
143         if (!manager)
144                 return;
145
146         if (!g_strcmp0(new_owner, "")) {
147                 if (manager->client_count > 0) {
148                         for (list = manager->client_list; list; list = list->next) {
149                                 str = list->data;
150                                 if (str && !g_strcmp0(old_owner, str)) {
151                                         manager->client_list =
152                                                  g_slist_remove(manager->client_list, str);
153                                         g_free(str);
154                                         manager->client_count--;
155                                         WDS_LOGD("Removed name[%s] old[%s] new[%s] count[%d]",
156                                                  name, old_owner, new_owner, manager->client_count);
157                                         break;
158                                 }
159                         }
160                 }
161         }
162 }
163 //LCOV_EXCL_STOP
164 static int _wfd_local_init_device(wfd_manager_s *manager)
165 {
166         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
167         wfd_device_s *local = NULL;
168         int res = 0;
169         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
170         wfd_oem_config_s *config;
171
172         if (!manager) {
173                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
174                 return -1;
175         }
176
177         config = manager->wfd_oem_conf;
178
179         errno = 0;
180         local = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
181         if (!local) {
182                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
183                 WDS_LOGE("Failed to allocate memory for local device [%s]", error_buf);
184                 return -1;
185         }
186
187         res = wfd_util_get_phone_name(local->dev_name);
188         if (res < 0) {
189                 WDS_LOGE("Failed to get phone name of local device. Use default device name");//LCOV_EXCL_LINE
190                 if (config)
191                         g_strlcpy(local->dev_name, config->device_name, DEV_NAME_LEN + 1);
192                 else
193                         g_strlcpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN + 1);
194         }
195         WDS_LOGD("Local Device name [%s]", local->dev_name);
196         wfd_util_set_dev_name_notification();
197
198         local->config_methods = WFD_WPS_MODE_PBC | WFD_WPS_MODE_DISPLAY | WFD_WPS_MODE_KEYPAD;
199         local->wps_mode = WFD_WPS_MODE_PBC;
200         local->services = NULL;
201         local->service_count = 0;
202         /* TODO: initialize other local device datas */
203         manager->local = local;
204
205         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
206         return 0;
207 }
208
209 static int _wfd_local_deinit_device(wfd_manager_s *manager)
210 {
211         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
212
213         if (!manager) {
214                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
215                 return -1;
216         }
217
218         wfd_util_unset_dev_name_notification();
219
220         /* TODO: free member of local device */
221         g_free(manager->local);
222
223         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
224         return 0;
225 }
226
227 int wfd_local_reset_data(wfd_manager_s *manager)
228 {
229         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
230         wfd_device_s *local = NULL;
231
232         if (!manager) {
233                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
234                 return -1;
235         }
236
237         local = manager->local;
238         /* init local device data */
239         local->dev_role = WFD_DEV_ROLE_NONE;
240         local->wps_mode = WFD_WPS_MODE_PBC;
241         memset(local->go_dev_addr, 0x0, MACADDR_LEN);
242         if (manager->is_wifi_display_supported)
243                 memset(&(local->display), 0x0, sizeof(wfd_display_s));
244         memset(local->ip_addr, 0x0, IPADDR_LEN);
245
246         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
247         return 0;
248 }
249
250 int wfd_local_get_dev_name(char *dev_name)
251 {
252         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
253         wfd_device_s *local = g_manager->local;
254
255         if (!dev_name) {
256                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
257                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
258                 return -1;
259         }
260
261         g_strlcpy(dev_name, local->dev_name, DEV_NAME_LEN + 1);
262         WDS_LOGD("Local device name [%s]", dev_name);
263
264         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
265         return 0;
266 }
267
268 int wfd_local_set_dev_name(char *dev_name)
269 {
270         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
271         wfd_device_s *local = g_manager->local;
272
273         if (!dev_name) {
274                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
275                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
276                 return -1;
277         }
278
279         g_strlcpy(local->dev_name, dev_name, DEV_NAME_LEN + 1);
280
281         if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED) {
282                 wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
283                 WDS_LOGD("Device name changed.");//LCOV_EXCL_LINE
284         } else {
285                 WDS_LOGE("Device name can't changed: state is %d", g_manager->state);
286         }
287
288         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
289         return 0;
290 }
291
292 int wfd_local_get_dev_mac(char *dev_mac)
293 {
294         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
295         wfd_device_s *local = g_manager->local;
296
297         if (!dev_mac) {
298                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
299                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
300                 return -1;
301         }
302
303         g_snprintf(dev_mac, MACSTR_LEN, MACSTR, MAC2STR(local->dev_addr));
304         WDS_SECLOGD("Local device MAC address [%s]", dev_mac);
305
306         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
307         return 0;
308 }
309
310 int wfd_local_get_ip_addr(char *ip_str)
311 {
312         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
313         wfd_device_s *local = g_manager->local;
314
315         if (!ip_str) {
316                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
317                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
318                 return -1;
319         }
320
321         snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(local->ip_addr));
322         WDS_SECLOGD("Local IP address [" IPSECSTR "]", IP2SECSTR(local->ip_addr));
323
324         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
325         return 0;
326 }
327
328 int wfd_local_get_supported_wps_mode(int *config_methods)
329 {
330         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
331         wfd_device_s *local = g_manager->local;
332
333         if (!config_methods) {
334                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
335                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
336                 return -1;
337         }
338
339         *config_methods = local->config_methods;
340         WDS_LOGD("Local config method [0x%x]", *config_methods);
341
342         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
343         return 0;
344 }
345
346 int wfd_local_get_wps_mode(int *wps_mode)
347 {
348         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
349         wfd_device_s *local = g_manager->local;
350
351         if (!wps_mode) {
352                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
353                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
354                 return -1;
355         }
356
357         *wps_mode = local->wps_mode;
358         WDS_LOGD("Local wps mode [0x%x]", *wps_mode);
359
360         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
361         return 0;
362 }
363
364 #if 0
365 int wfd_local_set_wps_mode(int wps_mode)
366 {
367         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
368         wfd_device_s *local = g_manager->local;
369
370         if (!wps_mode) {
371                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
372                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
373                 return -1;
374         }
375
376         local->wps_mode = wps_mode;
377         WDS_LOGD("Local wps mode [0x%x]", wps_mode);
378
379         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
380         return 0;
381 }
382 #endif
383
384 int wfd_manager_get_go_intent(int *go_intent)
385 {
386         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
387         if (!go_intent) {
388                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
389                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
390                 return -1;
391         }
392
393         *go_intent = g_manager->go_intent;
394         WDS_LOGD("Local GO intent [%d]", *go_intent);
395
396         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
397         return 0;
398 }
399
400 int wfd_manager_set_go_intent(int go_intent)
401 {
402         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
403
404         if (go_intent < 0 || go_intent > 15) {
405                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
406                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
407                 return -1;
408         }
409
410         g_manager->go_intent = go_intent;
411         if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED)
412                 wfd_oem_set_go_intent(g_manager->oem_ops, go_intent);
413
414         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
415         return 0;
416 }
417
418 int wfd_manager_get_go_intent_per_type(int type, int *go_intent)
419 {
420         __WDS_LOG_FUNC_ENTER__;
421         if (!go_intent) {
422                 WDS_LOGE("Invalid parameter");
423                 __WDS_LOG_FUNC_EXIT__;
424                 return -1;
425         }
426
427         if (type < 0 || type >= WFD_MAX_TYPE) {
428                 WDS_LOGE("Invalid parameter");
429                 __WDS_LOG_FUNC_EXIT__;
430                 return -1;
431         }
432
433         *go_intent = g_manager->go_intent_per_type[type];
434         WDS_LOGD("Get Go_Intent[%d] : [%d]", type, *go_intent);
435
436         __WDS_LOG_FUNC_EXIT__;
437         return 0;
438 }
439
440 int wfd_manager_set_go_intent_per_type(int type, int go_intent)
441 {
442         __WDS_LOG_FUNC_ENTER__;
443
444         if (go_intent < 0 || go_intent > 15) {
445                 WDS_LOGE("Invalid parameter");
446                 __WDS_LOG_FUNC_EXIT__;
447                 return -1;
448         }
449
450         if (type < 0 || type >= WFD_MAX_TYPE) {
451                 WDS_LOGE("Invalid parameter");
452                 __WDS_LOG_FUNC_EXIT__;
453                 return -1;
454         }
455
456         g_manager->go_intent_per_type[type] = go_intent;
457         WDS_LOGD("Set Go_Intent[%d] : [%d]", type, g_manager->go_intent_per_type[type]);
458
459         __WDS_LOG_FUNC_EXIT__;
460         return 0;
461 }
462
463 int wfd_manager_get_max_station(int *max_station)
464 {
465         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
466
467         if (!max_station) {
468                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
469                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
470                 return -1;
471         }
472
473         *max_station = g_manager->max_station;
474         WDS_LOGD("Local max station[%d]", *max_station);
475
476         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
477         return 0;
478 }
479
480 int wfd_manager_set_max_station(int max_station)
481 {
482         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
483
484         if (max_station < 1) {
485                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
486                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
487                 return -1;
488         }
489
490         g_manager->max_station = max_station;
491
492         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
493         return 0;
494 }
495
496 int wfd_manager_get_autoconnection(int *autoconnection)
497 {
498         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
499         if (!autoconnection) {
500                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
501                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
502                 return -1;
503         }
504
505         *autoconnection = g_manager->autoconnection;
506         WDS_LOGD("Local autoconnection [%s]", *autoconnection ? "TRUE" : "FALSE");//LCOV_EXCL_LINE
507
508         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
509         return 0;
510 }
511
512 int wfd_manager_set_autoconnection(int autoconnection)
513 {
514         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
515         if (autoconnection < 0) {
516                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
517                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
518                 return -1;
519         }
520
521         g_manager->autoconnection = autoconnection;
522
523         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
524         return 0;
525 }
526
527 int wfd_manager_get_req_wps_mode(int *req_wps_mode)
528 {
529         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
530
531         if (!req_wps_mode) {
532                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
533                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
534                 return -1;
535         }
536
537         *req_wps_mode = g_manager->req_wps_mode;
538         WDS_LOGD("Requested wps mode [0x%x]", *req_wps_mode);
539
540         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
541         return 0;
542 }
543
544 int wfd_manager_set_req_wps_mode(int req_wps_mode)
545 {
546         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
547         wfd_device_s *local = g_manager->local;
548
549         if (req_wps_mode != WIFI_DIRECT_WPS_TYPE_PBC &&
550                         req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY &&
551                         req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD) {
552                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
553                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
554                 return -1;
555         }
556
557         g_manager->req_wps_mode = req_wps_mode;
558         WDS_LOGD("Requested wps mode [0x%x]", req_wps_mode);
559         if (req_wps_mode == WFD_WPS_MODE_DISPLAY)
560                 local->wps_mode = WFD_WPS_MODE_KEYPAD;
561         else if (req_wps_mode == WFD_WPS_MODE_KEYPAD)
562                 local->wps_mode = WFD_WPS_MODE_DISPLAY;
563         else
564                 local->wps_mode = req_wps_mode;
565
566         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
567         return 0;
568 }
569
570 int wfd_manager_local_config_set(wfd_manager_s *manager)
571 {
572         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
573         wfd_device_s *local = NULL;
574         int ip_over_eapol = 0;
575         int res = 0;
576
577         if (!manager) {
578                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
579                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
580         }
581
582         local = manager->local;
583
584         local->wps_mode = WFD_WPS_MODE_PBC;
585         WDS_LOGD("Device name set as %s", local->dev_name);
586         res = wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
587         if (res < 0) {
588                 WDS_LOGE("Failed to set device name");//LCOV_EXCL_LINE
589                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
590         }
591
592         local->pri_dev_type = DEFAULT_PRIMARY_DEVICE_TYPE;
593         local->sec_dev_type = DEFAULT_SECONDARY_DEVICE_TYPE;
594         res = wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
595         if (res < 0) {
596                 WDS_LOGE("Failed to set device type");//LCOV_EXCL_LINE
597                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
598         }
599
600         res = wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
601         if (res < 0) {
602                 WDS_LOGE("Failed to set go intent");//LCOV_EXCL_LINE
603                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
604         }
605
606         if (manager->is_ip_over_eapol)
607                 ip_over_eapol = 1;
608         else
609                 ip_over_eapol = 0;
610         res = wfd_oem_set_eapol_ip_config(manager->oem_ops, ip_over_eapol);
611         if (res < 0) {
612                 WDS_LOGE("Failed to set eapol ip config");//LCOV_EXCL_LINE
613                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
614         }
615
616         return WIFI_DIRECT_ERROR_NONE;
617 }
618
619 int wfd_manager_activate(wfd_manager_s *manager)
620 {
621         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
622         int prev_state = 0;
623         int res = 0;
624
625         if (!manager) {
626                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
627                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
628         }
629
630         if (manager->state > WIFI_DIRECT_STATE_ACTIVATING) {
631                 WDS_LOGE("Already activated");//LCOV_EXCL_LINE
632                 return 1;
633         }
634
635         if (manager->state == WIFI_DIRECT_STATE_ACTIVATING) {
636                 WDS_LOGE("In progress");//LCOV_EXCL_LINE
637                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
638         }
639
640         res = wfd_util_wifi_direct_activatable();
641         if (res < 0)
642                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
643
644         wfd_state_get(manager, &prev_state);
645         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
646         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATING);
647         res = wfd_util_check_wifi_state();
648         if (res < 0) {
649                 WDS_LOGE("Failed to get wifi state");//LCOV_EXCL_LINE
650                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
651         } else if (res == 0) {
652                 res = wfd_oem_activate(manager->oem_ops, 0);
653                 if (res < 0) {
654                         WDS_LOGE("Failed to activate");//LCOV_EXCL_LINE
655                         wfd_state_set(manager, prev_state);
656                         wfd_util_set_wifi_direct_state(prev_state);
657                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
658                 }
659         } else {
660                 res = wfd_oem_activate(manager->oem_ops, res);
661                 if (res < 0) {
662                         WDS_LOGE("Failed to activate");//LCOV_EXCL_LINE
663                         wfd_state_set(manager, prev_state);
664                         wfd_util_set_wifi_direct_state(prev_state);
665                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
666                 }
667         }
668         WDS_LOGE("Succeeded to activate");//LCOV_EXCL_LINE
669
670         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
671         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
672
673         wfd_manager_local_config_set(manager);
674         wfd_util_set_country();
675         if (manager->is_connection_agent)
676                 wfd_util_start_wifi_direct_popup();
677
678         res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
679         if (res < 0)
680                 WDS_LOGE("Failed to get local device MAC address");//LCOV_EXCL_LINE
681
682         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
683         return WIFI_DIRECT_ERROR_NONE;
684 }
685
686 int wfd_manager_deactivate(wfd_manager_s *manager)
687 {
688         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
689         int prev_state = 0;
690         int res = 0;
691         wfd_group_s *group = NULL;
692
693         if (!manager) {
694                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
695                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
696         }
697
698         wfd_state_get(manager, &prev_state);
699         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
700         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATING);
701
702         if (manager->is_wifi_display_supported) {
703                 res = wfd_oem_miracast_init(manager->oem_ops, false);
704                 if (res < 0)
705                         WDS_LOGE("Failed to initialize miracast");//LCOV_EXCL_LINE
706         }
707
708         group = (wfd_group_s*) manager->group;
709         if (group && group->pending == FALSE) {
710                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
711                 if (res < 0)
712                         WDS_LOGE("Failed to destroy group before deactivation");//LCOV_EXCL_LINE
713         }
714
715         res = wfd_util_check_wifi_state();
716         if (res < 0) {
717                 WDS_LOGE("Failed to get wifi state");//LCOV_EXCL_LINE
718                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
719         } else if (res == 0) {
720                 res = wfd_oem_deactivate(manager->oem_ops, 0);
721                 if (res < 0) {
722                         WDS_LOGE("Failed to deactivate");//LCOV_EXCL_LINE
723                         wfd_state_set(manager, prev_state);
724                         wfd_util_set_wifi_direct_state(prev_state);
725                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
726                 }
727         } else {
728                 /* FIXME: We should do something to stop p2p feature of Driver */
729                 res = wfd_oem_deactivate(manager->oem_ops, res);
730                 if (res < 0) {
731                         WDS_LOGE("Failed to deactivate");//LCOV_EXCL_LINE
732                         wfd_state_set(manager, prev_state);
733                         wfd_util_set_wifi_direct_state(prev_state);
734                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
735                 }
736                 WDS_LOGE("Do not need to deactivate Wi-Fi");//LCOV_EXCL_LINE
737         }
738
739         WDS_LOGE("Succeeded to deactivate");//LCOV_EXCL_LINE
740
741         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
742         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
743
744         manager->req_wps_mode = WFD_WPS_MODE_PBC;
745
746         wfd_destroy_session(manager);
747         wfd_destroy_group(manager);
748         wfd_peer_clear_all(manager);
749         wfd_local_reset_data(manager);
750
751         if (manager->is_connection_agent)
752                 wfd_util_stop_wifi_direct_popup();
753
754         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
755         return WIFI_DIRECT_ERROR_NONE;
756 }
757
758 int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
759 {
760         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
761         wfd_session_s *session = NULL;
762         int res = 0;
763
764         if (!manager || !peer_addr) {
765                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
766                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
767         }
768
769         if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
770                         manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
771                         manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
772                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
773                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
774         }
775
776         wfd_group_s *group = (wfd_group_s*) manager->group;
777         if (group && group->member_count >= manager->max_station) {
778                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
779                 return WIFI_DIRECT_ERROR_TOO_MANY_CLIENT;
780         }
781
782         session = (wfd_session_s*) manager->session;
783         if (session && session->type != SESSION_TYPE_INVITE) {
784                 WDS_LOGE("Session already exist and it's not an invitation session");//LCOV_EXCL_LINE
785                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
786                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
787         }
788
789         if (!session) {
790                 session = wfd_create_session(manager, peer_addr,
791                                         manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
792                 if (!session) {
793                         WDS_LOGE("Failed to create new session");//LCOV_EXCL_LINE
794                         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
795                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
796                 }
797         }
798
799         if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
800                         session->type != SESSION_TYPE_INVITE) {
801                 session->type = SESSION_TYPE_INVITE;
802                 res = wfd_session_invite(session);
803         } else {
804                 res = wfd_session_start(session);
805         }
806         if (res < 0) {
807                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
808                 wfd_destroy_session(manager);
809                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
810                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
811         }
812         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
813         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
814
815         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
816         return WIFI_DIRECT_ERROR_NONE;
817 }
818
819 int wfd_manager_asp_connect_session(wfd_manager_s *manager, void *params)
820 {
821         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
822         wfd_session_s *session = NULL;
823         wfd_oem_asp_prov_s *prov_params = NULL;
824         int req_wps_mode = WFD_WPS_MODE_P2PS;
825         int res = 0;
826
827         prov_params = (wfd_oem_asp_prov_s *)params;
828         if (!manager || !prov_params) {
829                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
830                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
831                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
832         }
833
834         session = (wfd_session_s*) manager->session;
835         if (session) {
836                 WDS_LOGE("Session already exists");//LCOV_EXCL_LINE
837                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
838                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
839         }
840
841         if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
842                 req_wps_mode = WFD_WPS_MODE_DISPLAY;
843         else if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
844                 req_wps_mode = WFD_WPS_MODE_KEYPAD;
845         else
846                 req_wps_mode = WFD_WPS_MODE_P2PS;
847
848         session = wfd_create_session(manager, prov_params->service_mac,
849                         req_wps_mode, SESSION_DIRECTION_OUTGOING);
850         if (!session) {
851                 WDS_LOGE("Failed to create new session");//LCOV_EXCL_LINE
852                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
853                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
854         }
855
856         res = wfd_session_asp_session_start(session, prov_params);
857         if (res < 0) {
858                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
859                 wfd_destroy_session(manager);
860                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
861                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
862         }
863
864         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
865         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
866
867         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
868         return WIFI_DIRECT_ERROR_NONE;
869 }
870
871 int wfd_manager_asp_confirm_session(wfd_manager_s *manager, void *params, int confirmed)
872 {
873         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
874         wfd_session_s *session = NULL;
875         wfd_oem_asp_prov_s *prov_params = NULL;
876         int res = 0;
877
878         prov_params = (wfd_oem_asp_prov_s *)params;
879         if (!manager || !prov_params) {
880                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
881                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
882                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
883         }
884
885         session = (wfd_session_s*) manager->session;
886         if (!session) {
887                 WDS_LOGE("Session not exists");//LCOV_EXCL_LINE
888                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
889                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
890         }
891
892
893         WDS_LOGD("confirm session [%u] with peer [" MACSTR "]", prov_params->session_id,
894                         MAC2STR(prov_params->session_mac));
895
896         WDS_LOGD("created session [%u] with peer [" MACSTR "]", session->session_id,
897                         MAC2STR(session->session_mac));
898
899         if (session->session_id != prov_params->session_id ||
900                         memcmp(&(session->session_mac), prov_params->session_mac, MACADDR_LEN) != 0) {
901                 WDS_LOGE("Session MAC or ID not matched");//LCOV_EXCL_LINE
902                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
903         }
904
905         if (confirmed)
906                 prov_params->status = 12;
907         else
908                 prov_params->status = 11;
909         prov_params->deferring = 1;
910
911         res = wfd_oem_asp_prov_disc_req(manager->oem_ops, prov_params);
912         if (res < 0) {
913                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
914                 wfd_destroy_session(manager);
915                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
916                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
917         }
918         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
919         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
920
921         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
922         return WIFI_DIRECT_ERROR_NONE;
923 }
924
925 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
926 {
927         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
928         wfd_session_s *session = NULL;
929         wfd_device_s *peer = NULL;
930         int res = 0;
931
932         if (!manager || !peer_addr) {
933                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
934                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
935         }
936
937         session = (wfd_session_s*) manager->session;
938         if (!session) {
939                 WDS_LOGE("Session not found");//LCOV_EXCL_LINE
940                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
941         }
942
943         peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
944         if (!peer) {
945                 WDS_LOGE("Peer is NULL");//LCOV_EXCL_LINE
946                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
947         }
948
949         if (memcmp(session->peer->dev_addr, peer_addr, MACADDR_LEN) != 0) {
950                 WDS_LOGE("Peer and ongoing session peer are different");//LCOV_EXCL_LINE
951                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
952         }
953
954         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
955                 WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");//LCOV_EXCL_LINE
956                 res = wfd_session_wps(session);
957         } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
958                 WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");//LCOV_EXCL_LINE
959                 if (session->type == SESSION_TYPE_INVITE) {
960                         if (session->state == SESSION_STATE_CREATED) {
961                                 WDS_LOGD("Invitation session. PD will be started");//LCOV_EXCL_LINE
962                                 res = wfd_session_start(session);
963                         } else {
964                                 WDS_LOGD("Invitation session. Join will be started");//LCOV_EXCL_LINE
965                                 res = wfd_session_join(session);
966                         }
967                 } else {
968                         /**
969                          * TODO: Add autoconnection peer matching logic.
970                          */
971                         if (manager->autoconnection && (manager->auto_pin[0] != 0))
972                                 g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
973
974                         WDS_LOGD("Peer device is GO, so WPS will be started");//LCOV_EXCL_LINE
975                         res = wfd_session_connect(session);
976                 }
977         } else {
978                 /**
979                  * TODO: Add autoconnection peer matching logic.
980                  */
981                 /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
982                 /* Otherwise, GO Nego is sometimes failed. */
983                 if (manager->autoconnection == FALSE) {
984                         WDS_LOGD("My device is Device, so Negotiation will be started");//LCOV_EXCL_LINE
985                         res = wfd_session_connect(session);
986                 }
987         }
988         if (res < 0) {
989                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
990                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
991                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
992                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
993                 } else {
994                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
995                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
996                 }
997                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
998         }
999         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
1000         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
1001
1002         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1003         return WIFI_DIRECT_ERROR_NONE;
1004 }
1005
1006
1007 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
1008 {
1009         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1010         wfd_group_s *group = NULL;
1011         int member_cnt = 0;
1012         int res = 0;
1013
1014         if (!manager || !peer_addr) {
1015                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1016                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1017         }
1018
1019         if (!manager->session && manager->state != WIFI_DIRECT_STATE_CONNECTING) {
1020                 WDS_LOGE("It's not CONNECTING state");//LCOV_EXCL_LINE
1021                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1022         }
1023
1024         res = wfd_session_cancel(manager->session, peer_addr);
1025         if (res < 0) {
1026                 WDS_LOGE("Failed to cancel session");//LCOV_EXCL_LINE
1027                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1028         }
1029
1030         group = (wfd_group_s*) manager->group;
1031         if (group)
1032                 member_cnt = wfd_group_remove_member(group, peer_addr);
1033         else
1034                 manager->local->dev_role = WFD_DEV_ROLE_NONE;
1035
1036         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1037                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1038                 if (member_cnt)
1039                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1040         } else {
1041                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1042                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1043         }
1044
1045         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1046         return WIFI_DIRECT_ERROR_NONE;
1047 }
1048
1049
1050 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
1051 {
1052         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1053         wfd_session_s *session = NULL;
1054         int res = 0;
1055
1056         if (!manager || !peer_addr) {
1057                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1058                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1059         }
1060
1061         session = (wfd_session_s*) manager->session;
1062         if (!session) {
1063                 WDS_LOGE("Session not found");//LCOV_EXCL_LINE
1064                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1065         }
1066
1067         if (manager->state != WIFI_DIRECT_STATE_CONNECTING) {
1068                 WDS_LOGE("It's not permitted with this state [%d]", manager->state);
1069                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1070         }
1071
1072         if (session->direction != SESSION_DIRECTION_INCOMING) {
1073                 WDS_LOGE("Only incomming session can be rejected");//LCOV_EXCL_LINE
1074                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1075         }
1076
1077         res = wfd_session_reject(session, peer_addr);
1078         if (res < 0) {
1079                 WDS_LOGE("Failed to reject connection");//LCOV_EXCL_LINE
1080                 /* TODO: check whether set state and break */
1081         }
1082         wfd_destroy_session(manager);
1083
1084         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1085                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1086                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1087         } else {
1088                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1089                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1090         }
1091
1092         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1093         return WIFI_DIRECT_ERROR_NONE;
1094 }
1095
1096
1097 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
1098 {
1099         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1100         wfd_group_s *group = NULL;
1101         wfd_device_s *peer = NULL;
1102         int res = 0;
1103
1104         if (!manager) {
1105                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1106                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1107         }
1108
1109         if (!peer_addr) {
1110                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1111                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1112         }
1113
1114         group = (wfd_group_s*) manager->group;
1115         if (!group) {
1116                 WDS_LOGE("Group not found");//LCOV_EXCL_LINE
1117                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1118         }
1119
1120         peer = wfd_group_find_member_by_addr(group, peer_addr);
1121         if (!peer) {
1122                 WDS_LOGE("Connected peer not found");//LCOV_EXCL_LINE
1123                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1124         }
1125
1126         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
1127         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCONNECTING);
1128
1129         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1130                 if (peer->is_p2p)
1131                         res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr, 0);
1132                 else
1133                         res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr, 1);
1134         } else {
1135                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1136         }
1137
1138         if (res < 0) {
1139                 WDS_LOGE("Failed to disconnect peer");//LCOV_EXCL_LINE
1140                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1141                 goto failed;
1142         }
1143         WDS_LOGE("Succeeded to disconnect peer");//LCOV_EXCL_LINE
1144
1145         wfd_group_remove_member(group, peer_addr);
1146
1147         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1148                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1149                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1150         } else {
1151                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1152                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1153         }
1154
1155         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1156         return WIFI_DIRECT_ERROR_NONE;
1157
1158 failed:
1159         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1160                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1161                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1162         } else {
1163                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1164                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1165         }
1166
1167         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1168         return res;
1169 }
1170
1171 int wfd_manager_disconnect_all(wfd_manager_s *manager)
1172 {
1173         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1174         wfd_group_s *group = NULL;
1175         int res = 0;
1176
1177         if (!manager) {
1178                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1179                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1180         }
1181
1182         group = (wfd_group_s*) manager->group;
1183         if (!group) {
1184                 WDS_LOGE("Group not found");//LCOV_EXCL_LINE
1185                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1186         }
1187
1188         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
1189         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCONNECTING);
1190
1191         res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1192         if (res < 0) {
1193                 WDS_LOGE("Failed to destroy group");//LCOV_EXCL_LINE
1194                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1195                 goto failed;
1196         }
1197         WDS_LOGE("Succeeded to disconnect all peer");//LCOV_EXCL_LINE
1198
1199         wfd_destroy_group(manager);
1200
1201         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1202         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1203
1204         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1205         return WIFI_DIRECT_ERROR_NONE;
1206
1207 failed:
1208         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1209                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1210                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1211         } else {
1212                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1213                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1214         }
1215
1216         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1217         return res;
1218 }
1219
1220 int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
1221 {
1222         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1223         wfd_device_s *peer_dev = NULL;
1224         wfd_discovery_entry_s *peer_info;
1225         wfd_oem_device_s *oem_dev = NULL;
1226         int res = 0;
1227         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1228
1229         if (!manager || !addr) {
1230                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1231                 return -1;
1232         }
1233
1234         unsigned long time = 0;
1235 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1236         wfd_util_get_current_time(&time);
1237 #else
1238         struct timeval tval;
1239         gettimeofday(&tval, NULL);
1240         time = tval.tv_sec;
1241 #endif
1242         WDS_LOGI("Current time [%ld]", time);
1243 //LCOV_EXCL_START
1244         //wfd_manager_get_peer_info takes responsibility of the oem_dev' memory ownership.
1245         res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
1246         if (res < 0 || !oem_dev) {
1247                 WDS_LOGE("Failed to get peer information");//LCOV_EXCL_LINE
1248                 return -1;
1249         }
1250
1251         peer_dev = wfd_peer_find_by_addr(manager, addr);
1252         if (!peer_dev) {
1253                 peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
1254                 if (!peer_dev) {
1255                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1256                         WDS_LOGE("Failed to allocate memory for peer device. [%s]", error_buf);
1257                         if (oem_dev->vsie)
1258                                 g_free(oem_dev->vsie);
1259                         g_free(oem_dev);
1260                         return -1;
1261                 }
1262                 memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
1263                 manager->peers = g_list_prepend(manager->peers, peer_dev);
1264                 manager->peer_count++;
1265                 peer_dev->time = time;
1266                 WDS_LOGD("peer_count[%d]", manager->peer_count);
1267         } else {
1268                 if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
1269                         WDS_LOGE("Too old age to update peer");//LCOV_EXCL_LINE
1270                         if (oem_dev->vsie)
1271                                 g_free(oem_dev->vsie);
1272                         g_free(oem_dev);
1273                         return -1;
1274                 }
1275         }
1276
1277         g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
1278         memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
1279         memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
1280         peer_dev->dev_role = oem_dev->dev_role;
1281         peer_dev->config_methods = oem_dev->config_methods;
1282         peer_dev->pri_dev_type = oem_dev->pri_dev_type;
1283         peer_dev->sec_dev_type = oem_dev->sec_dev_type;
1284         peer_dev->dev_flags = oem_dev->dev_flags;
1285         peer_dev->group_flags = oem_dev->group_flags;
1286         peer_dev->wps_mode =  oem_dev->wps_mode;
1287
1288         if (manager->is_wifi_display_supported)
1289                 memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
1290
1291         peer_dev->time = time;
1292         peer_dev->channel = oem_dev->channel;
1293
1294         if (oem_dev->vsie) {
1295                 if (peer_dev->vsie)
1296                         g_free(peer_dev->vsie);
1297                 peer_dev->vsie = g_strdup(oem_dev->vsie);
1298                 g_free(oem_dev->vsie);
1299         }
1300
1301         g_free(oem_dev);
1302
1303         peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
1304         if (!(peer_info)) {
1305                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1306                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1307                 return -1;
1308         }
1309
1310         g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
1311         memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
1312         memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
1313         peer_info->channel = peer_dev->channel;
1314         peer_info->services = 0;
1315         peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
1316         peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1317         peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
1318         peer_info->wps_device_pwd_id = 0;
1319         peer_info->wps_cfg_methods = peer_dev->config_methods;
1320         peer_info->category = peer_dev->pri_dev_type;
1321         peer_info->subcategory = peer_dev->sec_dev_type;
1322
1323         if (manager->is_wifi_display_supported)
1324                 if (peer_dev->display.availability && peer_dev->display.port)
1325                         peer_info->is_wfd_device = 1;
1326
1327         if (peer_dev->vsie)
1328                 peer_info->vsie = g_strdup(peer_dev->vsie);
1329
1330         *peer = peer_info;
1331 //LCOV_EXCL_STOP
1332         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1333         return res;
1334 }
1335
1336
1337 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
1338 {
1339         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1340         GList *temp = NULL;
1341         wfd_device_s *peer = NULL;
1342         wfd_discovery_entry_s *peers = NULL;
1343         int peer_count = 0;
1344         int count = 0;
1345         int res = 0;
1346         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1347
1348         if (!manager || !peers_data) {
1349                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1350                 return -1;
1351         }
1352
1353         unsigned long time = 0;
1354 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1355         wfd_util_get_current_time(&time);
1356 #else
1357         struct timeval tval;
1358         gettimeofday(&tval, NULL);
1359         time = tval.tv_sec;
1360 #endif
1361         WDS_LOGI("Current time [%ld]", time);
1362
1363         peer_count = manager->peer_count;
1364         WDS_LOGI("peer count [%d]", peer_count);
1365         if (peer_count < 0)
1366                 return -1;
1367         else if (peer_count == 0)
1368                 return 0;
1369
1370         errno = 0;
1371         peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
1372         if (!peers) {
1373                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1374                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1375                 return -1;
1376         }
1377
1378         temp = g_list_first(manager->peers);
1379         while (temp && count < peer_count) {
1380                 peer = temp->data;
1381                 if (!peer)
1382                         goto next;
1383                 if (peer->time + 8 < time) {
1384                         WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
1385                         res = wfd_update_peer(manager, peer);
1386                         if (res < 0) {
1387                                 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
1388                                 temp = g_list_next(temp);
1389                                 manager->peers = g_list_remove(manager->peers, peer);
1390                                 manager->peer_count--;
1391                                 wfd_peer_destroy(peer);
1392                                 peer = NULL;
1393                                 continue;
1394                         }
1395                 }
1396
1397                 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1398                 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1399                 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1400                 peers[count].channel = peer->channel;
1401                 peers[count].services = 0;
1402                 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1403                 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1404                 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1405                 peers[count].wps_device_pwd_id = 0;
1406                 peers[count].wps_cfg_methods = peer->config_methods;
1407                 peers[count].category = peer->pri_dev_type;
1408                 peers[count].subcategory = peer->sec_dev_type;
1409
1410
1411                 if (manager->is_wifi_display_supported)
1412                         if (peer->display.availability && peer->display.port)
1413                                 peers[count].is_wfd_device = 1;
1414                 count++;
1415                 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1416 next:
1417                 temp = g_list_next(temp);
1418                 peer = NULL;
1419         }
1420         WDS_LOGD("%d peers converted", count);
1421         WDS_LOGD("Final peer count is %d", manager->peer_count);
1422
1423         *peers_data = peers;
1424
1425         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1426         return count;
1427 }
1428
1429 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1430 {
1431         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1432         wfd_connected_peer_info_s *peers = NULL;
1433         wfd_group_s *group = NULL;
1434         wfd_device_s *peer = NULL;
1435         GList *temp = NULL;
1436         int peer_count = 0;
1437         int count = 0;
1438         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1439
1440         if (!manager || !peers_data) {
1441                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1442                 return -1;
1443         }
1444
1445         group = manager->group;
1446         if (!group) {
1447                 WDS_LOGE("Group not exist");//LCOV_EXCL_LINE
1448                 return -1;
1449         }
1450
1451         peer_count = group->member_count;
1452         if (peer_count == 0) {
1453                 WDS_LOGD("Member not exist");//LCOV_EXCL_LINE
1454                 return 0;
1455         }
1456
1457         errno = 0;
1458         peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
1459         if (!peers) {
1460                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1461                 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", error_buf);
1462                 return -1;
1463         }
1464
1465         temp = g_list_first(group->members);
1466         while (temp && count < group->member_count) {
1467                 peer = temp->data;
1468                 {
1469                         g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1470                         memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1471                         memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1472                         memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1473                         peers[count].category = peer->pri_dev_type;
1474                         peers[count].subcategory = peer->sec_dev_type;
1475                         peers[count].channel = peer->channel;
1476                         peers[count].is_p2p = peer->is_p2p;
1477                         peers[count].services = 0;
1478
1479                         if (manager->is_wifi_display_supported)
1480                                 if (peer->display.availability && peer->display.port)
1481                                         peers[count].is_wfd_device = 1;
1482
1483                         WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1484                         count++;
1485                 }
1486                 temp = g_list_next(temp);
1487                 peer = NULL;
1488         }
1489         WDS_LOGD("%d members converted", count);
1490
1491         *peers_data = peers;
1492
1493         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1494         return count;
1495 }
1496
1497 wfd_device_s *wfd_manager_get_connected_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1498 {
1499         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1500         wfd_device_s *peer = NULL;
1501
1502         if (peer_addr == NULL) {
1503                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1504                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1505                 return peer;
1506         }
1507
1508         if (manager->group)
1509                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1510
1511         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1512         return peer;
1513 }
1514
1515 #if 0
1516 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1517 {
1518         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1519         wfd_device_s *peer = NULL;
1520
1521         if (!manager || !peer_addr) {
1522                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1523                 return NULL;
1524         }
1525
1526         peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1527
1528         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1529         return peer;
1530 }
1531 #endif
1532
1533 int wfd_manager_get_goup_ifname(char **ifname)
1534 {
1535         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1536         wfd_group_s *group = g_manager->group;
1537
1538         if (!ifname) {
1539                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1540                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1541                 return -1;
1542         }
1543
1544         if (!group) {
1545                 WDS_LOGE("Group not exist");//LCOV_EXCL_LINE
1546                 return -1;
1547         }
1548
1549         *ifname = group->ifname;
1550
1551         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1552         return 0;
1553 }
1554
1555 int wfd_manager_set_display_device(int type, int port, int hdcp)
1556 {
1557         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1558         wfd_device_s * device = g_manager->local;
1559         wfd_oem_display_s display;
1560         int res = 0;
1561
1562         if (!device) {
1563                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1564                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1565                 return -1;
1566         }
1567
1568         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1569
1570         display.type = type;
1571         display.port = port;
1572         display.hdcp_support = hdcp;
1573
1574         display.availability = device->display.availability;
1575         display.max_tput = device->display.max_tput;
1576
1577         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1578         if (res < 0) {
1579                 WDS_LOGE("Failed to set wifi display");//LCOV_EXCL_LINE
1580                 return -1;
1581         }
1582
1583         device->display.type = type;
1584         device->display.port = port;
1585         device->display.hdcp_support = hdcp;
1586
1587         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1588         return res;
1589 }
1590
1591 int wfd_manager_set_session_availability(int availability)
1592 {
1593         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1594         wfd_device_s * device = g_manager->local;
1595         wfd_oem_display_s display;
1596         int res = 0;
1597
1598         if (!device) {
1599                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1600                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1601                 return -1;
1602         }
1603
1604         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1605
1606         display.availability = availability;
1607
1608         display.type = device->display.type;
1609         display.hdcp_support = device->display.hdcp_support;
1610         display.port = device->display.port;
1611         display.max_tput = device->display.max_tput;
1612
1613         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1614         if (res < 0) {
1615                 WDS_LOGE("Failed to set wifi display session availability");//LCOV_EXCL_LINE
1616                 return -1;
1617         }
1618
1619         device->display.availability = availability;
1620
1621         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1622         return res;
1623 }
1624
1625 int wfd_manager_get_display_device(int *type, int *port, int *hdcp)
1626 {
1627         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1628         wfd_device_s *device = g_manager->local;
1629         int res = 0;
1630
1631         if (!device || !type || !port || !hdcp) {
1632                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1633                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1634                 return -1;
1635         }
1636
1637         *type = device->display.type;
1638         *port = device->display.port;
1639         *hdcp = device->display.hdcp_support;
1640
1641         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1642         return res;
1643 }
1644
1645 int wfd_manager_get_session_availability(int *availability)
1646 {
1647         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1648         wfd_device_s *device = g_manager->local;
1649         int res = 0;
1650
1651         if (!device || !availability) {
1652                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1653                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1654                 return -1;
1655         }
1656
1657         *availability = device->display.availability;
1658
1659         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1660         return res;
1661 }
1662
1663 int wfd_manager_start_discovery(wfd_manager_s *manager, int mode, int timeout,
1664                                 const char* type, int channel, int frequency)
1665 {
1666         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1667         int res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1668         wfd_oem_scan_param_s param;
1669         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
1670
1671         WDS_LOGI("Mode [%d], Timeout [%d], type [%s], channel [%d], frequency [%d]",
1672                  mode, timeout, type, channel, frequency);
1673
1674         if (manager->local->dev_role == WFD_DEV_ROLE_GO)
1675                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1676
1677         switch (channel) {
1678         case WFD_DISCOVERY_FULL_SCAN:
1679                 param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
1680                 break;
1681         case WFD_DISCOVERY_SOCIAL_CHANNEL:
1682                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1683                 break;
1684         case WFD_DISCOVERY_CHANNEL1:
1685                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL1;
1686                 param.freq = 2412;
1687                 break;
1688         case WFD_DISCOVERY_CHANNEL6:
1689                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL6;
1690                 param.freq = 2437;
1691                 break;
1692         case WFD_DISCOVERY_CHANNEL11:
1693                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL11;
1694                 param.freq = 2462;
1695                 break;
1696         default:
1697                 param.scan_type = WFD_OEM_SCAN_TYPE_SPECIFIC;
1698                 if (frequency > 0)
1699                         param.freq = frequency;
1700                 else
1701                         param.freq = wfd_util_channel_to_freq(channel);
1702         }
1703
1704         if (mode)
1705                 param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
1706         else
1707                 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
1708
1709         param.scan_time = timeout;
1710
1711         res = wfd_oem_start_scan(manager->oem_ops, &param);
1712         if (res < 0) {
1713                 WDS_LOGE("Failed to start scan");//LCOV_EXCL_LINE
1714                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1715                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1716         }
1717
1718         if (mode)
1719                 manager->scan_mode = WFD_SCAN_MODE_PASSIVE;
1720         else
1721                 manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
1722
1723         if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
1724                 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
1725                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
1726         }
1727
1728         WDS_LOGD("Succeeded to start scan");//LCOV_EXCL_LINE
1729         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1730         return WIFI_DIRECT_ERROR_NONE;
1731 }
1732
1733 int wfd_manager_cancel_discovery(wfd_manager_s *manager)
1734 {
1735         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1736         int res = 0;
1737
1738         res = wfd_oem_stop_scan(manager->oem_ops);
1739         if (res < 0) {
1740                 WDS_LOGE("Failed to stop scan");//LCOV_EXCL_LINE
1741                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1742                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1743         }
1744
1745         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1746                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1747                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1748         } else if (manager->local->dev_role == WFD_DEV_ROLE_GC) {
1749                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1750                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1751         } else {
1752                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1753                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1754         }
1755
1756         WDS_LOGD("Succeeded to stop scan");//LCOV_EXCL_LINE
1757         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1758         return WIFI_DIRECT_ERROR_NONE;
1759 }
1760
1761 wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1762 {
1763         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1764         wfd_device_s *peer = NULL;
1765         if (manager->group)
1766                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1767
1768         if (peer)
1769                 return peer;
1770
1771         peer = wfd_peer_find_by_addr(manager, peer_addr);
1772
1773         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1774         return peer;
1775 }
1776
1777 static wfd_manager_s *wfd_manager_init()
1778 {
1779         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1780         wfd_manager_s *manager = NULL;
1781         int res = 0;
1782
1783         manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
1784         if (!manager) {
1785                 WDS_LOGE("Failed to allocate memory for wfd_manager structure");//LCOV_EXCL_LINE
1786                 return NULL;
1787         }
1788
1789         manager->wfd_oem_conf = (wfd_oem_config_s*) g_try_malloc0(sizeof(wfd_oem_config_s));
1790         if (!manager->wfd_oem_conf) {
1791                 g_free(manager);
1792                 WDS_LOGE("Failed to allocate memory for wfd_oem_conf structure");//LCOV_EXCL_LINE
1793                 return NULL;
1794         }
1795
1796         manager->go_intent = 7;
1797         manager->req_wps_mode = WFD_WPS_MODE_PBC;
1798         manager->max_station = 8;
1799         manager->session_timer = 120;
1800         manager->auto_group_remove_enable = TRUE;
1801
1802         manager->go_intent_per_type[WFD_DISPLAY_TYPE_SOURCE] = WFD_GO_INTENT_DISPLY_SOURCE;
1803         manager->go_intent_per_type[WFD_DISPLAY_TYPE_PRISINK] = WFD_GO_INTENT_MAX;
1804         manager->go_intent_per_type[WFD_DISPLAY_TYPE_SECSINK] = WFD_GO_INTENT_MAX;
1805         manager->go_intent_per_type[WFD_DISPLAY_TYPE_DUAL] = WFD_GO_INTENT_MAX;
1806         manager->go_intent_per_type[WFD_DISPLAY_TYPE_NONE] = WFD_GO_INTENT_MAX;
1807
1808         wfd_util_check_features(manager);
1809         wfd_util_load_wfd_conf(manager);
1810
1811         res = _wfd_local_init_device(manager);
1812         if (res < 0) {
1813                 WDS_LOGE("Failed to initialize local device");//LCOV_EXCL_LINE
1814                 g_free(manager->wfd_oem_conf);
1815                 g_free(manager);
1816                 return NULL;            /* really stop manager? */
1817         }
1818         WDS_LOGD("Succeeded to initialize local device");//LCOV_EXCL_LINE
1819
1820         manager->client_count = 0;
1821         manager->client_list = NULL;
1822         if (manager->is_on_demand) {
1823                 manager->exit_timer = g_timeout_add(120000,
1824                                                         (GSourceFunc) _wfd_exit_timeout_cb, manager);
1825                 WDS_LOGD("Exit timer started");//LCOV_EXCL_LINE
1826         }
1827
1828
1829         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1830         return manager;
1831 }
1832
1833 int wfd_manager_deinit(wfd_manager_s *manager)
1834 {
1835         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1836
1837         if (!manager) {
1838                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1839                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1840                 return -1;
1841         }
1842
1843         if (manager->is_on_demand && manager->exit_timer > 0) {
1844                 g_source_remove(manager->exit_timer);
1845                 manager->exit_timer = 0;
1846         }
1847
1848         _wfd_local_deinit_device(manager);
1849
1850         g_free(manager->wfd_oem_conf);
1851         g_free(manager);
1852
1853         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1854         return 0;
1855 }
1856
1857 int wfd_manager_load()
1858 {
1859         int res = 0;
1860         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1861
1862         /* TODO: Parsing argument */
1863         /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1864
1865         /**
1866          * wfd-manager initialization
1867          */
1868         g_manager = wfd_manager_init();
1869         if (!g_manager) {
1870                 WDS_LOGE("Failed to initialize wifi-direct manager");//LCOV_EXCL_LINE
1871                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1872                 return -1;
1873         }
1874         WDS_LOGD("Succeeded to initialize manager");//LCOV_EXCL_LINE
1875
1876         res = wfd_util_get_local_dev_mac(g_manager->local->dev_addr);
1877         if (res < 0)
1878                 WDS_LOGE("Failed to get local device MAC address");//LCOV_EXCL_LINE
1879
1880         if (wfd_manager_iface_init() != 0) {
1881                 WDS_LOGE("Failed to initialize iface");//LCOV_EXCL_LINE
1882                 wfd_manager_deinit(g_manager);
1883                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1884                 return -1;
1885         }
1886         WDS_LOGD("Succeeded to load iface");//LCOV_EXCL_LINE
1887
1888         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1889         return 0;
1890 }
1891
1892 void wfd_manager_unload()
1893 {
1894         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1895
1896         wfd_manager_iface_deinit();
1897         wfd_manager_deinit(g_manager);
1898         g_manager = NULL;
1899
1900         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1901         return;
1902 }