8b86a4ed1df700a9d4cb0e81c24d8bcd2bdf0bda
[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, OEM_MACADDR_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         if (g_pd->callback->group_destroyed_cb)
2880                 g_pd->callback->group_destroyed_cb(&event);
2881
2882         _ws_flush();
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         g_pd->g_dbus = NULL;
3830         __WDP_LOG_FUNC_EXIT__;
3831         return 0;
3832 }
3833
3834 static void _ws_manage_group_iface_signal(const gchar *group_iface_obj_path,
3835                 gboolean is_created)
3836 {
3837         __WDP_LOG_FUNC_ENTER__;
3838         GDBusConnection *connection;
3839
3840         if (!g_pd) {
3841                 WDP_LOGD("Ignore");
3842                 __WDP_LOG_FUNC_EXIT__;
3843                 return;
3844         }
3845
3846         if (!g_strcmp0(g_pd->iface_path, group_iface_obj_path)) {
3847                 WDP_LOGD("group iface is p2p iface, ignore");
3848                 __WDP_LOG_FUNC_EXIT__;
3849                 return;
3850         }
3851
3852         connection = g_pd->g_dbus;
3853         int i;
3854         if (is_created) {
3855                 /* subscribe Interface iface signal */
3856                 for (i = 0; ws_group_interface_signal_map[i].member != NULL; i++) {
3857                         ws_group_interface_signal_map[i].sub_id =
3858                                 g_dbus_connection_signal_subscribe(connection,
3859                                                 SUPPLICANT_SERVICE, /* bus name */
3860                                                 ws_group_interface_signal_map[i].interface, /* interface */
3861                                                 ws_group_interface_signal_map[i].member, /* member */
3862                                                 group_iface_obj_path, /* object path */
3863                                                 NULL, /* arg0 */
3864                                                 G_DBUS_SIGNAL_FLAGS_NONE,
3865                                                 ws_group_interface_signal_map[i].function,
3866                                                 NULL, NULL);
3867                         WDP_LOGD("Subscribed Interface iface signal [%s]", ws_group_interface_signal_map[i].member);
3868                 }
3869
3870         } else {
3871                 for (i = 0; ws_group_interface_signal_map[i].member != NULL; i++) {
3872                         g_dbus_connection_signal_unsubscribe(connection, ws_group_interface_signal_map[i].sub_id);
3873                         ws_group_interface_signal_map[i].sub_id = 0;
3874                 }
3875         }
3876         __WDP_LOG_FUNC_EXIT__;
3877         return;
3878 }
3879
3880 int wfd_plugin_load(wfd_oem_ops_s **ops)
3881 {
3882         __WDP_LOG_FUNC_ENTER__;
3883         if (!ops) {
3884                 WDP_LOGE("Invalid parameter");
3885                 __WDP_LOG_FUNC_EXIT__;
3886                 return -1;
3887         }
3888
3889         *ops = &supplicant_ops;
3890
3891         __WDP_LOG_FUNC_EXIT__;
3892         return 0;
3893 }
3894
3895 static int _ws_reset_plugin(ws_dbus_plugin_data_s *f_pd)
3896 {
3897         __WDP_LOG_FUNC_ENTER__;
3898
3899         if (!f_pd) {
3900                 WDP_LOGE("Invalid parameter");
3901                 __WDP_LOG_FUNC_EXIT__;
3902                 return -1;
3903         }
3904
3905         _ws_deinit_dbus_connection();
3906
3907         if (f_pd->activated)
3908                 ws_deactivate(f_pd->concurrent);
3909
3910         g_free(f_pd);
3911
3912         __WDP_LOG_FUNC_EXIT__;
3913         return 0;
3914 }
3915
3916 static int __ws_check_net_interface(char* if_name)
3917 {
3918         struct ifreq ifr;
3919         int fd;
3920
3921         if (if_name == NULL) {
3922                 WDP_LOGE("Invalid param");
3923                 return -1;
3924         }
3925
3926         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3927         if (fd < 0) {
3928                 WDP_LOGE("socket create error: %d", fd);
3929                 return -2;
3930         }
3931
3932         memset(&ifr, 0, sizeof(ifr));
3933         g_strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
3934
3935         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
3936                 close(fd);
3937                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3938                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3939                 WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s [ %s ]", error_buf, if_name); /* interface is not found. */
3940                 return -3;
3941         }
3942
3943         close(fd);
3944
3945         if (ifr.ifr_flags & IFF_UP) {
3946                 WDP_LOGD("%s interface is up", if_name);
3947                 return 1;
3948         } else if (!(ifr.ifr_flags & IFF_UP)) {
3949                 WDP_LOGD("%s interface is down", if_name);
3950                 return 0;
3951         }
3952         return 0;
3953 }
3954
3955 int ws_configure(wfd_oem_config_s *conf)
3956 {
3957         __WDP_LOG_FUNC_ENTER__;
3958
3959         if (conf == NULL) {
3960                 __WDP_LOG_FUNC_EXIT__;
3961                 return -1;
3962         }
3963
3964         if (config)
3965                 g_free(config);
3966
3967         config = (wfd_oem_config_s *) g_try_malloc0(sizeof(wfd_oem_config_s));
3968         if (!config) {
3969                 __WDP_LOG_FUNC_EXIT__;
3970                 return -1;
3971         }
3972
3973         memcpy(config, conf, sizeof(wfd_oem_config_s));
3974
3975         __WDP_LOG_FUNC_EXIT__;
3976         return 0;
3977 }
3978
3979 int ws_init(wfd_oem_event_cbs_s *event_cbs)
3980 {
3981         __WDP_LOG_FUNC_ENTER__;
3982
3983         if (event_cbs == NULL) {
3984                 __WDP_LOG_FUNC_EXIT__;
3985                 return -1;
3986         }
3987
3988         if (g_pd)
3989                 _ws_reset_plugin(g_pd);
3990
3991         errno = 0;
3992         g_pd = (ws_dbus_plugin_data_s*) g_try_malloc0(sizeof(ws_dbus_plugin_data_s));
3993         if (!g_pd) {
3994                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
3995                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
3996                 WDP_LOGE("Failed to allocate memory for plugin data. [%s]", error_buf);
3997                 return -1;
3998         }
3999
4000         g_pd->callback = event_cbs;
4001         g_pd->initialized = TRUE;
4002
4003         __WDP_LOG_FUNC_EXIT__;
4004         return 0;
4005 }
4006
4007 int ws_deinit(void)
4008 {
4009         __WDP_LOG_FUNC_ENTER__;
4010
4011         if (g_pd) {
4012                 _ws_reset_plugin(g_pd);
4013                 g_pd = NULL;
4014         }
4015
4016         if (config)
4017                 g_free(config);
4018
4019         __WDP_LOG_FUNC_EXIT__;
4020         return 0;
4021 }
4022
4023 gboolean _ws_util_execute_file(const char *file_path,
4024         char *const args[], char *const envs[])
4025 {
4026         pid_t pid = 0;
4027         int rv = 0;
4028         errno = 0;
4029         register unsigned int index = 0;
4030         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
4031
4032         while (args[index] != NULL) {
4033                 WDP_LOGD("[%s]", args[index]);
4034                 index++;
4035         }
4036
4037         if (!(pid = fork())) {
4038                 WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
4039                 WDP_LOGD("Inside child, exec (%s) command", file_path);
4040
4041                 errno = 0;
4042                 if (execve(file_path, args, envs) == -1) {
4043                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4044                         WDP_LOGE("Fail to execute command (%s)", error_buf);
4045                         exit(1);
4046                 }
4047         } else if (pid > 0) {
4048                 if (waitpid(pid, &rv, 0) == -1)
4049                         WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
4050                 if (WIFEXITED(rv))
4051                         WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
4052                 else if (WIFSIGNALED(rv))
4053                         WDP_LOGD("killed by signal %d", WTERMSIG(rv));
4054                 else if (WIFSTOPPED(rv))
4055                         WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
4056                 else if (WIFCONTINUED(rv))
4057                         WDP_LOGD("continued");
4058
4059                 return TRUE;
4060         }
4061
4062         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4063         WDP_LOGE("failed to fork (%s)", error_buf);
4064         return FALSE;
4065 }
4066
4067 static int __ws_p2p_firmware_start(const char *interface_name)
4068 {
4069         GError *error = NULL;
4070         GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
4071         if (conn == NULL) {
4072                 WDP_LOGE("Failed to get system bus");
4073         return -1;
4074         }
4075
4076         error = NULL;
4077         GVariant *params = g_variant_new("(sb)", interface_name, FALSE);
4078         GVariant *reply = g_dbus_connection_call_sync(
4079                 conn,
4080                 NETCONFIG_SERVICE, /* bus name */
4081                 NETCONFIG_WIFI_PATH, /* object path */
4082                 NETCONFIG_WIFI_INTERFACE, /* interface name */
4083                 "LoadDriver", /* method name */
4084                 params, /* GVariant *params */
4085                 NULL, /* reply_type */
4086                 G_DBUS_CALL_FLAGS_NONE, /* flags */
4087                 SUPPLICANT_TIMEOUT , /* timeout */
4088                 NULL, /* cancellable */
4089                 &error); /* error */
4090
4091         if (error != NULL) {
4092                 WDP_LOGE("Error! Failed to call method: [%s]", error->message);
4093                 g_error_free(error);
4094                 __WDP_LOG_FUNC_EXIT__;
4095         }
4096
4097         if (reply)
4098                 g_variant_unref(reply);
4099         g_object_unref(conn);
4100
4101         return 0;
4102 }
4103
4104 static int __ws_p2p_firmware_stop(const char *interface_name)
4105 {
4106         int rv = 0;
4107
4108         rv = hal_wifi_get_backend();
4109         if (rv < 0) {
4110                 WDP_LOGD("hal_wifi_get_backend() failed, ret: %d", rv);
4111                 return -1;
4112         }
4113
4114         rv = hal_wifi_stop(interface_name);
4115         if (rv < 0) {
4116                 WDP_LOGD("hal_wifi_stop() failed, ret: %d", rv);
4117                 return -1;
4118         }
4119
4120         WDP_LOGI("Successfully removed p2p device driver");
4121         return 0;
4122 }
4123
4124 static int __ws_p2p_supplicant_start(void)
4125 {
4126         gboolean rv = FALSE;
4127         const char *path = "/usr/sbin/p2p_supp.sh";
4128         char *const args[] = { "/usr/sbin/p2p_supp.sh", "start_dbus", NULL };
4129         char *const envs[] = { NULL };
4130
4131         rv = _ws_util_execute_file(path, args, envs);
4132
4133         if (rv != TRUE) {
4134                 WDP_LOGE("Failed to start p2p_supp.sh");
4135                 return -1;
4136         }
4137
4138         WDP_LOGI("Successfully started p2p_supp.sh");
4139         return 0;
4140 }
4141
4142
4143 static int __ws_p2p_supplicant_stop(void)
4144 {
4145         gboolean rv = FALSE;
4146         const char *path = "/usr/sbin/p2p_supp.sh";
4147         char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
4148         char *const envs[] = { NULL };
4149
4150         rv = _ws_util_execute_file(path, args, envs);
4151
4152         if (rv != TRUE) {
4153                 WDP_LOGE("Failed to stop p2p_supp.sh");
4154                 return -1;
4155         }
4156
4157         WDP_LOGI("Successfully stopped p2p_supp.sh");
4158         return 0;
4159 }
4160 #if 0
4161 static int __ws_p2p_on(void)
4162 {
4163         DBusError error;
4164         DBusMessage *reply = NULL;
4165         DBusMessage *message = NULL;
4166         DBusConnection *connection = NULL;
4167
4168         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
4169         if (connection == NULL) {
4170                 WDP_LOGE("Failed to get system bus");
4171                 return -EIO;
4172         }
4173
4174         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
4175                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
4176         if (message == NULL) {
4177                 WDP_LOGE("Failed DBus method call");
4178                 dbus_connection_unref(connection);
4179                 return -EIO;
4180         }
4181
4182         dbus_error_init(&error);
4183
4184         reply = dbus_connection_send_with_reply_and_block(connection, message,
4185                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
4186         if (dbus_error_is_set(&error) == TRUE) {
4187                 if (NULL != strstr(error.message, ".AlreadyExists")) {
4188                         /* p2p already enabled */
4189                 } else {
4190                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
4191                                         "DBus error [%s: %s]", error.name, error.message);
4192
4193                         dbus_error_free(&error);
4194                 }
4195
4196                 dbus_error_free(&error);
4197         }
4198
4199         if (reply != NULL)
4200                 dbus_message_unref(reply);
4201
4202         dbus_message_unref(message);
4203         dbus_connection_unref(connection);
4204
4205         return 0;
4206 }
4207
4208 static int __ws_p2p_off(void)
4209 {
4210         DBusError error;
4211         DBusMessage *reply = NULL;
4212         DBusMessage *message = NULL;
4213         DBusConnection *connection = NULL;
4214
4215         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
4216         if (connection == NULL) {
4217                 WDP_LOGE("Failed to get system bus");
4218                 return -EIO;
4219         }
4220
4221         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
4222                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
4223         if (message == NULL) {
4224                 WDP_LOGE("Failed DBus method call");
4225                 dbus_connection_unref(connection);
4226                 return -EIO;
4227         }
4228
4229         dbus_error_init(&error);
4230
4231         reply = dbus_connection_send_with_reply_and_block(connection, message,
4232                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
4233         if (dbus_error_is_set(&error) == TRUE) {
4234                 if (NULL != strstr(error.message, ".AlreadyExists")) {
4235                         /*  p2p already disabled */
4236                 } else {
4237                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
4238                                         "DBus error [%s: %s]", error.name, error.message);
4239
4240                         dbus_error_free(&error);
4241                 }
4242
4243                 dbus_error_free(&error);
4244         }
4245
4246         if (reply != NULL)
4247                 dbus_message_unref(reply);
4248
4249         dbus_message_unref(message);
4250         dbus_connection_unref(connection);
4251
4252         return 0;
4253 }
4254 #endif
4255
4256 int __ws_init_p2pdevice(void)
4257 {
4258         __WDP_LOG_FUNC_ENTER__;
4259         GDBusConnection *g_dbus = NULL;
4260
4261         GVariant *value = NULL;
4262         GVariant *param = NULL;
4263         GVariantBuilder *builder = NULL;
4264         GVariantBuilder *type_builder = NULL;
4265         dbus_method_param_s params;
4266
4267         unsigned char primary_device_type[8] = {
4268                 0x00, 0x00, 0x00, 0x50,
4269                 0xf2, 0x04, 0x00, 0x00
4270         };
4271
4272         int i = 0;
4273         int res = 0;
4274
4275         if (!g_pd) {
4276                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4277                 __WDP_LOG_FUNC_EXIT__;
4278                 return -1;
4279         }
4280
4281         if (!config) {
4282                 WDP_LOGE("no configurable data found");
4283                 __WDP_LOG_FUNC_EXIT__;
4284                 return -1;
4285         }
4286
4287         primary_device_type[1] = config->pri_dev_type;
4288         primary_device_type[7] = config->sec_dev_type;
4289
4290         for (i = 0; i < WS_DEVTYPE_LEN; i++)
4291                 WDP_LOGD("device type[%02x]", primary_device_type[i]);
4292
4293         g_dbus = g_pd->g_dbus;
4294         if (!g_dbus) {
4295                 WDP_LOGE("DBus connection is NULL");
4296                 __WDP_LOG_FUNC_EXIT__;
4297                 return -1;
4298         }
4299         memset(&params, 0x0, sizeof(dbus_method_param_s));
4300
4301         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
4302                          g_dbus);
4303
4304         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4305         g_variant_builder_add(builder, "{sv}", "DeviceName",
4306                                         g_variant_new_string(config->device_name));
4307
4308         g_variant_builder_add(builder, "{sv}", "GOIntent",
4309                                         g_variant_new_uint32(config->go_intent));
4310
4311         g_variant_builder_add(builder, "{sv}", "PersistentReconnect",
4312                                         g_variant_new_boolean(config->persistent_reconnect));
4313
4314         g_variant_builder_add(builder, "{sv}", "ListenRegClass",
4315                                         g_variant_new_uint32(config->listen_reg_class));
4316
4317         g_variant_builder_add(builder, "{sv}", "ListenChannel",
4318                                         g_variant_new_uint32(config->listen_channel));
4319
4320         g_variant_builder_add(builder, "{sv}", "OperRegClass",
4321                                         g_variant_new_uint32(config->operating_reg_class));
4322
4323         g_variant_builder_add(builder, "{sv}", "OperChannel",
4324                                         g_variant_new_uint32(config->operating_channel));
4325
4326         g_variant_builder_add(builder, "{sv}", "SsidPostfix",
4327                                         g_variant_new_string(config->device_name));
4328
4329         g_variant_builder_add(builder, "{sv}", "NoGroupIface",
4330                                         g_variant_new_boolean(config->no_group_iface));
4331
4332         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
4333         for (i = 0; i < WS_DEVTYPE_LEN; i++)
4334                 g_variant_builder_add(type_builder, "y", primary_device_type[i]);
4335         g_variant_builder_add(builder, "{sv}", "PrimaryDeviceType",
4336                         g_variant_new("ay", type_builder));
4337         g_variant_builder_unref(type_builder);
4338         value = g_variant_new("a{sv}", builder);
4339         g_variant_builder_unref(builder);
4340
4341         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
4342
4343         params.params = param;
4344         DEBUG_G_VARIANT("Params : ", params.params);
4345
4346         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4347         if (res < 0)
4348                 WDP_LOGE("Failed to send command to wpa_supplicant");
4349         else
4350                 WDP_LOGD("Succeeded to initialize p2pdevice");
4351         __WDP_LOG_FUNC_EXIT__;
4352         return res;
4353 }
4354
4355 int __ws_set_config_methods(void)
4356 {
4357         __WDP_LOG_FUNC_ENTER__;
4358         GDBusConnection *g_dbus = NULL;
4359
4360         GVariant *value = NULL;
4361         GVariant *param = NULL;
4362
4363         dbus_method_param_s params;
4364         int res = 0;
4365
4366         if (!g_pd) {
4367                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4368                 __WDP_LOG_FUNC_EXIT__;
4369                 return -1;
4370         }
4371
4372         if (!config) {
4373                 WDP_LOGE("no configurable data found");
4374                 __WDP_LOG_FUNC_EXIT__;
4375                 return -1;
4376         }
4377
4378         g_dbus = g_pd->g_dbus;
4379         if (!g_dbus) {
4380                 WDP_LOGE("DBus connection is NULL");
4381                 __WDP_LOG_FUNC_EXIT__;
4382                 return -1;
4383         }
4384         memset(&params, 0x0, sizeof(dbus_method_param_s));
4385
4386         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
4387                          g_dbus);
4388
4389         value = g_variant_new_string(config->config_methods);
4390
4391         param = g_variant_new("(ssv)", SUPPLICANT_WPS, "ConfigMethods", value);
4392         params.params = param;
4393
4394         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4395         if (res < 0)
4396                 WDP_LOGE("Failed to send command to wpa_supplicant");
4397         else
4398                 WDP_LOGD("Succeeded to set config method(%s)", config->config_methods);
4399
4400         __WDP_LOG_FUNC_EXIT__;
4401         return res;
4402 }
4403
4404 int ws_activate(int concurrent)
4405 {
4406         __WDP_LOG_FUNC_ENTER__;
4407         int res = 0;
4408         int retry_count = 0;
4409
4410         if (!g_pd) {
4411                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4412                 __WDP_LOG_FUNC_EXIT__;
4413                 return -1;
4414         }
4415
4416         if (!config) {
4417                 WDP_LOGE("no configurable data found");
4418                 __WDP_LOG_FUNC_EXIT__;
4419                 return -1;
4420         }
4421
4422         res = __ws_p2p_supplicant_start();
4423         if (res < 0) {
4424                 res = __ws_p2p_supplicant_stop();
4425                 WDP_LOGI("P2P supplicant stopped with error %d", res);
4426                 __WDP_LOG_FUNC_EXIT__;
4427                 return -1;
4428         }
4429
4430         while (retry_count < WS_CONN_RETRY_COUNT) {
4431                 /* load wlan driver */
4432                 if (concurrent == 0)
4433                         res = __ws_p2p_firmware_start(config->ifname);
4434                 if (res < 0) {
4435                         WDP_LOGE("Failed to load driver [ret=%d]", res);
4436                         return -1;
4437                 }
4438                 WDP_LOGI("P2P firmware started with error %d", res);
4439
4440                 if (__ws_check_net_interface(config->ifname) < 0) {
4441                         usleep(150000); /* wait for 150ms */
4442                         concurrent = 0;
4443                         retry_count++;
4444                         WDP_LOGE("interface is not up: retry, %d", retry_count);
4445                 } else {
4446                         break;
4447                 }
4448         }
4449
4450         if (retry_count >= WS_CONN_RETRY_COUNT) {
4451                 WDP_LOGE("Driver loading is failed [%d]", res);
4452                 __WDP_LOG_FUNC_EXIT__;
4453                 return -1;
4454         }
4455         if (retry_count > 0) {
4456                 /* Give driver marginal time to config net */
4457                 WDP_LOGE("Driver loading is done. Wait marginal time for driver");
4458                 sleep(1); /* 1s */
4459         }
4460
4461         g_pd->concurrent = concurrent;
4462
4463         res = _ws_init_dbus_connection();
4464         if (res < 0) {
4465                 _ws_deinit_dbus_connection();
4466                 res = __ws_p2p_supplicant_stop();
4467                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
4468                 res = __ws_p2p_firmware_stop(config->ifname);
4469                 WDP_LOGI("P2P firmware stopped with error %d", res);
4470                 __WDP_LOG_FUNC_EXIT__;
4471                 return -1;
4472         }
4473
4474         g_pd->activated = TRUE;
4475         __ws_init_p2pdevice();
4476         __ws_set_config_methods();
4477         seek_list = NULL;
4478
4479         __WDP_LOG_FUNC_EXIT__;
4480         return 0;
4481 }
4482
4483 int ws_deactivate(int concurrent)
4484 {
4485         __WDP_LOG_FUNC_ENTER__;
4486         wfd_oem_asp_service_s *data = NULL;
4487         int res = -1;
4488
4489         if (!g_pd) {
4490                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4491                 __WDP_LOG_FUNC_EXIT__;
4492                 return res;
4493         }
4494
4495         if (!config) {
4496                 WDP_LOGE("no configurable data found");
4497                 __WDP_LOG_FUNC_EXIT__;
4498                 return res;
4499         }
4500
4501         if (!g_pd->activated) {
4502                 WDP_LOGE("Wi-Fi Direct is not activated");
4503                 __WDP_LOG_FUNC_EXIT__;
4504                 return res;
4505         }
4506
4507         ws_stop_scan();
4508
4509         g_pd->concurrent = concurrent;
4510
4511         if (g_strcmp0(config->ifname, config->group_ifname) != 0)
4512                 _ws_get_interface(config->group_ifname, __ws_remove_interface, NULL);
4513         if (concurrent == 0)
4514                 _ws_get_interface(config->ifname, __ws_remove_interface, NULL);
4515
4516         _ws_deinit_dbus_connection();
4517
4518         if (concurrent == 0) {
4519                 res = __ws_p2p_supplicant_stop();
4520                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
4521                 res = __ws_p2p_firmware_stop(config->ifname);
4522                 WDP_LOGI("P2P firmware stopped with error %d", res);
4523         }
4524         g_pd->activated = FALSE;
4525
4526         GLIST_ITER_START(seek_list, data)
4527
4528         if (data) {
4529                 temp = g_list_next(seek_list);
4530                 seek_list = g_list_remove(seek_list, data);
4531                 g_free(data->service_type);
4532                 g_free(data->service_info);
4533                 g_free(data);
4534         }
4535
4536         GLIST_ITER_END()
4537         __WDP_LOG_FUNC_EXIT__;
4538         return 0;
4539 }
4540
4541 #if 0
4542 static gboolean _retry_start_scan(gpointer data)
4543 {
4544         __WDP_LOG_FUNC_ENTER__;
4545
4546         WDP_LOGD("Succeeded to start scan");
4547
4548         __WDP_LOG_FUNC_EXIT__;
4549         return 0;
4550 }
4551 #endif
4552
4553 static void __ws_add_seek_params(GVariantBuilder *builder)
4554 {
4555         GVariantBuilder *outter = NULL;
4556         GVariantBuilder *inner = NULL;
4557         wfd_oem_asp_service_s *data = NULL;
4558         int len = 0;
4559         int i = 0;
4560
4561         if (seek_list == NULL || g_list_length(seek_list) == 0) {
4562                 WDP_LOGD("seek list is NULL");
4563                 return;
4564         }
4565         WDP_LOGD("seek list length [%d]", g_list_length(seek_list));
4566
4567         outter = g_variant_builder_new(G_VARIANT_TYPE("aay"));
4568
4569 GLIST_ITER_START(seek_list, data)
4570         if (data && data->service_type) {
4571                 len = strlen(data->service_type) + 1;
4572                 WDP_LOGD("data [%s] len [%d]", data->service_type, len);
4573                 inner = g_variant_builder_new(G_VARIANT_TYPE("ay"));
4574                 for (i = 0; i < len; i++)
4575                         g_variant_builder_add(inner, "y", data->service_type[i]);
4576                 g_variant_builder_add(outter, "ay", inner);
4577                 g_variant_builder_unref(inner);
4578         }
4579 GLIST_ITER_END()
4580         g_variant_builder_add(builder, "{sv}", "Seek", g_variant_new("aay", outter));
4581         g_variant_builder_unref(outter);
4582
4583         return;
4584 }
4585
4586 int ws_start_scan(wfd_oem_scan_param_s *param)
4587 {
4588         __WDP_LOG_FUNC_ENTER__;
4589         GDBusConnection *g_dbus = NULL;
4590         GVariantBuilder *builder = NULL;
4591         GVariant *value = NULL;
4592         dbus_method_param_s params;
4593         int res = 0;
4594
4595         if (!param) {
4596                 WDP_LOGE("Invalid parameter");
4597                 __WDP_LOG_FUNC_EXIT__;
4598                 return -1;
4599         }
4600
4601         if (!g_pd) {
4602                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4603                 __WDP_LOG_FUNC_EXIT__;
4604                 return -1;
4605         }
4606
4607         g_dbus = g_pd->g_dbus;
4608         if (!g_dbus) {
4609                 WDP_LOGE("DBus connection is NULL");
4610                 __WDP_LOG_FUNC_EXIT__;
4611                 return -1;
4612         }
4613         memset(&params, 0x0, sizeof(dbus_method_param_s));
4614
4615         if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE) {
4616
4617                 dbus_set_method_param(&params, "Find",  g_pd->iface_path, g_dbus);
4618
4619                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4620
4621                         if (param->scan_time)
4622                                 g_variant_builder_add(builder, "{sv}", "Timeout",
4623                                                         g_variant_new_int32(param->scan_time));
4624                         if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
4625                                 g_variant_builder_add(builder, "{sv}", "DiscoveryType",
4626                                                         g_variant_new_string("social"));
4627                         if (seek_list != NULL)
4628                                 __ws_add_seek_params(builder);
4629
4630                         value = g_variant_new("(a{sv})", builder);
4631                         g_variant_builder_unref(builder);
4632         } else {
4633
4634                 dbus_set_method_param(&params, "Listen", g_pd->iface_path, g_dbus);
4635                 value = g_variant_new("(i)", param->scan_time);
4636         }
4637
4638         params.params = value;
4639         DEBUG_G_VARIANT("Params : ", params.params);
4640
4641         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4642         if (res < 0)
4643                 WDP_LOGE("Failed to send command to wpa_supplicant");
4644         else
4645                 WDP_LOGD("Succeeded to start scan");
4646
4647         __WDP_LOG_FUNC_EXIT__;
4648         return res;
4649 }
4650
4651 int ws_restart_scan(int freq)
4652 {
4653         __WDP_LOG_FUNC_ENTER__;
4654         GDBusConnection *g_dbus = NULL;
4655         GVariantBuilder *builder = NULL;
4656         GVariant *value = NULL;
4657         dbus_method_param_s params;
4658         int res = 0;
4659
4660         if (!g_pd) {
4661                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4662                 __WDP_LOG_FUNC_EXIT__;
4663                 return -1;
4664         }
4665
4666         g_dbus = g_pd->g_dbus;
4667         if (!g_dbus) {
4668                 WDP_LOGE("DBus connection is NULL");
4669                 __WDP_LOG_FUNC_EXIT__;
4670                 return -1;
4671         }
4672         memset(&params, 0x0, sizeof(dbus_method_param_s));
4673
4674         dbus_set_method_param(&params, "Find", g_pd->iface_path, g_dbus);
4675
4676         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4677         g_variant_builder_add(builder, "{sv}", "Timeout", g_variant_new_int32(2));
4678         g_variant_builder_add(builder, "{sv}", "DiscoveryType",
4679                                 g_variant_new_string("social"));
4680         value = g_variant_new("(a{sv})", builder);
4681         g_variant_builder_unref(builder);
4682
4683         params.params = value;
4684         DEBUG_G_VARIANT("Params : ", params.params);
4685
4686         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4687         if (res < 0)
4688                 WDP_LOGE("Failed to send command to wpa_supplicant");
4689         else
4690                 WDP_LOGD("Succeeded to start scan");
4691
4692         __WDP_LOG_FUNC_EXIT__;
4693         return res;
4694 }
4695
4696 int ws_stop_scan(void)
4697 {
4698         __WDP_LOG_FUNC_ENTER__;
4699         GDBusConnection *g_dbus = NULL;
4700         dbus_method_param_s params;
4701         int res = 0;
4702
4703         if (!g_pd) {
4704                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4705                 __WDP_LOG_FUNC_EXIT__;
4706                 return -1;
4707         }
4708
4709         g_dbus = g_pd->g_dbus;
4710         if (!g_dbus) {
4711                 WDP_LOGE("DBus connection is NULL");
4712                 __WDP_LOG_FUNC_EXIT__;
4713                 return -1;
4714         }
4715         memset(&params, 0x0, sizeof(dbus_method_param_s));
4716
4717         dbus_set_method_param(&params, "StopFind", g_pd->iface_path, g_dbus);
4718         params.params = NULL;
4719
4720         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4721         if (res < 0)
4722                         WDP_LOGE("Failed to send command to wpa_supplicant");
4723         else
4724                 WDP_LOGD("Succeeded to stop scan");
4725
4726         __WDP_LOG_FUNC_EXIT__;
4727         return res;
4728 }
4729
4730 int ws_get_visibility(int *visibility)
4731 {
4732         __WDP_LOG_FUNC_ENTER__;
4733
4734         __WDP_LOG_FUNC_EXIT__;
4735         return 0;
4736 }
4737
4738 int ws_set_visibility(int visibility)
4739 {
4740         __WDP_LOG_FUNC_ENTER__;
4741
4742         __WDP_LOG_FUNC_EXIT__;
4743         return 0;
4744 }
4745
4746 int ws_get_scan_result(GList **peers, int *peer_count)
4747 {
4748         __WDP_LOG_FUNC_ENTER__;
4749
4750         __WDP_LOG_FUNC_EXIT__;
4751         return 0;
4752 }
4753 static wfd_oem_device_s *__create_oem_device(void)
4754 {
4755         wfd_oem_device_s *device =
4756                         (wfd_oem_device_s *) g_try_malloc0(sizeof(wfd_oem_device_s));
4757         if (!device) {
4758                 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
4759                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
4760                 WDP_LOGF("Failed to allocate memory for event. [%s]",
4761                            error_buf);
4762         }
4763
4764         return device;
4765 }
4766
4767 int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
4768 {
4769         __WDP_LOG_FUNC_ENTER__;
4770         GDBusConnection *g_dbus = NULL;
4771         wfd_oem_device_s *device = NULL;
4772         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4773         int res = 0;
4774
4775         if (!peer_addr || !peer) {
4776                 WDP_LOGE("Invalid parameter");
4777                 __WDP_LOG_FUNC_EXIT__;
4778                 return -1;
4779         }
4780
4781         if (!g_pd) {
4782                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4783                 __WDP_LOG_FUNC_EXIT__;
4784                 return -1;
4785         }
4786
4787         g_dbus = g_pd->g_dbus;
4788         if (!g_dbus) {
4789                 WDP_LOGE("DBus connection is NULL");
4790                 __WDP_LOG_FUNC_EXIT__;
4791                 return -1;
4792         }
4793
4794         device = __create_oem_device();
4795         if (!device) {
4796                 __WDP_LOG_FUNC_EXIT__;
4797                 return -1;
4798         }
4799
4800         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4801                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4802
4803         WDP_LOGD("get peer path [%s]", peer_path);
4804
4805         res = dbus_property_get_all(peer_path, g_dbus, SUPPLICANT_P2P_PEER,
4806                                 __ws_get_peer_property, device);
4807
4808         if (res < 0) {
4809                 WDP_LOGE("Failed to send command to wpa_supplicant");
4810                 if (device->vsie)
4811                         g_free(device->vsie);
4812                 g_free(device);
4813                 __WDP_LOG_FUNC_EXIT__;
4814                 return -1;
4815         } else {
4816                 WDP_LOGD("succeeded to get peer info");
4817                 *peer = device;
4818         }
4819
4820         //Memory ownership of dev_data is transferred to method handler
4821         //which uses this function.
4822
4823         __WDP_LOG_FUNC_EXIT__;
4824         return 0;
4825 }
4826
4827 int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
4828 {
4829         __WDP_LOG_FUNC_ENTER__;
4830         GDBusConnection *g_dbus = NULL;
4831         GVariant *value = NULL;
4832         dbus_method_param_s params;
4833         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4834         int res = 0;
4835
4836         if (!peer_addr) {
4837                 WDP_LOGE("Invalid parameter");
4838                 __WDP_LOG_FUNC_EXIT__;
4839                 return -1;
4840         }
4841
4842         if (!g_pd) {
4843                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4844                 __WDP_LOG_FUNC_EXIT__;
4845                 return -1;
4846         }
4847
4848         g_dbus = g_pd->g_dbus;
4849         if (!g_dbus) {
4850                 WDP_LOGE("DBus connection is NULL");
4851                 __WDP_LOG_FUNC_EXIT__;
4852                 return -1;
4853         }
4854         memset(&params, 0x0, sizeof(dbus_method_param_s));
4855
4856         dbus_set_method_param(&params, "ProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
4857
4858         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4859                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4860         WDP_LOGD("get peer path [%s]", peer_path);
4861
4862         value = g_variant_new("(os)", peer_path, __ws_wps_to_txt(wps_mode));
4863
4864         params.params = value;
4865         DEBUG_G_VARIANT("Params : ", params.params);
4866
4867         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4868         if (res < 0)
4869                 WDP_LOGE("Failed to send command to wpa_supplicant");
4870         else
4871                 WDP_LOGD("Succeeded to send prov disc to peer[" MACSTR "]", MAC2STR(peer_addr));
4872
4873         __WDP_LOG_FUNC_EXIT__;
4874         return res;
4875 }
4876
4877 int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
4878 {
4879         __WDP_LOG_FUNC_ENTER__;
4880         GDBusConnection *g_dbus = NULL;
4881         GVariantBuilder *builder = NULL;
4882         GVariant *value = NULL;
4883         dbus_method_param_s params;
4884         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
4885         int res = 0;
4886
4887         if (!peer_addr || !param) {
4888                 WDP_LOGE("Invalid parameter");
4889                 __WDP_LOG_FUNC_EXIT__;
4890                 return -1;
4891         }
4892
4893         if (!g_pd) {
4894                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4895                 __WDP_LOG_FUNC_EXIT__;
4896                 return -1;
4897         }
4898
4899         g_dbus = g_pd->g_dbus;
4900         if (!g_dbus) {
4901                 WDP_LOGE("DBus connection is NULL");
4902                 __WDP_LOG_FUNC_EXIT__;
4903                 return -1;
4904         }
4905         memset(&params, 0x0, sizeof(dbus_method_param_s));
4906
4907         dbus_set_method_param(&params, "Connect", g_pd->iface_path, g_dbus);
4908
4909         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4910                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4911         WDP_LOGD("get peer path [%s]", peer_path);
4912
4913         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4914         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
4915         if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
4916                 g_variant_builder_add(builder, "{sv}", "persistent", g_variant_new_boolean(TRUE));
4917
4918         if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
4919                 g_variant_builder_add(builder, "{sv}", "join", g_variant_new_boolean(TRUE));
4920
4921         if (param->conn_flags & WFD_OEM_CONN_TYPE_AUTH)
4922                 g_variant_builder_add(builder, "{sv}", "autorize_only", g_variant_new_boolean(TRUE));
4923
4924         if (param->wps_pin[0] != '\0')
4925                 g_variant_builder_add(builder, "{sv}", "pin", g_variant_new_string(param->wps_pin));
4926
4927         g_variant_builder_add(builder, "{sv}", "wps_method",
4928                                 g_variant_new_string(__ws_wps_to_txt(param->wps_mode)));
4929
4930         value = g_variant_new("(a{sv})", builder);
4931         g_variant_builder_unref(builder);
4932
4933         params.params = value;
4934         DEBUG_G_VARIANT("Params : ", params.params);
4935
4936         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
4937         if (res < 0)
4938                 WDP_LOGE("Failed to send command to wpa_supplicant");
4939         else
4940                 WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
4941
4942         __WDP_LOG_FUNC_EXIT__;
4943         return res;
4944 }
4945
4946 int ws_disconnect(unsigned char *peer_addr, int is_iface_addr)
4947 {
4948         __WDP_LOG_FUNC_ENTER__;
4949         GDBusConnection *g_dbus = NULL;
4950         GVariant *value = NULL;
4951         dbus_method_param_s params;
4952         GVariantBuilder *builder = NULL;
4953         int res = 0;
4954
4955         if (!peer_addr) {
4956                 WDP_LOGE("Invalid parameter");
4957                 __WDP_LOG_FUNC_EXIT__;
4958                 return -1;
4959         }
4960
4961         if (!g_pd) {
4962                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
4963                 __WDP_LOG_FUNC_EXIT__;
4964                 return -1;
4965         }
4966
4967         g_dbus = g_pd->g_dbus;
4968         if (!g_dbus) {
4969                 WDP_LOGE("DBus connection is NULL");
4970                 __WDP_LOG_FUNC_EXIT__;
4971                 return -1;
4972         }
4973         memset(&params, 0x0, sizeof(dbus_method_param_s));
4974
4975         dbus_set_method_param(&params, "RemoveClient", g_pd->iface_path, g_dbus);
4976         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
4977
4978         if (is_iface_addr) {
4979                 char peer_mac_str[WS_MACSTR_LEN] = {'\0', };
4980
4981                 g_snprintf(peer_mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
4982                 WDP_LOGI("peer addr [%s]", peer_mac_str);
4983                 g_variant_builder_add(builder, "{sv}", "iface",
4984                                 g_variant_new_string(peer_mac_str));
4985         } else {
4986                 char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0', };
4987
4988                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
4989                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
4990                 g_variant_builder_add(builder, "{sv}", "peer",
4991                                 g_variant_new_object_path(peer_path));
4992         }
4993
4994         value = g_variant_new("(a{sv})", builder);
4995         g_variant_builder_unref(builder);
4996
4997         params.params = value;
4998         DEBUG_G_VARIANT("Params : ", params.params);
4999
5000         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5001         if (res < 0)
5002                 WDP_LOGE("Failed to send command to wpa_supplicant");
5003         else
5004                 WDP_LOGD("Succeeded to send disconnection command to peer[" MACSECSTR "]",
5005                                 MAC2SECSTR(peer_addr));
5006
5007         __WDP_LOG_FUNC_EXIT__;
5008         return res;
5009 }
5010
5011 int ws_reject_connection(unsigned char *peer_addr)
5012 {
5013         __WDP_LOG_FUNC_ENTER__;
5014         GDBusConnection *g_dbus = NULL;
5015         GVariant *value = NULL;
5016         dbus_method_param_s params;
5017         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
5018         int res = 0;
5019
5020         if (!peer_addr) {
5021                 WDP_LOGE("Invalid parameter");
5022                 __WDP_LOG_FUNC_EXIT__;
5023                 return -1;
5024         }
5025
5026         if (!g_pd) {
5027                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5028                 __WDP_LOG_FUNC_EXIT__;
5029                 return -1;
5030         }
5031
5032         g_dbus = g_pd->g_dbus;
5033         if (!g_dbus) {
5034                 WDP_LOGE("DBus connection is NULL");
5035                 __WDP_LOG_FUNC_EXIT__;
5036                 return -1;
5037         }
5038         memset(&params, 0x0, sizeof(dbus_method_param_s));
5039
5040         dbus_set_method_param(&params, "RejectPeer", g_pd->iface_path, g_dbus);
5041
5042         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
5043                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
5044         WDP_LOGE("get peer path [%s]", peer_path);
5045
5046         value = g_variant_new("(o)", peer_path);
5047
5048         params.params = value;
5049         DEBUG_G_VARIANT("Params : ", params.params);
5050
5051         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5052         if (res < 0)
5053                 WDP_LOGE("Failed to send command to wpa_supplicant");
5054         else
5055                 WDP_LOGD("Succeeded to reject peer[" MACSTR "]", MAC2STR(peer_addr));
5056
5057         _ws_flush();
5058         __WDP_LOG_FUNC_EXIT__;
5059         return res;
5060 }
5061
5062 int ws_cancel_connection(unsigned char *peer_addr)
5063 {
5064         __WDP_LOG_FUNC_ENTER__;
5065
5066         _ws_cancel();
5067
5068         __WDP_LOG_FUNC_EXIT__;
5069         return 0;
5070 }
5071
5072 int ws_get_connected_peers(GList **peers, int *peer_count)
5073 {
5074         __WDP_LOG_FUNC_ENTER__;
5075
5076         __WDP_LOG_FUNC_EXIT__;
5077         return 0;
5078 }
5079
5080 int ws_get_pin(char *pin)
5081 {
5082         __WDP_LOG_FUNC_ENTER__;
5083
5084         __WDP_LOG_FUNC_EXIT__;
5085         return 0;
5086 }
5087
5088 int ws_set_pin(char *pin)
5089 {
5090         __WDP_LOG_FUNC_ENTER__;
5091
5092         __WDP_LOG_FUNC_EXIT__;
5093         return 0;
5094 }
5095
5096 static void __ws_get_pin(GVariant *value, void *user_data)
5097 {
5098         __WDP_LOG_FUNC_ENTER__;
5099         const char *pin = NULL;
5100
5101         g_variant_get(value, "(&s)", &pin);
5102         g_strlcpy((char *)user_data, pin, OEM_PINSTR_LEN + 1);
5103
5104         __WDP_LOG_FUNC_EXIT__;
5105         return;
5106 }
5107
5108 int ws_generate_pin(char **pin)
5109 {
5110         __WDP_LOG_FUNC_ENTER__;
5111         GDBusConnection *g_dbus = NULL;
5112         dbus_method_param_s params;
5113         char n_pin[9] = {0,};
5114         int res = 0;
5115
5116         if (!g_pd) {
5117                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5118                 return -1;
5119         }
5120
5121         g_dbus = g_pd->g_dbus;
5122         if (!g_dbus) {
5123                 WDP_LOGE("DBus connection is NULL");
5124                 return -1;
5125         }
5126         memset(&params, 0x0, sizeof(dbus_method_param_s));
5127
5128         dbus_set_method_param(&params, "GeneratePin", g_pd->iface_path, g_dbus);
5129         params.params = NULL;
5130
5131         res = dbus_method_call(&params, SUPPLICANT_WPS, __ws_get_pin, (void *)n_pin);
5132         if (res < 0)
5133                 WDP_LOGE("Failed to send command to wpa_supplicant");
5134         else
5135                 WDP_LOGD("Succeeded to generate_pin [ %s ]", n_pin);
5136
5137         *pin = strndup(n_pin, OEM_PINSTR_LEN);
5138         __WDP_LOG_FUNC_EXIT__;
5139         return 0;
5140 }
5141
5142 int ws_get_supported_wps_mode(int *wps_mode)
5143 {
5144         __WDP_LOG_FUNC_ENTER__;
5145         if (!wps_mode) {
5146                 WDP_LOGE("Invalid parameter");
5147                 __WDP_LOG_FUNC_EXIT__;
5148                 return -1;
5149         }
5150
5151         *wps_mode = wps_config_method;
5152         __WDP_LOG_FUNC_EXIT__;
5153         return 0;
5154 }
5155
5156 int _ws_get_persistent_net_id(int *persistent_network_id, const unsigned char *go_dev_mac)
5157 {
5158         __WDP_LOG_FUNC_ENTER__;
5159         int persistent_group_count = 0;
5160         int counter = 0;
5161         int res = 0;
5162
5163         wfd_oem_persistent_group_s *plist = NULL;
5164
5165         res = ws_get_persistent_groups(&plist, &persistent_group_count);
5166         if (res < 0) {
5167                 WDP_LOGE("failed to get persistent groups");
5168                 __WDP_LOG_FUNC_EXIT__;
5169                 return -1;
5170         }
5171
5172         if (persistent_group_count > WS_MAX_PERSISTENT_COUNT) {
5173                 WDP_LOGE("persistent group count greater than max Persistent count");
5174                 persistent_group_count = WS_MAX_PERSISTENT_COUNT;
5175         }
5176
5177         WDP_LOGD("Persistent Group Count=%d", persistent_group_count);
5178
5179         for (counter = 0; counter < persistent_group_count ; counter++) {
5180                 if (!memcmp(go_dev_mac, plist[counter].go_mac_address, WS_MACADDR_LEN)) {
5181                         *persistent_network_id = plist[counter].network_id;
5182                         break;
5183                 } else {
5184                         WDP_LOGD("Invite: Persistent GO[" MACSTR "], GO Addr[" MACSTR "]",
5185                                         MAC2STR(plist[counter].go_mac_address), MAC2STR(go_dev_mac));
5186                 }
5187         }
5188
5189         g_free(plist);
5190         plist = NULL;
5191         WDP_LOGD("persistent network ID : [%d]", *persistent_network_id);
5192
5193         __WDP_LOG_FUNC_EXIT__;
5194         return 0;
5195 }
5196
5197 static void __store_group_iface_path(GVariant* value, void* user_data)
5198 {
5199         __WDP_LOG_FUNC_ENTER__;
5200         ws_dbus_plugin_data_s * pd_data;
5201         const char *path = NULL;
5202
5203         if (!g_pd) {
5204                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5205                 return;
5206         }
5207
5208         pd_data = (ws_dbus_plugin_data_s *) g_pd;
5209
5210         g_variant_get(value, "(&o)", &path);
5211         g_strlcpy(pd_data->group_iface_path, path, DBUS_OBJECT_PATH_MAX);
5212
5213         WDP_LOGD("group object path [%s]", pd_data->group_iface_path);
5214         /* subscribe interface p2p signal */
5215 }
5216
5217 int ws_create_group(wfd_oem_group_param_s *param)
5218 {
5219         __WDP_LOG_FUNC_ENTER__;
5220         GDBusConnection *g_dbus = NULL;
5221         GVariantBuilder *builder = NULL;
5222         GVariant *value = NULL;
5223         dbus_method_param_s params;
5224         char persistent_group_obj_path[OBJECT_PATH_MAX] = {0,};
5225         int res = 0;
5226
5227         if (!param) {
5228                 WDP_LOGE("Invalid parameter");
5229                 __WDP_LOG_FUNC_EXIT__;
5230                 return -1;
5231         }
5232
5233         if (!g_pd) {
5234                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5235                 __WDP_LOG_FUNC_EXIT__;
5236                 return -1;
5237         }
5238
5239         g_dbus = g_pd->g_dbus;
5240         if (!g_dbus) {
5241                 WDP_LOGE("DBus connection is NULL");
5242                 __WDP_LOG_FUNC_EXIT__;
5243                 return -1;
5244         }
5245         memset(&params, 0x0, sizeof(dbus_method_param_s));
5246
5247         dbus_set_method_param(&params, "GroupAdd", g_pd->iface_path, g_dbus);
5248
5249         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5250
5251         if (param->persistent > 0) {
5252                 unsigned char mac_address[WS_MACADDR_LEN] = {0x00, };
5253                 int persistent_group_id = -1;
5254
5255                 res = _ws_get_local_dev_mac(mac_address);
5256                 if (res < 0) {
5257                         WDP_LOGE("failed to get local mac address");
5258                         __WDP_LOG_FUNC_EXIT__;
5259                         return -1;
5260                 }
5261
5262                 res = _ws_get_persistent_net_id(&persistent_group_id, mac_address);
5263                 if (res < 0) {
5264                         WDP_LOGE("failed to get persistent group ID");
5265                         __WDP_LOG_FUNC_EXIT__;
5266                         return -1;
5267                 }
5268
5269                 WDP_LOGD("persistent network ID : [%d]", persistent_group_id);
5270
5271                 g_variant_builder_add(builder, "{sv}", "persistent",
5272                                 g_variant_new_boolean(TRUE));
5273                 if (persistent_group_id > -1) {
5274                         g_snprintf(persistent_group_obj_path, OBJECT_PATH_MAX,
5275                                         "%s/" SUPPLICANT_PERSISTENT_GROUPS_PART "/%d",
5276                                         g_pd->iface_path, persistent_group_id);
5277                         g_variant_builder_add(builder, "{sv}", "persistent_group_object",
5278                                         g_variant_new_object_path(persistent_group_obj_path));
5279                 }
5280
5281         } else {
5282                 g_variant_builder_add(builder, "{sv}", "persistent",
5283                                 g_variant_new_boolean(FALSE));
5284         }
5285
5286         if (param->passphrase && strlen(param->passphrase) > 0)
5287                 g_variant_builder_add(builder, "{sv}", "passphrase",
5288                                 g_variant_new_string(param->passphrase));
5289
5290         if (param->ssid && strlen(param->ssid) > 0)
5291                 g_variant_builder_add(builder, "{sv}", "ssid",
5292                                 g_variant_new_string(param->ssid));
5293
5294         if (param->freq)
5295                 g_variant_builder_add(builder, "{sv}", "frequency",
5296                                 g_variant_new_int32(param->freq));
5297
5298         value = g_variant_new("(a{sv})", builder);
5299         g_variant_builder_unref(builder);
5300
5301         params.params = value;
5302         DEBUG_G_VARIANT("Params : ", params.params);
5303
5304         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
5305                         __store_group_iface_path, g_pd);
5306         if (res < 0)
5307                 WDP_LOGE("Failed to send command to wpa_supplicant");
5308         else
5309                 WDP_LOGD("Succeeded to add group");
5310
5311         __WDP_LOG_FUNC_EXIT__;
5312         return res;
5313 }
5314
5315 int ws_destroy_group(const char *ifname)
5316 {
5317         __WDP_LOG_FUNC_ENTER__;
5318         GDBusConnection *g_dbus = NULL;
5319         dbus_method_param_s params;
5320         int res = 0;
5321
5322         if (!ifname) {
5323                 WDP_LOGE("Invalid parameter");
5324                 return -1;
5325         }
5326
5327         if (!g_pd) {
5328                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5329                 __WDP_LOG_FUNC_EXIT__;
5330                 return -1;
5331         }
5332
5333         g_dbus = g_pd->g_dbus;
5334         if (!g_dbus) {
5335                 WDP_LOGE("DBus connection is NULL");
5336                 __WDP_LOG_FUNC_EXIT__;
5337                 return -1;
5338         }
5339
5340         if (g_pd->group_iface_path[0] == 0) {
5341                 WDP_LOGE("group iface path is NULL");
5342                 return -1;
5343         }
5344
5345         memset(&params, 0x0, sizeof(dbus_method_param_s));
5346
5347         dbus_set_method_param(&params, "Disconnect", g_pd->group_iface_path, g_dbus);
5348         params.params = NULL;
5349
5350         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5351         if (res < 0) {
5352                 WDP_LOGE("Failed to send command to wpa_supplicant");
5353                 __WDP_LOG_FUNC_EXIT__;
5354                 return -1;
5355         } else {
5356                 _ws_flush();
5357                 WDP_LOGD("Succeeded to remove group");
5358         }
5359
5360         __WDP_LOG_FUNC_EXIT__;
5361         return 0;
5362 }
5363
5364 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
5365 {
5366         __WDP_LOG_FUNC_ENTER__;
5367         GDBusConnection *g_dbus = NULL;
5368         GVariantBuilder *builder = NULL;
5369         GVariant *value = NULL;
5370         dbus_method_param_s params;
5371         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
5372         int res = 0;
5373
5374         if (!peer_addr || !param) {
5375                 WDP_LOGE("Invalid parameter");
5376                 return -1;
5377         }
5378
5379         if (!g_pd) {
5380                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5381                 __WDP_LOG_FUNC_EXIT__;
5382                 return -1;
5383         }
5384
5385         g_dbus = g_pd->g_dbus;
5386         if (!g_dbus) {
5387                 WDP_LOGE("DBus connection is NULL");
5388                 __WDP_LOG_FUNC_EXIT__;
5389                 return -1;
5390         }
5391         memset(&params, 0x0, sizeof(dbus_method_param_s));
5392
5393         dbus_set_method_param(&params, "Invite", g_pd->group_iface_path, g_dbus);
5394
5395         g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
5396                         COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
5397         WDP_LOGE("get peer path [%s]", peer_path);
5398
5399         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5400         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
5401         value = g_variant_new("(a{sv})", builder);
5402         g_variant_builder_unref(builder);
5403
5404         params.params = value;
5405         DEBUG_G_VARIANT("Params : ", params.params);
5406
5407         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
5408         if (res < 0)
5409                 WDP_LOGE("Failed to send command to wpa_supplicant");
5410         else
5411                 WDP_LOGD("Succeeded to invite peer[" MACSTR "]", MAC2STR(peer_addr));
5412
5413         __WDP_LOG_FUNC_EXIT__;
5414         return 0;
5415 }
5416
5417 /* Only group owner can use this command */
5418 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
5419 {
5420         __WDP_LOG_FUNC_ENTER__;
5421         GDBusConnection *g_dbus = NULL;
5422         GVariantBuilder *builder = NULL;
5423         GVariant *value = NULL;
5424         GVariant *dev_addr = NULL;
5425         dbus_method_param_s params;
5426         int i = 0;
5427         int res = 0;
5428
5429         if (!g_pd) {
5430                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5431                 __WDP_LOG_FUNC_EXIT__;
5432                 return -1;
5433         }
5434
5435         g_dbus = g_pd->g_dbus;
5436         if (!g_dbus) {
5437                 WDP_LOGE("DBus connection is NULL");
5438                 __WDP_LOG_FUNC_EXIT__;
5439                 return -1;
5440         }
5441
5442         memset(&params, 0x0, sizeof(dbus_method_param_s));
5443
5444         dbus_set_method_param(&params, "Start", g_pd->group_iface_path, g_dbus);
5445
5446         if (peer_addr != NULL) {
5447                 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
5448                 for (i = 0; i < WS_MACADDR_LEN; i++)
5449                         g_variant_builder_add(builder, "y", peer_addr[i]);
5450
5451                 dev_addr = g_variant_new("ay", builder);
5452                 g_variant_builder_unref(builder);
5453         }
5454
5455         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5456         g_variant_builder_add(builder, "{sv}", "Role", g_variant_new_string("enrollee"));
5457         if (peer_addr != NULL)
5458                 g_variant_builder_add(builder, "{sv}", "P2PDeviceAddress", dev_addr);
5459
5460         if (pin != NULL && pin[0] != '\0') {
5461                 g_variant_builder_add(builder, "{sv}", "Type", g_variant_new_string("pin"));
5462                 g_variant_builder_add(builder, "{sv}", "Pin", g_variant_new_string(pin));
5463         } else {
5464                 g_variant_builder_add(builder, "{sv}", "Type", g_variant_new_string("pbc"));
5465         }
5466
5467         value = g_variant_new("(a{sv})", builder);
5468         g_variant_builder_unref(builder);
5469
5470         params.params = value;
5471         DEBUG_G_VARIANT("Params : ", params.params);
5472
5473         res = dbus_method_call(&params, SUPPLICANT_WPS, NULL, NULL);
5474         if (res < 0)
5475                 WDP_LOGE("Failed to send command to wpa_supplicant");
5476         else
5477                 WDP_LOGD("Succeeded to run wps");
5478
5479         __WDP_LOG_FUNC_EXIT__;
5480         return 0;
5481 }
5482
5483 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
5484 {
5485         __WDP_LOG_FUNC_ENTER__;
5486
5487         WDP_LOGD("Succeeded to start WPS");
5488
5489         __WDP_LOG_FUNC_EXIT__;
5490         return 0;
5491 }
5492
5493 int ws_wps_cancel(void)
5494 {
5495         __WDP_LOG_FUNC_ENTER__;
5496         GDBusConnection *g_dbus = NULL;
5497         dbus_method_param_s params;
5498         int res = 0;
5499
5500         g_dbus = g_pd->g_dbus;
5501         if (!g_dbus) {
5502                 WDP_LOGE("DBus connection is NULL");
5503                 __WDP_LOG_FUNC_EXIT__;
5504                 return -1;
5505         }
5506         memset(&params, 0x0, sizeof(dbus_method_param_s));
5507
5508         dbus_set_method_param(&params, "Cancel", g_pd->group_iface_path, g_dbus);
5509         params.params = NULL;
5510
5511         res = dbus_method_call(&params, SUPPLICANT_WPS, NULL, NULL);
5512         if (res < 0)
5513                 WDP_LOGE("Failed to send command to wpa_supplicant");
5514         else
5515                 WDP_LOGD("Succeeded to cancel WPS");
5516
5517         __WDP_LOG_FUNC_EXIT__;
5518         return 0;
5519 }
5520
5521 int ws_get_dev_name(char *dev_name)
5522 {
5523         __WDP_LOG_FUNC_ENTER__;
5524
5525         __WDP_LOG_FUNC_EXIT__;
5526         return 0;
5527 }
5528
5529 int ws_set_dev_name(char *dev_name)
5530 {
5531         __WDP_LOG_FUNC_ENTER__;
5532         GDBusConnection *g_dbus = NULL;
5533
5534         GVariant *value = NULL;
5535         GVariant *param = NULL;
5536         GVariantBuilder *builder = NULL;
5537         dbus_method_param_s params;
5538         int res = 0;
5539
5540         if (!dev_name) {
5541                 WDP_LOGE("Invalid parameter");
5542                 __WDP_LOG_FUNC_EXIT__;
5543                 return -1;
5544         }
5545
5546         if (!g_pd) {
5547                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5548                 __WDP_LOG_FUNC_EXIT__;
5549                 return -1;
5550         }
5551
5552         g_dbus = g_pd->g_dbus;
5553         if (!g_dbus) {
5554                 WDP_LOGE("DBus connection is NULL");
5555                 __WDP_LOG_FUNC_EXIT__;
5556                 return -1;
5557         }
5558         memset(&params, 0x0, sizeof(dbus_method_param_s));
5559
5560         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5561                          g_dbus);
5562
5563         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5564         g_variant_builder_add(builder, "{sv}", "DeviceName",
5565                                 g_variant_new_string(dev_name));
5566         g_variant_builder_add(builder, "{sv}", "SsidPostfix",
5567                                  g_variant_new_string(dev_name));
5568         value = g_variant_new("a{sv}", builder);
5569         g_variant_builder_unref(builder);
5570
5571         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE,
5572                                 "P2PDeviceConfig", value);
5573
5574         params.params = param;
5575         DEBUG_G_VARIANT("Params : ", params.params);
5576
5577         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5578         if (res < 0)
5579                 WDP_LOGE("Failed to send command to wpa_supplicant");
5580         else
5581                 WDP_LOGD("Succeeded to set device name");
5582
5583         __WDP_LOG_FUNC_EXIT__;
5584         return res;
5585 }
5586
5587 int ws_get_dev_mac(char *dev_mac)
5588 {
5589         __WDP_LOG_FUNC_ENTER__;
5590
5591         __WDP_LOG_FUNC_EXIT__;
5592         return 0;
5593 }
5594
5595 int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
5596 {
5597         __WDP_LOG_FUNC_ENTER__;
5598
5599         __WDP_LOG_FUNC_EXIT__;
5600         return 0;
5601 }
5602
5603 int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
5604 {
5605         __WDP_LOG_FUNC_ENTER__;
5606
5607         __WDP_LOG_FUNC_EXIT__;
5608         return 0;
5609 }
5610
5611 int ws_get_go_intent(int *go_intent)
5612 {
5613         __WDP_LOG_FUNC_ENTER__;
5614         GDBusConnection *g_dbus = NULL;
5615         GVariant *param = NULL;
5616         GVariant *reply = NULL;
5617         GError *error = NULL;
5618         GVariantIter *iter = NULL;
5619
5620
5621         if (!go_intent) {
5622                 WDP_LOGE("Invalid parameter");
5623                 return -1;
5624         }
5625
5626         if (!g_pd) {
5627                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5628                 __WDP_LOG_FUNC_EXIT__;
5629                 return -1;
5630         }
5631
5632         g_dbus = g_pd->g_dbus;
5633         if (!g_dbus) {
5634                 WDP_LOGE("DBus connection is NULL");
5635                 __WDP_LOG_FUNC_EXIT__;
5636                 return -1;
5637         }
5638
5639         param = g_variant_new("(ss)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig");
5640         DEBUG_G_VARIANT("Params : ", param);
5641
5642         reply = g_dbus_connection_call_sync(
5643                         g_dbus,
5644                         SUPPLICANT_SERVICE, /* bus name */
5645                         g_pd->iface_path, /* object path */
5646                         DBUS_PROPERTIES_INTERFACE, /* interface name */
5647                         DBUS_PROPERTIES_METHOD_GET, /* method name */
5648                         param, /* GVariant *params */
5649                         NULL, /* reply_type */
5650                         G_DBUS_CALL_FLAGS_NONE, /* flags */
5651                         SUPPLICANT_TIMEOUT , /* timeout */
5652                         NULL, /* cancellable */
5653                         &error); /* error */
5654
5655         if (error != NULL) {
5656                 WDP_LOGE("Error! Failed to get interface State: [%s]",
5657                                 error->message);
5658                 g_error_free(error);
5659                 if (reply)
5660                         g_variant_unref(reply);
5661                 __WDP_LOG_FUNC_EXIT__;
5662                 return -1;
5663         }
5664
5665         if (reply != NULL) {
5666                 g_variant_get(reply, "(a{sv})", &iter);
5667
5668                 if (iter != NULL) {
5669                         gchar *key = NULL;
5670                         GVariant *value = NULL;
5671
5672                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
5673                                 CHECK_KEY_VALUE(key, value);
5674
5675                                 if (g_strcmp0(key, "GOIntent") == 0)
5676                                         g_variant_get(value, "u", go_intent);
5677                         }
5678                         g_variant_iter_free(iter);
5679                 }
5680                 g_variant_unref(reply);
5681         }
5682         __WDP_LOG_FUNC_EXIT__;
5683         return 0;
5684 }
5685
5686 int ws_set_go_intent(int go_intent)
5687 {
5688         __WDP_LOG_FUNC_ENTER__;
5689         GDBusConnection *g_dbus = NULL;
5690
5691         GVariant *value = NULL;
5692         GVariant *param = NULL;
5693         GVariantBuilder *builder = NULL;
5694         dbus_method_param_s params;
5695         int res = 0;
5696
5697         if (!g_pd) {
5698                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5699                 __WDP_LOG_FUNC_EXIT__;
5700                 return -1;
5701         }
5702
5703         g_dbus = g_pd->g_dbus;
5704         if (!g_dbus) {
5705                 WDP_LOGE("DBus connection is NULL");
5706                 __WDP_LOG_FUNC_EXIT__;
5707                 return -1;
5708         }
5709         memset(&params, 0x0, sizeof(dbus_method_param_s));
5710
5711         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5712                          g_dbus);
5713
5714         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
5715         g_variant_builder_add(builder, "{sv}", "GOIntent",
5716                                 g_variant_new_uint32(go_intent));
5717         value = g_variant_new("a{sv}", builder);
5718         g_variant_builder_unref(builder);
5719
5720         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
5721
5722         params.params = param;
5723         DEBUG_G_VARIANT("Params : ", params.params);
5724
5725         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5726         if (res < 0)
5727                 WDP_LOGE("Failed to send command to wpa_supplicant");
5728         else
5729                 WDP_LOGE("Succeeded to set go intent");
5730         __WDP_LOG_FUNC_EXIT__;
5731         return res;
5732 }
5733
5734 int ws_set_country(char *ccode)
5735 {
5736         __WDP_LOG_FUNC_ENTER__;
5737         __WDP_LOG_FUNC_ENTER__;
5738         GDBusConnection *g_dbus = NULL;
5739
5740         GVariant *value = NULL;
5741         GVariant *param = NULL;
5742
5743         dbus_method_param_s params;
5744         int res = 0;
5745
5746         if (!g_pd) {
5747                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5748                 __WDP_LOG_FUNC_EXIT__;
5749                 return -1;
5750         }
5751
5752         g_dbus = g_pd->g_dbus;
5753         if (!g_dbus) {
5754                 WDP_LOGE("DBus connection is NULL");
5755                 __WDP_LOG_FUNC_EXIT__;
5756                 return -1;
5757         }
5758         memset(&params, 0x0, sizeof(dbus_method_param_s));
5759
5760         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
5761                          g_dbus);
5762
5763         value = g_variant_new_string(ccode);
5764
5765         param = g_variant_new("(ssv)", SUPPLICANT_IFACE, "Country", value);
5766
5767         params.params = param;
5768         DEBUG_G_VARIANT("Params : ", params.params);
5769
5770         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
5771         if (res < 0)
5772                 WDP_LOGE("Failed to send command to wpa_supplicant");
5773         else
5774                 WDP_LOGD("Succeeded to set country(%s)", ccode);
5775
5776         __WDP_LOG_FUNC_EXIT__;
5777         return res;
5778 }
5779
5780 void __parsing_networks(const char* key, GVariant* value, void* user_data)
5781 {
5782         __WDP_LOG_FUNC_ENTER__;
5783         if (!user_data) {
5784                 __WDP_LOG_FUNC_EXIT__;
5785                 return;
5786         }
5787
5788         ws_network_info_s *network = (ws_network_info_s *)user_data;
5789
5790         CHECK_KEY_VALUE(key, value);
5791
5792         if (g_strcmp0(key, "ssid") == 0) {
5793                 const char *ssid = NULL;
5794                 g_variant_get(value, "&s", &ssid);
5795                 WDP_LOGD("ssid [%s]", ssid);
5796                 g_strlcpy(network->ssid, ssid + 1, WS_SSID_LEN + 1);
5797                 network->ssid[strlen(ssid) - 2] = '\0';
5798
5799         } else if (g_strcmp0(key, "bssid") == 0) {
5800                 unsigned char *bssid = NULL;
5801                 g_variant_get(value, "&s", &bssid);
5802                 WDP_LOGD("bssid [%s]", bssid);
5803                 __ws_txt_to_mac(bssid, network->bssid);
5804
5805         } else if (g_strcmp0(key, "proto") == 0) {
5806                 const char *proto = NULL;
5807                 g_variant_get(value, "&s", &proto);
5808                 WDP_LOGD("proto [%s]", proto);
5809
5810                 if (g_strrstr(proto, WFD_OEM_STR_PROTO_WPA) != NULL)
5811                         network->proto |= WFD_OEM_PROTO_WPA;
5812                 if (g_strrstr(proto, WFD_OEM_STR_PROTO_RSN) != NULL)
5813                         network->proto |= WFD_OEM_PROTO_RSN;
5814
5815         } else if (g_strcmp0(key, "key_mgmt") == 0) {
5816                 const char *key_mgmt = NULL;
5817                 g_variant_get(value, "&s", &key_mgmt);
5818                 WDP_LOGD("key_mgmt [%s]", key_mgmt);
5819
5820                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_IEEE8021X) != NULL)
5821                         network->key_mgmt |= WFD_OEM_KEY_MGMT_IEEE8021X;
5822                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_PSK) != NULL)
5823                         network->key_mgmt |= WFD_OEM_KEY_MGMT_PSK;
5824                 if (g_strrstr(key_mgmt, WFD_OEM_STR_KEY_MGMT_NONE) != NULL)
5825                         network->key_mgmt |= WFD_OEM_KEY_MGMT_NONE;
5826
5827         } else if (g_strcmp0(key, "pairwise") == 0) {
5828                 const char *pairwise = NULL;
5829                 g_variant_get(value, "&s", &pairwise);
5830                 WDP_LOGD("pairwise [%s]", pairwise);
5831
5832                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_NONE) != NULL)
5833                         network->pairwise |= WFD_OEM_CIPHER_NONE;
5834                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_TKIP) != NULL)
5835                         network->pairwise |= WFD_OEM_CIPHER_TKIP;
5836                 if (g_strrstr(pairwise, WFD_OEM_STR_CIPHER_CCMP) != NULL)
5837                         network->pairwise |= WFD_OEM_CIPHER_CCMP;
5838
5839         }  else if (g_strcmp0(key, "group") == 0) {
5840                 const char *group = NULL;
5841                 g_variant_get(value, "&s", &group);
5842                 WDP_LOGD("group [%s]", group);
5843
5844                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_NONE) != NULL)
5845                         network->group |= WFD_OEM_CIPHER_NONE;
5846                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_WEP40) != NULL)
5847                         network->group |= WFD_OEM_CIPHER_WEP40;
5848                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_WEP104) != NULL)
5849                         network->group |= WFD_OEM_CIPHER_WEP104;
5850                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_TKIP) != NULL)
5851                         network->group |= WFD_OEM_CIPHER_TKIP;
5852                 if (g_strrstr(group, WFD_OEM_STR_CIPHER_CCMP) != NULL)
5853                         network->group |= WFD_OEM_CIPHER_CCMP;
5854
5855         } else if (g_strcmp0(key, "auth_alg") == 0) {
5856                 const char *auth_alg = NULL;
5857                 g_variant_get(value, "&s", &auth_alg);
5858                 WDP_LOGD("auth_alg [%s]", auth_alg);
5859
5860                 if (g_strrstr(auth_alg, WFD_OEM_STR_AUTH_ALG_OPEN) != NULL)
5861                         network->auth_alg |= WFD_OEM_AUTH_ALG_OPEN;
5862
5863         } else if (g_strcmp0(key, "mode") == 0) {
5864                 const char *mode = NULL;
5865                 g_variant_get(value, "&s", &mode);
5866                 WDP_LOGD("mode [%s]", mode);
5867
5868                 if (g_strrstr(mode, WFD_OEM_STR_MODE_GC) != NULL)
5869                         network->mode |= WFD_OEM_PERSISTENT_MODE_GC;
5870                 if (g_strrstr(mode, WFD_OEM_STR_MODE_GO) != NULL)
5871                         network->mode |= WFD_OEM_PERSISTENT_MODE_GO;
5872
5873         } else if (g_strcmp0(key, "p2p_client_list") == 0) {
5874                 const char *p2p_client_list = NULL;
5875                 char *ptr = NULL;
5876                 int list_len = 0;
5877                 int num = 0;
5878
5879                 g_variant_get(value, "&s", &p2p_client_list);
5880                 WDP_LOGD("p2p_client_list [%s]", p2p_client_list);
5881                 ptr = (char *)p2p_client_list;
5882                 list_len = strlen(p2p_client_list);
5883                 WDP_LOGD("list_len [%d]", list_len);
5884                 while (ptr && list_len >= (OEM_MACSTR_LEN - 1)) {
5885                         __ws_txt_to_mac((unsigned char *)ptr, (network->p2p_client_list[num]));
5886                         ptr += OEM_MACSTR_LEN;
5887                         list_len -= OEM_MACSTR_LEN;
5888                         if (ptr && ptr[0] == ' ') {
5889                                 ptr += 1;
5890                                 list_len -= 1;
5891                         }
5892                         num++;
5893                         if (num >= OEM_MAX_PEER_NUM)
5894                                 break;
5895                 }
5896                 network->p2p_client_num = num;
5897                 WDP_LOGD("p2p_client_num [%d]", network->p2p_client_num);
5898         }
5899         return;
5900 }
5901
5902 void __ws_extract_p2pdevice_details(const char *key, GVariant *value, void *user_data)
5903 {
5904         __WDP_LOG_FUNC_ENTER__;
5905         CHECK_KEY_VALUE(key, value);
5906
5907         if (g_strcmp0(key, "PersistentGroups") == 0) {
5908                 GVariantIter *iter = NULL;
5909                 const char *path = NULL;
5910                 int num = 0;
5911
5912                 ws_network_info_s *networks = NULL;
5913                 networks = (ws_network_info_s *)user_data;
5914                 if (!networks) {
5915                         WDP_LOGE("network is NULL");
5916                         __WDP_LOG_FUNC_EXIT__;
5917                         return;
5918                 }
5919
5920                 g_variant_get(value, "ao", &iter);
5921                 while (g_variant_iter_loop(iter, "&o", &path)) {
5922                         char *loc = NULL;
5923
5924                         if (num >= WS_MAX_PERSISTENT_COUNT)
5925                                 break;
5926
5927                         WDP_LOGD("Retrive persistent path [%s]", path);
5928                         g_strlcpy(networks[num].persistent_path, path, DBUS_OBJECT_PATH_MAX);
5929
5930                         loc = strrchr(networks[num].persistent_path, '/');
5931                         if (loc)
5932                                 networks[num].network_id = strtoul(loc+1, NULL, 10);
5933
5934                         WDP_LOGD("Retrive persistent path [%s]", networks[num].persistent_path);
5935                         dbus_property_get_all(networks[num].persistent_path, g_pd->g_dbus,
5936                                         SUPPLICANT_P2P_PERSISTENTGROUP, __parsing_networks, &networks[num]);
5937                         num++;
5938                 }
5939
5940                 networks[0].total = num;
5941                 WDP_LOGI("total number [%d]", num);
5942                 g_variant_iter_free(iter);
5943         }
5944         __WDP_LOG_FUNC_EXIT__;
5945 }
5946
5947
5948 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
5949 {
5950         __WDP_LOG_FUNC_ENTER__;
5951         GDBusConnection *g_dbus = NULL;
5952
5953         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
5954         wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
5955         int i, cnt = 0;
5956
5957         if (!g_pd) {
5958                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
5959                 __WDP_LOG_FUNC_EXIT__;
5960                 return -1;
5961         }
5962
5963         g_dbus = g_pd->g_dbus;
5964         if (!g_dbus) {
5965                 WDP_LOGE("DBus connection is NULL");
5966                 __WDP_LOG_FUNC_EXIT__;
5967                 return -1;
5968         }
5969
5970         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
5971         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
5972                         __ws_extract_p2pdevice_details, &networks[0]);
5973
5974         cnt = networks[0].total;
5975
5976         WDP_LOGD("Persistent Group Count=%d", cnt);
5977         if (cnt > WS_MAX_PERSISTENT_COUNT) {
5978                 WDP_LOGE("Persistent group count exceeded or parsing error");
5979                 __WDP_LOG_FUNC_EXIT__;
5980                 return -1;
5981         }
5982
5983         if (cnt == 0) {
5984                 WDP_LOGE("Persistent group count zero");
5985                 *group_count = 0;
5986                 *groups = NULL;
5987                 __WDP_LOG_FUNC_EXIT__;
5988                 return 0;
5989         }
5990
5991         wfd_persistent_groups = (wfd_oem_persistent_group_s *) g_try_malloc0(cnt * sizeof(wfd_oem_persistent_group_s));
5992         if (wfd_persistent_groups == NULL) {
5993                 WDP_LOGE("Failed to allocate memory for wfd_persistent_groups ");
5994                 __WDP_LOG_FUNC_EXIT__;
5995                 return -1;
5996         }
5997
5998         for (i = 0; i < cnt; i++) {
5999                 int j = 0;
6000
6001                 WDP_LOGD("----persistent group [%d]----", i);
6002                 WDP_LOGD("network_id [%d]", networks[i].network_id);
6003                 WDP_LOGD("ssid [%s]", networks[i].ssid);
6004                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
6005                 WDP_LOGD("p2p_client_num [%d]", networks[i].p2p_client_num);
6006                 for (j = 0; j < networks[i].p2p_client_num; j++)
6007                         WDP_LOGD("p2p_client_list ["MACSTR"]", MAC2STR(networks[i].p2p_client_list[j]));
6008
6009                 wfd_persistent_groups[i].network_id = networks[i].network_id;
6010                 g_strlcpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN + 1);
6011                 memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
6012                 wfd_persistent_groups[i].p2p_client_num = networks[i].p2p_client_num;
6013                 if (wfd_persistent_groups[i].p2p_client_num > 0)
6014                         memcpy(wfd_persistent_groups[i].p2p_client_list, networks[i].p2p_client_list,
6015                                         OEM_MACADDR_LEN * OEM_MAX_PEER_NUM * sizeof(char));
6016         }
6017
6018         *group_count = cnt;
6019         *groups = wfd_persistent_groups;
6020
6021         __WDP_LOG_FUNC_EXIT__;
6022         return 0;
6023 }
6024
6025 int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
6026 {
6027         __WDP_LOG_FUNC_ENTER__;
6028         GDBusConnection *g_dbus = NULL;
6029
6030         dbus_method_param_s params;
6031         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
6032         int i, cnt = 0;
6033         int res = 0;
6034
6035         if (!g_pd) {
6036                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6037                 __WDP_LOG_FUNC_EXIT__;
6038                 return -1;
6039         }
6040
6041         g_dbus = g_pd->g_dbus;
6042         if (!g_dbus) {
6043                 WDP_LOGE("DBus connection is NULL");
6044                 __WDP_LOG_FUNC_EXIT__;
6045                 return -1;
6046         }
6047         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
6048         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
6049                         __ws_extract_p2pdevice_details, networks);
6050
6051         cnt = networks[0].total;
6052
6053         WDP_LOGD("Persistent Group Count=%d", cnt);
6054         if (cnt > WS_MAX_PERSISTENT_COUNT) {
6055                 WDP_LOGE("Persistent group count exceeded or parsing error");
6056                 __WDP_LOG_FUNC_EXIT__;
6057                 return -1;
6058         }
6059
6060         for (i = 0; i < cnt; i++) {
6061                 int j = 0;
6062
6063                 WDP_LOGD("----persistent group [%d]----", i);
6064                 WDP_LOGD("network_id [%d]", networks[i].network_id);
6065                 WDP_LOGD("network ssid [%s]", networks[i].ssid);
6066                 WDP_LOGD("network bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
6067                 WDP_LOGD("network p2p_client_num [%d]", networks[i].p2p_client_num);
6068                 for (j = 0; j < networks[i].p2p_client_num; j++)
6069                         WDP_LOGD("network p2p_client_list ["MACSTR"]",
6070                                         MAC2STR(networks[i].p2p_client_list[j]));
6071
6072                 WDP_LOGD("ssid [%s]", ssid);
6073                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(bssid));
6074
6075                 if (!g_strcmp0(ssid, networks[i].ssid) &&
6076                                 !memcmp(bssid, networks[i].bssid, WS_MACADDR_LEN)) {
6077                         WDP_LOGD("Persistent group owner found [%d: %s]",
6078                                         networks[i].network_id, ssid);
6079
6080                         memset(&params, 0x0, sizeof(dbus_method_param_s));
6081                         dbus_set_method_param(&params, "RemovePersistentGroup",
6082                                         g_pd->iface_path, g_dbus);
6083                         params.params = g_variant_new("(o)", networks[i].persistent_path);
6084                         DEBUG_G_VARIANT("Params : ", params.params);
6085
6086                         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6087                         if (res < 0) {
6088                                 WDP_LOGE("Failed to send command to wpa_supplicant");
6089                                 __WDP_LOG_FUNC_EXIT__;
6090                                 return -1;
6091                         }
6092
6093                         WDP_LOGD("Succeeded to remove persistent group");;
6094                         break;
6095                 }
6096         }
6097
6098         if (i == cnt) {
6099                 WDP_LOGE("Persistent group not found [%s]", ssid);
6100                 return -1;
6101         }
6102
6103         __WDP_LOG_FUNC_EXIT__;
6104         return 0;
6105 }
6106
6107 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
6108 {
6109         __WDP_LOG_FUNC_ENTER__;
6110         GDBusConnection *g_dbus = NULL;
6111
6112         GVariant *value = NULL;
6113         GVariant *param = NULL;
6114         GVariantBuilder *builder = NULL;
6115         dbus_method_param_s params;
6116         int res = 0;
6117
6118         if (!g_pd) {
6119                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6120                 __WDP_LOG_FUNC_EXIT__;
6121                 return -1;
6122         }
6123
6124         g_dbus = g_pd->g_dbus;
6125         if (!g_dbus) {
6126                 WDP_LOGE("DBus connection is NULL");
6127                 __WDP_LOG_FUNC_EXIT__;
6128                 return -1;
6129         }
6130         memset(&params, 0x0, sizeof(dbus_method_param_s));
6131
6132         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
6133                         g_dbus);
6134
6135         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6136         g_variant_builder_add(builder, "{sv}", "PersistentReconnect",
6137                                 g_variant_new_boolean(reconnect));
6138         value = g_variant_new("a{sv}", builder);
6139         g_variant_builder_unref(builder);
6140
6141         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
6142
6143         params.params = param;
6144         DEBUG_G_VARIANT("Params : ", params.params);
6145
6146         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6147         if (res < 0)
6148                 WDP_LOGE("Failed to send command to wpa_supplicant");
6149         else
6150                 WDP_LOGD("Succeeded to set persistent reconnect");
6151
6152         __WDP_LOG_FUNC_EXIT__;
6153         return res;
6154 }
6155
6156 static int __ws_compress_query(char *compressed, char *query, int qtype)
6157 {
6158         char *token = NULL;
6159         char *temp = NULL;
6160         int token_num = 0;
6161         int token_len = 0;
6162         int length = 0;
6163
6164         token = strtok_r(query, ".", &temp);
6165         while (token) {
6166                 if (!strcmp(token, "local")) {
6167                         WDP_LOGD("Query conversion done");
6168                         break;
6169
6170                 } else if (!strncmp(token, "_tcp", 4)) {
6171                         memcpy(&compressed[length], WS_TCP_PTR_HEX, 2);
6172                         length += 2;
6173
6174                 } else if (!strncmp(token, "_udp", 4)) {
6175                         memcpy(&compressed[length], WS_UDP_PTR_HEX, 2);
6176                         length += 2;
6177
6178                 } else {
6179                         WDP_LOGD("Token: [%s]", token);
6180                         token_len = strlen(token);
6181                         compressed[length] = token_len;
6182                         length++;
6183
6184                         memcpy(&compressed[length], token, token_len);
6185                         length += token_len;
6186                 }
6187                 token_num++;
6188                 token = strtok_r(NULL, ".", &temp);
6189         }
6190         if (qtype == WS_QTYPE_PTR || token_num == 2)
6191                 memcpy(&compressed[length], WS_PTR_TYPE_HEX, 3);
6192         else if (qtype == WS_QTYPE_TXT || token_num == 3)
6193                 memcpy(&compressed[length], WS_TXT_TYPE_HEX, 3);
6194
6195         length += 3;
6196         WDP_LOGD("converted query length [%d] token num [%d]", length, token_num);
6197
6198         return length;
6199 }
6200
6201 static int __ws_compress_rdata(char *compressed, char *rdata, int qtype)
6202 {
6203         char *token = NULL;
6204         char *temp = NULL;
6205         int token_len = 0;
6206         int length = 0;
6207
6208         if (qtype == WS_QTYPE_PTR) {
6209
6210                 token = strtok_r(rdata, ".", &temp);
6211                 if (token) {
6212                         WDP_LOGD("Token: %s", token);
6213                         token_len = strlen(token);
6214                         compressed[length] = token_len;
6215                         length++;
6216
6217                         memcpy(&compressed[length], token, token_len);
6218                         length += token_len;
6219                 }
6220
6221                 compressed[length] = 0xc0;
6222                 compressed[length+1] = 0x27;
6223                 length += 2;
6224
6225         } else if (qtype == WS_QTYPE_TXT) {
6226
6227                 token = strtok_r(rdata, ",", &temp);
6228
6229                 while (token) {
6230                         WDP_LOGD("Token: [%s]", token);
6231
6232                         token_len = strlen(token);
6233                         compressed[length] = token_len;
6234                         length++;
6235
6236                         memcpy(&compressed[length], token, token_len);
6237                         length += token_len;
6238
6239                         token = strtok_r(NULL, ",", &temp);
6240                 }
6241         } else {
6242                 WDP_LOGD("RDATA is NULL");
6243         }
6244         return length;
6245 }
6246
6247 int _convert_bonjour_to_args(char *query, char *rdata, GVariantBuilder *builder)
6248 {
6249         GVariantBuilder *args = NULL;
6250         char compressed[256] = {0, };
6251         char *temp = NULL;
6252         int length = 0;
6253         int qtype = 0;
6254         int i = 0;
6255
6256         if (!query || !builder) {
6257                 WDP_LOGE("Invalid parameter");
6258                 return -1;
6259         }
6260         if (!rdata || !strlen(rdata)) {
6261                 WDP_LOGD("RDATA is NULL\n");
6262         } else {
6263                 temp = strstr(rdata, query);
6264
6265                 if (temp != NULL && temp - rdata > 0)
6266                         qtype = WS_QTYPE_PTR;
6267                 else
6268                         qtype = WS_QTYPE_TXT;
6269                 temp = NULL;
6270         }
6271
6272         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("bonjour"));
6273
6274         /* compress query */
6275         length = __ws_compress_query(compressed, query, qtype);
6276
6277         args = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6278         for (i = 0; i < length; i++)
6279                 g_variant_builder_add(args, "y", compressed[i]);
6280         g_variant_builder_add(builder, "{sv}", "query", g_variant_new("ay", args));
6281         g_variant_builder_unref(args);
6282
6283         memset(compressed, 0x0, 256);
6284         length = 0;
6285         args = NULL;
6286
6287         if (qtype != 0) {
6288                 length = __ws_compress_rdata(compressed, rdata, qtype);
6289
6290                 args = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6291                 for (i = 0; i < length; i++)
6292                         g_variant_builder_add(args, "y", compressed[i]);
6293                 g_variant_builder_add(builder, "{sv}", "response", g_variant_new("ay", args));
6294                 g_variant_builder_unref(args);
6295         }
6296
6297         return 0;
6298 }
6299
6300 int _check_service_query_exists(wfd_oem_service_s *service)
6301 {
6302         int count = 0;
6303         wfd_oem_service_s *data = NULL;
6304
6305         for (count = 0; count < g_list_length(service_list); count++) {
6306                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
6307                 if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
6308                         WDP_LOGD("Query already exists");
6309                         return 1;
6310                 }
6311         }
6312         return 0;
6313 }
6314
6315 static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
6316 {
6317         if (NULL == s_type || NULL == mac_str || NULL == query_id)
6318                 return NULL;
6319
6320         int count = 0;
6321         wfd_oem_service_s *data = NULL;
6322
6323         for (count = 0; count < g_list_length(service_list); count++) {
6324                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
6325                 if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
6326                                 memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
6327                         g_strlcpy(query_id, data->query_id, OEM_QUERY_ID_LEN + 1);
6328                         break;
6329                 }
6330         }
6331         if (strlen(query_id) <= 0) {
6332                 WDP_LOGD("!! Query ID not found !!");
6333                 return NULL;
6334         }
6335
6336         WDP_LOGD("query id :[%s]", query_id);
6337
6338         return data;
6339 }
6340
6341 void __add_service_query(GVariant *value, void *user_data)
6342 {
6343         __WDP_LOG_FUNC_ENTER__;
6344         wfd_oem_service_s *service = NULL;
6345
6346         long long unsigned ref = 0;
6347         int res = 0;
6348
6349         if (!user_data)
6350                 return;
6351
6352         g_variant_get(value, "(t)", &ref);
6353
6354         service = (wfd_oem_service_s*) g_try_malloc0(sizeof(wfd_oem_service_s));
6355         if (!service) {
6356                 WDP_LOGE("Failed to allocate memory for service");
6357                 return;
6358         }
6359
6360         memcpy(service, user_data, sizeof(wfd_oem_service_s));
6361
6362         g_snprintf(service->query_id, OEM_QUERY_ID_LEN + 1, "%llx", ref);
6363
6364         res = _check_service_query_exists(service);
6365         if (res)
6366                 g_free(service);
6367         else
6368                 service_list = g_list_append(service_list, service);
6369
6370         __WDP_LOG_FUNC_EXIT__;
6371         return;
6372
6373 }
6374
6375 /* for now, supplicant dbus interface only provides upnp service fully */
6376 int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
6377 {
6378         __WDP_LOG_FUNC_ENTER__;
6379         GDBusConnection *g_dbus = NULL;
6380         GVariantBuilder *builder = NULL;
6381         GVariant *value = NULL;
6382         wfd_oem_service_s data = {0,};
6383         dbus_method_param_s params;
6384         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
6385         int i = 0;
6386         int res = 0;
6387
6388         if (!mac_addr) {
6389                 WDP_LOGE("Invalid parameter");
6390                 __WDP_LOG_FUNC_EXIT__;
6391                 return -1;
6392         }
6393
6394         if (!g_pd) {
6395                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6396                 __WDP_LOG_FUNC_EXIT__;
6397                 return -1;
6398         }
6399
6400         g_dbus = g_pd->g_dbus;
6401         if (!g_dbus) {
6402                 WDP_LOGE("DBus connection is NULL");
6403                 __WDP_LOG_FUNC_EXIT__;
6404                 return -1;
6405         }
6406         memset(&params, 0x0, sizeof(dbus_method_param_s));
6407
6408         dbus_set_method_param(&params, "ServiceDiscoveryRequest", g_pd->iface_path, g_dbus);
6409
6410         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6411
6412         if (mac_addr && !ISZEROMACADDR(mac_addr)) {
6413                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
6414                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(mac_addr));
6415                 WDP_LOGD("get peer path [%s]", peer_path);
6416                 g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
6417         }
6418
6419         if (service_type == WFD_OEM_SERVICE_TYPE_ALL) {
6420
6421                 char *service_all = "\x02\x00\x00\x01";
6422                 GVariantBuilder *query = NULL;
6423
6424                 query = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6425                 for (i = 0; i < SERVICE_QUERY_LEN; i++)
6426                         g_variant_builder_add(query, "y", service_all[i]);
6427                 g_variant_builder_add(builder, "{sv}", "query", g_variant_new("ay", query));
6428                 g_variant_builder_unref(query);
6429                 g_strlcpy(data.service_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
6430
6431         } else if (service_type == WFD_OEM_SERVICE_TYPE_UPNP) {
6432
6433                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6434                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6435                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string("ssdp:all"));
6436                 g_strlcpy(data.service_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
6437
6438         } else if (service_type == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6439
6440                 char *service_bonjour = "\x02\x00\x01\x01";
6441                 GVariantBuilder *query = NULL;
6442
6443                 query = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6444                 for (i = 0; i < SERVICE_QUERY_LEN; i++)
6445                         g_variant_builder_add(query, "y", service_bonjour[i]);
6446                 g_variant_builder_add(builder, "{sv}", "tlv", g_variant_new("ay", query));
6447                 g_variant_builder_unref(query);
6448                 g_strlcpy(data.service_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
6449         }
6450
6451         value = g_variant_new("(a{sv})", builder);
6452         g_variant_builder_unref(builder);
6453
6454         params.params = value;
6455         DEBUG_G_VARIANT("Params : ", params.params);
6456
6457         if (ISZEROMACADDR(mac_addr))
6458                 snprintf(data.dev_addr, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
6459         else
6460                 snprintf(data.dev_addr, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
6461
6462         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, __add_service_query, &data);
6463         if (res < 0)
6464                 WDP_LOGE("Failed to send command to wpa_supplicant");
6465         else
6466                 WDP_LOGD("Succeeded to start service discovery");
6467
6468         __WDP_LOG_FUNC_EXIT__;
6469         return res;
6470 }
6471
6472 int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
6473 {
6474         __WDP_LOG_FUNC_ENTER__;
6475         GDBusConnection *g_dbus = NULL;
6476         dbus_method_param_s params;
6477         wfd_oem_service_s *data = NULL;
6478         char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
6479         char s_type[OEM_SERVICE_TYPE_LEN + 1] = {0, };
6480         char mac_str[18] = {0, };
6481         long long unsigned id;
6482
6483         int res = 0;
6484
6485         if (!mac_addr) {
6486                 WDP_LOGE("Invalid parameter");
6487                 __WDP_LOG_FUNC_EXIT__;
6488                 return -1;
6489         }
6490
6491         if (!g_pd) {
6492                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6493                 __WDP_LOG_FUNC_EXIT__;
6494                 return -1;
6495         }
6496
6497         g_dbus = g_pd->g_dbus;
6498         if (!g_dbus) {
6499                 WDP_LOGE("DBus connection is NULL");
6500                 __WDP_LOG_FUNC_EXIT__;
6501                 return -1;
6502         }
6503
6504         if (ISZEROMACADDR(mac_addr)) {
6505                 snprintf(mac_str, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
6506         } else {
6507                 snprintf(mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
6508         }
6509
6510         switch (service_type) {
6511         case WFD_OEM_SERVICE_TYPE_ALL:
6512                 g_strlcpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
6513         break;
6514         case WFD_OEM_SERVICE_TYPE_BONJOUR:
6515                 g_strlcpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
6516         break;
6517         case WFD_OEM_SERVICE_TYPE_UPNP:
6518                 g_strlcpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
6519         break;
6520         default:
6521                 WDP_LOGE("Invalid Service type");
6522                 __WDP_LOG_FUNC_EXIT__;
6523                 return -1;
6524         }
6525
6526         WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
6527         WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
6528
6529         data = _remove_service_query(s_type, mac_str, query_id);
6530         if (NULL == data) {
6531                 __WDP_LOG_FUNC_EXIT__;
6532                 return -1;
6533         }
6534         memset(&params, 0x0, sizeof(dbus_method_param_s));
6535
6536         dbus_set_method_param(&params, "ServiceDiscoveryCancelRequest", g_pd->iface_path, g_dbus);
6537         id = (long long unsigned)strtoul(query_id, NULL, 16);
6538         params.params = g_variant_new("(t)", id);
6539
6540         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6541         if (res < 0)
6542                 WDP_LOGE("Failed to send command to wpa_supplicant");
6543         else
6544                 WDP_LOGD("Succeeded to cancel service discovery");
6545
6546         service_list = g_list_remove(service_list, data);
6547         free(data);
6548
6549         __WDP_LOG_FUNC_EXIT__;
6550         return res;
6551 }
6552
6553 int ws_serv_add(wfd_oem_new_service_s *service)
6554 {
6555         __WDP_LOG_FUNC_ENTER__;
6556         GDBusConnection *g_dbus = NULL;
6557         GVariantBuilder *builder = NULL;
6558         GVariant *value = NULL;
6559         dbus_method_param_s params;
6560         int res = 0;
6561
6562         if (!g_pd) {
6563                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6564                 __WDP_LOG_FUNC_EXIT__;
6565                 return -1;
6566         }
6567
6568         g_dbus = g_pd->g_dbus;
6569         if (!g_dbus) {
6570                 WDP_LOGE("DBus connection is NULL");
6571                 __WDP_LOG_FUNC_EXIT__;
6572                 return -1;
6573         }
6574         memset(&params, 0x0, sizeof(dbus_method_param_s));
6575
6576         dbus_set_method_param(&params, "AddService", g_pd->iface_path, g_dbus);
6577
6578         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6579
6580         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6581
6582                 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
6583                 WDP_LOGD("Query: %s", service->data.bonjour.query);
6584                 WDP_LOGD("RData: %s", service->data.bonjour.rdata);
6585
6586                 res = _convert_bonjour_to_args(service->data.bonjour.query,
6587                                                             service->data.bonjour.rdata, builder);
6588                 if (res < 0) {
6589                         WDP_LOGE("Failed to convert Key string");
6590                         g_variant_builder_unref(builder);
6591                         return -1;
6592                 }
6593
6594         } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
6595                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6596                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6597                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
6598         }
6599
6600         value = g_variant_new("(a{sv})", builder);
6601         g_variant_builder_unref(builder);
6602
6603         params.params = value;
6604         DEBUG_G_VARIANT("Params : ", params.params);
6605
6606         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6607         if (res < 0)
6608                 WDP_LOGE("Failed to send command to wpa_supplicant");
6609         else
6610                 WDP_LOGD("Succeeded to add service");
6611
6612         __WDP_LOG_FUNC_EXIT__;
6613         return 0;
6614 }
6615
6616 int ws_serv_del(wfd_oem_new_service_s *service)
6617 {
6618         __WDP_LOG_FUNC_ENTER__;
6619         GDBusConnection *g_dbus = NULL;
6620         GVariantBuilder *builder = NULL;
6621         GVariant *value = NULL;
6622         dbus_method_param_s params;
6623         int res = 0;
6624
6625         if (!g_pd) {
6626                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6627                 __WDP_LOG_FUNC_EXIT__;
6628                 return -1;
6629         }
6630
6631         g_dbus = g_pd->g_dbus;
6632         if (!g_dbus) {
6633                 WDP_LOGE("DBus connection is NULL");
6634                 __WDP_LOG_FUNC_EXIT__;
6635                 return -1;
6636         }
6637         memset(&params, 0x0, sizeof(dbus_method_param_s));
6638
6639         dbus_set_method_param(&params, "DeleteService", g_pd->iface_path, g_dbus);
6640
6641         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6642
6643         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
6644
6645                 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
6646                 WDP_LOGD("Query: %s", service->data.bonjour.query);
6647
6648                 res = _convert_bonjour_to_args(service->data.bonjour.query,
6649                                                             NULL, builder);
6650                 if (res < 0) {
6651                         WDP_LOGE("Failed to convert Key string");
6652                         g_variant_builder_unref(builder);
6653                         return -1;
6654                 }
6655
6656         } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
6657                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("upnp"));
6658                 g_variant_builder_add(builder, "{sv}", "version", g_variant_new_int32(10));
6659                 g_variant_builder_add(builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
6660         }
6661
6662         value = g_variant_new("(a{sv})", builder);
6663         g_variant_builder_unref(builder);
6664
6665         params.params = value;
6666         DEBUG_G_VARIANT("Params : ", params.params);
6667
6668         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
6669         if (res < 0)
6670                 WDP_LOGE("Failed to send command to wpa_supplicant");
6671         else
6672                 WDP_LOGD("Succeeded to del service");
6673
6674         __WDP_LOG_FUNC_EXIT__;
6675         return 0;
6676 }
6677
6678 int _ws_disable_display()
6679 {
6680         __WDP_LOG_FUNC_ENTER__;
6681         GDBusConnection *g_dbus = NULL;
6682         GVariantBuilder *builder = NULL;
6683         GVariant *value = NULL;
6684         GVariant *param = NULL;
6685         dbus_method_param_s params;
6686         int res = 0;
6687
6688         if (!g_pd) {
6689                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
6690                 __WDP_LOG_FUNC_EXIT__;
6691                 return -1;
6692         }
6693
6694         g_dbus = g_pd->g_dbus;
6695         if (!g_dbus) {
6696                 WDP_LOGE("DBus connection is NULL");
6697                 __WDP_LOG_FUNC_EXIT__;
6698                 return -1;
6699         }
6700         memset(&params, 0x0, sizeof(dbus_method_param_s));
6701
6702         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
6703                          g_dbus);
6704
6705         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6706         value = g_variant_new("ay", builder);
6707         g_variant_builder_unref(builder);
6708
6709         param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
6710
6711         params.params = param;
6712         DEBUG_G_VARIANT("Params : ", params.params);
6713
6714         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6715         if (res < 0)
6716                 WDP_LOGE("Failed to send command to wpa_supplicant");
6717         else
6718                 WDP_LOGD("Succeeded to disable Wi-Fi display");
6719
6720         __WDP_LOG_FUNC_EXIT__;
6721         return res;
6722 }
6723
6724 int ws_miracast_init(int enable)
6725 {
6726         __WDP_LOG_FUNC_ENTER__;
6727         wfd_oem_display_s wifi_display;
6728         int res = 0;
6729
6730         memset(&wifi_display, 0x0, sizeof(wfd_oem_display_s));
6731
6732         wifi_display.availability = enable;
6733         wifi_display.hdcp_support = 1;
6734         wifi_display.port = 0x07E6;
6735         wifi_display.max_tput = 0x0028;
6736
6737         res = ws_set_display(&wifi_display);
6738         if (res < 0) {
6739                 WDP_LOGE("Failed to set miracast parameter(device info)");
6740                 __WDP_LOG_FUNC_EXIT__;
6741                 return -1;
6742         }
6743
6744         if (!enable) {
6745                 res = _ws_disable_display();
6746                 if (res < 0)
6747                         WDP_LOGE("Failed to disable wifi display");
6748                 else
6749                         WDP_LOGD("Succeeded to disable wifi display");
6750         }
6751         __WDP_LOG_FUNC_EXIT__;
6752         return res;
6753 }
6754
6755 int ws_set_display(wfd_oem_display_s *wifi_display)
6756 {
6757         __WDP_LOG_FUNC_ENTER__;
6758         GDBusConnection *g_dbus = NULL;
6759
6760         GVariant *value = NULL;
6761         GVariant *param = NULL;
6762         GVariantBuilder *builder = NULL;
6763         dbus_method_param_s params;
6764         int i = 0;
6765         int res = 0;
6766
6767         unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
6768
6769         if (!wifi_display) {
6770                 WDP_LOGE("Invalid parameter");
6771                 return -1;
6772         }
6773         g_dbus = g_pd->g_dbus;
6774         if (!g_dbus) {
6775                 WDP_LOGE("DBus connection is NULL");
6776                 __WDP_LOG_FUNC_EXIT__;
6777                 return -1;
6778         }
6779         memset(&params, 0x0, sizeof(dbus_method_param_s));
6780
6781         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
6782                          g_dbus);
6783
6784         ies[2] = WFD_SUBELEM_LEN_DEV_INFO;
6785         ies[3] = wifi_display->hdcp_support;
6786         ies[4] = (wifi_display->type) | (wifi_display->availability<<4);
6787         ies[5] = wifi_display->port>>8;
6788         ies[6] = wifi_display->port&0xff;
6789         ies[7] = wifi_display->max_tput>>8;
6790         ies[8] = wifi_display->max_tput&0xff;
6791
6792         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
6793         for (i = 0; i < WFD_SUBELEM_LEN_DEV_INFO + 3; i++)
6794                 g_variant_builder_add(builder, "y", ies[i]);
6795         value = g_variant_new("ay", builder);
6796         g_variant_builder_unref(builder);
6797
6798         param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
6799
6800         params.params = param;
6801         DEBUG_G_VARIANT("Params : ", params.params);
6802
6803         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6804         if (res < 0)
6805                 WDP_LOGE("Failed to send command to wpa_supplicant");
6806         else
6807                 WDP_LOGD("Succeeded to set Wi-Fi Display");
6808
6809         __WDP_LOG_FUNC_EXIT__;
6810         return res;
6811 }
6812
6813 int ws_refresh(void)
6814 {
6815         __WDP_LOG_FUNC_ENTER__;
6816
6817         _ws_cancel();
6818         _ws_flush();
6819
6820         __WDP_LOG_FUNC_EXIT__;
6821         return 0;
6822 }
6823
6824 int ws_save_config(void)
6825 {
6826         __WDP_LOG_FUNC_ENTER__;
6827         GDBusConnection *g_dbus = NULL;
6828         dbus_method_param_s params;
6829         int res = 0;
6830
6831         g_dbus = g_pd->g_dbus;
6832         if (!g_dbus) {
6833                 WDP_LOGE("DBus connection is NULL");
6834                 __WDP_LOG_FUNC_EXIT__;
6835                 return -1;
6836         }
6837         memset(&params, 0x0, sizeof(dbus_method_param_s));
6838
6839         dbus_set_method_param(&params, "SaveConfig", g_pd->iface_path, g_dbus);
6840         params.params = NULL;
6841
6842         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
6843         if (res < 0)
6844                 WDP_LOGE("Failed to save config to wpa_supplicant");
6845         else
6846                 WDP_LOGD("Succeeded to save config");
6847
6848         __WDP_LOG_FUNC_EXIT__;
6849         return res;
6850 }
6851
6852 int ws_set_operating_channel(int channel)
6853 {
6854         __WDP_LOG_FUNC_ENTER__;
6855         GDBusConnection *g_dbus = NULL;
6856         GVariant *value = NULL;
6857         GVariant *param = NULL;
6858         GVariantBuilder *builder = NULL;
6859         dbus_method_param_s params;
6860         int res = 0;
6861
6862         g_dbus = g_pd->g_dbus;
6863         if (!g_dbus) {
6864                 WDP_LOGE("DBus connection is NULL");
6865                 __WDP_LOG_FUNC_EXIT__;
6866                 return -1;
6867         }
6868
6869         memset(&params, 0x0, sizeof(dbus_method_param_s));
6870
6871         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path, g_dbus);
6872
6873         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
6874         g_variant_builder_add(builder, "{sv}", "OperChannel", g_variant_new_uint32(channel));
6875         value = g_variant_new("a{sv}", builder);
6876         g_variant_builder_unref(builder);
6877
6878         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
6879         params.params = param;
6880
6881         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
6882         if (res < 0)
6883                 WDP_LOGE("Failed to send command to wpa_supplicant");
6884         else
6885                 WDP_LOGD("Succeeded to set Operating Channel");
6886
6887         __WDP_LOG_FUNC_EXIT__;
6888         return res;
6889 }
6890
6891 int ws_remove_all_network(void)
6892 {
6893         __WDP_LOG_FUNC_ENTER__;
6894         GDBusConnection *g_dbus = NULL;
6895         dbus_method_param_s params;
6896         int res = 0;
6897
6898         g_dbus = g_pd->g_dbus;
6899         if (!g_dbus) {
6900                 WDP_LOGE("DBus connection is NULL");
6901                 __WDP_LOG_FUNC_EXIT__;
6902                 return -1;
6903         }
6904         memset(&params, 0x0, sizeof(dbus_method_param_s));
6905
6906         dbus_set_method_param(&params, "RemoveAllNetworks", g_pd->iface_path, g_dbus);
6907         params.params = NULL;
6908
6909         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
6910         if (res < 0)
6911                 WDP_LOGE("Failed to send [RemoveAllNetworks] command to wpa_supplicant");
6912         else
6913                 WDP_LOGD("Succeeded to remove all networks from supplicant");
6914
6915         WDP_LOGD("Succeeded to remove all network");
6916         __WDP_LOG_FUNC_EXIT__;
6917         return res;
6918 }
6919
6920 int ws_get_wpa_status(int *wpa_status)
6921 {
6922         __WDP_LOG_FUNC_ENTER__;
6923         GDBusConnection *g_dbus = NULL;
6924         GVariant *param = NULL;
6925         GVariant *reply = NULL;
6926         GError *error = NULL;
6927
6928         if (!wpa_status) {
6929                 WDP_LOGE("Invalid parameter");
6930                 __WDP_LOG_FUNC_EXIT__;
6931                 return -1;
6932         }
6933
6934         *wpa_status = WFD_OEM_WPA_STATE_MAX;
6935
6936         g_dbus = g_pd->g_dbus;
6937         if (!g_dbus) {
6938                 WDP_LOGE("DBus connection is NULL");
6939                 __WDP_LOG_FUNC_EXIT__;
6940                 return -1;
6941         }
6942
6943         param = g_variant_new("(s)", SUPPLICANT_IFACE);
6944
6945         reply = g_dbus_connection_call_sync(
6946                         g_pd->g_dbus,
6947                         SUPPLICANT_SERVICE, /* bus name */
6948                         g_pd->iface_path, /* object path */
6949                         DBUS_PROPERTIES_INTERFACE, /* interface name */
6950                         DBUS_PROPERTIES_METHOD_GETALL, /* method name */
6951                         param, /* GVariant *params */
6952                         NULL, /* reply_type */
6953                         G_DBUS_CALL_FLAGS_NONE, /* flags */
6954                         SUPPLICANT_TIMEOUT , /* timeout */
6955                         NULL, /* cancellable */
6956                         &error); /* error */
6957
6958         if (error != NULL) {
6959                 WDP_LOGE("Error! Failed to get properties: [%s]",
6960                                                         error->message);
6961                 g_error_free(error);
6962                 if (reply)
6963                         g_variant_unref(reply);
6964                 __WDP_LOG_FUNC_EXIT__;
6965                 return -1;
6966         }
6967
6968         gchar *reply_str = NULL;
6969         if (reply)
6970                 reply_str = g_variant_print(reply, TRUE);
6971         WDP_LOGE("reply [%s]", reply_str ? reply_str : "NULL");
6972         g_free(reply_str);
6973
6974         if (reply != NULL) {
6975                 GVariantIter *iter = NULL;
6976                 g_variant_get(reply, "(a{sv})", &iter);
6977
6978                 if (iter != NULL) {
6979                         gchar *key = NULL;
6980                         GVariant *value = NULL;
6981
6982                         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
6983                                 if (g_strcmp0(key, "State") == 0) {
6984                                         const gchar *state = NULL;
6985                                         g_variant_get(value, "&s", &state);
6986                                         WDP_LOGI("state : [%s]", state);
6987
6988                                         if (g_strcmp0(state, "disconnected") == 0)
6989                                                 *wpa_status = WFD_OEM_WPA_STATE_DISCONNECTED;
6990                                         else if (g_strcmp0(state, "inactive") == 0)
6991                                                 *wpa_status = WFD_OEM_WPA_STATE_INACTIVE;
6992                                         else if (g_strcmp0(state, "scanning") == 0)
6993                                                 *wpa_status = WFD_OEM_WPA_STATE_SCANNING;
6994                                         else if (g_strcmp0(state, "authenticating") == 0)
6995                                                 *wpa_status = WFD_OEM_WPA_STATE_AUTHENTICATING;
6996                                         else if (g_strcmp0(state, "associating") == 0)
6997                                                 *wpa_status = WFD_OEM_WPA_STATE_ASSOCIATING;
6998                                         else if (g_strcmp0(state, "associated") == 0)
6999                                                 *wpa_status = WFD_OEM_WPA_STATE_ASSOCIATED;
7000                                         else if (g_strcmp0(state, "4way_handshake") == 0)
7001                                                 *wpa_status = WFD_OEM_WPA_STATE_4WAY_HANDSHAKE;
7002                                         else if (g_strcmp0(state, "group_handshake") == 0)
7003                                                 *wpa_status = WFD_OEM_WPA_STATE_GROUP_HANDSHAKE;
7004                                         else if (g_strcmp0(state, "completed") == 0)
7005                                                 *wpa_status = WFD_OEM_WPA_STATE_COMPLETED;
7006                                         else
7007                                                 *wpa_status = WFD_OEM_WPA_STATE_MAX;
7008                                 }
7009                         }
7010                         g_variant_iter_free(iter);
7011                 }
7012                 g_variant_unref(reply);
7013         } else {
7014                 WDP_LOGD("No properties");
7015         }
7016
7017         WDP_LOGI("wpa_status : [%d]", *wpa_status);
7018
7019         __WDP_LOG_FUNC_EXIT__;
7020         return 0;
7021 }
7022
7023 int ws_advertise_service(wfd_oem_asp_service_s *service, int replace)
7024 {
7025         __WDP_LOG_FUNC_ENTER__;
7026         GDBusConnection *g_dbus = NULL;
7027         GVariantBuilder *builder = NULL;
7028         GVariant *value = NULL;
7029         dbus_method_param_s params;
7030         unsigned int config_method = 0x1108;
7031         int auto_accept = 0;
7032         gboolean rep;
7033         int res = 0;
7034
7035         g_dbus = g_pd->g_dbus;
7036         if (!g_dbus) {
7037                 WDP_LOGE("DBus connection is NULL");
7038                 return -1;
7039         }
7040
7041         if (service->config_method == 2) {
7042                 config_method = WS_CONFIG_METHOD_KEYPAD |
7043                                 WS_CONFIG_METHOD_DISPLAY;
7044         } else if (service->config_method == 3) {
7045                 config_method = WS_CONFIG_METHOD_DISPLAY;
7046         } else if (service->config_method == 4) {
7047                 config_method = WS_CONFIG_METHOD_KEYPAD;
7048         }
7049
7050         if (service->auto_accept) {
7051                 if (service->role == 0)
7052                         auto_accept = 1;
7053                 else
7054                         auto_accept = 2;
7055         } else {
7056                 auto_accept = 0;
7057         }
7058
7059         rep = (replace == 1);
7060
7061         memset(&params, 0x0, sizeof(dbus_method_param_s));
7062
7063         dbus_set_method_param(&params, "AddService", g_pd->iface_path, g_dbus);
7064
7065         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7066
7067         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("asp"));
7068         g_variant_builder_add(builder, "{sv}", "auto_accept", g_variant_new_int32(auto_accept));
7069         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(service->adv_id));
7070         g_variant_builder_add(builder, "{sv}", "svc_state", g_variant_new_uint32(service->status));
7071         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new_uint32(config_method));
7072         g_variant_builder_add(builder, "{sv}", "replace", g_variant_new_boolean(rep));
7073         if (service->service_type != NULL)
7074                 g_variant_builder_add(builder, "{sv}", "adv_str",
7075                         g_variant_new_string(service->service_type));
7076         if (service->service_info != NULL)
7077                 g_variant_builder_add(builder, "{sv}", "svc_info",
7078                                 g_variant_new_string(service->service_info));
7079         if (service->instance_name != NULL)
7080                 g_variant_builder_add(builder, "{sv}", "svc_instance",
7081                                 g_variant_new_string(service->instance_name));
7082
7083         value = g_variant_new("(a{sv})", builder);
7084         g_variant_builder_unref(builder);
7085         DEBUG_G_VARIANT("Params : ", value);
7086
7087         params.params = value;
7088
7089         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7090         if (res < 0)
7091                 WDP_LOGE("Failed to send command to wpa_supplicant");
7092         else
7093                 WDP_LOGD("Succeeded to add service");
7094
7095         __WDP_LOG_FUNC_EXIT__;
7096         return 0;
7097 }
7098
7099 int ws_cancel_advertise_service(wfd_oem_asp_service_s *service)
7100 {
7101         __WDP_LOG_FUNC_ENTER__;
7102         GDBusConnection *g_dbus = NULL;
7103         GVariantBuilder *builder = NULL;
7104         GVariant *value = NULL;
7105         dbus_method_param_s params;
7106         int res = 0;
7107
7108         g_dbus = g_pd->g_dbus;
7109         if (!g_dbus) {
7110                 WDP_LOGE("DBus connection is NULL");
7111                 return -1;
7112         }
7113         memset(&params, 0x0, sizeof(dbus_method_param_s));
7114
7115         dbus_set_method_param(&params, "DeleteService", g_pd->iface_path, g_dbus);
7116
7117         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7118
7119         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new_string("asp"));
7120         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(service->adv_id));
7121
7122         value = g_variant_new("(a{sv})", builder);
7123         g_variant_builder_unref(builder);
7124         DEBUG_G_VARIANT("Params : ", value);
7125         params.params = value;
7126
7127         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7128         if (res < 0)
7129                 WDP_LOGE("Failed to send command to wpa_supplicant");
7130         else
7131                 WDP_LOGD("Succeeded to del service");
7132
7133         __WDP_LOG_FUNC_EXIT__;
7134         return 0;
7135 }
7136
7137 static void __ws_add_seek(wfd_oem_asp_service_s *service)
7138 {
7139         __WDP_LOG_FUNC_ENTER__;
7140         wfd_oem_asp_service_s *seek = NULL;
7141         if (!service) {
7142                 WDP_LOGE("invalid parameters");
7143                 return;
7144         }
7145
7146         seek = g_try_malloc0(sizeof(wfd_oem_asp_service_s));
7147         if (!seek) {
7148                 WDP_LOGE("Failed to allocate memory for service");
7149                 return;
7150         }
7151
7152         service->search_id = (intptr_t)seek;
7153         memcpy(seek, service, sizeof(wfd_oem_asp_service_s));
7154         if (service->service_type)
7155                 seek->service_type = strdup(service->service_type);
7156         seek_list = g_list_prepend(seek_list, seek);
7157
7158         __WDP_LOG_FUNC_EXIT__;
7159         return;
7160 }
7161
7162 static wfd_oem_asp_service_s * __ws_get_seek(long long unsigned asp_search_id)
7163 {
7164         __WDP_LOG_FUNC_ENTER__;
7165         wfd_oem_asp_service_s *seek = NULL;
7166         GList *list = NULL;
7167
7168         for (list = seek_list; list != NULL; list = list->next) {
7169                 seek = list->data;
7170                 if (seek && (seek->asp_search_id == asp_search_id)) {
7171                         WDP_LOGD("List found");
7172                         break;
7173                 } else {
7174                         seek = NULL;
7175                 }
7176         }
7177         __WDP_LOG_FUNC_EXIT__;
7178         return seek;
7179 }
7180
7181 static void __ws_remove_seek(wfd_oem_asp_service_s *service)
7182 {
7183         __WDP_LOG_FUNC_ENTER__;
7184         wfd_oem_asp_service_s *seek = NULL;
7185         GList *list = NULL;
7186
7187         for (list = seek_list; list != NULL; list = list->next) {
7188
7189                 seek = list->data;
7190                 if (seek && (seek->asp_search_id == service->asp_search_id)) {
7191                         WDP_LOGD("List remove");
7192                         seek_list = g_list_remove(seek_list, seek);
7193                         g_free(seek->service_type);
7194                         g_free(seek->service_info);
7195                         g_free(seek);
7196                 }
7197         }
7198         __WDP_LOG_FUNC_EXIT__;
7199         return;
7200 }
7201
7202 static void __get_asp_search_id(GVariant *value, void *args)
7203 {
7204         __WDP_LOG_FUNC_ENTER__;
7205         wfd_oem_asp_service_s *service = NULL;
7206         wfd_oem_asp_service_s *seek = NULL;
7207         long long unsigned search_id = 0;
7208
7209         g_variant_get(value, "(t)", &search_id);
7210
7211         service = (wfd_oem_asp_service_s *)args;
7212         if (!service) {
7213                 WDP_LOGE("invalid parameters");
7214                 __WDP_LOG_FUNC_EXIT__;
7215                 return;
7216         }
7217
7218         seek = g_try_malloc0(sizeof(wfd_oem_asp_service_s));
7219         if (!seek) {
7220                 WDP_LOGE("Failed to allocate memory for service");
7221                 __WDP_LOG_FUNC_EXIT__;
7222                 return;
7223         }
7224
7225         service->search_id = search_id;
7226         memcpy(seek, service, sizeof(wfd_oem_asp_service_s));
7227         if (service->service_type)
7228                 seek->service_type = strdup(service->service_type);
7229         if (service->service_info)
7230                 seek->service_info = strdup(service->service_info);
7231         seek_list = g_list_append(seek_list, seek);
7232
7233         __WDP_LOG_FUNC_EXIT__;
7234         return;
7235 }
7236
7237 int ws_seek_service(wfd_oem_asp_service_s *service)
7238 {
7239         __WDP_LOG_FUNC_ENTER__;
7240         GDBusConnection *g_dbus = NULL;
7241         GList *list = NULL;
7242         wfd_oem_asp_service_s *seek = NULL;
7243         int res = 0;
7244
7245         g_dbus = g_pd->g_dbus;
7246         if (!g_dbus) {
7247                 WDP_LOGE("DBus connection is NULL");
7248                 __WDP_LOG_FUNC_EXIT__;
7249                 return -1;
7250         }
7251         list = g_list_last(seek_list);
7252         if (list == NULL) {
7253                 service->tran_id = 1;
7254
7255         } else {
7256                 seek = list->data;
7257                 if (seek)
7258                         service->tran_id = seek->tran_id + 1;
7259                 else
7260                         service->tran_id = 1;
7261         }
7262
7263         if (service->service_info) {
7264                 GVariantBuilder *builder = NULL;
7265                 GVariant *value = NULL;
7266                 dbus_method_param_s params;
7267
7268                 memset(&params, 0x0, sizeof(dbus_method_param_s));
7269                 dbus_set_method_param(&params, "ServiceDiscoveryRequest",
7270                                 g_pd->iface_path, g_dbus);
7271
7272                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7273
7274                 g_variant_builder_add(builder, "{sv}", "service_type",
7275                                 g_variant_new_string("asp"));
7276                 g_variant_builder_add(builder, "{sv}", "transaction_id",
7277                                 g_variant_new_byte(service->tran_id));
7278                 if (service->service_type != NULL)
7279                         g_variant_builder_add(builder, "{sv}", "svc_str",
7280                                         g_variant_new_string(service->service_type));
7281
7282                 if (service->service_info != NULL)
7283                         g_variant_builder_add(builder, "{sv}", "svc_info",
7284                                         g_variant_new_string(service->service_info));
7285
7286                 if (service->instance_name != NULL)
7287                         g_variant_builder_add(builder, "{sv}", "svc_instance",
7288                                         g_variant_new_string(service->instance_name));
7289
7290                 value = g_variant_new("(a{sv})", builder);
7291                 g_variant_builder_unref(builder);
7292
7293                 DEBUG_G_VARIANT("Params : ", value);
7294
7295                 params.params = value;
7296                 res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
7297                                 __get_asp_search_id, service);
7298
7299         } else {
7300                 __ws_add_seek(service);
7301         }
7302
7303         if (res < 0)
7304                 WDP_LOGE("Failed to send command to wpa_supplicant");
7305         else
7306                 WDP_LOGD("Succeeded to seek service");
7307
7308         __WDP_LOG_FUNC_EXIT__;
7309         return res;
7310 }
7311
7312 int ws_cancel_seek_service(wfd_oem_asp_service_s *service)
7313 {
7314         __WDP_LOG_FUNC_ENTER__;
7315         GDBusConnection *g_dbus = NULL;
7316         wfd_oem_asp_service_s *seek = NULL;
7317         dbus_method_param_s params;
7318         int res = 0;
7319
7320         g_dbus = g_pd->g_dbus;
7321         if (!g_dbus) {
7322                 WDP_LOGE("DBus connection is NULL");
7323                 __WDP_LOG_FUNC_EXIT__;
7324                 return -1;
7325         }
7326
7327         seek = __ws_get_seek(service->asp_search_id);
7328         if (!seek) {
7329                 WDP_LOGE("seek data is NULL");
7330                 __WDP_LOG_FUNC_EXIT__;
7331                 return -1;
7332         }
7333
7334         if (seek->service_info) {
7335
7336                 memset(&params, 0x0, sizeof(dbus_method_param_s));
7337                 dbus_set_method_param(&params, "ServiceDiscoveryCancelRequest",
7338                                 g_pd->iface_path, g_dbus);
7339
7340                 params.params = g_variant_new("(t)", service->search_id);
7341
7342                 DEBUG_G_VARIANT("Params : ", params.params);
7343
7344                 res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7345                 if (res < 0)
7346                         WDP_LOGE("Failed to send command to wpa_supplicant");
7347                 else
7348                         WDP_LOGD("Succeeded to cancel seek service");
7349         }
7350         if (res == 0)
7351                 __ws_remove_seek(seek);
7352
7353         __WDP_LOG_FUNC_EXIT__;
7354         return res;
7355 }
7356
7357 int ws_asp_prov_disc_req(wfd_oem_asp_prov_s *asp_params)
7358 {
7359         __WDP_LOG_FUNC_ENTER__;
7360         GDBusConnection *g_dbus = NULL;
7361         GVariantBuilder *builder = NULL;
7362         GVariantBuilder *mac_builder = NULL;
7363         GVariant *value = NULL;
7364         dbus_method_param_s params;
7365         static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
7366         int config_method = 0x1000;
7367         int res = 0;
7368         int i = 0;
7369
7370         if (!asp_params) {
7371                 WDP_LOGE("Invalid parameter");
7372                 __WDP_LOG_FUNC_EXIT__;
7373                 return -1;
7374         }
7375         g_dbus = g_pd->g_dbus;
7376         if (!g_dbus) {
7377                 WDP_LOGE("DBus connection is NULL");
7378                 __WDP_LOG_FUNC_EXIT__;
7379                 return -1;
7380         }
7381
7382         if (asp_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
7383                 config_method = 0x8;
7384         else if (asp_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
7385                 config_method = 0x100;
7386
7387         memset(&params, 0x0, sizeof(dbus_method_param_s));
7388
7389         dbus_set_method_param(&params, "ASPProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
7390
7391         if (asp_params->deferring == 0)
7392                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
7393                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(asp_params->service_mac));
7394         else
7395                 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
7396                                 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(asp_params->session_mac));
7397         WDP_LOGD("get peer path [%s]", peer_path);
7398
7399         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7400         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
7401
7402         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new_uint32(asp_params->adv_id));
7403         g_variant_builder_add(builder, "{sv}", "session_id", g_variant_new_uint32(asp_params->session_id));
7404         g_variant_builder_add(builder, "{sv}", "role", g_variant_new_byte(asp_params->network_role));
7405         g_variant_builder_add(builder, "{sv}", "method", g_variant_new_int32(config_method));
7406         if (asp_params->status > 0)
7407                 g_variant_builder_add(builder, "{sv}", "status", g_variant_new_int32(asp_params->status));
7408         if (asp_params->session_information)
7409                 g_variant_builder_add(builder, "{sv}", "info", g_variant_new_string(asp_params->session_information));
7410
7411         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7412         for (i = 0; i < OEM_MACADDR_LEN; i++)
7413                 g_variant_builder_add(mac_builder, "y", asp_params->service_mac[i]);
7414         g_variant_builder_add(builder, "{sv}", "adv_mac",
7415                         g_variant_new("ay", mac_builder));
7416         g_variant_builder_unref(mac_builder);
7417
7418         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7419         for (i = 0; i < OEM_MACADDR_LEN; i++)
7420                 g_variant_builder_add(mac_builder, "y", asp_params->session_mac[i]);
7421         g_variant_builder_add(builder, "{sv}", "session_mac",
7422                         g_variant_new("ay", mac_builder));
7423         g_variant_builder_unref(mac_builder);
7424
7425         value = g_variant_new("(a{sv})", builder);
7426         g_variant_builder_unref(builder);
7427         DEBUG_G_VARIANT("Params : ", value);
7428
7429         params.params = value;
7430
7431         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7432         if (res < 0)
7433                 WDP_LOGE("Failed to send command to wpa_supplicant");
7434         else
7435                 WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(asp_params->service_mac));
7436
7437         __WDP_LOG_FUNC_EXIT__;
7438         return res;
7439 }
7440
7441 int ws_set_eapol_ip_config(int enable)
7442 {
7443         __WDP_LOG_FUNC_ENTER__;
7444         GDBusConnection *g_dbus = NULL;
7445
7446         GVariant *value = NULL;
7447         GVariant *param = NULL;
7448         GVariantBuilder *builder = NULL;
7449         GVariantBuilder *type_builder = NULL;
7450         dbus_method_param_s params;
7451         int res = 0;
7452         int i = 0;
7453         enum {
7454                 IP_GO,
7455                 IP_MASK,
7456                 IP_START,
7457                 IP_END,
7458         };
7459         unsigned char eapol_ip[IP_END + 1][OEM_IPADDR_LEN + 1] = {0,};
7460
7461         if (!g_pd) {
7462                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7463                 __WDP_LOG_FUNC_EXIT__;
7464                 return -1;
7465         }
7466
7467         g_dbus = g_pd->g_dbus;
7468         if (!g_dbus) {
7469                 WDP_LOGE("DBus connection is NULL");
7470                 __WDP_LOG_FUNC_EXIT__;
7471                 return -1;
7472         }
7473         memset(&params, 0x0, sizeof(dbus_method_param_s));
7474
7475         dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
7476                          g_dbus);
7477
7478         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
7479
7480         memset(&eapol_ip, 0x0, (IP_END + 1) * (OEM_IPADDR_LEN + 1));
7481         if (enable == 1) {
7482                 memcpy(eapol_ip[IP_GO], DEFAULT_IP_GO, OEM_IPADDR_LEN);
7483                 memcpy(eapol_ip[IP_MASK], DEFAULT_IP_MASK, OEM_IPADDR_LEN);
7484                 memcpy(eapol_ip[IP_START], DEFAULT_IP_START, OEM_IPADDR_LEN);
7485                 memcpy(eapol_ip[IP_END], DEFAULT_IP_END, OEM_IPADDR_LEN);
7486         }
7487
7488         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7489         for (i = 0; i < OEM_IPADDR_LEN; i++)
7490                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_GO][i]);
7491         g_variant_builder_add(builder, "{sv}", "IpAddrGo",
7492                         g_variant_new("ay", type_builder));
7493         g_variant_builder_unref(type_builder);
7494
7495         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7496         for (i = 0; i < OEM_IPADDR_LEN; i++)
7497                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_MASK][i]);
7498         g_variant_builder_add(builder, "{sv}", "IpAddrMask",
7499                         g_variant_new("ay", type_builder));
7500         g_variant_builder_unref(type_builder);
7501
7502         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7503         for (i = 0; i < OEM_IPADDR_LEN; i++)
7504                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_START][i]);
7505         g_variant_builder_add(builder, "{sv}", "IpAddrStart",
7506                         g_variant_new("ay", type_builder));
7507         g_variant_builder_unref(type_builder);
7508
7509         type_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7510         for (i = 0; i < OEM_IPADDR_LEN; i++)
7511                 g_variant_builder_add(type_builder, "y", eapol_ip[IP_END][i]);
7512         g_variant_builder_add(builder, "{sv}", "IpAddrEnd",
7513                         g_variant_new("ay", type_builder));
7514         g_variant_builder_unref(type_builder);
7515
7516         value = g_variant_new("a{sv}", builder);
7517         g_variant_builder_unref(builder);
7518
7519         param = g_variant_new("(ssv)", SUPPLICANT_P2PDEVICE, "P2PDeviceConfig", value);
7520
7521         params.params = param;
7522
7523         DEBUG_G_VARIANT("Params : ", param);
7524         res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
7525         if (res < 0) {
7526                 WDP_LOGE("Failed to send command to wpa_supplicant");
7527         } else {
7528                 WDP_LOGI("Succeeded to set eapol IP");
7529         }
7530         __WDP_LOG_FUNC_EXIT__;
7531         return res;
7532 }
7533
7534 int ws_add_vsie(wfd_oem_vsie_frames_e frame_id, const char* vsie)
7535 {
7536         __WDP_LOG_FUNC_ENTER__;
7537         GDBusConnection *g_dbus = NULL;
7538         GVariant *value = NULL;
7539         GVariantBuilder *bytearray_builder = NULL;
7540         dbus_method_param_s params;
7541         int res = 0;
7542         int i = 0;
7543         size_t vsie_len = 0;
7544
7545         unsigned char *bytearray = NULL;
7546         size_t bytearray_len = 0;
7547
7548         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7549             vsie == NULL) {
7550                 WDP_LOGE("Invalid parameter");
7551                 return -1;
7552         }
7553
7554         if (!g_pd) {
7555                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7556                 __WDP_LOG_FUNC_EXIT__;
7557                 return -1;
7558         }
7559
7560         g_dbus = g_pd->g_dbus;
7561         if (!g_dbus) {
7562                 WDP_LOGE("DBus connection is NULL");
7563                 __WDP_LOG_FUNC_EXIT__;
7564                 return -1;
7565         }
7566
7567         vsie_len = strlen(vsie);
7568         if (vsie_len == 0) {
7569                 WDP_LOGE("vsie length is zero");
7570                 __WDP_LOG_FUNC_EXIT__;
7571                 return -1;
7572         }
7573
7574         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
7575
7576         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
7577         if (bytearray == NULL) {
7578                 WDP_LOGE("Failed to allocate memory to bytearray");
7579                 __WDP_LOG_FUNC_EXIT__;
7580                 return -1;
7581         }
7582
7583         if (__ws_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
7584                 WDP_LOGE("invalid vsie string");
7585                 g_free(bytearray);
7586                 __WDP_LOG_FUNC_EXIT__;
7587                 return -1;
7588         }
7589
7590         memset(&params, 0x0, sizeof(dbus_method_param_s));
7591         dbus_set_method_param(&params, "VendorElemAdd", g_pd->iface_path,
7592                               g_dbus);
7593
7594         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7595         for (i = 0; i < bytearray_len; i++)
7596                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
7597
7598         value = g_variant_new("(iay)", frame_id, bytearray_builder);
7599         g_variant_builder_unref(bytearray_builder);
7600
7601         params.params = value;
7602
7603         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
7604         if (res < 0) {
7605                 WDP_LOGE("Failed to send command to wpa_supplicant");
7606                 g_free(bytearray);
7607                 __WDP_LOG_FUNC_EXIT__;
7608                 return -1;
7609         }
7610
7611         WDP_LOGD("Succeeded to add vsie: Frame ID [%d], VSIE [%s]", frame_id,
7612                  vsie);
7613
7614         g_free(bytearray);
7615         __WDP_LOG_FUNC_EXIT__;
7616         return 0;
7617 }
7618
7619 int ws_get_vsie(wfd_oem_vsie_frames_e frame_id, char **vsie)
7620 {
7621         __WDP_LOG_FUNC_ENTER__;
7622         GDBusConnection *g_dbus = NULL;
7623         GVariant *param = NULL;
7624         GVariant *reply = NULL;
7625         GError *error = NULL;
7626
7627         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7628             vsie == NULL) {
7629                 WDP_LOGE("Invalid parameter");
7630                 __WDP_LOG_FUNC_EXIT__;
7631                 return -1;
7632         }
7633
7634         if (!g_pd) {
7635                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7636                 __WDP_LOG_FUNC_EXIT__;
7637                 return -1;
7638         }
7639
7640         g_dbus = g_pd->g_dbus;
7641         if (!g_dbus) {
7642                 WDP_LOGE("DBus connection is NULL");
7643                 __WDP_LOG_FUNC_EXIT__;
7644                 return -1;
7645         }
7646
7647         param = g_variant_new("(i)", frame_id);
7648
7649         reply = g_dbus_connection_call_sync(
7650                         g_pd->g_dbus,
7651                         SUPPLICANT_SERVICE, /* bus name */
7652                         g_pd->iface_path, /* object path */
7653                         SUPPLICANT_IFACE, /* interface name */
7654                         "VendorElemGet", /* method name */
7655                         param, /* GVariant *params */
7656                         NULL, /* reply_type */
7657                         G_DBUS_CALL_FLAGS_NONE, /* flags */
7658                         SUPPLICANT_TIMEOUT, /* timeout */
7659                         NULL, /* cancellable */
7660                         &error); /* error */
7661
7662         if (error != NULL) {
7663                 WDP_LOGE("Error! Failed to get vsie: [%s]", error->message);
7664                 g_error_free(error);
7665                 if (reply)
7666                         g_variant_unref(reply);
7667                 __WDP_LOG_FUNC_EXIT__;
7668                 return -1;
7669         }
7670
7671         if (reply != NULL) {
7672                 DEBUG_G_VARIANT("Reply : ", reply);
7673
7674                 GVariantIter *iter = NULL;
7675                 unsigned char *vsie_bytes = NULL;
7676                 int vsie_len = 0;
7677
7678                 g_variant_get(reply, "(ay)", &iter);
7679                 if (iter == NULL) {
7680                         WDP_LOGD("vsie is not present");
7681                         __WDP_LOG_FUNC_EXIT__;
7682                         return -1;
7683                 }
7684
7685                 vsie_len = __ws_unpack_ay_malloc(&vsie_bytes, iter);
7686                 if (vsie_bytes == NULL) {
7687                         WDP_LOGD("vsie_bytes not allocated");
7688                         __WDP_LOG_FUNC_EXIT__;
7689                         return -1;
7690                 }
7691
7692                 __ws_byte_to_txt(vsie_bytes, vsie, vsie_len);
7693                 if (!vsie) {
7694                         g_free(vsie_bytes);
7695                         WDP_LOGE("vsie not allocated.");
7696                         __WDP_LOG_FUNC_EXIT__;
7697                         return -1;
7698                 }
7699
7700                 g_free(vsie_bytes);
7701         }
7702
7703         WDP_LOGD("Succeeded to get vsie: Frame ID [%d], VSIE [%s]", frame_id,
7704                  *vsie);
7705         __WDP_LOG_FUNC_EXIT__;
7706         return 0;
7707 }
7708
7709 int ws_remove_vsie(wfd_oem_vsie_frames_e frame_id, const char *vsie)
7710 {
7711         __WDP_LOG_FUNC_ENTER__;
7712         GDBusConnection *g_dbus = NULL;
7713         GVariantBuilder *bytearray_builder = NULL;
7714         GVariant *value = NULL;
7715         dbus_method_param_s params;
7716         int res = 0;
7717         int i = 0;
7718         size_t vsie_len = 0;
7719
7720         unsigned char *bytearray = NULL;
7721         size_t bytearray_len = 0;
7722
7723         if (frame_id >= WFD_OEM_VSIE_FRAME_MAX ||
7724             vsie == NULL) {
7725                 WDP_LOGE("Invalid parameter");
7726                 return -1;
7727         }
7728
7729         if (!g_pd) {
7730                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7731                 __WDP_LOG_FUNC_EXIT__;
7732                 return -1;
7733         }
7734
7735         g_dbus = g_pd->g_dbus;
7736         if (!g_dbus) {
7737                 WDP_LOGE("DBus connection is NULL");
7738                 __WDP_LOG_FUNC_EXIT__;
7739                 return -1;
7740         }
7741
7742         vsie_len = strlen(vsie);
7743         if (vsie_len == 0) {
7744                 WDP_LOGE("vsie length is zero");
7745                 __WDP_LOG_FUNC_EXIT__;
7746                 return -1;
7747         }
7748
7749         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
7750
7751         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
7752         if (bytearray == NULL) {
7753                 WDP_LOGE("Failed to allocate memory to bytearray");
7754                 __WDP_LOG_FUNC_EXIT__;
7755                 return -1;
7756         }
7757
7758         if (__ws_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
7759                 WDP_LOGE("invalid vsie string");
7760                 g_free(bytearray);
7761                 __WDP_LOG_FUNC_EXIT__;
7762                 return -1;
7763         }
7764
7765         memset(&params, 0x0, sizeof(dbus_method_param_s));
7766         dbus_set_method_param(&params, "VendorElemRem", g_pd->iface_path,
7767                               g_dbus);
7768
7769         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
7770         for (i = 0; i < bytearray_len; i++)
7771                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
7772
7773         value = g_variant_new("(iay)", frame_id, bytearray_builder);
7774         g_variant_builder_unref(bytearray_builder);
7775
7776         params.params = value;
7777
7778         res = dbus_method_call(&params, SUPPLICANT_IFACE, NULL, NULL);
7779         if (res < 0) {
7780                 WDP_LOGE("Failed to send command to wpa_supplicant");
7781                 g_free(bytearray);
7782                 __WDP_LOG_FUNC_EXIT__;
7783                 return -1;
7784         }
7785
7786         WDP_LOGD("Succeeded to remove vsie: Frame ID [%d], VSIE [%s]", frame_id,
7787                  vsie);
7788         g_free(bytearray);
7789         __WDP_LOG_FUNC_EXIT__;
7790         return 0;
7791 }
7792
7793 int ws_set_supported_wps_mode(int wps_mode)
7794 {
7795         __WDP_LOG_FUNC_ENTER__;
7796         char config_value[DBUS_OBJECT_PATH_MAX+1] = {0,};
7797         int length = 0;
7798         int new_wps_mode = wps_mode;
7799         int res = 0;
7800
7801         if (!config) {
7802                 WDP_LOGE("no configurable data found");
7803                 __WDP_LOG_FUNC_EXIT__;
7804                 return -1;
7805         }
7806
7807         if (new_wps_mode == 0) {
7808                 WDP_LOGE("Reset to default value");
7809                 new_wps_mode = WFD_OEM_WPS_MODE_PBC|WFD_OEM_WPS_MODE_DISPLAY|WFD_OEM_WPS_MODE_KEYPAD;
7810         }
7811
7812         if (new_wps_mode & WFD_OEM_WPS_MODE_KEYPAD) {
7813                 g_strlcat(config_value, "keypad ", sizeof(config_value));
7814                 length += 7;
7815         }
7816         if (new_wps_mode & WFD_OEM_WPS_MODE_PBC) {
7817                 g_strlcat(config_value, "virtual_push_button ", sizeof(config_value));
7818                 length += 20;
7819         }
7820         if (new_wps_mode & WFD_OEM_WPS_MODE_DISPLAY) {
7821                 g_strlcat(config_value, "physical_display ", sizeof(config_value));
7822                 length += 17;
7823         }
7824         config_value[length-1] = 0;
7825         g_strlcpy(config->config_methods, config_value, OEM_CONFIG_METHOD_LEN);
7826         WDP_LOGD("config_value = %s, length = %d", config_value, length-1);
7827         res = __ws_set_config_methods();
7828         if (res < 0) {
7829                 WDP_LOGE("Failed to set config method");
7830                 __WDP_LOG_FUNC_EXIT__;
7831                 return -1;
7832         }
7833         wps_config_method = new_wps_mode;
7834         __WDP_LOG_FUNC_EXIT__;
7835         return 0;
7836 }
7837
7838 static int _ws_remove_persistent_group_by_object_path(const char *object_path)
7839 {
7840         __WDP_LOG_FUNC_ENTER__;
7841         GDBusConnection *g_dbus = NULL;
7842         dbus_method_param_s params;
7843         int res = 0;
7844
7845         if (!g_pd) {
7846                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7847                 __WDP_LOG_FUNC_EXIT__;
7848                 return -1;
7849         }
7850
7851         g_dbus = g_pd->g_dbus;
7852         if (!g_dbus) {
7853                 WDP_LOGE("DBus connection is NULL");
7854                 __WDP_LOG_FUNC_EXIT__;
7855                 return -1;
7856         }
7857
7858         memset(&params, 0x0, sizeof(dbus_method_param_s));
7859         dbus_set_method_param(&params, "RemovePersistentGroup",
7860                         g_pd->iface_path, g_dbus);
7861         params.params = g_variant_new("(o)", object_path);
7862
7863         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7864         if (res < 0) {
7865                 WDP_LOGE("Failed to send command to wpa_supplicant");
7866                 __WDP_LOG_FUNC_EXIT__;
7867                 return -1;
7868         }
7869
7870         ws_save_config();
7871         WDP_LOGD("Succeeded to remove persistent group");;
7872         __WDP_LOG_FUNC_EXIT__;
7873         return 0;
7874 }
7875
7876 int ws_remove_persistent_device(unsigned char *mac_addr)
7877 {
7878         __WDP_LOG_FUNC_ENTER__;
7879         GDBusConnection *g_dbus = NULL;
7880         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
7881         int i = 0;
7882         int cnt = 0;
7883         int need_delete = 0;
7884         int res = 0;
7885
7886         if (!g_pd) {
7887                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
7888                 __WDP_LOG_FUNC_EXIT__;
7889                 return -1;
7890         }
7891
7892         g_dbus = g_pd->g_dbus;
7893         if (!g_dbus) {
7894                 WDP_LOGE("DBus connection is NULL");
7895                 __WDP_LOG_FUNC_EXIT__;
7896                 return -1;
7897         }
7898         memset(&networks, 0x0, WS_MAX_PERSISTENT_COUNT * sizeof(ws_network_info_s));
7899         dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICANT_P2PDEVICE,
7900                         __ws_extract_p2pdevice_details, networks);
7901
7902         cnt = networks[0].total;
7903
7904         WDP_LOGD("Persistent Group Count=%d", cnt);
7905         if (cnt > WS_MAX_PERSISTENT_COUNT) {
7906                 WDP_LOGE("Persistent group count exceeded or parsing error");
7907                 __WDP_LOG_FUNC_EXIT__;
7908                 return -1;
7909         }
7910
7911         for (i = 0 ; i < cnt ; i++) {
7912                 int j = 0;
7913                 need_delete = 0;
7914
7915                 WDP_LOGD("----persistent group [%d]----", i);
7916                 WDP_LOGD("network_id [%d]", networks[i].network_id);
7917                 WDP_LOGD("ssid [%s]", networks[i].ssid);
7918                 WDP_LOGD("bssid ["MACSTR"]", MAC2STR(networks[i].bssid));
7919                 WDP_LOGD("p2p_client_num [%d]", networks[i].p2p_client_num);
7920                 for (j = 0; j < networks[i].p2p_client_num; j++) {
7921                         WDP_LOGD("p2p_client_list ["MACSTR"]", MAC2STR(networks[i].p2p_client_list[j]));
7922                 }
7923
7924                 WDP_LOGD("mac_addr ["MACSTR"]", MAC2STR(mac_addr));
7925
7926                 if (memcmp(mac_addr, networks[i].bssid, WS_MACADDR_LEN) == 0) {
7927                         WDP_LOGD("Persistent group owner found [%d: "MACSTR"]", networks[i].network_id, MAC2STR(mac_addr));
7928                         need_delete = 1;
7929                 }
7930
7931                 if (need_delete == 0) {
7932                         for (j = 0; j < networks[i].p2p_client_num; j++) {
7933                                 if (!memcmp(mac_addr, networks[i].p2p_client_list[j], WS_MACADDR_LEN)) {
7934                                         WDP_LOGD("Persistent group client found [%d: "MACSTR"]", networks[i].network_id, MAC2STR(mac_addr));
7935                                         need_delete = 1;
7936                                 }
7937                         }
7938                 }
7939
7940                 if (need_delete) {
7941                         res = _ws_remove_persistent_group_by_object_path(networks[i].persistent_path);
7942                         WDP_LOGI("persistent group deleted [%s]", networks[i].persistent_path);
7943                         if (res < 0) {
7944                                 WDP_LOGE("Failed to _ws_remove_persistent_group_by_object_path");
7945                         } else {
7946                                 WDP_LOGD("Succeeded to _ws_remove_persistent_group_by_object_path");
7947                         }
7948                 }
7949         }
7950
7951         __WDP_LOG_FUNC_EXIT__;
7952         return res;
7953 }
7954
7955 int ws_remove_all_persistent_device(void)
7956 {
7957         __WDP_LOG_FUNC_ENTER__;
7958         GDBusConnection *g_dbus = NULL;
7959         dbus_method_param_s params;
7960         int res = 0;
7961
7962         g_dbus = g_pd->g_dbus;
7963         if (!g_dbus) {
7964                 WDP_LOGE("DBus connection is NULL");
7965                 __WDP_LOG_FUNC_EXIT__;
7966                 return -1;
7967         }
7968         memset(&params, 0x0, sizeof(dbus_method_param_s));
7969
7970         dbus_set_method_param(&params, "RemoveAllPersistentGroups", g_pd->iface_path, g_dbus);
7971         params.params = NULL;
7972
7973         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE, NULL, NULL);
7974         if (res < 0) {
7975                 WDP_LOGE("Failed to RemoveAllPersistentGroups");
7976         } else {
7977                 WDP_LOGD("Succeeded to RemoveAllPersistentGroups");
7978         }
7979
7980         ws_save_config();
7981         WDP_LOGD("Succeeded to remove all network");
7982         __WDP_LOG_FUNC_EXIT__;
7983         return res;
7984 }
7985
7986 static void __ws_get_supported_channels_reply(GVariant *reply, void *user_data)
7987 {
7988         __WDP_LOG_FUNC_ENTER__;
7989
7990         GVariantIter *iter = NULL;
7991         wfd_oem_supported_channels_s *data = (wfd_oem_supported_channels_s *)user_data;
7992
7993         if (reply) {
7994                 int channel = 0;
7995
7996                 g_variant_get(reply, "(ai)", &iter);
7997
7998                 while (g_variant_iter_loop(iter, "i", &channel))
7999                         data->channels[data->count++] = channel;
8000
8001                 g_variant_iter_free (iter);
8002
8003         } else {
8004                 WDP_LOGE("Reply is NULL");
8005         }
8006         __WDP_LOG_FUNC_EXIT__;
8007 }
8008
8009 int ws_get_supported_channels(wfd_oem_supported_channels_s *data)
8010 {
8011         __WDP_LOG_FUNC_ENTER__;
8012         int res = 0;
8013         dbus_method_param_s params;
8014
8015         if (!g_pd) {
8016                 WDP_LOGE("ws_dbus_plugin_data_s is not created yet");
8017                 __WDP_LOG_FUNC_EXIT__;
8018                 return -1;
8019         }
8020
8021         memset(&params, 0x0, sizeof(dbus_method_param_s));
8022         memset(data, 0x0, sizeof(wfd_oem_supported_channels_s));
8023
8024         dbus_set_method_param(&params, "GetSupportedChannels", g_pd->iface_path, g_pd->g_dbus);
8025         params.params = NULL;
8026
8027         res = dbus_method_call(&params, SUPPLICANT_P2PDEVICE,
8028                         __ws_get_supported_channels_reply, data);
8029         if (res < 0) {
8030                 WDP_LOGE("Failed to GetSupportedChannels");
8031         } else {
8032                 WDP_LOGD("Succeeded to GetSupportedChannels");
8033         }
8034
8035         __WDP_LOG_FUNC_EXIT__;
8036         return res;
8037 }