Fix logical dead code issue
[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         if (manager->is_connection_agent)
675                 wfd_util_start_wifi_direct_popup();
676
677         res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
678         if (res < 0)
679                 WDS_LOGE("Failed to get local device MAC address");//LCOV_EXCL_LINE
680
681         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
682         return WIFI_DIRECT_ERROR_NONE;
683 }
684
685 int wfd_manager_deactivate(wfd_manager_s *manager)
686 {
687         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
688         int prev_state = 0;
689         int res = 0;
690         wfd_group_s *group = NULL;
691
692         if (!manager) {
693                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
694                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
695         }
696
697         wfd_state_get(manager, &prev_state);
698         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
699         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATING);
700
701         if (manager->is_wifi_display_supported) {
702                 res = wfd_oem_miracast_init(manager->oem_ops, false);
703                 if (res < 0)
704                         WDS_LOGE("Failed to initialize miracast");//LCOV_EXCL_LINE
705         }
706
707         group = (wfd_group_s*) manager->group;
708         if (group && group->pending == FALSE) {
709                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
710                 if (res < 0)
711                         WDS_LOGE("Failed to destroy group before deactivation");//LCOV_EXCL_LINE
712         }
713
714         res = wfd_util_check_wifi_state();
715         if (res < 0) {
716                 WDS_LOGE("Failed to get wifi state");//LCOV_EXCL_LINE
717                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
718         } else if (res == 0) {
719                 res = wfd_oem_deactivate(manager->oem_ops, 0);
720                 if (res < 0) {
721                         WDS_LOGE("Failed to deactivate");//LCOV_EXCL_LINE
722                         wfd_state_set(manager, prev_state);
723                         wfd_util_set_wifi_direct_state(prev_state);
724                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
725                 }
726         } else {
727                 /* FIXME: We should do something to stop p2p feature of Driver */
728                 res = wfd_oem_deactivate(manager->oem_ops, res);
729                 if (res < 0) {
730                         WDS_LOGE("Failed to deactivate");//LCOV_EXCL_LINE
731                         wfd_state_set(manager, prev_state);
732                         wfd_util_set_wifi_direct_state(prev_state);
733                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
734                 }
735                 WDS_LOGE("Do not need to deactivate Wi-Fi");//LCOV_EXCL_LINE
736         }
737
738         WDS_LOGE("Succeeded to deactivate");//LCOV_EXCL_LINE
739
740         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
741         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
742
743         manager->req_wps_mode = WFD_WPS_MODE_PBC;
744
745         wfd_destroy_session(manager);
746         wfd_destroy_group(manager);
747         wfd_peer_clear_all(manager);
748         wfd_local_reset_data(manager);
749
750         if (manager->is_connection_agent)
751                 wfd_util_stop_wifi_direct_popup();
752
753         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
754         return WIFI_DIRECT_ERROR_NONE;
755 }
756
757 int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
758 {
759         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
760         wfd_session_s *session = NULL;
761         int res = 0;
762
763         if (!manager || !peer_addr) {
764                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
765                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
766         }
767
768         if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
769                         manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
770                         manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
771                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
772                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
773         }
774
775         wfd_group_s *group = (wfd_group_s*) manager->group;
776         if (group && group->member_count >= manager->max_station) {
777                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
778                 return WIFI_DIRECT_ERROR_TOO_MANY_CLIENT;
779         }
780
781         session = (wfd_session_s*) manager->session;
782         if (session && session->type != SESSION_TYPE_INVITE) {
783                 WDS_LOGE("Session already exist and it's not an invitation session");//LCOV_EXCL_LINE
784                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
785                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
786         }
787
788         if (!session) {
789                 session = wfd_create_session(manager, peer_addr,
790                                         manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
791                 if (!session) {
792                         WDS_LOGE("Failed to create new session");//LCOV_EXCL_LINE
793                         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
794                         return WIFI_DIRECT_ERROR_OPERATION_FAILED;
795                 }
796         }
797
798         if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
799                         session->type != SESSION_TYPE_INVITE) {
800                 session->type = SESSION_TYPE_INVITE;
801                 res = wfd_session_invite(session);
802         } else {
803                 res = wfd_session_start(session);
804         }
805         if (res < 0) {
806                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
807                 wfd_destroy_session(manager);
808                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
809                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
810         }
811         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
812         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
813
814         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
815         return WIFI_DIRECT_ERROR_NONE;
816 }
817
818 int wfd_manager_asp_connect_session(wfd_manager_s *manager, void *params)
819 {
820         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
821         wfd_session_s *session = NULL;
822         wfd_oem_asp_prov_s *prov_params = NULL;
823         int req_wps_mode = WFD_WPS_MODE_P2PS;
824         int res = 0;
825
826         prov_params = (wfd_oem_asp_prov_s *)params;
827         if (!manager || !prov_params) {
828                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
829                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
830                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
831         }
832
833         session = (wfd_session_s*) manager->session;
834         if (session) {
835                 WDS_LOGE("Session already exists");//LCOV_EXCL_LINE
836                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
837                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
838         }
839
840         if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
841                 req_wps_mode = WFD_WPS_MODE_DISPLAY;
842         else if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
843                 req_wps_mode = WFD_WPS_MODE_KEYPAD;
844         else
845                 req_wps_mode = WFD_WPS_MODE_P2PS;
846
847         session = wfd_create_session(manager, prov_params->service_mac,
848                         req_wps_mode, SESSION_DIRECTION_OUTGOING);
849         if (!session) {
850                 WDS_LOGE("Failed to create new session");//LCOV_EXCL_LINE
851                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
852                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
853         }
854
855         res = wfd_session_asp_session_start(session, prov_params);
856         if (res < 0) {
857                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
858                 wfd_destroy_session(manager);
859                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
860                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
861         }
862
863         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
864         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
865
866         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
867         return WIFI_DIRECT_ERROR_NONE;
868 }
869
870 int wfd_manager_asp_confirm_session(wfd_manager_s *manager, void *params, int confirmed)
871 {
872         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
873         wfd_session_s *session = NULL;
874         wfd_oem_asp_prov_s *prov_params = NULL;
875         int res = 0;
876
877         prov_params = (wfd_oem_asp_prov_s *)params;
878         if (!manager || !prov_params) {
879                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
880                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
881                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
882         }
883
884         session = (wfd_session_s*) manager->session;
885         if (!session) {
886                 WDS_LOGE("Session not exists");//LCOV_EXCL_LINE
887                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
888                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
889         }
890
891
892         WDS_LOGD("confirm session [%u] with peer [" MACSTR "]", prov_params->session_id,
893                         MAC2STR(prov_params->session_mac));
894
895         WDS_LOGD("created session [%u] with peer [" MACSTR "]", session->session_id,
896                         MAC2STR(session->session_mac));
897
898         if (session->session_id != prov_params->session_id ||
899                         memcmp(&(session->session_mac), prov_params->session_mac, MACADDR_LEN) != 0) {
900                 WDS_LOGE("Session MAC or ID not matched");//LCOV_EXCL_LINE
901                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
902         }
903
904         if (confirmed)
905                 prov_params->status = 12;
906         else
907                 prov_params->status = 11;
908         prov_params->deferring = 1;
909
910         res = wfd_oem_asp_prov_disc_req(manager->oem_ops, prov_params);
911         if (res < 0) {
912                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
913                 wfd_destroy_session(manager);
914                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
915                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
916         }
917         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
918         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
919
920         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
921         return WIFI_DIRECT_ERROR_NONE;
922 }
923
924 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
925 {
926         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
927         wfd_session_s *session = NULL;
928         wfd_device_s *peer = NULL;
929         int res = 0;
930
931         if (!manager || !peer_addr) {
932                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
933                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
934         }
935
936         session = (wfd_session_s*) manager->session;
937         if (!session) {
938                 WDS_LOGE("Session not found");//LCOV_EXCL_LINE
939                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
940         }
941
942         peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
943         if (!peer) {
944                 WDS_LOGE("Peer is NULL");//LCOV_EXCL_LINE
945                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
946         }
947
948         if (memcmp(session->peer->dev_addr, peer_addr, MACADDR_LEN) != 0) {
949                 WDS_LOGE("Peer and ongoing session peer are different");//LCOV_EXCL_LINE
950                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
951         }
952
953         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
954                 WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");//LCOV_EXCL_LINE
955                 res = wfd_session_wps(session);
956         } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
957                 WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");//LCOV_EXCL_LINE
958                 if (session->type == SESSION_TYPE_INVITE) {
959                         if (session->state == SESSION_STATE_CREATED) {
960                                 WDS_LOGD("Invitation session. PD will be started");//LCOV_EXCL_LINE
961                                 res = wfd_session_start(session);
962                         } else {
963                                 WDS_LOGD("Invitation session. Join will be started");//LCOV_EXCL_LINE
964                                 res = wfd_session_join(session);
965                         }
966                 } else {
967                         /**
968                          * TODO: Add autoconnection peer matching logic.
969                          */
970                         if (manager->autoconnection && (manager->auto_pin[0] != 0))
971                                 g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
972
973                         WDS_LOGD("Peer device is GO, so WPS will be started");//LCOV_EXCL_LINE
974                         res = wfd_session_connect(session);
975                 }
976         } else {
977                 /**
978                  * TODO: Add autoconnection peer matching logic.
979                  */
980                 /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
981                 /* Otherwise, GO Nego is sometimes failed. */
982                 if (manager->autoconnection == FALSE) {
983                         WDS_LOGD("My device is Device, so Negotiation will be started");//LCOV_EXCL_LINE
984                         res = wfd_session_connect(session);
985                 }
986         }
987         if (res < 0) {
988                 WDS_LOGE("Failed to start session");//LCOV_EXCL_LINE
989                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
990                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
991                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
992                 } else {
993                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
994                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
995                 }
996                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
997         }
998         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
999         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
1000
1001         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1002         return WIFI_DIRECT_ERROR_NONE;
1003 }
1004
1005
1006 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
1007 {
1008         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1009         wfd_group_s *group = NULL;
1010         int member_cnt = 0;
1011         int res = 0;
1012
1013         if (!manager || !peer_addr) {
1014                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1015                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1016         }
1017
1018         if (!manager->session && manager->state != WIFI_DIRECT_STATE_CONNECTING) {
1019                 WDS_LOGE("It's not CONNECTING state");//LCOV_EXCL_LINE
1020                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1021         }
1022
1023         res = wfd_session_cancel(manager->session, peer_addr);
1024         if (res < 0) {
1025                 WDS_LOGE("Failed to cancel session");//LCOV_EXCL_LINE
1026                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1027         }
1028
1029         group = (wfd_group_s*) manager->group;
1030         if (group)
1031                 member_cnt = wfd_group_remove_member(group, peer_addr);
1032         else
1033                 manager->local->dev_role = WFD_DEV_ROLE_NONE;
1034
1035         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1036                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1037                 if (member_cnt)
1038                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1039         } else {
1040                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1041                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1042         }
1043
1044         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1045         return WIFI_DIRECT_ERROR_NONE;
1046 }
1047
1048
1049 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
1050 {
1051         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1052         wfd_session_s *session = NULL;
1053         int res = 0;
1054
1055         if (!manager || !peer_addr) {
1056                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1057                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1058         }
1059
1060         session = (wfd_session_s*) manager->session;
1061         if (!session) {
1062                 WDS_LOGE("Session not found");//LCOV_EXCL_LINE
1063                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1064         }
1065
1066         if (manager->state != WIFI_DIRECT_STATE_CONNECTING) {
1067                 WDS_LOGE("It's not permitted with this state [%d]", manager->state);
1068                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1069         }
1070
1071         if (session->direction != SESSION_DIRECTION_INCOMING) {
1072                 WDS_LOGE("Only incomming session can be rejected");//LCOV_EXCL_LINE
1073                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1074         }
1075
1076         res = wfd_session_reject(session, peer_addr);
1077         if (res < 0) {
1078                 WDS_LOGE("Failed to reject connection");//LCOV_EXCL_LINE
1079                 /* TODO: check whether set state and break */
1080         }
1081         wfd_destroy_session(manager);
1082
1083         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1084                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1085                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1086         } else {
1087                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1088                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1089         }
1090
1091         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1092         return WIFI_DIRECT_ERROR_NONE;
1093 }
1094
1095
1096 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
1097 {
1098         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1099         wfd_group_s *group = NULL;
1100         wfd_device_s *peer = NULL;
1101         int res = 0;
1102
1103         if (!manager) {
1104                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1105                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1106         }
1107
1108         if (!peer_addr) {
1109                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1110                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1111         }
1112
1113         group = (wfd_group_s*) manager->group;
1114         if (!group) {
1115                 WDS_LOGE("Group not found");//LCOV_EXCL_LINE
1116                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1117         }
1118
1119         peer = wfd_group_find_member_by_addr(group, peer_addr);
1120         if (!peer) {
1121                 WDS_LOGE("Connected peer not found");//LCOV_EXCL_LINE
1122                 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
1123         }
1124
1125         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
1126         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCONNECTING);
1127
1128         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1129                 if (peer->is_p2p)
1130                         res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr, 0);
1131                 else
1132                         res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr, 1);
1133         } else {
1134                 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1135         }
1136
1137         if (res < 0) {
1138                 WDS_LOGE("Failed to disconnect peer");//LCOV_EXCL_LINE
1139                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1140                 goto failed;
1141         }
1142         WDS_LOGE("Succeeded to disconnect peer");//LCOV_EXCL_LINE
1143
1144         wfd_group_remove_member(group, peer_addr);
1145
1146         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1147                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1148                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1149         } else {
1150                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1151                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1152         }
1153
1154         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1155         return WIFI_DIRECT_ERROR_NONE;
1156
1157 failed:
1158         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1159                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1160                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1161         } else {
1162                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1163                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1164         }
1165
1166         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1167         return res;
1168 }
1169
1170 int wfd_manager_disconnect_all(wfd_manager_s *manager)
1171 {
1172         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1173         wfd_group_s *group = NULL;
1174         int res = 0;
1175
1176         if (!manager) {
1177                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1178                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1179         }
1180
1181         group = (wfd_group_s*) manager->group;
1182         if (!group) {
1183                 WDS_LOGE("Group not found");//LCOV_EXCL_LINE
1184                 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
1185         }
1186
1187         wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
1188         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCONNECTING);
1189
1190         res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1191         if (res < 0) {
1192                 WDS_LOGE("Failed to destroy group");//LCOV_EXCL_LINE
1193                 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1194                 goto failed;
1195         }
1196         WDS_LOGE("Succeeded to disconnect all peer");//LCOV_EXCL_LINE
1197
1198         wfd_destroy_group(manager);
1199
1200         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1201         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1202
1203         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1204         return WIFI_DIRECT_ERROR_NONE;
1205
1206 failed:
1207         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1208                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1209                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1210         } else {
1211                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1212                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1213         }
1214
1215         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1216         return res;
1217 }
1218
1219 int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
1220 {
1221         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1222         wfd_device_s *peer_dev = NULL;
1223         wfd_discovery_entry_s *peer_info;
1224         wfd_oem_device_s *oem_dev = NULL;
1225         int res = 0;
1226         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1227
1228         if (!manager || !addr) {
1229                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1230                 return -1;
1231         }
1232
1233         unsigned long time = 0;
1234 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1235         wfd_util_get_current_time(&time);
1236 #else
1237         struct timeval tval;
1238         gettimeofday(&tval, NULL);
1239         time = tval.tv_sec;
1240 #endif
1241         WDS_LOGI("Current time [%ld]", time);
1242 //LCOV_EXCL_START
1243         //wfd_manager_get_peer_info takes responsibility of the oem_dev' memory ownership.
1244         res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
1245         if (res < 0 || !oem_dev) {
1246                 WDS_LOGE("Failed to get peer information");//LCOV_EXCL_LINE
1247                 return -1;
1248         }
1249
1250         peer_dev = wfd_peer_find_by_addr(manager, addr);
1251         if (!peer_dev) {
1252                 peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
1253                 if (!peer_dev) {
1254                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1255                         WDS_LOGE("Failed to allocate memory for peer device. [%s]", error_buf);
1256                         if (oem_dev->vsie)
1257                                 g_free(oem_dev->vsie);
1258                         g_free(oem_dev);
1259                         return -1;
1260                 }
1261                 memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
1262                 manager->peers = g_list_prepend(manager->peers, peer_dev);
1263                 manager->peer_count++;
1264                 peer_dev->time = time;
1265                 WDS_LOGD("peer_count[%d]", manager->peer_count);
1266         } else {
1267                 if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
1268                         WDS_LOGE("Too old age to update peer");//LCOV_EXCL_LINE
1269                         if (oem_dev->vsie)
1270                                 g_free(oem_dev->vsie);
1271                         g_free(oem_dev);
1272                         return -1;
1273                 }
1274         }
1275
1276         g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
1277         memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
1278         memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
1279         peer_dev->dev_role = oem_dev->dev_role;
1280         peer_dev->config_methods = oem_dev->config_methods;
1281         peer_dev->pri_dev_type = oem_dev->pri_dev_type;
1282         peer_dev->sec_dev_type = oem_dev->sec_dev_type;
1283         peer_dev->dev_flags = oem_dev->dev_flags;
1284         peer_dev->group_flags = oem_dev->group_flags;
1285         peer_dev->wps_mode =  oem_dev->wps_mode;
1286
1287         if (manager->is_wifi_display_supported)
1288                 memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
1289
1290         peer_dev->time = time;
1291         peer_dev->channel = oem_dev->channel;
1292
1293         if (oem_dev->vsie) {
1294                 if (peer_dev->vsie)
1295                         g_free(peer_dev->vsie);
1296                 peer_dev->vsie = g_strdup(oem_dev->vsie);
1297                 g_free(oem_dev->vsie);
1298         }
1299
1300         g_free(oem_dev);
1301
1302         peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
1303         if (!(peer_info)) {
1304                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1305                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1306                 return -1;
1307         }
1308
1309         g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
1310         memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
1311         memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
1312         peer_info->channel = peer_dev->channel;
1313         peer_info->services = 0;
1314         peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
1315         peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1316         peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
1317         peer_info->wps_device_pwd_id = 0;
1318         peer_info->wps_cfg_methods = peer_dev->config_methods;
1319         peer_info->category = peer_dev->pri_dev_type;
1320         peer_info->subcategory = peer_dev->sec_dev_type;
1321
1322         if (manager->is_wifi_display_supported)
1323                 if (peer_dev->display.availability && peer_dev->display.port)
1324                         peer_info->is_wfd_device = 1;
1325
1326         if (peer_dev->vsie)
1327                 peer_info->vsie = g_strdup(peer_dev->vsie);
1328
1329         *peer = peer_info;
1330 //LCOV_EXCL_STOP
1331         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1332         return res;
1333 }
1334
1335
1336 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
1337 {
1338         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1339         GList *temp = NULL;
1340         wfd_device_s *peer = NULL;
1341         wfd_discovery_entry_s *peers = NULL;
1342         int peer_count = 0;
1343         int count = 0;
1344         int res = 0;
1345         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1346
1347         if (!manager || !peers_data) {
1348                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1349                 return -1;
1350         }
1351
1352         unsigned long time = 0;
1353 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1354         wfd_util_get_current_time(&time);
1355 #else
1356         struct timeval tval;
1357         gettimeofday(&tval, NULL);
1358         time = tval.tv_sec;
1359 #endif
1360         WDS_LOGI("Current time [%ld]", time);
1361
1362         peer_count = manager->peer_count;
1363         WDS_LOGI("peer count [%d]", peer_count);
1364         if (peer_count < 0)
1365                 return -1;
1366         else if (peer_count == 0)
1367                 return 0;
1368
1369         errno = 0;
1370         peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
1371         if (!peers) {
1372                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1373                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1374                 return -1;
1375         }
1376
1377         temp = g_list_first(manager->peers);
1378         while (temp && count < peer_count) {
1379                 peer = temp->data;
1380                 if (!peer)
1381                         goto next;
1382                 if (peer->time + 8 < time) {
1383                         WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
1384                         res = wfd_update_peer(manager, peer);
1385                         if (res < 0) {
1386                                 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
1387                                 temp = g_list_next(temp);
1388                                 manager->peers = g_list_remove(manager->peers, peer);
1389                                 manager->peer_count--;
1390                                 wfd_peer_destroy(peer);
1391                                 peer = NULL;
1392                                 continue;
1393                         }
1394                 }
1395
1396                 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1397                 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1398                 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1399                 peers[count].channel = peer->channel;
1400                 peers[count].services = 0;
1401                 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1402                 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1403                 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1404                 peers[count].wps_device_pwd_id = 0;
1405                 peers[count].wps_cfg_methods = peer->config_methods;
1406                 peers[count].category = peer->pri_dev_type;
1407                 peers[count].subcategory = peer->sec_dev_type;
1408
1409
1410                 if (manager->is_wifi_display_supported)
1411                         if (peer->display.availability && peer->display.port)
1412                                 peers[count].is_wfd_device = 1;
1413                 count++;
1414                 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1415 next:
1416                 temp = g_list_next(temp);
1417                 peer = NULL;
1418         }
1419         WDS_LOGD("%d peers converted", count);
1420         WDS_LOGD("Final peer count is %d", manager->peer_count);
1421
1422         *peers_data = peers;
1423
1424         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1425         return count;
1426 }
1427
1428 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1429 {
1430         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1431         wfd_connected_peer_info_s *peers = NULL;
1432         wfd_group_s *group = NULL;
1433         wfd_device_s *peer = NULL;
1434         GList *temp = NULL;
1435         int peer_count = 0;
1436         int count = 0;
1437         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1438
1439         if (!manager || !peers_data) {
1440                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1441                 return -1;
1442         }
1443
1444         group = manager->group;
1445         if (!group) {
1446                 WDS_LOGE("Group not exist");//LCOV_EXCL_LINE
1447                 return -1;
1448         }
1449
1450         peer_count = group->member_count;
1451         if (peer_count == 0) {
1452                 WDS_LOGD("Member not exist");//LCOV_EXCL_LINE
1453                 return 0;
1454         }
1455
1456         errno = 0;
1457         peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
1458         if (!peers) {
1459                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1460                 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", error_buf);
1461                 return -1;
1462         }
1463
1464         temp = g_list_first(group->members);
1465         while (temp && count < group->member_count) {
1466                 peer = temp->data;
1467                 {
1468                         g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1469                         memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1470                         memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1471                         memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1472                         peers[count].category = peer->pri_dev_type;
1473                         peers[count].subcategory = peer->sec_dev_type;
1474                         peers[count].channel = peer->channel;
1475                         peers[count].is_p2p = peer->is_p2p;
1476                         peers[count].services = 0;
1477
1478                         if (manager->is_wifi_display_supported)
1479                                 if (peer->display.availability && peer->display.port)
1480                                         peers[count].is_wfd_device = 1;
1481
1482                         WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1483                         count++;
1484                 }
1485                 temp = g_list_next(temp);
1486                 peer = NULL;
1487         }
1488         WDS_LOGD("%d members converted", count);
1489
1490         *peers_data = peers;
1491
1492         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1493         return count;
1494 }
1495
1496 wfd_device_s *wfd_manager_get_connected_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1497 {
1498         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1499         wfd_device_s *peer = NULL;
1500
1501         if (peer_addr == NULL) {
1502                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1503                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1504                 return peer;
1505         }
1506
1507         if (manager->group)
1508                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1509
1510         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1511         return peer;
1512 }
1513
1514 #if 0
1515 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1516 {
1517         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1518         wfd_device_s *peer = NULL;
1519
1520         if (!manager || !peer_addr) {
1521                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1522                 return NULL;
1523         }
1524
1525         peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1526
1527         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1528         return peer;
1529 }
1530 #endif
1531
1532 int wfd_manager_get_goup_ifname(char **ifname)
1533 {
1534         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1535         wfd_group_s *group = g_manager->group;
1536
1537         if (!ifname) {
1538                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1539                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1540                 return -1;
1541         }
1542
1543         if (!group) {
1544                 WDS_LOGE("Group not exist");//LCOV_EXCL_LINE
1545                 return -1;
1546         }
1547
1548         *ifname = group->ifname;
1549
1550         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1551         return 0;
1552 }
1553
1554 int wfd_manager_set_display_device(int type, int port, int hdcp)
1555 {
1556         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1557         wfd_device_s * device = g_manager->local;
1558         wfd_oem_display_s display;
1559         int res = 0;
1560
1561         if (!device) {
1562                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1563                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1564                 return -1;
1565         }
1566
1567         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1568
1569         display.type = type;
1570         display.port = port;
1571         display.hdcp_support = hdcp;
1572
1573         display.availability = device->display.availability;
1574         display.max_tput = device->display.max_tput;
1575
1576         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1577         if (res < 0) {
1578                 WDS_LOGE("Failed to set wifi display");//LCOV_EXCL_LINE
1579                 return -1;
1580         }
1581
1582         device->display.type = type;
1583         device->display.port = port;
1584         device->display.hdcp_support = hdcp;
1585
1586         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1587         return res;
1588 }
1589
1590 int wfd_manager_set_session_availability(int availability)
1591 {
1592         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1593         wfd_device_s * device = g_manager->local;
1594         wfd_oem_display_s display;
1595         int res = 0;
1596
1597         if (!device) {
1598                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1599                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1600                 return -1;
1601         }
1602
1603         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1604
1605         display.availability = availability;
1606
1607         display.type = device->display.type;
1608         display.hdcp_support = device->display.hdcp_support;
1609         display.port = device->display.port;
1610         display.max_tput = device->display.max_tput;
1611
1612         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1613         if (res < 0) {
1614                 WDS_LOGE("Failed to set wifi display session availability");//LCOV_EXCL_LINE
1615                 return -1;
1616         }
1617
1618         device->display.availability = availability;
1619
1620         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1621         return res;
1622 }
1623
1624 int wfd_manager_get_display_device(int *type, int *port, int *hdcp)
1625 {
1626         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1627         wfd_device_s *device = g_manager->local;
1628         int res = 0;
1629
1630         if (!device || !type || !port || !hdcp) {
1631                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1632                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1633                 return -1;
1634         }
1635
1636         *type = device->display.type;
1637         *port = device->display.port;
1638         *hdcp = device->display.hdcp_support;
1639
1640         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1641         return res;
1642 }
1643
1644 int wfd_manager_get_session_availability(int *availability)
1645 {
1646         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1647         wfd_device_s *device = g_manager->local;
1648         int res = 0;
1649
1650         if (!device || !availability) {
1651                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1652                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1653                 return -1;
1654         }
1655
1656         *availability = device->display.availability;
1657
1658         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1659         return res;
1660 }
1661
1662 int wfd_manager_start_discovery(wfd_manager_s *manager, int mode, int timeout,
1663                                 const char* type, int channel, int frequency)
1664 {
1665         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1666         int res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1667         wfd_oem_scan_param_s param;
1668         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
1669
1670         WDS_LOGI("Mode [%d], Timeout [%d], type [%s], channel [%d], frequency [%d]",
1671                  mode, timeout, type, channel, frequency);
1672
1673         if (manager->local->dev_role == WFD_DEV_ROLE_GO)
1674                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1675
1676         switch (channel) {
1677         case WFD_DISCOVERY_FULL_SCAN:
1678                 param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
1679                 break;
1680         case WFD_DISCOVERY_SOCIAL_CHANNEL:
1681                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1682                 break;
1683         case WFD_DISCOVERY_CHANNEL1:
1684                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL1;
1685                 param.freq = 2412;
1686                 break;
1687         case WFD_DISCOVERY_CHANNEL6:
1688                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL6;
1689                 param.freq = 2437;
1690                 break;
1691         case WFD_DISCOVERY_CHANNEL11:
1692                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL11;
1693                 param.freq = 2462;
1694                 break;
1695         default:
1696                 param.scan_type = WFD_OEM_SCAN_TYPE_SPECIFIC;
1697                 if (frequency > 0)
1698                         param.freq = frequency;
1699                 else
1700                         param.freq = wfd_util_channel_to_freq(channel);
1701         }
1702
1703         if (mode)
1704                 param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
1705         else
1706                 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
1707
1708         param.scan_time = timeout;
1709
1710         res = wfd_oem_start_scan(manager->oem_ops, &param);
1711         if (res < 0) {
1712                 WDS_LOGE("Failed to start scan");//LCOV_EXCL_LINE
1713                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1714                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1715         }
1716
1717         if (mode)
1718                 manager->scan_mode = WFD_SCAN_MODE_PASSIVE;
1719         else
1720                 manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
1721
1722         if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
1723                 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
1724                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
1725         }
1726
1727         WDS_LOGD("Succeeded to start scan");//LCOV_EXCL_LINE
1728         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1729         return WIFI_DIRECT_ERROR_NONE;
1730 }
1731
1732 int wfd_manager_cancel_discovery(wfd_manager_s *manager)
1733 {
1734         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1735         int res = 0;
1736
1737         res = wfd_oem_stop_scan(manager->oem_ops);
1738         if (res < 0) {
1739                 WDS_LOGE("Failed to stop scan");//LCOV_EXCL_LINE
1740                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1741                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1742         }
1743
1744         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1745                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1746                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1747         } else if (manager->local->dev_role == WFD_DEV_ROLE_GC) {
1748                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1749                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1750         } else {
1751                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1752                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1753         }
1754
1755         WDS_LOGD("Succeeded to stop scan");//LCOV_EXCL_LINE
1756         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1757         return WIFI_DIRECT_ERROR_NONE;
1758 }
1759
1760 wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1761 {
1762         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1763         wfd_device_s *peer = NULL;
1764         if (manager->group)
1765                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1766
1767         if (peer)
1768                 return peer;
1769
1770         peer = wfd_peer_find_by_addr(manager, peer_addr);
1771
1772         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1773         return peer;
1774 }
1775
1776 static wfd_manager_s *wfd_manager_init()
1777 {
1778         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1779         wfd_manager_s *manager = NULL;
1780         int res = 0;
1781
1782         manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
1783         if (!manager) {
1784                 WDS_LOGE("Failed to allocate memory for wfd_manager structure");//LCOV_EXCL_LINE
1785                 return NULL;
1786         }
1787
1788         manager->wfd_oem_conf = (wfd_oem_config_s*) g_try_malloc0(sizeof(wfd_oem_config_s));
1789         if (!manager->wfd_oem_conf) {
1790                 g_free(manager);
1791                 WDS_LOGE("Failed to allocate memory for wfd_oem_conf structure");//LCOV_EXCL_LINE
1792                 return NULL;
1793         }
1794
1795         manager->go_intent = 7;
1796         manager->req_wps_mode = WFD_WPS_MODE_PBC;
1797         manager->max_station = 8;
1798         manager->session_timer = 120;
1799         manager->auto_group_remove_enable = TRUE;
1800
1801         manager->go_intent_per_type[WFD_DISPLAY_TYPE_SOURCE] = WFD_GO_INTENT_DISPLY_SOURCE;
1802         manager->go_intent_per_type[WFD_DISPLAY_TYPE_PRISINK] = WFD_GO_INTENT_MAX;
1803         manager->go_intent_per_type[WFD_DISPLAY_TYPE_SECSINK] = WFD_GO_INTENT_MAX;
1804         manager->go_intent_per_type[WFD_DISPLAY_TYPE_DUAL] = WFD_GO_INTENT_MAX;
1805         manager->go_intent_per_type[WFD_DISPLAY_TYPE_NONE] = WFD_GO_INTENT_MAX;
1806
1807         wfd_util_check_features(manager);
1808         wfd_util_load_wfd_conf(manager);
1809
1810         res = _wfd_local_init_device(manager);
1811         if (res < 0) {
1812                 WDS_LOGE("Failed to initialize local device");//LCOV_EXCL_LINE
1813                 g_free(manager->wfd_oem_conf);
1814                 g_free(manager);
1815                 return NULL;            /* really stop manager? */
1816         }
1817         WDS_LOGD("Succeeded to initialize local device");//LCOV_EXCL_LINE
1818
1819         manager->client_count = 0;
1820         manager->client_list = NULL;
1821         if (manager->is_on_demand) {
1822                 manager->exit_timer = g_timeout_add(120000,
1823                                                         (GSourceFunc) _wfd_exit_timeout_cb, manager);
1824                 WDS_LOGD("Exit timer started");//LCOV_EXCL_LINE
1825         }
1826
1827
1828         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1829         return manager;
1830 }
1831
1832 int wfd_manager_deinit(wfd_manager_s *manager)
1833 {
1834         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1835
1836         if (!manager) {
1837                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1838                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1839                 return -1;
1840         }
1841
1842         if (manager->is_on_demand && manager->exit_timer > 0) {
1843                 g_source_remove(manager->exit_timer);
1844                 manager->exit_timer = 0;
1845         }
1846
1847         _wfd_local_deinit_device(manager);
1848
1849         g_free(manager->wfd_oem_conf);
1850         g_free(manager);
1851
1852         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1853         return 0;
1854 }
1855
1856 int wfd_manager_load()
1857 {
1858         int res = 0;
1859         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1860
1861         /* TODO: Parsing argument */
1862         /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1863
1864         /**
1865          * wfd-manager initialization
1866          */
1867         g_manager = wfd_manager_init();
1868         if (!g_manager) {
1869                 WDS_LOGE("Failed to initialize wifi-direct manager");//LCOV_EXCL_LINE
1870                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1871                 return -1;
1872         }
1873         WDS_LOGD("Succeeded to initialize manager");//LCOV_EXCL_LINE
1874
1875         res = wfd_util_get_local_dev_mac(g_manager->local->dev_addr);
1876         if (res < 0)
1877                 WDS_LOGE("Failed to get local device MAC address");//LCOV_EXCL_LINE
1878
1879         if (wfd_manager_iface_init() != 0) {
1880                 WDS_LOGE("Failed to initialize iface");//LCOV_EXCL_LINE
1881                 wfd_manager_deinit(g_manager);
1882                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1883                 return -1;
1884         }
1885         WDS_LOGD("Succeeded to load iface");//LCOV_EXCL_LINE
1886
1887         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1888         return 0;
1889 }
1890
1891 void wfd_manager_unload()
1892 {
1893         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1894
1895         wfd_manager_iface_deinit();
1896         wfd_manager_deinit(g_manager);
1897         g_manager = NULL;
1898
1899         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1900         return;
1901 }