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