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