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