Add legacy connection handler for addtional group iface
[platform/core/connectivity/wifi-direct-manager.git] / plugin / wpasupplicant / ctrl_iface_dbus / wfd-plugin-wpasupplicant.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 wpasupplicant dbus plugin functions.
22  *
23  * @file                wfd-plugin-dbus-wpasupplicant.c
24  * @author      Jiung Yu (jiung.yu@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <sys/socket.h>
34 #include <sys/un.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #define _GNU_SOURCE
38 #include <poll.h>
39 #include <errno.h>
40 #include <sys/ioctl.h>
41 #include <net/if.h>
42
43 #include <glib.h>
44 #include <gio/gio.h>
45
46 #include <tzplatform_config.h>
47 #include <hal-wifi.h>
48
49 #include "wifi-direct-oem.h"
50 #include "wfd-plugin-log.h"
51 #include "dbus/wfd-plugin-supplicant-dbus.h"
52 #include "wfd-plugin-wpasupplicant.h"
53
54 #define GLIST_ITER_START(arg_list, elem)\
55         GList *temp = NULL;\
56         temp = g_list_first(arg_list);\
57         while (temp) {\
58                 elem = temp->data;\
59                 temp = g_list_next(temp);\
60
61 #define GLIST_ITER_END() }
62
63 #define NETCONFIG_SERVICE "net.netconfig"
64 #define NETCONFIG_WIFI_INTERFACE "net.netconfig.wifi"
65 #define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
66
67 #define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
68
69 #define CONF_FILE_PATH tzplatform_mkpath(TZ_SYS_ETC, "wpa_supplicant/wpa_supplicant.conf")
70 #define MAX_FILE_PATH_LEN 256
71
72 static wfd_oem_ops_s supplicant_ops = {
73         .configure = ws_configure,
74         .init = ws_init,
75         .deinit = ws_deinit,
76         .activate = ws_activate,
77         .deactivate = ws_deactivate,
78
79         .start_scan = ws_start_scan,
80         .stop_scan = ws_stop_scan,
81         .get_visibility = ws_get_visibility,
82         .set_visibility = ws_set_visibility,
83         .get_scan_result = ws_get_scan_result,
84         .get_peer_info = ws_get_peer_info,
85
86         .prov_disc_req = ws_prov_disc_req,
87
88         .connect = ws_connect,
89         .disconnect = ws_disconnect,
90         .reject_connection = ws_reject_connection,
91         .cancel_connection = ws_cancel_connection,
92
93         .get_connected_peers = ws_get_connected_peers,
94         .get_pin = ws_get_pin,
95         .set_pin = ws_set_pin,
96         .generate_pin = ws_generate_pin,
97         .get_supported_wps_mode = ws_get_supported_wps_mode,
98
99         .create_group = ws_create_group,
100         .destroy_group = ws_destroy_group,
101         .invite = ws_invite,
102         .wps_start = ws_wps_start,
103         .enrollee_start = ws_enrollee_start,
104         .wps_cancel = ws_wps_cancel,
105
106         .get_dev_name = ws_get_dev_name,
107         .set_dev_name = ws_set_dev_name,
108         .get_dev_mac = ws_get_dev_mac,
109         .get_dev_type = ws_get_dev_type,
110         .set_dev_type = ws_set_dev_type,
111         .get_go_intent = ws_get_go_intent,
112         .set_go_intent = ws_set_go_intent,
113         .set_country = ws_set_country,
114         .get_persistent_groups = ws_get_persistent_groups,
115         .remove_persistent_group = ws_remove_persistent_group,
116         .set_persistent_reconnect = ws_set_persistent_reconnect,
117
118         .start_service_discovery = ws_start_service_discovery,
119         .cancel_service_discovery = ws_cancel_service_discovery,
120
121         .serv_add = ws_serv_add,
122         .serv_del = ws_serv_del,
123
124         .miracast_init = ws_miracast_init,
125         .set_display = ws_set_display,
126
127         .refresh = ws_refresh,
128         .save_config =  ws_save_config,
129         .set_operating_channel = ws_set_operating_channel,
130         .remove_all_network = ws_remove_all_network,
131         .get_wpa_status = ws_get_wpa_status,
132
133         .advertise_service = ws_advertise_service,
134         .cancel_advertise_service = ws_cancel_advertise_service,
135         .seek_service = ws_seek_service,
136         .cancel_seek_service = ws_cancel_seek_service,
137         .asp_prov_disc_req = ws_asp_prov_disc_req,
138
139         .set_eapol_ip_config = ws_set_eapol_ip_config,
140
141         .add_vsie = ws_add_vsie,
142         .get_vsie = ws_get_vsie,
143         .remove_vsie = ws_remove_vsie,
144         .set_supported_wps_mode = ws_set_supported_wps_mode,
145         .remove_persistent_device = ws_remove_persistent_device,
146         .remove_all_persistent_device = ws_remove_all_persistent_device,
147
148         .get_supported_channels = ws_get_supported_channels,
149
150         .extra_data = NULL
151 };
152
153 static ws_dbus_plugin_data_s *g_pd;
154 static wfd_oem_config_s *config = NULL;
155 static int is_peer_joined_notified = 0;
156 static int is_peer_disconnected_notified = 0;
157 static int wps_config_method = WFD_OEM_WPS_MODE_PBC|WFD_OEM_WPS_MODE_DISPLAY|WFD_OEM_WPS_MODE_KEYPAD;
158
159 static GList *service_list;
160 static GList *seek_list;
161
162 static int __ws_txt_to_mac(unsigned char *txt, unsigned char *mac)
163 {
164         int i = 0;
165
166         if (!txt || !mac) {
167                 WDP_LOGE("Invalid parameter");
168                 return -1;
169         }
170
171         for (;;) {
172                 mac[i++] = (char) strtoul((char *)txt, (char **)&txt, 16);
173                 if (!*txt++ || i == 6)
174                         break;
175         }
176
177         if (i != WS_MACADDR_LEN)
178                 return -1;
179
180         WDP_LOGD("Converted MAC address [" MACSECSTR "]", MAC2SECSTR(mac));
181         return 0;
182 }
183
184 static int __ws_mac_compact_to_normal(char *compact, unsigned char *mac)
185 {
186         g_snprintf((char *)mac, OEM_MACSTR_LEN, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
187                         compact[0], compact[1], compact[2], compact[3],
188                         compact[4], compact[5], compact[6], compact[7],
189                         compact[8], compact[9], compact[10], compact[11]);
190         return 0;
191 }
192
193 static const char *__ws_wps_to_txt(int wps_mode)
194 {
195         switch (wps_mode) {
196         case WFD_OEM_WPS_MODE_PBC:
197                 return WS_DBUS_STR_PBC;
198         case WFD_OEM_WPS_MODE_DISPLAY:
199                 return WS_DBUS_STR_DISPLAY;
200         case WFD_OEM_WPS_MODE_KEYPAD:
201                 return WS_DBUS_STR_KEYPAD;
202         case WFD_OEM_WPS_MODE_NONE:
203         case WFD_OEM_WPS_MODE_P2PS:
204                 return WS_DBUS_STR_P2PS;
205         default:
206                 return "";
207         }
208 }
209
210 static int __ws_hex_char_to_num(char c)
211 {
212         if (c >= '0' && c <= '9')
213                 return c - '0';
214
215         if (c >= 'a' && c <= 'f')
216                 return c - 'a' + 10;
217
218         if (c >= 'A' && c <= 'F')
219                 return c - 'A' + 10;
220
221         return -1;
222 }
223
224 static int __ws_hex_to_byte(const char *hex)
225 {
226         int a, b;
227
228         a = __ws_hex_char_to_num(*hex++);
229         if (a < 0)
230                 return -1;
231
232         b = __ws_hex_char_to_num(*hex++);
233         if (b < 0)
234                 return -1;
235
236         return (a << 4) | b;
237 }
238
239 static int __ws_hex_str_to_bin(const char *hex, unsigned char *buf, size_t len)
240 {
241         size_t i;
242         int a;
243         const char *ipos = hex;
244         unsigned char *opos = buf;
245
246         for (i = 0; i < len; i++) {
247                 a = __ws_hex_to_byte(ipos);
248                 if (a < 0)
249                         return -1;
250
251                 *opos++ = a;
252                 ipos += 2;
253         }
254
255         return 0;
256 }
257
258 static int __ws_byte_to_hex(char *buf, int buf_size, unsigned char *data, int data_len)
259 {
260         int i;
261         char *pos = buf;
262         char *end = buf + buf_size;
263         int ret;
264         if (buf_size == 0)
265                 return 0;
266         for (i = 0; i < data_len; i++) {
267                 ret = snprintf(pos, end - pos, "%02x", data[i]);
268                 if (ret < 0 || ret >= end - pos) {
269                         end[-1] = '\0';
270                         return pos - buf;
271                 }
272                 pos += ret;
273         }
274         end[-1] = '\0';
275         return pos - buf;
276 }
277
278 static int __ws_hex_to_num(char *src, int len)
279 {
280         char *temp = NULL;
281         int num = 0;
282
283         if (!src || len < 0) {
284                 WDP_LOGE("Invalid parameter");
285                 return -1;
286         }
287
288         temp = (char*) g_try_malloc0(len+1);
289         if (!temp) {
290                 WDP_LOGE("Failed to allocate memory");
291                 return -1;
292         }
293
294         memcpy(temp, src, len);
295         num = strtoul(temp, NULL, 16);
296         g_free(temp);
297
298         return num;
299 }
300
301 static int __ws_segment_to_service(char *segment, wfd_oem_new_service_s **service)
302 {
303         wfd_oem_new_service_s *serv_tmp = NULL;
304         char *ptr = NULL;
305         char *temp = NULL;
306         int i = 0;
307
308         if (!segment || !service) {
309                 WDP_LOGE("Invalid parameter");
310                 return -1;
311         }
312
313         ptr = segment;
314         WDP_LOGD("Segment: %s", segment);
315
316         serv_tmp = (wfd_oem_new_service_s*) g_try_malloc0(sizeof(wfd_oem_new_service_s));
317         if (!serv_tmp) {
318                 WDP_LOGE("Failed to allocate memory for service");
319                 return -1;
320         }
321
322         serv_tmp->protocol = __ws_hex_to_num(ptr, 2);
323         serv_tmp->trans_id = __ws_hex_to_num(ptr+2, 2);
324         serv_tmp->status = __ws_hex_to_num(ptr+4, 2);
325         ptr += 6;
326         WDP_LOGD("Protocol[%d], Transaction ID[%d], Status[%d]", serv_tmp->protocol, serv_tmp->trans_id, serv_tmp->status);
327
328         if (serv_tmp->status != 0) {
329                 WDP_LOGE("Service status is not success");
330                 g_free(serv_tmp);
331                 return -1;
332         }
333
334         if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
335                 WDP_LOGD("===== Bonjour service =====");
336                 char compr[5] = {0, };
337                 char query[256] = {0, };
338                 char rdata[256] = {0, };
339                 int dns_type = 0;
340
341                 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
342                         unsigned long int size = 0;
343                         char temp_str[3] = {0,};
344                         memcpy(temp_str, ptr, 2);
345                         size = strtoul(temp_str, NULL, 16);
346                         ptr += 2;
347                         if (size <= 0xff) {
348                                 temp = (char*) calloc(1, size + 2);
349                                 if (temp) {
350                                         temp[0] = '.';
351                                         for (i = 0; i < size; i++) {
352                                                 temp[i+1] = (char) __ws_hex_to_num(ptr, 2);
353                                                 ptr += 2;
354                                         }
355                                         g_strlcat(query, temp, sizeof(query));
356                                         g_free(temp);
357                                         temp = NULL;
358                                 }
359                         }
360                 }
361
362                 if (!strncmp(ptr, "c0", 2)) {
363                         memcpy(compr, ptr, 4);
364                         ptr += 2;
365
366                         if (!strncmp(ptr, "27", 2)) {
367                                 WDP_LOGD("Segment ended");
368                                 ptr += 2;
369                         } else {
370                                 ptr += 2;
371                                 dns_type = __ws_hex_to_num(ptr, 4);
372                                 ptr += 6;
373                                 if (dns_type == 12) {
374                                         if (!strncmp(compr, "c011", 4))
375                                                 g_strlcat(query, ".local.", sizeof(query));
376                                         else if (!strncmp(compr, "c00c", 4))
377                                                 g_strlcat(query, "._tcp.local.", sizeof(query));
378                                         else if (!strncmp(compr, "c01c", 4))
379                                                 g_strlcat(query, "._udp.local.", sizeof(query));
380                                 }
381                         }
382                 }
383                 serv_tmp->data.bonjour.query = strdup(query + 1);
384                 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
385                         unsigned long int size = 0;
386                         char temp_str[3] = {0,};
387                         memcpy(temp_str, ptr, 2);
388                         size = strtoul(temp_str, NULL, 16);
389                         ptr += 2;
390                         if (size <= 0xff) {
391                                 temp = (char*) g_try_malloc0(size + 2);
392                                 if (temp) {
393                                         temp[0] = '.';
394                                         for (i = 0; i < size; i++) {
395                                                 temp[i+1] = (char) __ws_hex_to_num(ptr, 2);
396                                                 ptr += 2;
397                                         }
398                                         g_strlcat(rdata, temp, sizeof(rdata));
399                                         g_free(temp);
400                                         temp = NULL;
401                                 }
402                         }
403                 }
404                 serv_tmp->data.bonjour.rdata = strdup(rdata + 1);
405
406                 WDP_LOGD("Query: %s", serv_tmp->data.bonjour.query);
407                 WDP_LOGD("RData: %s", serv_tmp->data.bonjour.rdata);
408         } else {
409                 WDP_LOGE("Not supported yet. Only bonjour service supproted [%d]",
410                                         serv_tmp->protocol);
411                 g_free(serv_tmp);
412                 return -1;
413         }
414
415         *service = serv_tmp;
416
417         return 0;
418 }
419
420 static void __extract_addr_from_path(char *peer_path, unsigned char *dev_addr)
421 {
422         static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
423         char *loc = NULL;
424
425         if (!peer_path || !dev_addr)
426                 return;
427
428         loc = strrchr(peer_path, '/');
429         if (loc != NULL)
430                 __ws_mac_compact_to_normal(loc + 1, peer_dev);
431
432         __ws_txt_to_mac(peer_dev, dev_addr);
433         WDP_LOGD("dev addr [" MACSTR "]", MAC2STR(dev_addr));
434 }
435
436 static void __ws_path_to_addr(char *peer_path,
437                 unsigned char *dev_addr, GVariant *parameter)
438 {
439         __WDP_LOG_FUNC_ENTER__;
440
441         const char *path = NULL;
442
443         g_variant_get(parameter, "(&o)", &path);
444         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
445         WDP_LOGD("Retrive Added path [%s]", peer_path);
446
447         __extract_addr_from_path(peer_path, dev_addr);
448
449         __WDP_LOG_FUNC_EXIT__;
450         return;
451 }
452
453 static int __ws_unpack_ay(unsigned char *dst, GVariant *src, int size)
454 {
455         GVariantIter *iter = NULL;
456         int length = 0;
457
458         if (!dst || !src || size == 0) {
459                 WDP_LOGE("Invalid parameter");
460                 return -1;
461         }
462         g_variant_get(src, "ay", &iter);
463         if (iter == NULL) {
464                 WDP_LOGE("failed to get iterator");
465                 return -1;
466         }
467
468         while (g_variant_iter_loop(iter, "y", &dst[length])) {
469                 length++;
470                 if (length >= size)
471                         break;
472         }
473         g_variant_iter_free(iter);
474
475         return length;
476 }
477
478 static int __ws_byte_to_txt(const unsigned char *src, char **dst, int src_len)
479 {
480         __WDP_LOG_FUNC_ENTER__;
481
482         int dst_length = 0;
483         int i = 0;
484         char *buf = NULL;
485
486         if (src_len <= 0) {
487                 WDP_LOGE("Invalid parameter.");
488                 __WDP_LOG_FUNC_EXIT__;
489                 return -1;
490         }
491
492         *dst = (char *) g_try_malloc0((2*src_len)+1);
493         if (!(*dst)) {
494                 WDP_LOGE("failed to allocate memory to buffer.");
495                 __WDP_LOG_FUNC_EXIT__;
496                 return -1;
497         }
498
499         buf = (*dst);
500
501         for (i = 0; i < src_len; i++) {
502                 snprintf(buf, 3, "%02x", src[i]);
503                 buf += 2;
504                 dst_length += 2;
505         }
506
507         __WDP_LOG_FUNC_EXIT__;
508         return dst_length;
509 }
510
511 static int __ws_unpack_ay_malloc(unsigned char **dst, GVariantIter *iter)
512 {
513         GVariantIter *iter_copy = NULL;
514         int length = 0;
515         char tmp = 0;
516         unsigned char *tmp_dst = NULL;
517
518         if (!dst || *dst || !iter) {
519                 WDP_LOGE("Invalid parameter");
520                 return 0;
521         }
522
523         iter_copy = g_variant_iter_copy(iter);
524
525         while (g_variant_iter_loop(iter, "y", &tmp))
526                 length++;
527         g_variant_iter_free(iter);
528
529         tmp_dst = (unsigned char *)g_try_malloc0(length + 1);
530         if (!tmp_dst) {
531                 WDP_LOGE("failed to allocate memory");
532                 g_variant_iter_free(iter_copy);
533                 return 0;
534         }
535
536         length = 0;
537         while (g_variant_iter_loop(iter_copy, "y", &tmp_dst[length]))
538                 length++;
539         g_variant_iter_free(iter_copy);
540
541         if (length == 0) {
542                 g_free(tmp_dst);
543                 tmp_dst = NULL;
544         } else {
545                 tmp_dst[length] = '\0';
546         }
547
548         *dst = tmp_dst;
549         WDP_LOGD("Length [%d]", length);
550         return length;
551 }
552
553 static int __parsing_wfd_info(unsigned char *wfd_dev_info,
554                 wfd_oem_display_s* display)
555 {
556         __WDP_LOG_FUNC_ENTER__;
557
558         int wfd_info = 0;
559         if (!wfd_dev_info || !display) {
560                 WDP_LOGE("Invalid parameter");
561                 __WDP_LOG_FUNC_EXIT__;
562                 return -1;
563         }
564
565         wfd_info = (wfd_dev_info[3]<<8 | wfd_dev_info[4]);
566
567         if (wfd_info & WS_WFD_INFO_PRIMARY_SINK)
568                 display->type |= WS_WFD_INFO_PRIMARY_SINK;
569         if (wfd_info & WS_WFD_INFO_SECONDARY_SINK)
570                 display->type |= WS_WFD_INFO_SECONDARY_SINK;
571
572         display->availability = (wfd_info & WS_WFD_INFO_AVAILABILITY) >> 4;
573         display->hdcp_support = (wfd_info & WS_WFD_INFO_HDCP_SUPPORT) >> 8;
574
575         display->port = (wfd_dev_info[5]<<8 | wfd_dev_info[6]);
576         display->max_tput = (wfd_dev_info[7]<<8 | wfd_dev_info[8]);
577
578         WDP_LOGD("type [%d],availability [%d],hdcp_support [%d],ctrl_port [%d] "
579                         "max_tput[%d]", display->type, display->availability,
580                         display->hdcp_support, display->port, display->max_tput);
581
582         __WDP_LOG_FUNC_EXIT__;
583         return 0;
584 }
585
586 static int _ws_get_local_dev_mac(unsigned char *dev_mac)
587 {
588         __WDP_LOG_FUNC_ENTER__;
589         FILE *fd = NULL;
590         char file_path[MAX_FILE_PATH_LEN] = {0, };
591         char local_mac[OEM_MACSTR_LEN] = {0, };
592         char *ptr = NULL;
593         int res = 0;
594         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
595
596         errno = 0;
597         g_snprintf(file_path, sizeof(file_path),
598                         "/sys/class/net/%s/address", config->p2p_ifname);
599
600         fd = fopen(file_path, "r");
601         if (!fd) {
602                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
603                 WDP_LOGE("Failed to open MAC info file [%s] (%s)", file_path, error_buf);
604                 __WDP_LOG_FUNC_EXIT__;
605                 return -1;
606         }
607
608         errno = 0;
609         ptr = fgets((char *)local_mac, WS_MACSTR_LEN, fd);
610         if (!ptr) {
611                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
612                 WDP_LOGE("Failed to read file or no data read(%s)", error_buf);
613                 fclose(fd);
614                 __WDP_LOG_FUNC_EXIT__;
615                 return -1;
616         }
617         WDP_SECLOGD("Local MAC address [%s]", ptr);
618         WDP_SECLOGD("Local MAC address [%s]", local_mac);
619
620         res = __ws_txt_to_mac((unsigned char *)local_mac, dev_mac);
621         if (res < 0) {
622                 WDP_LOGE("Failed to convert text to MAC address");
623                 fclose(fd);
624                 __WDP_LOG_FUNC_EXIT__;
625                 return -1;
626         }
627
628         WDP_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(dev_mac));
629
630         fclose(fd);
631         __WDP_LOG_FUNC_EXIT__;
632         return 0;
633 }
634
635 static void _ws_manage_group_iface_signal(const gchar *group_iface_obj_path,
636                 gboolean is_created);
637
638 static void _ws_process_interface_removed(GDBusConnection *connection,
639                 const gchar *sender, const gchar *object_path, const gchar *interface,
640                 const gchar *signal, GVariant *parameters, gpointer user_data)
641 {
642         __WDP_LOG_FUNC_ENTER__;
643         static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
644         const char *path = NULL;
645
646         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
647
648         if (!g_pd) {
649                 WDP_LOGD("Ignoring event");
650                 __WDP_LOG_FUNC_EXIT__;
651                 return;
652         }
653
654         g_variant_get(parameters, "(&o)", &path);
655         g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
656
657         WDP_LOGD("Retrive removed path [%s]", interface_path);
658
659         if (!g_strcmp0(g_pd->group_iface_path, interface_path)) {
660                 WDP_LOGD("p2p group interface removed");
661                 memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
662         } else if (!g_strcmp0(g_pd->iface_path, interface_path)) {
663
664                 WDP_LOGD("p2p interface removed");
665                 wfd_oem_event_s event;
666
667                 ws_deactivate(1);
668
669                 memset(&event, 0x0, sizeof(wfd_oem_event_s));
670                 event.event_id = WFD_OEM_EVENT_DEACTIVATED;
671                 if (g_pd->callback && g_pd->callback->deactivated_cb)
672                         g_pd->callback->deactivated_cb(&event);
673
674                 memset(g_pd->iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
675         }
676         __WDP_LOG_FUNC_EXIT__;
677 }
678
679 static struct {
680         int sub_id;
681         const char *interface;
682         const char *member;
683         void (*function) (GDBusConnection *connection,
684                         const gchar *sender, const gchar *object_path, const gchar *interface,
685                         const gchar *signal, GVariant *parameters, gpointer user_data);
686 } ws_supplicant_signal_map[] = {
687         {
688                 0,
689                 SUPPLICANT_INTERFACE,
690                 "InterfaceRemoved",
691                 _ws_process_interface_removed
692         },
693         {
694                 0,
695                 NULL,
696                 NULL,
697                 NULL
698         }
699 };
700
701 static void __ws_get_peer_property(const char *key, GVariant *value, void *user_data)
702 {
703         __WDP_LOG_FUNC_ENTER__;
704
705         wfd_oem_device_s *peer = (wfd_oem_device_s *)user_data;
706         if (!peer) {
707                 __WDP_LOG_FUNC_EXIT__;
708                 return;
709         }
710
711         CHECK_KEY_VALUE(key, value);
712
713         if (g_strcmp0(key, "DeviceName") == 0) {
714                 const char *name = NULL;
715
716                 g_variant_get(value, "&s", &name);
717                 g_strlcpy(peer->dev_name, name, WS_SSID_LEN + 1);
718                 WDP_LOGD("Device name [%s]", peer->dev_name);
719
720         } else if (g_strcmp0(key, "config_method") == 0) {
721                 int config_methods = 0;
722                 g_variant_get(value, "q", &config_methods);
723
724                 if (config_methods & WS_CONFIG_METHOD_DISPLAY)
725                         peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
726                 if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
727                         peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
728                 if (config_methods & WS_CONFIG_METHOD_KEYPAD)
729                         peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
730                 WDP_LOGD("Config method [0x%x]", peer->config_methods);
731
732         } else if (g_strcmp0(key, "level") == 0) {
733                 int  rssi = 0;
734
735                 g_variant_get(value, "i", &rssi);
736                 peer->rssi = rssi;
737                 WDP_LOGD("Peer RSSI [%d]", peer->rssi);
738
739         } else if (g_strcmp0(key, "devicecapability") == 0) {
740                 unsigned char devicecapability = 0;
741
742                 g_variant_get(value, "y", &devicecapability);
743                 peer->dev_flags = (int)devicecapability;
744                 WDP_LOGD("Device Capa [0x%02x]", peer->dev_flags);
745
746         } else if (g_strcmp0(key, "groupcapability") == 0) {
747                 unsigned char groupcapability = 0;
748
749                 g_variant_get(value, "y", &groupcapability);
750                 WDP_LOGD("Group Capa [0x%02x]", groupcapability);
751                 if (groupcapability & WS_GROUP_CAP_GROUP_OWNER) {
752                         peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
753                         peer->dev_role = WFD_OEM_DEV_ROLE_GO;
754                 }
755                 if (groupcapability & WS_GROUP_CAP_PERSISTENT_GROUP)
756                         peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
757
758         } else if (g_strcmp0(key, "PrimaryDeviceType") == 0) {
759                 unsigned char primarydevicetype[WS_DEVTYPE_LEN] = {0,};
760
761                 if (__ws_unpack_ay(primarydevicetype, value, WS_DEVTYPE_LEN)) {
762                         peer->pri_dev_type = primarydevicetype[1];
763                         peer->sec_dev_type = primarydevicetype[WS_DEVTYPE_LEN -1];
764                 }
765         } else if (g_strcmp0(key, "SecondaryDeviceTypes") == 0) {
766         } else if (g_strcmp0(key, "VendorExtension") == 0) {
767         } else if (g_strcmp0(key, "IEs") == 0) {
768                 unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
769
770                 if (__ws_unpack_ay(ies, value, WFD_SUBELEM_LEN_DEV_INFO + 3))
771                         __parsing_wfd_info(ies, &(peer->display));
772         } else if (g_strcmp0(key, "DeviceAddress") == 0) {
773
774                 if (__ws_unpack_ay(peer->dev_addr, value, WS_MACADDR_LEN))
775                         WDP_LOGD("Device address [" MACSTR "]", MAC2STR(peer->dev_addr));
776
777         } else if (g_strcmp0(key, "InterfaceAddress") == 0) {
778
779                 if (__ws_unpack_ay(peer->intf_addr, value, WS_MACADDR_LEN))
780                         WDP_LOGD("Interface address [" MACSTR "]", MAC2STR(peer->intf_addr));
781
782         } else if (g_strcmp0(key, "GODeviceAddress") == 0) {
783
784                 if (__ws_unpack_ay(peer->go_dev_addr, value, WS_MACADDR_LEN))
785                         WDP_LOGD("GODevice address [" MACSTR "]", MAC2STR(peer->go_dev_addr));
786
787                 if (!ISZEROMACADDR(peer->go_dev_addr))
788                         peer->dev_role = WFD_OEM_DEV_ROLE_GC;
789
790         } else if (g_strcmp0(key, "VSIE") == 0) {
791                 int vsie_len;
792                 unsigned char vsie[OEM_VSIE_MAX_LEN] = {0,};
793
794                 vsie_len = __ws_unpack_ay(vsie, value, OEM_VSIE_MAX_LEN);
795                 if (vsie_len > 0) {
796                         __ws_byte_to_txt(vsie, (char **)&(peer->vsie), vsie_len);
797                         WDP_LOGD("VSIE [%s]", peer->vsie);
798                 }
799
800         } else {
801                 WDP_LOGD("Unknown value");
802         }
803         __WDP_LOG_FUNC_EXIT__;
804         return;
805 }
806
807 static void __ws_peer_property(const char *key, GVariant *value, void *user_data)
808 {
809         __WDP_LOG_FUNC_ENTER__;
810         if (!user_data) {
811                 __WDP_LOG_FUNC_EXIT__;
812                 return;
813         }
814
815         wfd_oem_dev_data_s *peer = (wfd_oem_dev_data_s *)user_data;
816
817         CHECK_KEY_VALUE(key, value);
818
819         if (g_strcmp0(key, "DeviceName") == 0) {
820                 const char *name = NULL;
821
822                 g_variant_get(value, "&s", &name);
823                 g_strlcpy(peer->name, name, WS_SSID_LEN + 1);
824                 WDP_LOGD("Device Name [%s]", peer->name);
825
826         } else if (g_strcmp0(key, "config_method") == 0) {
827                 int config_methods = 0;
828
829                 g_variant_get(value, "q", &config_methods);
830
831                 if (config_methods & WS_CONFIG_METHOD_DISPLAY)
832                         peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
833                 if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
834                         peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
835                 if (config_methods & WS_CONFIG_METHOD_KEYPAD)
836                         peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
837                 WDP_LOGD("Config method [0x%x]", peer->config_methods);
838
839         } else if (g_strcmp0(key, "level") == 0) {
840                 int  rssi = 0;
841
842                 g_variant_get(value, "i", &rssi);
843                 peer->rssi = rssi;
844                 WDP_LOGD("Peer RSSI [%d]", peer->rssi);
845
846         } else if (g_strcmp0(key, "devicecapability") == 0) {
847                 unsigned char devicecapability = 0;
848
849                 g_variant_get(value, "y", &devicecapability);
850                 peer->dev_flags = (int)devicecapability;
851                 WDP_LOGD("Device Capa [0x%02x]", peer->dev_flags);
852
853         } else if (g_strcmp0(key, "groupcapability") == 0) {
854                 unsigned char groupcapability = 0;
855
856                 g_variant_get(value, "y", &groupcapability);
857                 WDP_LOGD("Group Capa [0x%02x]", groupcapability);
858                 if (groupcapability & WS_GROUP_CAP_GROUP_OWNER) {
859                         peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
860                         peer->dev_role = WFD_OEM_DEV_ROLE_GO;
861                 }
862                 if (groupcapability & WS_GROUP_CAP_PERSISTENT_GROUP)
863                         peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
864
865         } else if (g_strcmp0(key, "PrimaryDeviceType") == 0) {
866                 unsigned char primarydevicetype[WS_DEVTYPE_LEN] = {0,};
867
868                 if (__ws_unpack_ay(primarydevicetype, value, WS_DEVTYPE_LEN)) {
869                         peer->pri_dev_type = primarydevicetype[1];
870                         peer->sec_dev_type = primarydevicetype[WS_DEVTYPE_LEN -1];
871                 }
872         } else if (g_strcmp0(key, "SecondaryDeviceTypes") == 0) {
873         } else if (g_strcmp0(key, "VendorExtension") == 0) {
874         } else if (g_strcmp0(key, "IEs") == 0) {
875                 unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
876
877                 if (__ws_unpack_ay(ies, value, WFD_SUBELEM_LEN_DEV_INFO + 3))
878                         __parsing_wfd_info(ies, &(peer->display));
879         } else if (g_strcmp0(key, "DeviceAddress") == 0) {
880
881                 if (__ws_unpack_ay(peer->p2p_dev_addr, value, WS_MACADDR_LEN))
882                         WDP_LOGD("Device address [" MACSTR "]", MAC2STR(peer->p2p_dev_addr));
883
884         } else if (g_strcmp0(key, "InterfaceAddress") == 0) {
885
886                 if (__ws_unpack_ay(peer->p2p_intf_addr, value, WS_MACADDR_LEN))
887                         WDP_LOGD("Interface Address [" MACSTR "]", MAC2STR(peer->p2p_intf_addr));
888
889         } else if (g_strcmp0(key, "GODeviceAddress") == 0) {
890
891                 unsigned char go_dev_addr[OEM_MACADDR_LEN] = {0,};
892                 if (__ws_unpack_ay(go_dev_addr, value, WS_MACADDR_LEN))
893                         WDP_LOGD("[" MACSTR "]", MAC2STR(go_dev_addr));
894
895                 if (!ISZEROMACADDR(go_dev_addr))
896                         peer->dev_role = WFD_OEM_DEV_ROLE_GC;
897
898         } else if (g_strcmp0(key, "AdvertiseService") == 0) {
899                 if (value != NULL && g_variant_get_size(value) != 0)
900                         peer->has_asp_services = 1;
901                 else
902                         peer->has_asp_services = 0;
903
904         } else if (g_strcmp0(key, "AdvertiseASPService") == 0) {
905                 if (value != NULL && g_variant_get_size(value) != 0)
906                         peer->has_asp2_services = 1;
907                 else
908                         peer->has_asp2_services = 0;
909
910         } else if (g_strcmp0(key, "VSIE") == 0) {
911                 int vsie_len;
912                 unsigned char vsie[OEM_VSIE_MAX_LEN] = {0,};
913
914                 vsie_len = __ws_unpack_ay(vsie, value, OEM_VSIE_MAX_LEN);
915                 if (vsie_len > 0) {
916                         __ws_byte_to_txt(vsie, (char **)&(peer->vsie), vsie_len);
917                         WDP_LOGD("VSIE [%s]", peer->vsie);
918                 }
919
920         } else {
921                 WDP_LOGD("Unknown value");
922         }
923         __WDP_LOG_FUNC_EXIT__;
924         return;
925 }
926
927 void __ws_interface_property(const char *key, GVariant *value, void *user_data)
928 {
929         __WDP_LOG_FUNC_ENTER__;
930         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
931         if (!event)
932                 return;
933
934         CHECK_KEY_VALUE(key, value);
935
936         if (g_strcmp0(key, "Ifname") == 0) {
937                 const char *ifname = NULL;
938
939                 g_variant_get(value, "&s", &ifname);
940                 g_strlcpy(event->ifname, ifname, OEM_IFACE_NAME_LEN+1);
941                 WDP_LOGD("Ifname [%s]", event->ifname);
942
943         }
944         __WDP_LOG_FUNC_EXIT__;
945         return;
946 }
947
948 void __ws_group_property(const char *key, GVariant *value, void *user_data)
949 {
950         __WDP_LOG_FUNC_ENTER__;
951         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
952         if (!event || !event->edata)
953                 return;
954
955         wfd_oem_group_data_s *group = (wfd_oem_group_data_s *)event->edata;
956
957         CHECK_KEY_VALUE(key, value);
958
959         if (g_strcmp0(key, "Role") == 0) {
960                 const char *role = NULL;
961
962                 g_variant_get(value, "&s", &role);
963                 WDP_LOGD("Role [%s]", role);
964
965                 if (!strncmp(role, "GO", 2))
966                         event->dev_role = WFD_OEM_DEV_ROLE_GO;
967                 else if (!strncmp(role, "client", 6))
968                         event->dev_role = WFD_OEM_DEV_ROLE_GC;
969
970         } else if (g_strcmp0(key, "Frequency") == 0) {
971                 int frequency = 0;
972
973                 g_variant_get(value, "q", &frequency);
974                 group->freq = (int)frequency;
975
976         } else if (g_strcmp0(key, "Passphrase") == 0) {
977                 const char *passphrase = NULL;
978
979                 g_variant_get(value, "&s", &passphrase);
980                 g_strlcpy(group->pass, passphrase, OEM_PASS_PHRASE_LEN+1);
981                 WDP_LOGD("passphrase [%s]", group->pass);
982
983         } else if (g_strcmp0(key, "Group") == 0) {
984
985         } else if (g_strcmp0(key, "SSID") == 0) {
986                 unsigned char ssid[WS_SSID_LEN +1] = {0,};
987
988                 __ws_unpack_ay(ssid, value, WS_SSID_LEN);
989                 memcpy(group->ssid, ssid, WS_SSID_LEN+1);
990                 WDP_LOGD("ssid [%s]", group->ssid);
991
992         } else if (g_strcmp0(key, "BSSID") == 0) {
993
994                 if (__ws_unpack_ay(group->go_dev_addr, value, WS_MACADDR_LEN))
995                         WDP_LOGD("[" MACSTR "]", MAC2STR(group->go_dev_addr));
996
997         } else {
998                 WDP_LOGD("Unknown value");
999         }
1000         __WDP_LOG_FUNC_EXIT__;
1001         return;
1002 }
1003
1004 void __ws_extract_invitation_details(const char *key, GVariant *value, void *user_data)
1005 {
1006         __WDP_LOG_FUNC_ENTER__;
1007         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1008         if (!event || !event->edata)
1009                 return;
1010
1011         wfd_oem_invite_data_s *invitation = (wfd_oem_invite_data_s *)event->edata;
1012
1013         CHECK_KEY_VALUE(key, value);
1014
1015         if (g_strcmp0(key, "sa") == 0) {
1016                 if (__ws_unpack_ay(invitation->sa, value, WS_MACADDR_LEN))
1017                         WDP_LOGD("SA [" MACSTR "]", MAC2STR(invitation->sa));
1018
1019         } else if (g_strcmp0(key, "go_dev_addr") == 0) {
1020                 if (__ws_unpack_ay(invitation->go_dev_addr, value, WS_MACADDR_LEN))
1021                                         WDP_LOGD("GO device address [" MACSTR "]", MAC2STR(invitation->go_dev_addr));
1022
1023         } else if (g_strcmp0(key, "bssid") == 0) {
1024                 if (__ws_unpack_ay(invitation->bssid, value, WS_MACADDR_LEN))
1025                                         WDP_LOGD("BSSID [" MACSTR "]", MAC2STR(invitation->bssid));
1026
1027         } else if (g_strcmp0(key, "persistent_id") == 0) {
1028                 g_variant_get(value, "i", &(invitation->persistent_id));
1029                 WDP_LOGD("persistent id [%d]", invitation->persistent_id);
1030
1031         } else if (g_strcmp0(key, "op_freq") == 0) {
1032                 g_variant_get(value, "i", &(invitation->oper_freq));
1033                 WDP_LOGD("op freq [%d]", invitation->oper_freq);
1034         } else {
1035                 WDP_LOGD("Unknown value");
1036         }
1037         __WDP_LOG_FUNC_EXIT__;
1038         return;
1039 }
1040
1041 static void __ws_parse_peer_joined(char *peer_path,
1042                 unsigned char *dev_addr, unsigned char *ip_addr, GVariant *parameter)
1043 {
1044         __WDP_LOG_FUNC_ENTER__;
1045
1046         GVariantIter *iter;
1047         gboolean iter_res = TRUE;
1048         const char *path = NULL;
1049         int i = 0;
1050
1051         g_variant_get(parameter, "(&oay)", &path, &iter);
1052         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
1053         WDP_LOGD("Retrive Added path [%s]", peer_path);
1054
1055         __extract_addr_from_path(peer_path, dev_addr);
1056
1057         for (i = 0; iter_res &&  i < OEM_IPADDR_LEN; i++)
1058                 iter_res = g_variant_iter_loop(iter, "y", &ip_addr[i]);
1059         g_variant_iter_free(iter);
1060
1061         WDP_LOGD("peer ip [" IPSTR "]", IP2STR(ip_addr));
1062
1063         __WDP_LOG_FUNC_EXIT__;
1064         return;
1065 }
1066
1067 static gboolean __is_valid_plugin(void)
1068 {
1069         gboolean is_valid = (g_pd && g_pd->callback);
1070
1071         if (!is_valid)
1072                 WDP_LOGD("Ignoring event");
1073
1074         return is_valid;
1075 }
1076
1077 static wfd_oem_dev_data_s *__create_dev_data(void)
1078 {
1079         wfd_oem_dev_data_s *dev_data =
1080                         (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1081         if (!dev_data) {
1082                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1083                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1084                 WDP_LOGF("Failed to allocate memory for event. [%s]",
1085                                 error_buf);
1086         }
1087
1088         return dev_data;
1089 }
1090
1091 static void __set_event_data(int event_id, int edata_type, void *data, wfd_oem_event_s *event)
1092 {
1093         if (!event)
1094                 return;
1095
1096         memset(event, 0x0, sizeof(wfd_oem_event_s));
1097
1098         event->edata = data;
1099         event->edata_type = edata_type;
1100         event->event_id = event_id;
1101
1102         return;
1103 }
1104
1105 static void __destroy_dev_data(wfd_oem_dev_data_s *dev_data)
1106 {
1107         if (!dev_data)
1108                 return;
1109
1110         if (dev_data->vsie)
1111                 g_free(dev_data->vsie);
1112         g_free(dev_data);
1113 }
1114
1115 static void _ws_process_peer_joined(GDBusConnection *connection,
1116                 const gchar *sender, const gchar *object_path, const gchar *interface,
1117                 const gchar *signal, GVariant *parameters, gpointer user_data)
1118 {
1119         __WDP_LOG_FUNC_ENTER__;
1120         wfd_oem_event_s event;
1121         wfd_oem_dev_data_s *dev_data = NULL;
1122         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1123
1124         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
1125
1126         if (!__is_valid_plugin())
1127                 return;
1128
1129         dev_data = __create_dev_data();
1130         if (!dev_data) {
1131                 __WDP_LOG_FUNC_EXIT__;
1132                 return;
1133         }
1134
1135         __set_event_data(WFD_OEM_EVENT_STA_CONNECTED,
1136                         WFD_OEM_EDATA_TYPE_DEVICE,
1137                         (void *)dev_data,
1138                         &event);
1139
1140         __ws_parse_peer_joined(peer_path, event.dev_addr, event.ip_addr_peer, parameters);
1141
1142         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1143                         __ws_peer_property, event.edata);
1144
1145         if (g_pd->callback->sta_connected_cb)
1146                 g_pd->callback->sta_connected_cb(&event);
1147
1148         is_peer_joined_notified = 1;
1149
1150         __destroy_dev_data(dev_data);
1151
1152         __WDP_LOG_FUNC_EXIT__;
1153 }
1154
1155 static void _ws_process_peer_disconnected(GDBusConnection *connection,
1156                 const gchar *sender, const gchar *object_path, const gchar *interface,
1157                 const gchar *signal, GVariant *parameters, gpointer user_data)
1158 {
1159         __WDP_LOG_FUNC_ENTER__;
1160         wfd_oem_event_s event;
1161         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1162
1163         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
1164
1165         if (!g_pd || !g_pd->callback) {
1166                 WDP_LOGD("Ignoring event");
1167                 __WDP_LOG_FUNC_EXIT__;
1168                 return;
1169         }
1170
1171         memset(&event, 0x0, sizeof(wfd_oem_event_s));
1172
1173         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
1174         event.event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
1175
1176         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1177
1178         if (g_pd->callback->sta_disconnected_cb)
1179                 g_pd->callback->sta_disconnected_cb(&event);
1180
1181         is_peer_disconnected_notified = 1;
1182         __WDP_LOG_FUNC_EXIT__;
1183 }
1184
1185 static struct {
1186         int sub_id;
1187         const char *interface;
1188         const char *member;
1189         void (*function) (GDBusConnection *connection,
1190                         const gchar *sender, const gchar *object_path, const gchar *interface,
1191                         const gchar *signal, GVariant *parameters, gpointer user_data);
1192 } ws_group_signal_map[] = {
1193         {
1194                 0,
1195                 SUPPLICANT_P2P_GROUP,
1196                 "PeerJoined",
1197                 _ws_process_peer_joined
1198         },
1199         {
1200                 0,
1201                 SUPPLICANT_P2P_GROUP,
1202                 "PeerDisconnected",
1203                 _ws_process_peer_disconnected
1204         },
1205         {
1206                 0,
1207                 NULL,
1208                 NULL,
1209                 NULL
1210         }
1211 };
1212
1213 void __ws_extract_group_details(const char *key, GVariant *value, void *user_data)
1214 {
1215         __WDP_LOG_FUNC_ENTER__;
1216         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1217         if (!event || !event->edata)
1218                 return;
1219
1220         if (!g_pd) {
1221                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
1222                 __WDP_LOG_FUNC_EXIT__;
1223                 return;
1224         }
1225
1226         wfd_oem_group_data_s *group = (wfd_oem_group_data_s *)event->edata;
1227
1228         CHECK_KEY_VALUE(key, value);
1229
1230         if (g_strcmp0(key, "interface_object") == 0) {
1231                 static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1232                 const char *i_path = NULL;
1233
1234                 g_variant_get(value, "&o", &i_path);
1235                 g_strlcpy(interface_path, i_path, DBUS_OBJECT_PATH_MAX);
1236                 WDP_LOGD("Retrive Added path [%s]", interface_path);
1237                 g_strlcpy(g_pd->group_iface_path, interface_path, DBUS_OBJECT_PATH_MAX);
1238
1239                 dbus_property_get_all(interface_path, g_pd->g_dbus,
1240                                 SUPPLICANT_IFACE, __ws_interface_property, event);
1241
1242                 _ws_manage_group_iface_signal(interface_path, TRUE);
1243
1244         } else if (g_strcmp0(key, "role") == 0) {
1245                 const char *role = NULL;
1246
1247                 g_variant_get(value, "&s", &role);
1248                 WDP_LOGD("Role [%s]", role);
1249
1250                 if (!strncmp(role, "GO", 2))
1251                         event->dev_role = WFD_OEM_DEV_ROLE_GO;
1252                 else if (!strncmp(role, "client", 6))
1253                         event->dev_role = WFD_OEM_DEV_ROLE_GC;
1254         } else if (g_strcmp0(key, "persistent") == 0) {
1255                 g_variant_get(value, "b", &group->is_persistent);
1256                 WDP_LOGD("Is Persistent : [%s]", group->is_persistent ? "YES" : "NO");
1257
1258         } else if (g_strcmp0(key, "IpAddr") == 0) {
1259
1260                 if (__ws_unpack_ay(group->ip_addr, value, OEM_IPADDR_LEN))
1261                         WDP_LOGD("IP address [" IPSTR "]", IP2STR(group->ip_addr));
1262
1263         } else if (g_strcmp0(key, "IpAddrMask") == 0) {
1264
1265                 if (__ws_unpack_ay(group->ip_addr_mask, value, OEM_IPADDR_LEN))
1266                         WDP_LOGD("IP mask [" IPSTR "]", IP2STR(group->ip_addr_mask));
1267
1268         } else if (g_strcmp0(key, "IpAddrGo") == 0) {
1269
1270                 if (__ws_unpack_ay(group->ip_addr_go, value, OEM_IPADDR_LEN))
1271                         WDP_LOGD("GO IP address [" IPSTR "]", IP2STR(group->ip_addr_go));
1272         } else if (g_strcmp0(key, "group_object") == 0) {
1273                 static char group_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1274                 const char *g_path;
1275                 int i = 0;
1276
1277                 g_variant_get(value, "&o", &g_path);
1278                 g_strlcpy(group_path, g_path, DBUS_OBJECT_PATH_MAX);
1279                 WDP_LOGD("Retrive group path [%s]", group_path);
1280                 dbus_property_get_all(group_path, g_pd->g_dbus, SUPPLICANT_P2P_GROUP,
1281                                 __ws_group_property, event);
1282
1283                 for (i = 0; ws_group_signal_map[i].member != NULL; i++) {
1284                         ws_group_signal_map[i].sub_id =
1285                                 g_dbus_connection_signal_subscribe(g_pd->g_dbus,
1286                                                 SUPPLICANT_SERVICE, /* bus name */
1287                                                 ws_group_signal_map[i].interface, /* interface */
1288                                                 ws_group_signal_map[i].member, /* member */
1289                                                 group_path, /* object path */
1290                                                 NULL, /* arg0 */
1291                                                 G_DBUS_SIGNAL_FLAGS_NONE,
1292                                                 ws_group_signal_map[i].function,
1293                                                 NULL, NULL);
1294                         WDP_LOGD("Subscribed Group iface signal [%s]", ws_group_signal_map[i].member);
1295                 }
1296         }
1297         __WDP_LOG_FUNC_EXIT__;
1298         return;
1299 }
1300
1301 void __ws_extract_gonegfailaure_details(const char *key, GVariant *value, void *user_data)
1302 {
1303         __WDP_LOG_FUNC_ENTER__;
1304         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1305         if (!event || !event->edata)
1306                 return;
1307
1308         wfd_oem_conn_data_s *conn = (wfd_oem_conn_data_s *)event->edata;
1309
1310         CHECK_KEY_VALUE(key, value);
1311
1312         if (g_strcmp0(key, "peer_object") == 0) {
1313                 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1314                 const char *path;
1315
1316                 g_variant_get(value, "&o", &path);
1317                 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
1318                 WDP_LOGD("Retrive peer path [%s]", peer_path);
1319
1320         } else if (g_strcmp0(key, "status") == 0) {
1321                 int status = 0;
1322
1323                 g_variant_get(value, "i", &status);
1324                 WDP_LOGD("Retrive status [%d]", status);
1325                 conn->status = status;
1326         }
1327         __WDP_LOG_FUNC_EXIT__;
1328         return;
1329 }
1330
1331 void __ws_extract_gonegsuccess_details(const char *key, GVariant *value, void *user_data)
1332 {
1333         __WDP_LOG_FUNC_ENTER__;
1334         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1335         if (!event || !event->edata)
1336                 return;
1337
1338         wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s *)event->edata;
1339
1340         CHECK_KEY_VALUE(key, value);
1341
1342         if (g_strcmp0(key, "peer_object") == 0) {
1343
1344         } else if (g_strcmp0(key, "status") == 0) {
1345
1346         } else if (g_strcmp0(key, "passphrase") == 0) {
1347
1348         } else if (g_strcmp0(key, "role_go") == 0) {
1349                 /* local device role */
1350                 const char *role = NULL;
1351
1352                 g_variant_get(value, "&s", &role);
1353                 if (!strncmp(role, "GO", 2))
1354                         event->dev_role = WFD_OEM_DEV_ROLE_GO;
1355                 else if (!strncmp(role, "client", 6))
1356                         event->dev_role = WFD_OEM_DEV_ROLE_GC;
1357
1358         } else if (g_strcmp0(key, "ssid") == 0) {
1359                 unsigned char ssid[WS_SSID_LEN +1] = {0,};
1360
1361                 __ws_unpack_ay(ssid, value, WS_SSID_LEN);
1362                 memcpy(edata->ssid, ssid, WS_SSID_LEN+1);
1363                 WDP_LOGD("ssid [%s]", edata->ssid);
1364
1365         } else if (g_strcmp0(key, "peer_device_addr") == 0) {
1366
1367                 if (__ws_unpack_ay(edata->peer_device_addr, value, WS_MACADDR_LEN))
1368                         WDP_LOGD("Device address[" MACSTR "]", MAC2STR(edata->peer_device_addr));
1369
1370         } else if (g_strcmp0(key, "peer_interface_addr") == 0) {
1371
1372                 if (__ws_unpack_ay(edata->peer_intf_addr, value, WS_MACADDR_LEN))
1373                         WDP_LOGD("Interface address [" MACSTR "]", MAC2STR(edata->peer_intf_addr));
1374
1375         } else if (g_strcmp0(key, "wps_method") == 0) {
1376
1377         } else if (g_strcmp0(key, "frequency_list") == 0) {
1378
1379         } else if (g_strcmp0(key, "persistent_group") == 0) {
1380
1381                 g_variant_get(value, "i", &(edata->persistent_group));
1382                 WDP_LOGD("persistent_group [%d]", edata->persistent_group);
1383
1384         } else if (g_strcmp0(key, "peer_config_timeout") == 0) {
1385
1386         }
1387         __WDP_LOG_FUNC_EXIT__;
1388         return;
1389 }
1390
1391 void __ws_extract_peer_service(wfd_oem_event_s *data, unsigned char *service_hex, int tlvs_len)
1392 {
1393         GList *services = NULL;
1394         wfd_oem_new_service_s *new_service = NULL;
1395         char *segment = NULL;
1396         int count = 0;
1397         int ptr = 0;
1398         int length = 0;
1399         int res = 0;
1400
1401         while (ptr + 2 < WS_MAX_SERVICE_LEN &&
1402                         (length = (service_hex[ptr+1]*256) + service_hex[ptr]) > 0) {
1403                 segment = (char*) g_try_malloc0(length*2+1);
1404                 if (segment) {
1405                         __ws_byte_to_hex(segment, length * 2 + 1, &service_hex[ptr + 3], length);
1406                         res = __ws_segment_to_service(segment, &new_service);
1407                         if (res < 0) {
1408                                 WDP_LOGE("Failed to convert segment as service instance");
1409                                 g_free(segment);
1410                                 segment = NULL;
1411                                 continue;
1412                         }
1413                         services = g_list_append(services, new_service);
1414                         count++;
1415                         ptr += length + 4;
1416                         g_free(segment);
1417                         segment = NULL;
1418                 }
1419                 data->edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
1420                 data->dev_role = count;
1421                 data->edata = (void*) services;
1422         }
1423 }
1424
1425 void __ws_extract_servicediscoveryresponse_details(const char *key, GVariant *value, void *user_data)
1426 {
1427         __WDP_LOG_FUNC_ENTER__;
1428         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1429
1430         if (!event)
1431                 return;
1432
1433         CHECK_KEY_VALUE(key, value);
1434
1435         if (g_strcmp0(key, "peer_object") == 0) {
1436                 static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
1437                 const char *path = NULL;
1438                 char *loc = NULL;
1439
1440                 g_variant_get(value, "&o", &path);
1441                 if (path == NULL)
1442                         return;
1443
1444                 WDP_LOGD("Retrive Added path [%s]", path);
1445                 loc = strrchr(path, '/');
1446                 if (loc != NULL)
1447                         __ws_mac_compact_to_normal(loc + 1, peer_dev);
1448                 __ws_txt_to_mac(peer_dev, event->dev_addr);
1449
1450         } else if (g_strcmp0(key, "update_indicator") == 0) {
1451
1452         } else if (g_strcmp0(key, "tlvs") == 0) {
1453                 GVariantIter *iter = NULL;
1454                 unsigned char service_hex[WS_MAX_SERVICE_LEN];
1455                 int byte_length = 0;
1456
1457                 g_variant_get(value, "ay", &iter);
1458                 if (iter == NULL) {
1459                         WDP_LOGE("failed to get iterator");
1460                         return;
1461                 }
1462
1463                 memset(service_hex, 0x0, WS_MAX_SERVICE_LEN);
1464                 while (g_variant_iter_loop(iter, "y", &service_hex[byte_length]))
1465                         byte_length++;
1466                 g_variant_iter_free(iter);
1467
1468                 __ws_extract_peer_service(event, service_hex, byte_length);
1469         }
1470
1471         __WDP_LOG_FUNC_EXIT__;
1472 }
1473
1474 static void __ws_extract_serviceaspresponse_details(const char *key, GVariant *value, void *user_data)
1475 {
1476         __WDP_LOG_FUNC_ENTER__;
1477         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1478         if (!event || !event->edata)
1479                 return;
1480
1481         wfd_oem_asp_service_s *service = (wfd_oem_asp_service_s *)event->edata;
1482
1483         if (g_strcmp0(key, "peer_object") == 0) {
1484                 static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
1485                 const char *path = NULL;
1486                 char *loc = NULL;
1487
1488                 g_variant_get(value, "&o", &path);
1489                 if (path == NULL)
1490                         return;
1491
1492                 WDP_LOGD("Retrive Added path [%s]", path);
1493                 loc = strrchr(path, '/');
1494                 if (loc != NULL)
1495                         __ws_mac_compact_to_normal(loc + 1, peer_dev);
1496                 __ws_txt_to_mac(peer_dev, event->dev_addr);
1497
1498         } else if (g_strcmp0(key, "srv_trans_id") == 0) {
1499                 unsigned int srv_trans_id = 0;
1500                 g_variant_get(value, "u", &srv_trans_id);
1501                 service->tran_id = srv_trans_id;
1502                 WDP_LOGD("Retrive srv_trans_id [%x]", service->tran_id);
1503
1504         } else if (g_strcmp0(key, "adv_id") == 0) {
1505                 unsigned int adv_id = 0;
1506                 g_variant_get(value, "u", &adv_id);
1507                 service->adv_id = adv_id;
1508                 WDP_LOGD("Retrive adv_id [%x]", service->adv_id);
1509
1510         } else if (g_strcmp0(key, "svc_status") == 0) {
1511                 unsigned char svc_status = 0;
1512                 g_variant_get(value, "u", &svc_status);
1513                 service->status = svc_status;
1514                 WDP_LOGD("Retrive svc_status [%x]", service->status);
1515
1516         } else if (g_strcmp0(key, "config_methods") == 0) {
1517                 unsigned int config_methods = 0;
1518                 g_variant_get(value, "q", &config_methods);
1519                 service->config_method = config_methods;
1520                 WDP_LOGD("Retrive config_methods [%x]", service->config_method);
1521
1522         } else if (g_strcmp0(key, "svc_str") == 0) {
1523                 const char *svc_str = NULL;
1524                 g_variant_get(value, "&s", &svc_str);
1525                 if (svc_str != NULL)
1526                         service->service_type = g_strdup(svc_str);
1527                 WDP_LOGD("Retrive srv_name [%s]", service->service_type);
1528
1529         } else if (g_strcmp0(key, "info") == 0) {
1530                 const char *info = NULL;
1531                 g_variant_get(value, "&s", &info);
1532                 if (info != NULL)
1533                         service->service_info = g_strdup(info);
1534                 WDP_LOGD("Retrive srv_info [%s]", service->service_info);
1535         }
1536         __WDP_LOG_FUNC_EXIT__;
1537 }
1538
1539 static void __ws_extract_asp_provision_start_details(const char *key, GVariant *value, void *user_data)
1540 {
1541         __WDP_LOG_FUNC_ENTER__;
1542         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1543         wfd_oem_asp_prov_s *asp_params = NULL;
1544         if (!event || !event->edata) {
1545                 __WDP_LOG_FUNC_EXIT__;
1546                 return;
1547         }
1548
1549         asp_params = (wfd_oem_asp_prov_s *)event->edata;
1550
1551         if (g_strcmp0(key, "peer_object") == 0) {
1552                 static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
1553                 const char *path = NULL;
1554                 char *loc = NULL;
1555
1556                 g_variant_get(value, "&o", &path);
1557                 if (path == NULL) {
1558                         __WDP_LOG_FUNC_EXIT__;
1559                         return;
1560                 }
1561
1562                 WDP_LOGD("Retrive Added path [%s]", path);
1563                 loc = strrchr(path, '/');
1564                 if (loc != NULL)
1565                         __ws_mac_compact_to_normal(loc + 1, peer_dev);
1566                 __ws_txt_to_mac(peer_dev, event->dev_addr);
1567
1568         } else if (g_strcmp0(key, "adv_id") == 0) {
1569                 g_variant_get(value, "u", &asp_params->adv_id);
1570                 WDP_LOGD("Retrive adv_id [%u]", asp_params->adv_id);
1571
1572         } else if (g_strcmp0(key, "ses_id") == 0) {
1573                 g_variant_get(value, "u", &asp_params->session_id);
1574                 WDP_LOGD("Retrive session id [%u]", asp_params->session_id);
1575
1576         } else if (g_strcmp0(key, "dev_passwd_id") == 0) {
1577                 g_variant_get(value, "i", &event->wps_mode);
1578                 WDP_LOGD("Retrive dev_passwd_id [%d]", event->wps_mode);
1579
1580         } else if (g_strcmp0(key, "conncap") == 0) {
1581                 g_variant_get(value, "u", &asp_params->network_role);
1582                 WDP_LOGD("Retrive conncap [%x]", asp_params->network_role);
1583
1584         } else if (g_strcmp0(key, "adv_mac") == 0) {
1585                 if (__ws_unpack_ay(asp_params->service_mac, value, WS_MACADDR_LEN))
1586                         WDP_LOGD("Adv address[" MACSTR "]", MAC2STR(asp_params->service_mac));
1587
1588         } else if (g_strcmp0(key, "ses_mac") == 0) {
1589                 if (__ws_unpack_ay(asp_params->session_mac, value, WS_MACADDR_LEN))
1590                         WDP_LOGD("session address[" MACSTR "]", MAC2STR(asp_params->session_mac));
1591
1592         } else if (g_strcmp0(key, "session_info") == 0) {
1593                 const char *session_info = NULL;
1594                 g_variant_get(value, "&s", &session_info);
1595                 if (session_info != NULL)
1596                         asp_params->session_information = g_strdup(session_info);
1597                 WDP_LOGD("Retrive session_info [%s]", asp_params->session_information);
1598         }
1599         __WDP_LOG_FUNC_EXIT__;
1600 }
1601
1602 static void __ws_extract_asp_provision_done_details(const char *key, GVariant *value, void *user_data)
1603 {
1604         __WDP_LOG_FUNC_ENTER__;
1605         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1606         wfd_oem_asp_prov_s *asp_params = NULL;
1607         if (!event || !event->edata) {
1608                 __WDP_LOG_FUNC_EXIT__;
1609                 return;
1610         }
1611
1612         asp_params = (wfd_oem_asp_prov_s *)event->edata;
1613
1614
1615         if (g_strcmp0(key, "peer_object") == 0) {
1616                 static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
1617                 const char *path = NULL;
1618                 char *loc = NULL;
1619
1620                 g_variant_get(value, "&o", &path);
1621                 if (path == NULL) {
1622                         __WDP_LOG_FUNC_EXIT__;
1623                         return;
1624                 }
1625
1626                 WDP_LOGD("Retrive Added path [%s]", path);
1627                 loc = strrchr(path, '/');
1628                 if (loc != NULL)
1629                         __ws_mac_compact_to_normal(loc + 1, peer_dev);
1630                 __ws_txt_to_mac(peer_dev, event->dev_addr);
1631
1632                 WDP_LOGD("peer address[" MACSTR "]", MAC2STR(event->dev_addr));
1633
1634         } else if (g_strcmp0(key, "adv_id") == 0) {
1635                 g_variant_get(value, "u", &asp_params->adv_id);
1636                 WDP_LOGD("Retrive adv_id [%u]", asp_params->adv_id);
1637
1638         } else if (g_strcmp0(key, "ses_id") == 0) {
1639                 g_variant_get(value, "u", &asp_params->session_id);
1640                 WDP_LOGD("Retrive session id [%u]", asp_params->session_id);
1641
1642         } else if (g_strcmp0(key, "dev_passwd_id") == 0) {
1643                 g_variant_get(value, "i", &event->wps_mode);
1644                 WDP_LOGD("Retrive dev_passwd_id [%d]", event->wps_mode);
1645
1646         } else if (g_strcmp0(key, "conncap") == 0) {
1647                 g_variant_get(value, "u", &asp_params->network_role);
1648                 WDP_LOGD("Retrive network role [%x]", asp_params->network_role);
1649
1650         } else if (g_strcmp0(key, "status") == 0) {
1651                 g_variant_get(value, "u", &asp_params->status);
1652                 WDP_LOGD("Retrive status [%x]", asp_params->status);
1653
1654         } else if (g_strcmp0(key, "persist") == 0) {
1655                 g_variant_get(value, "u", &asp_params->persistent_group_id);
1656                 asp_params->persist = 1;
1657                 WDP_LOGD("Retrive persist [%u]", asp_params->persistent_group_id);
1658
1659         }   else if (g_strcmp0(key, "adv_mac") == 0) {
1660                 if (__ws_unpack_ay(asp_params->service_mac, value, WS_MACADDR_LEN))
1661                         WDP_LOGD("Adv address[" MACSTR "]", MAC2STR(asp_params->service_mac));
1662
1663         } else if (g_strcmp0(key, "ses_mac") == 0) {
1664                 if (__ws_unpack_ay(asp_params->session_mac, value, WS_MACADDR_LEN))
1665                         WDP_LOGD("session address[" MACSTR "]", MAC2STR(asp_params->session_mac));
1666
1667         } else if (g_strcmp0(key, "group_mac") == 0) {
1668                 if (__ws_unpack_ay(asp_params->group_mac, value, WS_MACADDR_LEN))
1669                         WDP_LOGD("group address[" MACSTR "]", MAC2STR(asp_params->group_mac));
1670         }
1671         __WDP_LOG_FUNC_EXIT__;
1672 }
1673
1674 static void __ws_extract_provision_fail_details(const char *key, GVariant *value, void *user_data)
1675 {
1676         __WDP_LOG_FUNC_ENTER__;
1677         wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1678         wfd_oem_asp_prov_s *asp_params = NULL;
1679         if (!event || !event->edata) {
1680                 __WDP_LOG_FUNC_EXIT__;
1681                 return;
1682         }
1683
1684         asp_params = (wfd_oem_asp_prov_s *)event->edata;
1685
1686         if (g_strcmp0(key, "peer_object") == 0) {
1687                 static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
1688                 const char *path = NULL;
1689                 char *loc = NULL;
1690
1691                 g_variant_get(value, "&o", &path);
1692                 if (path == NULL) {
1693                         __WDP_LOG_FUNC_EXIT__;
1694                         return;
1695                 }
1696
1697                 WDP_LOGD("Retrive Added path [%s]", path);
1698                 loc = strrchr(path, '/');
1699                 if (loc != NULL)
1700                         __ws_mac_compact_to_normal(loc + 1, peer_dev);
1701                 __ws_txt_to_mac(peer_dev, event->dev_addr);
1702
1703         } else if (g_strcmp0(key, "adv_id") == 0) {
1704                 g_variant_get(value, "u", &asp_params->adv_id);
1705                 WDP_LOGD("Retrive adv_id [%d]", asp_params->adv_id);
1706
1707         }  else if (g_strcmp0(key, "status") == 0) {
1708                 g_variant_get(value, "i", &asp_params->status);
1709                 WDP_LOGD("Retrive status [%d]", asp_params->status);
1710
1711         } else if (g_strcmp0(key, "deferred_session_resp") == 0) {
1712                 const char *session_info = NULL;
1713                 g_variant_get(value, "&s", &session_info);
1714                 if (session_info != NULL)
1715                         asp_params->session_information = g_strdup(session_info);
1716                 WDP_LOGD("Retrive deferred_session_resp [%s]", asp_params->session_information);
1717         }
1718         __WDP_LOG_FUNC_EXIT__;
1719 }
1720
1721 static int _ws_flush(void)
1722 {
1723         __WDP_LOG_FUNC_ENTER__;
1724         GDBusConnection *g_dbus = NULL;
1725         dbus_method_param_s params;
1726         int res = 0;
1727
1728         if (!g_pd) {
1729                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
1730                 __WDP_LOG_FUNC_EXIT__;
1731                 return -1;
1732         }
1733
1734         g_dbus = g_pd->g_dbus;
1735         if (!g_dbus) {
1736                 WDP_LOGE("DBus connection is NULL");
1737                 __WDP_LOG_FUNC_EXIT__;
1738                 return -1;
1739         }
1740         memset(&params, 0x0, sizeof(dbus_method_param_s));
1741
1742         dbus_set_method_param(&params, "Flush", g_pd->iface_path, g_dbus);
1743         params.params = NULL;
1744
1745         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
1746         if (res < 0)
1747                 WDP_LOGE("Failed to send command to wpa_supplicant");
1748         else
1749                 WDP_LOGD("Succeeded to flush");
1750
1751         __WDP_LOG_FUNC_EXIT__;
1752         return 0;
1753 }
1754
1755 static int _ws_cancel(void)
1756 {
1757         __WDP_LOG_FUNC_ENTER__;
1758         GDBusConnection *g_dbus = NULL;
1759         dbus_method_param_s params;
1760         int res = 0;
1761
1762         if (!g_pd) {
1763                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
1764                 __WDP_LOG_FUNC_EXIT__;
1765                 return -1;
1766         }
1767
1768
1769         g_dbus = g_pd->g_dbus;
1770         if (!g_dbus) {
1771                 WDP_LOGE("DBus connection is NULL");
1772                 __WDP_LOG_FUNC_EXIT__;
1773                 return -1;
1774         }
1775         memset(&params, 0x0, sizeof(dbus_method_param_s));
1776
1777         dbus_set_method_param(&params, "Cancel", g_pd->iface_path , g_dbus);
1778         params.params = NULL;
1779
1780         res = dbus_method_call(&params, SUPPLICANT_WPS, NULL, NULL);
1781         if (res < 0)
1782                 WDP_LOGE("Failed to send command to wpa_supplicant");
1783         else
1784                 WDP_LOGD("Succeeded to cancel");
1785
1786         __WDP_LOG_FUNC_EXIT__;
1787         return 0;
1788 }
1789
1790 int ws_get_advertise_service(const char *peer_path, GList **asp_services)
1791 {
1792         __WDP_LOG_FUNC_ENTER__;
1793         GDBusConnection *g_dbus = NULL;
1794         GVariant *param = NULL;
1795         GVariant *reply = NULL;
1796         GVariant *temp1 = NULL;
1797         GVariant *temp2 = NULL;
1798         GError *error = NULL;
1799         GVariantIter *iter = NULL;
1800         wfd_oem_advertise_service_s *service;
1801         wfd_oem_asp_service_s *seek = NULL;
1802         unsigned char desc[7];
1803         unsigned int adv_id;
1804         unsigned int config_method;
1805         unsigned char length;
1806         char *value;
1807         int cnt;
1808         int res = 0;
1809
1810         if (!g_pd) {
1811                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
1812                 return -1;
1813         }
1814
1815         g_dbus = g_pd->g_dbus;
1816         if (!g_dbus) {
1817                 WDP_LOGE("DBus connection is NULL");
1818                 return -1;
1819         }
1820
1821         param = g_variant_new("(ss)", SUPPLICANT_P2P_PEER, "AdvertiseService");
1822         DEBUG_G_VARIANT("Params : ", param);
1823
1824         reply = g_dbus_connection_call_sync(
1825                         g_dbus,
1826                         SUPPLICANT_SERVICE, /* bus name */
1827                         peer_path, /* object path */
1828                         DBUS_PROPERTIES_INTERFACE, /* interface name */
1829                         DBUS_PROPERTIES_METHOD_GET, /* method name */
1830                         param, /* GVariant *params */
1831                         NULL, /* reply_type */
1832                         G_DBUS_CALL_FLAGS_NONE, /* flags */
1833                         SUPPLICANT_TIMEOUT , /* timeout */
1834                         NULL, /* cancellable */
1835                         &error); /* error */
1836
1837         if (error != NULL) {
1838                 WDP_LOGE("Error! Failed to get peer advertise service: [%s]",
1839                                 error->message);
1840                 g_error_free(error);
1841                 if (reply)
1842                         g_variant_unref(reply);
1843                 __WDP_LOG_FUNC_EXIT__;
1844                 return -1;
1845         }
1846
1847         if (reply != NULL) {
1848                 DEBUG_G_VARIANT("Reply : ", reply);
1849
1850                 /* replay will have the format <(<ay>,)>
1851                  * So, you need to remove tuple out side of variant and
1852                  * variant out side of byte array
1853                  * */
1854                 temp1 = g_variant_get_child_value(reply, 0);
1855                 temp2 = g_variant_get_child_value(temp1, 0);
1856                 g_variant_get(temp2, "ay", &iter);
1857                 if (iter == NULL) {
1858                         g_variant_unref(reply);
1859                         WDP_LOGE("Failed to get iterator");
1860                         return -1;
1861                 }
1862                 g_variant_unref(temp2);
1863                 g_variant_unref(temp1);
1864
1865                 while (1) {
1866                         /* 4byte advertisement ID, 2 byte config method, 1byte length */
1867
1868                         cnt = 0;
1869                         memset(desc, 0x0, 7);
1870                         while (cnt < 7 && g_variant_iter_loop(iter, "y", &desc[cnt]))
1871                                 cnt++;
1872
1873                         if (cnt != 7 || desc[6] == 0) {
1874                                 WDP_LOGE("Invalid descriptor header length cnt [%d]", cnt);
1875                                 g_variant_unref(reply);
1876                                 return res;
1877                         }
1878
1879                         adv_id = desc[3] << 24 | desc[2] << 16 | desc[1] << 8 | desc[0];
1880                         config_method = desc[4] << 8 | desc[4];
1881                         length = desc[6];
1882                         value = NULL;
1883                         value = g_try_malloc0(length + 1);
1884                         if (value == NULL) {
1885                                 WDP_LOGE("g_try_malloc0 failed");
1886                                 g_variant_unref(reply);
1887                                 return res;
1888                         }
1889                         WDP_LOGD("adv_id[%u] config_method[%u]  length[%hhu]", adv_id, config_method, length);
1890
1891                         cnt = 0;
1892                         while (cnt < length && g_variant_iter_loop(iter, "y", &value[cnt]))
1893                                 cnt++;
1894
1895                         if (cnt != length) {
1896                                 WDP_LOGE("Length doesn't matched with header value cnt [%d]", cnt);
1897                                 g_variant_unref(reply);
1898                                 g_free(value);
1899                                 return res;
1900                         }
1901
1902                         service = NULL;
1903                         service = (wfd_oem_advertise_service_s *)
1904                                         g_try_malloc0(sizeof(wfd_oem_advertise_service_s));
1905                         if (service == NULL) {
1906                                 WDP_LOGE("g_try_malloc0 failed");
1907                                 g_variant_unref(reply);
1908                                 g_free(value);
1909                                 return res;
1910                         }
1911                         service->adv_id = adv_id;
1912                         service->config_method = config_method;
1913                         service->service_type_length = length;
1914                         service->service_type = value;
1915
1916 GLIST_ITER_START(seek_list, seek)
1917                         if (g_strcmp0(seek->service_type, service->service_type) == 0) {
1918                                 WDP_LOGD("service type matched [%s] search_id [%llu]",
1919                                                 service->service_type, seek->search_id);
1920                         } else {
1921                                 seek = NULL;
1922                         }
1923 GLIST_ITER_END()
1924
1925                         if (seek != NULL && seek->service_info != NULL) {
1926                                 WDP_LOGD("service info exists, service discovery will be performed");
1927                         } else {
1928                                 WDP_LOGD("service info doesn't exists. Add service to list");
1929                                 if (seek)
1930                                         service->search_id = seek->search_id;
1931                                 *asp_services = g_list_append(*asp_services, service);
1932                         }
1933                 }
1934                 g_variant_unref(reply);
1935         }
1936         __WDP_LOG_FUNC_EXIT__;
1937         return res;
1938 }
1939
1940
1941 int ws_get_advertise_asp_service(const char *peer_path, GList **asp_services)
1942 {
1943         __WDP_LOG_FUNC_ENTER__;
1944         GDBusConnection *g_dbus = NULL;
1945         GVariant *param = NULL;
1946         GVariant *reply = NULL;
1947         GVariant *temp1 = NULL;
1948         GVariant *temp2 = NULL;
1949         GError *error = NULL;
1950         GVariantIter *iter = NULL;
1951         wfd_oem_advertise_service_s *service;
1952         wfd_oem_asp_service_s *seek = NULL;
1953         unsigned char desc[7];
1954         unsigned int adv_id;
1955         unsigned int config_method;
1956         unsigned char length;
1957         char *service_type = NULL;
1958         char *instance_name = NULL;
1959         unsigned char instance_length = 0;
1960         int cnt;
1961         int res = 0;
1962
1963         if (!g_pd) {
1964                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
1965                 return -1;
1966         }
1967
1968         g_dbus = g_pd->g_dbus;
1969         if (!g_dbus) {
1970                 WDP_LOGE("DBus connection is NULL");
1971                 return -1;
1972         }
1973
1974         param = g_variant_new("(ss)", SUPPLICANT_P2P_PEER, "AdvertiseASPService");
1975         DEBUG_G_VARIANT("Params : ", param);
1976
1977         reply = g_dbus_connection_call_sync(
1978                         g_dbus,
1979                         SUPPLICANT_SERVICE, /* bus name */
1980                         peer_path, /* object path */
1981                         DBUS_PROPERTIES_INTERFACE, /* interface name */
1982                         DBUS_PROPERTIES_METHOD_GET, /* method name */
1983                         param, /* GVariant *params */
1984                         NULL, /* reply_type */
1985                         G_DBUS_CALL_FLAGS_NONE, /* flags */
1986                         SUPPLICANT_TIMEOUT , /* timeout */
1987                         NULL, /* cancellable */
1988                         &error); /* error */
1989
1990         if (error != NULL) {
1991                 WDP_LOGE("Error! Failed to get peer advertise service: [%s]",
1992                                 error->message);
1993                 g_error_free(error);
1994                 if (reply)
1995                         g_variant_unref(reply);
1996                 __WDP_LOG_FUNC_EXIT__;
1997                 return -1;
1998         }
1999
2000         if (reply != NULL) {
2001                 DEBUG_G_VARIANT("Reply : ", reply);
2002
2003                 /* replay will have the format <(<ay>,)>
2004                  * So, you need to remove tuple out side of variant and
2005                  * variant out side of byte array
2006                  * */
2007                 temp1 = g_variant_get_child_value(reply, 0);
2008                 temp2 = g_variant_get_child_value(temp1, 0);
2009                 g_variant_get(temp2, "ay", &iter);
2010                 if (iter == NULL) {
2011                         g_variant_unref(reply);
2012                         WDP_LOGE("Failed to get iterator");
2013                         return -1;
2014                 }
2015                 g_variant_unref(temp2);
2016                 g_variant_unref(temp1);
2017
2018                 while (1) {
2019                         /* 4byte advertisement ID, 2 byte config method, 1byte length */
2020
2021                         cnt = 0;
2022                         memset(desc, 0x0, 7);
2023                         while (cnt < 7 && g_variant_iter_loop(iter, "y", &desc[cnt]))
2024                                 cnt++;
2025
2026                         if (cnt != 7 || desc[6] == 0) {
2027                                 WDP_LOGE("Invalid descriptor header length cnt [%d]", cnt);
2028                                 g_variant_unref(reply);
2029                                 return res;
2030                         }
2031
2032                         adv_id = desc[3] << 24 | desc[2] << 16 | desc[1] << 8 | desc[0];
2033                         config_method = desc[4] << 8 | desc[4];
2034                         length = desc[6];
2035                         service_type = g_try_malloc0(length + 1);
2036                         if (service_type == NULL) {
2037                                 WDP_LOGE("g_try_malloc0 failed");
2038                                 g_variant_unref(reply);
2039                                 return res;
2040                         }
2041                         WDP_LOGD("adv_id[%u] config_method[%u]  length[%hhu]", adv_id, config_method, length);
2042
2043                         cnt = 0;
2044                         while (cnt < length + 1 && g_variant_iter_loop(iter, "y", &service_type[cnt]))
2045                                 cnt++;
2046
2047                         if (cnt != length + 1) {
2048                                 WDP_LOGE("Length doesn't matched with header value cnt [%d]", cnt);
2049                                 g_variant_unref(reply);
2050                                 g_free(service_type);
2051                                 return res;
2052                         }
2053
2054                         instance_length = (unsigned char)service_type[length];
2055                         service_type[length] = '\0';
2056
2057                         if (instance_length != 0) {
2058                                 instance_name = g_try_malloc0(instance_length + 1);
2059                                 if (instance_name == NULL) {
2060                                         WDP_LOGE("g_try_malloc0 failed");
2061                                         g_variant_unref(reply);
2062                                         g_free(service_type);
2063                                         return res;
2064                                 }
2065                                 WDP_LOGD("instnace name length[%hhu]", instance_length);
2066
2067                                 cnt = 0;
2068                                 while (cnt < instance_length && g_variant_iter_loop(iter, "y", &instance_name[cnt]))
2069                                         cnt++;
2070
2071                                 if (cnt != instance_length) {
2072                                         WDP_LOGE("Length doesn't matched with header value cnt [%d]", cnt);
2073                                         g_variant_unref(reply);
2074                                         g_free(service_type);
2075                                         g_free(instance_name);
2076                                         return res;
2077                                 }
2078                         }
2079
2080                         service = NULL;
2081                         service = (wfd_oem_advertise_service_s *)
2082                                         g_try_malloc0(sizeof(wfd_oem_advertise_service_s));
2083                         if (service == NULL) {
2084                                 WDP_LOGE("g_try_malloc0 failed");
2085                                 g_variant_unref(reply);
2086                                 g_free(service_type);
2087                                 g_free(instance_name);
2088                                 return res;
2089                         }
2090                         service->adv_id = adv_id;
2091                         service->config_method = config_method;
2092                         service->service_type_length = length;
2093                         service->service_type = service_type;
2094                         service->instance_name_length = instance_length;
2095                         service->instance_name = instance_name;
2096
2097 GLIST_ITER_START(seek_list, seek)
2098                         if (g_strcmp0(seek->service_type, service->service_type) == 0) {
2099                                 /* TODO: We need to support for instance name also hear */
2100                                 WDP_LOGD("service type matched [%s] search_id [%llu]",
2101                                                 service->service_type, seek->search_id);
2102                         } else {
2103                                 seek = NULL;
2104                         }
2105 GLIST_ITER_END()
2106
2107                         if (seek != NULL && seek->service_info != NULL) {
2108                                 WDP_LOGD("service info exists, service discovery will be performed");
2109                         } else {
2110                                 WDP_LOGD("service info doesn't exists. Add service to list");
2111                                 if (seek)
2112                                         service->search_id = seek->search_id;
2113                                 *asp_services = g_list_append(*asp_services, service);
2114                         }
2115                 }
2116                 g_variant_unref(reply);
2117         }
2118         __WDP_LOG_FUNC_EXIT__;
2119         return res;
2120 }
2121
2122 static void _ws_process_device_found_properties(GDBusConnection *connection,
2123                 const gchar *sender, const gchar *object_path, const gchar *interface,
2124                 const gchar *signal, GVariant *parameters, gpointer user_data)
2125 {
2126         __WDP_LOG_FUNC_ENTER__;
2127         wfd_oem_event_s event;
2128         wfd_oem_dev_data_s *dev_data = NULL;
2129         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2130         GVariantIter *iter = NULL;
2131         const char *path = NULL;
2132
2133         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2134
2135         if (!__is_valid_plugin())
2136                 return;
2137
2138         dev_data = __create_dev_data();
2139         if (!dev_data) {
2140                 __WDP_LOG_FUNC_EXIT__;
2141                 return;
2142         }
2143
2144         __set_event_data(WFD_OEM_EVENT_PEER_FOUND,
2145                         WFD_OEM_EDATA_TYPE_DEVICE,
2146                         (void *)dev_data,
2147                         &event);
2148
2149         g_variant_get(parameters, "(&oa{sv})", &path, &iter);
2150         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
2151         WDP_LOGD("Retrive Added path [%s]", peer_path);
2152
2153         __extract_addr_from_path(peer_path, event.dev_addr);
2154
2155         if (iter != NULL) {
2156                 gchar *key = NULL;
2157                 GVariant *value = NULL;
2158
2159                 while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
2160                         CHECK_KEY_VALUE(key, value);
2161
2162                         __ws_peer_property(key, value, (void *)event.edata);
2163                 }
2164                 g_variant_iter_free(iter);
2165         }
2166
2167         if (dev_data->has_asp_services)
2168                 ws_get_advertise_service(peer_path, (GList **)&(event.asp_services));
2169         if (dev_data->has_asp2_services)
2170                 ws_get_advertise_asp_service(peer_path, (GList **)&(event.asp2_services));
2171
2172         if (g_pd->callback->peer_found_cb)
2173                 g_pd->callback->peer_found_cb(&event);
2174
2175         if (event.asp_services != NULL) {
2176                 GList *l;
2177                 wfd_oem_advertise_service_s *service;
2178                 for (l = (GList *)event.asp_services; l != NULL; l = l->next) {
2179                         service = (wfd_oem_advertise_service_s *)l->data;
2180                         event.asp_services = g_list_remove(l, service);
2181                         g_free(service->service_type);
2182                         g_free(service);
2183                 }
2184         }
2185         if (event.asp2_services != NULL) {
2186                 GList *l;
2187                 wfd_oem_advertise_service_s *service;
2188                 for (l = (GList *)event.asp2_services; l != NULL; l = l->next) {
2189                         service = (wfd_oem_advertise_service_s *)l->data;
2190                         event.asp_services = g_list_remove(l, service);
2191                         g_free(service->service_type);
2192                         g_free(service->instance_name);
2193                         g_free(service);
2194                 }
2195         }
2196
2197         __destroy_dev_data(dev_data);
2198
2199         __WDP_LOG_FUNC_EXIT__;
2200 }
2201
2202 static void _ws_process_device_lost(GDBusConnection *connection,
2203                 const gchar *sender, const gchar *object_path, const gchar *interface,
2204                 const gchar *signal, GVariant *parameters, gpointer user_data)
2205 {
2206         __WDP_LOG_FUNC_ENTER__;
2207         wfd_oem_event_s event;
2208         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2209
2210         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2211
2212         if (!g_pd || !g_pd->callback) {
2213                 WDP_LOGD("Ignoring event");
2214                 __WDP_LOG_FUNC_EXIT__;
2215                 return;
2216         }
2217
2218         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2219
2220         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
2221         event.event_id = WFD_OEM_EVENT_PEER_DISAPPEARED;
2222
2223         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2224
2225         if (g_pd->callback->peer_disappeared_cb)
2226                 g_pd->callback->peer_disappeared_cb(&event);
2227
2228
2229         __WDP_LOG_FUNC_EXIT__;
2230 }
2231
2232 static void _ws_process_find_stoppped(GDBusConnection *connection,
2233                 const gchar *sender, const gchar *object_path, const gchar *interface,
2234                 const gchar *signal, GVariant *parameters, gpointer user_data)
2235 {
2236         __WDP_LOG_FUNC_ENTER__;
2237         wfd_oem_event_s event;
2238
2239         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2240
2241         if (!g_pd || !g_pd->callback) {
2242                 WDP_LOGD("Ignoring event");
2243                 __WDP_LOG_FUNC_EXIT__;
2244                 return;
2245         }
2246
2247         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2248
2249         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
2250         event.event_id = WFD_OEM_EVENT_DISCOVERY_FINISHED;
2251
2252         if (g_pd->callback->discovery_finished_cb)
2253                 g_pd->callback->discovery_finished_cb(&event);
2254
2255         __WDP_LOG_FUNC_EXIT__;
2256 }
2257
2258 static void _ws_process_prov_disc_req_display_pin(GDBusConnection *connection,
2259                 const gchar *sender, const gchar *object_path, const gchar *interface,
2260                 const gchar *signal, GVariant *parameters, gpointer user_data)
2261 {
2262         __WDP_LOG_FUNC_ENTER__;
2263         wfd_oem_event_s event;
2264         wfd_oem_dev_data_s *dev_data = NULL;
2265         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2266         const char *path = NULL;
2267         const char *pin = NULL;
2268         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2269
2270         if (!__is_valid_plugin())
2271                 return;
2272
2273         dev_data = __create_dev_data();
2274         if (!dev_data) {
2275                 __WDP_LOG_FUNC_EXIT__;
2276                 return;
2277         }
2278
2279         __set_event_data(WFD_OEM_EVENT_PROV_DISC_REQ,
2280                         WFD_OEM_EDATA_TYPE_DEVICE,
2281                         (void *)dev_data,
2282                         &event);
2283         event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
2284
2285         g_variant_get(parameters, "(&o&s)", &path, &pin);
2286         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
2287         WDP_LOGD("Retrive Added path [%s]", peer_path);
2288
2289         __extract_addr_from_path(peer_path, event.dev_addr);
2290
2291         g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
2292         WDP_LOGD("Retrive pin [%s]", event.wps_pin);
2293
2294         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2295                         __ws_peer_property, event.edata);
2296
2297         if (g_pd->callback->prov_disc_req_cb)
2298                 g_pd->callback->prov_disc_req_cb(&event);
2299
2300         __destroy_dev_data(dev_data);
2301
2302         __WDP_LOG_FUNC_EXIT__;
2303 }
2304
2305 static void _ws_process_prov_disc_resp_display_pin(GDBusConnection *connection,
2306                 const gchar *sender, const gchar *object_path, const gchar *interface,
2307                 const gchar *signal, GVariant *parameters, gpointer user_data)
2308 {
2309         __WDP_LOG_FUNC_ENTER__;
2310         wfd_oem_event_s event;
2311         wfd_oem_dev_data_s *dev_data = NULL;
2312         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2313         const char *path = NULL;
2314         const char *pin = NULL;
2315
2316         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2317
2318         if (!__is_valid_plugin())
2319                 return;
2320
2321         dev_data = __create_dev_data();
2322         if (!dev_data) {
2323                 __WDP_LOG_FUNC_EXIT__;
2324                 return;
2325         }
2326
2327         __set_event_data(WFD_OEM_EVENT_PROV_DISC_RESP,
2328                         WFD_OEM_EDATA_TYPE_DEVICE,
2329                         (void *)dev_data,
2330                         &event);
2331         event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
2332
2333         g_variant_get(parameters, "(&o&s)", &path, &pin);
2334         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
2335         WDP_LOGD("Retrive Added path [%s]", peer_path);
2336
2337         __extract_addr_from_path(peer_path, event.dev_addr);
2338
2339         g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
2340         WDP_LOGD("Retrive pin [%s]", event.wps_pin);
2341
2342         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2343                         __ws_peer_property, event.edata);
2344
2345         if (g_pd->callback->prov_disc_resp_cb)
2346                 g_pd->callback->prov_disc_resp_cb(&event);
2347
2348         __destroy_dev_data(dev_data);
2349
2350         __WDP_LOG_FUNC_EXIT__;
2351 }
2352
2353 static void _ws_process_prov_disc_req_enter_pin(GDBusConnection *connection,
2354                 const gchar *sender, const gchar *object_path, const gchar *interface,
2355                 const gchar *signal, GVariant *parameters, gpointer user_data)
2356 {
2357         __WDP_LOG_FUNC_ENTER__;
2358         wfd_oem_event_s event;
2359         wfd_oem_dev_data_s *dev_data = NULL;
2360         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2361
2362         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2363         if (!__is_valid_plugin())
2364                 return;
2365
2366         dev_data = __create_dev_data();
2367         if (!dev_data) {
2368                 __WDP_LOG_FUNC_EXIT__;
2369                 return;
2370         }
2371
2372         __set_event_data(WFD_OEM_EVENT_PROV_DISC_REQ,
2373                         WFD_OEM_EDATA_TYPE_DEVICE,
2374                         (void *)dev_data,
2375                         &event);
2376         event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
2377
2378         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2379
2380         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2381                         __ws_peer_property, event.edata);
2382
2383         if (g_pd->callback->prov_disc_req_cb)
2384                 g_pd->callback->prov_disc_req_cb(&event);
2385
2386         __destroy_dev_data(dev_data);
2387
2388         __WDP_LOG_FUNC_EXIT__;
2389 }
2390
2391 static void _ws_process_prov_disc_resp_enter_pin(GDBusConnection *connection,
2392                 const gchar *sender, const gchar *object_path, const gchar *interface,
2393                 const gchar *signal, GVariant *parameters, gpointer user_data)
2394 {
2395         __WDP_LOG_FUNC_ENTER__;
2396         wfd_oem_event_s event;
2397         wfd_oem_dev_data_s *dev_data = NULL;
2398         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2399
2400         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2401
2402         if (!__is_valid_plugin())
2403                 return;
2404
2405         dev_data = __create_dev_data();
2406         if (!dev_data) {
2407                 __WDP_LOG_FUNC_EXIT__;
2408                 return;
2409         }
2410
2411         __set_event_data(WFD_OEM_EVENT_PROV_DISC_RESP,
2412                         WFD_OEM_EDATA_TYPE_DEVICE,
2413                         (void *)dev_data,
2414                         &event);
2415
2416         event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
2417
2418         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2419
2420         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2421                         __ws_peer_property, event.edata);
2422
2423         if (g_pd->callback->prov_disc_resp_cb)
2424                 g_pd->callback->prov_disc_resp_cb(&event);
2425
2426         __destroy_dev_data(dev_data);
2427
2428         __WDP_LOG_FUNC_EXIT__;
2429 }
2430
2431 static void _ws_process_prov_disc_pbc_req(GDBusConnection *connection,
2432                 const gchar *sender, const gchar *object_path, const gchar *interface,
2433                 const gchar *signal, GVariant *parameters, gpointer user_data)
2434 {
2435         __WDP_LOG_FUNC_ENTER__;
2436         wfd_oem_event_s event;
2437         wfd_oem_dev_data_s *dev_data = NULL;
2438         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2439
2440         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2441
2442         if (!__is_valid_plugin())
2443                 return;
2444
2445         dev_data = __create_dev_data();
2446         if (!dev_data) {
2447                 __WDP_LOG_FUNC_EXIT__;
2448                 return;
2449         }
2450         __set_event_data(WFD_OEM_EVENT_PROV_DISC_REQ,
2451                         WFD_OEM_EDATA_TYPE_DEVICE,
2452                         (void *)dev_data,
2453                         &event);
2454         event.wps_mode = WFD_OEM_WPS_MODE_PBC;
2455
2456         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2457
2458         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2459                         __ws_peer_property, event.edata);
2460
2461         if (g_pd->callback->prov_disc_req_cb)
2462                 g_pd->callback->prov_disc_req_cb(&event);
2463
2464         __destroy_dev_data(dev_data);
2465
2466         __WDP_LOG_FUNC_EXIT__;
2467 }
2468
2469 static void _ws_process_prov_disc_pbc_resp(GDBusConnection *connection,
2470                 const gchar *sender, const gchar *object_path, const gchar *interface,
2471                 const gchar *signal, GVariant *parameters, gpointer user_data)
2472 {
2473         __WDP_LOG_FUNC_ENTER__;
2474         wfd_oem_event_s event;
2475         wfd_oem_dev_data_s *dev_data = NULL;
2476         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2477
2478         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2479
2480         if (!__is_valid_plugin())
2481                 return;
2482
2483         dev_data = __create_dev_data();
2484         if (!dev_data) {
2485                 __WDP_LOG_FUNC_EXIT__;
2486                 return;
2487         }
2488         __set_event_data(WFD_OEM_EVENT_PROV_DISC_RESP,
2489                         WFD_OEM_EDATA_TYPE_DEVICE,
2490                         (void *)dev_data,
2491                         &event);
2492         event.wps_mode = WFD_OEM_WPS_MODE_PBC;
2493
2494         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2495
2496         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2497                         __ws_peer_property, event.edata);
2498
2499         if (g_pd->callback->prov_disc_resp_cb)
2500                 g_pd->callback->prov_disc_resp_cb(&event);
2501
2502         __destroy_dev_data(dev_data);
2503
2504         __WDP_LOG_FUNC_EXIT__;
2505 }
2506
2507 static void _ws_process_prov_disc_failure(GDBusConnection *connection,
2508                 const gchar *sender, const gchar *object_path, const gchar *interface,
2509                 const gchar *signal, GVariant *parameters, gpointer user_data)
2510 {
2511         __WDP_LOG_FUNC_ENTER__;
2512         GVariantIter *iter = NULL;
2513         wfd_oem_event_s event;
2514         wfd_oem_asp_prov_s *edata;
2515
2516         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2517
2518         if (!g_pd || !g_pd->callback) {
2519                 WDP_LOGD("Ignoring event");
2520                 __WDP_LOG_FUNC_EXIT__;
2521                 return;
2522         }
2523
2524         edata = (wfd_oem_asp_prov_s *) g_try_malloc0(sizeof(wfd_oem_asp_prov_s));
2525         if (!edata) {
2526                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2527                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2528                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2529                                 error_buf);
2530                 __WDP_LOG_FUNC_EXIT__;
2531                 return;
2532         }
2533         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2534
2535         event.edata = (void*) edata;
2536         event.event_id = WFD_OEM_EVENT_PROV_DISC_FAIL;
2537
2538         if (parameters != NULL) {
2539                 g_variant_get(parameters, "(a{sv})", &iter);
2540                 if (iter != NULL) {
2541                         dbus_property_foreach(iter, __ws_extract_provision_fail_details, &event);
2542                         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_PROV;
2543                         g_variant_iter_free(iter);
2544                 }
2545         } else {
2546                 WDP_LOGE("No Properties");
2547         }
2548
2549         if (g_pd->callback->prov_disc_fail_cb)
2550                 g_pd->callback->prov_disc_fail_cb(&event);
2551
2552         if (event.edata_type == WFD_OEM_EDATA_TYPE_ASP_PROV)
2553                 g_free(edata->session_information);
2554         g_free(edata);
2555
2556         __WDP_LOG_FUNC_EXIT__;
2557 }
2558
2559 static void _ws_process_group_started(GDBusConnection *connection,
2560                 const gchar *sender, const gchar *object_path, const gchar *interface,
2561                 const gchar *signal, GVariant *parameters, gpointer user_data)
2562 {
2563         __WDP_LOG_FUNC_ENTER__;
2564         GVariantIter *iter = NULL;
2565         wfd_oem_event_s event;
2566         wfd_oem_group_data_s *edata = NULL;
2567
2568         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2569
2570         if (!g_pd || !g_pd->callback) {
2571                 WDP_LOGD("Ignoring event");
2572                 __WDP_LOG_FUNC_EXIT__;
2573                 return;
2574         }
2575
2576         edata = (wfd_oem_group_data_s*)calloc(1, sizeof(wfd_oem_group_data_s));
2577         if (!edata) {
2578                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2579                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2580                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2581                                 error_buf);
2582                 __WDP_LOG_FUNC_EXIT__;
2583                 return;
2584         }
2585         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2586
2587         event.edata = (void*) edata;
2588         event.edata_type = WFD_OEM_EDATA_TYPE_GROUP;
2589         event.event_id = WFD_OEM_EVENT_GROUP_CREATED;
2590
2591         if (parameters != NULL) {
2592                 g_variant_get(parameters, "(a{sv})", &iter);
2593
2594                 if (iter != NULL) {
2595                         dbus_property_foreach(iter, __ws_extract_group_details, &event);
2596                         g_variant_iter_free(iter);
2597                 }
2598         } else {
2599                 WDP_LOGE("No properties");
2600         }
2601
2602         if (g_pd->callback->group_created_cb)
2603                 g_pd->callback->group_created_cb(&event);
2604
2605         g_free(event.edata);
2606
2607         __WDP_LOG_FUNC_EXIT__;
2608 }
2609
2610 static void _ws_process_go_neg_success(GDBusConnection *connection,
2611                 const gchar *sender, const gchar *object_path, const gchar *interface,
2612                 const gchar *signal, GVariant *parameters, gpointer user_data)
2613 {
2614         __WDP_LOG_FUNC_ENTER__;
2615         GVariantIter *iter = NULL;
2616         wfd_oem_event_s event;
2617         wfd_oem_conn_data_s *edata = NULL;
2618
2619         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2620
2621         if (!g_pd || !g_pd->callback) {
2622                 WDP_LOGD("Ignoring event");
2623                 __WDP_LOG_FUNC_EXIT__;
2624                 return;
2625         }
2626
2627         edata = (wfd_oem_conn_data_s*)calloc(1, sizeof(wfd_oem_conn_data_s));
2628         if (!edata) {
2629                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2630                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2631                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2632                                 error_buf);
2633                 __WDP_LOG_FUNC_EXIT__;
2634                 return;
2635         }
2636         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2637
2638         event.edata = edata;
2639         event.edata_type = WFD_OEM_EDATA_TYPE_CONN;
2640         event.event_id = WFD_OEM_EVENT_GO_NEG_DONE;
2641
2642         if (parameters != NULL) {
2643                 g_variant_get(parameters, "(a{sv})", &iter);
2644
2645                 if (iter != NULL) {
2646                         dbus_property_foreach(iter, __ws_extract_gonegsuccess_details, &event);
2647                         g_variant_iter_free(iter);
2648                 }
2649         } else {
2650                 WDP_LOGE("No properties");
2651         }
2652
2653         if (g_pd->callback->go_neg_done_cb)
2654                 g_pd->callback->go_neg_done_cb(&event);
2655
2656         g_free(edata);
2657
2658         __WDP_LOG_FUNC_EXIT__;
2659 }
2660
2661 static void _ws_process_go_neg_failure(GDBusConnection *connection,
2662                 const gchar *sender, const gchar *object_path, const gchar *interface,
2663                 const gchar *signal, GVariant *parameters, gpointer user_data)
2664 {
2665         __WDP_LOG_FUNC_ENTER__;
2666         GVariantIter *iter = NULL;
2667         wfd_oem_event_s event;
2668         wfd_oem_conn_data_s *edata = NULL;
2669
2670         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2671
2672         if (!g_pd || !g_pd->callback) {
2673                 WDP_LOGD("Ignoring event");
2674                 __WDP_LOG_FUNC_EXIT__;
2675                 return;
2676         }
2677
2678         edata = (wfd_oem_conn_data_s *) g_try_malloc0(sizeof(wfd_oem_conn_data_s));
2679         if (!edata) {
2680                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2681                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2682                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2683                                 error_buf);
2684                 __WDP_LOG_FUNC_EXIT__;
2685                 return;
2686         }
2687         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2688
2689         event.edata = (void*) edata;
2690         event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
2691         event.event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
2692
2693         if (parameters != NULL) {
2694                 g_variant_get(parameters, "(a{sv})", &iter);
2695
2696                 if (iter != NULL) {
2697                         dbus_property_foreach(iter, __ws_extract_gonegfailaure_details, &event);
2698                         g_variant_iter_free(iter);
2699                 }
2700         } else {
2701                 WDP_LOGE("No properties");
2702         }
2703
2704         if (g_pd->callback->go_neg_fail_cb)
2705                 g_pd->callback->go_neg_fail_cb(&event);
2706
2707         g_free(event.edata);
2708
2709         __WDP_LOG_FUNC_EXIT__;
2710 }
2711
2712 static void __set_wps_mode_for_event(int dev_passwd_id, wfd_oem_event_s *event)
2713 {
2714         if (!event)
2715                 return;
2716
2717         WDP_LOGD("Retrive dev_passwd_id [%d]", dev_passwd_id);
2718
2719         if (dev_passwd_id == WS_DEV_PASSWD_ID_PUSH_BUTTON)
2720                 event->wps_mode = WFD_OEM_WPS_MODE_PBC;
2721         else if (dev_passwd_id == WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED)
2722                 event->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
2723         else if (dev_passwd_id == WS_DEV_PASSWD_ID_USER_SPECIFIED)
2724                 event->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
2725         else
2726                 event->wps_mode = WFD_OEM_WPS_MODE_NONE;
2727 }
2728
2729 static void _ws_process_go_neg_request(GDBusConnection *connection,
2730                 const gchar *sender, const gchar *object_path, const gchar *interface,
2731                 const gchar *signal, GVariant *parameters, gpointer user_data)
2732 {
2733         __WDP_LOG_FUNC_ENTER__;
2734         wfd_oem_event_s event;
2735         wfd_oem_dev_data_s *dev_data = NULL;
2736         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2737         const char *path = NULL;
2738         int dev_passwd_id = 0;
2739         int device_go_intent = 0;
2740
2741         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2742
2743         if (!__is_valid_plugin())
2744                 return;
2745
2746         dev_data = __create_dev_data();
2747         if (!dev_data) {
2748                 __WDP_LOG_FUNC_EXIT__;
2749                 return;
2750         }
2751         __set_event_data(WFD_OEM_EVENT_GO_NEG_REQ,
2752                         WFD_OEM_EDATA_TYPE_DEVICE,
2753                         (void *)dev_data,
2754                         &event);
2755
2756         g_variant_get(parameters, "(&oqy)", &path, &dev_passwd_id, &device_go_intent);
2757         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
2758
2759         WDP_LOGD("Retrive peer path [%s]", peer_path);
2760         __set_wps_mode_for_event(dev_passwd_id, &event);
2761         WDP_LOGD("Retrive device_go_intent [%d]", device_go_intent);
2762         dev_data->device_go_intent = device_go_intent;
2763
2764         __extract_addr_from_path(peer_path, event.dev_addr);
2765
2766         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2767                         __ws_peer_property, event.edata);
2768
2769         if (g_pd->callback->go_neg_req_cb)
2770                 g_pd->callback->go_neg_req_cb(&event);
2771
2772         __destroy_dev_data(dev_data);
2773
2774         __WDP_LOG_FUNC_EXIT__;
2775 }
2776 static void _ws_process_invitation_received(GDBusConnection *connection,
2777                 const gchar *sender, const gchar *object_path, const gchar *interface,
2778                 const gchar *signal, GVariant *parameters, gpointer user_data)
2779 {
2780         __WDP_LOG_FUNC_ENTER__;
2781         GVariantIter *iter = NULL;
2782         wfd_oem_event_s event;
2783         wfd_oem_invite_data_s *edata = NULL;
2784
2785         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2786
2787         if (!g_pd || !g_pd->callback) {
2788                 WDP_LOGD("Ignoring event");
2789                 __WDP_LOG_FUNC_EXIT__;
2790                 return;
2791         }
2792
2793         edata = (wfd_oem_invite_data_s *) g_try_malloc0(sizeof(wfd_oem_invite_data_s));
2794         if (!edata) {
2795                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2796                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2797                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2798                                 error_buf);
2799                 __WDP_LOG_FUNC_EXIT__;
2800                 return;
2801         }
2802         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2803
2804         event.edata = (void*) edata;
2805         event.edata_type = WFD_OEM_EDATA_TYPE_INVITE;
2806         event.event_id = WFD_OEM_EVENT_INVITATION_REQ;
2807
2808         if (parameters != NULL) {
2809                 g_variant_get(parameters, "(a{sv})", &iter);
2810
2811                 if (iter != NULL) {
2812                         dbus_property_foreach(iter, __ws_extract_invitation_details, &event);
2813                         g_variant_iter_free(iter);
2814                 }
2815         } else {
2816                 WDP_LOGE("No properties");
2817         }
2818         memcpy(&(event.dev_addr), edata->sa, OEM_MACADDR_LEN);
2819
2820         if (g_pd->callback->invitation_req_cb)
2821                 g_pd->callback->invitation_req_cb(&event);
2822
2823         g_free(event.edata);
2824
2825         __WDP_LOG_FUNC_EXIT__;
2826 }
2827
2828 static void _ws_process_invitation_result(GDBusConnection *connection,
2829                 const gchar *sender, const gchar *object_path, const gchar *interface,
2830                 const gchar *signal, GVariant *parameters, gpointer user_data)
2831 {
2832         __WDP_LOG_FUNC_ENTER__;
2833         wfd_oem_event_s event;
2834
2835         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2836
2837         if (!g_pd || !g_pd->callback) {
2838                 WDP_LOGD("Ignoring event");
2839                 __WDP_LOG_FUNC_EXIT__;
2840                 return;
2841         }
2842
2843         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2844
2845         __WDP_LOG_FUNC_EXIT__;
2846 }
2847
2848 static void _ws_process_group_finished(GDBusConnection *connection,
2849                 const gchar *sender, const gchar *object_path, const gchar *interface,
2850                 const gchar *signal, GVariant *parameters, gpointer user_data)
2851 {
2852         __WDP_LOG_FUNC_ENTER__;
2853         wfd_oem_event_s event;
2854         int i = 0;
2855
2856         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2857
2858         if (!g_pd || !g_pd->callback) {
2859                 WDP_LOGD("Ignoring event");
2860                 __WDP_LOG_FUNC_EXIT__;
2861                 return;
2862         }
2863
2864         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2865
2866         event.event_id = WFD_OEM_EVENT_GROUP_DESTROYED;
2867         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
2868
2869         for (i = 0; ws_group_signal_map[i].member != NULL; i++) {
2870                 g_dbus_connection_signal_unsubscribe(g_pd->g_dbus, ws_group_signal_map[i].sub_id);
2871                 ws_group_signal_map[i].sub_id = 0;
2872         }
2873
2874         _ws_manage_group_iface_signal(interface, FALSE);
2875         memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
2876         _ws_flush();
2877
2878         if (g_pd->callback->group_destroyed_cb)
2879                 g_pd->callback->group_destroyed_cb(&event);
2880
2881         __WDP_LOG_FUNC_EXIT__;
2882 }
2883
2884 static void _ws_process_service_discovery_response(GDBusConnection *connection,
2885                 const gchar *sender, const gchar *object_path, const gchar *interface,
2886                 const gchar *signal, GVariant *parameters, gpointer user_data)
2887 {
2888         __WDP_LOG_FUNC_ENTER__;
2889         GVariantIter *iter = NULL;
2890         wfd_oem_event_s event;
2891
2892         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2893
2894         if (!g_pd || !g_pd->callback) {
2895                 WDP_LOGD("Ignoring event");
2896                 __WDP_LOG_FUNC_EXIT__;
2897                 return;
2898         }
2899
2900         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2901
2902         event.event_id = WFD_OEM_EVENT_SERV_DISC_RESP;
2903
2904         if (parameters != NULL) {
2905                 g_variant_get(parameters, "(a{sv})", &iter);
2906                 if (iter != NULL) {
2907                         dbus_property_foreach(iter, __ws_extract_servicediscoveryresponse_details, &event);
2908                         event.edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
2909                         g_variant_iter_free(iter);
2910                 }
2911         } else {
2912                 WDP_LOGE("No Properties");
2913         }
2914
2915         if (g_pd->callback->serv_disc_resp_cb)
2916                 g_pd->callback->serv_disc_resp_cb(&event);
2917
2918         if (event.edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE)
2919                 g_list_free((GList*) event.edata);
2920
2921         __WDP_LOG_FUNC_EXIT__;
2922 }
2923
2924 static void _ws_process_service_asp_response(GDBusConnection *connection,
2925                 const gchar *sender, const gchar *object_path, const gchar *interface,
2926                 const gchar *signal, GVariant *parameters, gpointer user_data)
2927 {
2928         __WDP_LOG_FUNC_ENTER__;
2929         GVariantIter *iter = NULL;
2930         wfd_oem_event_s event;
2931         wfd_oem_asp_service_s *service = NULL;
2932         wfd_oem_asp_service_s *tmp = NULL;
2933
2934         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2935
2936         if (!g_pd || !g_pd->callback) {
2937                 WDP_LOGD("Ignoring event");
2938                 __WDP_LOG_FUNC_EXIT__;
2939                 return;
2940         }
2941
2942         service = (wfd_oem_asp_service_s *) g_try_malloc0(sizeof(wfd_oem_asp_service_s));
2943         if (!service) {
2944                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2945                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2946                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2947                                 error_buf);
2948                 __WDP_LOG_FUNC_EXIT__;
2949                 return;
2950         }
2951         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2952
2953         event.edata = (void*) service;
2954         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_SERVICE;
2955         event.event_id = WFD_OEM_EVENT_ASP_SERV_RESP;
2956
2957         if (parameters != NULL) {
2958                 g_variant_get(parameters, "(a{sv})", &iter);
2959                 if (iter != NULL) {
2960                         dbus_property_foreach(iter, __ws_extract_serviceaspresponse_details, &event);
2961                         g_variant_iter_free(iter);
2962                 }
2963         } else {
2964                 WDP_LOGE("No Properties");
2965         }
2966 GLIST_ITER_START(seek_list, tmp)
2967         if (tmp->tran_id == service->tran_id) {
2968                 WDP_LOGD("srv_trans_id matched [%d] search_id [%llu]"
2969                                 , tmp->tran_id, tmp->search_id);
2970                 service->search_id = tmp->search_id;
2971                 break;
2972         } else {
2973                 tmp = NULL;
2974         }
2975 GLIST_ITER_END()
2976
2977         if (tmp != NULL && tmp->service_info != NULL) {
2978                 if (g_pd->callback->asp_serv_resp_cb)
2979                         g_pd->callback->asp_serv_resp_cb(&event);
2980         } else {
2981                 WDP_LOGD("service info is not required, don't notify to user");
2982         }
2983
2984         g_free(service->service_type);
2985         g_free(service->service_info);
2986         g_free(service);
2987
2988         __WDP_LOG_FUNC_EXIT__;
2989 }
2990
2991 static void _ws_process_persistent_group_added(GDBusConnection *connection,
2992                 const gchar *sender, const gchar *object_path, const gchar *interface,
2993                 const gchar *signal, GVariant *parameters, gpointer user_data)
2994 {
2995         __WDP_LOG_FUNC_ENTER__;
2996         wfd_oem_event_s event;
2997
2998         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2999
3000         if (!g_pd || !g_pd->callback) {
3001                 WDP_LOGD("Ignoring event");
3002                 __WDP_LOG_FUNC_EXIT__;
3003                 return;
3004         }
3005
3006         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3007
3008         __WDP_LOG_FUNC_EXIT__;
3009 }
3010
3011 static void _ws_process_persistent_group_removed(GDBusConnection *connection,
3012                 const gchar *sender, const gchar *object_path, const gchar *interface,
3013                 const gchar *signal, GVariant *parameters, gpointer user_data)
3014 {
3015         __WDP_LOG_FUNC_ENTER__;
3016         wfd_oem_event_s event;
3017
3018         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3019
3020         if (!g_pd || !g_pd->callback) {
3021                 WDP_LOGD("Ignoring event");
3022                 __WDP_LOG_FUNC_EXIT__;
3023                 return;
3024         }
3025
3026         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3027
3028         __WDP_LOG_FUNC_EXIT__;
3029 }
3030
3031 static void _ws_process_wps_failed(GDBusConnection *connection,
3032                 const gchar *sender, const gchar *object_path, const gchar *interface,
3033                 const gchar *signal, GVariant *parameters, gpointer user_data)
3034 {
3035         __WDP_LOG_FUNC_ENTER__;
3036         GVariantIter *iter = NULL;
3037         wfd_oem_event_s event;
3038         const char *name = NULL;
3039
3040         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3041
3042         if (!g_pd || !g_pd->callback) {
3043                 WDP_LOGD("Ignoring event");
3044                 __WDP_LOG_FUNC_EXIT__;
3045                 return;
3046         }
3047
3048         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3049
3050         event.event_id = WFD_OEM_EVENT_WPS_FAIL;
3051         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3052
3053         g_variant_get(parameters, "(&sa{sv})", &name, &iter);
3054
3055         WDP_LOGD("code [%s]", name);
3056
3057         if (iter != NULL) {
3058
3059                 gchar *key = NULL;
3060                 GVariant *value = NULL;
3061
3062                 while (g_variant_iter_loop(iter, "{sv}", &key, &value))
3063                         CHECK_KEY_VALUE(key, value);
3064
3065                 g_variant_iter_free(iter);
3066         }
3067
3068         if (g_pd->callback->wps_fail_cb)
3069                 g_pd->callback->wps_fail_cb(&event);
3070
3071         __WDP_LOG_FUNC_EXIT__;
3072 }
3073
3074 static void _ws_process_group_formation_failure(GDBusConnection *connection,
3075                 const gchar *sender, const gchar *object_path, const gchar *interface,
3076                 const gchar *signal, GVariant *parameters, gpointer user_data)
3077 {
3078         __WDP_LOG_FUNC_ENTER__;
3079         wfd_oem_event_s event;
3080
3081         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3082
3083         if (!g_pd || !g_pd->callback) {
3084                 WDP_LOGD("Ignoring event");
3085                 __WDP_LOG_FUNC_EXIT__;
3086                 return;
3087         }
3088
3089         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3090
3091         event.event_id = WFD_OEM_EVENT_GROUP_FORMATION_FAILURE;
3092         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3093
3094         if (g_pd->callback->group_formation_failure_cb)
3095                 g_pd->callback->group_formation_failure_cb(&event);
3096
3097         __WDP_LOG_FUNC_EXIT__;
3098 }
3099
3100 static void _ws_process_invitation_accepted(GDBusConnection *connection,
3101                 const gchar *sender, const gchar *object_path, const gchar *interface,
3102                 const gchar *signal, GVariant *parameters, gpointer user_data)
3103 {
3104         __WDP_LOG_FUNC_ENTER__;
3105         GVariantIter *iter = NULL;
3106         wfd_oem_event_s event;
3107
3108         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3109
3110         if (!g_pd || !g_pd->callback) {
3111                 WDP_LOGD("Ignoring event");
3112                 __WDP_LOG_FUNC_EXIT__;
3113                 return;
3114         }
3115
3116         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3117
3118         event.event_id = WFD_OEM_EVENT_INVITATION_ACCEPTED;
3119         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3120
3121         if (parameters != NULL) {
3122                 g_variant_get(parameters, "(a{sv})", &iter);
3123
3124                 if (iter != NULL) {
3125                         gchar *key = NULL;
3126                         GVariant *value = NULL;
3127
3128                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
3129                                 CHECK_KEY_VALUE(key, value);
3130
3131                                 if (g_strcmp0(key, "sa") == 0)
3132                                         if (__ws_unpack_ay(event.dev_addr, value, WS_MACADDR_LEN))
3133                                                 WDP_LOGI("[" MACSTR "]", MAC2STR(event.dev_addr));
3134                         }
3135                         g_variant_iter_free(iter);
3136                 }
3137         }
3138
3139         if (g_pd->callback->invitation_accepted_cb)
3140                 g_pd->callback->invitation_accepted_cb(&event);
3141
3142         __WDP_LOG_FUNC_EXIT__;
3143 }
3144
3145 static void _ws_process_asp_provision_start(GDBusConnection *connection,
3146                 const gchar *sender, const gchar *object_path, const gchar *interface,
3147                 const gchar *signal, GVariant *parameters, gpointer user_data)
3148 {
3149         __WDP_LOG_FUNC_ENTER__;
3150         GVariantIter *iter = NULL;
3151         wfd_oem_event_s event;
3152         wfd_oem_asp_prov_s *edata;
3153
3154         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3155
3156         if (!g_pd || !g_pd->callback) {
3157                 WDP_LOGD("Ignoring event");
3158                 __WDP_LOG_FUNC_EXIT__;
3159                 return;
3160         }
3161
3162         edata = (wfd_oem_asp_prov_s *) g_try_malloc0(sizeof(wfd_oem_asp_prov_s));
3163         if (!edata) {
3164                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3165                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3166                 WDP_LOGF("Failed to allocate memory for event. [%s]",
3167                                 error_buf);
3168                 __WDP_LOG_FUNC_EXIT__;
3169                 return;
3170         }
3171         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3172
3173         event.edata = (void*) edata;
3174         event.event_id = WFD_OEM_EVENT_ASP_PROV_START;
3175
3176         if (parameters != NULL) {
3177                 g_variant_get(parameters, "(a{sv})", &iter);
3178                 if (iter != NULL) {
3179                         dbus_property_foreach(iter, __ws_extract_asp_provision_start_details, &event);
3180                         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_PROV;
3181                         g_variant_iter_free(iter);
3182                 }
3183         } else {
3184                 WDP_LOGE("No Properties");
3185         }
3186
3187         if (g_pd->callback->asp_prov_start_cb)
3188                 g_pd->callback->asp_prov_start_cb(&event);
3189
3190         if (event.edata_type == WFD_OEM_EDATA_TYPE_ASP_PROV)
3191                 g_free(edata->session_information);
3192         g_free(edata);
3193
3194         __WDP_LOG_FUNC_EXIT__;
3195 }
3196
3197 static void _ws_process_asp_provision_done(GDBusConnection *connection,
3198                 const gchar *sender, const gchar *object_path, const gchar *interface,
3199                 const gchar *signal, GVariant *parameters, gpointer user_data)
3200 {
3201         __WDP_LOG_FUNC_ENTER__;
3202         GVariantIter *iter = NULL;
3203         wfd_oem_event_s event;
3204         wfd_oem_asp_prov_s *edata;
3205
3206         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3207
3208         if (!g_pd || !g_pd->callback) {
3209                 WDP_LOGD("Ignoring event");
3210                 __WDP_LOG_FUNC_EXIT__;
3211                 return;
3212         }
3213
3214         edata = (wfd_oem_asp_prov_s *) g_try_malloc0(sizeof(wfd_oem_asp_prov_s));
3215         if (!edata) {
3216                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3217                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3218                 WDP_LOGF("Failed to allocate memory for event. [%s]",
3219                                 error_buf);
3220                 __WDP_LOG_FUNC_EXIT__;
3221                 return;
3222         }
3223         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3224
3225         event.edata = (void*) edata;
3226         event.event_id = WFD_OEM_EVENT_ASP_PROV_DONE;
3227
3228         if (parameters != NULL) {
3229                 g_variant_get(parameters, "(a{sv})", &iter);
3230                 if (iter != NULL) {
3231                         dbus_property_foreach(iter, __ws_extract_asp_provision_done_details, &event);
3232                         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_PROV;
3233                         g_variant_iter_free(iter);
3234                 }
3235         } else {
3236                 WDP_LOGE("No Properties");
3237         }
3238
3239         if (g_pd->callback->asp_prov_done_cb)
3240                 g_pd->callback->asp_prov_done_cb(&event);
3241
3242         g_free(edata);
3243
3244         __WDP_LOG_FUNC_EXIT__;
3245 }
3246
3247 static struct {
3248         int sub_id;
3249         const char *interface;
3250         const char *member;
3251         void (*function) (GDBusConnection *connection,
3252                         const gchar *sender, const gchar *object_path, const gchar *interface,
3253                         const gchar *signal, GVariant *parameters, gpointer user_data);
3254 } ws_p2pdevice_signal_map[] = {
3255         {
3256                 0,
3257                 SUPPLICANT_P2PDEVICE,
3258                 "DeviceFoundProperties",
3259                 _ws_process_device_found_properties
3260         },
3261         {
3262                 0,
3263                 SUPPLICANT_P2PDEVICE,
3264                 "DeviceLost",
3265                 _ws_process_device_lost
3266         },
3267         {
3268                 0,
3269                 SUPPLICANT_P2PDEVICE,
3270                 "FindStopped",
3271                 _ws_process_find_stoppped
3272         },
3273         {
3274                 0,
3275                 SUPPLICANT_P2PDEVICE,
3276                 "ProvisionDiscoveryRequestDisplayPin",
3277                 _ws_process_prov_disc_req_display_pin
3278         },
3279         {
3280                 0,
3281                 SUPPLICANT_P2PDEVICE,
3282                 "ProvisionDiscoveryResponseDisplayPin",
3283                 _ws_process_prov_disc_resp_display_pin
3284         },
3285         {
3286                 0,
3287                 SUPPLICANT_P2PDEVICE,
3288                 "ProvisionDiscoveryRequestEnterPin",
3289                 _ws_process_prov_disc_req_enter_pin
3290         },
3291         {
3292                 0,
3293                 SUPPLICANT_P2PDEVICE,
3294                 "ProvisionDiscoveryResponseEnterPin",
3295                 _ws_process_prov_disc_resp_enter_pin
3296         },
3297         {
3298                 0,
3299                 SUPPLICANT_P2PDEVICE,
3300                 "ProvisionDiscoveryPBCRequest",
3301                 _ws_process_prov_disc_pbc_req
3302         },
3303         {
3304                 0,
3305                 SUPPLICANT_P2PDEVICE,
3306                 "ProvisionDiscoveryPBCResponse",
3307                 _ws_process_prov_disc_pbc_resp
3308         },
3309         {
3310                 0,
3311                 SUPPLICANT_P2PDEVICE,
3312                 "ProvisionDiscoveryFailure",
3313                 _ws_process_prov_disc_failure
3314         },
3315         {
3316                 0,
3317                 SUPPLICANT_P2PDEVICE,
3318                 "GroupStarted",
3319                 _ws_process_group_started
3320         },
3321         {
3322                 0,
3323                 SUPPLICANT_P2PDEVICE,
3324                 "GONegotiationSuccess",
3325                 _ws_process_go_neg_success
3326         },
3327         {
3328                 0,
3329                 SUPPLICANT_P2PDEVICE,
3330                 "GONegotiationFailure",
3331                 _ws_process_go_neg_failure
3332         },
3333         {
3334                 0,
3335                 SUPPLICANT_P2PDEVICE,
3336                 "GONegotiationRequest",
3337                 _ws_process_go_neg_request
3338         },
3339         {
3340                 0,
3341                 SUPPLICANT_P2PDEVICE,
3342                 "InvitationReceived",
3343                 _ws_process_invitation_received
3344         },
3345         {
3346                 0,
3347                 SUPPLICANT_P2PDEVICE,
3348                 "InvitationResult",
3349                 _ws_process_invitation_result
3350         },
3351         {
3352                 0,
3353                 SUPPLICANT_P2PDEVICE,
3354                 "GroupFinished",
3355                 _ws_process_group_finished
3356         },
3357         {
3358                 0,
3359                 SUPPLICANT_P2PDEVICE,
3360                 "ServiceDiscoveryResponse",
3361                 _ws_process_service_discovery_response
3362         },
3363         {
3364                 0,
3365                 SUPPLICANT_P2PDEVICE,
3366                 "ServiceASPResponse",
3367                 _ws_process_service_asp_response
3368         },
3369         {
3370                 0,
3371                 SUPPLICANT_P2PDEVICE,
3372                 "ASPProvisionStart",
3373                 _ws_process_asp_provision_start
3374         },
3375         {
3376                 0,
3377                 SUPPLICANT_P2PDEVICE,
3378                 "ASPProvisionDone",
3379                 _ws_process_asp_provision_done
3380         },
3381         {
3382                 0,
3383                 SUPPLICANT_P2PDEVICE,
3384                 "PersistentGroupAdded",
3385                 _ws_process_persistent_group_added
3386         },
3387         {
3388                 0,
3389                 SUPPLICANT_P2PDEVICE,
3390                 "PersistentGroupRemoved",
3391                 _ws_process_persistent_group_removed
3392         },
3393         {
3394                 0,
3395                 SUPPLICANT_P2PDEVICE,
3396                 "WpsFailed",
3397                 _ws_process_wps_failed
3398         },
3399         {
3400                 0,
3401                 SUPPLICANT_P2PDEVICE,
3402                 "GroupFormationFailure",
3403                 _ws_process_group_formation_failure
3404         },
3405         {
3406                 0,
3407                 SUPPLICANT_P2PDEVICE,
3408                 "InvitationAccepted",
3409                 _ws_process_invitation_accepted
3410         },
3411         {
3412                 0,
3413                 NULL,
3414                 NULL,
3415                 NULL
3416         }
3417 };
3418
3419 static void _ws_process_sta_authorized(GDBusConnection *connection,
3420                 const gchar *sender, const gchar *object_path, const gchar *interface,
3421                 const gchar *signal, GVariant *parameters, gpointer user_data)
3422 {
3423         __WDP_LOG_FUNC_ENTER__;
3424         wfd_oem_event_s event;
3425         const gchar* mac_str = NULL;
3426
3427         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3428
3429         if (!g_pd || !g_pd->callback) {
3430                 WDP_LOGD("Ignoring event");
3431                 __WDP_LOG_FUNC_EXIT__;
3432                 return;
3433         }
3434
3435         if (is_peer_joined_notified) {
3436                 is_peer_joined_notified = 0;
3437                 __WDP_LOG_FUNC_EXIT__;
3438                 return;
3439         }
3440
3441         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3442         g_variant_get(parameters, "(&s)", &mac_str);
3443         __ws_txt_to_mac((unsigned char *)mac_str, event.intf_addr);
3444
3445         event.event_id = WFD_OEM_EVENT_STA_CONNECTED;
3446         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3447
3448         if (g_pd->callback->sta_connected_cb)
3449                 g_pd->callback->sta_connected_cb(&event);
3450
3451         __WDP_LOG_FUNC_EXIT__;
3452 }
3453
3454 static void _ws_process_sta_deauthorized(GDBusConnection *connection,
3455                 const gchar *sender, const gchar *object_path, const gchar *interface,
3456                 const gchar *signal, GVariant *parameters, gpointer user_data)
3457 {
3458         __WDP_LOG_FUNC_ENTER__;
3459         wfd_oem_event_s event;
3460         const gchar* mac_str = NULL;
3461
3462         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3463
3464         if (!g_pd || !g_pd->callback) {
3465                 WDP_LOGD("Ignoring event");
3466                 __WDP_LOG_FUNC_EXIT__;
3467                 return;
3468         }
3469
3470         if (is_peer_disconnected_notified) {
3471                 is_peer_disconnected_notified = 0;
3472                 __WDP_LOG_FUNC_EXIT__;
3473                 return;
3474         }
3475
3476         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3477         g_variant_get(parameters, "(&s)", &mac_str);
3478         __ws_txt_to_mac((unsigned char *)mac_str, event.intf_addr);
3479
3480         event.event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
3481         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3482
3483         if (g_pd->callback->sta_disconnected_cb)
3484                 g_pd->callback->sta_disconnected_cb(&event);
3485
3486         __WDP_LOG_FUNC_EXIT__;
3487 }
3488
3489 static struct {
3490         int sub_id;
3491         const char *interface;
3492         const char *member;
3493         void (*function) (GDBusConnection *connection,
3494                         const gchar *sender, const gchar *object_path, const gchar *interface,
3495                         const gchar *signal, GVariant *parameters, gpointer user_data);
3496 } ws_interface_signal_map[] = {
3497         {
3498                 0,
3499                 SUPPLICANT_IFACE,
3500                 "StaAuthorized",
3501                 _ws_process_sta_authorized
3502         },
3503         {
3504                 0,
3505                 SUPPLICANT_IFACE,
3506                 "StaDeauthorized",
3507                 _ws_process_sta_deauthorized
3508         },
3509         {
3510                 0,
3511                 NULL,
3512                 NULL,
3513                 NULL
3514         }
3515 };
3516
3517 static struct {
3518         int sub_id;
3519         const char *interface;
3520         const char *member;
3521         void (*function) (GDBusConnection *connection,
3522                         const gchar *sender, const gchar *object_path, const gchar *interface,
3523                         const gchar *signal, GVariant *parameters, gpointer user_data);
3524 } ws_group_interface_signal_map[] = {
3525         {
3526                 0,
3527                 SUPPLICANT_IFACE,
3528                 "StaAuthorized",
3529                 _ws_process_sta_authorized
3530         },
3531         {
3532                 0,
3533                 SUPPLICANT_IFACE,
3534                 "StaDeauthorized",
3535                 _ws_process_sta_deauthorized
3536         },
3537         {
3538                 0,
3539                 NULL,
3540                 NULL,
3541                 NULL
3542         }
3543 };
3544
3545 static void __register_p2pdevice_signal(GVariant *value, void *user_data)
3546 {
3547         __WDP_LOG_FUNC_ENTER__;
3548         ws_dbus_plugin_data_s * pd_data;
3549         static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
3550         const char *path = NULL;
3551         int i = 0;
3552
3553         if (!g_pd) {
3554                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3555                 __WDP_LOG_FUNC_EXIT__;
3556                 return;
3557         }
3558
3559         pd_data = (ws_dbus_plugin_data_s *)g_pd;
3560
3561         g_variant_get(value, "(&o)", &path);
3562         g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
3563         g_strlcpy(pd_data->iface_path, path, DBUS_OBJECT_PATH_MAX);
3564
3565         WDP_LOGD("interface object path [%s]", interface_path);
3566
3567         /* subscribe Interface iface signal */
3568         for (i = 0; ws_interface_signal_map[i].member != NULL; i++) {
3569                 ws_interface_signal_map[i].sub_id =
3570                         g_dbus_connection_signal_subscribe(pd_data->g_dbus,
3571                                         SUPPLICANT_SERVICE, /* bus name */
3572                                         ws_interface_signal_map[i].interface, /* interface */
3573                                         ws_interface_signal_map[i].member, /* member */
3574                                         pd_data->iface_path, /* object path */
3575                                         NULL, /* arg0 */
3576                                         G_DBUS_SIGNAL_FLAGS_NONE,
3577                                         ws_interface_signal_map[i].function,
3578                                         NULL, NULL);
3579                 WDP_LOGD("Subscribed Interface iface signal [%s]", ws_interface_signal_map[i].member);
3580         }
3581
3582         /* subscribe P2PDevice iface signal */
3583         for (i = 0; ws_p2pdevice_signal_map[i].member != NULL; i++) {
3584                 ws_p2pdevice_signal_map[i].sub_id =
3585                         g_dbus_connection_signal_subscribe(pd_data->g_dbus,
3586                                         SUPPLICANT_SERVICE, /* bus name */
3587                                         ws_p2pdevice_signal_map[i].interface, /* interface */
3588                                         ws_p2pdevice_signal_map[i].member, /* member */
3589                                         pd_data->iface_path, /* object path */
3590                                         NULL, /* arg0 */
3591                                         G_DBUS_SIGNAL_FLAGS_NONE,
3592                                         ws_p2pdevice_signal_map[i].function,
3593                                         NULL, NULL);
3594                 WDP_LOGD("Subscribed P2PDevice iface signal [%s]", ws_p2pdevice_signal_map[i].member);
3595         }
3596
3597         __WDP_LOG_FUNC_EXIT__;
3598 }
3599
3600 static int _ws_create_interface(const char *iface_name, handle_reply function, void *user_data)
3601 {
3602         __WDP_LOG_FUNC_ENTER__;
3603         GDBusConnection *g_dbus = NULL;
3604         GVariantBuilder *builder = NULL;
3605         dbus_method_param_s params;
3606
3607         int res = 0;
3608
3609         if (!g_pd) {
3610                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3611                 __WDP_LOG_FUNC_EXIT__;
3612                 return -1;
3613         }
3614
3615         g_dbus = g_pd->g_dbus;
3616         if (!g_dbus) {
3617                 WDP_LOGE("DBus connection is NULL");
3618                 __WDP_LOG_FUNC_EXIT__;
3619                 return -1;
3620         }
3621         memset(&params, 0x0, sizeof(dbus_method_param_s));
3622
3623         dbus_set_method_param(&params, "CreateInterface", SUPPLICANT_PATH, g_dbus);
3624
3625         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
3626         g_variant_builder_add(builder, "{sv}", "Ifname", g_variant_new_string(iface_name));
3627         g_variant_builder_add(builder, "{sv}", "ConfigFile", g_variant_new_string(CONF_FILE_PATH));
3628         params.params = g_variant_new("(a{sv})", builder);
3629         g_variant_builder_unref(builder);
3630         res = dbus_method_call(&params, SUPPLICANT_INTERFACE, function, user_data);
3631         if (res < 0)
3632                 WDP_LOGE("Failed to send command to wpa_supplicant");
3633         else
3634                 WDP_LOGD("Succeeded to CreateInterface");
3635
3636         __WDP_LOG_FUNC_EXIT__;
3637         return res;
3638 }
3639
3640 static int _ws_get_interface(const char *iface_name, handle_reply function, void *user_data)
3641 {
3642         __WDP_LOG_FUNC_ENTER__;
3643         GDBusConnection *g_dbus = NULL;
3644         dbus_method_param_s params;
3645         int res = 0;
3646
3647         if (!g_pd) {
3648                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3649                 __WDP_LOG_FUNC_EXIT__;
3650                 return -1;
3651         }
3652
3653         g_dbus = g_pd->g_dbus;
3654         if (!g_dbus) {
3655                 WDP_LOGE("DBus connection is NULL");
3656                 __WDP_LOG_FUNC_EXIT__;
3657                 return -1;
3658         }
3659
3660         dbus_set_method_param(&params, SUPPLICANT_METHOD_GETINTERFACE,
3661                         SUPPLICANT_PATH, g_pd->g_dbus);
3662
3663         params.params = g_variant_new("(s)", iface_name);
3664         DEBUG_G_VARIANT("Params : ", params.params);
3665
3666         res = dbus_method_call(&params, SUPPLICANT_INTERFACE,
3667                         function, user_data);
3668
3669         if (res < 0)
3670                 WDP_LOGE("Failed to send command to wpa_supplicant");
3671         else
3672                 WDP_LOGD("Succeeded to get interface");
3673
3674         __WDP_LOG_FUNC_EXIT__;
3675         return res;
3676 }
3677
3678 static void __ws_remove_interface(GVariant *value, void *user_data)
3679 {
3680         __WDP_LOG_FUNC_ENTER__;
3681         GDBusConnection *g_dbus = NULL;
3682         dbus_method_param_s params;
3683         const char *path = NULL;
3684         static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
3685         int res = 0;
3686
3687         if (!g_pd) {
3688                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3689                 return;
3690         }
3691
3692         g_dbus = g_pd->g_dbus;
3693         if (!g_dbus) {
3694                 WDP_LOGE("DBus connection is NULL");
3695                 return;
3696         }
3697
3698         g_variant_get(value, "(&o)", &path);
3699         g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
3700         WDP_LOGD("interface object path [%s]", interface_path);
3701
3702         memset(&params, 0x0, sizeof(dbus_method_param_s));
3703
3704         dbus_set_method_param(&params, "RemoveInterface", SUPPLICANT_PATH, g_dbus);
3705         params.params = g_variant_new("(o)", interface_path);
3706
3707         res = dbus_method_call(&params, SUPPLICANT_INTERFACE, NULL, NULL);
3708         if (res < 0)
3709                 WDP_LOGE("Failed to send command to wpa_supplicant");
3710         else
3711                 WDP_LOGD("Succeeded to RemoveInterface");
3712
3713         __WDP_LOG_FUNC_EXIT__;
3714         return;
3715 }
3716
3717 static int _ws_init_dbus_connection(void)
3718 {
3719         __WDP_LOG_FUNC_ENTER__;
3720         GDBusConnection *conn = NULL;
3721         GError *error = NULL;
3722         int res = 0;
3723         int i = 0;
3724
3725         if (!g_pd) {
3726                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3727                 __WDP_LOG_FUNC_EXIT__;
3728                 return -1;
3729         }
3730
3731         if (!config) {
3732                 WDP_LOGE("no configurable data found");
3733                 __WDP_LOG_FUNC_EXIT__;
3734                 return -1;
3735         }
3736
3737         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
3738
3739         if (conn == NULL) {
3740                 if (error != NULL) {
3741                         WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
3742                                         error->message);
3743                         g_error_free(error);
3744                 }
3745                 __WDP_LOG_FUNC_EXIT__;
3746                 return -1;
3747         }
3748
3749         g_pd->g_dbus = conn;
3750
3751         for (i = 0; ws_supplicant_signal_map[i].member != NULL; i++) {
3752                 ws_supplicant_signal_map[i].sub_id =
3753                         g_dbus_connection_signal_subscribe(g_pd->g_dbus,
3754                                         SUPPLICANT_SERVICE, /* bus name */
3755                                         ws_supplicant_signal_map[i].interface, /* interface */
3756                                         ws_supplicant_signal_map[i].member, /* member */
3757                                         SUPPLICANT_PATH, /* object path */
3758                                         NULL, /* arg0 */
3759                                         G_DBUS_SIGNAL_FLAGS_NONE,
3760                                         ws_supplicant_signal_map[i].function,
3761                                         NULL, NULL);
3762                 WDP_LOGD("Subscribed supplicant iface signal [%s]", ws_supplicant_signal_map[i].member);
3763         }
3764
3765         if (g_strcmp0(config->ifname, config->p2p_ifname) != 0) {
3766                 if (_ws_get_interface(config->ifname, NULL, NULL) < 0)
3767                         res = _ws_create_interface(config->ifname, NULL, NULL);
3768                 if (_ws_get_interface(config->p2p_ifname, __register_p2pdevice_signal, NULL) < 0)
3769                         res = _ws_create_interface(config->p2p_ifname, __register_p2pdevice_signal, NULL);
3770         } else {
3771                 if (_ws_get_interface(config->p2p_ifname, __register_p2pdevice_signal, NULL) < 0)
3772                         res = _ws_create_interface(config->p2p_ifname, __register_p2pdevice_signal, NULL);
3773         }
3774
3775         if (res < 0)
3776                 WDP_LOGE("Failed to subscribe interface signal");
3777         else
3778                 WDP_LOGI("Successfully register signal filters");
3779
3780         __WDP_LOG_FUNC_EXIT__;
3781         return res;
3782 }
3783
3784 static int _ws_deinit_dbus_connection(void)
3785 {
3786         GDBusConnection *g_dbus = NULL;
3787         int i = 0;
3788
3789         if (!g_pd) {
3790                 WDP_LOGE("Invalid parameter");
3791                 __WDP_LOG_FUNC_EXIT__;
3792                 return -1;
3793         }
3794
3795         g_dbus = g_pd->g_dbus;
3796         if (!g_dbus) {
3797                 WDP_LOGE("DBus connection is NULL");
3798                 __WDP_LOG_FUNC_EXIT__;
3799                 return -1;
3800         }
3801
3802         for (i = 0; ws_supplicant_signal_map[i].member != NULL; i++) {
3803                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_supplicant_signal_map[i].sub_id);
3804                 ws_supplicant_signal_map[i].sub_id = 0;
3805         }
3806
3807         for (i = 0; ws_interface_signal_map[i].member != NULL; i++) {
3808                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_interface_signal_map[i].sub_id);
3809                 ws_interface_signal_map[i].sub_id = 0;
3810         }
3811
3812         for (i = 0; ws_p2pdevice_signal_map[i].member != NULL; i++) {
3813                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_p2pdevice_signal_map[i].sub_id);
3814                 ws_p2pdevice_signal_map[i].sub_id = 0;
3815         }
3816
3817         for (i = 0; ws_group_signal_map[i].member != NULL; i++) {
3818                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_group_signal_map[i].sub_id);
3819                 ws_group_signal_map[i].sub_id = 0;
3820         }
3821
3822         memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
3823         memset(g_pd->iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
3824
3825         g_object_unref(g_dbus);
3826         __WDP_LOG_FUNC_EXIT__;
3827         return 0;
3828 }
3829
3830 static void _ws_manage_group_iface_signal(const gchar *group_iface_obj_path,
3831                 gboolean is_created)
3832 {
3833         __WDP_LOG_FUNC_ENTER__;
3834         GDBusConnection *connection;
3835
3836         if (!g_pd) {
3837                 WDP_LOGD("Ignore");
3838                 __WDP_LOG_FUNC_EXIT__;
3839                 return;
3840         }
3841
3842         if (!g_strcmp0(g_pd->iface_path, group_iface_obj_path)) {
3843                 WDP_LOGD("group iface is p2p iface, ignore");
3844                 __WDP_LOG_FUNC_EXIT__;
3845                 return;
3846         }
3847
3848         connection = g_pd->g_dbus;
3849         int i;
3850         if (is_created) {
3851                 /* subscribe Interface iface signal */
3852                 for (i = 0; ws_group_interface_signal_map[i].member != NULL; i++) {
3853                         ws_group_interface_signal_map[i].sub_id =
3854                                 g_dbus_connection_signal_subscribe(connection,
3855                                                 SUPPLICANT_SERVICE, /* bus name */
3856                                                 ws_group_interface_signal_map[i].interface, /* interface */
3857                                                 ws_group_interface_signal_map[i].member, /* member */
3858                                                 group_iface_obj_path, /* object path */
3859                                                 NULL, /* arg0 */
3860                                                 G_DBUS_SIGNAL_FLAGS_NONE,
3861                                                 ws_group_interface_signal_map[i].function,
3862                                                 NULL, NULL);
3863                         WDP_LOGD("Subscribed Interface iface signal [%s]", ws_group_interface_signal_map[i].member);
3864                 }
3865
3866         } else {
3867                 for (i = 0; ws_group_interface_signal_map[i].member != NULL; i++) {
3868                         g_dbus_connection_signal_unsubscribe(connection, ws_group_interface_signal_map[i].sub_id);
3869                         ws_group_interface_signal_map[i].sub_id = 0;
3870                 }
3871         }
3872         __WDP_LOG_FUNC_EXIT__;
3873         return;
3874 }
3875
3876 int wfd_plugin_load(wfd_oem_ops_s **ops)
3877 {
3878         __WDP_LOG_FUNC_ENTER__;
3879         if (!ops) {
3880                 WDP_LOGE("Invalid parameter");
3881                 __WDP_LOG_FUNC_EXIT__;
3882                 return -1;
3883         }
3884
3885         *ops = &supplicant_ops;
3886
3887         __WDP_LOG_FUNC_EXIT__;
3888         return 0;
3889 }
3890
3891 static int _ws_reset_plugin(ws_dbus_plugin_data_s *f_pd)
3892 {
3893         __WDP_LOG_FUNC_ENTER__;
3894
3895         if (!f_pd) {
3896                 WDP_LOGE("Invalid parameter");
3897                 __WDP_LOG_FUNC_EXIT__;
3898                 return -1;
3899         }
3900
3901         _ws_deinit_dbus_connection();
3902
3903         if (f_pd->activated)
3904                 ws_deactivate(f_pd->concurrent);
3905
3906         g_free(f_pd);
3907
3908         __WDP_LOG_FUNC_EXIT__;
3909         return 0;
3910 }
3911
3912 static int __ws_check_net_interface(char* if_name)
3913 {
3914         struct ifreq ifr;
3915         int fd;
3916
3917         if (if_name == NULL) {
3918                 WDP_LOGE("Invalid param");
3919                 return -1;
3920         }
3921
3922         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3923         if (fd < 0) {
3924                 WDP_LOGE("socket create error: %d", fd);
3925                 return -2;
3926         }
3927
3928         memset(&ifr, 0, sizeof(ifr));
3929         g_strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
3930
3931         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
3932                 close(fd);
3933                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3934                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3935                 WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s [ %s ]", error_buf, if_name); /* interface is not found. */
3936                 return -3;
3937         }
3938
3939         close(fd);
3940
3941         if (ifr.ifr_flags & IFF_UP) {
3942                 WDP_LOGD("%s interface is up", if_name);
3943                 return 1;
3944         } else if (!(ifr.ifr_flags & IFF_UP)) {
3945                 WDP_LOGD("%s interface is down", if_name);
3946                 return 0;
3947         }
3948         return 0;
3949 }
3950
3951 int ws_configure(wfd_oem_config_s *conf)
3952 {
3953         __WDP_LOG_FUNC_ENTER__;
3954
3955         if (conf == NULL) {
3956                 __WDP_LOG_FUNC_EXIT__;
3957                 return -1;
3958         }
3959
3960         if (config)
3961                 g_free(config);
3962
3963         config = (wfd_oem_config_s *) g_try_malloc0(sizeof(wfd_oem_config_s));
3964         if (!config) {
3965                 __WDP_LOG_FUNC_EXIT__;
3966                 return -1;
3967         }
3968
3969         memcpy(config, conf, sizeof(wfd_oem_config_s));
3970
3971         __WDP_LOG_FUNC_EXIT__;
3972         return 0;
3973 }
3974
3975 int ws_init(wfd_oem_event_cbs_s *event_cbs)
3976 {
3977         __WDP_LOG_FUNC_ENTER__;
3978
3979         if (event_cbs == NULL) {
3980                 __WDP_LOG_FUNC_EXIT__;
3981                 return -1;
3982         }
3983
3984         if (g_pd)
3985                 _ws_reset_plugin(g_pd);
3986
3987         errno = 0;
3988         g_pd = (ws_dbus_plugin_data_s*) g_try_malloc0(sizeof(ws_dbus_plugin_data_s));
3989         if (!g_pd) {
3990                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3991                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3992                 WDP_LOGE("Failed to allocate memory for plugin data. [%s]", error_buf);
3993                 return -1;
3994         }
3995
3996         g_pd->callback = event_cbs;
3997         g_pd->initialized = TRUE;
3998
3999         __WDP_LOG_FUNC_EXIT__;
4000         return 0;
4001 }
4002
4003 int ws_deinit(void)
4004 {
4005         __WDP_LOG_FUNC_ENTER__;
4006
4007         if (g_pd) {
4008                 _ws_reset_plugin(g_pd);
4009                 g_pd = NULL;
4010         }
4011
4012         if (config)
4013                 g_free(config);
4014
4015         __WDP_LOG_FUNC_EXIT__;
4016         return 0;
4017 }
4018
4019 gboolean _ws_util_execute_file(const char *file_path,
4020         char *const args[], char *const envs[])
4021 {
4022         pid_t pid = 0;
4023         int rv = 0;
4024         errno = 0;
4025         register unsigned int index = 0;
4026         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
4027
4028         while (args[index] != NULL) {
4029                 WDP_LOGD("[%s]", args[index]);
4030                 index++;
4031         }
4032
4033         if (!(pid = fork())) {
4034                 WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
4035                 WDP_LOGD("Inside child, exec (%s) command", file_path);
4036
4037                 errno = 0;
4038                 if (execve(file_path, args, envs) == -1) {
4039                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4040                         WDP_LOGE("Fail to execute command (%s)", error_buf);
4041                         exit(1);
4042                 }
4043         } else if (pid > 0) {
4044                 if (waitpid(pid, &rv, 0) == -1)
4045                         WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
4046                 if (WIFEXITED(rv))
4047                         WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
4048                 else if (WIFSIGNALED(rv))
4049                         WDP_LOGD("killed by signal %d", WTERMSIG(rv));
4050                 else if (WIFSTOPPED(rv))
4051                         WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
4052                 else if (WIFCONTINUED(rv))
4053                         WDP_LOGD("continued");
4054
4055                 return TRUE;
4056         }
4057
4058         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4059         WDP_LOGE("failed to fork (%s)", error_buf);
4060         return FALSE;
4061 }
4062
4063 static int __ws_p2p_firmware_start(const char *interface_name)
4064 {
4065         int rv = 0;
4066
4067         rv = hal_wifi_get_backend();
4068         if (rv < 0) {
4069                 WDP_LOGD("hal_wifi_get_backend() failed, ret: %d", rv);
4070                 return -1;
4071         }
4072
4073         rv = hal_wifi_p2p_start(interface_name);
4074         if (rv < 0) {
4075                 WDP_LOGD("hal_wifi_p2p_start() failed, ret: %d", rv);
4076                 return -1;
4077         }
4078
4079         WDP_LOGI("Successfully loaded p2p device driver");
4080         return 0;
4081 }
4082
4083 static int __ws_p2p_firmware_stop(const char *interface_name)
4084 {
4085         int rv = 0;
4086
4087         rv = hal_wifi_get_backend();
4088         if (rv < 0) {
4089                 WDP_LOGD("hal_wifi_get_backend() failed, ret: %d", rv);
4090                 return -1;
4091         }
4092
4093         rv = hal_wifi_stop(interface_name);
4094         if (rv < 0) {
4095                 WDP_LOGD("hal_wifi_stop() failed, ret: %d", rv);
4096                 return -1;
4097         }
4098
4099         WDP_LOGI("Successfully removed p2p device driver");
4100         return 0;
4101 }
4102
4103 static int __ws_p2p_supplicant_start(void)
4104 {
4105         gboolean rv = FALSE;
4106         const char *path = "/usr/sbin/p2p_supp.sh";
4107         char *const args[] = { "/usr/sbin/p2p_supp.sh", "start_dbus", NULL };
4108         char *const envs[] = { NULL };
4109
4110         rv = _ws_util_execute_file(path, args, envs);
4111
4112         if (rv != TRUE) {
4113                 WDP_LOGE("Failed to start p2p_supp.sh");
4114                 return -1;
4115         }
4116
4117         WDP_LOGI("Successfully started p2p_supp.sh");
4118         return 0;
4119 }
4120
4121
4122 static int __ws_p2p_supplicant_stop(void)
4123 {
4124         gboolean rv = FALSE;
4125         const char *path = "/usr/sbin/p2p_supp.sh";
4126         char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
4127         char *const envs[] = { NULL };
4128
4129         rv = _ws_util_execute_file(path, args, envs);
4130
4131         if (rv != TRUE) {
4132                 WDP_LOGE("Failed to stop p2p_supp.sh");
4133                 return -1;
4134         }
4135
4136         WDP_LOGI("Successfully stopped p2p_supp.sh");
4137         return 0;
4138 }
4139 #if 0
4140 static int __ws_p2p_on(void)
4141 {
4142         DBusError error;
4143         DBusMessage *reply = NULL;
4144         DBusMessage *message = NULL;
4145         DBusConnection *connection = NULL;
4146
4147         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
4148         if (connection == NULL) {
4149                 WDP_LOGE("Failed to get system bus");
4150                 return -EIO;
4151         }
4152
4153         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
4154                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
4155         if (message == NULL) {
4156                 WDP_LOGE("Failed DBus method call");
4157                 dbus_connection_unref(connection);
4158                 return -EIO;
4159         }
4160
4161         dbus_error_init(&error);
4162
4163         reply = dbus_connection_send_with_reply_and_block(connection, message,
4164                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
4165         if (dbus_error_is_set(&error) == TRUE) {
4166                 if (NULL != strstr(error.message, ".AlreadyExists")) {
4167                         /* p2p already enabled */
4168                 } else {
4169                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
4170                                         "DBus error [%s: %s]", error.name, error.message);
4171
4172                         dbus_error_free(&error);
4173                 }
4174
4175                 dbus_error_free(&error);
4176         }
4177
4178         if (reply != NULL)
4179                 dbus_message_unref(reply);
4180
4181         dbus_message_unref(message);
4182         dbus_connection_unref(connection);
4183
4184         return 0;
4185 }
4186
4187 static int __ws_p2p_off(void)
4188 {
4189         DBusError error;
4190         DBusMessage *reply = NULL;
4191         DBusMessage *message = NULL;
4192         DBusConnection *connection = NULL;
4193
4194         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
4195         if (connection == NULL) {
4196                 WDP_LOGE("Failed to get system bus");
4197                 return -EIO;
4198         }
4199
4200         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
4201                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
4202         if (message == NULL) {
4203                 WDP_LOGE("Failed DBus method call");
4204                 dbus_connection_unref(connection);
4205                 return -EIO;
4206         }
4207
4208         dbus_error_init(&error);
4209
4210         reply = dbus_connection_send_with_reply_and_block(connection, message,
4211                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
4212         if (dbus_error_is_set(&error) == TRUE) {
4213                 if (NULL != strstr(error.message, ".AlreadyExists")) {
4214                         /*  p2p already disabled */
4215                 } else {
4216                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
4217                                         "DBus error [%s: %s]", error.name, error.message);
4218
4219                         dbus_error_free(&error);
4220                 }
4221
4222                 dbus_error_free(&error);
4223         }
4224
4225         if (reply != NULL)
4226                 dbus_message_unref(reply);
4227
4228         dbus_message_unref(message);
4229         dbus_connection_unref(connection);
4230
4231         return 0;
4232 }
4233 #endif
4234
4235 int __ws_init_p2pdevice(void)
4236 {
4237         __WDP_LOG_FUNC_ENTER__;
4238         GDBusConnection *g_dbus = NULL;
4239
4240         GVariant *value = NULL;
4241         GVariant *param = NULL;
4242         GVariantBuilder *builder = NULL;
4243         GVariantBuilder *type_builder = NULL;
4244         dbus_method_param_s params;
4245
4246         unsigned char primary_device_type[8] = {
4247                 0x00, 0x00, 0x00, 0x50,
4248                 0xf2, 0x04, 0x00, 0x00
4249         };
4250
4251         int i = 0;
4252         int res = 0;
4253
4254         if (!g_pd) {
4255                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4256                 __WDP_LOG_FUNC_EXIT__;
4257                 return -1;
4258         }
4259
4260         if (!config) {
4261                 WDP_LOGE("no configurable data found");
4262                 __WDP_LOG_FUNC_EXIT__;
4263                 return -1;
4264         }
4265
4266         primary_device_type[1] = config->pri_dev_type;
4267         primary_device_type[7] = config->sec_dev_type;
4268
4269         for (i = 0; i < WS_DEVTYPE_LEN; i++)
4270                 WDP_LOGD("device type[%02x]", primary_device_type[i]);
4271
4272         g_dbus = g_pd->g_dbus;
4273         if (!g_dbus) {
4274                 WDP_LOGE("DBus connection is NULL");
4275                 __WDP_LOG_FUNC_EXIT__;
4276                 return -1;
4277         }
4278         memset(&params, 0x0, sizeof(dbus_method_param_s));
4279
4280         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
4281                          g_dbus);
4282
4283         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4284         g_variant_builder_add(builder, "{sv}", "DeviceName",
4285                                         g_variant_new_string(config->device_name));
4286
4287         g_variant_builder_add(builder, "{sv}", "GOIntent",
4288                                         g_variant_new_uint32(config->go_intent));
4289
4290         g_variant_builder_add(builder, "{sv}", "PersistentReconnect",
4291                                         g_variant_new_boolean(config->persistent_reconnect));
4292
4293         g_variant_builder_add(builder, "{sv}", "ListenRegClass",
4294                                         g_variant_new_uint32(config->listen_reg_class));
4295
4296         g_variant_builder_add(builder, "{sv}", "ListenChannel",
4297                                         g_variant_new_uint32(config->listen_channel));
4298
4299         g_variant_builder_add(builder, "{sv}", "OperRegClass",
4300                                         g_variant_new_uint32(config->operating_reg_class));
4301
4302         g_variant_builder_add(builder, "{sv}", "OperChannel",
4303                                         g_variant_new_uint32(config->operating_channel));
4304
4305         g_variant_builder_add(builder, "{sv}", "SsidPostfix",
4306                                         g_variant_new_string(config->device_name));
4307
4308         g_variant_builder_add(builder, "{sv}", "NoGroupIface",
4309                                         g_variant_new_boolean(config->no_group_iface));
4310
4311         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
4312         for (i = 0; i < WS_DEVTYPE_LEN; i++)
4313                 g_variant_builder_add(type_builder, "y", primary_device_type[i]);
4314         g_variant_builder_add(builder, "{sv}", "PrimaryDeviceType",
4315                         g_variant_new("ay", type_builder));
4316         g_variant_builder_unref(type_builder);
4317         value = g_variant_new("a{sv}", builder);
4318         g_variant_builder_unref(builder);
4319
4320         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
4321
4322         params.params = param;
4323         DEBUG_G_VARIANT("Params : ", params.params);
4324
4325         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4326         if (res < 0)
4327                 WDP_LOGE("Failed to send command to wpa_supplicant");
4328         else
4329                 WDP_LOGD("Succeeded to initialize p2pdevice");
4330         __WDP_LOG_FUNC_EXIT__;
4331         return res;
4332 }
4333
4334 int __ws_set_config_methods(void)
4335 {
4336         __WDP_LOG_FUNC_ENTER__;
4337         GDBusConnection *g_dbus = NULL;
4338
4339         GVariant *value = NULL;
4340         GVariant *param = NULL;
4341
4342         dbus_method_param_s params;
4343         int res = 0;
4344
4345         if (!g_pd) {
4346                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4347                 __WDP_LOG_FUNC_EXIT__;
4348                 return -1;
4349         }
4350
4351         if (!config) {
4352                 WDP_LOGE("no configurable data found");
4353                 __WDP_LOG_FUNC_EXIT__;
4354                 return -1;
4355         }
4356
4357         g_dbus = g_pd->g_dbus;
4358         if (!g_dbus) {
4359                 WDP_LOGE("DBus connection is NULL");
4360                 __WDP_LOG_FUNC_EXIT__;
4361                 return -1;
4362         }
4363         memset(&params, 0x0, sizeof(dbus_method_param_s));
4364
4365         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
4366                          g_dbus);
4367
4368         value = g_variant_new_string(config->config_methods);
4369
4370         param = g_variant_new("(ssv)", SUPPLICANT_WPS, "ConfigMethods", value);
4371         params.params = param;
4372
4373         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4374         if (res < 0)
4375                 WDP_LOGE("Failed to send command to wpa_supplicant");
4376         else
4377                 WDP_LOGD("Succeeded to set config method(%s)", config->config_methods);
4378
4379         __WDP_LOG_FUNC_EXIT__;
4380         return res;
4381 }
4382
4383 int ws_activate(int concurrent)
4384 {
4385         __WDP_LOG_FUNC_ENTER__;
4386         int res = 0;
4387         int retry_count = 0;
4388
4389         if (!g_pd) {
4390                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4391                 __WDP_LOG_FUNC_EXIT__;
4392                 return -1;
4393         }
4394
4395         if (!config) {
4396                 WDP_LOGE("no configurable data found");
4397                 __WDP_LOG_FUNC_EXIT__;
4398                 return -1;
4399         }
4400
4401         res = __ws_p2p_supplicant_start();
4402         if (res < 0) {
4403                 res = __ws_p2p_supplicant_stop();
4404                 WDP_LOGI("P2P supplicant stopped with error %d", res);
4405                 __WDP_LOG_FUNC_EXIT__;
4406                 return -1;
4407         }
4408
4409         while (retry_count < WS_CONN_RETRY_COUNT) {
4410                 /* load wlan driver */
4411                 if (concurrent == 0)
4412                         res = __ws_p2p_firmware_start(config->ifname);
4413                 if (res < 0) {
4414                         WDP_LOGE("Failed to load driver [ret=%d]", res);
4415                         return -1;
4416                 }
4417                 WDP_LOGI("P2P firmware started with error %d", res);
4418
4419                 if (__ws_check_net_interface(config->ifname) < 0) {
4420                         usleep(150000); /* wait for 150ms */
4421                         concurrent = 0;
4422                         retry_count++;
4423                         WDP_LOGE("interface is not up: retry, %d", retry_count);
4424                 } else {
4425                         break;
4426                 }
4427         }
4428
4429         if (retry_count >= WS_CONN_RETRY_COUNT) {
4430                 WDP_LOGE("Driver loading is failed [%d]", res);
4431                 __WDP_LOG_FUNC_EXIT__;
4432                 return -1;
4433         }
4434         if (retry_count > 0) {
4435                 /* Give driver marginal time to config net */
4436                 WDP_LOGE("Driver loading is done. Wait marginal time for driver");
4437                 sleep(1); /* 1s */
4438         }
4439
4440         g_pd->concurrent = concurrent;
4441
4442         res = _ws_init_dbus_connection();
4443         if (res < 0) {
4444                 res = __ws_p2p_supplicant_stop();
4445                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
4446                 res = __ws_p2p_firmware_stop(config->ifname);
4447                 WDP_LOGI("P2P firmware stopped with error %d", res);
4448                 __WDP_LOG_FUNC_EXIT__;
4449                 return -1;
4450         }
4451
4452         g_pd->activated = TRUE;
4453         __ws_init_p2pdevice();
4454         __ws_set_config_methods();
4455         seek_list = NULL;
4456
4457         __WDP_LOG_FUNC_EXIT__;
4458         return 0;
4459 }
4460
4461 int ws_deactivate(int concurrent)
4462 {
4463         __WDP_LOG_FUNC_ENTER__;
4464         wfd_oem_asp_service_s *data = NULL;
4465         int res = -1;
4466
4467         if (!g_pd) {
4468                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4469                 __WDP_LOG_FUNC_EXIT__;
4470                 return res;
4471         }
4472
4473         if (!config) {
4474                 WDP_LOGE("no configurable data found");
4475                 __WDP_LOG_FUNC_EXIT__;
4476                 return res;
4477         }
4478
4479         if (!g_pd->activated) {
4480                 WDP_LOGE("Wi-Fi Direct is not activated");
4481                 __WDP_LOG_FUNC_EXIT__;
4482                 return res;
4483         }
4484
4485         ws_stop_scan();
4486
4487         g_pd->concurrent = concurrent;
4488
4489         if (g_strcmp0(config->ifname, config->group_ifname) != 0)
4490                 _ws_get_interface(config->group_ifname, __ws_remove_interface, NULL);
4491         if (concurrent == 0)
4492                 _ws_get_interface(config->ifname, __ws_remove_interface, NULL);
4493
4494         _ws_deinit_dbus_connection();
4495
4496         if (concurrent == 0) {
4497                 res = __ws_p2p_supplicant_stop();
4498                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
4499                 res = __ws_p2p_firmware_stop(config->ifname);
4500                 WDP_LOGI("P2P firmware stopped with error %d", res);
4501         }
4502         g_pd->activated = FALSE;
4503
4504         GLIST_ITER_START(seek_list, data)
4505
4506         if (data) {
4507                 temp = g_list_next(seek_list);
4508                 seek_list = g_list_remove(seek_list, data);
4509                 g_free(data->service_type);
4510                 g_free(data->service_info);
4511                 g_free(data);
4512         }
4513
4514         GLIST_ITER_END()
4515         __WDP_LOG_FUNC_EXIT__;
4516         return 0;
4517 }
4518
4519 #if 0
4520 static gboolean _retry_start_scan(gpointer data)
4521 {
4522         __WDP_LOG_FUNC_ENTER__;
4523
4524         WDP_LOGD("Succeeded to start scan");
4525
4526         __WDP_LOG_FUNC_EXIT__;
4527         return 0;
4528 }
4529 #endif
4530
4531 static void __ws_add_seek_params(GVariantBuilder *builder)
4532 {
4533         GVariantBuilder *outter = NULL;
4534         GVariantBuilder *inner = NULL;
4535         wfd_oem_asp_service_s *data = NULL;
4536         int len = 0;
4537         int i = 0;
4538
4539         if (seek_list == NULL || g_list_length(seek_list) == 0) {
4540                 WDP_LOGD("seek list is NULL");
4541                 return;
4542         }
4543         WDP_LOGD("seek list length [%d]", g_list_length(seek_list));
4544
4545         outter = g_variant_builder_new(G_VARIANT_TYPE("aay"));
4546
4547 GLIST_ITER_START(seek_list, data)
4548         if (data && data->service_type) {
4549                 len = strlen(data->service_type) + 1;
4550                 WDP_LOGD("data [%s] len [%d]", data->service_type, len);
4551                 inner = g_variant_builder_new(G_VARIANT_TYPE("ay"));
4552                 for (i = 0; i < len; i++)
4553                         g_variant_builder_add(inner, "y", data->service_type[i]);
4554                 g_variant_builder_add(outter, "ay", inner);
4555                 g_variant_builder_unref(inner);
4556         }
4557 GLIST_ITER_END()
4558         g_variant_builder_add(builder, "{sv}", "Seek", g_variant_new("aay", outter));
4559         g_variant_builder_unref(outter);
4560
4561         return;
4562 }
4563
4564 int ws_start_scan(wfd_oem_scan_param_s *param)
4565 {
4566         __WDP_LOG_FUNC_ENTER__;
4567         GDBusConnection *g_dbus = NULL;
4568         GVariantBuilder *builder = NULL;
4569         GVariant *value = NULL;
4570         dbus_method_param_s params;
4571         int res = 0;
4572
4573         if (!param) {
4574                 WDP_LOGE("Invalid parameter");
4575                 __WDP_LOG_FUNC_EXIT__;
4576                 return -1;
4577         }
4578
4579         if (!g_pd) {
4580                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4581                 __WDP_LOG_FUNC_EXIT__;
4582                 return -1;
4583         }
4584
4585         g_dbus = g_pd->g_dbus;
4586         if (!g_dbus) {
4587                 WDP_LOGE("DBus connection is NULL");
4588                 __WDP_LOG_FUNC_EXIT__;
4589                 return -1;
4590         }
4591         memset(&params, 0x0, sizeof(dbus_method_param_s));
4592
4593         if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE) {
4594
4595                 dbus_set_method_param(&params, "Find",  g_pd->iface_path, g_dbus);
4596
4597                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4598
4599                         if (param->scan_time)
4600                                 g_variant_builder_add(builder, "{sv}", "Timeout",
4601                                                         g_variant_new_int32(param->scan_time));
4602                         if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
4603                                 g_variant_builder_add(builder, "{sv}", "DiscoveryType",
4604                                                         g_variant_new_string("social"));
4605                         if (seek_list != NULL)
4606                                 __ws_add_seek_params(builder);
4607
4608                         value = g_variant_new("(a{sv})", builder);
4609                         g_variant_builder_unref(builder);
4610         } else {
4611
4612                 dbus_set_method_param(&params, "Listen", g_pd->iface_path, g_dbus);
4613                 value = g_variant_new("(i)", param->scan_time);
4614         }
4615
4616         params.params = value;
4617         DEBUG_G_VARIANT("Params : ", params.params);
4618
4619         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4620         if (res < 0)
4621                 WDP_LOGE("Failed to send command to wpa_supplicant");
4622         else
4623                 WDP_LOGD("Succeeded to start scan");
4624
4625         __WDP_LOG_FUNC_EXIT__;
4626         return res;
4627 }
4628
4629 int ws_restart_scan(int freq)
4630 {
4631         __WDP_LOG_FUNC_ENTER__;
4632         GDBusConnection *g_dbus = NULL;
4633         GVariantBuilder *builder = NULL;
4634         GVariant *value = NULL;
4635         dbus_method_param_s params;
4636         int res = 0;
4637
4638         if (!g_pd) {
4639                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4640                 __WDP_LOG_FUNC_EXIT__;
4641                 return -1;
4642         }
4643
4644         g_dbus = g_pd->g_dbus;
4645         if (!g_dbus) {
4646                 WDP_LOGE("DBus connection is NULL");
4647                 __WDP_LOG_FUNC_EXIT__;
4648                 return -1;
4649         }
4650         memset(&params, 0x0, sizeof(dbus_method_param_s));
4651
4652         dbus_set_method_param(&params, "Find", g_pd->iface_path, g_dbus);
4653
4654         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4655         g_variant_builder_add(builder, "{sv}", "Timeout", g_variant_new_int32(2));
4656         g_variant_builder_add(builder, "{sv}", "DiscoveryType",
4657                                 g_variant_new_string("social"));
4658         value = g_variant_new("(a{sv})", builder);
4659         g_variant_builder_unref(builder);
4660
4661         params.params = value;
4662         DEBUG_G_VARIANT("Params : ", params.params);
4663
4664         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4665         if (res < 0)
4666                 WDP_LOGE("Failed to send command to wpa_supplicant");
4667         else
4668                 WDP_LOGD("Succeeded to start scan");
4669
4670         __WDP_LOG_FUNC_EXIT__;
4671         return res;
4672 }
4673
4674 int ws_stop_scan(void)
4675 {
4676         __WDP_LOG_FUNC_ENTER__;
4677         GDBusConnection *g_dbus = NULL;
4678         dbus_method_param_s params;
4679         int res = 0;
4680
4681         if (!g_pd) {
4682                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4683                 __WDP_LOG_FUNC_EXIT__;
4684                 return -1;
4685         }
4686
4687         g_dbus = g_pd->g_dbus;
4688         if (!g_dbus) {
4689                 WDP_LOGE("DBus connection is NULL");
4690                 __WDP_LOG_FUNC_EXIT__;
4691                 return -1;
4692         }
4693         memset(&params, 0x0, sizeof(dbus_method_param_s));
4694
4695         dbus_set_method_param(&params, "StopFind", g_pd->iface_path, g_dbus);
4696         params.params = NULL;
4697
4698         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4699         if (res < 0)
4700                         WDP_LOGE("Failed to send command to wpa_supplicant");
4701         else
4702                 WDP_LOGD("Succeeded to stop scan");
4703
4704         __WDP_LOG_FUNC_EXIT__;
4705         return res;
4706 }
4707
4708 int ws_get_visibility(int *visibility)
4709 {
4710         __WDP_LOG_FUNC_ENTER__;
4711
4712         __WDP_LOG_FUNC_EXIT__;
4713         return 0;
4714 }
4715
4716 int ws_set_visibility(int visibility)
4717 {
4718         __WDP_LOG_FUNC_ENTER__;
4719
4720         __WDP_LOG_FUNC_EXIT__;
4721         return 0;
4722 }
4723
4724 int ws_get_scan_result(GList **peers, int *peer_count)
4725 {
4726         __WDP_LOG_FUNC_ENTER__;
4727
4728         __WDP_LOG_FUNC_EXIT__;
4729         return 0;
4730 }
4731 static wfd_oem_device_s *__create_oem_device(void)
4732 {
4733         wfd_oem_device_s *device =
4734                         (wfd_oem_device_s *) g_try_malloc0(sizeof(wfd_oem_device_s));
4735         if (!device) {
4736                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
4737                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4738                 WDP_LOGF("Failed to allocate memory for event. [%s]",
4739                            error_buf);
4740         }
4741
4742         return device;
4743 }
4744
4745 int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
4746 {
4747         __WDP_LOG_FUNC_ENTER__;
4748         GDBusConnection *g_dbus = NULL;
4749         wfd_oem_device_s *device = NULL;
4750         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4751         int res = 0;
4752
4753         if (!peer_addr || !peer) {
4754                 WDP_LOGE("Invalid parameter");
4755                 __WDP_LOG_FUNC_EXIT__;
4756                 return -1;
4757         }
4758
4759         if (!g_pd) {
4760                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4761                 __WDP_LOG_FUNC_EXIT__;
4762                 return -1;
4763         }
4764
4765         g_dbus = g_pd->g_dbus;
4766         if (!g_dbus) {
4767                 WDP_LOGE("DBus connection is NULL");
4768                 __WDP_LOG_FUNC_EXIT__;
4769                 return -1;
4770         }
4771
4772         device = __create_oem_device();
4773         if (!device) {
4774                 __WDP_LOG_FUNC_EXIT__;
4775                 return -1;
4776         }
4777
4778         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4779                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4780
4781         WDP_LOGD("get peer path [%s]", peer_path);
4782
4783         res = dbus_property_get_all(peer_path, g_dbus, SUPPLICANT_P2P_PEER,
4784                                 __ws_get_peer_property, device);
4785
4786         if (res < 0) {
4787                 WDP_LOGE("Failed to send command to wpa_supplicant");
4788                 if (device->vsie)
4789                         g_free(device->vsie);
4790                 g_free(device);
4791                 __WDP_LOG_FUNC_EXIT__;
4792                 return -1;
4793         } else {
4794                 WDP_LOGD("succeeded to get peer info");
4795                 *peer = device;
4796         }
4797
4798         //Memory ownership of dev_data is transferred to method handler
4799         //which uses this function.
4800
4801         __WDP_LOG_FUNC_EXIT__;
4802         return 0;
4803 }
4804
4805 int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
4806 {
4807         __WDP_LOG_FUNC_ENTER__;
4808         GDBusConnection *g_dbus = NULL;
4809         GVariant *value = NULL;
4810         dbus_method_param_s params;
4811         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4812         int res = 0;
4813
4814         if (!peer_addr) {
4815                 WDP_LOGE("Invalid parameter");
4816                 __WDP_LOG_FUNC_EXIT__;
4817                 return -1;
4818         }
4819
4820         if (!g_pd) {
4821                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4822                 __WDP_LOG_FUNC_EXIT__;
4823                 return -1;
4824         }
4825
4826         g_dbus = g_pd->g_dbus;
4827         if (!g_dbus) {
4828                 WDP_LOGE("DBus connection is NULL");
4829                 __WDP_LOG_FUNC_EXIT__;
4830                 return -1;
4831         }
4832         memset(&params, 0x0, sizeof(dbus_method_param_s));
4833
4834         dbus_set_method_param(&params, "ProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
4835
4836         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4837                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4838         WDP_LOGD("get peer path [%s]", peer_path);
4839
4840         value = g_variant_new("(os)", peer_path, __ws_wps_to_txt(wps_mode));
4841
4842         params.params = value;
4843         DEBUG_G_VARIANT("Params : ", params.params);
4844
4845         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4846         if (res < 0)
4847                 WDP_LOGE("Failed to send command to wpa_supplicant");
4848         else
4849                 WDP_LOGD("Succeeded to send prov disc to peer[" MACSTR "]", MAC2STR(peer_addr));
4850
4851         __WDP_LOG_FUNC_EXIT__;
4852         return res;
4853 }
4854
4855 int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
4856 {
4857         __WDP_LOG_FUNC_ENTER__;
4858         GDBusConnection *g_dbus = NULL;
4859         GVariantBuilder *builder = NULL;
4860         GVariant *value = NULL;
4861         dbus_method_param_s params;
4862         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4863         int res = 0;
4864
4865         if (!peer_addr || !param) {
4866                 WDP_LOGE("Invalid parameter");
4867                 __WDP_LOG_FUNC_EXIT__;
4868                 return -1;
4869         }
4870
4871         if (!g_pd) {
4872                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4873                 __WDP_LOG_FUNC_EXIT__;
4874                 return -1;
4875         }
4876
4877         g_dbus = g_pd->g_dbus;
4878         if (!g_dbus) {
4879                 WDP_LOGE("DBus connection is NULL");
4880                 __WDP_LOG_FUNC_EXIT__;
4881                 return -1;
4882         }
4883         memset(&params, 0x0, sizeof(dbus_method_param_s));
4884
4885         dbus_set_method_param(&params, "Connect", g_pd->iface_path, g_dbus);
4886
4887         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4888                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4889         WDP_LOGD("get peer path [%s]", peer_path);
4890
4891         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4892         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
4893         if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
4894                 g_variant_builder_add(builder, "{sv}", "persistent", g_variant_new_boolean(TRUE));
4895
4896         if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
4897                 g_variant_builder_add(builder, "{sv}", "join", g_variant_new_boolean(TRUE));
4898
4899         if (param->conn_flags & WFD_OEM_CONN_TYPE_AUTH)
4900                 g_variant_builder_add(builder, "{sv}", "autorize_only", g_variant_new_boolean(TRUE));
4901
4902         if (param->wps_pin[0] != '\0')
4903                 g_variant_builder_add(builder, "{sv}", "pin", g_variant_new_string(param->wps_pin));
4904
4905         g_variant_builder_add(builder, "{sv}", "wps_method",
4906                                 g_variant_new_string(__ws_wps_to_txt(param->wps_mode)));
4907
4908         value = g_variant_new("(a{sv})", builder);
4909         g_variant_builder_unref(builder);
4910
4911         params.params = value;
4912         DEBUG_G_VARIANT("Params : ", params.params);
4913
4914         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4915         if (res < 0)
4916                 WDP_LOGE("Failed to send command to wpa_supplicant");
4917         else
4918                 WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
4919
4920         __WDP_LOG_FUNC_EXIT__;
4921         return res;
4922 }
4923
4924 int ws_disconnect(unsigned char *peer_addr, int is_iface_addr)
4925 {
4926         __WDP_LOG_FUNC_ENTER__;
4927         GDBusConnection *g_dbus = NULL;
4928         GVariant *value = NULL;
4929         dbus_method_param_s params;
4930         GVariantBuilder *builder = NULL;
4931         int res = 0;
4932
4933         if (!peer_addr) {
4934                 WDP_LOGE("Invalid parameter");
4935                 __WDP_LOG_FUNC_EXIT__;
4936                 return -1;
4937         }
4938
4939         if (!g_pd) {
4940                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4941                 __WDP_LOG_FUNC_EXIT__;
4942                 return -1;
4943         }
4944
4945         g_dbus = g_pd->g_dbus;
4946         if (!g_dbus) {
4947                 WDP_LOGE("DBus connection is NULL");
4948                 __WDP_LOG_FUNC_EXIT__;
4949                 return -1;
4950         }
4951         memset(&params, 0x0, sizeof(dbus_method_param_s));
4952
4953         dbus_set_method_param(&params, "RemoveClient", g_pd->iface_path, g_dbus);
4954         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4955
4956         if (is_iface_addr) {
4957                 char peer_mac_str[WS_MACSTR_LEN] = {'\0', };
4958
4959                 g_snprintf(peer_mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
4960                 WDP_LOGI("peer addr [%s]", peer_mac_str);
4961                 g_variant_builder_add(builder, "{sv}", "iface",
4962                                 g_variant_new_string(peer_mac_str));
4963         } else {
4964                 char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0', };
4965
4966                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4967                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4968                 g_variant_builder_add(builder, "{sv}", "peer",
4969                                 g_variant_new_object_path(peer_path));
4970         }
4971
4972         value = g_variant_new("(a{sv})", builder);
4973         g_variant_builder_unref(builder);
4974
4975         params.params = value;
4976         DEBUG_G_VARIANT("Params : ", params.params);
4977
4978         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4979         if (res < 0)
4980                 WDP_LOGE("Failed to send command to wpa_supplicant");
4981         else
4982                 WDP_LOGD("Succeeded to send disconnection command to peer[" MACSECSTR "]",
4983                                 MAC2SECSTR(peer_addr));
4984
4985         __WDP_LOG_FUNC_EXIT__;
4986         return res;
4987 }
4988
4989 int ws_reject_connection(unsigned char *peer_addr)
4990 {
4991         __WDP_LOG_FUNC_ENTER__;
4992         GDBusConnection *g_dbus = NULL;
4993         GVariant *value = NULL;
4994         dbus_method_param_s params;
4995         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4996         int res = 0;
4997
4998         if (!peer_addr) {
4999                 WDP_LOGE("Invalid parameter");
5000                 __WDP_LOG_FUNC_EXIT__;
5001                 return -1;
5002         }
5003
5004         if (!g_pd) {
5005                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5006                 __WDP_LOG_FUNC_EXIT__;
5007                 return -1;
5008         }
5009
5010         g_dbus = g_pd->g_dbus;
5011         if (!g_dbus) {
5012                 WDP_LOGE("DBus connection is NULL");
5013                 __WDP_LOG_FUNC_EXIT__;
5014                 return -1;
5015         }
5016         memset(&params, 0x0, sizeof(dbus_method_param_s));
5017
5018         dbus_set_method_param(&params, "RejectPeer", g_pd->iface_path, g_dbus);
5019
5020         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
5021                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
5022         WDP_LOGE("get peer path [%s]", peer_path);
5023
5024         value = g_variant_new("(o)", peer_path);
5025
5026         params.params = value;
5027         DEBUG_G_VARIANT("Params : ", params.params);
5028
5029         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5030         if (res < 0)
5031                 WDP_LOGE("Failed to send command to wpa_supplicant");
5032         else
5033                 WDP_LOGD("Succeeded to reject peer[" MACSTR "]", MAC2STR(peer_addr));
5034
5035         _ws_flush();
5036         __WDP_LOG_FUNC_EXIT__;
5037         return res;
5038 }
5039
5040 int ws_cancel_connection(unsigned char *peer_addr)
5041 {
5042         __WDP_LOG_FUNC_ENTER__;
5043
5044         _ws_cancel();
5045
5046         __WDP_LOG_FUNC_EXIT__;
5047         return 0;
5048 }
5049
5050 int ws_get_connected_peers(GList **peers, int *peer_count)
5051 {
5052         __WDP_LOG_FUNC_ENTER__;
5053
5054         __WDP_LOG_FUNC_EXIT__;
5055         return 0;
5056 }
5057
5058 int ws_get_pin(char *pin)
5059 {
5060         __WDP_LOG_FUNC_ENTER__;
5061
5062         __WDP_LOG_FUNC_EXIT__;
5063         return 0;
5064 }
5065
5066 int ws_set_pin(char *pin)
5067 {
5068         __WDP_LOG_FUNC_ENTER__;
5069
5070         __WDP_LOG_FUNC_EXIT__;
5071         return 0;
5072 }
5073
5074 static void __ws_get_pin(GVariant *value, void *user_data)
5075 {
5076         __WDP_LOG_FUNC_ENTER__;
5077         const char *pin = NULL;
5078
5079         g_variant_get(value, "(&s)", &pin);
5080         g_strlcpy((char *)user_data, pin, OEM_PINSTR_LEN + 1);
5081
5082         __WDP_LOG_FUNC_EXIT__;
5083         return;
5084 }
5085
5086 int ws_generate_pin(char **pin)
5087 {
5088         __WDP_LOG_FUNC_ENTER__;
5089         GDBusConnection *g_dbus = NULL;
5090         dbus_method_param_s params;
5091         char n_pin[9] = {0,};
5092         int res = 0;
5093
5094         if (!g_pd) {
5095                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5096                 return -1;
5097         }
5098
5099         g_dbus = g_pd->g_dbus;
5100         if (!g_dbus) {
5101                 WDP_LOGE("DBus connection is NULL");
5102                 return -1;
5103         }
5104         memset(&params, 0x0, sizeof(dbus_method_param_s));
5105
5106         dbus_set_method_param(&params, "GeneratePin", g_pd->iface_path, g_dbus);
5107         params.params = NULL;
5108
5109         res = dbus_method_call(&params, SUPPLICANT_WPS, __ws_get_pin, (void *)n_pin);
5110         if (res < 0)
5111                 WDP_LOGE("Failed to send command to wpa_supplicant");
5112         else
5113                 WDP_LOGD("Succeeded to generate_pin [ %s ]", n_pin);
5114
5115         *pin = strndup(n_pin, OEM_PINSTR_LEN);
5116         __WDP_LOG_FUNC_EXIT__;
5117         return 0;
5118 }
5119
5120 int ws_get_supported_wps_mode(int *wps_mode)
5121 {
5122         __WDP_LOG_FUNC_ENTER__;
5123         if (!wps_mode) {
5124                 WDP_LOGE("Invalid parameter");
5125                 __WDP_LOG_FUNC_EXIT__;
5126                 return -1;
5127         }
5128
5129         *wps_mode = wps_config_method;
5130         __WDP_LOG_FUNC_EXIT__;
5131         return 0;
5132 }
5133
5134 int _ws_get_persistent_net_id(int *persistent_network_id, const unsigned char *go_dev_mac)
5135 {
5136         __WDP_LOG_FUNC_ENTER__;
5137         int persistent_group_count = 0;
5138         int counter = 0;
5139         int res = 0;
5140
5141         wfd_oem_persistent_group_s *plist = NULL;
5142
5143         res = ws_get_persistent_groups(&plist, &persistent_group_count);
5144         if (res < 0) {
5145                 WDP_LOGE("failed to get persistent groups");
5146                 __WDP_LOG_FUNC_EXIT__;
5147                 return -1;
5148         }
5149
5150         if (persistent_group_count > WS_MAX_PERSISTENT_COUNT) {
5151                 WDP_LOGE("persistent group count greater than max Persistent count");
5152                 persistent_group_count = WS_MAX_PERSISTENT_COUNT;
5153         }
5154
5155         WDP_LOGD("Persistent Group Count=%d", persistent_group_count);
5156
5157         for (counter = 0; counter < persistent_group_count ; counter++) {
5158                 if (!memcmp(go_dev_mac, plist[counter].go_mac_address, WS_MACADDR_LEN)) {
5159                         *persistent_network_id = plist[counter].network_id;
5160                         break;
5161                 } else {
5162                         WDP_LOGD("Invite: Persistent GO[" MACSTR "], GO Addr[" MACSTR "]",
5163                                         MAC2STR(plist[counter].go_mac_address), MAC2STR(go_dev_mac));
5164                 }
5165         }
5166
5167         g_free(plist);
5168         plist = NULL;
5169         WDP_LOGD("persistent network ID : [%d]", *persistent_network_id);
5170
5171         __WDP_LOG_FUNC_EXIT__;
5172         return 0;
5173 }
5174
5175 static void __store_group_iface_path(GVariant* value, void* user_data)
5176 {
5177         __WDP_LOG_FUNC_ENTER__;
5178         ws_dbus_plugin_data_s * pd_data;
5179         const char *path = NULL;
5180
5181         if (!g_pd) {
5182                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5183                 return;
5184         }
5185
5186         pd_data = (ws_dbus_plugin_data_s *) g_pd;
5187
5188         g_variant_get(value, "(&o)", &path);
5189         g_strlcpy(pd_data->group_iface_path, path, DBUS_OBJECT_PATH_MAX);
5190
5191         WDP_LOGD("group object path [%s]", pd_data->group_iface_path);
5192         /* subscribe interface p2p signal */
5193 }
5194
5195 int ws_create_group(wfd_oem_group_param_s *param)
5196 {
5197         __WDP_LOG_FUNC_ENTER__;
5198         GDBusConnection *g_dbus = NULL;
5199         GVariantBuilder *builder = NULL;
5200         GVariant *value = NULL;
5201         dbus_method_param_s params;
5202         char persistent_group_obj_path[OBJECT_PATH_MAX] = {0,};
5203         int res = 0;
5204
5205         if (!param) {
5206                 WDP_LOGE("Invalid parameter");
5207                 __WDP_LOG_FUNC_EXIT__;
5208                 return -1;
5209         }
5210
5211         if (!g_pd) {
5212                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5213                 __WDP_LOG_FUNC_EXIT__;
5214                 return -1;
5215         }
5216
5217         g_dbus = g_pd->g_dbus;
5218         if (!g_dbus) {
5219                 WDP_LOGE("DBus connection is NULL");
5220                 __WDP_LOG_FUNC_EXIT__;
5221                 return -1;
5222         }
5223         memset(&params, 0x0, sizeof(dbus_method_param_s));
5224
5225         dbus_set_method_param(&params, "GroupAdd", g_pd->iface_path, g_dbus);
5226
5227         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5228
5229         if (param->persistent > 0) {
5230                 unsigned char mac_address[WS_MACADDR_LEN] = {0x00, };
5231                 int persistent_group_id = -1;
5232
5233                 res = _ws_get_local_dev_mac(mac_address);
5234                 if (res < 0) {
5235                         WDP_LOGE("failed to get local mac address");
5236                         __WDP_LOG_FUNC_EXIT__;
5237                         return -1;
5238                 }
5239
5240                 res = _ws_get_persistent_net_id(&persistent_group_id, mac_address);
5241                 if (res < 0) {
5242                         WDP_LOGE("failed to get persistent group ID");
5243                         __WDP_LOG_FUNC_EXIT__;
5244                         return -1;
5245                 }
5246
5247                 WDP_LOGD("persistent network ID : [%d]", persistent_group_id);
5248
5249                 g_variant_builder_add(builder, "{sv}", "persistent",
5250                                 g_variant_new_boolean(TRUE));
5251                 if (persistent_group_id > -1) {
5252                         g_snprintf(persistent_group_obj_path, OBJECT_PATH_MAX,
5253                                         "%s/" SUPPLICANT_PERSISTENT_GROUPS_PART "/%d",
5254                                         g_pd->iface_path, persistent_group_id);
5255                         g_variant_builder_add(builder, "{sv}", "persistent_group_object",
5256                                         g_variant_new_object_path(persistent_group_obj_path));
5257                 }
5258
5259         } else {
5260                 g_variant_builder_add(builder, "{sv}", "persistent",
5261                                 g_variant_new_boolean(FALSE));
5262         }
5263
5264         if (param->passphrase && strlen(param->passphrase) > 0)
5265                 g_variant_builder_add(builder, "{sv}", "passphrase",
5266                                 g_variant_new_string(param->passphrase));
5267
5268         if (param->ssid && strlen(param->ssid) > 0)
5269                 g_variant_builder_add(builder, "{sv}", "ssid",
5270                                 g_variant_new_string(param->ssid));
5271
5272         if (param->freq)
5273                 g_variant_builder_add(builder, "{sv}", "frequency",
5274                                 g_variant_new_int32(param->freq));
5275
5276         value = g_variant_new("(a{sv})", builder);
5277         g_variant_builder_unref(builder);
5278
5279         params.params = value;
5280         DEBUG_G_VARIANT("Params : ", params.params);
5281
5282         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
5283                         __store_group_iface_path, g_pd);
5284         if (res < 0)
5285                 WDP_LOGE("Failed to send command to wpa_supplicant");
5286         else
5287                 WDP_LOGD("Succeeded to add group");
5288
5289         __WDP_LOG_FUNC_EXIT__;
5290         return res;
5291 }
5292
5293 int ws_destroy_group(const char *ifname)
5294 {
5295         __WDP_LOG_FUNC_ENTER__;
5296         GDBusConnection *g_dbus = NULL;
5297         dbus_method_param_s params;
5298         int res = 0;
5299
5300         if (!ifname) {
5301                 WDP_LOGE("Invalid parameter");
5302                 return -1;
5303         }
5304
5305         if (!g_pd) {
5306                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5307                 __WDP_LOG_FUNC_EXIT__;
5308                 return -1;
5309         }
5310
5311         g_dbus = g_pd->g_dbus;
5312         if (!g_dbus) {
5313                 WDP_LOGE("DBus connection is NULL");
5314                 __WDP_LOG_FUNC_EXIT__;
5315                 return -1;
5316         }
5317
5318         if (g_pd->group_iface_path[0] == 0) {
5319                 WDP_LOGE("group iface path is NULL");
5320                 return -1;
5321         }
5322
5323         memset(&params, 0x0, sizeof(dbus_method_param_s));
5324
5325         dbus_set_method_param(&params, "Disconnect", g_pd->group_iface_path, g_dbus);
5326         params.params = NULL;
5327
5328         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5329         if (res < 0) {
5330                 WDP_LOGE("Failed to send command to wpa_supplicant");
5331                 __WDP_LOG_FUNC_EXIT__;
5332                 return -1;
5333         } else {
5334                 _ws_flush();
5335                 WDP_LOGD("Succeeded to remove group");
5336         }
5337
5338         __WDP_LOG_FUNC_EXIT__;
5339         return 0;
5340 }
5341
5342 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
5343 {
5344         __WDP_LOG_FUNC_ENTER__;
5345         GDBusConnection *g_dbus = NULL;
5346         GVariantBuilder *builder = NULL;
5347         GVariant *value = NULL;
5348         dbus_method_param_s params;
5349         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
5350         int res = 0;
5351
5352         if (!peer_addr || !param) {
5353                 WDP_LOGE("Invalid parameter");
5354                 return -1;
5355         }
5356
5357         if (!g_pd) {
5358                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5359                 __WDP_LOG_FUNC_EXIT__;
5360                 return -1;
5361         }
5362
5363         g_dbus = g_pd->g_dbus;
5364         if (!g_dbus) {
5365                 WDP_LOGE("DBus connection is NULL");
5366                 __WDP_LOG_FUNC_EXIT__;
5367                 return -1;
5368         }
5369         memset(&params, 0x0, sizeof(dbus_method_param_s));
5370
5371         dbus_set_method_param(&params, "Invite", g_pd->group_iface_path, g_dbus);
5372
5373         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
5374                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
5375         WDP_LOGE("get peer path [%s]", peer_path);
5376
5377         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5378         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
5379         value = g_variant_new("(a{sv})", builder);
5380         g_variant_builder_unref(builder);
5381
5382         params.params = value;
5383         DEBUG_G_VARIANT("Params : ", params.params);
5384
5385         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5386         if (res < 0)
5387                 WDP_LOGE("Failed to send command to wpa_supplicant");
5388         else
5389                 WDP_LOGD("Succeeded to invite peer[" MACSTR "]", MAC2STR(peer_addr));
5390
5391         __WDP_LOG_FUNC_EXIT__;
5392         return 0;
5393 }
5394
5395 /* Only group owner can use this command */
5396 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
5397 {
5398         __WDP_LOG_FUNC_ENTER__;
5399         GDBusConnection *g_dbus = NULL;
5400         GVariantBuilder *builder = NULL;
5401         GVariant *value = NULL;
5402         GVariant *dev_addr = NULL;
5403         dbus_method_param_s params;
5404         int i = 0;
5405         int res = 0;
5406
5407         if (!g_pd) {
5408                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5409                 __WDP_LOG_FUNC_EXIT__;
5410                 return -1;
5411         }
5412
5413         g_dbus = g_pd->g_dbus;
5414         if (!g_dbus) {
5415                 WDP_LOGE("DBus connection is NULL");
5416                 __WDP_LOG_FUNC_EXIT__;
5417                 return -1;
5418         }
5419
5420         memset(&params, 0x0, sizeof(dbus_method_param_s));
5421
5422         dbus_set_method_param(&params, "Start", g_pd->group_iface_path, g_dbus);
5423
5424         if (peer_addr != NULL) {
5425                 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
5426                 for (i = 0; i < WS_MACADDR_LEN; i++)
5427                         g_variant_builder_add(builder, "y", peer_addr[i]);
5428
5429                 dev_addr = g_variant_new("ay", builder);
5430                 g_variant_builder_unref(builder);
5431         }
5432
5433         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5434         g_variant_builder_add(builder, "{sv}", "Role", g_variant_new_string("enrollee"));
5435         if (peer_addr != NULL)
5436                 g_variant_builder_add(builder, "{sv}", "P2PDeviceAddress", dev_addr);
5437
5438         if (pin != NULL && pin[0] != '\0') {
5439                 g_variant_builder_add(builder, "{sv}", "Type", g_variant_new_string("pin"));
5440                 g_variant_builder_add(builder, "{sv}", "Pin", g_variant_new_string(pin));
5441         } else {
5442                 g_variant_builder_add(builder, "{sv}", "Type", g_variant_new_string("pbc"));
5443         }
5444
5445         value = g_variant_new("(a{sv})", builder);
5446         g_variant_builder_unref(builder);
5447
5448         params.params = value;
5449         DEBUG_G_VARIANT("Params : ", params.params);
5450
5451         res = dbus_method_call(&params, SUPPLICANT_WPS, NULL, NULL);
5452         if (res < 0)
5453                 WDP_LOGE("Failed to send command to wpa_supplicant");
5454         else
5455                 WDP_LOGD("Succeeded to run wps");
5456
5457         __WDP_LOG_FUNC_EXIT__;
5458         return 0;
5459 }
5460
5461 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
5462 {
5463         __WDP_LOG_FUNC_ENTER__;
5464
5465         WDP_LOGD("Succeeded to start WPS");
5466
5467         __WDP_LOG_FUNC_EXIT__;
5468         return 0;
5469 }
5470
5471 int ws_wps_cancel(void)
5472 {
5473         __WDP_LOG_FUNC_ENTER__;
5474         GDBusConnection *g_dbus = NULL;
5475         dbus_method_param_s params;
5476         int res = 0;
5477
5478         g_dbus = g_pd->g_dbus;
5479         if (!g_dbus) {
5480                 WDP_LOGE("DBus connection is NULL");
5481                 __WDP_LOG_FUNC_EXIT__;
5482                 return -1;
5483         }
5484         memset(&params, 0x0, sizeof(dbus_method_param_s));
5485
5486         dbus_set_method_param(&params, "Cancel", g_pd->group_iface_path, g_dbus);
5487         params.params = NULL;
5488
5489         res = dbus_method_call(&params, SUPPLICANT_WPS, NULL, NULL);
5490         if (res < 0)
5491                 WDP_LOGE("Failed to send command to wpa_supplicant");
5492         else
5493                 WDP_LOGD("Succeeded to cancel WPS");
5494
5495         __WDP_LOG_FUNC_EXIT__;
5496         return 0;
5497 }
5498
5499 int ws_get_dev_name(char *dev_name)
5500 {
5501         __WDP_LOG_FUNC_ENTER__;
5502
5503         __WDP_LOG_FUNC_EXIT__;
5504         return 0;
5505 }
5506
5507 int ws_set_dev_name(char *dev_name)
5508 {
5509         __WDP_LOG_FUNC_ENTER__;
5510         GDBusConnection *g_dbus = NULL;
5511
5512         GVariant *value = NULL;
5513         GVariant *param = NULL;
5514         GVariantBuilder *builder = NULL;
5515         dbus_method_param_s params;
5516         int res = 0;
5517
5518         if (!dev_name) {
5519                 WDP_LOGE("Invalid parameter");
5520                 __WDP_LOG_FUNC_EXIT__;
5521                 return -1;
5522         }
5523
5524         if (!g_pd) {
5525                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5526                 __WDP_LOG_FUNC_EXIT__;
5527                 return -1;
5528         }
5529
5530         g_dbus = g_pd->g_dbus;
5531         if (!g_dbus) {
5532                 WDP_LOGE("DBus connection is NULL");
5533                 __WDP_LOG_FUNC_EXIT__;
5534                 return -1;
5535         }
5536         memset(&params, 0x0, sizeof(dbus_method_param_s));
5537
5538         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5539                          g_dbus);
5540
5541         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5542         g_variant_builder_add(builder, "{sv}", "DeviceName",
5543                                 g_variant_new_string(dev_name));
5544         g_variant_builder_add(builder, "{sv}", "SsidPostfix",
5545                                  g_variant_new_string(dev_name));
5546         value = g_variant_new("a{sv}", builder);
5547         g_variant_builder_unref(builder);
5548
5549         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE,
5550                                 "P2PDeviceConfig", value);
5551
5552         params.params = param;
5553         DEBUG_G_VARIANT("Params : ", params.params);
5554
5555         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5556         if (res < 0)
5557                 WDP_LOGE("Failed to send command to wpa_supplicant");
5558         else
5559                 WDP_LOGD("Succeeded to set device name");
5560
5561         __WDP_LOG_FUNC_EXIT__;
5562         return res;
5563 }
5564
5565 int ws_get_dev_mac(char *dev_mac)
5566 {
5567         __WDP_LOG_FUNC_ENTER__;
5568
5569         __WDP_LOG_FUNC_EXIT__;
5570         return 0;
5571 }
5572
5573 int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
5574 {
5575         __WDP_LOG_FUNC_ENTER__;
5576
5577         __WDP_LOG_FUNC_EXIT__;
5578         return 0;
5579 }
5580
5581 int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
5582 {
5583         __WDP_LOG_FUNC_ENTER__;
5584
5585         __WDP_LOG_FUNC_EXIT__;
5586         return 0;
5587 }
5588
5589 int ws_get_go_intent(int *go_intent)
5590 {
5591         __WDP_LOG_FUNC_ENTER__;
5592         GDBusConnection *g_dbus = NULL;
5593         GVariant *param = NULL;
5594         GVariant *reply = NULL;
5595         GError *error = NULL;
5596         GVariantIter *iter = NULL;
5597
5598
5599         if (!go_intent) {
5600                 WDP_LOGE("Invalid parameter");
5601                 return -1;
5602         }
5603
5604         if (!g_pd) {
5605                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5606                 __WDP_LOG_FUNC_EXIT__;
5607                 return -1;
5608         }
5609
5610         g_dbus = g_pd->g_dbus;
5611         if (!g_dbus) {
5612                 WDP_LOGE("DBus connection is NULL");
5613                 __WDP_LOG_FUNC_EXIT__;
5614                 return -1;
5615         }
5616
5617         param = g_variant_new("(ss)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig");
5618         DEBUG_G_VARIANT("Params : ", param);
5619
5620         reply = g_dbus_connection_call_sync(
5621                         g_dbus,
5622                         SUPPLICANT_SERVICE, /* bus name */
5623                         g_pd->iface_path, /* object path */
5624                         DBUS_PROPERTIES_INTERFACE, /* interface name */
5625                         DBUS_PROPERTIES_METHOD_GET, /* method name */
5626                         param, /* GVariant *params */
5627                         NULL, /* reply_type */
5628                         G_DBUS_CALL_FLAGS_NONE, /* flags */
5629                         SUPPLICANT_TIMEOUT , /* timeout */
5630                         NULL, /* cancellable */
5631                         &error); /* error */
5632
5633         if (error != NULL) {
5634                 WDP_LOGE("Error! Failed to get interface State: [%s]",
5635                                 error->message);
5636                 g_error_free(error);
5637                 if (reply)
5638                         g_variant_unref(reply);
5639                 __WDP_LOG_FUNC_EXIT__;
5640                 return -1;
5641         }
5642
5643         if (reply != NULL) {
5644                 g_variant_get(reply, "(a{sv})", &iter);
5645
5646                 if (iter != NULL) {
5647                         gchar *key = NULL;
5648                         GVariant *value = NULL;
5649
5650                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
5651                                 CHECK_KEY_VALUE(key, value);
5652
5653                                 if (g_strcmp0(key, "GOIntent") == 0)
5654                                         g_variant_get(value, "u", go_intent);
5655                         }
5656                         g_variant_iter_free(iter);
5657                 }
5658                 g_variant_unref(reply);
5659         }
5660         __WDP_LOG_FUNC_EXIT__;
5661         return 0;
5662 }
5663
5664 int ws_set_go_intent(int go_intent)
5665 {
5666         __WDP_LOG_FUNC_ENTER__;
5667         GDBusConnection *g_dbus = NULL;
5668
5669         GVariant *value = NULL;
5670         GVariant *param = NULL;
5671         GVariantBuilder *builder = NULL;
5672         dbus_method_param_s params;
5673         int res = 0;
5674
5675         if (!g_pd) {
5676                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5677                 __WDP_LOG_FUNC_EXIT__;
5678                 return -1;
5679         }
5680
5681         g_dbus = g_pd->g_dbus;
5682         if (!g_dbus) {
5683                 WDP_LOGE("DBus connection is NULL");
5684                 __WDP_LOG_FUNC_EXIT__;
5685                 return -1;
5686         }
5687         memset(&params, 0x0, sizeof(dbus_method_param_s));
5688
5689         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5690                          g_dbus);
5691
5692         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5693         g_variant_builder_add(builder, "{sv}", "GOIntent",
5694                                 g_variant_new_uint32(go_intent));
5695         value = g_variant_new("a{sv}", builder);
5696         g_variant_builder_unref(builder);
5697
5698         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
5699
5700         params.params = param;
5701         DEBUG_G_VARIANT("Params : ", params.params);
5702
5703         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5704         if (res < 0)
5705                 WDP_LOGE("Failed to send command to wpa_supplicant");
5706         else
5707                 WDP_LOGE("Succeeded to set go intent");
5708         __WDP_LOG_FUNC_EXIT__;
5709         return res;
5710 }
5711
5712 int ws_set_country(char *ccode)
5713 {
5714         __WDP_LOG_FUNC_ENTER__;
5715         __WDP_LOG_FUNC_ENTER__;
5716         GDBusConnection *g_dbus = NULL;
5717
5718         GVariant *value = NULL;
5719         GVariant *param = NULL;
5720
5721         dbus_method_param_s params;
5722         int res = 0;
5723
5724         if (!g_pd) {
5725                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5726                 __WDP_LOG_FUNC_EXIT__;
5727                 return -1;
5728         }
5729
5730         g_dbus = g_pd->g_dbus;
5731         if (!g_dbus) {
5732                 WDP_LOGE("DBus connection is NULL");
5733                 __WDP_LOG_FUNC_EXIT__;
5734                 return -1;
5735         }
5736         memset(&params, 0x0, sizeof(dbus_method_param_s));
5737
5738         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5739                          g_dbus);
5740
5741         value = g_variant_new_string(ccode);
5742
5743         param = g_variant_new("(ssv)", SUPPLICANT_IFACE, "Country", value);
5744
5745         params.params = param;
5746         DEBUG_G_VARIANT("Params : ", params.params);
5747
5748         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5749         if (res < 0)
5750                 WDP_LOGE("Failed to send command to wpa_supplicant");
5751         else
5752                 WDP_LOGD("Succeeded to set country(%s)", ccode);
5753
5754         __WDP_LOG_FUNC_EXIT__;
5755         return res;
5756 }
5757
5758 void __parsing_networks(const char* key, GVariant* value, void* user_data)
5759 {
5760         __WDP_LOG_FUNC_ENTER__;
5761         if (!user_data) {
5762                 __WDP_LOG_FUNC_EXIT__;
5763                 return;
5764         }
5765
5766         ws_network_info_s *network = (ws_network_info_s *)user_data;
5767
5768         CHECK_KEY_VALUE(key, value);
5769
5770         if (g_strcmp0(key, "ssid") == 0) {
5771                 const char *ssid = NULL;
5772                 g_variant_get(value, "&s", &ssid);
5773                 WDP_LOGD("ssid [%s]", ssid);
5774                 g_strlcpy(network->ssid, ssid + 1, WS_SSID_LEN + 1);
5775                 network->ssid[strlen(ssid) - 2] = '\0';
5776
5777         } else if (g_strcmp0(key, "bssid") == 0) {
5778                 unsigned char *bssid = NULL;
5779                 g_variant_get(value, "&s", &bssid);
5780                 WDP_LOGD("bssid [%s]", bssid);
5781                 __ws_txt_to_mac(bssid, network->bssid);
5782
5783         } else if (g_strcmp0(key, "proto") == 0) {
5784                 const char *proto = NULL;
5785                 g_variant_get(value, "&s", &proto);
5786                 WDP_LOGD("proto [%s]", proto);
5787
5788                 if (g_strrstr(proto, WFD_OEM_STR_PROTO_WPA) != NULL)
5789                         network->proto |= WFD_OEM_PROTO_WPA;
5790                 if (g_strrstr(proto, WFD_OEM_STR_PROTO_RSN) != NULL)
5791                         network->proto |= WFD_OEM_PROTO_RSN;
5792
5793         } else if (g_strcmp0(key, "key_mgmt") == 0) {
5794                 const char *key_mgmt = NULL;
5795                 g_variant_get(value, "&s", &key_mgmt);
5796                 WDP_LOGD("key_mgmt [%s]", key_mgmt);
5797
5798                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_IEEE8021X) != NULL)
5799                         network->key_mgmt |= WFD_OEM_KEY_MGMT_IEEE8021X;
5800                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_PSK) != NULL)
5801                         network->key_mgmt |= WFD_OEM_KEY_MGMT_PSK;
5802                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_NONE) != NULL)
5803                         network->key_mgmt |= WFD_OEM_KEY_MGMT_NONE;
5804
5805         } else if (g_strcmp0(key, "pairwise") == 0) {
5806                 const char *pairwise = NULL;
5807                 g_variant_get(value, "&s", &pairwise);
5808                 WDP_LOGD("pairwise [%s]", pairwise);
5809
5810                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_NONE) != NULL)
5811                         network->pairwise |= WFD_OEM_CIPHER_NONE;
5812                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_TKIP) != NULL)
5813                         network->pairwise |= WFD_OEM_CIPHER_TKIP;
5814                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_CCMP) != NULL)
5815                         network->pairwise |= WFD_OEM_CIPHER_CCMP;
5816
5817         }  else if (g_strcmp0(key, "group") == 0) {
5818                 const char *group = NULL;
5819                 g_variant_get(value, "&s", &group);
5820                 WDP_LOGD("group [%s]", group);
5821
5822                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_NONE) != NULL)
5823                         network->group |= WFD_OEM_CIPHER_NONE;
5824                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_WEP40) != NULL)
5825                         network->group |= WFD_OEM_CIPHER_WEP40;
5826                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_WEP104) != NULL)
5827                         network->group |= WFD_OEM_CIPHER_WEP104;
5828                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_TKIP) != NULL)
5829                         network->group |= WFD_OEM_CIPHER_TKIP;
5830                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_CCMP) != NULL)
5831                         network->group |= WFD_OEM_CIPHER_CCMP;
5832
5833         } else if (g_strcmp0(key, "auth_alg") == 0) {
5834                 const char *auth_alg = NULL;
5835                 g_variant_get(value, "&s", &auth_alg);
5836                 WDP_LOGD("auth_alg [%s]", auth_alg);
5837
5838                 if (g_strrstr(auth_alg, WFD_OEM_STR_AUTH_ALG_OPEN) != NULL)
5839                         network->auth_alg |= WFD_OEM_AUTH_ALG_OPEN;
5840
5841         } else if (g_strcmp0(key, "mode") == 0) {
5842                 const char *mode = NULL;
5843                 g_variant_get(value, "&s", &mode);
5844                 WDP_LOGD("mode [%s]", mode);
5845
5846                 if (g_strrstr(mode, WFD_OEM_STR_MODE_GC) != NULL)
5847                         network->mode |= WFD_OEM_PERSISTENT_MODE_GC;
5848                 if (g_strrstr(mode, WFD_OEM_STR_MODE_GO) != NULL)
5849                         network->mode |= WFD_OEM_PERSISTENT_MODE_GO;
5850
5851         } else if (g_strcmp0(key, "p2p_client_list") == 0) {
5852                 const char *p2p_client_list = NULL;
5853                 char *ptr = NULL;
5854                 int list_len = 0;
5855                 int num = 0;
5856
5857                 g_variant_get(value, "&s", &p2p_client_list);
5858                 WDP_LOGD("p2p_client_list [%s]", p2p_client_list);
5859                 ptr = (char *)p2p_client_list;
5860                 list_len = strlen(p2p_client_list);
5861                 WDP_LOGD("list_len [%d]", list_len);
5862                 while (ptr && list_len >= (OEM_MACSTR_LEN - 1)) {
5863                         __ws_txt_to_mac((unsigned char *)ptr, (network->p2p_client_list[num]));
5864                         ptr += OEM_MACSTR_LEN;
5865                         list_len -= OEM_MACSTR_LEN;
5866                         if (ptr && ptr[0] == ' ') {
5867                                 ptr += 1;
5868                                 list_len -= 1;
5869                         }
5870                         num++;
5871                         if (num >= OEM_MAX_PEER_NUM)
5872                                 break;
5873                 }
5874                 network->p2p_client_num = num;
5875                 WDP_LOGD("p2p_client_num [%d]", network->p2p_client_num);
5876         }
5877         return;
5878 }
5879
5880 void __ws_extract_p2pdevice_details(const char *key, GVariant *value, void *user_data)
5881 {
5882         __WDP_LOG_FUNC_ENTER__;
5883         CHECK_KEY_VALUE(key, value);
5884
5885         if (g_strcmp0(key, "PersistentGroups") == 0) {
5886                 GVariantIter *iter = NULL;
5887                 const char *path = NULL;
5888                 int num = 0;
5889
5890                 ws_network_info_s *networks = NULL;
5891                 networks = (ws_network_info_s *)user_data;
5892                 if (!networks) {
5893                         WDP_LOGE("network is NULL");
5894                         __WDP_LOG_FUNC_EXIT__;
5895                         return;
5896                 }
5897
5898                 g_variant_get(value, "ao", &iter);
5899                 while (g_variant_iter_loop(iter, "&o", &path)) {
5900                         char *loc = NULL;
5901
5902                         if (num >= WS_MAX_PERSISTENT_COUNT)
5903                                 break;
5904
5905                         WDP_LOGD("Retrive persistent path [%s]", path);
5906                         g_strlcpy(networks[num].persistent_path, path, DBUS_OBJECT_PATH_MAX);
5907
5908                         loc = strrchr(networks[num].persistent_path, '/');
5909                         if (loc)
5910                                 networks[num].network_id = strtoul(loc+1, NULL, 10);
5911
5912                         WDP_LOGD("Retrive persistent path [%s]", networks[num].persistent_path);
5913                         dbus_property_get_all(networks[num].persistent_path, g_pd->g_dbus,
5914                                         SUPPLICANT_P2P_PERSISTENTGROUP, __parsing_networks, &networks[num]);
5915                         num++;
5916                 }
5917
5918                 networks[0].total = num;
5919                 WDP_LOGI("total number [%d]", num);
5920                 g_variant_iter_free(iter);
5921         }
5922         __WDP_LOG_FUNC_EXIT__;
5923 }
5924
5925
5926 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
5927 {
5928         __WDP_LOG_FUNC_ENTER__;
5929         GDBusConnection *g_dbus = NULL;
5930
5931         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
5932         wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
5933         int i, cnt = 0;
5934
5935         if (!g_pd) {
5936                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5937                 __WDP_LOG_FUNC_EXIT__;
5938                 return -1;
5939         }
5940
5941         g_dbus = g_pd->g_dbus;
5942         if (!g_dbus) {
5943                 WDP_LOGE("DBus connection is NULL");
5944                 __WDP_LOG_FUNC_EXIT__;
5945                 return -1;
5946         }
5947
5948         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
5949         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
5950                         __ws_extract_p2pdevice_details, &networks[0]);
5951
5952         cnt = networks[0].total;
5953
5954         WDP_LOGD("Persistent Group Count=%d", cnt);
5955         if (cnt > WS_MAX_PERSISTENT_COUNT) {
5956                 WDP_LOGE("Persistent group count exceeded or parsing error");
5957                 __WDP_LOG_FUNC_EXIT__;
5958                 return -1;
5959         }
5960
5961         if (cnt == 0) {
5962                 WDP_LOGE("Persistent group count zero");
5963                 *group_count = 0;
5964                 *groups = NULL;
5965                 __WDP_LOG_FUNC_EXIT__;
5966                 return 0;
5967         }
5968
5969         wfd_persistent_groups = (wfd_oem_persistent_group_s *) g_try_malloc0(cnt * sizeof(wfd_oem_persistent_group_s));
5970         if (wfd_persistent_groups == NULL) {
5971                 WDP_LOGE("Failed to allocate memory for wfd_persistent_groups ");
5972                 __WDP_LOG_FUNC_EXIT__;
5973                 return -1;
5974         }
5975
5976         for (i = 0; i < cnt; i++) {
5977                 int j = 0;
5978
5979                 WDP_LOGD("----persistent group [%d]----", i);
5980                 WDP_LOGD("network_id [%d]", networks[i].network_id);
5981                 WDP_LOGD("ssid [%s]", networks[i].ssid);
5982                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
5983                 WDP_LOGD("p2p_client_num [%d]", networks[i].p2p_client_num);
5984                 for (j = 0; j < networks[i].p2p_client_num; j++)
5985                         WDP_LOGD("p2p_client_list ["MACSTR"]", MAC2STR(networks[i].p2p_client_list[j]));
5986
5987                 wfd_persistent_groups[i].network_id = networks[i].network_id;
5988                 g_strlcpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN + 1);
5989                 memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
5990                 wfd_persistent_groups[i].p2p_client_num = networks[i].p2p_client_num;
5991                 if (wfd_persistent_groups[i].p2p_client_num > 0)
5992                         memcpy(wfd_persistent_groups[i].p2p_client_list, networks[i].p2p_client_list,
5993                                         OEM_MACADDR_LEN * OEM_MAX_PEER_NUM * sizeof(char));
5994         }
5995
5996         *group_count = cnt;
5997         *groups = wfd_persistent_groups;
5998
5999         __WDP_LOG_FUNC_EXIT__;
6000         return 0;
6001 }
6002
6003 int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
6004 {
6005         __WDP_LOG_FUNC_ENTER__;
6006         GDBusConnection *g_dbus = NULL;
6007
6008         dbus_method_param_s params;
6009         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
6010         int i, cnt = 0;
6011         int res = 0;
6012
6013         if (!g_pd) {
6014                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6015                 __WDP_LOG_FUNC_EXIT__;
6016                 return -1;
6017         }
6018
6019         g_dbus = g_pd->g_dbus;
6020         if (!g_dbus) {
6021                 WDP_LOGE("DBus connection is NULL");
6022                 __WDP_LOG_FUNC_EXIT__;
6023                 return -1;
6024         }
6025         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
6026         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
6027                         __ws_extract_p2pdevice_details, networks);
6028
6029         cnt = networks[0].total;
6030
6031         WDP_LOGD("Persistent Group Count=%d", cnt);
6032         if (cnt > WS_MAX_PERSISTENT_COUNT) {
6033                 WDP_LOGE("Persistent group count exceeded or parsing error");
6034                 __WDP_LOG_FUNC_EXIT__;
6035                 return -1;
6036         }
6037
6038         for (i = 0; i < cnt; i++) {
6039                 int j = 0;
6040
6041                 WDP_LOGD("----persistent group [%d]----", i);
6042                 WDP_LOGD("network_id [%d]", networks[i].network_id);
6043                 WDP_LOGD("network ssid [%s]", networks[i].ssid);
6044                 WDP_LOGD("network bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
6045                 WDP_LOGD("network p2p_client_num [%d]", networks[i].p2p_client_num);
6046                 for (j = 0; j < networks[i].p2p_client_num; j++)
6047                         WDP_LOGD("network p2p_client_list ["MACSTR"]",
6048                                         MAC2STR(networks[i].p2p_client_list[j]));
6049
6050                 WDP_LOGD("ssid [%s]", ssid);
6051                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(bssid));
6052
6053                 if (!g_strcmp0(ssid, networks[i].ssid) &&
6054                                 !memcmp(bssid, networks[i].bssid, WS_MACADDR_LEN)) {
6055                         WDP_LOGD("Persistent group owner found [%d: %s]",
6056                                         networks[i].network_id, ssid);
6057
6058                         memset(&params, 0x0, sizeof(dbus_method_param_s));
6059                         dbus_set_method_param(&params, "RemovePersistentGroup",
6060                                         g_pd->iface_path, g_dbus);
6061                         params.params = g_variant_new("(o)", networks[i].persistent_path);
6062                         DEBUG_G_VARIANT("Params : ", params.params);
6063
6064                         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6065                         if (res < 0) {
6066                                 WDP_LOGE("Failed to send command to wpa_supplicant");
6067                                 __WDP_LOG_FUNC_EXIT__;
6068                                 return -1;
6069                         }
6070
6071                         WDP_LOGD("Succeeded to remove persistent group");;
6072                         break;
6073                 }
6074         }
6075
6076         if (i == cnt) {
6077                 WDP_LOGE("Persistent group not found [%s]", ssid);
6078                 return -1;
6079         }
6080
6081         __WDP_LOG_FUNC_EXIT__;
6082         return 0;
6083 }
6084
6085 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
6086 {
6087         __WDP_LOG_FUNC_ENTER__;
6088         GDBusConnection *g_dbus = NULL;
6089
6090         GVariant *value = NULL;
6091         GVariant *param = NULL;
6092         GVariantBuilder *builder = NULL;
6093         dbus_method_param_s params;
6094         int res = 0;
6095
6096         if (!g_pd) {
6097                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6098                 __WDP_LOG_FUNC_EXIT__;
6099                 return -1;
6100         }
6101
6102         g_dbus = g_pd->g_dbus;
6103         if (!g_dbus) {
6104                 WDP_LOGE("DBus connection is NULL");
6105                 __WDP_LOG_FUNC_EXIT__;
6106                 return -1;
6107         }
6108         memset(&params, 0x0, sizeof(dbus_method_param_s));
6109
6110         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
6111                         g_dbus);
6112
6113         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6114         g_variant_builder_add(builder, "{sv}", "PersistentReconnect",
6115                                 g_variant_new_boolean(reconnect));
6116         value = g_variant_new("a{sv}", builder);
6117         g_variant_builder_unref(builder);
6118
6119         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
6120
6121         params.params = param;
6122         DEBUG_G_VARIANT("Params : ", params.params);
6123
6124         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6125         if (res < 0)
6126                 WDP_LOGE("Failed to send command to wpa_supplicant");
6127         else
6128                 WDP_LOGD("Succeeded to set persistent reconnect");
6129
6130         __WDP_LOG_FUNC_EXIT__;
6131         return res;
6132 }
6133
6134 static int __ws_compress_query(char *compressed, char *query, int qtype)
6135 {
6136         char *token = NULL;
6137         char *temp = NULL;
6138         int token_num = 0;
6139         int token_len = 0;
6140         int length = 0;
6141
6142         token = strtok_r(query, ".", &temp);
6143         while (token) {
6144                 if (!strcmp(token, "local")) {
6145                         WDP_LOGD("Query conversion done");
6146                         break;
6147
6148                 } else if (!strncmp(token, "_tcp", 4)) {
6149                         memcpy(&compressed[length], WS_TCP_PTR_HEX, 2);
6150                         length += 2;
6151
6152                 } else if (!strncmp(token, "_udp", 4)) {
6153                         memcpy(&compressed[length], WS_UDP_PTR_HEX, 2);
6154                         length += 2;
6155
6156                 } else {
6157                         WDP_LOGD("Token: [%s]", token);
6158                         token_len = strlen(token);
6159                         compressed[length] = token_len;
6160                         length++;
6161
6162                         memcpy(&compressed[length], token, token_len);
6163                         length += token_len;
6164                 }
6165                 token_num++;
6166                 token = strtok_r(NULL, ".", &temp);
6167         }
6168         if (qtype == WS_QTYPE_PTR || token_num == 2)
6169                 memcpy(&compressed[length], WS_PTR_TYPE_HEX, 3);
6170         else if (qtype == WS_QTYPE_TXT || token_num == 3)
6171                 memcpy(&compressed[length], WS_TXT_TYPE_HEX, 3);
6172
6173         length += 3;
6174         WDP_LOGD("converted query length [%d] token num [%d]", length, token_num);
6175
6176         return length;
6177 }
6178
6179 static int __ws_compress_rdata(char *compressed, char *rdata, int qtype)
6180 {
6181         char *token = NULL;
6182         char *temp = NULL;
6183         int token_len = 0;
6184         int length = 0;
6185
6186         if (qtype == WS_QTYPE_PTR) {
6187
6188                 token = strtok_r(rdata, ".", &temp);
6189                 if (token) {
6190                         WDP_LOGD("Token: %s", token);
6191                         token_len = strlen(token);
6192                         compressed[length] = token_len;
6193                         length++;
6194
6195                         memcpy(&compressed[length], token, token_len);
6196                         length += token_len;
6197                 }
6198
6199                 compressed[length] = 0xc0;
6200                 compressed[length+1] = 0x27;
6201                 length += 2;
6202
6203         } else if (qtype == WS_QTYPE_TXT) {
6204
6205                 token = strtok_r(rdata, ",", &temp);
6206
6207                 while (token) {
6208                         WDP_LOGD("Token: [%s]", token);
6209
6210                         token_len = strlen(token);
6211                         compressed[length] = token_len;
6212                         length++;
6213
6214                         memcpy(&compressed[length], token, token_len);
6215                         length += token_len;
6216
6217                         token = strtok_r(NULL, ",", &temp);
6218                 }
6219         } else {
6220                 WDP_LOGD("RDATA is NULL");
6221         }
6222         return length;
6223 }
6224
6225 int _convert_bonjour_to_args(char *query, char *rdata, GVariantBuilder *builder)
6226 {
6227         GVariantBuilder *args = NULL;
6228         char compressed[256] = {0, };
6229         char *temp = NULL;
6230         int length = 0;
6231         int qtype = 0;
6232         int i = 0;
6233
6234         if (!query || !builder) {
6235                 WDP_LOGE("Invalid parameter");
6236                 return -1;
6237         }
6238         if (!rdata || !strlen(rdata)) {
6239                 WDP_LOGD("RDATA is NULL\n");
6240         } else {
6241                 temp = strstr(rdata, query);
6242
6243                 if (temp != NULL && temp - rdata > 0)
6244                         qtype = WS_QTYPE_PTR;
6245                 else
6246                         qtype = WS_QTYPE_TXT;
6247                 temp = NULL;
6248         }
6249
6250         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("bonjour"));
6251
6252         /* compress query */
6253         length = __ws_compress_query(compressed, query, qtype);
6254
6255         args = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6256         for (i = 0; i < length; i++)
6257                 g_variant_builder_add(args, "y", compressed[i]);
6258         g_variant_builder_add(builder, "{sv}", "query", g_variant_new("ay", args));
6259         g_variant_builder_unref(args);
6260
6261         memset(compressed, 0x0, 256);
6262         length = 0;
6263         args = NULL;
6264
6265         if (qtype != 0) {
6266                 length = __ws_compress_rdata(compressed, rdata, qtype);
6267
6268                 args = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6269                 for (i = 0; i < length; i++)
6270                         g_variant_builder_add(args, "y", compressed[i]);
6271                 g_variant_builder_add(builder, "{sv}", "response", g_variant_new("ay", args));
6272                 g_variant_builder_unref(args);
6273         }
6274
6275         return 0;
6276 }
6277
6278 int _check_service_query_exists(wfd_oem_service_s *service)
6279 {
6280         int count = 0;
6281         wfd_oem_service_s *data = NULL;
6282
6283         for (count = 0; count < g_list_length(service_list); count++) {
6284                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
6285                 if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
6286                         WDP_LOGD("Query already exists");
6287                         return 1;
6288                 }
6289         }
6290         return 0;
6291 }
6292
6293 static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
6294 {
6295         if (NULL == s_type || NULL == mac_str || NULL == query_id)
6296                 return NULL;
6297
6298         int count = 0;
6299         wfd_oem_service_s *data = NULL;
6300
6301         for (count = 0; count < g_list_length(service_list); count++) {
6302                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
6303                 if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
6304                                 memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
6305                         g_strlcpy(query_id, data->query_id, OEM_QUERY_ID_LEN + 1);
6306                         break;
6307                 }
6308         }
6309         if (strlen(query_id) <= 0) {
6310                 WDP_LOGD("!! Query ID not found !!");
6311                 return NULL;
6312         }
6313
6314         WDP_LOGD("query id :[%s]", query_id);
6315
6316         return data;
6317 }
6318
6319 void __add_service_query(GVariant *value, void *user_data)
6320 {
6321         __WDP_LOG_FUNC_ENTER__;
6322         wfd_oem_service_s *service = NULL;
6323
6324         long long unsigned ref = 0;
6325         int res = 0;
6326
6327         if (!user_data)
6328                 return;
6329
6330         g_variant_get(value, "(t)", &ref);
6331
6332         service = (wfd_oem_service_s*) g_try_malloc0(sizeof(wfd_oem_service_s));
6333         if (!service) {
6334                 WDP_LOGE("Failed to allocate memory for service");
6335                 return;
6336         }
6337
6338         memcpy(service, user_data, sizeof(wfd_oem_service_s));
6339
6340         g_snprintf(service->query_id, OEM_QUERY_ID_LEN + 1, "%llx", ref);
6341
6342         res = _check_service_query_exists(service);
6343         if (res)
6344                 g_free(service);
6345         else
6346                 service_list = g_list_append(service_list, service);
6347
6348         __WDP_LOG_FUNC_EXIT__;
6349         return;
6350
6351 }
6352
6353 /* for now, supplicant dbus interface only provides upnp service fully */
6354 int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
6355 {
6356         __WDP_LOG_FUNC_ENTER__;
6357         GDBusConnection *g_dbus = NULL;
6358         GVariantBuilder *builder = NULL;
6359         GVariant *value = NULL;
6360         wfd_oem_service_s data = {0,};
6361         dbus_method_param_s params;
6362         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
6363         int i = 0;
6364         int res = 0;
6365
6366         if (!mac_addr) {
6367                 WDP_LOGE("Invalid parameter");
6368                 __WDP_LOG_FUNC_EXIT__;
6369                 return -1;
6370         }
6371
6372         if (!g_pd) {
6373                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6374                 __WDP_LOG_FUNC_EXIT__;
6375                 return -1;
6376         }
6377
6378         g_dbus = g_pd->g_dbus;
6379         if (!g_dbus) {
6380                 WDP_LOGE("DBus connection is NULL");
6381                 __WDP_LOG_FUNC_EXIT__;
6382                 return -1;
6383         }
6384         memset(&params, 0x0, sizeof(dbus_method_param_s));
6385
6386         dbus_set_method_param(&params, "ServiceDiscoveryRequest", g_pd->iface_path, g_dbus);
6387
6388         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6389
6390         if (mac_addr && !ISZEROMACADDR(mac_addr)) {
6391                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
6392                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(mac_addr));
6393                 WDP_LOGD("get peer path [%s]", peer_path);
6394                 g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
6395         }
6396
6397         if (service_type == WFD_OEM_SERVICE_TYPE_ALL) {
6398
6399                 char *service_all = "\x02\x00\x00\x01";
6400                 GVariantBuilder *query = NULL;
6401
6402                 query = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6403                 for (i = 0; i < SERVICE_QUERY_LEN; i++)
6404                         g_variant_builder_add(query, "y", service_all[i]);
6405                 g_variant_builder_add(builder, "{sv}", "query", g_variant_new("ay", query));
6406                 g_variant_builder_unref(query);
6407                 g_strlcpy(data.service_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
6408
6409         } else if (service_type == WFD_OEM_SERVICE_TYPE_UPNP) {
6410
6411                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6412                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6413                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string("ssdp:all"));
6414                 g_strlcpy(data.service_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
6415
6416         } else if (service_type == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6417
6418                 char *service_bonjour = "\x02\x00\x01\x01";
6419                 GVariantBuilder *query = NULL;
6420
6421                 query = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6422                 for (i = 0; i < SERVICE_QUERY_LEN; i++)
6423                         g_variant_builder_add(query, "y", service_bonjour[i]);
6424                 g_variant_builder_add(builder, "{sv}", "tlv", g_variant_new("ay", query));
6425                 g_variant_builder_unref(query);
6426                 g_strlcpy(data.service_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
6427         }
6428
6429         value = g_variant_new("(a{sv})", builder);
6430         g_variant_builder_unref(builder);
6431
6432         params.params = value;
6433         DEBUG_G_VARIANT("Params : ", params.params);
6434
6435         if (ISZEROMACADDR(mac_addr))
6436                 snprintf(data.dev_addr, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
6437         else
6438                 snprintf(data.dev_addr, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
6439
6440         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, __add_service_query, &data);
6441         if (res < 0)
6442                 WDP_LOGE("Failed to send command to wpa_supplicant");
6443         else
6444                 WDP_LOGD("Succeeded to start service discovery");
6445
6446         __WDP_LOG_FUNC_EXIT__;
6447         return res;
6448 }
6449
6450 int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
6451 {
6452         __WDP_LOG_FUNC_ENTER__;
6453         GDBusConnection *g_dbus = NULL;
6454         dbus_method_param_s params;
6455         wfd_oem_service_s *data = NULL;
6456         char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
6457         char s_type[OEM_SERVICE_TYPE_LEN + 1] = {0, };
6458         char mac_str[18] = {0, };
6459         long long unsigned id;
6460
6461         int res = 0;
6462
6463         if (!mac_addr) {
6464                 WDP_LOGE("Invalid parameter");
6465                 __WDP_LOG_FUNC_EXIT__;
6466                 return -1;
6467         }
6468
6469         if (!g_pd) {
6470                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6471                 __WDP_LOG_FUNC_EXIT__;
6472                 return -1;
6473         }
6474
6475         g_dbus = g_pd->g_dbus;
6476         if (!g_dbus) {
6477                 WDP_LOGE("DBus connection is NULL");
6478                 __WDP_LOG_FUNC_EXIT__;
6479                 return -1;
6480         }
6481
6482         if (ISZEROMACADDR(mac_addr)) {
6483                 snprintf(mac_str, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
6484         } else {
6485                 snprintf(mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
6486         }
6487
6488         switch (service_type) {
6489         case WFD_OEM_SERVICE_TYPE_ALL:
6490                 g_strlcpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
6491         break;
6492         case WFD_OEM_SERVICE_TYPE_BONJOUR:
6493                 g_strlcpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
6494         break;
6495         case WFD_OEM_SERVICE_TYPE_UPNP:
6496                 g_strlcpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
6497         break;
6498         default:
6499                 WDP_LOGE("Invalid Service type");
6500                 __WDP_LOG_FUNC_EXIT__;
6501                 return -1;
6502         }
6503
6504         WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
6505         WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
6506
6507         data = _remove_service_query(s_type, mac_str, query_id);
6508         if (NULL == data) {
6509                 __WDP_LOG_FUNC_EXIT__;
6510                 return -1;
6511         }
6512         memset(&params, 0x0, sizeof(dbus_method_param_s));
6513
6514         dbus_set_method_param(&params, "ServiceDiscoveryCancelRequest", g_pd->iface_path, g_dbus);
6515         id = (long long unsigned)strtoul(query_id, NULL, 16);
6516         params.params = g_variant_new("(t)", id);
6517
6518         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6519         if (res < 0)
6520                 WDP_LOGE("Failed to send command to wpa_supplicant");
6521         else
6522                 WDP_LOGD("Succeeded to cancel service discovery");
6523
6524         service_list = g_list_remove(service_list, data);
6525         free(data);
6526
6527         __WDP_LOG_FUNC_EXIT__;
6528         return res;
6529 }
6530
6531 int ws_serv_add(wfd_oem_new_service_s *service)
6532 {
6533         __WDP_LOG_FUNC_ENTER__;
6534         GDBusConnection *g_dbus = NULL;
6535         GVariantBuilder *builder = NULL;
6536         GVariant *value = NULL;
6537         dbus_method_param_s params;
6538         int res = 0;
6539
6540         if (!g_pd) {
6541                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6542                 __WDP_LOG_FUNC_EXIT__;
6543                 return -1;
6544         }
6545
6546         g_dbus = g_pd->g_dbus;
6547         if (!g_dbus) {
6548                 WDP_LOGE("DBus connection is NULL");
6549                 __WDP_LOG_FUNC_EXIT__;
6550                 return -1;
6551         }
6552         memset(&params, 0x0, sizeof(dbus_method_param_s));
6553
6554         dbus_set_method_param(&params, "AddService", g_pd->iface_path, g_dbus);
6555
6556         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6557
6558         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6559
6560                 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
6561                 WDP_LOGD("Query: %s", service->data.bonjour.query);
6562                 WDP_LOGD("RData: %s", service->data.bonjour.rdata);
6563
6564                 res = _convert_bonjour_to_args(service->data.bonjour.query,
6565                                                             service->data.bonjour.rdata, builder);
6566                 if (res < 0) {
6567                         WDP_LOGE("Failed to convert Key string");
6568                         g_variant_builder_unref(builder);
6569                         return -1;
6570                 }
6571
6572         } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
6573                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6574                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6575                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
6576         }
6577
6578         value = g_variant_new("(a{sv})", builder);
6579         g_variant_builder_unref(builder);
6580
6581         params.params = value;
6582         DEBUG_G_VARIANT("Params : ", params.params);
6583
6584         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6585         if (res < 0)
6586                 WDP_LOGE("Failed to send command to wpa_supplicant");
6587         else
6588                 WDP_LOGD("Succeeded to add service");
6589
6590         __WDP_LOG_FUNC_EXIT__;
6591         return 0;
6592 }
6593
6594 int ws_serv_del(wfd_oem_new_service_s *service)
6595 {
6596         __WDP_LOG_FUNC_ENTER__;
6597         GDBusConnection *g_dbus = NULL;
6598         GVariantBuilder *builder = NULL;
6599         GVariant *value = NULL;
6600         dbus_method_param_s params;
6601         int res = 0;
6602
6603         if (!g_pd) {
6604                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6605                 __WDP_LOG_FUNC_EXIT__;
6606                 return -1;
6607         }
6608
6609         g_dbus = g_pd->g_dbus;
6610         if (!g_dbus) {
6611                 WDP_LOGE("DBus connection is NULL");
6612                 __WDP_LOG_FUNC_EXIT__;
6613                 return -1;
6614         }
6615         memset(&params, 0x0, sizeof(dbus_method_param_s));
6616
6617         dbus_set_method_param(&params, "DeleteService", g_pd->iface_path, g_dbus);
6618
6619         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6620
6621         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6622
6623                 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
6624                 WDP_LOGD("Query: %s", service->data.bonjour.query);
6625
6626                 res = _convert_bonjour_to_args(service->data.bonjour.query,
6627                                                             NULL, builder);
6628                 if (res < 0) {
6629                         WDP_LOGE("Failed to convert Key string");
6630                         g_variant_builder_unref(builder);
6631                         return -1;
6632                 }
6633
6634         } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
6635                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6636                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6637                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
6638         }
6639
6640         value = g_variant_new("(a{sv})", builder);
6641         g_variant_builder_unref(builder);
6642
6643         params.params = value;
6644         DEBUG_G_VARIANT("Params : ", params.params);
6645
6646         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6647         if (res < 0)
6648                 WDP_LOGE("Failed to send command to wpa_supplicant");
6649         else
6650                 WDP_LOGD("Succeeded to del service");
6651
6652         __WDP_LOG_FUNC_EXIT__;
6653         return 0;
6654 }
6655
6656 int _ws_disable_display()
6657 {
6658         __WDP_LOG_FUNC_ENTER__;
6659         GDBusConnection *g_dbus = NULL;
6660         GVariantBuilder *builder = NULL;
6661         GVariant *value = NULL;
6662         GVariant *param = NULL;
6663         dbus_method_param_s params;
6664         int res = 0;
6665
6666         if (!g_pd) {
6667                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6668                 __WDP_LOG_FUNC_EXIT__;
6669                 return -1;
6670         }
6671
6672         g_dbus = g_pd->g_dbus;
6673         if (!g_dbus) {
6674                 WDP_LOGE("DBus connection is NULL");
6675                 __WDP_LOG_FUNC_EXIT__;
6676                 return -1;
6677         }
6678         memset(&params, 0x0, sizeof(dbus_method_param_s));
6679
6680         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
6681                          g_dbus);
6682
6683         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6684         value = g_variant_new("ay", builder);
6685         g_variant_builder_unref(builder);
6686
6687         param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
6688
6689         params.params = param;
6690         DEBUG_G_VARIANT("Params : ", params.params);
6691
6692         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6693         if (res < 0)
6694                 WDP_LOGE("Failed to send command to wpa_supplicant");
6695         else
6696                 WDP_LOGD("Succeeded to disable Wi-Fi display");
6697
6698         __WDP_LOG_FUNC_EXIT__;
6699         return res;
6700 }
6701
6702 int ws_miracast_init(int enable)
6703 {
6704         __WDP_LOG_FUNC_ENTER__;
6705         wfd_oem_display_s wifi_display;
6706         int res = 0;
6707
6708         memset(&wifi_display, 0x0, sizeof(wfd_oem_display_s));
6709
6710         wifi_display.availability = enable;
6711         wifi_display.hdcp_support = 1;
6712         wifi_display.port = 0x07E6;
6713         wifi_display.max_tput = 0x0028;
6714
6715         res = ws_set_display(&wifi_display);
6716         if (res < 0) {
6717                 WDP_LOGE("Failed to set miracast parameter(device info)");
6718                 __WDP_LOG_FUNC_EXIT__;
6719                 return -1;
6720         }
6721
6722         if (!enable) {
6723                 res = _ws_disable_display();
6724                 if (res < 0)
6725                         WDP_LOGE("Failed to disable wifi display");
6726                 else
6727                         WDP_LOGD("Succeeded to disable wifi display");
6728         }
6729         __WDP_LOG_FUNC_EXIT__;
6730         return res;
6731 }
6732
6733 int ws_set_display(wfd_oem_display_s *wifi_display)
6734 {
6735         __WDP_LOG_FUNC_ENTER__;
6736         GDBusConnection *g_dbus = NULL;
6737
6738         GVariant *value = NULL;
6739         GVariant *param = NULL;
6740         GVariantBuilder *builder = NULL;
6741         dbus_method_param_s params;
6742         int i = 0;
6743         int res = 0;
6744
6745         unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
6746
6747         if (!wifi_display) {
6748                 WDP_LOGE("Invalid parameter");
6749                 return -1;
6750         }
6751         g_dbus = g_pd->g_dbus;
6752         if (!g_dbus) {
6753                 WDP_LOGE("DBus connection is NULL");
6754                 __WDP_LOG_FUNC_EXIT__;
6755                 return -1;
6756         }
6757         memset(&params, 0x0, sizeof(dbus_method_param_s));
6758
6759         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
6760                          g_dbus);
6761
6762         ies[2] = WFD_SUBELEM_LEN_DEV_INFO;
6763         ies[3] = wifi_display->hdcp_support;
6764         ies[4] = (wifi_display->type) | (wifi_display->availability<<4);
6765         ies[5] = wifi_display->port>>8;
6766         ies[6] = wifi_display->port&0xff;
6767         ies[7] = wifi_display->max_tput>>8;
6768         ies[8] = wifi_display->max_tput&0xff;
6769
6770         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6771         for (i = 0; i < WFD_SUBELEM_LEN_DEV_INFO + 3; i++)
6772                 g_variant_builder_add(builder, "y", ies[i]);
6773         value = g_variant_new("ay", builder);
6774         g_variant_builder_unref(builder);
6775
6776         param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
6777
6778         params.params = param;
6779         DEBUG_G_VARIANT("Params : ", params.params);
6780
6781         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6782         if (res < 0)
6783                 WDP_LOGE("Failed to send command to wpa_supplicant");
6784         else
6785                 WDP_LOGD("Succeeded to set Wi-Fi Display");
6786
6787         __WDP_LOG_FUNC_EXIT__;
6788         return res;
6789 }
6790
6791 int ws_refresh(void)
6792 {
6793         __WDP_LOG_FUNC_ENTER__;
6794
6795         _ws_cancel();
6796         _ws_flush();
6797
6798         __WDP_LOG_FUNC_EXIT__;
6799         return 0;
6800 }
6801
6802 int ws_save_config(void)
6803 {
6804         __WDP_LOG_FUNC_ENTER__;
6805         GDBusConnection *g_dbus = NULL;
6806         dbus_method_param_s params;
6807         int res = 0;
6808
6809         g_dbus = g_pd->g_dbus;
6810         if (!g_dbus) {
6811                 WDP_LOGE("DBus connection is NULL");
6812                 __WDP_LOG_FUNC_EXIT__;
6813                 return -1;
6814         }
6815         memset(&params, 0x0, sizeof(dbus_method_param_s));
6816
6817         dbus_set_method_param(&params, "SaveConfig", g_pd->iface_path, g_dbus);
6818         params.params = NULL;
6819
6820         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
6821         if (res < 0)
6822                 WDP_LOGE("Failed to save config to wpa_supplicant");
6823         else
6824                 WDP_LOGD("Succeeded to save config");
6825
6826         __WDP_LOG_FUNC_EXIT__;
6827         return res;
6828 }
6829
6830 int ws_set_operating_channel(int channel)
6831 {
6832         __WDP_LOG_FUNC_ENTER__;
6833         GDBusConnection *g_dbus = NULL;
6834         GVariant *value = NULL;
6835         GVariant *param = NULL;
6836         GVariantBuilder *builder = NULL;
6837         dbus_method_param_s params;
6838         int res = 0;
6839
6840         g_dbus = g_pd->g_dbus;
6841         if (!g_dbus) {
6842                 WDP_LOGE("DBus connection is NULL");
6843                 __WDP_LOG_FUNC_EXIT__;
6844                 return -1;
6845         }
6846
6847         memset(&params, 0x0, sizeof(dbus_method_param_s));
6848
6849         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path, g_dbus);
6850
6851         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6852         g_variant_builder_add(builder, "{sv}", "OperChannel", g_variant_new_uint32(channel));
6853         value = g_variant_new("a{sv}", builder);
6854         g_variant_builder_unref(builder);
6855
6856         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
6857         params.params = param;
6858
6859         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6860         if (res < 0)
6861                 WDP_LOGE("Failed to send command to wpa_supplicant");
6862         else
6863                 WDP_LOGD("Succeeded to set Operating Channel");
6864
6865         __WDP_LOG_FUNC_EXIT__;
6866         return res;
6867 }
6868
6869 int ws_remove_all_network(void)
6870 {
6871         __WDP_LOG_FUNC_ENTER__;
6872         GDBusConnection *g_dbus = NULL;
6873         dbus_method_param_s params;
6874         int res = 0;
6875
6876         g_dbus = g_pd->g_dbus;
6877         if (!g_dbus) {
6878                 WDP_LOGE("DBus connection is NULL");
6879                 __WDP_LOG_FUNC_EXIT__;
6880                 return -1;
6881         }
6882         memset(&params, 0x0, sizeof(dbus_method_param_s));
6883
6884         dbus_set_method_param(&params, "RemoveAllNetworks", g_pd->iface_path, g_dbus);
6885         params.params = NULL;
6886
6887         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
6888         if (res < 0)
6889                 WDP_LOGE("Failed to send [RemoveAllNetworks] command to wpa_supplicant");
6890         else
6891                 WDP_LOGD("Succeeded to remove all networks from supplicant");
6892
6893         WDP_LOGD("Succeeded to remove all network");
6894         __WDP_LOG_FUNC_EXIT__;
6895         return res;
6896 }
6897
6898 int ws_get_wpa_status(int *wpa_status)
6899 {
6900         __WDP_LOG_FUNC_ENTER__;
6901         GDBusConnection *g_dbus = NULL;
6902         GVariant *param = NULL;
6903         GVariant *reply = NULL;
6904         GError *error = NULL;
6905
6906         if (!wpa_status) {
6907                 WDP_LOGE("Invalid parameter");
6908                 __WDP_LOG_FUNC_EXIT__;
6909                 return -1;
6910         }
6911
6912         *wpa_status = WFD_OEM_WPA_STATE_MAX;
6913
6914         g_dbus = g_pd->g_dbus;
6915         if (!g_dbus) {
6916                 WDP_LOGE("DBus connection is NULL");
6917                 __WDP_LOG_FUNC_EXIT__;
6918                 return -1;
6919         }
6920
6921         param = g_variant_new("(s)", SUPPLICANT_IFACE);
6922
6923         reply = g_dbus_connection_call_sync(
6924                         g_pd->g_dbus,
6925                         SUPPLICANT_SERVICE, /* bus name */
6926                         g_pd->iface_path, /* object path */
6927                         DBUS_PROPERTIES_INTERFACE, /* interface name */
6928                         DBUS_PROPERTIES_METHOD_GETALL, /* method name */
6929                         param, /* GVariant *params */
6930                         NULL, /* reply_type */
6931                         G_DBUS_CALL_FLAGS_NONE, /* flags */
6932                         SUPPLICANT_TIMEOUT , /* timeout */
6933                         NULL, /* cancellable */
6934                         &error); /* error */
6935
6936         if (error != NULL) {
6937                 WDP_LOGE("Error! Failed to get properties: [%s]",
6938                                                         error->message);
6939                 g_error_free(error);
6940                 if (reply)
6941                         g_variant_unref(reply);
6942                 __WDP_LOG_FUNC_EXIT__;
6943                 return -1;
6944         }
6945
6946         gchar *reply_str = NULL;
6947         if (reply)
6948                 reply_str = g_variant_print(reply, TRUE);
6949         WDP_LOGE("reply [%s]", reply_str ? reply_str : "NULL");
6950         g_free(reply_str);
6951
6952         if (reply != NULL) {
6953                 GVariantIter *iter = NULL;
6954                 g_variant_get(reply, "(a{sv})", &iter);
6955
6956                 if (iter != NULL) {
6957                         gchar *key = NULL;
6958                         GVariant *value = NULL;
6959
6960                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
6961                                 if (g_strcmp0(key, "State") == 0) {
6962                                         const gchar *state = NULL;
6963                                         g_variant_get(value, "&s", &state);
6964                                         WDP_LOGI("state : [%s]", state);
6965
6966                                         if (g_strcmp0(state, "disconnected") == 0)
6967                                                 *wpa_status = WFD_OEM_WPA_STATE_DISCONNECTED;
6968                                         else if (g_strcmp0(state, "inactive") == 0)
6969                                                 *wpa_status = WFD_OEM_WPA_STATE_INACTIVE;
6970                                         else if (g_strcmp0(state, "scanning") == 0)
6971                                                 *wpa_status = WFD_OEM_WPA_STATE_SCANNING;
6972                                         else if (g_strcmp0(state, "authenticating") == 0)
6973                                                 *wpa_status = WFD_OEM_WPA_STATE_AUTHENTICATING;
6974                                         else if (g_strcmp0(state, "associating") == 0)
6975                                                 *wpa_status = WFD_OEM_WPA_STATE_ASSOCIATING;
6976                                         else if (g_strcmp0(state, "associated") == 0)
6977                                                 *wpa_status = WFD_OEM_WPA_STATE_ASSOCIATED;
6978                                         else if (g_strcmp0(state, "4way_handshake") == 0)
6979                                                 *wpa_status = WFD_OEM_WPA_STATE_4WAY_HANDSHAKE;
6980                                         else if (g_strcmp0(state, "group_handshake") == 0)
6981                                                 *wpa_status = WFD_OEM_WPA_STATE_GROUP_HANDSHAKE;
6982                                         else if (g_strcmp0(state, "completed") == 0)
6983                                                 *wpa_status = WFD_OEM_WPA_STATE_COMPLETED;
6984                                         else
6985                                                 *wpa_status = WFD_OEM_WPA_STATE_MAX;
6986                                 }
6987                         }
6988                         g_variant_iter_free(iter);
6989                 }
6990                 g_variant_unref(reply);
6991         } else {
6992                 WDP_LOGD("No properties");
6993         }
6994
6995         WDP_LOGI("wpa_status : [%d]", *wpa_status);
6996
6997         __WDP_LOG_FUNC_EXIT__;
6998         return 0;
6999 }
7000
7001 int ws_advertise_service(wfd_oem_asp_service_s *service, int replace)
7002 {
7003         __WDP_LOG_FUNC_ENTER__;
7004         GDBusConnection *g_dbus = NULL;
7005         GVariantBuilder *builder = NULL;
7006         GVariant *value = NULL;
7007         dbus_method_param_s params;
7008         unsigned int config_method = 0x1108;
7009         int auto_accept = 0;
7010         gboolean rep;
7011         int res = 0;
7012
7013         g_dbus = g_pd->g_dbus;
7014         if (!g_dbus) {
7015                 WDP_LOGE("DBus connection is NULL");
7016                 return -1;
7017         }
7018
7019         if (service->config_method == 2) {
7020                 config_method = WS_CONFIG_METHOD_KEYPAD |
7021                                 WS_CONFIG_METHOD_DISPLAY;
7022         } else if (service->config_method == 3) {
7023                 config_method = WS_CONFIG_METHOD_DISPLAY;
7024         } else if (service->config_method == 4) {
7025                 config_method = WS_CONFIG_METHOD_KEYPAD;
7026         }
7027
7028         if (service->auto_accept) {
7029                 if (service->role == 0)
7030                         auto_accept = 1;
7031                 else
7032                         auto_accept = 2;
7033         } else {
7034                 auto_accept = 0;
7035         }
7036
7037         rep = (replace == 1);
7038
7039         memset(&params, 0x0, sizeof(dbus_method_param_s));
7040
7041         dbus_set_method_param(&params, "AddService", g_pd->iface_path, g_dbus);
7042
7043         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7044
7045         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("asp"));
7046         g_variant_builder_add(builder, "{sv}", "auto_accept", g_variant_new_int32(auto_accept));
7047         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(service->adv_id));
7048         g_variant_builder_add(builder, "{sv}", "svc_state", g_variant_new_uint32(service->status));
7049         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new_uint32(config_method));
7050         g_variant_builder_add(builder, "{sv}", "replace", g_variant_new_boolean(rep));
7051         if (service->service_type != NULL)
7052                 g_variant_builder_add(builder, "{sv}", "adv_str",
7053                         g_variant_new_string(service->service_type));
7054         if (service->service_info != NULL)
7055                 g_variant_builder_add(builder, "{sv}", "svc_info",
7056                                 g_variant_new_string(service->service_info));
7057         if (service->instance_name != NULL)
7058                 g_variant_builder_add(builder, "{sv}", "svc_instance",
7059                                 g_variant_new_string(service->instance_name));
7060
7061         value = g_variant_new("(a{sv})", builder);
7062         g_variant_builder_unref(builder);
7063         DEBUG_G_VARIANT("Params : ", value);
7064
7065         params.params = value;
7066
7067         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7068         if (res < 0)
7069                 WDP_LOGE("Failed to send command to wpa_supplicant");
7070         else
7071                 WDP_LOGD("Succeeded to add service");
7072
7073         __WDP_LOG_FUNC_EXIT__;
7074         return 0;
7075 }
7076
7077 int ws_cancel_advertise_service(wfd_oem_asp_service_s *service)
7078 {
7079         __WDP_LOG_FUNC_ENTER__;
7080         GDBusConnection *g_dbus = NULL;
7081         GVariantBuilder *builder = NULL;
7082         GVariant *value = NULL;
7083         dbus_method_param_s params;
7084         int res = 0;
7085
7086         g_dbus = g_pd->g_dbus;
7087         if (!g_dbus) {
7088                 WDP_LOGE("DBus connection is NULL");
7089                 return -1;
7090         }
7091         memset(&params, 0x0, sizeof(dbus_method_param_s));
7092
7093         dbus_set_method_param(&params, "DeleteService", g_pd->iface_path, g_dbus);
7094
7095         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7096
7097         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("asp"));
7098         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(service->adv_id));
7099
7100         value = g_variant_new("(a{sv})", builder);
7101         g_variant_builder_unref(builder);
7102         DEBUG_G_VARIANT("Params : ", value);
7103         params.params = value;
7104
7105         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7106         if (res < 0)
7107                 WDP_LOGE("Failed to send command to wpa_supplicant");
7108         else
7109                 WDP_LOGD("Succeeded to del service");
7110
7111         __WDP_LOG_FUNC_EXIT__;
7112         return 0;
7113 }
7114
7115 static void __ws_add_seek(wfd_oem_asp_service_s *service)
7116 {
7117         __WDP_LOG_FUNC_ENTER__;
7118         wfd_oem_asp_service_s *seek = NULL;
7119         if (!service) {
7120                 WDP_LOGE("invalid parameters");
7121                 return;
7122         }
7123
7124         seek = g_try_malloc0(sizeof(wfd_oem_asp_service_s));
7125         if (!seek) {
7126                 WDP_LOGE("Failed to allocate memory for service");
7127                 return;
7128         }
7129
7130         service->search_id = (intptr_t)seek;
7131         memcpy(seek, service, sizeof(wfd_oem_asp_service_s));
7132         if (service->service_type)
7133                 seek->service_type = strdup(service->service_type);
7134         seek_list = g_list_prepend(seek_list, seek);
7135
7136         __WDP_LOG_FUNC_EXIT__;
7137         return;
7138 }
7139
7140 static wfd_oem_asp_service_s * __ws_get_seek(long long unsigned asp_search_id)
7141 {
7142         __WDP_LOG_FUNC_ENTER__;
7143         wfd_oem_asp_service_s *seek = NULL;
7144         GList *list = NULL;
7145
7146         for (list = seek_list; list != NULL; list = list->next) {
7147                 seek = list->data;
7148                 if (seek && (seek->asp_search_id == asp_search_id)) {
7149                         WDP_LOGD("List found");
7150                         break;
7151                 } else {
7152                         seek = NULL;
7153                 }
7154         }
7155         __WDP_LOG_FUNC_EXIT__;
7156         return seek;
7157 }
7158
7159 static void __ws_remove_seek(wfd_oem_asp_service_s *service)
7160 {
7161         __WDP_LOG_FUNC_ENTER__;
7162         wfd_oem_asp_service_s *seek = NULL;
7163         GList *list = NULL;
7164
7165         for (list = seek_list; list != NULL; list = list->next) {
7166
7167                 seek = list->data;
7168                 if (seek && (seek->asp_search_id == service->asp_search_id)) {
7169                         WDP_LOGD("List remove");
7170                         seek_list = g_list_remove(seek_list, seek);
7171                         g_free(seek->service_type);
7172                         g_free(seek->service_info);
7173                         g_free(seek);
7174                 }
7175         }
7176         __WDP_LOG_FUNC_EXIT__;
7177         return;
7178 }
7179
7180 static void __get_asp_search_id(GVariant *value, void *args)
7181 {
7182         __WDP_LOG_FUNC_ENTER__;
7183         wfd_oem_asp_service_s *service = NULL;
7184         wfd_oem_asp_service_s *seek = NULL;
7185         long long unsigned search_id = 0;
7186
7187         g_variant_get(value, "(t)", &search_id);
7188
7189         service = (wfd_oem_asp_service_s *)args;
7190         if (!service) {
7191                 WDP_LOGE("invalid parameters");
7192                 __WDP_LOG_FUNC_EXIT__;
7193                 return;
7194         }
7195
7196         seek = g_try_malloc0(sizeof(wfd_oem_asp_service_s));
7197         if (!seek) {
7198                 WDP_LOGE("Failed to allocate memory for service");
7199                 __WDP_LOG_FUNC_EXIT__;
7200                 return;
7201         }
7202
7203         service->search_id = search_id;
7204         memcpy(seek, service, sizeof(wfd_oem_asp_service_s));
7205         if (service->service_type)
7206                 seek->service_type = strdup(service->service_type);
7207         if (service->service_info)
7208                 seek->service_info = strdup(service->service_info);
7209         seek_list = g_list_append(seek_list, seek);
7210
7211         __WDP_LOG_FUNC_EXIT__;
7212         return;
7213 }
7214
7215 int ws_seek_service(wfd_oem_asp_service_s *service)
7216 {
7217         __WDP_LOG_FUNC_ENTER__;
7218         GDBusConnection *g_dbus = NULL;
7219         GList *list = NULL;
7220         wfd_oem_asp_service_s *seek = NULL;
7221         int res = 0;
7222
7223         g_dbus = g_pd->g_dbus;
7224         if (!g_dbus) {
7225                 WDP_LOGE("DBus connection is NULL");
7226                 __WDP_LOG_FUNC_EXIT__;
7227                 return -1;
7228         }
7229         list = g_list_last(seek_list);
7230         if (list == NULL) {
7231                 service->tran_id = 1;
7232
7233         } else {
7234                 seek = list->data;
7235                 if (seek)
7236                         service->tran_id = seek->tran_id + 1;
7237                 else
7238                         service->tran_id = 1;
7239         }
7240
7241         if (service->service_info) {
7242                 GVariantBuilder *builder = NULL;
7243                 GVariant *value = NULL;
7244                 dbus_method_param_s params;
7245
7246                 memset(&params, 0x0, sizeof(dbus_method_param_s));
7247                 dbus_set_method_param(&params, "ServiceDiscoveryRequest",
7248                                 g_pd->iface_path, g_dbus);
7249
7250                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7251
7252                 g_variant_builder_add(builder, "{sv}", "service_type",
7253                                 g_variant_new_string("asp"));
7254                 g_variant_builder_add(builder, "{sv}", "transaction_id",
7255                                 g_variant_new_byte(service->tran_id));
7256                 if (service->service_type != NULL)
7257                         g_variant_builder_add(builder, "{sv}", "svc_str",
7258                                         g_variant_new_string(service->service_type));
7259
7260                 if (service->service_info != NULL)
7261                         g_variant_builder_add(builder, "{sv}", "svc_info",
7262                                         g_variant_new_string(service->service_info));
7263
7264                 if (service->instance_name != NULL)
7265                         g_variant_builder_add(builder, "{sv}", "svc_instance",
7266                                         g_variant_new_string(service->instance_name));
7267
7268                 value = g_variant_new("(a{sv})", builder);
7269                 g_variant_builder_unref(builder);
7270
7271                 DEBUG_G_VARIANT("Params : ", value);
7272
7273                 params.params = value;
7274                 res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
7275                                 __get_asp_search_id, service);
7276
7277         } else {
7278                 __ws_add_seek(service);
7279         }
7280
7281         if (res < 0)
7282                 WDP_LOGE("Failed to send command to wpa_supplicant");
7283         else
7284                 WDP_LOGD("Succeeded to seek service");
7285
7286         __WDP_LOG_FUNC_EXIT__;
7287         return res;
7288 }
7289
7290 int ws_cancel_seek_service(wfd_oem_asp_service_s *service)
7291 {
7292         __WDP_LOG_FUNC_ENTER__;
7293         GDBusConnection *g_dbus = NULL;
7294         wfd_oem_asp_service_s *seek = NULL;
7295         dbus_method_param_s params;
7296         int res = 0;
7297
7298         g_dbus = g_pd->g_dbus;
7299         if (!g_dbus) {
7300                 WDP_LOGE("DBus connection is NULL");
7301                 __WDP_LOG_FUNC_EXIT__;
7302                 return -1;
7303         }
7304
7305         seek = __ws_get_seek(service->asp_search_id);
7306         if (!seek) {
7307                 WDP_LOGE("seek data is NULL");
7308                 __WDP_LOG_FUNC_EXIT__;
7309                 return -1;
7310         }
7311
7312         if (seek->service_info) {
7313
7314                 memset(&params, 0x0, sizeof(dbus_method_param_s));
7315                 dbus_set_method_param(&params, "ServiceDiscoveryCancelRequest",
7316                                 g_pd->iface_path, g_dbus);
7317
7318                 params.params = g_variant_new("(t)", service->search_id);
7319
7320                 DEBUG_G_VARIANT("Params : ", params.params);
7321
7322                 res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7323                 if (res < 0)
7324                         WDP_LOGE("Failed to send command to wpa_supplicant");
7325                 else
7326                         WDP_LOGD("Succeeded to cancel seek service");
7327         }
7328         if (res == 0)
7329                 __ws_remove_seek(seek);
7330
7331         __WDP_LOG_FUNC_EXIT__;
7332         return res;
7333 }
7334
7335 int ws_asp_prov_disc_req(wfd_oem_asp_prov_s *asp_params)
7336 {
7337         __WDP_LOG_FUNC_ENTER__;
7338         GDBusConnection *g_dbus = NULL;
7339         GVariantBuilder *builder = NULL;
7340         GVariantBuilder *mac_builder = NULL;
7341         GVariant *value = NULL;
7342         dbus_method_param_s params;
7343         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
7344         int config_method = 0x1000;
7345         int res = 0;
7346         int i = 0;
7347
7348         if (!asp_params) {
7349                 WDP_LOGE("Invalid parameter");
7350                 __WDP_LOG_FUNC_EXIT__;
7351                 return -1;
7352         }
7353         g_dbus = g_pd->g_dbus;
7354         if (!g_dbus) {
7355                 WDP_LOGE("DBus connection is NULL");
7356                 __WDP_LOG_FUNC_EXIT__;
7357                 return -1;
7358         }
7359
7360         if (asp_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
7361                 config_method = 0x8;
7362         else if (asp_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
7363                 config_method = 0x100;
7364
7365         memset(&params, 0x0, sizeof(dbus_method_param_s));
7366
7367         dbus_set_method_param(&params, "ASPProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
7368
7369         if (asp_params->deferring == 0)
7370                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
7371                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(asp_params->service_mac));
7372         else
7373                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
7374                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(asp_params->session_mac));
7375         WDP_LOGD("get peer path [%s]", peer_path);
7376
7377         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7378         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
7379
7380         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(asp_params->adv_id));
7381         g_variant_builder_add(builder, "{sv}", "session_id", g_variant_new_uint32(asp_params->session_id));
7382         g_variant_builder_add(builder, "{sv}", "role", g_variant_new_byte(asp_params->network_role));
7383         g_variant_builder_add(builder, "{sv}", "method", g_variant_new_int32(config_method));
7384         if (asp_params->status > 0)
7385                 g_variant_builder_add(builder, "{sv}", "status", g_variant_new_int32(asp_params->status));
7386         if (asp_params->session_information)
7387                 g_variant_builder_add(builder, "{sv}", "info", g_variant_new_string(asp_params->session_information));
7388
7389         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7390         for (i = 0; i < OEM_MACADDR_LEN; i++)
7391                 g_variant_builder_add(mac_builder, "y", asp_params->service_mac[i]);
7392         g_variant_builder_add(builder, "{sv}", "adv_mac",
7393                         g_variant_new("ay", mac_builder));
7394         g_variant_builder_unref(mac_builder);
7395
7396         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7397         for (i = 0; i < OEM_MACADDR_LEN; i++)
7398                 g_variant_builder_add(mac_builder, "y", asp_params->session_mac[i]);
7399         g_variant_builder_add(builder, "{sv}", "session_mac",
7400                         g_variant_new("ay", mac_builder));
7401         g_variant_builder_unref(mac_builder);
7402
7403         value = g_variant_new("(a{sv})", builder);
7404         g_variant_builder_unref(builder);
7405         DEBUG_G_VARIANT("Params : ", value);
7406
7407         params.params = value;
7408
7409         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7410         if (res < 0)
7411                 WDP_LOGE("Failed to send command to wpa_supplicant");
7412         else
7413                 WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(asp_params->service_mac));
7414
7415         __WDP_LOG_FUNC_EXIT__;
7416         return res;
7417 }
7418
7419 int ws_set_eapol_ip_config(int enable)
7420 {
7421         __WDP_LOG_FUNC_ENTER__;
7422         GDBusConnection *g_dbus = NULL;
7423
7424         GVariant *value = NULL;
7425         GVariant *param = NULL;
7426         GVariantBuilder *builder = NULL;
7427         GVariantBuilder *type_builder = NULL;
7428         dbus_method_param_s params;
7429         int res = 0;
7430         int i = 0;
7431         enum {
7432                 IP_GO,
7433                 IP_MASK,
7434                 IP_START,
7435                 IP_END,
7436         };
7437         unsigned char eapol_ip[IP_END + 1][OEM_IPADDR_LEN + 1] = {0,};
7438
7439         if (!g_pd) {
7440                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7441                 __WDP_LOG_FUNC_EXIT__;
7442                 return -1;
7443         }
7444
7445         g_dbus = g_pd->g_dbus;
7446         if (!g_dbus) {
7447                 WDP_LOGE("DBus connection is NULL");
7448                 __WDP_LOG_FUNC_EXIT__;
7449                 return -1;
7450         }
7451         memset(&params, 0x0, sizeof(dbus_method_param_s));
7452
7453         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
7454                          g_dbus);
7455
7456         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7457
7458         memset(&eapol_ip, 0x0, (IP_END + 1) * (OEM_IPADDR_LEN + 1));
7459         if (enable == 1) {
7460                 memcpy(eapol_ip[IP_GO], DEFAULT_IP_GO, OEM_IPADDR_LEN);
7461                 memcpy(eapol_ip[IP_MASK], DEFAULT_IP_MASK, OEM_IPADDR_LEN);
7462                 memcpy(eapol_ip[IP_START], DEFAULT_IP_START, OEM_IPADDR_LEN);
7463                 memcpy(eapol_ip[IP_END], DEFAULT_IP_END, OEM_IPADDR_LEN);
7464         }
7465
7466         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7467         for (i = 0; i < OEM_IPADDR_LEN; i++)
7468                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_GO][i]);
7469         g_variant_builder_add(builder, "{sv}", "IpAddrGo",
7470                         g_variant_new("ay", type_builder));
7471         g_variant_builder_unref(type_builder);
7472
7473         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7474         for (i = 0; i < OEM_IPADDR_LEN; i++)
7475                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_MASK][i]);
7476         g_variant_builder_add(builder, "{sv}", "IpAddrMask",
7477                         g_variant_new("ay", type_builder));
7478         g_variant_builder_unref(type_builder);
7479
7480         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7481         for (i = 0; i < OEM_IPADDR_LEN; i++)
7482                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_START][i]);
7483         g_variant_builder_add(builder, "{sv}", "IpAddrStart",
7484                         g_variant_new("ay", type_builder));
7485         g_variant_builder_unref(type_builder);
7486
7487         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7488         for (i = 0; i < OEM_IPADDR_LEN; i++)
7489                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_END][i]);
7490         g_variant_builder_add(builder, "{sv}", "IpAddrEnd",
7491                         g_variant_new("ay", type_builder));
7492         g_variant_builder_unref(type_builder);
7493
7494         value = g_variant_new("a{sv}", builder);
7495         g_variant_builder_unref(builder);
7496
7497         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
7498
7499         params.params = param;
7500
7501         DEBUG_G_VARIANT("Params : ", param);
7502         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
7503         if (res < 0) {
7504                 WDP_LOGE("Failed to send command to wpa_supplicant");
7505         } else {
7506                 WDP_LOGI("Succeeded to set eapol IP");
7507         }
7508         __WDP_LOG_FUNC_EXIT__;
7509         return res;
7510 }
7511
7512 int ws_add_vsie(wfd_oem_vsie_frames_e frame_id, const char* vsie)
7513 {
7514         __WDP_LOG_FUNC_ENTER__;
7515         GDBusConnection *g_dbus = NULL;
7516         GVariant *value = NULL;
7517         GVariantBuilder *bytearray_builder = NULL;
7518         dbus_method_param_s params;
7519         int res = 0;
7520         int i = 0;
7521         size_t vsie_len = 0;
7522
7523         unsigned char *bytearray = NULL;
7524         size_t bytearray_len = 0;
7525
7526         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7527             vsie == NULL) {
7528                 WDP_LOGE("Invalid parameter");
7529                 return -1;
7530         }
7531
7532         if (!g_pd) {
7533                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7534                 __WDP_LOG_FUNC_EXIT__;
7535                 return -1;
7536         }
7537
7538         g_dbus = g_pd->g_dbus;
7539         if (!g_dbus) {
7540                 WDP_LOGE("DBus connection is NULL");
7541                 __WDP_LOG_FUNC_EXIT__;
7542                 return -1;
7543         }
7544
7545         vsie_len = strlen(vsie);
7546         if (vsie_len == 0) {
7547                 WDP_LOGE("vsie length is zero");
7548                 __WDP_LOG_FUNC_EXIT__;
7549                 return -1;
7550         }
7551
7552         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
7553
7554         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
7555         if (bytearray == NULL) {
7556                 WDP_LOGE("Failed to allocate memory to bytearray");
7557                 __WDP_LOG_FUNC_EXIT__;
7558                 return -1;
7559         }
7560
7561         if (__ws_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
7562                 WDP_LOGE("invalid vsie string");
7563                 g_free(bytearray);
7564                 __WDP_LOG_FUNC_EXIT__;
7565                 return -1;
7566         }
7567
7568         memset(&params, 0x0, sizeof(dbus_method_param_s));
7569         dbus_set_method_param(&params, "VendorElemAdd", g_pd->iface_path,
7570                               g_dbus);
7571
7572         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7573         for (i = 0; i < bytearray_len; i++)
7574                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
7575
7576         value = g_variant_new("(iay)", frame_id, bytearray_builder);
7577         g_variant_builder_unref(bytearray_builder);
7578
7579         params.params = value;
7580
7581         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
7582         if (res < 0) {
7583                 WDP_LOGE("Failed to send command to wpa_supplicant");
7584                 g_free(bytearray);
7585                 __WDP_LOG_FUNC_EXIT__;
7586                 return -1;
7587         }
7588
7589         WDP_LOGD("Succeeded to add vsie: Frame ID [%d], VSIE [%s]", frame_id,
7590                  vsie);
7591
7592         g_free(bytearray);
7593         __WDP_LOG_FUNC_EXIT__;
7594         return 0;
7595 }
7596
7597 int ws_get_vsie(wfd_oem_vsie_frames_e frame_id, char **vsie)
7598 {
7599         __WDP_LOG_FUNC_ENTER__;
7600         GDBusConnection *g_dbus = NULL;
7601         GVariant *param = NULL;
7602         GVariant *reply = NULL;
7603         GError *error = NULL;
7604
7605         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7606             vsie == NULL) {
7607                 WDP_LOGE("Invalid parameter");
7608                 __WDP_LOG_FUNC_EXIT__;
7609                 return -1;
7610         }
7611
7612         if (!g_pd) {
7613                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7614                 __WDP_LOG_FUNC_EXIT__;
7615                 return -1;
7616         }
7617
7618         g_dbus = g_pd->g_dbus;
7619         if (!g_dbus) {
7620                 WDP_LOGE("DBus connection is NULL");
7621                 __WDP_LOG_FUNC_EXIT__;
7622                 return -1;
7623         }
7624
7625         param = g_variant_new("(i)", frame_id);
7626
7627         reply = g_dbus_connection_call_sync(
7628                         g_pd->g_dbus,
7629                         SUPPLICANT_SERVICE, /* bus name */
7630                         g_pd->iface_path, /* object path */
7631                         SUPPLICANT_IFACE, /* interface name */
7632                         "VendorElemGet", /* method name */
7633                         param, /* GVariant *params */
7634                         NULL, /* reply_type */
7635                         G_DBUS_CALL_FLAGS_NONE, /* flags */
7636                         SUPPLICANT_TIMEOUT, /* timeout */
7637                         NULL, /* cancellable */
7638                         &error); /* error */
7639
7640         if (error != NULL) {
7641                 WDP_LOGE("Error! Failed to get vsie: [%s]", error->message);
7642                 g_error_free(error);
7643                 if (reply)
7644                         g_variant_unref(reply);
7645                 __WDP_LOG_FUNC_EXIT__;
7646                 return -1;
7647         }
7648
7649         if (reply != NULL) {
7650                 DEBUG_G_VARIANT("Reply : ", reply);
7651
7652                 GVariantIter *iter = NULL;
7653                 unsigned char *vsie_bytes = NULL;
7654                 int vsie_len = 0;
7655
7656                 g_variant_get(reply, "(ay)", &iter);
7657                 if (iter == NULL) {
7658                         WDP_LOGD("vsie is not present");
7659                         __WDP_LOG_FUNC_EXIT__;
7660                         return -1;
7661                 }
7662
7663                 vsie_len = __ws_unpack_ay_malloc(&vsie_bytes, iter);
7664                 if (vsie_bytes == NULL) {
7665                         WDP_LOGD("vsie_bytes not allocated");
7666                         __WDP_LOG_FUNC_EXIT__;
7667                         return -1;
7668                 }
7669
7670                 __ws_byte_to_txt(vsie_bytes, vsie, vsie_len);
7671                 if (!vsie) {
7672                         g_free(vsie_bytes);
7673                         WDP_LOGE("vsie not allocated.");
7674                         __WDP_LOG_FUNC_EXIT__;
7675                         return -1;
7676                 }
7677
7678                 g_free(vsie_bytes);
7679         }
7680
7681         WDP_LOGD("Succeeded to get vsie: Frame ID [%d], VSIE [%s]", frame_id,
7682                  *vsie);
7683         __WDP_LOG_FUNC_EXIT__;
7684         return 0;
7685 }
7686
7687 int ws_remove_vsie(wfd_oem_vsie_frames_e frame_id, const char *vsie)
7688 {
7689         __WDP_LOG_FUNC_ENTER__;
7690         GDBusConnection *g_dbus = NULL;
7691         GVariantBuilder *bytearray_builder = NULL;
7692         GVariant *value = NULL;
7693         dbus_method_param_s params;
7694         int res = 0;
7695         int i = 0;
7696         size_t vsie_len = 0;
7697
7698         unsigned char *bytearray = NULL;
7699         size_t bytearray_len = 0;
7700
7701         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7702             vsie == NULL) {
7703                 WDP_LOGE("Invalid parameter");
7704                 return -1;
7705         }
7706
7707         if (!g_pd) {
7708                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7709                 __WDP_LOG_FUNC_EXIT__;
7710                 return -1;
7711         }
7712
7713         g_dbus = g_pd->g_dbus;
7714         if (!g_dbus) {
7715                 WDP_LOGE("DBus connection is NULL");
7716                 __WDP_LOG_FUNC_EXIT__;
7717                 return -1;
7718         }
7719
7720         vsie_len = strlen(vsie);
7721         if (vsie_len == 0) {
7722                 WDP_LOGE("vsie length is zero");
7723                 __WDP_LOG_FUNC_EXIT__;
7724                 return -1;
7725         }
7726
7727         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
7728
7729         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
7730         if (bytearray == NULL) {
7731                 WDP_LOGE("Failed to allocate memory to bytearray");
7732                 __WDP_LOG_FUNC_EXIT__;
7733                 return -1;
7734         }
7735
7736         if (__ws_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
7737                 WDP_LOGE("invalid vsie string");
7738                 g_free(bytearray);
7739                 __WDP_LOG_FUNC_EXIT__;
7740                 return -1;
7741         }
7742
7743         memset(&params, 0x0, sizeof(dbus_method_param_s));
7744         dbus_set_method_param(&params, "VendorElemRem", g_pd->iface_path,
7745                               g_dbus);
7746
7747         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7748         for (i = 0; i < bytearray_len; i++)
7749                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
7750
7751         value = g_variant_new("(iay)", frame_id, bytearray_builder);
7752         g_variant_builder_unref(bytearray_builder);
7753
7754         params.params = value;
7755
7756         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
7757         if (res < 0) {
7758                 WDP_LOGE("Failed to send command to wpa_supplicant");
7759                 g_free(bytearray);
7760                 __WDP_LOG_FUNC_EXIT__;
7761                 return -1;
7762         }
7763
7764         WDP_LOGD("Succeeded to remove vsie: Frame ID [%d], VSIE [%s]", frame_id,
7765                  vsie);
7766         g_free(bytearray);
7767         __WDP_LOG_FUNC_EXIT__;
7768         return 0;
7769 }
7770
7771 int ws_set_supported_wps_mode(int wps_mode)
7772 {
7773         __WDP_LOG_FUNC_ENTER__;
7774         char config_value[DBUS_OBJECT_PATH_MAX+1] = {0,};
7775         int length = 0;
7776         int new_wps_mode = wps_mode;
7777         int res = 0;
7778
7779         if (!config) {
7780                 WDP_LOGE("no configurable data found");
7781                 __WDP_LOG_FUNC_EXIT__;
7782                 return -1;
7783         }
7784
7785         if (new_wps_mode == 0) {
7786                 WDP_LOGE("Reset to default value");
7787                 new_wps_mode = WFD_OEM_WPS_MODE_PBC|WFD_OEM_WPS_MODE_DISPLAY|WFD_OEM_WPS_MODE_KEYPAD;
7788         }
7789
7790         if (new_wps_mode & WFD_OEM_WPS_MODE_KEYPAD) {
7791                 g_strlcat(config_value, "keypad ", sizeof(config_value));
7792                 length += 7;
7793         }
7794         if (new_wps_mode & WFD_OEM_WPS_MODE_PBC) {
7795                 g_strlcat(config_value, "virtual_push_button ", sizeof(config_value));
7796                 length += 20;
7797         }
7798         if (new_wps_mode & WFD_OEM_WPS_MODE_DISPLAY) {
7799                 g_strlcat(config_value, "physical_display ", sizeof(config_value));
7800                 length += 17;
7801         }
7802         config_value[length-1] = 0;
7803         g_strlcpy(config->config_methods, config_value, OEM_CONFIG_METHOD_LEN);
7804         WDP_LOGD("config_value = %s, length = %d", config_value, length-1);
7805         res = __ws_set_config_methods();
7806         if (res < 0) {
7807                 WDP_LOGE("Failed to set config method");
7808                 __WDP_LOG_FUNC_EXIT__;
7809                 return -1;
7810         }
7811         wps_config_method = new_wps_mode;
7812         __WDP_LOG_FUNC_EXIT__;
7813         return 0;
7814 }
7815
7816 static int _ws_remove_persistent_group_by_object_path(const char *object_path)
7817 {
7818         __WDP_LOG_FUNC_ENTER__;
7819         GDBusConnection *g_dbus = NULL;
7820         dbus_method_param_s params;
7821         int res = 0;
7822
7823         if (!g_pd) {
7824                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7825                 __WDP_LOG_FUNC_EXIT__;
7826                 return -1;
7827         }
7828
7829         g_dbus = g_pd->g_dbus;
7830         if (!g_dbus) {
7831                 WDP_LOGE("DBus connection is NULL");
7832                 __WDP_LOG_FUNC_EXIT__;
7833                 return -1;
7834         }
7835
7836         memset(&params, 0x0, sizeof(dbus_method_param_s));
7837         dbus_set_method_param(&params, "RemovePersistentGroup",
7838                         g_pd->iface_path, g_dbus);
7839         params.params = g_variant_new("(o)", object_path);
7840
7841         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7842         if (res < 0) {
7843                 WDP_LOGE("Failed to send command to wpa_supplicant");
7844                 __WDP_LOG_FUNC_EXIT__;
7845                 return -1;
7846         }
7847
7848         ws_save_config();
7849         WDP_LOGD("Succeeded to remove persistent group");;
7850         __WDP_LOG_FUNC_EXIT__;
7851         return 0;
7852 }
7853
7854 int ws_remove_persistent_device(unsigned char *mac_addr)
7855 {
7856         __WDP_LOG_FUNC_ENTER__;
7857         GDBusConnection *g_dbus = NULL;
7858         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
7859         int i = 0;
7860         int cnt = 0;
7861         int need_delete = 0;
7862         int res = 0;
7863
7864         if (!g_pd) {
7865                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7866                 __WDP_LOG_FUNC_EXIT__;
7867                 return -1;
7868         }
7869
7870         g_dbus = g_pd->g_dbus;
7871         if (!g_dbus) {
7872                 WDP_LOGE("DBus connection is NULL");
7873                 __WDP_LOG_FUNC_EXIT__;
7874                 return -1;
7875         }
7876         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
7877         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
7878                         __ws_extract_p2pdevice_details, networks);
7879
7880         cnt = networks[0].total;
7881
7882         WDP_LOGD("Persistent Group Count=%d", cnt);
7883         if (cnt > WS_MAX_PERSISTENT_COUNT) {
7884                 WDP_LOGE("Persistent group count exceeded or parsing error");
7885                 __WDP_LOG_FUNC_EXIT__;
7886                 return -1;
7887         }
7888
7889         for (i = 0 ; i < cnt ; i++) {
7890                 int j = 0;
7891                 need_delete = 0;
7892
7893                 WDP_LOGD("----persistent group [%d]----", i);
7894                 WDP_LOGD("network_id [%d]", networks[i].network_id);
7895                 WDP_LOGD("ssid [%s]", networks[i].ssid);
7896                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
7897                 WDP_LOGD("p2p_client_num [%d]", networks[i].p2p_client_num);
7898                 for (j = 0; j < networks[i].p2p_client_num; j++) {
7899                         WDP_LOGD("p2p_client_list ["MACSTR"]", MAC2STR(networks[i].p2p_client_list[j]));
7900                 }
7901
7902                 WDP_LOGD("mac_addr ["MACSTR"]", MAC2STR(mac_addr));
7903
7904                 if (memcmp(mac_addr, networks[i].bssid, WS_MACADDR_LEN) == 0) {
7905                         WDP_LOGD("Persistent group owner found [%d: "MACSTR"]", networks[i].network_id, MAC2STR(mac_addr));
7906                         need_delete = 1;
7907                 }
7908
7909                 if (need_delete == 0) {
7910                         for (j = 0; j < networks[i].p2p_client_num; j++) {
7911                                 if (!memcmp(mac_addr, networks[i].p2p_client_list[j], WS_MACADDR_LEN)) {
7912                                         WDP_LOGD("Persistent group client found [%d: "MACSTR"]", networks[i].network_id, MAC2STR(mac_addr));
7913                                         need_delete = 1;
7914                                 }
7915                         }
7916                 }
7917
7918                 if (need_delete) {
7919                         res = _ws_remove_persistent_group_by_object_path(networks[i].persistent_path);
7920                         WDP_LOGI("persistent group deleted [%s]", networks[i].persistent_path);
7921                         if (res < 0) {
7922                                 WDP_LOGE("Failed to _ws_remove_persistent_group_by_object_path");
7923                         } else {
7924                                 WDP_LOGD("Succeeded to _ws_remove_persistent_group_by_object_path");
7925                         }
7926                 }
7927         }
7928
7929         __WDP_LOG_FUNC_EXIT__;
7930         return res;
7931 }
7932
7933 int ws_remove_all_persistent_device(void)
7934 {
7935         __WDP_LOG_FUNC_ENTER__;
7936         GDBusConnection *g_dbus = NULL;
7937         dbus_method_param_s params;
7938         int res = 0;
7939
7940         g_dbus = g_pd->g_dbus;
7941         if (!g_dbus) {
7942                 WDP_LOGE("DBus connection is NULL");
7943                 __WDP_LOG_FUNC_EXIT__;
7944                 return -1;
7945         }
7946         memset(&params, 0x0, sizeof(dbus_method_param_s));
7947
7948         dbus_set_method_param(&params, "RemoveAllPersistentGroups", g_pd->iface_path, g_dbus);
7949         params.params = NULL;
7950
7951         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7952         if (res < 0) {
7953                 WDP_LOGE("Failed to RemoveAllPersistentGroups");
7954         } else {
7955                 WDP_LOGD("Succeeded to RemoveAllPersistentGroups");
7956         }
7957
7958         ws_save_config();
7959         WDP_LOGD("Succeeded to remove all network");
7960         __WDP_LOG_FUNC_EXIT__;
7961         return res;
7962 }
7963
7964 static void __ws_get_supported_channels_reply(GVariant *reply, void *user_data)
7965 {
7966         __WDP_LOG_FUNC_ENTER__;
7967
7968         GVariantIter *iter = NULL;
7969         wfd_oem_supported_channels_s *data = (wfd_oem_supported_channels_s *)user_data;
7970
7971         if (reply) {
7972                 int channel = 0;
7973
7974                 g_variant_get(reply, "(ai)", &iter);
7975
7976                 while (g_variant_iter_loop(iter, "i", &channel))
7977                         data->channels[data->count++] = channel;
7978
7979                 g_variant_iter_free (iter);
7980
7981         } else {
7982                 WDP_LOGE("Reply is NULL");
7983         }
7984         __WDP_LOG_FUNC_EXIT__;
7985 }
7986
7987 int ws_get_supported_channels(wfd_oem_supported_channels_s *data)
7988 {
7989         __WDP_LOG_FUNC_ENTER__;
7990         int res = 0;
7991         dbus_method_param_s params;
7992
7993         if (!g_pd) {
7994                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7995                 __WDP_LOG_FUNC_EXIT__;
7996                 return -1;
7997         }
7998
7999         memset(&params, 0x0, sizeof(dbus_method_param_s));
8000         memset(data, 0x0, sizeof(wfd_oem_supported_channels_s));
8001
8002         dbus_set_method_param(&params, "GetSupportedChannels", g_pd->iface_path, g_pd->g_dbus);
8003         params.params = NULL;
8004
8005         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
8006                         __ws_get_supported_channels_reply, data);
8007         if (res < 0) {
8008                 WDP_LOGE("Failed to GetSupportedChannels");
8009         } else {
8010                 WDP_LOGD("Succeeded to GetSupportedChannels");
8011         }
8012
8013         __WDP_LOG_FUNC_EXIT__;
8014         return res;
8015 }