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