e7b48824e6f12421c11c9f79cde93803bce07588
[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->p2p_dev_addr[0] == 0x0)
2168                 memcpy(dev_data->p2p_dev_addr, event.dev_addr, WS_MACSTR_LEN);
2169
2170         if (dev_data->has_asp_services)
2171                 ws_get_advertise_service(peer_path, (GList **)&(event.asp_services));
2172         if (dev_data->has_asp2_services)
2173                 ws_get_advertise_asp_service(peer_path, (GList **)&(event.asp2_services));
2174
2175         if (g_pd->callback->peer_found_cb)
2176                 g_pd->callback->peer_found_cb(&event);
2177
2178         if (event.asp_services != NULL) {
2179                 GList *l;
2180                 wfd_oem_advertise_service_s *service;
2181                 for (l = (GList *)event.asp_services; l != NULL; l = l->next) {
2182                         service = (wfd_oem_advertise_service_s *)l->data;
2183                         event.asp_services = g_list_remove(l, service);
2184                         g_free(service->service_type);
2185                         g_free(service);
2186                 }
2187         }
2188         if (event.asp2_services != NULL) {
2189                 GList *l;
2190                 wfd_oem_advertise_service_s *service;
2191                 for (l = (GList *)event.asp2_services; l != NULL; l = l->next) {
2192                         service = (wfd_oem_advertise_service_s *)l->data;
2193                         event.asp_services = g_list_remove(l, service);
2194                         g_free(service->service_type);
2195                         g_free(service->instance_name);
2196                         g_free(service);
2197                 }
2198         }
2199
2200         __destroy_dev_data(dev_data);
2201
2202         __WDP_LOG_FUNC_EXIT__;
2203 }
2204
2205 static void _ws_process_device_lost(GDBusConnection *connection,
2206                 const gchar *sender, const gchar *object_path, const gchar *interface,
2207                 const gchar *signal, GVariant *parameters, gpointer user_data)
2208 {
2209         __WDP_LOG_FUNC_ENTER__;
2210         wfd_oem_event_s event;
2211         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2212
2213         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2214
2215         if (!g_pd || !g_pd->callback) {
2216                 WDP_LOGD("Ignoring event");
2217                 __WDP_LOG_FUNC_EXIT__;
2218                 return;
2219         }
2220
2221         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2222
2223         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
2224         event.event_id = WFD_OEM_EVENT_PEER_DISAPPEARED;
2225
2226         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2227
2228         if (g_pd->callback->peer_disappeared_cb)
2229                 g_pd->callback->peer_disappeared_cb(&event);
2230
2231
2232         __WDP_LOG_FUNC_EXIT__;
2233 }
2234
2235 static void _ws_process_find_stoppped(GDBusConnection *connection,
2236                 const gchar *sender, const gchar *object_path, const gchar *interface,
2237                 const gchar *signal, GVariant *parameters, gpointer user_data)
2238 {
2239         __WDP_LOG_FUNC_ENTER__;
2240         wfd_oem_event_s event;
2241
2242         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2243
2244         if (!g_pd || !g_pd->callback) {
2245                 WDP_LOGD("Ignoring event");
2246                 __WDP_LOG_FUNC_EXIT__;
2247                 return;
2248         }
2249
2250         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2251
2252         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
2253         event.event_id = WFD_OEM_EVENT_DISCOVERY_FINISHED;
2254
2255         if (g_pd->callback->discovery_finished_cb)
2256                 g_pd->callback->discovery_finished_cb(&event);
2257
2258         __WDP_LOG_FUNC_EXIT__;
2259 }
2260
2261 static void _ws_process_prov_disc_req_display_pin(GDBusConnection *connection,
2262                 const gchar *sender, const gchar *object_path, const gchar *interface,
2263                 const gchar *signal, GVariant *parameters, gpointer user_data)
2264 {
2265         __WDP_LOG_FUNC_ENTER__;
2266         wfd_oem_event_s event;
2267         wfd_oem_dev_data_s *dev_data = NULL;
2268         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2269         const char *path = NULL;
2270         const char *pin = NULL;
2271         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2272
2273         if (!__is_valid_plugin())
2274                 return;
2275
2276         dev_data = __create_dev_data();
2277         if (!dev_data) {
2278                 __WDP_LOG_FUNC_EXIT__;
2279                 return;
2280         }
2281
2282         __set_event_data(WFD_OEM_EVENT_PROV_DISC_REQ,
2283                         WFD_OEM_EDATA_TYPE_DEVICE,
2284                         (void *)dev_data,
2285                         &event);
2286         event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
2287
2288         g_variant_get(parameters, "(&o&s)", &path, &pin);
2289         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
2290         WDP_LOGD("Retrive Added path [%s]", peer_path);
2291
2292         __extract_addr_from_path(peer_path, event.dev_addr);
2293
2294         g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
2295         WDP_LOGD("Retrive pin [%s]", event.wps_pin);
2296
2297         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2298                         __ws_peer_property, event.edata);
2299
2300         if (g_pd->callback->prov_disc_req_cb)
2301                 g_pd->callback->prov_disc_req_cb(&event);
2302
2303         __destroy_dev_data(dev_data);
2304
2305         __WDP_LOG_FUNC_EXIT__;
2306 }
2307
2308 static void _ws_process_prov_disc_resp_display_pin(GDBusConnection *connection,
2309                 const gchar *sender, const gchar *object_path, const gchar *interface,
2310                 const gchar *signal, GVariant *parameters, gpointer user_data)
2311 {
2312         __WDP_LOG_FUNC_ENTER__;
2313         wfd_oem_event_s event;
2314         wfd_oem_dev_data_s *dev_data = NULL;
2315         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2316         const char *path = NULL;
2317         const char *pin = NULL;
2318
2319         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2320
2321         if (!__is_valid_plugin())
2322                 return;
2323
2324         dev_data = __create_dev_data();
2325         if (!dev_data) {
2326                 __WDP_LOG_FUNC_EXIT__;
2327                 return;
2328         }
2329
2330         __set_event_data(WFD_OEM_EVENT_PROV_DISC_RESP,
2331                         WFD_OEM_EDATA_TYPE_DEVICE,
2332                         (void *)dev_data,
2333                         &event);
2334         event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
2335
2336         g_variant_get(parameters, "(&o&s)", &path, &pin);
2337         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
2338         WDP_LOGD("Retrive Added path [%s]", peer_path);
2339
2340         __extract_addr_from_path(peer_path, event.dev_addr);
2341
2342         g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
2343         WDP_LOGD("Retrive pin [%s]", event.wps_pin);
2344
2345         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2346                         __ws_peer_property, event.edata);
2347
2348         if (g_pd->callback->prov_disc_resp_cb)
2349                 g_pd->callback->prov_disc_resp_cb(&event);
2350
2351         __destroy_dev_data(dev_data);
2352
2353         __WDP_LOG_FUNC_EXIT__;
2354 }
2355
2356 static void _ws_process_prov_disc_req_enter_pin(GDBusConnection *connection,
2357                 const gchar *sender, const gchar *object_path, const gchar *interface,
2358                 const gchar *signal, GVariant *parameters, gpointer user_data)
2359 {
2360         __WDP_LOG_FUNC_ENTER__;
2361         wfd_oem_event_s event;
2362         wfd_oem_dev_data_s *dev_data = NULL;
2363         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2364
2365         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2366         if (!__is_valid_plugin())
2367                 return;
2368
2369         dev_data = __create_dev_data();
2370         if (!dev_data) {
2371                 __WDP_LOG_FUNC_EXIT__;
2372                 return;
2373         }
2374
2375         __set_event_data(WFD_OEM_EVENT_PROV_DISC_REQ,
2376                         WFD_OEM_EDATA_TYPE_DEVICE,
2377                         (void *)dev_data,
2378                         &event);
2379         event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
2380
2381         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2382
2383         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2384                         __ws_peer_property, event.edata);
2385
2386         if (g_pd->callback->prov_disc_req_cb)
2387                 g_pd->callback->prov_disc_req_cb(&event);
2388
2389         __destroy_dev_data(dev_data);
2390
2391         __WDP_LOG_FUNC_EXIT__;
2392 }
2393
2394 static void _ws_process_prov_disc_resp_enter_pin(GDBusConnection *connection,
2395                 const gchar *sender, const gchar *object_path, const gchar *interface,
2396                 const gchar *signal, GVariant *parameters, gpointer user_data)
2397 {
2398         __WDP_LOG_FUNC_ENTER__;
2399         wfd_oem_event_s event;
2400         wfd_oem_dev_data_s *dev_data = NULL;
2401         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2402
2403         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2404
2405         if (!__is_valid_plugin())
2406                 return;
2407
2408         dev_data = __create_dev_data();
2409         if (!dev_data) {
2410                 __WDP_LOG_FUNC_EXIT__;
2411                 return;
2412         }
2413
2414         __set_event_data(WFD_OEM_EVENT_PROV_DISC_RESP,
2415                         WFD_OEM_EDATA_TYPE_DEVICE,
2416                         (void *)dev_data,
2417                         &event);
2418
2419         event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
2420
2421         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2422
2423         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2424                         __ws_peer_property, event.edata);
2425
2426         if (g_pd->callback->prov_disc_resp_cb)
2427                 g_pd->callback->prov_disc_resp_cb(&event);
2428
2429         __destroy_dev_data(dev_data);
2430
2431         __WDP_LOG_FUNC_EXIT__;
2432 }
2433
2434 static void _ws_process_prov_disc_pbc_req(GDBusConnection *connection,
2435                 const gchar *sender, const gchar *object_path, const gchar *interface,
2436                 const gchar *signal, GVariant *parameters, gpointer user_data)
2437 {
2438         __WDP_LOG_FUNC_ENTER__;
2439         wfd_oem_event_s event;
2440         wfd_oem_dev_data_s *dev_data = NULL;
2441         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2442
2443         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2444
2445         if (!__is_valid_plugin())
2446                 return;
2447
2448         dev_data = __create_dev_data();
2449         if (!dev_data) {
2450                 __WDP_LOG_FUNC_EXIT__;
2451                 return;
2452         }
2453         __set_event_data(WFD_OEM_EVENT_PROV_DISC_REQ,
2454                         WFD_OEM_EDATA_TYPE_DEVICE,
2455                         (void *)dev_data,
2456                         &event);
2457         event.wps_mode = WFD_OEM_WPS_MODE_PBC;
2458
2459         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2460
2461         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2462                         __ws_peer_property, event.edata);
2463
2464         if (g_pd->callback->prov_disc_req_cb)
2465                 g_pd->callback->prov_disc_req_cb(&event);
2466
2467         __destroy_dev_data(dev_data);
2468
2469         __WDP_LOG_FUNC_EXIT__;
2470 }
2471
2472 static void _ws_process_prov_disc_pbc_resp(GDBusConnection *connection,
2473                 const gchar *sender, const gchar *object_path, const gchar *interface,
2474                 const gchar *signal, GVariant *parameters, gpointer user_data)
2475 {
2476         __WDP_LOG_FUNC_ENTER__;
2477         wfd_oem_event_s event;
2478         wfd_oem_dev_data_s *dev_data = NULL;
2479         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2480
2481         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2482
2483         if (!__is_valid_plugin())
2484                 return;
2485
2486         dev_data = __create_dev_data();
2487         if (!dev_data) {
2488                 __WDP_LOG_FUNC_EXIT__;
2489                 return;
2490         }
2491         __set_event_data(WFD_OEM_EVENT_PROV_DISC_RESP,
2492                         WFD_OEM_EDATA_TYPE_DEVICE,
2493                         (void *)dev_data,
2494                         &event);
2495         event.wps_mode = WFD_OEM_WPS_MODE_PBC;
2496
2497         __ws_path_to_addr(peer_path, event.dev_addr, parameters);
2498
2499         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2500                         __ws_peer_property, event.edata);
2501
2502         if (g_pd->callback->prov_disc_resp_cb)
2503                 g_pd->callback->prov_disc_resp_cb(&event);
2504
2505         __destroy_dev_data(dev_data);
2506
2507         __WDP_LOG_FUNC_EXIT__;
2508 }
2509
2510 static void _ws_process_prov_disc_failure(GDBusConnection *connection,
2511                 const gchar *sender, const gchar *object_path, const gchar *interface,
2512                 const gchar *signal, GVariant *parameters, gpointer user_data)
2513 {
2514         __WDP_LOG_FUNC_ENTER__;
2515         GVariantIter *iter = NULL;
2516         wfd_oem_event_s event;
2517         wfd_oem_asp_prov_s *edata;
2518
2519         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2520
2521         if (!g_pd || !g_pd->callback) {
2522                 WDP_LOGD("Ignoring event");
2523                 __WDP_LOG_FUNC_EXIT__;
2524                 return;
2525         }
2526
2527         edata = (wfd_oem_asp_prov_s *) g_try_malloc0(sizeof(wfd_oem_asp_prov_s));
2528         if (!edata) {
2529                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2530                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2531                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2532                                 error_buf);
2533                 __WDP_LOG_FUNC_EXIT__;
2534                 return;
2535         }
2536         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2537
2538         event.edata = (void*) edata;
2539         event.event_id = WFD_OEM_EVENT_PROV_DISC_FAIL;
2540
2541         if (parameters != NULL) {
2542                 g_variant_get(parameters, "(a{sv})", &iter);
2543                 if (iter != NULL) {
2544                         dbus_property_foreach(iter, __ws_extract_provision_fail_details, &event);
2545                         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_PROV;
2546                         g_variant_iter_free(iter);
2547                 }
2548         } else {
2549                 WDP_LOGE("No Properties");
2550         }
2551
2552         if (g_pd->callback->prov_disc_fail_cb)
2553                 g_pd->callback->prov_disc_fail_cb(&event);
2554
2555         if (event.edata_type == WFD_OEM_EDATA_TYPE_ASP_PROV)
2556                 g_free(edata->session_information);
2557         g_free(edata);
2558
2559         __WDP_LOG_FUNC_EXIT__;
2560 }
2561
2562 static void _ws_process_group_started(GDBusConnection *connection,
2563                 const gchar *sender, const gchar *object_path, const gchar *interface,
2564                 const gchar *signal, GVariant *parameters, gpointer user_data)
2565 {
2566         __WDP_LOG_FUNC_ENTER__;
2567         GVariantIter *iter = NULL;
2568         wfd_oem_event_s event;
2569         wfd_oem_group_data_s *edata = NULL;
2570
2571         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2572
2573         if (!g_pd || !g_pd->callback) {
2574                 WDP_LOGD("Ignoring event");
2575                 __WDP_LOG_FUNC_EXIT__;
2576                 return;
2577         }
2578
2579         edata = (wfd_oem_group_data_s*)calloc(1, sizeof(wfd_oem_group_data_s));
2580         if (!edata) {
2581                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2582                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2583                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2584                                 error_buf);
2585                 __WDP_LOG_FUNC_EXIT__;
2586                 return;
2587         }
2588         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2589
2590         event.edata = (void*) edata;
2591         event.edata_type = WFD_OEM_EDATA_TYPE_GROUP;
2592         event.event_id = WFD_OEM_EVENT_GROUP_CREATED;
2593
2594         if (parameters != NULL) {
2595                 g_variant_get(parameters, "(a{sv})", &iter);
2596
2597                 if (iter != NULL) {
2598                         dbus_property_foreach(iter, __ws_extract_group_details, &event);
2599                         g_variant_iter_free(iter);
2600                 }
2601         } else {
2602                 WDP_LOGE("No properties");
2603         }
2604
2605         if (g_pd->callback->group_created_cb)
2606                 g_pd->callback->group_created_cb(&event);
2607
2608         g_free(event.edata);
2609
2610         __WDP_LOG_FUNC_EXIT__;
2611 }
2612
2613 static void _ws_process_go_neg_success(GDBusConnection *connection,
2614                 const gchar *sender, const gchar *object_path, const gchar *interface,
2615                 const gchar *signal, GVariant *parameters, gpointer user_data)
2616 {
2617         __WDP_LOG_FUNC_ENTER__;
2618         GVariantIter *iter = NULL;
2619         wfd_oem_event_s event;
2620         wfd_oem_conn_data_s *edata = NULL;
2621
2622         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2623
2624         if (!g_pd || !g_pd->callback) {
2625                 WDP_LOGD("Ignoring event");
2626                 __WDP_LOG_FUNC_EXIT__;
2627                 return;
2628         }
2629
2630         edata = (wfd_oem_conn_data_s*)calloc(1, sizeof(wfd_oem_conn_data_s));
2631         if (!edata) {
2632                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2633                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2634                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2635                                 error_buf);
2636                 __WDP_LOG_FUNC_EXIT__;
2637                 return;
2638         }
2639         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2640
2641         event.edata = edata;
2642         event.edata_type = WFD_OEM_EDATA_TYPE_CONN;
2643         event.event_id = WFD_OEM_EVENT_GO_NEG_DONE;
2644
2645         if (parameters != NULL) {
2646                 g_variant_get(parameters, "(a{sv})", &iter);
2647
2648                 if (iter != NULL) {
2649                         dbus_property_foreach(iter, __ws_extract_gonegsuccess_details, &event);
2650                         g_variant_iter_free(iter);
2651                 }
2652         } else {
2653                 WDP_LOGE("No properties");
2654         }
2655
2656         if (g_pd->callback->go_neg_done_cb)
2657                 g_pd->callback->go_neg_done_cb(&event);
2658
2659         g_free(edata);
2660
2661         __WDP_LOG_FUNC_EXIT__;
2662 }
2663
2664 static void _ws_process_go_neg_failure(GDBusConnection *connection,
2665                 const gchar *sender, const gchar *object_path, const gchar *interface,
2666                 const gchar *signal, GVariant *parameters, gpointer user_data)
2667 {
2668         __WDP_LOG_FUNC_ENTER__;
2669         GVariantIter *iter = NULL;
2670         wfd_oem_event_s event;
2671         wfd_oem_conn_data_s *edata = NULL;
2672
2673         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2674
2675         if (!g_pd || !g_pd->callback) {
2676                 WDP_LOGD("Ignoring event");
2677                 __WDP_LOG_FUNC_EXIT__;
2678                 return;
2679         }
2680
2681         edata = (wfd_oem_conn_data_s *) g_try_malloc0(sizeof(wfd_oem_conn_data_s));
2682         if (!edata) {
2683                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2684                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2685                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2686                                 error_buf);
2687                 __WDP_LOG_FUNC_EXIT__;
2688                 return;
2689         }
2690         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2691
2692         event.edata = (void*) edata;
2693         event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
2694         event.event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
2695
2696         if (parameters != NULL) {
2697                 g_variant_get(parameters, "(a{sv})", &iter);
2698
2699                 if (iter != NULL) {
2700                         dbus_property_foreach(iter, __ws_extract_gonegfailaure_details, &event);
2701                         g_variant_iter_free(iter);
2702                 }
2703         } else {
2704                 WDP_LOGE("No properties");
2705         }
2706
2707         if (g_pd->callback->go_neg_fail_cb)
2708                 g_pd->callback->go_neg_fail_cb(&event);
2709
2710         g_free(event.edata);
2711
2712         __WDP_LOG_FUNC_EXIT__;
2713 }
2714
2715 static void __set_wps_mode_for_event(int dev_passwd_id, wfd_oem_event_s *event)
2716 {
2717         if (!event)
2718                 return;
2719
2720         WDP_LOGD("Retrive dev_passwd_id [%d]", dev_passwd_id);
2721
2722         if (dev_passwd_id == WS_DEV_PASSWD_ID_PUSH_BUTTON)
2723                 event->wps_mode = WFD_OEM_WPS_MODE_PBC;
2724         else if (dev_passwd_id == WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED)
2725                 event->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
2726         else if (dev_passwd_id == WS_DEV_PASSWD_ID_USER_SPECIFIED)
2727                 event->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
2728         else
2729                 event->wps_mode = WFD_OEM_WPS_MODE_NONE;
2730 }
2731
2732 static void _ws_process_go_neg_request(GDBusConnection *connection,
2733                 const gchar *sender, const gchar *object_path, const gchar *interface,
2734                 const gchar *signal, GVariant *parameters, gpointer user_data)
2735 {
2736         __WDP_LOG_FUNC_ENTER__;
2737         wfd_oem_event_s event;
2738         wfd_oem_dev_data_s *dev_data = NULL;
2739         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2740         const char *path = NULL;
2741         int dev_passwd_id = 0;
2742         int device_go_intent = 0;
2743
2744         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2745
2746         if (!__is_valid_plugin())
2747                 return;
2748
2749         dev_data = __create_dev_data();
2750         if (!dev_data) {
2751                 __WDP_LOG_FUNC_EXIT__;
2752                 return;
2753         }
2754         __set_event_data(WFD_OEM_EVENT_GO_NEG_REQ,
2755                         WFD_OEM_EDATA_TYPE_DEVICE,
2756                         (void *)dev_data,
2757                         &event);
2758
2759         g_variant_get(parameters, "(&oqy)", &path, &dev_passwd_id, &device_go_intent);
2760         g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
2761
2762         WDP_LOGD("Retrive peer path [%s]", peer_path);
2763         __set_wps_mode_for_event(dev_passwd_id, &event);
2764         WDP_LOGD("Retrive device_go_intent [%d]", device_go_intent);
2765         dev_data->device_go_intent = device_go_intent;
2766
2767         __extract_addr_from_path(peer_path, event.dev_addr);
2768
2769         dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
2770                         __ws_peer_property, event.edata);
2771
2772         if (g_pd->callback->go_neg_req_cb)
2773                 g_pd->callback->go_neg_req_cb(&event);
2774
2775         __destroy_dev_data(dev_data);
2776
2777         __WDP_LOG_FUNC_EXIT__;
2778 }
2779 static void _ws_process_invitation_received(GDBusConnection *connection,
2780                 const gchar *sender, const gchar *object_path, const gchar *interface,
2781                 const gchar *signal, GVariant *parameters, gpointer user_data)
2782 {
2783         __WDP_LOG_FUNC_ENTER__;
2784         GVariantIter *iter = NULL;
2785         wfd_oem_event_s event;
2786         wfd_oem_invite_data_s *edata = NULL;
2787
2788         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2789
2790         if (!g_pd || !g_pd->callback) {
2791                 WDP_LOGD("Ignoring event");
2792                 __WDP_LOG_FUNC_EXIT__;
2793                 return;
2794         }
2795
2796         edata = (wfd_oem_invite_data_s *) g_try_malloc0(sizeof(wfd_oem_invite_data_s));
2797         if (!edata) {
2798                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2799                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2800                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2801                                 error_buf);
2802                 __WDP_LOG_FUNC_EXIT__;
2803                 return;
2804         }
2805         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2806
2807         event.edata = (void*) edata;
2808         event.edata_type = WFD_OEM_EDATA_TYPE_INVITE;
2809         event.event_id = WFD_OEM_EVENT_INVITATION_REQ;
2810
2811         if (parameters != NULL) {
2812                 g_variant_get(parameters, "(a{sv})", &iter);
2813
2814                 if (iter != NULL) {
2815                         dbus_property_foreach(iter, __ws_extract_invitation_details, &event);
2816                         g_variant_iter_free(iter);
2817                 }
2818         } else {
2819                 WDP_LOGE("No properties");
2820         }
2821         memcpy(&(event.dev_addr), edata->sa, OEM_MACADDR_LEN);
2822
2823         if (g_pd->callback->invitation_req_cb)
2824                 g_pd->callback->invitation_req_cb(&event);
2825
2826         g_free(event.edata);
2827
2828         __WDP_LOG_FUNC_EXIT__;
2829 }
2830
2831 static void _ws_process_invitation_result(GDBusConnection *connection,
2832                 const gchar *sender, const gchar *object_path, const gchar *interface,
2833                 const gchar *signal, GVariant *parameters, gpointer user_data)
2834 {
2835         __WDP_LOG_FUNC_ENTER__;
2836         wfd_oem_event_s event;
2837
2838         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2839
2840         if (!g_pd || !g_pd->callback) {
2841                 WDP_LOGD("Ignoring event");
2842                 __WDP_LOG_FUNC_EXIT__;
2843                 return;
2844         }
2845
2846         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2847
2848         __WDP_LOG_FUNC_EXIT__;
2849 }
2850
2851 static void _ws_process_group_finished(GDBusConnection *connection,
2852                 const gchar *sender, const gchar *object_path, const gchar *interface,
2853                 const gchar *signal, GVariant *parameters, gpointer user_data)
2854 {
2855         __WDP_LOG_FUNC_ENTER__;
2856         wfd_oem_event_s event;
2857         int i = 0;
2858
2859         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2860
2861         if (!g_pd || !g_pd->callback) {
2862                 WDP_LOGD("Ignoring event");
2863                 __WDP_LOG_FUNC_EXIT__;
2864                 return;
2865         }
2866
2867         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2868
2869         event.event_id = WFD_OEM_EVENT_GROUP_DESTROYED;
2870         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
2871
2872         for (i = 0; ws_group_signal_map[i].member != NULL; i++) {
2873                 g_dbus_connection_signal_unsubscribe(g_pd->g_dbus, ws_group_signal_map[i].sub_id);
2874                 ws_group_signal_map[i].sub_id = 0;
2875         }
2876
2877         _ws_manage_group_iface_signal(interface, FALSE);
2878         memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
2879         _ws_flush();
2880
2881         if (g_pd->callback->group_destroyed_cb)
2882                 g_pd->callback->group_destroyed_cb(&event);
2883
2884         __WDP_LOG_FUNC_EXIT__;
2885 }
2886
2887 static void _ws_process_service_discovery_response(GDBusConnection *connection,
2888                 const gchar *sender, const gchar *object_path, const gchar *interface,
2889                 const gchar *signal, GVariant *parameters, gpointer user_data)
2890 {
2891         __WDP_LOG_FUNC_ENTER__;
2892         GVariantIter *iter = NULL;
2893         wfd_oem_event_s event;
2894
2895         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2896
2897         if (!g_pd || !g_pd->callback) {
2898                 WDP_LOGD("Ignoring event");
2899                 __WDP_LOG_FUNC_EXIT__;
2900                 return;
2901         }
2902
2903         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2904
2905         event.event_id = WFD_OEM_EVENT_SERV_DISC_RESP;
2906
2907         if (parameters != NULL) {
2908                 g_variant_get(parameters, "(a{sv})", &iter);
2909                 if (iter != NULL) {
2910                         dbus_property_foreach(iter, __ws_extract_servicediscoveryresponse_details, &event);
2911                         event.edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
2912                         g_variant_iter_free(iter);
2913                 }
2914         } else {
2915                 WDP_LOGE("No Properties");
2916         }
2917
2918         if (g_pd->callback->serv_disc_resp_cb)
2919                 g_pd->callback->serv_disc_resp_cb(&event);
2920
2921         if (event.edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE)
2922                 g_list_free((GList*) event.edata);
2923
2924         __WDP_LOG_FUNC_EXIT__;
2925 }
2926
2927 static void _ws_process_service_asp_response(GDBusConnection *connection,
2928                 const gchar *sender, const gchar *object_path, const gchar *interface,
2929                 const gchar *signal, GVariant *parameters, gpointer user_data)
2930 {
2931         __WDP_LOG_FUNC_ENTER__;
2932         GVariantIter *iter = NULL;
2933         wfd_oem_event_s event;
2934         wfd_oem_asp_service_s *service = NULL;
2935         wfd_oem_asp_service_s *tmp = NULL;
2936
2937         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
2938
2939         if (!g_pd || !g_pd->callback) {
2940                 WDP_LOGD("Ignoring event");
2941                 __WDP_LOG_FUNC_EXIT__;
2942                 return;
2943         }
2944
2945         service = (wfd_oem_asp_service_s *) g_try_malloc0(sizeof(wfd_oem_asp_service_s));
2946         if (!service) {
2947                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
2948                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
2949                 WDP_LOGF("Failed to allocate memory for event. [%s]",
2950                                 error_buf);
2951                 __WDP_LOG_FUNC_EXIT__;
2952                 return;
2953         }
2954         memset(&event, 0x0, sizeof(wfd_oem_event_s));
2955
2956         event.edata = (void*) service;
2957         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_SERVICE;
2958         event.event_id = WFD_OEM_EVENT_ASP_SERV_RESP;
2959
2960         if (parameters != NULL) {
2961                 g_variant_get(parameters, "(a{sv})", &iter);
2962                 if (iter != NULL) {
2963                         dbus_property_foreach(iter, __ws_extract_serviceaspresponse_details, &event);
2964                         g_variant_iter_free(iter);
2965                 }
2966         } else {
2967                 WDP_LOGE("No Properties");
2968         }
2969 GLIST_ITER_START(seek_list, tmp)
2970         if (tmp->tran_id == service->tran_id) {
2971                 WDP_LOGD("srv_trans_id matched [%d] search_id [%llu]"
2972                                 , tmp->tran_id, tmp->search_id);
2973                 service->search_id = tmp->search_id;
2974                 break;
2975         } else {
2976                 tmp = NULL;
2977         }
2978 GLIST_ITER_END()
2979
2980         if (tmp != NULL && tmp->service_info != NULL) {
2981                 if (g_pd->callback->asp_serv_resp_cb)
2982                         g_pd->callback->asp_serv_resp_cb(&event);
2983         } else {
2984                 WDP_LOGD("service info is not required, don't notify to user");
2985         }
2986
2987         g_free(service->service_type);
2988         g_free(service->service_info);
2989         g_free(service);
2990
2991         __WDP_LOG_FUNC_EXIT__;
2992 }
2993
2994 static void _ws_process_persistent_group_added(GDBusConnection *connection,
2995                 const gchar *sender, const gchar *object_path, const gchar *interface,
2996                 const gchar *signal, GVariant *parameters, gpointer user_data)
2997 {
2998         __WDP_LOG_FUNC_ENTER__;
2999         wfd_oem_event_s event;
3000
3001         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3002
3003         if (!g_pd || !g_pd->callback) {
3004                 WDP_LOGD("Ignoring event");
3005                 __WDP_LOG_FUNC_EXIT__;
3006                 return;
3007         }
3008
3009         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3010
3011         __WDP_LOG_FUNC_EXIT__;
3012 }
3013
3014 static void _ws_process_persistent_group_removed(GDBusConnection *connection,
3015                 const gchar *sender, const gchar *object_path, const gchar *interface,
3016                 const gchar *signal, GVariant *parameters, gpointer user_data)
3017 {
3018         __WDP_LOG_FUNC_ENTER__;
3019         wfd_oem_event_s event;
3020
3021         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3022
3023         if (!g_pd || !g_pd->callback) {
3024                 WDP_LOGD("Ignoring event");
3025                 __WDP_LOG_FUNC_EXIT__;
3026                 return;
3027         }
3028
3029         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3030
3031         __WDP_LOG_FUNC_EXIT__;
3032 }
3033
3034 static void _ws_process_wps_failed(GDBusConnection *connection,
3035                 const gchar *sender, const gchar *object_path, const gchar *interface,
3036                 const gchar *signal, GVariant *parameters, gpointer user_data)
3037 {
3038         __WDP_LOG_FUNC_ENTER__;
3039         GVariantIter *iter = NULL;
3040         wfd_oem_event_s event;
3041         const char *name = NULL;
3042
3043         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3044
3045         if (!g_pd || !g_pd->callback) {
3046                 WDP_LOGD("Ignoring event");
3047                 __WDP_LOG_FUNC_EXIT__;
3048                 return;
3049         }
3050
3051         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3052
3053         event.event_id = WFD_OEM_EVENT_WPS_FAIL;
3054         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3055
3056         g_variant_get(parameters, "(&sa{sv})", &name, &iter);
3057
3058         WDP_LOGD("code [%s]", name);
3059
3060         if (iter != NULL) {
3061
3062                 gchar *key = NULL;
3063                 GVariant *value = NULL;
3064
3065                 while (g_variant_iter_loop(iter, "{sv}", &key, &value))
3066                         CHECK_KEY_VALUE(key, value);
3067
3068                 g_variant_iter_free(iter);
3069         }
3070
3071         if (g_pd->callback->wps_fail_cb)
3072                 g_pd->callback->wps_fail_cb(&event);
3073
3074         __WDP_LOG_FUNC_EXIT__;
3075 }
3076
3077 static void _ws_process_group_formation_failure(GDBusConnection *connection,
3078                 const gchar *sender, const gchar *object_path, const gchar *interface,
3079                 const gchar *signal, GVariant *parameters, gpointer user_data)
3080 {
3081         __WDP_LOG_FUNC_ENTER__;
3082         wfd_oem_event_s event;
3083
3084         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3085
3086         if (!g_pd || !g_pd->callback) {
3087                 WDP_LOGD("Ignoring event");
3088                 __WDP_LOG_FUNC_EXIT__;
3089                 return;
3090         }
3091
3092         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3093
3094         event.event_id = WFD_OEM_EVENT_GROUP_FORMATION_FAILURE;
3095         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3096
3097         if (g_pd->callback->group_formation_failure_cb)
3098                 g_pd->callback->group_formation_failure_cb(&event);
3099
3100         __WDP_LOG_FUNC_EXIT__;
3101 }
3102
3103 static void _ws_process_invitation_accepted(GDBusConnection *connection,
3104                 const gchar *sender, const gchar *object_path, const gchar *interface,
3105                 const gchar *signal, GVariant *parameters, gpointer user_data)
3106 {
3107         __WDP_LOG_FUNC_ENTER__;
3108         GVariantIter *iter = NULL;
3109         wfd_oem_event_s event;
3110
3111         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3112
3113         if (!g_pd || !g_pd->callback) {
3114                 WDP_LOGD("Ignoring event");
3115                 __WDP_LOG_FUNC_EXIT__;
3116                 return;
3117         }
3118
3119         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3120
3121         event.event_id = WFD_OEM_EVENT_INVITATION_ACCEPTED;
3122         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3123
3124         if (parameters != NULL) {
3125                 g_variant_get(parameters, "(a{sv})", &iter);
3126
3127                 if (iter != NULL) {
3128                         gchar *key = NULL;
3129                         GVariant *value = NULL;
3130
3131                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
3132                                 CHECK_KEY_VALUE(key, value);
3133
3134                                 if (g_strcmp0(key, "sa") == 0)
3135                                         if (__ws_unpack_ay(event.dev_addr, value, WS_MACADDR_LEN))
3136                                                 WDP_LOGI("[" MACSTR "]", MAC2STR(event.dev_addr));
3137                         }
3138                         g_variant_iter_free(iter);
3139                 }
3140         }
3141
3142         if (g_pd->callback->invitation_accepted_cb)
3143                 g_pd->callback->invitation_accepted_cb(&event);
3144
3145         __WDP_LOG_FUNC_EXIT__;
3146 }
3147
3148 static void _ws_process_asp_provision_start(GDBusConnection *connection,
3149                 const gchar *sender, const gchar *object_path, const gchar *interface,
3150                 const gchar *signal, GVariant *parameters, gpointer user_data)
3151 {
3152         __WDP_LOG_FUNC_ENTER__;
3153         GVariantIter *iter = NULL;
3154         wfd_oem_event_s event;
3155         wfd_oem_asp_prov_s *edata;
3156
3157         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3158
3159         if (!g_pd || !g_pd->callback) {
3160                 WDP_LOGD("Ignoring event");
3161                 __WDP_LOG_FUNC_EXIT__;
3162                 return;
3163         }
3164
3165         edata = (wfd_oem_asp_prov_s *) g_try_malloc0(sizeof(wfd_oem_asp_prov_s));
3166         if (!edata) {
3167                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3168                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3169                 WDP_LOGF("Failed to allocate memory for event. [%s]",
3170                                 error_buf);
3171                 __WDP_LOG_FUNC_EXIT__;
3172                 return;
3173         }
3174         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3175
3176         event.edata = (void*) edata;
3177         event.event_id = WFD_OEM_EVENT_ASP_PROV_START;
3178
3179         if (parameters != NULL) {
3180                 g_variant_get(parameters, "(a{sv})", &iter);
3181                 if (iter != NULL) {
3182                         dbus_property_foreach(iter, __ws_extract_asp_provision_start_details, &event);
3183                         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_PROV;
3184                         g_variant_iter_free(iter);
3185                 }
3186         } else {
3187                 WDP_LOGE("No Properties");
3188         }
3189
3190         if (g_pd->callback->asp_prov_start_cb)
3191                 g_pd->callback->asp_prov_start_cb(&event);
3192
3193         if (event.edata_type == WFD_OEM_EDATA_TYPE_ASP_PROV)
3194                 g_free(edata->session_information);
3195         g_free(edata);
3196
3197         __WDP_LOG_FUNC_EXIT__;
3198 }
3199
3200 static void _ws_process_asp_provision_done(GDBusConnection *connection,
3201                 const gchar *sender, const gchar *object_path, const gchar *interface,
3202                 const gchar *signal, GVariant *parameters, gpointer user_data)
3203 {
3204         __WDP_LOG_FUNC_ENTER__;
3205         GVariantIter *iter = NULL;
3206         wfd_oem_event_s event;
3207         wfd_oem_asp_prov_s *edata;
3208
3209         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3210
3211         if (!g_pd || !g_pd->callback) {
3212                 WDP_LOGD("Ignoring event");
3213                 __WDP_LOG_FUNC_EXIT__;
3214                 return;
3215         }
3216
3217         edata = (wfd_oem_asp_prov_s *) g_try_malloc0(sizeof(wfd_oem_asp_prov_s));
3218         if (!edata) {
3219                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3220                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3221                 WDP_LOGF("Failed to allocate memory for event. [%s]",
3222                                 error_buf);
3223                 __WDP_LOG_FUNC_EXIT__;
3224                 return;
3225         }
3226         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3227
3228         event.edata = (void*) edata;
3229         event.event_id = WFD_OEM_EVENT_ASP_PROV_DONE;
3230
3231         if (parameters != NULL) {
3232                 g_variant_get(parameters, "(a{sv})", &iter);
3233                 if (iter != NULL) {
3234                         dbus_property_foreach(iter, __ws_extract_asp_provision_done_details, &event);
3235                         event.edata_type = WFD_OEM_EDATA_TYPE_ASP_PROV;
3236                         g_variant_iter_free(iter);
3237                 }
3238         } else {
3239                 WDP_LOGE("No Properties");
3240         }
3241
3242         if (g_pd->callback->asp_prov_done_cb)
3243                 g_pd->callback->asp_prov_done_cb(&event);
3244
3245         g_free(edata);
3246
3247         __WDP_LOG_FUNC_EXIT__;
3248 }
3249
3250 static struct {
3251         int sub_id;
3252         const char *interface;
3253         const char *member;
3254         void (*function) (GDBusConnection *connection,
3255                         const gchar *sender, const gchar *object_path, const gchar *interface,
3256                         const gchar *signal, GVariant *parameters, gpointer user_data);
3257 } ws_p2pdevice_signal_map[] = {
3258         {
3259                 0,
3260                 SUPPLICANT_P2PDEVICE,
3261                 "DeviceFoundProperties",
3262                 _ws_process_device_found_properties
3263         },
3264         {
3265                 0,
3266                 SUPPLICANT_P2PDEVICE,
3267                 "DeviceLost",
3268                 _ws_process_device_lost
3269         },
3270         {
3271                 0,
3272                 SUPPLICANT_P2PDEVICE,
3273                 "FindStopped",
3274                 _ws_process_find_stoppped
3275         },
3276         {
3277                 0,
3278                 SUPPLICANT_P2PDEVICE,
3279                 "ProvisionDiscoveryRequestDisplayPin",
3280                 _ws_process_prov_disc_req_display_pin
3281         },
3282         {
3283                 0,
3284                 SUPPLICANT_P2PDEVICE,
3285                 "ProvisionDiscoveryResponseDisplayPin",
3286                 _ws_process_prov_disc_resp_display_pin
3287         },
3288         {
3289                 0,
3290                 SUPPLICANT_P2PDEVICE,
3291                 "ProvisionDiscoveryRequestEnterPin",
3292                 _ws_process_prov_disc_req_enter_pin
3293         },
3294         {
3295                 0,
3296                 SUPPLICANT_P2PDEVICE,
3297                 "ProvisionDiscoveryResponseEnterPin",
3298                 _ws_process_prov_disc_resp_enter_pin
3299         },
3300         {
3301                 0,
3302                 SUPPLICANT_P2PDEVICE,
3303                 "ProvisionDiscoveryPBCRequest",
3304                 _ws_process_prov_disc_pbc_req
3305         },
3306         {
3307                 0,
3308                 SUPPLICANT_P2PDEVICE,
3309                 "ProvisionDiscoveryPBCResponse",
3310                 _ws_process_prov_disc_pbc_resp
3311         },
3312         {
3313                 0,
3314                 SUPPLICANT_P2PDEVICE,
3315                 "ProvisionDiscoveryFailure",
3316                 _ws_process_prov_disc_failure
3317         },
3318         {
3319                 0,
3320                 SUPPLICANT_P2PDEVICE,
3321                 "GroupStarted",
3322                 _ws_process_group_started
3323         },
3324         {
3325                 0,
3326                 SUPPLICANT_P2PDEVICE,
3327                 "GONegotiationSuccess",
3328                 _ws_process_go_neg_success
3329         },
3330         {
3331                 0,
3332                 SUPPLICANT_P2PDEVICE,
3333                 "GONegotiationFailure",
3334                 _ws_process_go_neg_failure
3335         },
3336         {
3337                 0,
3338                 SUPPLICANT_P2PDEVICE,
3339                 "GONegotiationRequest",
3340                 _ws_process_go_neg_request
3341         },
3342         {
3343                 0,
3344                 SUPPLICANT_P2PDEVICE,
3345                 "InvitationReceived",
3346                 _ws_process_invitation_received
3347         },
3348         {
3349                 0,
3350                 SUPPLICANT_P2PDEVICE,
3351                 "InvitationResult",
3352                 _ws_process_invitation_result
3353         },
3354         {
3355                 0,
3356                 SUPPLICANT_P2PDEVICE,
3357                 "GroupFinished",
3358                 _ws_process_group_finished
3359         },
3360         {
3361                 0,
3362                 SUPPLICANT_P2PDEVICE,
3363                 "ServiceDiscoveryResponse",
3364                 _ws_process_service_discovery_response
3365         },
3366         {
3367                 0,
3368                 SUPPLICANT_P2PDEVICE,
3369                 "ServiceASPResponse",
3370                 _ws_process_service_asp_response
3371         },
3372         {
3373                 0,
3374                 SUPPLICANT_P2PDEVICE,
3375                 "ASPProvisionStart",
3376                 _ws_process_asp_provision_start
3377         },
3378         {
3379                 0,
3380                 SUPPLICANT_P2PDEVICE,
3381                 "ASPProvisionDone",
3382                 _ws_process_asp_provision_done
3383         },
3384         {
3385                 0,
3386                 SUPPLICANT_P2PDEVICE,
3387                 "PersistentGroupAdded",
3388                 _ws_process_persistent_group_added
3389         },
3390         {
3391                 0,
3392                 SUPPLICANT_P2PDEVICE,
3393                 "PersistentGroupRemoved",
3394                 _ws_process_persistent_group_removed
3395         },
3396         {
3397                 0,
3398                 SUPPLICANT_P2PDEVICE,
3399                 "WpsFailed",
3400                 _ws_process_wps_failed
3401         },
3402         {
3403                 0,
3404                 SUPPLICANT_P2PDEVICE,
3405                 "GroupFormationFailure",
3406                 _ws_process_group_formation_failure
3407         },
3408         {
3409                 0,
3410                 SUPPLICANT_P2PDEVICE,
3411                 "InvitationAccepted",
3412                 _ws_process_invitation_accepted
3413         },
3414         {
3415                 0,
3416                 NULL,
3417                 NULL,
3418                 NULL
3419         }
3420 };
3421
3422 static void _ws_process_sta_authorized(GDBusConnection *connection,
3423                 const gchar *sender, const gchar *object_path, const gchar *interface,
3424                 const gchar *signal, GVariant *parameters, gpointer user_data)
3425 {
3426         __WDP_LOG_FUNC_ENTER__;
3427         wfd_oem_event_s event;
3428         const gchar* mac_str = NULL;
3429
3430         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3431
3432         if (!g_pd || !g_pd->callback) {
3433                 WDP_LOGD("Ignoring event");
3434                 __WDP_LOG_FUNC_EXIT__;
3435                 return;
3436         }
3437
3438         if (is_peer_joined_notified) {
3439                 is_peer_joined_notified = 0;
3440                 __WDP_LOG_FUNC_EXIT__;
3441                 return;
3442         }
3443
3444         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3445         g_variant_get(parameters, "(&s)", &mac_str);
3446         __ws_txt_to_mac((unsigned char *)mac_str, event.intf_addr);
3447
3448         event.event_id = WFD_OEM_EVENT_STA_CONNECTED;
3449         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3450
3451         if (g_pd->callback->sta_connected_cb)
3452                 g_pd->callback->sta_connected_cb(&event);
3453
3454         __WDP_LOG_FUNC_EXIT__;
3455 }
3456
3457 static void _ws_process_sta_deauthorized(GDBusConnection *connection,
3458                 const gchar *sender, const gchar *object_path, const gchar *interface,
3459                 const gchar *signal, GVariant *parameters, gpointer user_data)
3460 {
3461         __WDP_LOG_FUNC_ENTER__;
3462         wfd_oem_event_s event;
3463         const gchar* mac_str = NULL;
3464
3465         DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
3466
3467         if (!g_pd || !g_pd->callback) {
3468                 WDP_LOGD("Ignoring event");
3469                 __WDP_LOG_FUNC_EXIT__;
3470                 return;
3471         }
3472
3473         if (is_peer_disconnected_notified) {
3474                 is_peer_disconnected_notified = 0;
3475                 __WDP_LOG_FUNC_EXIT__;
3476                 return;
3477         }
3478
3479         memset(&event, 0x0, sizeof(wfd_oem_event_s));
3480         g_variant_get(parameters, "(&s)", &mac_str);
3481         __ws_txt_to_mac((unsigned char *)mac_str, event.intf_addr);
3482
3483         event.event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
3484         event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
3485
3486         if (g_pd->callback->sta_disconnected_cb)
3487                 g_pd->callback->sta_disconnected_cb(&event);
3488
3489         __WDP_LOG_FUNC_EXIT__;
3490 }
3491
3492 static struct {
3493         int sub_id;
3494         const char *interface;
3495         const char *member;
3496         void (*function) (GDBusConnection *connection,
3497                         const gchar *sender, const gchar *object_path, const gchar *interface,
3498                         const gchar *signal, GVariant *parameters, gpointer user_data);
3499 } ws_interface_signal_map[] = {
3500         {
3501                 0,
3502                 SUPPLICANT_IFACE,
3503                 "StaAuthorized",
3504                 _ws_process_sta_authorized
3505         },
3506         {
3507                 0,
3508                 SUPPLICANT_IFACE,
3509                 "StaDeauthorized",
3510                 _ws_process_sta_deauthorized
3511         },
3512         {
3513                 0,
3514                 NULL,
3515                 NULL,
3516                 NULL
3517         }
3518 };
3519
3520 static struct {
3521         int sub_id;
3522         const char *interface;
3523         const char *member;
3524         void (*function) (GDBusConnection *connection,
3525                         const gchar *sender, const gchar *object_path, const gchar *interface,
3526                         const gchar *signal, GVariant *parameters, gpointer user_data);
3527 } ws_group_interface_signal_map[] = {
3528         {
3529                 0,
3530                 SUPPLICANT_IFACE,
3531                 "StaAuthorized",
3532                 _ws_process_sta_authorized
3533         },
3534         {
3535                 0,
3536                 SUPPLICANT_IFACE,
3537                 "StaDeauthorized",
3538                 _ws_process_sta_deauthorized
3539         },
3540         {
3541                 0,
3542                 NULL,
3543                 NULL,
3544                 NULL
3545         }
3546 };
3547
3548 static void __register_p2pdevice_signal(GVariant *value, void *user_data)
3549 {
3550         __WDP_LOG_FUNC_ENTER__;
3551         ws_dbus_plugin_data_s * pd_data;
3552         static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
3553         const char *path = NULL;
3554         int i = 0;
3555
3556         if (!g_pd) {
3557                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3558                 __WDP_LOG_FUNC_EXIT__;
3559                 return;
3560         }
3561
3562         pd_data = (ws_dbus_plugin_data_s *)g_pd;
3563
3564         g_variant_get(value, "(&o)", &path);
3565         g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
3566         g_strlcpy(pd_data->iface_path, path, DBUS_OBJECT_PATH_MAX);
3567
3568         WDP_LOGD("interface object path [%s]", interface_path);
3569
3570         /* subscribe Interface iface signal */
3571         for (i = 0; ws_interface_signal_map[i].member != NULL; i++) {
3572                 ws_interface_signal_map[i].sub_id =
3573                         g_dbus_connection_signal_subscribe(pd_data->g_dbus,
3574                                         SUPPLICANT_SERVICE, /* bus name */
3575                                         ws_interface_signal_map[i].interface, /* interface */
3576                                         ws_interface_signal_map[i].member, /* member */
3577                                         pd_data->iface_path, /* object path */
3578                                         NULL, /* arg0 */
3579                                         G_DBUS_SIGNAL_FLAGS_NONE,
3580                                         ws_interface_signal_map[i].function,
3581                                         NULL, NULL);
3582                 WDP_LOGD("Subscribed Interface iface signal [%s]", ws_interface_signal_map[i].member);
3583         }
3584
3585         /* subscribe P2PDevice iface signal */
3586         for (i = 0; ws_p2pdevice_signal_map[i].member != NULL; i++) {
3587                 ws_p2pdevice_signal_map[i].sub_id =
3588                         g_dbus_connection_signal_subscribe(pd_data->g_dbus,
3589                                         SUPPLICANT_SERVICE, /* bus name */
3590                                         ws_p2pdevice_signal_map[i].interface, /* interface */
3591                                         ws_p2pdevice_signal_map[i].member, /* member */
3592                                         pd_data->iface_path, /* object path */
3593                                         NULL, /* arg0 */
3594                                         G_DBUS_SIGNAL_FLAGS_NONE,
3595                                         ws_p2pdevice_signal_map[i].function,
3596                                         NULL, NULL);
3597                 WDP_LOGD("Subscribed P2PDevice iface signal [%s]", ws_p2pdevice_signal_map[i].member);
3598         }
3599
3600         __WDP_LOG_FUNC_EXIT__;
3601 }
3602
3603 static int _ws_create_interface(const char *iface_name, handle_reply function, void *user_data)
3604 {
3605         __WDP_LOG_FUNC_ENTER__;
3606         GDBusConnection *g_dbus = NULL;
3607         GVariantBuilder *builder = NULL;
3608         dbus_method_param_s params;
3609
3610         int res = 0;
3611
3612         if (!g_pd) {
3613                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3614                 __WDP_LOG_FUNC_EXIT__;
3615                 return -1;
3616         }
3617
3618         g_dbus = g_pd->g_dbus;
3619         if (!g_dbus) {
3620                 WDP_LOGE("DBus connection is NULL");
3621                 __WDP_LOG_FUNC_EXIT__;
3622                 return -1;
3623         }
3624         memset(&params, 0x0, sizeof(dbus_method_param_s));
3625
3626         dbus_set_method_param(&params, "CreateInterface", SUPPLICANT_PATH, g_dbus);
3627
3628         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
3629         g_variant_builder_add(builder, "{sv}", "Ifname", g_variant_new_string(iface_name));
3630         g_variant_builder_add(builder, "{sv}", "ConfigFile", g_variant_new_string(CONF_FILE_PATH));
3631         params.params = g_variant_new("(a{sv})", builder);
3632         g_variant_builder_unref(builder);
3633         res = dbus_method_call(&params, SUPPLICANT_INTERFACE, function, user_data);
3634         if (res < 0)
3635                 WDP_LOGE("Failed to send command to wpa_supplicant");
3636         else
3637                 WDP_LOGD("Succeeded to CreateInterface");
3638
3639         __WDP_LOG_FUNC_EXIT__;
3640         return res;
3641 }
3642
3643 static int _ws_get_interface(const char *iface_name, handle_reply function, void *user_data)
3644 {
3645         __WDP_LOG_FUNC_ENTER__;
3646         GDBusConnection *g_dbus = NULL;
3647         dbus_method_param_s params;
3648         int res = 0;
3649
3650         if (!g_pd) {
3651                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3652                 __WDP_LOG_FUNC_EXIT__;
3653                 return -1;
3654         }
3655
3656         g_dbus = g_pd->g_dbus;
3657         if (!g_dbus) {
3658                 WDP_LOGE("DBus connection is NULL");
3659                 __WDP_LOG_FUNC_EXIT__;
3660                 return -1;
3661         }
3662
3663         dbus_set_method_param(&params, SUPPLICANT_METHOD_GETINTERFACE,
3664                         SUPPLICANT_PATH, g_pd->g_dbus);
3665
3666         params.params = g_variant_new("(s)", iface_name);
3667         DEBUG_G_VARIANT("Params : ", params.params);
3668
3669         res = dbus_method_call(&params, SUPPLICANT_INTERFACE,
3670                         function, user_data);
3671
3672         if (res < 0)
3673                 WDP_LOGE("Failed to send command to wpa_supplicant");
3674         else
3675                 WDP_LOGD("Succeeded to get interface");
3676
3677         __WDP_LOG_FUNC_EXIT__;
3678         return res;
3679 }
3680
3681 static void __ws_remove_interface(GVariant *value, void *user_data)
3682 {
3683         __WDP_LOG_FUNC_ENTER__;
3684         GDBusConnection *g_dbus = NULL;
3685         dbus_method_param_s params;
3686         const char *path = NULL;
3687         static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
3688         int res = 0;
3689
3690         if (!g_pd) {
3691                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3692                 return;
3693         }
3694
3695         g_dbus = g_pd->g_dbus;
3696         if (!g_dbus) {
3697                 WDP_LOGE("DBus connection is NULL");
3698                 return;
3699         }
3700
3701         g_variant_get(value, "(&o)", &path);
3702         g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
3703         WDP_LOGD("interface object path [%s]", interface_path);
3704
3705         memset(&params, 0x0, sizeof(dbus_method_param_s));
3706
3707         dbus_set_method_param(&params, "RemoveInterface", SUPPLICANT_PATH, g_dbus);
3708         params.params = g_variant_new("(o)", interface_path);
3709
3710         res = dbus_method_call(&params, SUPPLICANT_INTERFACE, NULL, NULL);
3711         if (res < 0)
3712                 WDP_LOGE("Failed to send command to wpa_supplicant");
3713         else
3714                 WDP_LOGD("Succeeded to RemoveInterface");
3715
3716         __WDP_LOG_FUNC_EXIT__;
3717         return;
3718 }
3719
3720 static int _ws_init_dbus_connection(void)
3721 {
3722         __WDP_LOG_FUNC_ENTER__;
3723         GDBusConnection *conn = NULL;
3724         GError *error = NULL;
3725         int res = 0;
3726         int i = 0;
3727
3728         if (!g_pd) {
3729                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
3730                 __WDP_LOG_FUNC_EXIT__;
3731                 return -1;
3732         }
3733
3734         if (!config) {
3735                 WDP_LOGE("no configurable data found");
3736                 __WDP_LOG_FUNC_EXIT__;
3737                 return -1;
3738         }
3739
3740         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
3741
3742         if (conn == NULL) {
3743                 if (error != NULL) {
3744                         WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
3745                                         error->message);
3746                         g_error_free(error);
3747                 }
3748                 __WDP_LOG_FUNC_EXIT__;
3749                 return -1;
3750         }
3751
3752         g_pd->g_dbus = conn;
3753
3754         for (i = 0; ws_supplicant_signal_map[i].member != NULL; i++) {
3755                 ws_supplicant_signal_map[i].sub_id =
3756                         g_dbus_connection_signal_subscribe(g_pd->g_dbus,
3757                                         SUPPLICANT_SERVICE, /* bus name */
3758                                         ws_supplicant_signal_map[i].interface, /* interface */
3759                                         ws_supplicant_signal_map[i].member, /* member */
3760                                         SUPPLICANT_PATH, /* object path */
3761                                         NULL, /* arg0 */
3762                                         G_DBUS_SIGNAL_FLAGS_NONE,
3763                                         ws_supplicant_signal_map[i].function,
3764                                         NULL, NULL);
3765                 WDP_LOGD("Subscribed supplicant iface signal [%s]", ws_supplicant_signal_map[i].member);
3766         }
3767
3768         if (g_strcmp0(config->ifname, config->p2p_ifname) != 0) {
3769                 if (_ws_get_interface(config->ifname, NULL, NULL) < 0)
3770                         res = _ws_create_interface(config->ifname, NULL, NULL);
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         } else {
3774                 if (_ws_get_interface(config->p2p_ifname, __register_p2pdevice_signal, NULL) < 0)
3775                         res = _ws_create_interface(config->p2p_ifname, __register_p2pdevice_signal, NULL);
3776         }
3777
3778         if (res < 0)
3779                 WDP_LOGE("Failed to subscribe interface signal");
3780         else
3781                 WDP_LOGI("Successfully register signal filters");
3782
3783         __WDP_LOG_FUNC_EXIT__;
3784         return res;
3785 }
3786
3787 static int _ws_deinit_dbus_connection(void)
3788 {
3789         GDBusConnection *g_dbus = NULL;
3790         int i = 0;
3791
3792         if (!g_pd) {
3793                 WDP_LOGE("Invalid parameter");
3794                 __WDP_LOG_FUNC_EXIT__;
3795                 return -1;
3796         }
3797
3798         g_dbus = g_pd->g_dbus;
3799         if (!g_dbus) {
3800                 WDP_LOGE("DBus connection is NULL");
3801                 __WDP_LOG_FUNC_EXIT__;
3802                 return -1;
3803         }
3804
3805         for (i = 0; ws_supplicant_signal_map[i].member != NULL; i++) {
3806                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_supplicant_signal_map[i].sub_id);
3807                 ws_supplicant_signal_map[i].sub_id = 0;
3808         }
3809
3810         for (i = 0; ws_interface_signal_map[i].member != NULL; i++) {
3811                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_interface_signal_map[i].sub_id);
3812                 ws_interface_signal_map[i].sub_id = 0;
3813         }
3814
3815         for (i = 0; ws_p2pdevice_signal_map[i].member != NULL; i++) {
3816                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_p2pdevice_signal_map[i].sub_id);
3817                 ws_p2pdevice_signal_map[i].sub_id = 0;
3818         }
3819
3820         for (i = 0; ws_group_signal_map[i].member != NULL; i++) {
3821                 g_dbus_connection_signal_unsubscribe(g_dbus, ws_group_signal_map[i].sub_id);
3822                 ws_group_signal_map[i].sub_id = 0;
3823         }
3824
3825         memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
3826         memset(g_pd->iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
3827
3828         g_object_unref(g_dbus);
3829         __WDP_LOG_FUNC_EXIT__;
3830         return 0;
3831 }
3832
3833 static void _ws_manage_group_iface_signal(const gchar *group_iface_obj_path,
3834                 gboolean is_created)
3835 {
3836         __WDP_LOG_FUNC_ENTER__;
3837         GDBusConnection *connection;
3838
3839         if (!g_pd) {
3840                 WDP_LOGD("Ignore");
3841                 __WDP_LOG_FUNC_EXIT__;
3842                 return;
3843         }
3844
3845         if (!g_strcmp0(g_pd->iface_path, group_iface_obj_path)) {
3846                 WDP_LOGD("group iface is p2p iface, ignore");
3847                 __WDP_LOG_FUNC_EXIT__;
3848                 return;
3849         }
3850
3851         connection = g_pd->g_dbus;
3852         int i;
3853         if (is_created) {
3854                 /* subscribe Interface iface signal */
3855                 for (i = 0; ws_group_interface_signal_map[i].member != NULL; i++) {
3856                         ws_group_interface_signal_map[i].sub_id =
3857                                 g_dbus_connection_signal_subscribe(connection,
3858                                                 SUPPLICANT_SERVICE, /* bus name */
3859                                                 ws_group_interface_signal_map[i].interface, /* interface */
3860                                                 ws_group_interface_signal_map[i].member, /* member */
3861                                                 group_iface_obj_path, /* object path */
3862                                                 NULL, /* arg0 */
3863                                                 G_DBUS_SIGNAL_FLAGS_NONE,
3864                                                 ws_group_interface_signal_map[i].function,
3865                                                 NULL, NULL);
3866                         WDP_LOGD("Subscribed Interface iface signal [%s]", ws_group_interface_signal_map[i].member);
3867                 }
3868
3869         } else {
3870                 for (i = 0; ws_group_interface_signal_map[i].member != NULL; i++) {
3871                         g_dbus_connection_signal_unsubscribe(connection, ws_group_interface_signal_map[i].sub_id);
3872                         ws_group_interface_signal_map[i].sub_id = 0;
3873                 }
3874         }
3875         __WDP_LOG_FUNC_EXIT__;
3876         return;
3877 }
3878
3879 int wfd_plugin_load(wfd_oem_ops_s **ops)
3880 {
3881         __WDP_LOG_FUNC_ENTER__;
3882         if (!ops) {
3883                 WDP_LOGE("Invalid parameter");
3884                 __WDP_LOG_FUNC_EXIT__;
3885                 return -1;
3886         }
3887
3888         *ops = &supplicant_ops;
3889
3890         __WDP_LOG_FUNC_EXIT__;
3891         return 0;
3892 }
3893
3894 static int _ws_reset_plugin(ws_dbus_plugin_data_s *f_pd)
3895 {
3896         __WDP_LOG_FUNC_ENTER__;
3897
3898         if (!f_pd) {
3899                 WDP_LOGE("Invalid parameter");
3900                 __WDP_LOG_FUNC_EXIT__;
3901                 return -1;
3902         }
3903
3904         _ws_deinit_dbus_connection();
3905
3906         if (f_pd->activated)
3907                 ws_deactivate(f_pd->concurrent);
3908
3909         g_free(f_pd);
3910
3911         __WDP_LOG_FUNC_EXIT__;
3912         return 0;
3913 }
3914
3915 static int __ws_check_net_interface(char* if_name)
3916 {
3917         struct ifreq ifr;
3918         int fd;
3919
3920         if (if_name == NULL) {
3921                 WDP_LOGE("Invalid param");
3922                 return -1;
3923         }
3924
3925         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3926         if (fd < 0) {
3927                 WDP_LOGE("socket create error: %d", fd);
3928                 return -2;
3929         }
3930
3931         memset(&ifr, 0, sizeof(ifr));
3932         g_strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
3933
3934         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
3935                 close(fd);
3936                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3937                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3938                 WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s [ %s ]", error_buf, if_name); /* interface is not found. */
3939                 return -3;
3940         }
3941
3942         close(fd);
3943
3944         if (ifr.ifr_flags & IFF_UP) {
3945                 WDP_LOGD("%s interface is up", if_name);
3946                 return 1;
3947         } else if (!(ifr.ifr_flags & IFF_UP)) {
3948                 WDP_LOGD("%s interface is down", if_name);
3949                 return 0;
3950         }
3951         return 0;
3952 }
3953
3954 int ws_configure(wfd_oem_config_s *conf)
3955 {
3956         __WDP_LOG_FUNC_ENTER__;
3957
3958         if (conf == NULL) {
3959                 __WDP_LOG_FUNC_EXIT__;
3960                 return -1;
3961         }
3962
3963         if (config)
3964                 g_free(config);
3965
3966         config = (wfd_oem_config_s *) g_try_malloc0(sizeof(wfd_oem_config_s));
3967         if (!config) {
3968                 __WDP_LOG_FUNC_EXIT__;
3969                 return -1;
3970         }
3971
3972         memcpy(config, conf, sizeof(wfd_oem_config_s));
3973
3974         __WDP_LOG_FUNC_EXIT__;
3975         return 0;
3976 }
3977
3978 int ws_init(wfd_oem_event_cbs_s *event_cbs)
3979 {
3980         __WDP_LOG_FUNC_ENTER__;
3981
3982         if (event_cbs == NULL) {
3983                 __WDP_LOG_FUNC_EXIT__;
3984                 return -1;
3985         }
3986
3987         if (g_pd)
3988                 _ws_reset_plugin(g_pd);
3989
3990         errno = 0;
3991         g_pd = (ws_dbus_plugin_data_s*) g_try_malloc0(sizeof(ws_dbus_plugin_data_s));
3992         if (!g_pd) {
3993                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3994                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3995                 WDP_LOGE("Failed to allocate memory for plugin data. [%s]", error_buf);
3996                 return -1;
3997         }
3998
3999         g_pd->callback = event_cbs;
4000         g_pd->initialized = TRUE;
4001
4002         __WDP_LOG_FUNC_EXIT__;
4003         return 0;
4004 }
4005
4006 int ws_deinit(void)
4007 {
4008         __WDP_LOG_FUNC_ENTER__;
4009
4010         if (g_pd) {
4011                 _ws_reset_plugin(g_pd);
4012                 g_pd = NULL;
4013         }
4014
4015         if (config)
4016                 g_free(config);
4017
4018         __WDP_LOG_FUNC_EXIT__;
4019         return 0;
4020 }
4021
4022 gboolean _ws_util_execute_file(const char *file_path,
4023         char *const args[], char *const envs[])
4024 {
4025         pid_t pid = 0;
4026         int rv = 0;
4027         errno = 0;
4028         register unsigned int index = 0;
4029         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
4030
4031         while (args[index] != NULL) {
4032                 WDP_LOGD("[%s]", args[index]);
4033                 index++;
4034         }
4035
4036         if (!(pid = fork())) {
4037                 WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
4038                 WDP_LOGD("Inside child, exec (%s) command", file_path);
4039
4040                 errno = 0;
4041                 if (execve(file_path, args, envs) == -1) {
4042                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4043                         WDP_LOGE("Fail to execute command (%s)", error_buf);
4044                         exit(1);
4045                 }
4046         } else if (pid > 0) {
4047                 if (waitpid(pid, &rv, 0) == -1)
4048                         WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
4049                 if (WIFEXITED(rv))
4050                         WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
4051                 else if (WIFSIGNALED(rv))
4052                         WDP_LOGD("killed by signal %d", WTERMSIG(rv));
4053                 else if (WIFSTOPPED(rv))
4054                         WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
4055                 else if (WIFCONTINUED(rv))
4056                         WDP_LOGD("continued");
4057
4058                 return TRUE;
4059         }
4060
4061         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4062         WDP_LOGE("failed to fork (%s)", error_buf);
4063         return FALSE;
4064 }
4065
4066 static int __ws_p2p_firmware_start(const char *interface_name)
4067 {
4068         GError *error = NULL;
4069         GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
4070         if (conn == NULL) {
4071                 WDP_LOGE("Failed to get system bus");
4072         return -1;
4073         }
4074
4075         error = NULL;
4076         GVariant *params = g_variant_new("(sb)", interface_name, FALSE);
4077         GVariant *reply = g_dbus_connection_call_sync(
4078                 conn,
4079                 NETCONFIG_SERVICE, /* bus name */
4080                 NETCONFIG_WIFI_PATH, /* object path */
4081                 NETCONFIG_WIFI_INTERFACE, /* interface name */
4082                 "LoadDriver", /* method name */
4083                 params, /* GVariant *params */
4084                 NULL, /* reply_type */
4085                 G_DBUS_CALL_FLAGS_NONE, /* flags */
4086                 SUPPLICANT_TIMEOUT , /* timeout */
4087                 NULL, /* cancellable */
4088                 &error); /* error */
4089
4090         if (error != NULL) {
4091                 WDP_LOGE("Error! Failed to call method: [%s]", error->message);
4092                 g_error_free(error);
4093                 __WDP_LOG_FUNC_EXIT__;
4094         }
4095
4096         if (reply)
4097                 g_variant_unref(reply);
4098         g_object_unref(conn);
4099
4100         return 0;
4101 }
4102
4103 static int __ws_p2p_firmware_stop(const char *interface_name)
4104 {
4105         int rv = 0;
4106
4107         rv = hal_wifi_get_backend();
4108         if (rv < 0) {
4109                 WDP_LOGD("hal_wifi_get_backend() failed, ret: %d", rv);
4110                 return -1;
4111         }
4112
4113         rv = hal_wifi_stop(interface_name);
4114         if (rv < 0) {
4115                 WDP_LOGD("hal_wifi_stop() failed, ret: %d", rv);
4116                 return -1;
4117         }
4118
4119         WDP_LOGI("Successfully removed p2p device driver");
4120         return 0;
4121 }
4122
4123 static int __ws_p2p_supplicant_start(void)
4124 {
4125         gboolean rv = FALSE;
4126         const char *path = "/usr/sbin/p2p_supp.sh";
4127         char *const args[] = { "/usr/sbin/p2p_supp.sh", "start_dbus", NULL };
4128         char *const envs[] = { NULL };
4129
4130         rv = _ws_util_execute_file(path, args, envs);
4131
4132         if (rv != TRUE) {
4133                 WDP_LOGE("Failed to start p2p_supp.sh");
4134                 return -1;
4135         }
4136
4137         WDP_LOGI("Successfully started p2p_supp.sh");
4138         return 0;
4139 }
4140
4141
4142 static int __ws_p2p_supplicant_stop(void)
4143 {
4144         gboolean rv = FALSE;
4145         const char *path = "/usr/sbin/p2p_supp.sh";
4146         char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
4147         char *const envs[] = { NULL };
4148
4149         rv = _ws_util_execute_file(path, args, envs);
4150
4151         if (rv != TRUE) {
4152                 WDP_LOGE("Failed to stop p2p_supp.sh");
4153                 return -1;
4154         }
4155
4156         WDP_LOGI("Successfully stopped p2p_supp.sh");
4157         return 0;
4158 }
4159 #if 0
4160 static int __ws_p2p_on(void)
4161 {
4162         DBusError error;
4163         DBusMessage *reply = NULL;
4164         DBusMessage *message = NULL;
4165         DBusConnection *connection = NULL;
4166
4167         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
4168         if (connection == NULL) {
4169                 WDP_LOGE("Failed to get system bus");
4170                 return -EIO;
4171         }
4172
4173         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
4174                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
4175         if (message == NULL) {
4176                 WDP_LOGE("Failed DBus method call");
4177                 dbus_connection_unref(connection);
4178                 return -EIO;
4179         }
4180
4181         dbus_error_init(&error);
4182
4183         reply = dbus_connection_send_with_reply_and_block(connection, message,
4184                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
4185         if (dbus_error_is_set(&error) == TRUE) {
4186                 if (NULL != strstr(error.message, ".AlreadyExists")) {
4187                         /* p2p already enabled */
4188                 } else {
4189                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
4190                                         "DBus error [%s: %s]", error.name, error.message);
4191
4192                         dbus_error_free(&error);
4193                 }
4194
4195                 dbus_error_free(&error);
4196         }
4197
4198         if (reply != NULL)
4199                 dbus_message_unref(reply);
4200
4201         dbus_message_unref(message);
4202         dbus_connection_unref(connection);
4203
4204         return 0;
4205 }
4206
4207 static int __ws_p2p_off(void)
4208 {
4209         DBusError error;
4210         DBusMessage *reply = NULL;
4211         DBusMessage *message = NULL;
4212         DBusConnection *connection = NULL;
4213
4214         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
4215         if (connection == NULL) {
4216                 WDP_LOGE("Failed to get system bus");
4217                 return -EIO;
4218         }
4219
4220         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
4221                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
4222         if (message == NULL) {
4223                 WDP_LOGE("Failed DBus method call");
4224                 dbus_connection_unref(connection);
4225                 return -EIO;
4226         }
4227
4228         dbus_error_init(&error);
4229
4230         reply = dbus_connection_send_with_reply_and_block(connection, message,
4231                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
4232         if (dbus_error_is_set(&error) == TRUE) {
4233                 if (NULL != strstr(error.message, ".AlreadyExists")) {
4234                         /*  p2p already disabled */
4235                 } else {
4236                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
4237                                         "DBus error [%s: %s]", error.name, error.message);
4238
4239                         dbus_error_free(&error);
4240                 }
4241
4242                 dbus_error_free(&error);
4243         }
4244
4245         if (reply != NULL)
4246                 dbus_message_unref(reply);
4247
4248         dbus_message_unref(message);
4249         dbus_connection_unref(connection);
4250
4251         return 0;
4252 }
4253 #endif
4254
4255 int __ws_init_p2pdevice(void)
4256 {
4257         __WDP_LOG_FUNC_ENTER__;
4258         GDBusConnection *g_dbus = NULL;
4259
4260         GVariant *value = NULL;
4261         GVariant *param = NULL;
4262         GVariantBuilder *builder = NULL;
4263         GVariantBuilder *type_builder = NULL;
4264         dbus_method_param_s params;
4265
4266         unsigned char primary_device_type[8] = {
4267                 0x00, 0x00, 0x00, 0x50,
4268                 0xf2, 0x04, 0x00, 0x00
4269         };
4270
4271         int i = 0;
4272         int res = 0;
4273
4274         if (!g_pd) {
4275                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4276                 __WDP_LOG_FUNC_EXIT__;
4277                 return -1;
4278         }
4279
4280         if (!config) {
4281                 WDP_LOGE("no configurable data found");
4282                 __WDP_LOG_FUNC_EXIT__;
4283                 return -1;
4284         }
4285
4286         primary_device_type[1] = config->pri_dev_type;
4287         primary_device_type[7] = config->sec_dev_type;
4288
4289         for (i = 0; i < WS_DEVTYPE_LEN; i++)
4290                 WDP_LOGD("device type[%02x]", primary_device_type[i]);
4291
4292         g_dbus = g_pd->g_dbus;
4293         if (!g_dbus) {
4294                 WDP_LOGE("DBus connection is NULL");
4295                 __WDP_LOG_FUNC_EXIT__;
4296                 return -1;
4297         }
4298         memset(&params, 0x0, sizeof(dbus_method_param_s));
4299
4300         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
4301                          g_dbus);
4302
4303         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4304         g_variant_builder_add(builder, "{sv}", "DeviceName",
4305                                         g_variant_new_string(config->device_name));
4306
4307         g_variant_builder_add(builder, "{sv}", "GOIntent",
4308                                         g_variant_new_uint32(config->go_intent));
4309
4310         g_variant_builder_add(builder, "{sv}", "PersistentReconnect",
4311                                         g_variant_new_boolean(config->persistent_reconnect));
4312
4313         g_variant_builder_add(builder, "{sv}", "ListenRegClass",
4314                                         g_variant_new_uint32(config->listen_reg_class));
4315
4316         g_variant_builder_add(builder, "{sv}", "ListenChannel",
4317                                         g_variant_new_uint32(config->listen_channel));
4318
4319         g_variant_builder_add(builder, "{sv}", "OperRegClass",
4320                                         g_variant_new_uint32(config->operating_reg_class));
4321
4322         g_variant_builder_add(builder, "{sv}", "OperChannel",
4323                                         g_variant_new_uint32(config->operating_channel));
4324
4325         g_variant_builder_add(builder, "{sv}", "SsidPostfix",
4326                                         g_variant_new_string(config->device_name));
4327
4328         g_variant_builder_add(builder, "{sv}", "NoGroupIface",
4329                                         g_variant_new_boolean(config->no_group_iface));
4330
4331         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
4332         for (i = 0; i < WS_DEVTYPE_LEN; i++)
4333                 g_variant_builder_add(type_builder, "y", primary_device_type[i]);
4334         g_variant_builder_add(builder, "{sv}", "PrimaryDeviceType",
4335                         g_variant_new("ay", type_builder));
4336         g_variant_builder_unref(type_builder);
4337         value = g_variant_new("a{sv}", builder);
4338         g_variant_builder_unref(builder);
4339
4340         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
4341
4342         params.params = param;
4343         DEBUG_G_VARIANT("Params : ", params.params);
4344
4345         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4346         if (res < 0)
4347                 WDP_LOGE("Failed to send command to wpa_supplicant");
4348         else
4349                 WDP_LOGD("Succeeded to initialize p2pdevice");
4350         __WDP_LOG_FUNC_EXIT__;
4351         return res;
4352 }
4353
4354 int __ws_set_config_methods(void)
4355 {
4356         __WDP_LOG_FUNC_ENTER__;
4357         GDBusConnection *g_dbus = NULL;
4358
4359         GVariant *value = NULL;
4360         GVariant *param = NULL;
4361
4362         dbus_method_param_s params;
4363         int res = 0;
4364
4365         if (!g_pd) {
4366                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4367                 __WDP_LOG_FUNC_EXIT__;
4368                 return -1;
4369         }
4370
4371         if (!config) {
4372                 WDP_LOGE("no configurable data found");
4373                 __WDP_LOG_FUNC_EXIT__;
4374                 return -1;
4375         }
4376
4377         g_dbus = g_pd->g_dbus;
4378         if (!g_dbus) {
4379                 WDP_LOGE("DBus connection is NULL");
4380                 __WDP_LOG_FUNC_EXIT__;
4381                 return -1;
4382         }
4383         memset(&params, 0x0, sizeof(dbus_method_param_s));
4384
4385         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
4386                          g_dbus);
4387
4388         value = g_variant_new_string(config->config_methods);
4389
4390         param = g_variant_new("(ssv)", SUPPLICANT_WPS, "ConfigMethods", value);
4391         params.params = param;
4392
4393         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4394         if (res < 0)
4395                 WDP_LOGE("Failed to send command to wpa_supplicant");
4396         else
4397                 WDP_LOGD("Succeeded to set config method(%s)", config->config_methods);
4398
4399         __WDP_LOG_FUNC_EXIT__;
4400         return res;
4401 }
4402
4403 int ws_activate(int concurrent)
4404 {
4405         __WDP_LOG_FUNC_ENTER__;
4406         int res = 0;
4407         int retry_count = 0;
4408
4409         if (!g_pd) {
4410                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4411                 __WDP_LOG_FUNC_EXIT__;
4412                 return -1;
4413         }
4414
4415         if (!config) {
4416                 WDP_LOGE("no configurable data found");
4417                 __WDP_LOG_FUNC_EXIT__;
4418                 return -1;
4419         }
4420
4421         res = __ws_p2p_supplicant_start();
4422         if (res < 0) {
4423                 res = __ws_p2p_supplicant_stop();
4424                 WDP_LOGI("P2P supplicant stopped with error %d", res);
4425                 __WDP_LOG_FUNC_EXIT__;
4426                 return -1;
4427         }
4428
4429         while (retry_count < WS_CONN_RETRY_COUNT) {
4430                 /* load wlan driver */
4431                 if (concurrent == 0)
4432                         res = __ws_p2p_firmware_start(config->ifname);
4433                 if (res < 0) {
4434                         WDP_LOGE("Failed to load driver [ret=%d]", res);
4435                         return -1;
4436                 }
4437                 WDP_LOGI("P2P firmware started with error %d", res);
4438
4439                 if (__ws_check_net_interface(config->ifname) < 0) {
4440                         usleep(150000); /* wait for 150ms */
4441                         concurrent = 0;
4442                         retry_count++;
4443                         WDP_LOGE("interface is not up: retry, %d", retry_count);
4444                 } else {
4445                         break;
4446                 }
4447         }
4448
4449         if (retry_count >= WS_CONN_RETRY_COUNT) {
4450                 WDP_LOGE("Driver loading is failed [%d]", res);
4451                 __WDP_LOG_FUNC_EXIT__;
4452                 return -1;
4453         }
4454         if (retry_count > 0) {
4455                 /* Give driver marginal time to config net */
4456                 WDP_LOGE("Driver loading is done. Wait marginal time for driver");
4457                 sleep(1); /* 1s */
4458         }
4459
4460         g_pd->concurrent = concurrent;
4461
4462         res = _ws_init_dbus_connection();
4463         if (res < 0) {
4464                 res = __ws_p2p_supplicant_stop();
4465                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
4466                 res = __ws_p2p_firmware_stop(config->ifname);
4467                 WDP_LOGI("P2P firmware stopped with error %d", res);
4468                 __WDP_LOG_FUNC_EXIT__;
4469                 return -1;
4470         }
4471
4472         g_pd->activated = TRUE;
4473         __ws_init_p2pdevice();
4474         __ws_set_config_methods();
4475         seek_list = NULL;
4476
4477         __WDP_LOG_FUNC_EXIT__;
4478         return 0;
4479 }
4480
4481 int ws_deactivate(int concurrent)
4482 {
4483         __WDP_LOG_FUNC_ENTER__;
4484         wfd_oem_asp_service_s *data = NULL;
4485         int res = -1;
4486
4487         if (!g_pd) {
4488                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4489                 __WDP_LOG_FUNC_EXIT__;
4490                 return res;
4491         }
4492
4493         if (!config) {
4494                 WDP_LOGE("no configurable data found");
4495                 __WDP_LOG_FUNC_EXIT__;
4496                 return res;
4497         }
4498
4499         if (!g_pd->activated) {
4500                 WDP_LOGE("Wi-Fi Direct is not activated");
4501                 __WDP_LOG_FUNC_EXIT__;
4502                 return res;
4503         }
4504
4505         ws_stop_scan();
4506
4507         g_pd->concurrent = concurrent;
4508
4509         if (g_strcmp0(config->ifname, config->group_ifname) != 0)
4510                 _ws_get_interface(config->group_ifname, __ws_remove_interface, NULL);
4511         if (concurrent == 0)
4512                 _ws_get_interface(config->ifname, __ws_remove_interface, NULL);
4513
4514         _ws_deinit_dbus_connection();
4515
4516         if (concurrent == 0) {
4517                 res = __ws_p2p_supplicant_stop();
4518                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
4519                 res = __ws_p2p_firmware_stop(config->ifname);
4520                 WDP_LOGI("P2P firmware stopped with error %d", res);
4521         }
4522         g_pd->activated = FALSE;
4523
4524         GLIST_ITER_START(seek_list, data)
4525
4526         if (data) {
4527                 temp = g_list_next(seek_list);
4528                 seek_list = g_list_remove(seek_list, data);
4529                 g_free(data->service_type);
4530                 g_free(data->service_info);
4531                 g_free(data);
4532         }
4533
4534         GLIST_ITER_END()
4535         __WDP_LOG_FUNC_EXIT__;
4536         return 0;
4537 }
4538
4539 #if 0
4540 static gboolean _retry_start_scan(gpointer data)
4541 {
4542         __WDP_LOG_FUNC_ENTER__;
4543
4544         WDP_LOGD("Succeeded to start scan");
4545
4546         __WDP_LOG_FUNC_EXIT__;
4547         return 0;
4548 }
4549 #endif
4550
4551 static void __ws_add_seek_params(GVariantBuilder *builder)
4552 {
4553         GVariantBuilder *outter = NULL;
4554         GVariantBuilder *inner = NULL;
4555         wfd_oem_asp_service_s *data = NULL;
4556         int len = 0;
4557         int i = 0;
4558
4559         if (seek_list == NULL || g_list_length(seek_list) == 0) {
4560                 WDP_LOGD("seek list is NULL");
4561                 return;
4562         }
4563         WDP_LOGD("seek list length [%d]", g_list_length(seek_list));
4564
4565         outter = g_variant_builder_new(G_VARIANT_TYPE("aay"));
4566
4567 GLIST_ITER_START(seek_list, data)
4568         if (data && data->service_type) {
4569                 len = strlen(data->service_type) + 1;
4570                 WDP_LOGD("data [%s] len [%d]", data->service_type, len);
4571                 inner = g_variant_builder_new(G_VARIANT_TYPE("ay"));
4572                 for (i = 0; i < len; i++)
4573                         g_variant_builder_add(inner, "y", data->service_type[i]);
4574                 g_variant_builder_add(outter, "ay", inner);
4575                 g_variant_builder_unref(inner);
4576         }
4577 GLIST_ITER_END()
4578         g_variant_builder_add(builder, "{sv}", "Seek", g_variant_new("aay", outter));
4579         g_variant_builder_unref(outter);
4580
4581         return;
4582 }
4583
4584 int ws_start_scan(wfd_oem_scan_param_s *param)
4585 {
4586         __WDP_LOG_FUNC_ENTER__;
4587         GDBusConnection *g_dbus = NULL;
4588         GVariantBuilder *builder = NULL;
4589         GVariant *value = NULL;
4590         dbus_method_param_s params;
4591         int res = 0;
4592
4593         if (!param) {
4594                 WDP_LOGE("Invalid parameter");
4595                 __WDP_LOG_FUNC_EXIT__;
4596                 return -1;
4597         }
4598
4599         if (!g_pd) {
4600                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4601                 __WDP_LOG_FUNC_EXIT__;
4602                 return -1;
4603         }
4604
4605         g_dbus = g_pd->g_dbus;
4606         if (!g_dbus) {
4607                 WDP_LOGE("DBus connection is NULL");
4608                 __WDP_LOG_FUNC_EXIT__;
4609                 return -1;
4610         }
4611         memset(&params, 0x0, sizeof(dbus_method_param_s));
4612
4613         if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE) {
4614
4615                 dbus_set_method_param(&params, "Find",  g_pd->iface_path, g_dbus);
4616
4617                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4618
4619                         if (param->scan_time)
4620                                 g_variant_builder_add(builder, "{sv}", "Timeout",
4621                                                         g_variant_new_int32(param->scan_time));
4622                         if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
4623                                 g_variant_builder_add(builder, "{sv}", "DiscoveryType",
4624                                                         g_variant_new_string("social"));
4625                         if (seek_list != NULL)
4626                                 __ws_add_seek_params(builder);
4627
4628                         value = g_variant_new("(a{sv})", builder);
4629                         g_variant_builder_unref(builder);
4630         } else {
4631
4632                 dbus_set_method_param(&params, "Listen", g_pd->iface_path, g_dbus);
4633                 value = g_variant_new("(i)", param->scan_time);
4634         }
4635
4636         params.params = value;
4637         DEBUG_G_VARIANT("Params : ", params.params);
4638
4639         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4640         if (res < 0)
4641                 WDP_LOGE("Failed to send command to wpa_supplicant");
4642         else
4643                 WDP_LOGD("Succeeded to start scan");
4644
4645         __WDP_LOG_FUNC_EXIT__;
4646         return res;
4647 }
4648
4649 int ws_restart_scan(int freq)
4650 {
4651         __WDP_LOG_FUNC_ENTER__;
4652         GDBusConnection *g_dbus = NULL;
4653         GVariantBuilder *builder = NULL;
4654         GVariant *value = NULL;
4655         dbus_method_param_s params;
4656         int res = 0;
4657
4658         if (!g_pd) {
4659                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4660                 __WDP_LOG_FUNC_EXIT__;
4661                 return -1;
4662         }
4663
4664         g_dbus = g_pd->g_dbus;
4665         if (!g_dbus) {
4666                 WDP_LOGE("DBus connection is NULL");
4667                 __WDP_LOG_FUNC_EXIT__;
4668                 return -1;
4669         }
4670         memset(&params, 0x0, sizeof(dbus_method_param_s));
4671
4672         dbus_set_method_param(&params, "Find", g_pd->iface_path, g_dbus);
4673
4674         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4675         g_variant_builder_add(builder, "{sv}", "Timeout", g_variant_new_int32(2));
4676         g_variant_builder_add(builder, "{sv}", "DiscoveryType",
4677                                 g_variant_new_string("social"));
4678         value = g_variant_new("(a{sv})", builder);
4679         g_variant_builder_unref(builder);
4680
4681         params.params = value;
4682         DEBUG_G_VARIANT("Params : ", params.params);
4683
4684         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4685         if (res < 0)
4686                 WDP_LOGE("Failed to send command to wpa_supplicant");
4687         else
4688                 WDP_LOGD("Succeeded to start scan");
4689
4690         __WDP_LOG_FUNC_EXIT__;
4691         return res;
4692 }
4693
4694 int ws_stop_scan(void)
4695 {
4696         __WDP_LOG_FUNC_ENTER__;
4697         GDBusConnection *g_dbus = NULL;
4698         dbus_method_param_s params;
4699         int res = 0;
4700
4701         if (!g_pd) {
4702                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4703                 __WDP_LOG_FUNC_EXIT__;
4704                 return -1;
4705         }
4706
4707         g_dbus = g_pd->g_dbus;
4708         if (!g_dbus) {
4709                 WDP_LOGE("DBus connection is NULL");
4710                 __WDP_LOG_FUNC_EXIT__;
4711                 return -1;
4712         }
4713         memset(&params, 0x0, sizeof(dbus_method_param_s));
4714
4715         dbus_set_method_param(&params, "StopFind", g_pd->iface_path, g_dbus);
4716         params.params = NULL;
4717
4718         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4719         if (res < 0)
4720                         WDP_LOGE("Failed to send command to wpa_supplicant");
4721         else
4722                 WDP_LOGD("Succeeded to stop scan");
4723
4724         __WDP_LOG_FUNC_EXIT__;
4725         return res;
4726 }
4727
4728 int ws_get_visibility(int *visibility)
4729 {
4730         __WDP_LOG_FUNC_ENTER__;
4731
4732         __WDP_LOG_FUNC_EXIT__;
4733         return 0;
4734 }
4735
4736 int ws_set_visibility(int visibility)
4737 {
4738         __WDP_LOG_FUNC_ENTER__;
4739
4740         __WDP_LOG_FUNC_EXIT__;
4741         return 0;
4742 }
4743
4744 int ws_get_scan_result(GList **peers, int *peer_count)
4745 {
4746         __WDP_LOG_FUNC_ENTER__;
4747
4748         __WDP_LOG_FUNC_EXIT__;
4749         return 0;
4750 }
4751 static wfd_oem_device_s *__create_oem_device(void)
4752 {
4753         wfd_oem_device_s *device =
4754                         (wfd_oem_device_s *) g_try_malloc0(sizeof(wfd_oem_device_s));
4755         if (!device) {
4756                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
4757                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4758                 WDP_LOGF("Failed to allocate memory for event. [%s]",
4759                            error_buf);
4760         }
4761
4762         return device;
4763 }
4764
4765 int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
4766 {
4767         __WDP_LOG_FUNC_ENTER__;
4768         GDBusConnection *g_dbus = NULL;
4769         wfd_oem_device_s *device = NULL;
4770         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4771         int res = 0;
4772
4773         if (!peer_addr || !peer) {
4774                 WDP_LOGE("Invalid parameter");
4775                 __WDP_LOG_FUNC_EXIT__;
4776                 return -1;
4777         }
4778
4779         if (!g_pd) {
4780                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4781                 __WDP_LOG_FUNC_EXIT__;
4782                 return -1;
4783         }
4784
4785         g_dbus = g_pd->g_dbus;
4786         if (!g_dbus) {
4787                 WDP_LOGE("DBus connection is NULL");
4788                 __WDP_LOG_FUNC_EXIT__;
4789                 return -1;
4790         }
4791
4792         device = __create_oem_device();
4793         if (!device) {
4794                 __WDP_LOG_FUNC_EXIT__;
4795                 return -1;
4796         }
4797
4798         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4799                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4800
4801         WDP_LOGD("get peer path [%s]", peer_path);
4802
4803         res = dbus_property_get_all(peer_path, g_dbus, SUPPLICANT_P2P_PEER,
4804                                 __ws_get_peer_property, device);
4805
4806         if (res < 0) {
4807                 WDP_LOGE("Failed to send command to wpa_supplicant");
4808                 if (device->vsie)
4809                         g_free(device->vsie);
4810                 g_free(device);
4811                 __WDP_LOG_FUNC_EXIT__;
4812                 return -1;
4813         } else {
4814                 WDP_LOGD("succeeded to get peer info");
4815                 *peer = device;
4816         }
4817
4818         //Memory ownership of dev_data is transferred to method handler
4819         //which uses this function.
4820
4821         __WDP_LOG_FUNC_EXIT__;
4822         return 0;
4823 }
4824
4825 int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
4826 {
4827         __WDP_LOG_FUNC_ENTER__;
4828         GDBusConnection *g_dbus = NULL;
4829         GVariant *value = NULL;
4830         dbus_method_param_s params;
4831         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4832         int res = 0;
4833
4834         if (!peer_addr) {
4835                 WDP_LOGE("Invalid parameter");
4836                 __WDP_LOG_FUNC_EXIT__;
4837                 return -1;
4838         }
4839
4840         if (!g_pd) {
4841                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4842                 __WDP_LOG_FUNC_EXIT__;
4843                 return -1;
4844         }
4845
4846         g_dbus = g_pd->g_dbus;
4847         if (!g_dbus) {
4848                 WDP_LOGE("DBus connection is NULL");
4849                 __WDP_LOG_FUNC_EXIT__;
4850                 return -1;
4851         }
4852         memset(&params, 0x0, sizeof(dbus_method_param_s));
4853
4854         dbus_set_method_param(&params, "ProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
4855
4856         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4857                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4858         WDP_LOGD("get peer path [%s]", peer_path);
4859
4860         value = g_variant_new("(os)", peer_path, __ws_wps_to_txt(wps_mode));
4861
4862         params.params = value;
4863         DEBUG_G_VARIANT("Params : ", params.params);
4864
4865         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4866         if (res < 0)
4867                 WDP_LOGE("Failed to send command to wpa_supplicant");
4868         else
4869                 WDP_LOGD("Succeeded to send prov disc to peer[" MACSTR "]", MAC2STR(peer_addr));
4870
4871         __WDP_LOG_FUNC_EXIT__;
4872         return res;
4873 }
4874
4875 int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
4876 {
4877         __WDP_LOG_FUNC_ENTER__;
4878         GDBusConnection *g_dbus = NULL;
4879         GVariantBuilder *builder = NULL;
4880         GVariant *value = NULL;
4881         dbus_method_param_s params;
4882         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4883         int res = 0;
4884
4885         if (!peer_addr || !param) {
4886                 WDP_LOGE("Invalid parameter");
4887                 __WDP_LOG_FUNC_EXIT__;
4888                 return -1;
4889         }
4890
4891         if (!g_pd) {
4892                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4893                 __WDP_LOG_FUNC_EXIT__;
4894                 return -1;
4895         }
4896
4897         g_dbus = g_pd->g_dbus;
4898         if (!g_dbus) {
4899                 WDP_LOGE("DBus connection is NULL");
4900                 __WDP_LOG_FUNC_EXIT__;
4901                 return -1;
4902         }
4903         memset(&params, 0x0, sizeof(dbus_method_param_s));
4904
4905         dbus_set_method_param(&params, "Connect", g_pd->iface_path, g_dbus);
4906
4907         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4908                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4909         WDP_LOGD("get peer path [%s]", peer_path);
4910
4911         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4912         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
4913         if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
4914                 g_variant_builder_add(builder, "{sv}", "persistent", g_variant_new_boolean(TRUE));
4915
4916         if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
4917                 g_variant_builder_add(builder, "{sv}", "join", g_variant_new_boolean(TRUE));
4918
4919         if (param->conn_flags & WFD_OEM_CONN_TYPE_AUTH)
4920                 g_variant_builder_add(builder, "{sv}", "autorize_only", g_variant_new_boolean(TRUE));
4921
4922         if (param->wps_pin[0] != '\0')
4923                 g_variant_builder_add(builder, "{sv}", "pin", g_variant_new_string(param->wps_pin));
4924
4925         g_variant_builder_add(builder, "{sv}", "wps_method",
4926                                 g_variant_new_string(__ws_wps_to_txt(param->wps_mode)));
4927
4928         value = g_variant_new("(a{sv})", builder);
4929         g_variant_builder_unref(builder);
4930
4931         params.params = value;
4932         DEBUG_G_VARIANT("Params : ", params.params);
4933
4934         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4935         if (res < 0)
4936                 WDP_LOGE("Failed to send command to wpa_supplicant");
4937         else
4938                 WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
4939
4940         __WDP_LOG_FUNC_EXIT__;
4941         return res;
4942 }
4943
4944 int ws_disconnect(unsigned char *peer_addr, int is_iface_addr)
4945 {
4946         __WDP_LOG_FUNC_ENTER__;
4947         GDBusConnection *g_dbus = NULL;
4948         GVariant *value = NULL;
4949         dbus_method_param_s params;
4950         GVariantBuilder *builder = NULL;
4951         int res = 0;
4952
4953         if (!peer_addr) {
4954                 WDP_LOGE("Invalid parameter");
4955                 __WDP_LOG_FUNC_EXIT__;
4956                 return -1;
4957         }
4958
4959         if (!g_pd) {
4960                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4961                 __WDP_LOG_FUNC_EXIT__;
4962                 return -1;
4963         }
4964
4965         g_dbus = g_pd->g_dbus;
4966         if (!g_dbus) {
4967                 WDP_LOGE("DBus connection is NULL");
4968                 __WDP_LOG_FUNC_EXIT__;
4969                 return -1;
4970         }
4971         memset(&params, 0x0, sizeof(dbus_method_param_s));
4972
4973         dbus_set_method_param(&params, "RemoveClient", g_pd->iface_path, g_dbus);
4974         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4975
4976         if (is_iface_addr) {
4977                 char peer_mac_str[WS_MACSTR_LEN] = {'\0', };
4978
4979                 g_snprintf(peer_mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
4980                 WDP_LOGI("peer addr [%s]", peer_mac_str);
4981                 g_variant_builder_add(builder, "{sv}", "iface",
4982                                 g_variant_new_string(peer_mac_str));
4983         } else {
4984                 char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0', };
4985
4986                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4987                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4988                 g_variant_builder_add(builder, "{sv}", "peer",
4989                                 g_variant_new_object_path(peer_path));
4990         }
4991
4992         value = g_variant_new("(a{sv})", builder);
4993         g_variant_builder_unref(builder);
4994
4995         params.params = value;
4996         DEBUG_G_VARIANT("Params : ", params.params);
4997
4998         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4999         if (res < 0)
5000                 WDP_LOGE("Failed to send command to wpa_supplicant");
5001         else
5002                 WDP_LOGD("Succeeded to send disconnection command to peer[" MACSECSTR "]",
5003                                 MAC2SECSTR(peer_addr));
5004
5005         __WDP_LOG_FUNC_EXIT__;
5006         return res;
5007 }
5008
5009 int ws_reject_connection(unsigned char *peer_addr)
5010 {
5011         __WDP_LOG_FUNC_ENTER__;
5012         GDBusConnection *g_dbus = NULL;
5013         GVariant *value = NULL;
5014         dbus_method_param_s params;
5015         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
5016         int res = 0;
5017
5018         if (!peer_addr) {
5019                 WDP_LOGE("Invalid parameter");
5020                 __WDP_LOG_FUNC_EXIT__;
5021                 return -1;
5022         }
5023
5024         if (!g_pd) {
5025                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5026                 __WDP_LOG_FUNC_EXIT__;
5027                 return -1;
5028         }
5029
5030         g_dbus = g_pd->g_dbus;
5031         if (!g_dbus) {
5032                 WDP_LOGE("DBus connection is NULL");
5033                 __WDP_LOG_FUNC_EXIT__;
5034                 return -1;
5035         }
5036         memset(&params, 0x0, sizeof(dbus_method_param_s));
5037
5038         dbus_set_method_param(&params, "RejectPeer", g_pd->iface_path, g_dbus);
5039
5040         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
5041                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
5042         WDP_LOGE("get peer path [%s]", peer_path);
5043
5044         value = g_variant_new("(o)", peer_path);
5045
5046         params.params = value;
5047         DEBUG_G_VARIANT("Params : ", params.params);
5048
5049         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5050         if (res < 0)
5051                 WDP_LOGE("Failed to send command to wpa_supplicant");
5052         else
5053                 WDP_LOGD("Succeeded to reject peer[" MACSTR "]", MAC2STR(peer_addr));
5054
5055         _ws_flush();
5056         __WDP_LOG_FUNC_EXIT__;
5057         return res;
5058 }
5059
5060 int ws_cancel_connection(unsigned char *peer_addr)
5061 {
5062         __WDP_LOG_FUNC_ENTER__;
5063
5064         _ws_cancel();
5065
5066         __WDP_LOG_FUNC_EXIT__;
5067         return 0;
5068 }
5069
5070 int ws_get_connected_peers(GList **peers, int *peer_count)
5071 {
5072         __WDP_LOG_FUNC_ENTER__;
5073
5074         __WDP_LOG_FUNC_EXIT__;
5075         return 0;
5076 }
5077
5078 int ws_get_pin(char *pin)
5079 {
5080         __WDP_LOG_FUNC_ENTER__;
5081
5082         __WDP_LOG_FUNC_EXIT__;
5083         return 0;
5084 }
5085
5086 int ws_set_pin(char *pin)
5087 {
5088         __WDP_LOG_FUNC_ENTER__;
5089
5090         __WDP_LOG_FUNC_EXIT__;
5091         return 0;
5092 }
5093
5094 static void __ws_get_pin(GVariant *value, void *user_data)
5095 {
5096         __WDP_LOG_FUNC_ENTER__;
5097         const char *pin = NULL;
5098
5099         g_variant_get(value, "(&s)", &pin);
5100         g_strlcpy((char *)user_data, pin, OEM_PINSTR_LEN + 1);
5101
5102         __WDP_LOG_FUNC_EXIT__;
5103         return;
5104 }
5105
5106 int ws_generate_pin(char **pin)
5107 {
5108         __WDP_LOG_FUNC_ENTER__;
5109         GDBusConnection *g_dbus = NULL;
5110         dbus_method_param_s params;
5111         char n_pin[9] = {0,};
5112         int res = 0;
5113
5114         if (!g_pd) {
5115                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5116                 return -1;
5117         }
5118
5119         g_dbus = g_pd->g_dbus;
5120         if (!g_dbus) {
5121                 WDP_LOGE("DBus connection is NULL");
5122                 return -1;
5123         }
5124         memset(&params, 0x0, sizeof(dbus_method_param_s));
5125
5126         dbus_set_method_param(&params, "GeneratePin", g_pd->iface_path, g_dbus);
5127         params.params = NULL;
5128
5129         res = dbus_method_call(&params, SUPPLICANT_WPS, __ws_get_pin, (void *)n_pin);
5130         if (res < 0)
5131                 WDP_LOGE("Failed to send command to wpa_supplicant");
5132         else
5133                 WDP_LOGD("Succeeded to generate_pin [ %s ]", n_pin);
5134
5135         *pin = strndup(n_pin, OEM_PINSTR_LEN);
5136         __WDP_LOG_FUNC_EXIT__;
5137         return 0;
5138 }
5139
5140 int ws_get_supported_wps_mode(int *wps_mode)
5141 {
5142         __WDP_LOG_FUNC_ENTER__;
5143         if (!wps_mode) {
5144                 WDP_LOGE("Invalid parameter");
5145                 __WDP_LOG_FUNC_EXIT__;
5146                 return -1;
5147         }
5148
5149         *wps_mode = wps_config_method;
5150         __WDP_LOG_FUNC_EXIT__;
5151         return 0;
5152 }
5153
5154 int _ws_get_persistent_net_id(int *persistent_network_id, const unsigned char *go_dev_mac)
5155 {
5156         __WDP_LOG_FUNC_ENTER__;
5157         int persistent_group_count = 0;
5158         int counter = 0;
5159         int res = 0;
5160
5161         wfd_oem_persistent_group_s *plist = NULL;
5162
5163         res = ws_get_persistent_groups(&plist, &persistent_group_count);
5164         if (res < 0) {
5165                 WDP_LOGE("failed to get persistent groups");
5166                 __WDP_LOG_FUNC_EXIT__;
5167                 return -1;
5168         }
5169
5170         if (persistent_group_count > WS_MAX_PERSISTENT_COUNT) {
5171                 WDP_LOGE("persistent group count greater than max Persistent count");
5172                 persistent_group_count = WS_MAX_PERSISTENT_COUNT;
5173         }
5174
5175         WDP_LOGD("Persistent Group Count=%d", persistent_group_count);
5176
5177         for (counter = 0; counter < persistent_group_count ; counter++) {
5178                 if (!memcmp(go_dev_mac, plist[counter].go_mac_address, WS_MACADDR_LEN)) {
5179                         *persistent_network_id = plist[counter].network_id;
5180                         break;
5181                 } else {
5182                         WDP_LOGD("Invite: Persistent GO[" MACSTR "], GO Addr[" MACSTR "]",
5183                                         MAC2STR(plist[counter].go_mac_address), MAC2STR(go_dev_mac));
5184                 }
5185         }
5186
5187         g_free(plist);
5188         plist = NULL;
5189         WDP_LOGD("persistent network ID : [%d]", *persistent_network_id);
5190
5191         __WDP_LOG_FUNC_EXIT__;
5192         return 0;
5193 }
5194
5195 static void __store_group_iface_path(GVariant* value, void* user_data)
5196 {
5197         __WDP_LOG_FUNC_ENTER__;
5198         ws_dbus_plugin_data_s * pd_data;
5199         const char *path = NULL;
5200
5201         if (!g_pd) {
5202                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5203                 return;
5204         }
5205
5206         pd_data = (ws_dbus_plugin_data_s *) g_pd;
5207
5208         g_variant_get(value, "(&o)", &path);
5209         g_strlcpy(pd_data->group_iface_path, path, DBUS_OBJECT_PATH_MAX);
5210
5211         WDP_LOGD("group object path [%s]", pd_data->group_iface_path);
5212         /* subscribe interface p2p signal */
5213 }
5214
5215 int ws_create_group(wfd_oem_group_param_s *param)
5216 {
5217         __WDP_LOG_FUNC_ENTER__;
5218         GDBusConnection *g_dbus = NULL;
5219         GVariantBuilder *builder = NULL;
5220         GVariant *value = NULL;
5221         dbus_method_param_s params;
5222         char persistent_group_obj_path[OBJECT_PATH_MAX] = {0,};
5223         int res = 0;
5224
5225         if (!param) {
5226                 WDP_LOGE("Invalid parameter");
5227                 __WDP_LOG_FUNC_EXIT__;
5228                 return -1;
5229         }
5230
5231         if (!g_pd) {
5232                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5233                 __WDP_LOG_FUNC_EXIT__;
5234                 return -1;
5235         }
5236
5237         g_dbus = g_pd->g_dbus;
5238         if (!g_dbus) {
5239                 WDP_LOGE("DBus connection is NULL");
5240                 __WDP_LOG_FUNC_EXIT__;
5241                 return -1;
5242         }
5243         memset(&params, 0x0, sizeof(dbus_method_param_s));
5244
5245         dbus_set_method_param(&params, "GroupAdd", g_pd->iface_path, g_dbus);
5246
5247         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5248
5249         if (param->persistent > 0) {
5250                 unsigned char mac_address[WS_MACADDR_LEN] = {0x00, };
5251                 int persistent_group_id = -1;
5252
5253                 res = _ws_get_local_dev_mac(mac_address);
5254                 if (res < 0) {
5255                         WDP_LOGE("failed to get local mac address");
5256                         __WDP_LOG_FUNC_EXIT__;
5257                         return -1;
5258                 }
5259
5260                 res = _ws_get_persistent_net_id(&persistent_group_id, mac_address);
5261                 if (res < 0) {
5262                         WDP_LOGE("failed to get persistent group ID");
5263                         __WDP_LOG_FUNC_EXIT__;
5264                         return -1;
5265                 }
5266
5267                 WDP_LOGD("persistent network ID : [%d]", persistent_group_id);
5268
5269                 g_variant_builder_add(builder, "{sv}", "persistent",
5270                                 g_variant_new_boolean(TRUE));
5271                 if (persistent_group_id > -1) {
5272                         g_snprintf(persistent_group_obj_path, OBJECT_PATH_MAX,
5273                                         "%s/" SUPPLICANT_PERSISTENT_GROUPS_PART "/%d",
5274                                         g_pd->iface_path, persistent_group_id);
5275                         g_variant_builder_add(builder, "{sv}", "persistent_group_object",
5276                                         g_variant_new_object_path(persistent_group_obj_path));
5277                 }
5278
5279         } else {
5280                 g_variant_builder_add(builder, "{sv}", "persistent",
5281                                 g_variant_new_boolean(FALSE));
5282         }
5283
5284         if (param->passphrase && strlen(param->passphrase) > 0)
5285                 g_variant_builder_add(builder, "{sv}", "passphrase",
5286                                 g_variant_new_string(param->passphrase));
5287
5288         if (param->ssid && strlen(param->ssid) > 0)
5289                 g_variant_builder_add(builder, "{sv}", "ssid",
5290                                 g_variant_new_string(param->ssid));
5291
5292         if (param->freq)
5293                 g_variant_builder_add(builder, "{sv}", "frequency",
5294                                 g_variant_new_int32(param->freq));
5295
5296         value = g_variant_new("(a{sv})", builder);
5297         g_variant_builder_unref(builder);
5298
5299         params.params = value;
5300         DEBUG_G_VARIANT("Params : ", params.params);
5301
5302         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
5303                         __store_group_iface_path, g_pd);
5304         if (res < 0)
5305                 WDP_LOGE("Failed to send command to wpa_supplicant");
5306         else
5307                 WDP_LOGD("Succeeded to add group");
5308
5309         __WDP_LOG_FUNC_EXIT__;
5310         return res;
5311 }
5312
5313 int ws_destroy_group(const char *ifname)
5314 {
5315         __WDP_LOG_FUNC_ENTER__;
5316         GDBusConnection *g_dbus = NULL;
5317         dbus_method_param_s params;
5318         int res = 0;
5319
5320         if (!ifname) {
5321                 WDP_LOGE("Invalid parameter");
5322                 return -1;
5323         }
5324
5325         if (!g_pd) {
5326                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5327                 __WDP_LOG_FUNC_EXIT__;
5328                 return -1;
5329         }
5330
5331         g_dbus = g_pd->g_dbus;
5332         if (!g_dbus) {
5333                 WDP_LOGE("DBus connection is NULL");
5334                 __WDP_LOG_FUNC_EXIT__;
5335                 return -1;
5336         }
5337
5338         if (g_pd->group_iface_path[0] == 0) {
5339                 WDP_LOGE("group iface path is NULL");
5340                 return -1;
5341         }
5342
5343         memset(&params, 0x0, sizeof(dbus_method_param_s));
5344
5345         dbus_set_method_param(&params, "Disconnect", g_pd->group_iface_path, g_dbus);
5346         params.params = NULL;
5347
5348         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5349         if (res < 0) {
5350                 WDP_LOGE("Failed to send command to wpa_supplicant");
5351                 __WDP_LOG_FUNC_EXIT__;
5352                 return -1;
5353         } else {
5354                 _ws_flush();
5355                 WDP_LOGD("Succeeded to remove group");
5356         }
5357
5358         __WDP_LOG_FUNC_EXIT__;
5359         return 0;
5360 }
5361
5362 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
5363 {
5364         __WDP_LOG_FUNC_ENTER__;
5365         GDBusConnection *g_dbus = NULL;
5366         GVariantBuilder *builder = NULL;
5367         GVariant *value = NULL;
5368         dbus_method_param_s params;
5369         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
5370         int res = 0;
5371
5372         if (!peer_addr || !param) {
5373                 WDP_LOGE("Invalid parameter");
5374                 return -1;
5375         }
5376
5377         if (!g_pd) {
5378                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5379                 __WDP_LOG_FUNC_EXIT__;
5380                 return -1;
5381         }
5382
5383         g_dbus = g_pd->g_dbus;
5384         if (!g_dbus) {
5385                 WDP_LOGE("DBus connection is NULL");
5386                 __WDP_LOG_FUNC_EXIT__;
5387                 return -1;
5388         }
5389         memset(&params, 0x0, sizeof(dbus_method_param_s));
5390
5391         dbus_set_method_param(&params, "Invite", g_pd->group_iface_path, g_dbus);
5392
5393         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
5394                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
5395         WDP_LOGE("get peer path [%s]", peer_path);
5396
5397         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5398         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
5399         value = g_variant_new("(a{sv})", builder);
5400         g_variant_builder_unref(builder);
5401
5402         params.params = value;
5403         DEBUG_G_VARIANT("Params : ", params.params);
5404
5405         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5406         if (res < 0)
5407                 WDP_LOGE("Failed to send command to wpa_supplicant");
5408         else
5409                 WDP_LOGD("Succeeded to invite peer[" MACSTR "]", MAC2STR(peer_addr));
5410
5411         __WDP_LOG_FUNC_EXIT__;
5412         return 0;
5413 }
5414
5415 /* Only group owner can use this command */
5416 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
5417 {
5418         __WDP_LOG_FUNC_ENTER__;
5419         GDBusConnection *g_dbus = NULL;
5420         GVariantBuilder *builder = NULL;
5421         GVariant *value = NULL;
5422         GVariant *dev_addr = NULL;
5423         dbus_method_param_s params;
5424         int i = 0;
5425         int res = 0;
5426
5427         if (!g_pd) {
5428                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5429                 __WDP_LOG_FUNC_EXIT__;
5430                 return -1;
5431         }
5432
5433         g_dbus = g_pd->g_dbus;
5434         if (!g_dbus) {
5435                 WDP_LOGE("DBus connection is NULL");
5436                 __WDP_LOG_FUNC_EXIT__;
5437                 return -1;
5438         }
5439
5440         memset(&params, 0x0, sizeof(dbus_method_param_s));
5441
5442         dbus_set_method_param(&params, "Start", g_pd->group_iface_path, g_dbus);
5443
5444         if (peer_addr != NULL) {
5445                 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
5446                 for (i = 0; i < WS_MACADDR_LEN; i++)
5447                         g_variant_builder_add(builder, "y", peer_addr[i]);
5448
5449                 dev_addr = g_variant_new("ay", builder);
5450                 g_variant_builder_unref(builder);
5451         }
5452
5453         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5454         g_variant_builder_add(builder, "{sv}", "Role", g_variant_new_string("enrollee"));
5455         if (peer_addr != NULL)
5456                 g_variant_builder_add(builder, "{sv}", "P2PDeviceAddress", dev_addr);
5457
5458         if (pin != NULL && pin[0] != '\0') {
5459                 g_variant_builder_add(builder, "{sv}", "Type", g_variant_new_string("pin"));
5460                 g_variant_builder_add(builder, "{sv}", "Pin", g_variant_new_string(pin));
5461         } else {
5462                 g_variant_builder_add(builder, "{sv}", "Type", g_variant_new_string("pbc"));
5463         }
5464
5465         value = g_variant_new("(a{sv})", builder);
5466         g_variant_builder_unref(builder);
5467
5468         params.params = value;
5469         DEBUG_G_VARIANT("Params : ", params.params);
5470
5471         res = dbus_method_call(&params, SUPPLICANT_WPS, NULL, NULL);
5472         if (res < 0)
5473                 WDP_LOGE("Failed to send command to wpa_supplicant");
5474         else
5475                 WDP_LOGD("Succeeded to run wps");
5476
5477         __WDP_LOG_FUNC_EXIT__;
5478         return 0;
5479 }
5480
5481 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
5482 {
5483         __WDP_LOG_FUNC_ENTER__;
5484
5485         WDP_LOGD("Succeeded to start WPS");
5486
5487         __WDP_LOG_FUNC_EXIT__;
5488         return 0;
5489 }
5490
5491 int ws_wps_cancel(void)
5492 {
5493         __WDP_LOG_FUNC_ENTER__;
5494         GDBusConnection *g_dbus = NULL;
5495         dbus_method_param_s params;
5496         int res = 0;
5497
5498         g_dbus = g_pd->g_dbus;
5499         if (!g_dbus) {
5500                 WDP_LOGE("DBus connection is NULL");
5501                 __WDP_LOG_FUNC_EXIT__;
5502                 return -1;
5503         }
5504         memset(&params, 0x0, sizeof(dbus_method_param_s));
5505
5506         dbus_set_method_param(&params, "Cancel", g_pd->group_iface_path, g_dbus);
5507         params.params = NULL;
5508
5509         res = dbus_method_call(&params, SUPPLICANT_WPS, NULL, NULL);
5510         if (res < 0)
5511                 WDP_LOGE("Failed to send command to wpa_supplicant");
5512         else
5513                 WDP_LOGD("Succeeded to cancel WPS");
5514
5515         __WDP_LOG_FUNC_EXIT__;
5516         return 0;
5517 }
5518
5519 int ws_get_dev_name(char *dev_name)
5520 {
5521         __WDP_LOG_FUNC_ENTER__;
5522
5523         __WDP_LOG_FUNC_EXIT__;
5524         return 0;
5525 }
5526
5527 int ws_set_dev_name(char *dev_name)
5528 {
5529         __WDP_LOG_FUNC_ENTER__;
5530         GDBusConnection *g_dbus = NULL;
5531
5532         GVariant *value = NULL;
5533         GVariant *param = NULL;
5534         GVariantBuilder *builder = NULL;
5535         dbus_method_param_s params;
5536         int res = 0;
5537
5538         if (!dev_name) {
5539                 WDP_LOGE("Invalid parameter");
5540                 __WDP_LOG_FUNC_EXIT__;
5541                 return -1;
5542         }
5543
5544         if (!g_pd) {
5545                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5546                 __WDP_LOG_FUNC_EXIT__;
5547                 return -1;
5548         }
5549
5550         g_dbus = g_pd->g_dbus;
5551         if (!g_dbus) {
5552                 WDP_LOGE("DBus connection is NULL");
5553                 __WDP_LOG_FUNC_EXIT__;
5554                 return -1;
5555         }
5556         memset(&params, 0x0, sizeof(dbus_method_param_s));
5557
5558         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5559                          g_dbus);
5560
5561         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5562         g_variant_builder_add(builder, "{sv}", "DeviceName",
5563                                 g_variant_new_string(dev_name));
5564         g_variant_builder_add(builder, "{sv}", "SsidPostfix",
5565                                  g_variant_new_string(dev_name));
5566         value = g_variant_new("a{sv}", builder);
5567         g_variant_builder_unref(builder);
5568
5569         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE,
5570                                 "P2PDeviceConfig", value);
5571
5572         params.params = param;
5573         DEBUG_G_VARIANT("Params : ", params.params);
5574
5575         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5576         if (res < 0)
5577                 WDP_LOGE("Failed to send command to wpa_supplicant");
5578         else
5579                 WDP_LOGD("Succeeded to set device name");
5580
5581         __WDP_LOG_FUNC_EXIT__;
5582         return res;
5583 }
5584
5585 int ws_get_dev_mac(char *dev_mac)
5586 {
5587         __WDP_LOG_FUNC_ENTER__;
5588
5589         __WDP_LOG_FUNC_EXIT__;
5590         return 0;
5591 }
5592
5593 int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
5594 {
5595         __WDP_LOG_FUNC_ENTER__;
5596
5597         __WDP_LOG_FUNC_EXIT__;
5598         return 0;
5599 }
5600
5601 int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
5602 {
5603         __WDP_LOG_FUNC_ENTER__;
5604
5605         __WDP_LOG_FUNC_EXIT__;
5606         return 0;
5607 }
5608
5609 int ws_get_go_intent(int *go_intent)
5610 {
5611         __WDP_LOG_FUNC_ENTER__;
5612         GDBusConnection *g_dbus = NULL;
5613         GVariant *param = NULL;
5614         GVariant *reply = NULL;
5615         GError *error = NULL;
5616         GVariantIter *iter = NULL;
5617
5618
5619         if (!go_intent) {
5620                 WDP_LOGE("Invalid parameter");
5621                 return -1;
5622         }
5623
5624         if (!g_pd) {
5625                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5626                 __WDP_LOG_FUNC_EXIT__;
5627                 return -1;
5628         }
5629
5630         g_dbus = g_pd->g_dbus;
5631         if (!g_dbus) {
5632                 WDP_LOGE("DBus connection is NULL");
5633                 __WDP_LOG_FUNC_EXIT__;
5634                 return -1;
5635         }
5636
5637         param = g_variant_new("(ss)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig");
5638         DEBUG_G_VARIANT("Params : ", param);
5639
5640         reply = g_dbus_connection_call_sync(
5641                         g_dbus,
5642                         SUPPLICANT_SERVICE, /* bus name */
5643                         g_pd->iface_path, /* object path */
5644                         DBUS_PROPERTIES_INTERFACE, /* interface name */
5645                         DBUS_PROPERTIES_METHOD_GET, /* method name */
5646                         param, /* GVariant *params */
5647                         NULL, /* reply_type */
5648                         G_DBUS_CALL_FLAGS_NONE, /* flags */
5649                         SUPPLICANT_TIMEOUT , /* timeout */
5650                         NULL, /* cancellable */
5651                         &error); /* error */
5652
5653         if (error != NULL) {
5654                 WDP_LOGE("Error! Failed to get interface State: [%s]",
5655                                 error->message);
5656                 g_error_free(error);
5657                 if (reply)
5658                         g_variant_unref(reply);
5659                 __WDP_LOG_FUNC_EXIT__;
5660                 return -1;
5661         }
5662
5663         if (reply != NULL) {
5664                 g_variant_get(reply, "(a{sv})", &iter);
5665
5666                 if (iter != NULL) {
5667                         gchar *key = NULL;
5668                         GVariant *value = NULL;
5669
5670                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
5671                                 CHECK_KEY_VALUE(key, value);
5672
5673                                 if (g_strcmp0(key, "GOIntent") == 0)
5674                                         g_variant_get(value, "u", go_intent);
5675                         }
5676                         g_variant_iter_free(iter);
5677                 }
5678                 g_variant_unref(reply);
5679         }
5680         __WDP_LOG_FUNC_EXIT__;
5681         return 0;
5682 }
5683
5684 int ws_set_go_intent(int go_intent)
5685 {
5686         __WDP_LOG_FUNC_ENTER__;
5687         GDBusConnection *g_dbus = NULL;
5688
5689         GVariant *value = NULL;
5690         GVariant *param = NULL;
5691         GVariantBuilder *builder = NULL;
5692         dbus_method_param_s params;
5693         int res = 0;
5694
5695         if (!g_pd) {
5696                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5697                 __WDP_LOG_FUNC_EXIT__;
5698                 return -1;
5699         }
5700
5701         g_dbus = g_pd->g_dbus;
5702         if (!g_dbus) {
5703                 WDP_LOGE("DBus connection is NULL");
5704                 __WDP_LOG_FUNC_EXIT__;
5705                 return -1;
5706         }
5707         memset(&params, 0x0, sizeof(dbus_method_param_s));
5708
5709         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5710                          g_dbus);
5711
5712         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5713         g_variant_builder_add(builder, "{sv}", "GOIntent",
5714                                 g_variant_new_uint32(go_intent));
5715         value = g_variant_new("a{sv}", builder);
5716         g_variant_builder_unref(builder);
5717
5718         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
5719
5720         params.params = param;
5721         DEBUG_G_VARIANT("Params : ", params.params);
5722
5723         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5724         if (res < 0)
5725                 WDP_LOGE("Failed to send command to wpa_supplicant");
5726         else
5727                 WDP_LOGE("Succeeded to set go intent");
5728         __WDP_LOG_FUNC_EXIT__;
5729         return res;
5730 }
5731
5732 int ws_set_country(char *ccode)
5733 {
5734         __WDP_LOG_FUNC_ENTER__;
5735         __WDP_LOG_FUNC_ENTER__;
5736         GDBusConnection *g_dbus = NULL;
5737
5738         GVariant *value = NULL;
5739         GVariant *param = NULL;
5740
5741         dbus_method_param_s params;
5742         int res = 0;
5743
5744         if (!g_pd) {
5745                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5746                 __WDP_LOG_FUNC_EXIT__;
5747                 return -1;
5748         }
5749
5750         g_dbus = g_pd->g_dbus;
5751         if (!g_dbus) {
5752                 WDP_LOGE("DBus connection is NULL");
5753                 __WDP_LOG_FUNC_EXIT__;
5754                 return -1;
5755         }
5756         memset(&params, 0x0, sizeof(dbus_method_param_s));
5757
5758         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5759                          g_dbus);
5760
5761         value = g_variant_new_string(ccode);
5762
5763         param = g_variant_new("(ssv)", SUPPLICANT_IFACE, "Country", value);
5764
5765         params.params = param;
5766         DEBUG_G_VARIANT("Params : ", params.params);
5767
5768         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5769         if (res < 0)
5770                 WDP_LOGE("Failed to send command to wpa_supplicant");
5771         else
5772                 WDP_LOGD("Succeeded to set country(%s)", ccode);
5773
5774         __WDP_LOG_FUNC_EXIT__;
5775         return res;
5776 }
5777
5778 void __parsing_networks(const char* key, GVariant* value, void* user_data)
5779 {
5780         __WDP_LOG_FUNC_ENTER__;
5781         if (!user_data) {
5782                 __WDP_LOG_FUNC_EXIT__;
5783                 return;
5784         }
5785
5786         ws_network_info_s *network = (ws_network_info_s *)user_data;
5787
5788         CHECK_KEY_VALUE(key, value);
5789
5790         if (g_strcmp0(key, "ssid") == 0) {
5791                 const char *ssid = NULL;
5792                 g_variant_get(value, "&s", &ssid);
5793                 WDP_LOGD("ssid [%s]", ssid);
5794                 g_strlcpy(network->ssid, ssid + 1, WS_SSID_LEN + 1);
5795                 network->ssid[strlen(ssid) - 2] = '\0';
5796
5797         } else if (g_strcmp0(key, "bssid") == 0) {
5798                 unsigned char *bssid = NULL;
5799                 g_variant_get(value, "&s", &bssid);
5800                 WDP_LOGD("bssid [%s]", bssid);
5801                 __ws_txt_to_mac(bssid, network->bssid);
5802
5803         } else if (g_strcmp0(key, "proto") == 0) {
5804                 const char *proto = NULL;
5805                 g_variant_get(value, "&s", &proto);
5806                 WDP_LOGD("proto [%s]", proto);
5807
5808                 if (g_strrstr(proto, WFD_OEM_STR_PROTO_WPA) != NULL)
5809                         network->proto |= WFD_OEM_PROTO_WPA;
5810                 if (g_strrstr(proto, WFD_OEM_STR_PROTO_RSN) != NULL)
5811                         network->proto |= WFD_OEM_PROTO_RSN;
5812
5813         } else if (g_strcmp0(key, "key_mgmt") == 0) {
5814                 const char *key_mgmt = NULL;
5815                 g_variant_get(value, "&s", &key_mgmt);
5816                 WDP_LOGD("key_mgmt [%s]", key_mgmt);
5817
5818                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_IEEE8021X) != NULL)
5819                         network->key_mgmt |= WFD_OEM_KEY_MGMT_IEEE8021X;
5820                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_PSK) != NULL)
5821                         network->key_mgmt |= WFD_OEM_KEY_MGMT_PSK;
5822                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_NONE) != NULL)
5823                         network->key_mgmt |= WFD_OEM_KEY_MGMT_NONE;
5824
5825         } else if (g_strcmp0(key, "pairwise") == 0) {
5826                 const char *pairwise = NULL;
5827                 g_variant_get(value, "&s", &pairwise);
5828                 WDP_LOGD("pairwise [%s]", pairwise);
5829
5830                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_NONE) != NULL)
5831                         network->pairwise |= WFD_OEM_CIPHER_NONE;
5832                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_TKIP) != NULL)
5833                         network->pairwise |= WFD_OEM_CIPHER_TKIP;
5834                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_CCMP) != NULL)
5835                         network->pairwise |= WFD_OEM_CIPHER_CCMP;
5836
5837         }  else if (g_strcmp0(key, "group") == 0) {
5838                 const char *group = NULL;
5839                 g_variant_get(value, "&s", &group);
5840                 WDP_LOGD("group [%s]", group);
5841
5842                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_NONE) != NULL)
5843                         network->group |= WFD_OEM_CIPHER_NONE;
5844                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_WEP40) != NULL)
5845                         network->group |= WFD_OEM_CIPHER_WEP40;
5846                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_WEP104) != NULL)
5847                         network->group |= WFD_OEM_CIPHER_WEP104;
5848                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_TKIP) != NULL)
5849                         network->group |= WFD_OEM_CIPHER_TKIP;
5850                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_CCMP) != NULL)
5851                         network->group |= WFD_OEM_CIPHER_CCMP;
5852
5853         } else if (g_strcmp0(key, "auth_alg") == 0) {
5854                 const char *auth_alg = NULL;
5855                 g_variant_get(value, "&s", &auth_alg);
5856                 WDP_LOGD("auth_alg [%s]", auth_alg);
5857
5858                 if (g_strrstr(auth_alg, WFD_OEM_STR_AUTH_ALG_OPEN) != NULL)
5859                         network->auth_alg |= WFD_OEM_AUTH_ALG_OPEN;
5860
5861         } else if (g_strcmp0(key, "mode") == 0) {
5862                 const char *mode = NULL;
5863                 g_variant_get(value, "&s", &mode);
5864                 WDP_LOGD("mode [%s]", mode);
5865
5866                 if (g_strrstr(mode, WFD_OEM_STR_MODE_GC) != NULL)
5867                         network->mode |= WFD_OEM_PERSISTENT_MODE_GC;
5868                 if (g_strrstr(mode, WFD_OEM_STR_MODE_GO) != NULL)
5869                         network->mode |= WFD_OEM_PERSISTENT_MODE_GO;
5870
5871         } else if (g_strcmp0(key, "p2p_client_list") == 0) {
5872                 const char *p2p_client_list = NULL;
5873                 char *ptr = NULL;
5874                 int list_len = 0;
5875                 int num = 0;
5876
5877                 g_variant_get(value, "&s", &p2p_client_list);
5878                 WDP_LOGD("p2p_client_list [%s]", p2p_client_list);
5879                 ptr = (char *)p2p_client_list;
5880                 list_len = strlen(p2p_client_list);
5881                 WDP_LOGD("list_len [%d]", list_len);
5882                 while (ptr && list_len >= (OEM_MACSTR_LEN - 1)) {
5883                         __ws_txt_to_mac((unsigned char *)ptr, (network->p2p_client_list[num]));
5884                         ptr += OEM_MACSTR_LEN;
5885                         list_len -= OEM_MACSTR_LEN;
5886                         if (ptr && ptr[0] == ' ') {
5887                                 ptr += 1;
5888                                 list_len -= 1;
5889                         }
5890                         num++;
5891                         if (num >= OEM_MAX_PEER_NUM)
5892                                 break;
5893                 }
5894                 network->p2p_client_num = num;
5895                 WDP_LOGD("p2p_client_num [%d]", network->p2p_client_num);
5896         }
5897         return;
5898 }
5899
5900 void __ws_extract_p2pdevice_details(const char *key, GVariant *value, void *user_data)
5901 {
5902         __WDP_LOG_FUNC_ENTER__;
5903         CHECK_KEY_VALUE(key, value);
5904
5905         if (g_strcmp0(key, "PersistentGroups") == 0) {
5906                 GVariantIter *iter = NULL;
5907                 const char *path = NULL;
5908                 int num = 0;
5909
5910                 ws_network_info_s *networks = NULL;
5911                 networks = (ws_network_info_s *)user_data;
5912                 if (!networks) {
5913                         WDP_LOGE("network is NULL");
5914                         __WDP_LOG_FUNC_EXIT__;
5915                         return;
5916                 }
5917
5918                 g_variant_get(value, "ao", &iter);
5919                 while (g_variant_iter_loop(iter, "&o", &path)) {
5920                         char *loc = NULL;
5921
5922                         if (num >= WS_MAX_PERSISTENT_COUNT)
5923                                 break;
5924
5925                         WDP_LOGD("Retrive persistent path [%s]", path);
5926                         g_strlcpy(networks[num].persistent_path, path, DBUS_OBJECT_PATH_MAX);
5927
5928                         loc = strrchr(networks[num].persistent_path, '/');
5929                         if (loc)
5930                                 networks[num].network_id = strtoul(loc+1, NULL, 10);
5931
5932                         WDP_LOGD("Retrive persistent path [%s]", networks[num].persistent_path);
5933                         dbus_property_get_all(networks[num].persistent_path, g_pd->g_dbus,
5934                                         SUPPLICANT_P2P_PERSISTENTGROUP, __parsing_networks, &networks[num]);
5935                         num++;
5936                 }
5937
5938                 networks[0].total = num;
5939                 WDP_LOGI("total number [%d]", num);
5940                 g_variant_iter_free(iter);
5941         }
5942         __WDP_LOG_FUNC_EXIT__;
5943 }
5944
5945
5946 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
5947 {
5948         __WDP_LOG_FUNC_ENTER__;
5949         GDBusConnection *g_dbus = NULL;
5950
5951         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
5952         wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
5953         int i, cnt = 0;
5954
5955         if (!g_pd) {
5956                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5957                 __WDP_LOG_FUNC_EXIT__;
5958                 return -1;
5959         }
5960
5961         g_dbus = g_pd->g_dbus;
5962         if (!g_dbus) {
5963                 WDP_LOGE("DBus connection is NULL");
5964                 __WDP_LOG_FUNC_EXIT__;
5965                 return -1;
5966         }
5967
5968         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
5969         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
5970                         __ws_extract_p2pdevice_details, &networks[0]);
5971
5972         cnt = networks[0].total;
5973
5974         WDP_LOGD("Persistent Group Count=%d", cnt);
5975         if (cnt > WS_MAX_PERSISTENT_COUNT) {
5976                 WDP_LOGE("Persistent group count exceeded or parsing error");
5977                 __WDP_LOG_FUNC_EXIT__;
5978                 return -1;
5979         }
5980
5981         if (cnt == 0) {
5982                 WDP_LOGE("Persistent group count zero");
5983                 *group_count = 0;
5984                 *groups = NULL;
5985                 __WDP_LOG_FUNC_EXIT__;
5986                 return 0;
5987         }
5988
5989         wfd_persistent_groups = (wfd_oem_persistent_group_s *) g_try_malloc0(cnt * sizeof(wfd_oem_persistent_group_s));
5990         if (wfd_persistent_groups == NULL) {
5991                 WDP_LOGE("Failed to allocate memory for wfd_persistent_groups ");
5992                 __WDP_LOG_FUNC_EXIT__;
5993                 return -1;
5994         }
5995
5996         for (i = 0; i < cnt; i++) {
5997                 int j = 0;
5998
5999                 WDP_LOGD("----persistent group [%d]----", i);
6000                 WDP_LOGD("network_id [%d]", networks[i].network_id);
6001                 WDP_LOGD("ssid [%s]", networks[i].ssid);
6002                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
6003                 WDP_LOGD("p2p_client_num [%d]", networks[i].p2p_client_num);
6004                 for (j = 0; j < networks[i].p2p_client_num; j++)
6005                         WDP_LOGD("p2p_client_list ["MACSTR"]", MAC2STR(networks[i].p2p_client_list[j]));
6006
6007                 wfd_persistent_groups[i].network_id = networks[i].network_id;
6008                 g_strlcpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN + 1);
6009                 memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
6010                 wfd_persistent_groups[i].p2p_client_num = networks[i].p2p_client_num;
6011                 if (wfd_persistent_groups[i].p2p_client_num > 0)
6012                         memcpy(wfd_persistent_groups[i].p2p_client_list, networks[i].p2p_client_list,
6013                                         OEM_MACADDR_LEN * OEM_MAX_PEER_NUM * sizeof(char));
6014         }
6015
6016         *group_count = cnt;
6017         *groups = wfd_persistent_groups;
6018
6019         __WDP_LOG_FUNC_EXIT__;
6020         return 0;
6021 }
6022
6023 int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
6024 {
6025         __WDP_LOG_FUNC_ENTER__;
6026         GDBusConnection *g_dbus = NULL;
6027
6028         dbus_method_param_s params;
6029         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
6030         int i, cnt = 0;
6031         int res = 0;
6032
6033         if (!g_pd) {
6034                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6035                 __WDP_LOG_FUNC_EXIT__;
6036                 return -1;
6037         }
6038
6039         g_dbus = g_pd->g_dbus;
6040         if (!g_dbus) {
6041                 WDP_LOGE("DBus connection is NULL");
6042                 __WDP_LOG_FUNC_EXIT__;
6043                 return -1;
6044         }
6045         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
6046         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
6047                         __ws_extract_p2pdevice_details, networks);
6048
6049         cnt = networks[0].total;
6050
6051         WDP_LOGD("Persistent Group Count=%d", cnt);
6052         if (cnt > WS_MAX_PERSISTENT_COUNT) {
6053                 WDP_LOGE("Persistent group count exceeded or parsing error");
6054                 __WDP_LOG_FUNC_EXIT__;
6055                 return -1;
6056         }
6057
6058         for (i = 0; i < cnt; i++) {
6059                 int j = 0;
6060
6061                 WDP_LOGD("----persistent group [%d]----", i);
6062                 WDP_LOGD("network_id [%d]", networks[i].network_id);
6063                 WDP_LOGD("network ssid [%s]", networks[i].ssid);
6064                 WDP_LOGD("network bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
6065                 WDP_LOGD("network p2p_client_num [%d]", networks[i].p2p_client_num);
6066                 for (j = 0; j < networks[i].p2p_client_num; j++)
6067                         WDP_LOGD("network p2p_client_list ["MACSTR"]",
6068                                         MAC2STR(networks[i].p2p_client_list[j]));
6069
6070                 WDP_LOGD("ssid [%s]", ssid);
6071                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(bssid));
6072
6073                 if (!g_strcmp0(ssid, networks[i].ssid) &&
6074                                 !memcmp(bssid, networks[i].bssid, WS_MACADDR_LEN)) {
6075                         WDP_LOGD("Persistent group owner found [%d: %s]",
6076                                         networks[i].network_id, ssid);
6077
6078                         memset(&params, 0x0, sizeof(dbus_method_param_s));
6079                         dbus_set_method_param(&params, "RemovePersistentGroup",
6080                                         g_pd->iface_path, g_dbus);
6081                         params.params = g_variant_new("(o)", networks[i].persistent_path);
6082                         DEBUG_G_VARIANT("Params : ", params.params);
6083
6084                         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6085                         if (res < 0) {
6086                                 WDP_LOGE("Failed to send command to wpa_supplicant");
6087                                 __WDP_LOG_FUNC_EXIT__;
6088                                 return -1;
6089                         }
6090
6091                         WDP_LOGD("Succeeded to remove persistent group");;
6092                         break;
6093                 }
6094         }
6095
6096         if (i == cnt) {
6097                 WDP_LOGE("Persistent group not found [%s]", ssid);
6098                 return -1;
6099         }
6100
6101         __WDP_LOG_FUNC_EXIT__;
6102         return 0;
6103 }
6104
6105 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
6106 {
6107         __WDP_LOG_FUNC_ENTER__;
6108         GDBusConnection *g_dbus = NULL;
6109
6110         GVariant *value = NULL;
6111         GVariant *param = NULL;
6112         GVariantBuilder *builder = NULL;
6113         dbus_method_param_s params;
6114         int res = 0;
6115
6116         if (!g_pd) {
6117                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6118                 __WDP_LOG_FUNC_EXIT__;
6119                 return -1;
6120         }
6121
6122         g_dbus = g_pd->g_dbus;
6123         if (!g_dbus) {
6124                 WDP_LOGE("DBus connection is NULL");
6125                 __WDP_LOG_FUNC_EXIT__;
6126                 return -1;
6127         }
6128         memset(&params, 0x0, sizeof(dbus_method_param_s));
6129
6130         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
6131                         g_dbus);
6132
6133         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6134         g_variant_builder_add(builder, "{sv}", "PersistentReconnect",
6135                                 g_variant_new_boolean(reconnect));
6136         value = g_variant_new("a{sv}", builder);
6137         g_variant_builder_unref(builder);
6138
6139         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
6140
6141         params.params = param;
6142         DEBUG_G_VARIANT("Params : ", params.params);
6143
6144         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6145         if (res < 0)
6146                 WDP_LOGE("Failed to send command to wpa_supplicant");
6147         else
6148                 WDP_LOGD("Succeeded to set persistent reconnect");
6149
6150         __WDP_LOG_FUNC_EXIT__;
6151         return res;
6152 }
6153
6154 static int __ws_compress_query(char *compressed, char *query, int qtype)
6155 {
6156         char *token = NULL;
6157         char *temp = NULL;
6158         int token_num = 0;
6159         int token_len = 0;
6160         int length = 0;
6161
6162         token = strtok_r(query, ".", &temp);
6163         while (token) {
6164                 if (!strcmp(token, "local")) {
6165                         WDP_LOGD("Query conversion done");
6166                         break;
6167
6168                 } else if (!strncmp(token, "_tcp", 4)) {
6169                         memcpy(&compressed[length], WS_TCP_PTR_HEX, 2);
6170                         length += 2;
6171
6172                 } else if (!strncmp(token, "_udp", 4)) {
6173                         memcpy(&compressed[length], WS_UDP_PTR_HEX, 2);
6174                         length += 2;
6175
6176                 } else {
6177                         WDP_LOGD("Token: [%s]", token);
6178                         token_len = strlen(token);
6179                         compressed[length] = token_len;
6180                         length++;
6181
6182                         memcpy(&compressed[length], token, token_len);
6183                         length += token_len;
6184                 }
6185                 token_num++;
6186                 token = strtok_r(NULL, ".", &temp);
6187         }
6188         if (qtype == WS_QTYPE_PTR || token_num == 2)
6189                 memcpy(&compressed[length], WS_PTR_TYPE_HEX, 3);
6190         else if (qtype == WS_QTYPE_TXT || token_num == 3)
6191                 memcpy(&compressed[length], WS_TXT_TYPE_HEX, 3);
6192
6193         length += 3;
6194         WDP_LOGD("converted query length [%d] token num [%d]", length, token_num);
6195
6196         return length;
6197 }
6198
6199 static int __ws_compress_rdata(char *compressed, char *rdata, int qtype)
6200 {
6201         char *token = NULL;
6202         char *temp = NULL;
6203         int token_len = 0;
6204         int length = 0;
6205
6206         if (qtype == WS_QTYPE_PTR) {
6207
6208                 token = strtok_r(rdata, ".", &temp);
6209                 if (token) {
6210                         WDP_LOGD("Token: %s", token);
6211                         token_len = strlen(token);
6212                         compressed[length] = token_len;
6213                         length++;
6214
6215                         memcpy(&compressed[length], token, token_len);
6216                         length += token_len;
6217                 }
6218
6219                 compressed[length] = 0xc0;
6220                 compressed[length+1] = 0x27;
6221                 length += 2;
6222
6223         } else if (qtype == WS_QTYPE_TXT) {
6224
6225                 token = strtok_r(rdata, ",", &temp);
6226
6227                 while (token) {
6228                         WDP_LOGD("Token: [%s]", token);
6229
6230                         token_len = strlen(token);
6231                         compressed[length] = token_len;
6232                         length++;
6233
6234                         memcpy(&compressed[length], token, token_len);
6235                         length += token_len;
6236
6237                         token = strtok_r(NULL, ",", &temp);
6238                 }
6239         } else {
6240                 WDP_LOGD("RDATA is NULL");
6241         }
6242         return length;
6243 }
6244
6245 int _convert_bonjour_to_args(char *query, char *rdata, GVariantBuilder *builder)
6246 {
6247         GVariantBuilder *args = NULL;
6248         char compressed[256] = {0, };
6249         char *temp = NULL;
6250         int length = 0;
6251         int qtype = 0;
6252         int i = 0;
6253
6254         if (!query || !builder) {
6255                 WDP_LOGE("Invalid parameter");
6256                 return -1;
6257         }
6258         if (!rdata || !strlen(rdata)) {
6259                 WDP_LOGD("RDATA is NULL\n");
6260         } else {
6261                 temp = strstr(rdata, query);
6262
6263                 if (temp != NULL && temp - rdata > 0)
6264                         qtype = WS_QTYPE_PTR;
6265                 else
6266                         qtype = WS_QTYPE_TXT;
6267                 temp = NULL;
6268         }
6269
6270         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("bonjour"));
6271
6272         /* compress query */
6273         length = __ws_compress_query(compressed, query, qtype);
6274
6275         args = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6276         for (i = 0; i < length; i++)
6277                 g_variant_builder_add(args, "y", compressed[i]);
6278         g_variant_builder_add(builder, "{sv}", "query", g_variant_new("ay", args));
6279         g_variant_builder_unref(args);
6280
6281         memset(compressed, 0x0, 256);
6282         length = 0;
6283         args = NULL;
6284
6285         if (qtype != 0) {
6286                 length = __ws_compress_rdata(compressed, rdata, qtype);
6287
6288                 args = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6289                 for (i = 0; i < length; i++)
6290                         g_variant_builder_add(args, "y", compressed[i]);
6291                 g_variant_builder_add(builder, "{sv}", "response", g_variant_new("ay", args));
6292                 g_variant_builder_unref(args);
6293         }
6294
6295         return 0;
6296 }
6297
6298 int _check_service_query_exists(wfd_oem_service_s *service)
6299 {
6300         int count = 0;
6301         wfd_oem_service_s *data = NULL;
6302
6303         for (count = 0; count < g_list_length(service_list); count++) {
6304                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
6305                 if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
6306                         WDP_LOGD("Query already exists");
6307                         return 1;
6308                 }
6309         }
6310         return 0;
6311 }
6312
6313 static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
6314 {
6315         if (NULL == s_type || NULL == mac_str || NULL == query_id)
6316                 return NULL;
6317
6318         int count = 0;
6319         wfd_oem_service_s *data = NULL;
6320
6321         for (count = 0; count < g_list_length(service_list); count++) {
6322                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
6323                 if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
6324                                 memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
6325                         g_strlcpy(query_id, data->query_id, OEM_QUERY_ID_LEN + 1);
6326                         break;
6327                 }
6328         }
6329         if (strlen(query_id) <= 0) {
6330                 WDP_LOGD("!! Query ID not found !!");
6331                 return NULL;
6332         }
6333
6334         WDP_LOGD("query id :[%s]", query_id);
6335
6336         return data;
6337 }
6338
6339 void __add_service_query(GVariant *value, void *user_data)
6340 {
6341         __WDP_LOG_FUNC_ENTER__;
6342         wfd_oem_service_s *service = NULL;
6343
6344         long long unsigned ref = 0;
6345         int res = 0;
6346
6347         if (!user_data)
6348                 return;
6349
6350         g_variant_get(value, "(t)", &ref);
6351
6352         service = (wfd_oem_service_s*) g_try_malloc0(sizeof(wfd_oem_service_s));
6353         if (!service) {
6354                 WDP_LOGE("Failed to allocate memory for service");
6355                 return;
6356         }
6357
6358         memcpy(service, user_data, sizeof(wfd_oem_service_s));
6359
6360         g_snprintf(service->query_id, OEM_QUERY_ID_LEN + 1, "%llx", ref);
6361
6362         res = _check_service_query_exists(service);
6363         if (res)
6364                 g_free(service);
6365         else
6366                 service_list = g_list_append(service_list, service);
6367
6368         __WDP_LOG_FUNC_EXIT__;
6369         return;
6370
6371 }
6372
6373 /* for now, supplicant dbus interface only provides upnp service fully */
6374 int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
6375 {
6376         __WDP_LOG_FUNC_ENTER__;
6377         GDBusConnection *g_dbus = NULL;
6378         GVariantBuilder *builder = NULL;
6379         GVariant *value = NULL;
6380         wfd_oem_service_s data = {0,};
6381         dbus_method_param_s params;
6382         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
6383         int i = 0;
6384         int res = 0;
6385
6386         if (!mac_addr) {
6387                 WDP_LOGE("Invalid parameter");
6388                 __WDP_LOG_FUNC_EXIT__;
6389                 return -1;
6390         }
6391
6392         if (!g_pd) {
6393                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6394                 __WDP_LOG_FUNC_EXIT__;
6395                 return -1;
6396         }
6397
6398         g_dbus = g_pd->g_dbus;
6399         if (!g_dbus) {
6400                 WDP_LOGE("DBus connection is NULL");
6401                 __WDP_LOG_FUNC_EXIT__;
6402                 return -1;
6403         }
6404         memset(&params, 0x0, sizeof(dbus_method_param_s));
6405
6406         dbus_set_method_param(&params, "ServiceDiscoveryRequest", g_pd->iface_path, g_dbus);
6407
6408         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6409
6410         if (mac_addr && !ISZEROMACADDR(mac_addr)) {
6411                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
6412                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(mac_addr));
6413                 WDP_LOGD("get peer path [%s]", peer_path);
6414                 g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
6415         }
6416
6417         if (service_type == WFD_OEM_SERVICE_TYPE_ALL) {
6418
6419                 char *service_all = "\x02\x00\x00\x01";
6420                 GVariantBuilder *query = NULL;
6421
6422                 query = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6423                 for (i = 0; i < SERVICE_QUERY_LEN; i++)
6424                         g_variant_builder_add(query, "y", service_all[i]);
6425                 g_variant_builder_add(builder, "{sv}", "query", g_variant_new("ay", query));
6426                 g_variant_builder_unref(query);
6427                 g_strlcpy(data.service_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
6428
6429         } else if (service_type == WFD_OEM_SERVICE_TYPE_UPNP) {
6430
6431                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6432                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6433                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string("ssdp:all"));
6434                 g_strlcpy(data.service_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
6435
6436         } else if (service_type == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6437
6438                 char *service_bonjour = "\x02\x00\x01\x01";
6439                 GVariantBuilder *query = NULL;
6440
6441                 query = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6442                 for (i = 0; i < SERVICE_QUERY_LEN; i++)
6443                         g_variant_builder_add(query, "y", service_bonjour[i]);
6444                 g_variant_builder_add(builder, "{sv}", "tlv", g_variant_new("ay", query));
6445                 g_variant_builder_unref(query);
6446                 g_strlcpy(data.service_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
6447         }
6448
6449         value = g_variant_new("(a{sv})", builder);
6450         g_variant_builder_unref(builder);
6451
6452         params.params = value;
6453         DEBUG_G_VARIANT("Params : ", params.params);
6454
6455         if (ISZEROMACADDR(mac_addr))
6456                 snprintf(data.dev_addr, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
6457         else
6458                 snprintf(data.dev_addr, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
6459
6460         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, __add_service_query, &data);
6461         if (res < 0)
6462                 WDP_LOGE("Failed to send command to wpa_supplicant");
6463         else
6464                 WDP_LOGD("Succeeded to start service discovery");
6465
6466         __WDP_LOG_FUNC_EXIT__;
6467         return res;
6468 }
6469
6470 int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
6471 {
6472         __WDP_LOG_FUNC_ENTER__;
6473         GDBusConnection *g_dbus = NULL;
6474         dbus_method_param_s params;
6475         wfd_oem_service_s *data = NULL;
6476         char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
6477         char s_type[OEM_SERVICE_TYPE_LEN + 1] = {0, };
6478         char mac_str[18] = {0, };
6479         long long unsigned id;
6480
6481         int res = 0;
6482
6483         if (!mac_addr) {
6484                 WDP_LOGE("Invalid parameter");
6485                 __WDP_LOG_FUNC_EXIT__;
6486                 return -1;
6487         }
6488
6489         if (!g_pd) {
6490                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6491                 __WDP_LOG_FUNC_EXIT__;
6492                 return -1;
6493         }
6494
6495         g_dbus = g_pd->g_dbus;
6496         if (!g_dbus) {
6497                 WDP_LOGE("DBus connection is NULL");
6498                 __WDP_LOG_FUNC_EXIT__;
6499                 return -1;
6500         }
6501
6502         if (ISZEROMACADDR(mac_addr)) {
6503                 snprintf(mac_str, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
6504         } else {
6505                 snprintf(mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
6506         }
6507
6508         switch (service_type) {
6509         case WFD_OEM_SERVICE_TYPE_ALL:
6510                 g_strlcpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
6511         break;
6512         case WFD_OEM_SERVICE_TYPE_BONJOUR:
6513                 g_strlcpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
6514         break;
6515         case WFD_OEM_SERVICE_TYPE_UPNP:
6516                 g_strlcpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
6517         break;
6518         default:
6519                 WDP_LOGE("Invalid Service type");
6520                 __WDP_LOG_FUNC_EXIT__;
6521                 return -1;
6522         }
6523
6524         WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
6525         WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
6526
6527         data = _remove_service_query(s_type, mac_str, query_id);
6528         if (NULL == data) {
6529                 __WDP_LOG_FUNC_EXIT__;
6530                 return -1;
6531         }
6532         memset(&params, 0x0, sizeof(dbus_method_param_s));
6533
6534         dbus_set_method_param(&params, "ServiceDiscoveryCancelRequest", g_pd->iface_path, g_dbus);
6535         id = (long long unsigned)strtoul(query_id, NULL, 16);
6536         params.params = g_variant_new("(t)", id);
6537
6538         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6539         if (res < 0)
6540                 WDP_LOGE("Failed to send command to wpa_supplicant");
6541         else
6542                 WDP_LOGD("Succeeded to cancel service discovery");
6543
6544         service_list = g_list_remove(service_list, data);
6545         free(data);
6546
6547         __WDP_LOG_FUNC_EXIT__;
6548         return res;
6549 }
6550
6551 int ws_serv_add(wfd_oem_new_service_s *service)
6552 {
6553         __WDP_LOG_FUNC_ENTER__;
6554         GDBusConnection *g_dbus = NULL;
6555         GVariantBuilder *builder = NULL;
6556         GVariant *value = NULL;
6557         dbus_method_param_s params;
6558         int res = 0;
6559
6560         if (!g_pd) {
6561                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6562                 __WDP_LOG_FUNC_EXIT__;
6563                 return -1;
6564         }
6565
6566         g_dbus = g_pd->g_dbus;
6567         if (!g_dbus) {
6568                 WDP_LOGE("DBus connection is NULL");
6569                 __WDP_LOG_FUNC_EXIT__;
6570                 return -1;
6571         }
6572         memset(&params, 0x0, sizeof(dbus_method_param_s));
6573
6574         dbus_set_method_param(&params, "AddService", g_pd->iface_path, g_dbus);
6575
6576         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6577
6578         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6579
6580                 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
6581                 WDP_LOGD("Query: %s", service->data.bonjour.query);
6582                 WDP_LOGD("RData: %s", service->data.bonjour.rdata);
6583
6584                 res = _convert_bonjour_to_args(service->data.bonjour.query,
6585                                                             service->data.bonjour.rdata, builder);
6586                 if (res < 0) {
6587                         WDP_LOGE("Failed to convert Key string");
6588                         g_variant_builder_unref(builder);
6589                         return -1;
6590                 }
6591
6592         } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
6593                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6594                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6595                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
6596         }
6597
6598         value = g_variant_new("(a{sv})", builder);
6599         g_variant_builder_unref(builder);
6600
6601         params.params = value;
6602         DEBUG_G_VARIANT("Params : ", params.params);
6603
6604         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6605         if (res < 0)
6606                 WDP_LOGE("Failed to send command to wpa_supplicant");
6607         else
6608                 WDP_LOGD("Succeeded to add service");
6609
6610         __WDP_LOG_FUNC_EXIT__;
6611         return 0;
6612 }
6613
6614 int ws_serv_del(wfd_oem_new_service_s *service)
6615 {
6616         __WDP_LOG_FUNC_ENTER__;
6617         GDBusConnection *g_dbus = NULL;
6618         GVariantBuilder *builder = NULL;
6619         GVariant *value = NULL;
6620         dbus_method_param_s params;
6621         int res = 0;
6622
6623         if (!g_pd) {
6624                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6625                 __WDP_LOG_FUNC_EXIT__;
6626                 return -1;
6627         }
6628
6629         g_dbus = g_pd->g_dbus;
6630         if (!g_dbus) {
6631                 WDP_LOGE("DBus connection is NULL");
6632                 __WDP_LOG_FUNC_EXIT__;
6633                 return -1;
6634         }
6635         memset(&params, 0x0, sizeof(dbus_method_param_s));
6636
6637         dbus_set_method_param(&params, "DeleteService", g_pd->iface_path, g_dbus);
6638
6639         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6640
6641         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6642
6643                 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
6644                 WDP_LOGD("Query: %s", service->data.bonjour.query);
6645
6646                 res = _convert_bonjour_to_args(service->data.bonjour.query,
6647                                                             NULL, builder);
6648                 if (res < 0) {
6649                         WDP_LOGE("Failed to convert Key string");
6650                         g_variant_builder_unref(builder);
6651                         return -1;
6652                 }
6653
6654         } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
6655                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6656                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6657                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
6658         }
6659
6660         value = g_variant_new("(a{sv})", builder);
6661         g_variant_builder_unref(builder);
6662
6663         params.params = value;
6664         DEBUG_G_VARIANT("Params : ", params.params);
6665
6666         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6667         if (res < 0)
6668                 WDP_LOGE("Failed to send command to wpa_supplicant");
6669         else
6670                 WDP_LOGD("Succeeded to del service");
6671
6672         __WDP_LOG_FUNC_EXIT__;
6673         return 0;
6674 }
6675
6676 int _ws_disable_display()
6677 {
6678         __WDP_LOG_FUNC_ENTER__;
6679         GDBusConnection *g_dbus = NULL;
6680         GVariantBuilder *builder = NULL;
6681         GVariant *value = NULL;
6682         GVariant *param = NULL;
6683         dbus_method_param_s params;
6684         int res = 0;
6685
6686         if (!g_pd) {
6687                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6688                 __WDP_LOG_FUNC_EXIT__;
6689                 return -1;
6690         }
6691
6692         g_dbus = g_pd->g_dbus;
6693         if (!g_dbus) {
6694                 WDP_LOGE("DBus connection is NULL");
6695                 __WDP_LOG_FUNC_EXIT__;
6696                 return -1;
6697         }
6698         memset(&params, 0x0, sizeof(dbus_method_param_s));
6699
6700         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
6701                          g_dbus);
6702
6703         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6704         value = g_variant_new("ay", builder);
6705         g_variant_builder_unref(builder);
6706
6707         param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
6708
6709         params.params = param;
6710         DEBUG_G_VARIANT("Params : ", params.params);
6711
6712         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6713         if (res < 0)
6714                 WDP_LOGE("Failed to send command to wpa_supplicant");
6715         else
6716                 WDP_LOGD("Succeeded to disable Wi-Fi display");
6717
6718         __WDP_LOG_FUNC_EXIT__;
6719         return res;
6720 }
6721
6722 int ws_miracast_init(int enable)
6723 {
6724         __WDP_LOG_FUNC_ENTER__;
6725         wfd_oem_display_s wifi_display;
6726         int res = 0;
6727
6728         memset(&wifi_display, 0x0, sizeof(wfd_oem_display_s));
6729
6730         wifi_display.availability = enable;
6731         wifi_display.hdcp_support = 1;
6732         wifi_display.port = 0x07E6;
6733         wifi_display.max_tput = 0x0028;
6734
6735         res = ws_set_display(&wifi_display);
6736         if (res < 0) {
6737                 WDP_LOGE("Failed to set miracast parameter(device info)");
6738                 __WDP_LOG_FUNC_EXIT__;
6739                 return -1;
6740         }
6741
6742         if (!enable) {
6743                 res = _ws_disable_display();
6744                 if (res < 0)
6745                         WDP_LOGE("Failed to disable wifi display");
6746                 else
6747                         WDP_LOGD("Succeeded to disable wifi display");
6748         }
6749         __WDP_LOG_FUNC_EXIT__;
6750         return res;
6751 }
6752
6753 int ws_set_display(wfd_oem_display_s *wifi_display)
6754 {
6755         __WDP_LOG_FUNC_ENTER__;
6756         GDBusConnection *g_dbus = NULL;
6757
6758         GVariant *value = NULL;
6759         GVariant *param = NULL;
6760         GVariantBuilder *builder = NULL;
6761         dbus_method_param_s params;
6762         int i = 0;
6763         int res = 0;
6764
6765         unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
6766
6767         if (!wifi_display) {
6768                 WDP_LOGE("Invalid parameter");
6769                 return -1;
6770         }
6771         g_dbus = g_pd->g_dbus;
6772         if (!g_dbus) {
6773                 WDP_LOGE("DBus connection is NULL");
6774                 __WDP_LOG_FUNC_EXIT__;
6775                 return -1;
6776         }
6777         memset(&params, 0x0, sizeof(dbus_method_param_s));
6778
6779         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
6780                          g_dbus);
6781
6782         ies[2] = WFD_SUBELEM_LEN_DEV_INFO;
6783         ies[3] = wifi_display->hdcp_support;
6784         ies[4] = (wifi_display->type) | (wifi_display->availability<<4);
6785         ies[5] = wifi_display->port>>8;
6786         ies[6] = wifi_display->port&0xff;
6787         ies[7] = wifi_display->max_tput>>8;
6788         ies[8] = wifi_display->max_tput&0xff;
6789
6790         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6791         for (i = 0; i < WFD_SUBELEM_LEN_DEV_INFO + 3; i++)
6792                 g_variant_builder_add(builder, "y", ies[i]);
6793         value = g_variant_new("ay", builder);
6794         g_variant_builder_unref(builder);
6795
6796         param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
6797
6798         params.params = param;
6799         DEBUG_G_VARIANT("Params : ", params.params);
6800
6801         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6802         if (res < 0)
6803                 WDP_LOGE("Failed to send command to wpa_supplicant");
6804         else
6805                 WDP_LOGD("Succeeded to set Wi-Fi Display");
6806
6807         __WDP_LOG_FUNC_EXIT__;
6808         return res;
6809 }
6810
6811 int ws_refresh(void)
6812 {
6813         __WDP_LOG_FUNC_ENTER__;
6814
6815         _ws_cancel();
6816         _ws_flush();
6817
6818         __WDP_LOG_FUNC_EXIT__;
6819         return 0;
6820 }
6821
6822 int ws_save_config(void)
6823 {
6824         __WDP_LOG_FUNC_ENTER__;
6825         GDBusConnection *g_dbus = NULL;
6826         dbus_method_param_s params;
6827         int res = 0;
6828
6829         g_dbus = g_pd->g_dbus;
6830         if (!g_dbus) {
6831                 WDP_LOGE("DBus connection is NULL");
6832                 __WDP_LOG_FUNC_EXIT__;
6833                 return -1;
6834         }
6835         memset(&params, 0x0, sizeof(dbus_method_param_s));
6836
6837         dbus_set_method_param(&params, "SaveConfig", g_pd->iface_path, g_dbus);
6838         params.params = NULL;
6839
6840         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
6841         if (res < 0)
6842                 WDP_LOGE("Failed to save config to wpa_supplicant");
6843         else
6844                 WDP_LOGD("Succeeded to save config");
6845
6846         __WDP_LOG_FUNC_EXIT__;
6847         return res;
6848 }
6849
6850 int ws_set_operating_channel(int channel)
6851 {
6852         __WDP_LOG_FUNC_ENTER__;
6853         GDBusConnection *g_dbus = NULL;
6854         GVariant *value = NULL;
6855         GVariant *param = NULL;
6856         GVariantBuilder *builder = NULL;
6857         dbus_method_param_s params;
6858         int res = 0;
6859
6860         g_dbus = g_pd->g_dbus;
6861         if (!g_dbus) {
6862                 WDP_LOGE("DBus connection is NULL");
6863                 __WDP_LOG_FUNC_EXIT__;
6864                 return -1;
6865         }
6866
6867         memset(&params, 0x0, sizeof(dbus_method_param_s));
6868
6869         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path, g_dbus);
6870
6871         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6872         g_variant_builder_add(builder, "{sv}", "OperChannel", g_variant_new_uint32(channel));
6873         value = g_variant_new("a{sv}", builder);
6874         g_variant_builder_unref(builder);
6875
6876         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
6877         params.params = param;
6878
6879         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6880         if (res < 0)
6881                 WDP_LOGE("Failed to send command to wpa_supplicant");
6882         else
6883                 WDP_LOGD("Succeeded to set Operating Channel");
6884
6885         __WDP_LOG_FUNC_EXIT__;
6886         return res;
6887 }
6888
6889 int ws_remove_all_network(void)
6890 {
6891         __WDP_LOG_FUNC_ENTER__;
6892         GDBusConnection *g_dbus = NULL;
6893         dbus_method_param_s params;
6894         int res = 0;
6895
6896         g_dbus = g_pd->g_dbus;
6897         if (!g_dbus) {
6898                 WDP_LOGE("DBus connection is NULL");
6899                 __WDP_LOG_FUNC_EXIT__;
6900                 return -1;
6901         }
6902         memset(&params, 0x0, sizeof(dbus_method_param_s));
6903
6904         dbus_set_method_param(&params, "RemoveAllNetworks", g_pd->iface_path, g_dbus);
6905         params.params = NULL;
6906
6907         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
6908         if (res < 0)
6909                 WDP_LOGE("Failed to send [RemoveAllNetworks] command to wpa_supplicant");
6910         else
6911                 WDP_LOGD("Succeeded to remove all networks from supplicant");
6912
6913         WDP_LOGD("Succeeded to remove all network");
6914         __WDP_LOG_FUNC_EXIT__;
6915         return res;
6916 }
6917
6918 int ws_get_wpa_status(int *wpa_status)
6919 {
6920         __WDP_LOG_FUNC_ENTER__;
6921         GDBusConnection *g_dbus = NULL;
6922         GVariant *param = NULL;
6923         GVariant *reply = NULL;
6924         GError *error = NULL;
6925
6926         if (!wpa_status) {
6927                 WDP_LOGE("Invalid parameter");
6928                 __WDP_LOG_FUNC_EXIT__;
6929                 return -1;
6930         }
6931
6932         *wpa_status = WFD_OEM_WPA_STATE_MAX;
6933
6934         g_dbus = g_pd->g_dbus;
6935         if (!g_dbus) {
6936                 WDP_LOGE("DBus connection is NULL");
6937                 __WDP_LOG_FUNC_EXIT__;
6938                 return -1;
6939         }
6940
6941         param = g_variant_new("(s)", SUPPLICANT_IFACE);
6942
6943         reply = g_dbus_connection_call_sync(
6944                         g_pd->g_dbus,
6945                         SUPPLICANT_SERVICE, /* bus name */
6946                         g_pd->iface_path, /* object path */
6947                         DBUS_PROPERTIES_INTERFACE, /* interface name */
6948                         DBUS_PROPERTIES_METHOD_GETALL, /* method name */
6949                         param, /* GVariant *params */
6950                         NULL, /* reply_type */
6951                         G_DBUS_CALL_FLAGS_NONE, /* flags */
6952                         SUPPLICANT_TIMEOUT , /* timeout */
6953                         NULL, /* cancellable */
6954                         &error); /* error */
6955
6956         if (error != NULL) {
6957                 WDP_LOGE("Error! Failed to get properties: [%s]",
6958                                                         error->message);
6959                 g_error_free(error);
6960                 if (reply)
6961                         g_variant_unref(reply);
6962                 __WDP_LOG_FUNC_EXIT__;
6963                 return -1;
6964         }
6965
6966         gchar *reply_str = NULL;
6967         if (reply)
6968                 reply_str = g_variant_print(reply, TRUE);
6969         WDP_LOGE("reply [%s]", reply_str ? reply_str : "NULL");
6970         g_free(reply_str);
6971
6972         if (reply != NULL) {
6973                 GVariantIter *iter = NULL;
6974                 g_variant_get(reply, "(a{sv})", &iter);
6975
6976                 if (iter != NULL) {
6977                         gchar *key = NULL;
6978                         GVariant *value = NULL;
6979
6980                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
6981                                 if (g_strcmp0(key, "State") == 0) {
6982                                         const gchar *state = NULL;
6983                                         g_variant_get(value, "&s", &state);
6984                                         WDP_LOGI("state : [%s]", state);
6985
6986                                         if (g_strcmp0(state, "disconnected") == 0)
6987                                                 *wpa_status = WFD_OEM_WPA_STATE_DISCONNECTED;
6988                                         else if (g_strcmp0(state, "inactive") == 0)
6989                                                 *wpa_status = WFD_OEM_WPA_STATE_INACTIVE;
6990                                         else if (g_strcmp0(state, "scanning") == 0)
6991                                                 *wpa_status = WFD_OEM_WPA_STATE_SCANNING;
6992                                         else if (g_strcmp0(state, "authenticating") == 0)
6993                                                 *wpa_status = WFD_OEM_WPA_STATE_AUTHENTICATING;
6994                                         else if (g_strcmp0(state, "associating") == 0)
6995                                                 *wpa_status = WFD_OEM_WPA_STATE_ASSOCIATING;
6996                                         else if (g_strcmp0(state, "associated") == 0)
6997                                                 *wpa_status = WFD_OEM_WPA_STATE_ASSOCIATED;
6998                                         else if (g_strcmp0(state, "4way_handshake") == 0)
6999                                                 *wpa_status = WFD_OEM_WPA_STATE_4WAY_HANDSHAKE;
7000                                         else if (g_strcmp0(state, "group_handshake") == 0)
7001                                                 *wpa_status = WFD_OEM_WPA_STATE_GROUP_HANDSHAKE;
7002                                         else if (g_strcmp0(state, "completed") == 0)
7003                                                 *wpa_status = WFD_OEM_WPA_STATE_COMPLETED;
7004                                         else
7005                                                 *wpa_status = WFD_OEM_WPA_STATE_MAX;
7006                                 }
7007                         }
7008                         g_variant_iter_free(iter);
7009                 }
7010                 g_variant_unref(reply);
7011         } else {
7012                 WDP_LOGD("No properties");
7013         }
7014
7015         WDP_LOGI("wpa_status : [%d]", *wpa_status);
7016
7017         __WDP_LOG_FUNC_EXIT__;
7018         return 0;
7019 }
7020
7021 int ws_advertise_service(wfd_oem_asp_service_s *service, int replace)
7022 {
7023         __WDP_LOG_FUNC_ENTER__;
7024         GDBusConnection *g_dbus = NULL;
7025         GVariantBuilder *builder = NULL;
7026         GVariant *value = NULL;
7027         dbus_method_param_s params;
7028         unsigned int config_method = 0x1108;
7029         int auto_accept = 0;
7030         gboolean rep;
7031         int res = 0;
7032
7033         g_dbus = g_pd->g_dbus;
7034         if (!g_dbus) {
7035                 WDP_LOGE("DBus connection is NULL");
7036                 return -1;
7037         }
7038
7039         if (service->config_method == 2) {
7040                 config_method = WS_CONFIG_METHOD_KEYPAD |
7041                                 WS_CONFIG_METHOD_DISPLAY;
7042         } else if (service->config_method == 3) {
7043                 config_method = WS_CONFIG_METHOD_DISPLAY;
7044         } else if (service->config_method == 4) {
7045                 config_method = WS_CONFIG_METHOD_KEYPAD;
7046         }
7047
7048         if (service->auto_accept) {
7049                 if (service->role == 0)
7050                         auto_accept = 1;
7051                 else
7052                         auto_accept = 2;
7053         } else {
7054                 auto_accept = 0;
7055         }
7056
7057         rep = (replace == 1);
7058
7059         memset(&params, 0x0, sizeof(dbus_method_param_s));
7060
7061         dbus_set_method_param(&params, "AddService", g_pd->iface_path, g_dbus);
7062
7063         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7064
7065         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("asp"));
7066         g_variant_builder_add(builder, "{sv}", "auto_accept", g_variant_new_int32(auto_accept));
7067         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(service->adv_id));
7068         g_variant_builder_add(builder, "{sv}", "svc_state", g_variant_new_uint32(service->status));
7069         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new_uint32(config_method));
7070         g_variant_builder_add(builder, "{sv}", "replace", g_variant_new_boolean(rep));
7071         if (service->service_type != NULL)
7072                 g_variant_builder_add(builder, "{sv}", "adv_str",
7073                         g_variant_new_string(service->service_type));
7074         if (service->service_info != NULL)
7075                 g_variant_builder_add(builder, "{sv}", "svc_info",
7076                                 g_variant_new_string(service->service_info));
7077         if (service->instance_name != NULL)
7078                 g_variant_builder_add(builder, "{sv}", "svc_instance",
7079                                 g_variant_new_string(service->instance_name));
7080
7081         value = g_variant_new("(a{sv})", builder);
7082         g_variant_builder_unref(builder);
7083         DEBUG_G_VARIANT("Params : ", value);
7084
7085         params.params = value;
7086
7087         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7088         if (res < 0)
7089                 WDP_LOGE("Failed to send command to wpa_supplicant");
7090         else
7091                 WDP_LOGD("Succeeded to add service");
7092
7093         __WDP_LOG_FUNC_EXIT__;
7094         return 0;
7095 }
7096
7097 int ws_cancel_advertise_service(wfd_oem_asp_service_s *service)
7098 {
7099         __WDP_LOG_FUNC_ENTER__;
7100         GDBusConnection *g_dbus = NULL;
7101         GVariantBuilder *builder = NULL;
7102         GVariant *value = NULL;
7103         dbus_method_param_s params;
7104         int res = 0;
7105
7106         g_dbus = g_pd->g_dbus;
7107         if (!g_dbus) {
7108                 WDP_LOGE("DBus connection is NULL");
7109                 return -1;
7110         }
7111         memset(&params, 0x0, sizeof(dbus_method_param_s));
7112
7113         dbus_set_method_param(&params, "DeleteService", g_pd->iface_path, g_dbus);
7114
7115         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7116
7117         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("asp"));
7118         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(service->adv_id));
7119
7120         value = g_variant_new("(a{sv})", builder);
7121         g_variant_builder_unref(builder);
7122         DEBUG_G_VARIANT("Params : ", value);
7123         params.params = value;
7124
7125         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7126         if (res < 0)
7127                 WDP_LOGE("Failed to send command to wpa_supplicant");
7128         else
7129                 WDP_LOGD("Succeeded to del service");
7130
7131         __WDP_LOG_FUNC_EXIT__;
7132         return 0;
7133 }
7134
7135 static void __ws_add_seek(wfd_oem_asp_service_s *service)
7136 {
7137         __WDP_LOG_FUNC_ENTER__;
7138         wfd_oem_asp_service_s *seek = NULL;
7139         if (!service) {
7140                 WDP_LOGE("invalid parameters");
7141                 return;
7142         }
7143
7144         seek = g_try_malloc0(sizeof(wfd_oem_asp_service_s));
7145         if (!seek) {
7146                 WDP_LOGE("Failed to allocate memory for service");
7147                 return;
7148         }
7149
7150         service->search_id = (intptr_t)seek;
7151         memcpy(seek, service, sizeof(wfd_oem_asp_service_s));
7152         if (service->service_type)
7153                 seek->service_type = strdup(service->service_type);
7154         seek_list = g_list_prepend(seek_list, seek);
7155
7156         __WDP_LOG_FUNC_EXIT__;
7157         return;
7158 }
7159
7160 static wfd_oem_asp_service_s * __ws_get_seek(long long unsigned asp_search_id)
7161 {
7162         __WDP_LOG_FUNC_ENTER__;
7163         wfd_oem_asp_service_s *seek = NULL;
7164         GList *list = NULL;
7165
7166         for (list = seek_list; list != NULL; list = list->next) {
7167                 seek = list->data;
7168                 if (seek && (seek->asp_search_id == asp_search_id)) {
7169                         WDP_LOGD("List found");
7170                         break;
7171                 } else {
7172                         seek = NULL;
7173                 }
7174         }
7175         __WDP_LOG_FUNC_EXIT__;
7176         return seek;
7177 }
7178
7179 static void __ws_remove_seek(wfd_oem_asp_service_s *service)
7180 {
7181         __WDP_LOG_FUNC_ENTER__;
7182         wfd_oem_asp_service_s *seek = NULL;
7183         GList *list = NULL;
7184
7185         for (list = seek_list; list != NULL; list = list->next) {
7186
7187                 seek = list->data;
7188                 if (seek && (seek->asp_search_id == service->asp_search_id)) {
7189                         WDP_LOGD("List remove");
7190                         seek_list = g_list_remove(seek_list, seek);
7191                         g_free(seek->service_type);
7192                         g_free(seek->service_info);
7193                         g_free(seek);
7194                 }
7195         }
7196         __WDP_LOG_FUNC_EXIT__;
7197         return;
7198 }
7199
7200 static void __get_asp_search_id(GVariant *value, void *args)
7201 {
7202         __WDP_LOG_FUNC_ENTER__;
7203         wfd_oem_asp_service_s *service = NULL;
7204         wfd_oem_asp_service_s *seek = NULL;
7205         long long unsigned search_id = 0;
7206
7207         g_variant_get(value, "(t)", &search_id);
7208
7209         service = (wfd_oem_asp_service_s *)args;
7210         if (!service) {
7211                 WDP_LOGE("invalid parameters");
7212                 __WDP_LOG_FUNC_EXIT__;
7213                 return;
7214         }
7215
7216         seek = g_try_malloc0(sizeof(wfd_oem_asp_service_s));
7217         if (!seek) {
7218                 WDP_LOGE("Failed to allocate memory for service");
7219                 __WDP_LOG_FUNC_EXIT__;
7220                 return;
7221         }
7222
7223         service->search_id = search_id;
7224         memcpy(seek, service, sizeof(wfd_oem_asp_service_s));
7225         if (service->service_type)
7226                 seek->service_type = strdup(service->service_type);
7227         if (service->service_info)
7228                 seek->service_info = strdup(service->service_info);
7229         seek_list = g_list_append(seek_list, seek);
7230
7231         __WDP_LOG_FUNC_EXIT__;
7232         return;
7233 }
7234
7235 int ws_seek_service(wfd_oem_asp_service_s *service)
7236 {
7237         __WDP_LOG_FUNC_ENTER__;
7238         GDBusConnection *g_dbus = NULL;
7239         GList *list = NULL;
7240         wfd_oem_asp_service_s *seek = NULL;
7241         int res = 0;
7242
7243         g_dbus = g_pd->g_dbus;
7244         if (!g_dbus) {
7245                 WDP_LOGE("DBus connection is NULL");
7246                 __WDP_LOG_FUNC_EXIT__;
7247                 return -1;
7248         }
7249         list = g_list_last(seek_list);
7250         if (list == NULL) {
7251                 service->tran_id = 1;
7252
7253         } else {
7254                 seek = list->data;
7255                 if (seek)
7256                         service->tran_id = seek->tran_id + 1;
7257                 else
7258                         service->tran_id = 1;
7259         }
7260
7261         if (service->service_info) {
7262                 GVariantBuilder *builder = NULL;
7263                 GVariant *value = NULL;
7264                 dbus_method_param_s params;
7265
7266                 memset(&params, 0x0, sizeof(dbus_method_param_s));
7267                 dbus_set_method_param(&params, "ServiceDiscoveryRequest",
7268                                 g_pd->iface_path, g_dbus);
7269
7270                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7271
7272                 g_variant_builder_add(builder, "{sv}", "service_type",
7273                                 g_variant_new_string("asp"));
7274                 g_variant_builder_add(builder, "{sv}", "transaction_id",
7275                                 g_variant_new_byte(service->tran_id));
7276                 if (service->service_type != NULL)
7277                         g_variant_builder_add(builder, "{sv}", "svc_str",
7278                                         g_variant_new_string(service->service_type));
7279
7280                 if (service->service_info != NULL)
7281                         g_variant_builder_add(builder, "{sv}", "svc_info",
7282                                         g_variant_new_string(service->service_info));
7283
7284                 if (service->instance_name != NULL)
7285                         g_variant_builder_add(builder, "{sv}", "svc_instance",
7286                                         g_variant_new_string(service->instance_name));
7287
7288                 value = g_variant_new("(a{sv})", builder);
7289                 g_variant_builder_unref(builder);
7290
7291                 DEBUG_G_VARIANT("Params : ", value);
7292
7293                 params.params = value;
7294                 res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
7295                                 __get_asp_search_id, service);
7296
7297         } else {
7298                 __ws_add_seek(service);
7299         }
7300
7301         if (res < 0)
7302                 WDP_LOGE("Failed to send command to wpa_supplicant");
7303         else
7304                 WDP_LOGD("Succeeded to seek service");
7305
7306         __WDP_LOG_FUNC_EXIT__;
7307         return res;
7308 }
7309
7310 int ws_cancel_seek_service(wfd_oem_asp_service_s *service)
7311 {
7312         __WDP_LOG_FUNC_ENTER__;
7313         GDBusConnection *g_dbus = NULL;
7314         wfd_oem_asp_service_s *seek = NULL;
7315         dbus_method_param_s params;
7316         int res = 0;
7317
7318         g_dbus = g_pd->g_dbus;
7319         if (!g_dbus) {
7320                 WDP_LOGE("DBus connection is NULL");
7321                 __WDP_LOG_FUNC_EXIT__;
7322                 return -1;
7323         }
7324
7325         seek = __ws_get_seek(service->asp_search_id);
7326         if (!seek) {
7327                 WDP_LOGE("seek data is NULL");
7328                 __WDP_LOG_FUNC_EXIT__;
7329                 return -1;
7330         }
7331
7332         if (seek->service_info) {
7333
7334                 memset(&params, 0x0, sizeof(dbus_method_param_s));
7335                 dbus_set_method_param(&params, "ServiceDiscoveryCancelRequest",
7336                                 g_pd->iface_path, g_dbus);
7337
7338                 params.params = g_variant_new("(t)", service->search_id);
7339
7340                 DEBUG_G_VARIANT("Params : ", params.params);
7341
7342                 res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7343                 if (res < 0)
7344                         WDP_LOGE("Failed to send command to wpa_supplicant");
7345                 else
7346                         WDP_LOGD("Succeeded to cancel seek service");
7347         }
7348         if (res == 0)
7349                 __ws_remove_seek(seek);
7350
7351         __WDP_LOG_FUNC_EXIT__;
7352         return res;
7353 }
7354
7355 int ws_asp_prov_disc_req(wfd_oem_asp_prov_s *asp_params)
7356 {
7357         __WDP_LOG_FUNC_ENTER__;
7358         GDBusConnection *g_dbus = NULL;
7359         GVariantBuilder *builder = NULL;
7360         GVariantBuilder *mac_builder = NULL;
7361         GVariant *value = NULL;
7362         dbus_method_param_s params;
7363         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
7364         int config_method = 0x1000;
7365         int res = 0;
7366         int i = 0;
7367
7368         if (!asp_params) {
7369                 WDP_LOGE("Invalid parameter");
7370                 __WDP_LOG_FUNC_EXIT__;
7371                 return -1;
7372         }
7373         g_dbus = g_pd->g_dbus;
7374         if (!g_dbus) {
7375                 WDP_LOGE("DBus connection is NULL");
7376                 __WDP_LOG_FUNC_EXIT__;
7377                 return -1;
7378         }
7379
7380         if (asp_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
7381                 config_method = 0x8;
7382         else if (asp_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
7383                 config_method = 0x100;
7384
7385         memset(&params, 0x0, sizeof(dbus_method_param_s));
7386
7387         dbus_set_method_param(&params, "ASPProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
7388
7389         if (asp_params->deferring == 0)
7390                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
7391                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(asp_params->service_mac));
7392         else
7393                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
7394                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(asp_params->session_mac));
7395         WDP_LOGD("get peer path [%s]", peer_path);
7396
7397         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7398         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
7399
7400         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(asp_params->adv_id));
7401         g_variant_builder_add(builder, "{sv}", "session_id", g_variant_new_uint32(asp_params->session_id));
7402         g_variant_builder_add(builder, "{sv}", "role", g_variant_new_byte(asp_params->network_role));
7403         g_variant_builder_add(builder, "{sv}", "method", g_variant_new_int32(config_method));
7404         if (asp_params->status > 0)
7405                 g_variant_builder_add(builder, "{sv}", "status", g_variant_new_int32(asp_params->status));
7406         if (asp_params->session_information)
7407                 g_variant_builder_add(builder, "{sv}", "info", g_variant_new_string(asp_params->session_information));
7408
7409         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7410         for (i = 0; i < OEM_MACADDR_LEN; i++)
7411                 g_variant_builder_add(mac_builder, "y", asp_params->service_mac[i]);
7412         g_variant_builder_add(builder, "{sv}", "adv_mac",
7413                         g_variant_new("ay", mac_builder));
7414         g_variant_builder_unref(mac_builder);
7415
7416         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7417         for (i = 0; i < OEM_MACADDR_LEN; i++)
7418                 g_variant_builder_add(mac_builder, "y", asp_params->session_mac[i]);
7419         g_variant_builder_add(builder, "{sv}", "session_mac",
7420                         g_variant_new("ay", mac_builder));
7421         g_variant_builder_unref(mac_builder);
7422
7423         value = g_variant_new("(a{sv})", builder);
7424         g_variant_builder_unref(builder);
7425         DEBUG_G_VARIANT("Params : ", value);
7426
7427         params.params = value;
7428
7429         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7430         if (res < 0)
7431                 WDP_LOGE("Failed to send command to wpa_supplicant");
7432         else
7433                 WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(asp_params->service_mac));
7434
7435         __WDP_LOG_FUNC_EXIT__;
7436         return res;
7437 }
7438
7439 int ws_set_eapol_ip_config(int enable)
7440 {
7441         __WDP_LOG_FUNC_ENTER__;
7442         GDBusConnection *g_dbus = NULL;
7443
7444         GVariant *value = NULL;
7445         GVariant *param = NULL;
7446         GVariantBuilder *builder = NULL;
7447         GVariantBuilder *type_builder = NULL;
7448         dbus_method_param_s params;
7449         int res = 0;
7450         int i = 0;
7451         enum {
7452                 IP_GO,
7453                 IP_MASK,
7454                 IP_START,
7455                 IP_END,
7456         };
7457         unsigned char eapol_ip[IP_END + 1][OEM_IPADDR_LEN + 1] = {0,};
7458
7459         if (!g_pd) {
7460                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7461                 __WDP_LOG_FUNC_EXIT__;
7462                 return -1;
7463         }
7464
7465         g_dbus = g_pd->g_dbus;
7466         if (!g_dbus) {
7467                 WDP_LOGE("DBus connection is NULL");
7468                 __WDP_LOG_FUNC_EXIT__;
7469                 return -1;
7470         }
7471         memset(&params, 0x0, sizeof(dbus_method_param_s));
7472
7473         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
7474                          g_dbus);
7475
7476         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7477
7478         memset(&eapol_ip, 0x0, (IP_END + 1) * (OEM_IPADDR_LEN + 1));
7479         if (enable == 1) {
7480                 memcpy(eapol_ip[IP_GO], DEFAULT_IP_GO, OEM_IPADDR_LEN);
7481                 memcpy(eapol_ip[IP_MASK], DEFAULT_IP_MASK, OEM_IPADDR_LEN);
7482                 memcpy(eapol_ip[IP_START], DEFAULT_IP_START, OEM_IPADDR_LEN);
7483                 memcpy(eapol_ip[IP_END], DEFAULT_IP_END, OEM_IPADDR_LEN);
7484         }
7485
7486         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7487         for (i = 0; i < OEM_IPADDR_LEN; i++)
7488                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_GO][i]);
7489         g_variant_builder_add(builder, "{sv}", "IpAddrGo",
7490                         g_variant_new("ay", type_builder));
7491         g_variant_builder_unref(type_builder);
7492
7493         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7494         for (i = 0; i < OEM_IPADDR_LEN; i++)
7495                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_MASK][i]);
7496         g_variant_builder_add(builder, "{sv}", "IpAddrMask",
7497                         g_variant_new("ay", type_builder));
7498         g_variant_builder_unref(type_builder);
7499
7500         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7501         for (i = 0; i < OEM_IPADDR_LEN; i++)
7502                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_START][i]);
7503         g_variant_builder_add(builder, "{sv}", "IpAddrStart",
7504                         g_variant_new("ay", type_builder));
7505         g_variant_builder_unref(type_builder);
7506
7507         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7508         for (i = 0; i < OEM_IPADDR_LEN; i++)
7509                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_END][i]);
7510         g_variant_builder_add(builder, "{sv}", "IpAddrEnd",
7511                         g_variant_new("ay", type_builder));
7512         g_variant_builder_unref(type_builder);
7513
7514         value = g_variant_new("a{sv}", builder);
7515         g_variant_builder_unref(builder);
7516
7517         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
7518
7519         params.params = param;
7520
7521         DEBUG_G_VARIANT("Params : ", param);
7522         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
7523         if (res < 0) {
7524                 WDP_LOGE("Failed to send command to wpa_supplicant");
7525         } else {
7526                 WDP_LOGI("Succeeded to set eapol IP");
7527         }
7528         __WDP_LOG_FUNC_EXIT__;
7529         return res;
7530 }
7531
7532 int ws_add_vsie(wfd_oem_vsie_frames_e frame_id, const char* vsie)
7533 {
7534         __WDP_LOG_FUNC_ENTER__;
7535         GDBusConnection *g_dbus = NULL;
7536         GVariant *value = NULL;
7537         GVariantBuilder *bytearray_builder = NULL;
7538         dbus_method_param_s params;
7539         int res = 0;
7540         int i = 0;
7541         size_t vsie_len = 0;
7542
7543         unsigned char *bytearray = NULL;
7544         size_t bytearray_len = 0;
7545
7546         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7547             vsie == NULL) {
7548                 WDP_LOGE("Invalid parameter");
7549                 return -1;
7550         }
7551
7552         if (!g_pd) {
7553                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7554                 __WDP_LOG_FUNC_EXIT__;
7555                 return -1;
7556         }
7557
7558         g_dbus = g_pd->g_dbus;
7559         if (!g_dbus) {
7560                 WDP_LOGE("DBus connection is NULL");
7561                 __WDP_LOG_FUNC_EXIT__;
7562                 return -1;
7563         }
7564
7565         vsie_len = strlen(vsie);
7566         if (vsie_len == 0) {
7567                 WDP_LOGE("vsie length is zero");
7568                 __WDP_LOG_FUNC_EXIT__;
7569                 return -1;
7570         }
7571
7572         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
7573
7574         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
7575         if (bytearray == NULL) {
7576                 WDP_LOGE("Failed to allocate memory to bytearray");
7577                 __WDP_LOG_FUNC_EXIT__;
7578                 return -1;
7579         }
7580
7581         if (__ws_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
7582                 WDP_LOGE("invalid vsie string");
7583                 g_free(bytearray);
7584                 __WDP_LOG_FUNC_EXIT__;
7585                 return -1;
7586         }
7587
7588         memset(&params, 0x0, sizeof(dbus_method_param_s));
7589         dbus_set_method_param(&params, "VendorElemAdd", g_pd->iface_path,
7590                               g_dbus);
7591
7592         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7593         for (i = 0; i < bytearray_len; i++)
7594                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
7595
7596         value = g_variant_new("(iay)", frame_id, bytearray_builder);
7597         g_variant_builder_unref(bytearray_builder);
7598
7599         params.params = value;
7600
7601         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
7602         if (res < 0) {
7603                 WDP_LOGE("Failed to send command to wpa_supplicant");
7604                 g_free(bytearray);
7605                 __WDP_LOG_FUNC_EXIT__;
7606                 return -1;
7607         }
7608
7609         WDP_LOGD("Succeeded to add vsie: Frame ID [%d], VSIE [%s]", frame_id,
7610                  vsie);
7611
7612         g_free(bytearray);
7613         __WDP_LOG_FUNC_EXIT__;
7614         return 0;
7615 }
7616
7617 int ws_get_vsie(wfd_oem_vsie_frames_e frame_id, char **vsie)
7618 {
7619         __WDP_LOG_FUNC_ENTER__;
7620         GDBusConnection *g_dbus = NULL;
7621         GVariant *param = NULL;
7622         GVariant *reply = NULL;
7623         GError *error = NULL;
7624
7625         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7626             vsie == NULL) {
7627                 WDP_LOGE("Invalid parameter");
7628                 __WDP_LOG_FUNC_EXIT__;
7629                 return -1;
7630         }
7631
7632         if (!g_pd) {
7633                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7634                 __WDP_LOG_FUNC_EXIT__;
7635                 return -1;
7636         }
7637
7638         g_dbus = g_pd->g_dbus;
7639         if (!g_dbus) {
7640                 WDP_LOGE("DBus connection is NULL");
7641                 __WDP_LOG_FUNC_EXIT__;
7642                 return -1;
7643         }
7644
7645         param = g_variant_new("(i)", frame_id);
7646
7647         reply = g_dbus_connection_call_sync(
7648                         g_pd->g_dbus,
7649                         SUPPLICANT_SERVICE, /* bus name */
7650                         g_pd->iface_path, /* object path */
7651                         SUPPLICANT_IFACE, /* interface name */
7652                         "VendorElemGet", /* method name */
7653                         param, /* GVariant *params */
7654                         NULL, /* reply_type */
7655                         G_DBUS_CALL_FLAGS_NONE, /* flags */
7656                         SUPPLICANT_TIMEOUT, /* timeout */
7657                         NULL, /* cancellable */
7658                         &error); /* error */
7659
7660         if (error != NULL) {
7661                 WDP_LOGE("Error! Failed to get vsie: [%s]", error->message);
7662                 g_error_free(error);
7663                 if (reply)
7664                         g_variant_unref(reply);
7665                 __WDP_LOG_FUNC_EXIT__;
7666                 return -1;
7667         }
7668
7669         if (reply != NULL) {
7670                 DEBUG_G_VARIANT("Reply : ", reply);
7671
7672                 GVariantIter *iter = NULL;
7673                 unsigned char *vsie_bytes = NULL;
7674                 int vsie_len = 0;
7675
7676                 g_variant_get(reply, "(ay)", &iter);
7677                 if (iter == NULL) {
7678                         WDP_LOGD("vsie is not present");
7679                         __WDP_LOG_FUNC_EXIT__;
7680                         return -1;
7681                 }
7682
7683                 vsie_len = __ws_unpack_ay_malloc(&vsie_bytes, iter);
7684                 if (vsie_bytes == NULL) {
7685                         WDP_LOGD("vsie_bytes not allocated");
7686                         __WDP_LOG_FUNC_EXIT__;
7687                         return -1;
7688                 }
7689
7690                 __ws_byte_to_txt(vsie_bytes, vsie, vsie_len);
7691                 if (!vsie) {
7692                         g_free(vsie_bytes);
7693                         WDP_LOGE("vsie not allocated.");
7694                         __WDP_LOG_FUNC_EXIT__;
7695                         return -1;
7696                 }
7697
7698                 g_free(vsie_bytes);
7699         }
7700
7701         WDP_LOGD("Succeeded to get vsie: Frame ID [%d], VSIE [%s]", frame_id,
7702                  *vsie);
7703         __WDP_LOG_FUNC_EXIT__;
7704         return 0;
7705 }
7706
7707 int ws_remove_vsie(wfd_oem_vsie_frames_e frame_id, const char *vsie)
7708 {
7709         __WDP_LOG_FUNC_ENTER__;
7710         GDBusConnection *g_dbus = NULL;
7711         GVariantBuilder *bytearray_builder = NULL;
7712         GVariant *value = NULL;
7713         dbus_method_param_s params;
7714         int res = 0;
7715         int i = 0;
7716         size_t vsie_len = 0;
7717
7718         unsigned char *bytearray = NULL;
7719         size_t bytearray_len = 0;
7720
7721         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7722             vsie == NULL) {
7723                 WDP_LOGE("Invalid parameter");
7724                 return -1;
7725         }
7726
7727         if (!g_pd) {
7728                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7729                 __WDP_LOG_FUNC_EXIT__;
7730                 return -1;
7731         }
7732
7733         g_dbus = g_pd->g_dbus;
7734         if (!g_dbus) {
7735                 WDP_LOGE("DBus connection is NULL");
7736                 __WDP_LOG_FUNC_EXIT__;
7737                 return -1;
7738         }
7739
7740         vsie_len = strlen(vsie);
7741         if (vsie_len == 0) {
7742                 WDP_LOGE("vsie length is zero");
7743                 __WDP_LOG_FUNC_EXIT__;
7744                 return -1;
7745         }
7746
7747         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
7748
7749         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
7750         if (bytearray == NULL) {
7751                 WDP_LOGE("Failed to allocate memory to bytearray");
7752                 __WDP_LOG_FUNC_EXIT__;
7753                 return -1;
7754         }
7755
7756         if (__ws_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
7757                 WDP_LOGE("invalid vsie string");
7758                 g_free(bytearray);
7759                 __WDP_LOG_FUNC_EXIT__;
7760                 return -1;
7761         }
7762
7763         memset(&params, 0x0, sizeof(dbus_method_param_s));
7764         dbus_set_method_param(&params, "VendorElemRem", g_pd->iface_path,
7765                               g_dbus);
7766
7767         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7768         for (i = 0; i < bytearray_len; i++)
7769                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
7770
7771         value = g_variant_new("(iay)", frame_id, bytearray_builder);
7772         g_variant_builder_unref(bytearray_builder);
7773
7774         params.params = value;
7775
7776         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
7777         if (res < 0) {
7778                 WDP_LOGE("Failed to send command to wpa_supplicant");
7779                 g_free(bytearray);
7780                 __WDP_LOG_FUNC_EXIT__;
7781                 return -1;
7782         }
7783
7784         WDP_LOGD("Succeeded to remove vsie: Frame ID [%d], VSIE [%s]", frame_id,
7785                  vsie);
7786         g_free(bytearray);
7787         __WDP_LOG_FUNC_EXIT__;
7788         return 0;
7789 }
7790
7791 int ws_set_supported_wps_mode(int wps_mode)
7792 {
7793         __WDP_LOG_FUNC_ENTER__;
7794         char config_value[DBUS_OBJECT_PATH_MAX+1] = {0,};
7795         int length = 0;
7796         int new_wps_mode = wps_mode;
7797         int res = 0;
7798
7799         if (!config) {
7800                 WDP_LOGE("no configurable data found");
7801                 __WDP_LOG_FUNC_EXIT__;
7802                 return -1;
7803         }
7804
7805         if (new_wps_mode == 0) {
7806                 WDP_LOGE("Reset to default value");
7807                 new_wps_mode = WFD_OEM_WPS_MODE_PBC|WFD_OEM_WPS_MODE_DISPLAY|WFD_OEM_WPS_MODE_KEYPAD;
7808         }
7809
7810         if (new_wps_mode & WFD_OEM_WPS_MODE_KEYPAD) {
7811                 g_strlcat(config_value, "keypad ", sizeof(config_value));
7812                 length += 7;
7813         }
7814         if (new_wps_mode & WFD_OEM_WPS_MODE_PBC) {
7815                 g_strlcat(config_value, "virtual_push_button ", sizeof(config_value));
7816                 length += 20;
7817         }
7818         if (new_wps_mode & WFD_OEM_WPS_MODE_DISPLAY) {
7819                 g_strlcat(config_value, "physical_display ", sizeof(config_value));
7820                 length += 17;
7821         }
7822         config_value[length-1] = 0;
7823         g_strlcpy(config->config_methods, config_value, OEM_CONFIG_METHOD_LEN);
7824         WDP_LOGD("config_value = %s, length = %d", config_value, length-1);
7825         res = __ws_set_config_methods();
7826         if (res < 0) {
7827                 WDP_LOGE("Failed to set config method");
7828                 __WDP_LOG_FUNC_EXIT__;
7829                 return -1;
7830         }
7831         wps_config_method = new_wps_mode;
7832         __WDP_LOG_FUNC_EXIT__;
7833         return 0;
7834 }
7835
7836 static int _ws_remove_persistent_group_by_object_path(const char *object_path)
7837 {
7838         __WDP_LOG_FUNC_ENTER__;
7839         GDBusConnection *g_dbus = NULL;
7840         dbus_method_param_s params;
7841         int res = 0;
7842
7843         if (!g_pd) {
7844                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7845                 __WDP_LOG_FUNC_EXIT__;
7846                 return -1;
7847         }
7848
7849         g_dbus = g_pd->g_dbus;
7850         if (!g_dbus) {
7851                 WDP_LOGE("DBus connection is NULL");
7852                 __WDP_LOG_FUNC_EXIT__;
7853                 return -1;
7854         }
7855
7856         memset(&params, 0x0, sizeof(dbus_method_param_s));
7857         dbus_set_method_param(&params, "RemovePersistentGroup",
7858                         g_pd->iface_path, g_dbus);
7859         params.params = g_variant_new("(o)", object_path);
7860
7861         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7862         if (res < 0) {
7863                 WDP_LOGE("Failed to send command to wpa_supplicant");
7864                 __WDP_LOG_FUNC_EXIT__;
7865                 return -1;
7866         }
7867
7868         ws_save_config();
7869         WDP_LOGD("Succeeded to remove persistent group");;
7870         __WDP_LOG_FUNC_EXIT__;
7871         return 0;
7872 }
7873
7874 int ws_remove_persistent_device(unsigned char *mac_addr)
7875 {
7876         __WDP_LOG_FUNC_ENTER__;
7877         GDBusConnection *g_dbus = NULL;
7878         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
7879         int i = 0;
7880         int cnt = 0;
7881         int need_delete = 0;
7882         int res = 0;
7883
7884         if (!g_pd) {
7885                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7886                 __WDP_LOG_FUNC_EXIT__;
7887                 return -1;
7888         }
7889
7890         g_dbus = g_pd->g_dbus;
7891         if (!g_dbus) {
7892                 WDP_LOGE("DBus connection is NULL");
7893                 __WDP_LOG_FUNC_EXIT__;
7894                 return -1;
7895         }
7896         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
7897         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
7898                         __ws_extract_p2pdevice_details, networks);
7899
7900         cnt = networks[0].total;
7901
7902         WDP_LOGD("Persistent Group Count=%d", cnt);
7903         if (cnt > WS_MAX_PERSISTENT_COUNT) {
7904                 WDP_LOGE("Persistent group count exceeded or parsing error");
7905                 __WDP_LOG_FUNC_EXIT__;
7906                 return -1;
7907         }
7908
7909         for (i = 0 ; i < cnt ; i++) {
7910                 int j = 0;
7911                 need_delete = 0;
7912
7913                 WDP_LOGD("----persistent group [%d]----", i);
7914                 WDP_LOGD("network_id [%d]", networks[i].network_id);
7915                 WDP_LOGD("ssid [%s]", networks[i].ssid);
7916                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
7917                 WDP_LOGD("p2p_client_num [%d]", networks[i].p2p_client_num);
7918                 for (j = 0; j < networks[i].p2p_client_num; j++) {
7919                         WDP_LOGD("p2p_client_list ["MACSTR"]", MAC2STR(networks[i].p2p_client_list[j]));
7920                 }
7921
7922                 WDP_LOGD("mac_addr ["MACSTR"]", MAC2STR(mac_addr));
7923
7924                 if (memcmp(mac_addr, networks[i].bssid, WS_MACADDR_LEN) == 0) {
7925                         WDP_LOGD("Persistent group owner found [%d: "MACSTR"]", networks[i].network_id, MAC2STR(mac_addr));
7926                         need_delete = 1;
7927                 }
7928
7929                 if (need_delete == 0) {
7930                         for (j = 0; j < networks[i].p2p_client_num; j++) {
7931                                 if (!memcmp(mac_addr, networks[i].p2p_client_list[j], WS_MACADDR_LEN)) {
7932                                         WDP_LOGD("Persistent group client found [%d: "MACSTR"]", networks[i].network_id, MAC2STR(mac_addr));
7933                                         need_delete = 1;
7934                                 }
7935                         }
7936                 }
7937
7938                 if (need_delete) {
7939                         res = _ws_remove_persistent_group_by_object_path(networks[i].persistent_path);
7940                         WDP_LOGI("persistent group deleted [%s]", networks[i].persistent_path);
7941                         if (res < 0) {
7942                                 WDP_LOGE("Failed to _ws_remove_persistent_group_by_object_path");
7943                         } else {
7944                                 WDP_LOGD("Succeeded to _ws_remove_persistent_group_by_object_path");
7945                         }
7946                 }
7947         }
7948
7949         __WDP_LOG_FUNC_EXIT__;
7950         return res;
7951 }
7952
7953 int ws_remove_all_persistent_device(void)
7954 {
7955         __WDP_LOG_FUNC_ENTER__;
7956         GDBusConnection *g_dbus = NULL;
7957         dbus_method_param_s params;
7958         int res = 0;
7959
7960         g_dbus = g_pd->g_dbus;
7961         if (!g_dbus) {
7962                 WDP_LOGE("DBus connection is NULL");
7963                 __WDP_LOG_FUNC_EXIT__;
7964                 return -1;
7965         }
7966         memset(&params, 0x0, sizeof(dbus_method_param_s));
7967
7968         dbus_set_method_param(&params, "RemoveAllPersistentGroups", g_pd->iface_path, g_dbus);
7969         params.params = NULL;
7970
7971         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7972         if (res < 0) {
7973                 WDP_LOGE("Failed to RemoveAllPersistentGroups");
7974         } else {
7975                 WDP_LOGD("Succeeded to RemoveAllPersistentGroups");
7976         }
7977
7978         ws_save_config();
7979         WDP_LOGD("Succeeded to remove all network");
7980         __WDP_LOG_FUNC_EXIT__;
7981         return res;
7982 }
7983
7984 static void __ws_get_supported_channels_reply(GVariant *reply, void *user_data)
7985 {
7986         __WDP_LOG_FUNC_ENTER__;
7987
7988         GVariantIter *iter = NULL;
7989         wfd_oem_supported_channels_s *data = (wfd_oem_supported_channels_s *)user_data;
7990
7991         if (reply) {
7992                 int channel = 0;
7993
7994                 g_variant_get(reply, "(ai)", &iter);
7995
7996                 while (g_variant_iter_loop(iter, "i", &channel))
7997                         data->channels[data->count++] = channel;
7998
7999                 g_variant_iter_free (iter);
8000
8001         } else {
8002                 WDP_LOGE("Reply is NULL");
8003         }
8004         __WDP_LOG_FUNC_EXIT__;
8005 }
8006
8007 int ws_get_supported_channels(wfd_oem_supported_channels_s *data)
8008 {
8009         __WDP_LOG_FUNC_ENTER__;
8010         int res = 0;
8011         dbus_method_param_s params;
8012
8013         if (!g_pd) {
8014                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
8015                 __WDP_LOG_FUNC_EXIT__;
8016                 return -1;
8017         }
8018
8019         memset(&params, 0x0, sizeof(dbus_method_param_s));
8020         memset(data, 0x0, sizeof(wfd_oem_supported_channels_s));
8021
8022         dbus_set_method_param(&params, "GetSupportedChannels", g_pd->iface_path, g_pd->g_dbus);
8023         params.params = NULL;
8024
8025         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
8026                         __ws_get_supported_channels_reply, data);
8027         if (res < 0) {
8028                 WDP_LOGE("Failed to GetSupportedChannels");
8029         } else {
8030                 WDP_LOGD("Succeeded to GetSupportedChannels");
8031         }
8032
8033         __WDP_LOG_FUNC_EXIT__;
8034         return res;
8035 }