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