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