Fix several invalid read/write memory and definitely lost memory
[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         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                         free(oem_dev);
1257                         return -1;
1258                 }
1259                 memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
1260                 manager->peers = g_list_prepend(manager->peers, peer_dev);
1261                 manager->peer_count++;
1262                 peer_dev->time = time;
1263                 WDS_LOGD("peer_count[%d]", manager->peer_count);
1264         } else {
1265                 if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
1266                         WDS_LOGE("Too old age to update peer");//LCOV_EXCL_LINE
1267                         free(oem_dev);
1268                         return -1;
1269                 }
1270         }
1271
1272         g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
1273         memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
1274         memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
1275         peer_dev->dev_role = oem_dev->dev_role;
1276         peer_dev->config_methods = oem_dev->config_methods;
1277         peer_dev->pri_dev_type = oem_dev->pri_dev_type;
1278         peer_dev->sec_dev_type = oem_dev->sec_dev_type;
1279         peer_dev->dev_flags = oem_dev->dev_flags;
1280         peer_dev->group_flags = oem_dev->group_flags;
1281         peer_dev->wps_mode =  oem_dev->wps_mode;
1282
1283         if (manager->is_wifi_display_supported)
1284                 memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
1285
1286         peer_dev->time = time;
1287         peer_dev->channel = oem_dev->channel;
1288
1289         if (oem_dev->vsie) {
1290                 if (peer_dev->vsie)
1291                         g_free(peer_dev->vsie);
1292                 peer_dev->vsie = g_strdup(oem_dev->vsie);
1293                 g_free(oem_dev->vsie);
1294         }
1295
1296         g_free(oem_dev);
1297
1298         peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
1299         if (!(peer_info)) {
1300                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1301                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1302                 return -1;
1303         }
1304
1305         g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
1306         memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
1307         memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
1308         peer_info->channel = peer_dev->channel;
1309         peer_info->services = 0;
1310         peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
1311         peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1312         peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
1313         peer_info->wps_device_pwd_id = 0;
1314         peer_info->wps_cfg_methods = peer_dev->config_methods;
1315         peer_info->category = peer_dev->pri_dev_type;
1316         peer_info->subcategory = peer_dev->sec_dev_type;
1317
1318         if (manager->is_wifi_display_supported)
1319                 if (peer_dev->display.availability && peer_dev->display.port)
1320                         peer_info->is_wfd_device = 1;
1321
1322         if (peer_dev->vsie)
1323                 peer_info->vsie = g_strdup(peer_dev->vsie);
1324
1325         *peer = peer_info;
1326 //LCOV_EXCL_STOP
1327         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1328         return res;
1329 }
1330
1331
1332 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
1333 {
1334         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1335         GList *temp = NULL;
1336         wfd_device_s *peer = NULL;
1337         wfd_discovery_entry_s *peers = NULL;
1338         int peer_count = 0;
1339         int count = 0;
1340         int res = 0;
1341         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1342
1343         if (!manager || !peers_data) {
1344                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1345                 return -1;
1346         }
1347
1348         unsigned long time = 0;
1349 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1350         wfd_util_get_current_time(&time);
1351 #else
1352         struct timeval tval;
1353         gettimeofday(&tval, NULL);
1354         time = tval.tv_sec;
1355 #endif
1356         WDS_LOGI("Current time [%ld]", time);
1357
1358         peer_count = manager->peer_count;
1359         WDS_LOGI("peer count [%d]", peer_count);
1360         if (peer_count < 0)
1361                 return -1;
1362         else if (peer_count == 0)
1363                 return 0;
1364
1365         errno = 0;
1366         peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
1367         if (!peers) {
1368                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1369                 WDS_LOGE("Failed to allocate memory for peer data. [%s]", error_buf);
1370                 return -1;
1371         }
1372
1373         temp = g_list_first(manager->peers);
1374         while (temp && count < peer_count) {
1375                 peer = temp->data;
1376                 if (!peer)
1377                         goto next;
1378                 if (peer->time + 8 < time) {
1379                         WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
1380                         res = wfd_update_peer(manager, peer);
1381                         if (res < 0) {
1382                                 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
1383                                 temp = g_list_next(temp);
1384                                 manager->peers = g_list_remove(manager->peers, peer);
1385                                 manager->peer_count--;
1386                                 g_free(peer);
1387                                 peer = NULL;
1388                                 continue;
1389                         }
1390                 }
1391
1392                 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1393                 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1394                 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1395                 peers[count].channel = peer->channel;
1396                 peers[count].services = 0;
1397                 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1398                 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1399                 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1400                 peers[count].wps_device_pwd_id = 0;
1401                 peers[count].wps_cfg_methods = peer->config_methods;
1402                 peers[count].category = peer->pri_dev_type;
1403                 peers[count].subcategory = peer->sec_dev_type;
1404
1405
1406                 if (manager->is_wifi_display_supported)
1407                         if (peer->display.availability && peer->display.port)
1408                                 peers[count].is_wfd_device = 1;
1409                 count++;
1410                 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1411 next:
1412                 temp = g_list_next(temp);
1413                 peer = NULL;
1414         }
1415         WDS_LOGD("%d peers converted", count);
1416         WDS_LOGD("Final peer count is %d", manager->peer_count);
1417
1418         *peers_data = peers;
1419
1420         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1421         return count;
1422 }
1423
1424 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1425 {
1426         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1427         wfd_connected_peer_info_s *peers = NULL;
1428         wfd_group_s *group = NULL;
1429         wfd_device_s *peer = NULL;
1430         GList *temp = NULL;
1431         int peer_count = 0;
1432         int count = 0;
1433         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1434
1435         if (!manager || !peers_data) {
1436                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1437                 return -1;
1438         }
1439
1440         group = manager->group;
1441         if (!group) {
1442                 WDS_LOGE("Group not exist");//LCOV_EXCL_LINE
1443                 return -1;
1444         }
1445
1446         peer_count = group->member_count;
1447         if (peer_count == 0) {
1448                 WDS_LOGD("Member not exist");//LCOV_EXCL_LINE
1449                 return 0;
1450         }
1451
1452         errno = 0;
1453         peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
1454         if (!peers) {
1455                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1456                 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", error_buf);
1457                 return -1;
1458         }
1459
1460         temp = g_list_first(group->members);
1461         while (temp && count < group->member_count) {
1462                 peer = temp->data;
1463                 {
1464                         g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1465                         memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1466                         memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1467                         memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1468                         peers[count].category = peer->pri_dev_type;
1469                         peers[count].subcategory = peer->sec_dev_type;
1470                         peers[count].channel = peer->channel;
1471                         peers[count].is_p2p = peer->is_p2p;
1472                         peers[count].services = 0;
1473
1474                         if (manager->is_wifi_display_supported)
1475                                 if (peer->display.availability && peer->display.port)
1476                                         peers[count].is_wfd_device = 1;
1477
1478                         WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1479                         count++;
1480                 }
1481                 temp = g_list_next(temp);
1482                 peer = NULL;
1483         }
1484         WDS_LOGD("%d members converted", count);
1485
1486         *peers_data = peers;
1487
1488         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1489         return count;
1490 }
1491
1492 wfd_device_s *wfd_manager_get_connected_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1493 {
1494         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1495         wfd_device_s *peer = NULL;
1496
1497         if (peer_addr == NULL) {
1498                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1499                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1500                 return peer;
1501         }
1502
1503         if (manager->group)
1504                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1505
1506         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1507         return peer;
1508 }
1509
1510 #if 0
1511 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1512 {
1513         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1514         wfd_device_s *peer = NULL;
1515
1516         if (!manager || !peer_addr) {
1517                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1518                 return NULL;
1519         }
1520
1521         peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1522
1523         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1524         return peer;
1525 }
1526 #endif
1527
1528 int wfd_manager_get_goup_ifname(char **ifname)
1529 {
1530         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1531         wfd_group_s *group = g_manager->group;
1532
1533         if (!ifname) {
1534                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1535                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1536                 return -1;
1537         }
1538
1539         if (!group) {
1540                 WDS_LOGE("Group not exist");//LCOV_EXCL_LINE
1541                 return -1;
1542         }
1543
1544         *ifname = group->ifname;
1545
1546         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1547         return 0;
1548 }
1549
1550 int wfd_manager_set_display_device(int type, int port, int hdcp)
1551 {
1552         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1553         wfd_device_s * device = g_manager->local;
1554         wfd_oem_display_s display;
1555         int res = 0;
1556
1557         if (!device) {
1558                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1559                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1560                 return -1;
1561         }
1562
1563         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1564
1565         display.type = type;
1566         display.port = port;
1567         display.hdcp_support = hdcp;
1568
1569         display.availability = device->display.availability;
1570         display.max_tput = device->display.max_tput;
1571
1572         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1573         if (res < 0) {
1574                 WDS_LOGE("Failed to set wifi display");//LCOV_EXCL_LINE
1575                 return -1;
1576         }
1577
1578         device->display.type = type;
1579         device->display.port = port;
1580         device->display.hdcp_support = hdcp;
1581
1582         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1583         return res;
1584 }
1585
1586 int wfd_manager_set_session_availability(int availability)
1587 {
1588         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1589         wfd_device_s * device = g_manager->local;
1590         wfd_oem_display_s display;
1591         int res = 0;
1592
1593         if (!device) {
1594                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1595                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1596                 return -1;
1597         }
1598
1599         memset(&display, 0x0, sizeof(wfd_oem_display_s));
1600
1601         display.availability = availability;
1602
1603         display.type = device->display.type;
1604         display.hdcp_support = device->display.hdcp_support;
1605         display.port = device->display.port;
1606         display.max_tput = device->display.max_tput;
1607
1608         res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1609         if (res < 0) {
1610                 WDS_LOGE("Failed to set wifi display session availability");//LCOV_EXCL_LINE
1611                 return -1;
1612         }
1613
1614         device->display.availability = availability;
1615
1616         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1617         return res;
1618 }
1619
1620 int wfd_manager_get_display_device(int *type, int *port, int *hdcp)
1621 {
1622         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1623         wfd_device_s *device = g_manager->local;
1624         int res = 0;
1625
1626         if (!device || !type || !port || !hdcp) {
1627                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1628                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1629                 return -1;
1630         }
1631
1632         *type = device->display.type;
1633         *port = device->display.port;
1634         *hdcp = device->display.hdcp_support;
1635
1636         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1637         return res;
1638 }
1639
1640 int wfd_manager_get_session_availability(int *availability)
1641 {
1642         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1643         wfd_device_s *device = g_manager->local;
1644         int res = 0;
1645
1646         if (!device || !availability) {
1647                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1648                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1649                 return -1;
1650         }
1651
1652         *availability = device->display.availability;
1653
1654         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1655         return res;
1656 }
1657
1658 int wfd_manager_start_discovery(wfd_manager_s *manager, int mode, int timeout,
1659                                 const char* type, int channel, int frequency)
1660 {
1661         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1662         int res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
1663         wfd_oem_scan_param_s param;
1664         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
1665
1666         WDS_LOGI("Mode [%d], Timeout [%d], type [%s], channel [%d], frequency [%d]",
1667                  mode, timeout, type, channel, frequency);
1668
1669         if (manager->local->dev_role == WFD_DEV_ROLE_GO)
1670                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1671
1672         switch (channel) {
1673         case WFD_DISCOVERY_FULL_SCAN:
1674                 param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
1675                 break;
1676         case WFD_DISCOVERY_SOCIAL_CHANNEL:
1677                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
1678                 break;
1679         case WFD_DISCOVERY_CHANNEL1:
1680                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL1;
1681                 param.freq = 2412;
1682                 break;
1683         case WFD_DISCOVERY_CHANNEL6:
1684                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL6;
1685                 param.freq = 2437;
1686                 break;
1687         case WFD_DISCOVERY_CHANNEL11:
1688                 param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL11;
1689                 param.freq = 2462;
1690                 break;
1691         default:
1692                 param.scan_type = WFD_OEM_SCAN_TYPE_SPECIFIC;
1693                 if (frequency > 0)
1694                         param.freq = frequency;
1695                 else
1696                         param.freq = wfd_util_channel_to_freq(channel);
1697         }
1698
1699         if (mode)
1700                 param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
1701         else
1702                 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
1703
1704         param.scan_time = timeout;
1705
1706         res = wfd_oem_start_scan(manager->oem_ops, &param);
1707         if (res < 0) {
1708                 WDS_LOGE("Failed to start scan");//LCOV_EXCL_LINE
1709                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1710                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1711         }
1712
1713         if (mode)
1714                 manager->scan_mode = WFD_SCAN_MODE_PASSIVE;
1715         else
1716                 manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
1717
1718         if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
1719                 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
1720                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
1721         }
1722
1723         WDS_LOGD("Succeeded to start scan");//LCOV_EXCL_LINE
1724         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1725         return WIFI_DIRECT_ERROR_NONE;
1726 }
1727
1728 int wfd_manager_cancel_discovery(wfd_manager_s *manager)
1729 {
1730         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1731         int res = 0;
1732
1733         res = wfd_oem_stop_scan(manager->oem_ops);
1734         if (res < 0) {
1735                 WDS_LOGE("Failed to stop scan");//LCOV_EXCL_LINE
1736                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1737                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1738         }
1739
1740         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1741                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1742                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1743         } else {
1744                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1745                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1746         }
1747
1748         WDS_LOGD("Succeeded to stop scan");//LCOV_EXCL_LINE
1749         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1750         return WIFI_DIRECT_ERROR_NONE;
1751 }
1752
1753 wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1754 {
1755         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1756         wfd_device_s *peer = NULL;
1757         if (manager->group)
1758                 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1759
1760         if (peer)
1761                 return peer;
1762
1763         peer = wfd_peer_find_by_addr(manager, peer_addr);
1764
1765         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1766         return peer;
1767 }
1768
1769 static wfd_manager_s *wfd_manager_init()
1770 {
1771         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1772         wfd_manager_s *manager = NULL;
1773         int res = 0;
1774
1775         manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
1776         if (!manager) {
1777                 WDS_LOGE("Failed to allocate memory for wfd_manager structure");//LCOV_EXCL_LINE
1778                 return NULL;
1779         }
1780
1781         manager->wfd_oem_conf = (wfd_oem_config_s*) g_try_malloc0(sizeof(wfd_oem_config_s));
1782         if (!manager->wfd_oem_conf) {
1783                 g_free(manager);
1784                 WDS_LOGE("Failed to allocate memory for wfd_oem_conf structure");//LCOV_EXCL_LINE
1785                 return NULL;
1786         }
1787
1788         manager->go_intent = 7;
1789         manager->req_wps_mode = WFD_WPS_MODE_PBC;
1790         manager->max_station = 8;
1791         manager->session_timer = 120;
1792         manager->auto_group_remove_enable = TRUE;
1793
1794         manager->go_intent_per_type[WFD_DISPLAY_TYPE_SOURCE] = WFD_GO_INTENT_DISPLY_SOURCE;
1795         manager->go_intent_per_type[WFD_DISPLAY_TYPE_PRISINK] = WFD_GO_INTENT_MAX;
1796         manager->go_intent_per_type[WFD_DISPLAY_TYPE_SECSINK] = WFD_GO_INTENT_MAX;
1797         manager->go_intent_per_type[WFD_DISPLAY_TYPE_DUAL] = WFD_GO_INTENT_MAX;
1798         manager->go_intent_per_type[WFD_DISPLAY_TYPE_NONE] = WFD_GO_INTENT_MAX;
1799
1800         wfd_util_check_features(manager);
1801         wfd_util_load_wfd_conf(manager);
1802
1803         res = _wfd_local_init_device(manager);
1804         if (res < 0) {
1805                 WDS_LOGE("Failed to initialize local device");//LCOV_EXCL_LINE
1806                 g_free(manager->wfd_oem_conf);
1807                 g_free(manager);
1808                 return NULL;            /* really stop manager? */
1809         }
1810         WDS_LOGD("Succeeded to initialize local device");//LCOV_EXCL_LINE
1811
1812         manager->client_count = 0;
1813         manager->client_list = NULL;
1814         if (manager->is_on_demand) {
1815                 manager->exit_timer = g_timeout_add(120000,
1816                                                         (GSourceFunc) _wfd_exit_timeout_cb, manager);
1817                 WDS_LOGD("Exit timer started");//LCOV_EXCL_LINE
1818         }
1819
1820
1821         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1822         return manager;
1823 }
1824
1825 int wfd_manager_deinit(wfd_manager_s *manager)
1826 {
1827         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1828
1829         if (!manager) {
1830                 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
1831                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1832                 return -1;
1833         }
1834
1835         if (manager->is_on_demand && manager->exit_timer > 0) {
1836                 g_source_remove(manager->exit_timer);
1837                 manager->exit_timer = 0;
1838         }
1839
1840         _wfd_local_deinit_device(manager);
1841
1842         g_free(manager->wfd_oem_conf);
1843         g_free(manager);
1844
1845         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1846         return 0;
1847 }
1848
1849 int wfd_manager_load()
1850 {
1851         int res = 0;
1852         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1853
1854         /* TODO: Parsing argument */
1855         /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1856
1857         /**
1858          * wfd-manager initialization
1859          */
1860         g_manager = wfd_manager_init();
1861         if (!g_manager) {
1862                 WDS_LOGE("Failed to initialize wifi-direct manager");//LCOV_EXCL_LINE
1863                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1864                 return -1;
1865         }
1866         WDS_LOGD("Succeeded to initialize manager");//LCOV_EXCL_LINE
1867
1868         res = wfd_util_get_local_dev_mac(g_manager->local->dev_addr);
1869         if (res < 0)
1870                 WDS_LOGE("Failed to get local device MAC address");//LCOV_EXCL_LINE
1871
1872         if (wfd_manager_iface_init() != 0) {
1873                 WDS_LOGE("Failed to initialize iface");//LCOV_EXCL_LINE
1874                 wfd_manager_deinit(g_manager);
1875                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1876                 return -1;
1877         }
1878         WDS_LOGD("Succeeded to load iface");//LCOV_EXCL_LINE
1879
1880         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1881         return 0;
1882 }
1883
1884 void wfd_manager_unload()
1885 {
1886         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1887
1888         wfd_manager_iface_deinit();
1889         wfd_manager_deinit(g_manager);
1890         g_manager = NULL;
1891
1892         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1893         return;
1894 }