2 * Network Configuration Module
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * This file implements wifi direct wpasupplicant dbus plugin functions.
23 * @file wfd-plugin-dbus-wpasupplicant.c
24 * @author Jiung Yu (jiung.yu@samsung.com)
31 #include <sys/types.h>
33 #include <sys/socket.h>
40 #include <sys/ioctl.h>
46 #include "wifi-direct-oem.h"
47 #include "wfd-plugin-log.h"
48 #include "wfd-plugin-wpasupplicant.h"
49 #include "dbus/wfd-plugin-supplicant-dbus.h"
51 #define NETCONFIG_SERVICE "net.netconfig"
52 #define NETCONFIG_WIFI_INTERFACE "net.netconfig.wifi"
53 #define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
55 #define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
57 static wfd_oem_ops_s supplicant_ops = {
60 .activate = ws_activate,
61 .deactivate = ws_deactivate,
63 .start_scan = ws_start_scan,
64 .stop_scan = ws_stop_scan,
65 .get_visibility = ws_get_visibility,
66 .set_visibility = ws_set_visibility,
67 .get_scan_result = ws_get_scan_result,
68 .get_peer_info = ws_get_peer_info,
70 .prov_disc_req = ws_prov_disc_req,
72 .connect = ws_connect,
73 .disconnect = ws_disconnect,
74 .reject_connection = ws_reject_connection,
75 .cancel_connection = ws_cancel_connection,
77 .get_connected_peers = ws_get_connected_peers,
78 .get_pin = ws_get_pin,
79 .set_pin = ws_set_pin,
80 .get_supported_wps_mode = ws_get_supported_wps_mode,
82 .create_group = ws_create_group,
83 .destroy_group = ws_destroy_group,
85 .wps_start = ws_wps_start,
86 .enrollee_start = ws_enrollee_start,
87 .wps_cancel = ws_wps_cancel,
89 .get_dev_name = ws_get_dev_name,
90 .set_dev_name = ws_set_dev_name,
91 .get_dev_mac = ws_get_dev_mac,
92 .get_dev_type = ws_get_dev_type,
93 .set_dev_type = ws_set_dev_type,
94 .get_go_intent = ws_get_go_intent,
95 .set_go_intent = ws_set_go_intent,
96 .set_country = ws_set_country,
97 .get_persistent_groups = ws_get_persistent_groups,
98 .remove_persistent_group = ws_remove_persistent_group,
99 .set_persistent_reconnect = ws_set_persistent_reconnect,
101 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
102 .start_service_discovery = ws_start_service_discovery,
103 .cancel_service_discovery = ws_cancel_service_discovery,
105 .serv_add = ws_serv_add,
106 .serv_del = ws_serv_del,
107 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
109 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
110 .miracast_init = ws_miracast_init,
111 .set_display = ws_set_display,
112 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
114 .refresh = ws_refresh,
118 static ws_dbus_plugin_data_s *g_pd;
120 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
121 static GList *service_list;
122 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
124 static void _supplicant_signal_cb(GDBusConnection *connection,
125 const gchar *sender, const gchar *object_path, const gchar *interface,
126 const gchar *signal, GVariant *parameters, gpointer user_data);
128 static void _p2pdevice_signal_cb(GDBusConnection *connection,
129 const gchar *sender, const gchar *object_path, const gchar *interface,
130 const gchar *signal, GVariant *parameters, gpointer user_data);
132 static void _group_signal_cb(GDBusConnection *connection,
133 const gchar *sender, const gchar *object_path, const gchar *interface,
134 const gchar *signal, GVariant *parameters, gpointer user_data);
136 static int __ws_txt_to_mac(unsigned char *txt, unsigned char *mac)
141 WDP_LOGE("Invalid parameter");
146 mac[i++] = (char) strtoul((char *)txt, (char **)&txt, 16);
147 if (!*txt++ || i == 6)
151 if (i != WS_MACADDR_LEN)
157 static int __ws_mac_compact_to_normal(char *compact, unsigned char *mac)
159 g_snprintf((char *)mac, OEM_MACSTR_LEN, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
160 compact[0], compact[1], compact[2], compact[3],
161 compact[4], compact[5], compact[6], compact[7],
162 compact[8], compact[9], compact[10], compact[11]);
166 static char *__ws_wps_to_txt(int wps_mode)
169 case WFD_OEM_WPS_MODE_PBC:
170 return WS_DBUS_STR_PBC;
172 case WFD_OEM_WPS_MODE_DISPLAY:
173 return WS_DBUS_STR_DISPLAY;
175 case WFD_OEM_WPS_MODE_KEYPAD:
176 return WS_DBUS_STR_KEYPAD;
183 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
184 static int __ws_byte_to_hex(char *buf, int buf_size, unsigned char *data, int data_len)
188 char *end = buf + buf_size;
192 for (i = 0; i < data_len; i++) {
193 ret = snprintf(pos, end - pos, "%02x", data[i]);
194 if (ret < 0 || ret >= end - pos) {
204 static int __ws_hex_to_num(char *src, int len)
209 if (!src || len < 0) {
210 WDP_LOGE("Invalid parameter");
214 temp = (char*) g_try_malloc0(len+1);
216 WDP_LOGE("Failed to allocate memory");
220 memcpy(temp, src, len);
221 num = strtoul(temp, NULL, 16);
227 static int __ws_hex_to_txt(char *src, int length, char *dest)
229 // TODO: check it is good to change dest parameter as double pointer.
230 // It could be better to allocate memory for dest parameter here.
236 if (!src || length < 0 || !dest) {
237 WDP_LOGE("Invalid parameter");
241 // TODO: flush destination memory
251 for (i=0; i<len/2 && *ptr!=0; i++) {
252 temp[i] = (char) __ws_hex_to_num(ptr, 2);
254 WDP_LOGE("Failed to convert hexa string to num");
263 gboolean _ws_util_execute_file(const char *file_path,
264 char *const args[], char *const envs[])
269 register unsigned int index = 0;
271 while (args[index] != NULL) {
272 WDP_LOGD("[%s]", args[index]);
276 if (!(pid = fork())) {
277 WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
278 WDP_LOGD("Inside child, exec (%s) command", file_path);
281 if (execve(file_path, args, envs) == -1) {
282 WDP_LOGE("Fail to execute command (%s)", strerror(errno));
285 } else if (pid > 0) {
286 if (waitpid(pid, &rv, 0) == -1)
287 WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
289 WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
290 } else if (WIFSIGNALED(rv)) {
291 WDP_LOGD("killed by signal %d", WTERMSIG(rv));
292 } else if (WIFSTOPPED(rv)) {
293 WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
294 } else if (WIFCONTINUED(rv)) {
295 WDP_LOGD("continued");
301 WDP_LOGE("failed to fork (%s)", strerror(errno));
305 static int __ws_segment_to_service(char *segment, wfd_oem_new_service_s **service)
307 wfd_oem_new_service_s *serv_tmp = NULL;
313 if (!segment || !service) {
314 WDP_LOGE("Invalid parameter");
319 WDP_LOGD("Segment: %s", segment);
321 serv_tmp = (wfd_oem_new_service_s*) calloc(1, sizeof(wfd_oem_new_service_s));
323 WDP_LOGE("Failed to allocate memory for service");
327 serv_tmp->protocol = __ws_hex_to_num(ptr, 2);
328 serv_tmp->trans_id = __ws_hex_to_num(ptr+2, 2);
329 serv_tmp->status = __ws_hex_to_num(ptr+4, 2);
331 WDP_LOGD("Protocol[%d], Transaction ID[%d], Status[%d]", serv_tmp->protocol, serv_tmp->trans_id, serv_tmp->status);
333 if (serv_tmp->status != 0) {
334 WDP_LOGE("Service status is not success");
339 if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
340 WDP_LOGD("===== Bonjour service =====");
341 char compr[5] = {0, };
342 char query[256] = {0, };
343 char rdata[256] = {0, };
346 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
347 len = __ws_hex_to_num(ptr, 2);
350 temp = (char*) calloc(1, len+2);
352 for (i=0; i<len; i++) {
353 temp[i+1] = (char) __ws_hex_to_num(ptr, 2);
356 strncat(query, temp, len+1);
362 if (!strncmp(ptr, "c0", 2)) {
363 memcpy(compr, ptr, 4);
366 if (!strncmp(ptr, "27", 2)) {
367 WDP_LOGD("Segment ended");
371 dns_type = __ws_hex_to_num(ptr, 4);
373 if (dns_type == 12) {
374 if (!strncmp(compr, "c011", 4))
375 strncat(query, ".local.", 7);
376 else if (!strncmp(compr, "c00c", 4))
377 strncat(query, "._tcp.local.", 12);
378 else if (!strncmp(compr, "c01c", 4))
379 strncat(query, "._udp.local.", 12);
383 serv_tmp->data.bonjour.query = strdup(query + 1);
384 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
385 len = __ws_hex_to_num(ptr, 2);
388 temp = (char*) calloc(1, len+2);
390 for (i=0; i<len; i++) {
391 temp[i+1] = (char) __ws_hex_to_num(ptr, 2);
394 strncat(rdata, temp, len+1);
399 serv_tmp->data.bonjour.rdata = strdup(rdata + 1);
401 WDP_LOGD("Query: %s", serv_tmp->data.bonjour.query);
402 WDP_LOGD("RData: %s", serv_tmp->data.bonjour.rdata);
403 } else if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_VENDOR) {
404 WDP_LOGD("===== Vendor specific service =====");
405 if (!strncmp(ptr, "0000f00b", 8)) {
406 WDP_LOGD("\tSAMSUNG_BT_ADDR");
408 serv_tmp->protocol = WFD_OEM_SERVICE_TYPE_BT_ADDR;
409 serv_tmp->data.vendor.data1 = (char*) calloc(1, 9);
410 g_strlcpy(serv_tmp->data.vendor.data1, "0000f00b", 9);
411 serv_tmp->data.vendor.data2 = (char*) calloc(1, 18);
412 __ws_hex_to_txt(ptr, 0, serv_tmp->data.vendor.data2);
414 WDP_LOGD("Info1: %s", serv_tmp->data.vendor.data1);
415 WDP_LOGD("Info2: %s", serv_tmp->data.vendor.data2);
417 WDP_LOGE("Not supported yet. Only bonjour and samsung vendor service supproted [%d]",
427 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
429 static void __ws_path_to_addr(char *peer_path,
430 unsigned char *dev_addr, GVariant *parameter)
432 __WDP_LOG_FUNC_ENTER__;
434 static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
435 const char *path = NULL;
438 g_variant_get(parameter, "(o)", &path);
439 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
440 WDP_LOGE("Retrive Added path [%s]", peer_path);
442 loc = strrchr(peer_path,'/');
443 __ws_mac_compact_to_normal(loc + 1, peer_dev);
445 __ws_txt_to_mac(peer_dev, dev_addr);
446 WDP_LOGE("peer mac [" MACSTR "]", MAC2STR(dev_addr));
449 __WDP_LOG_FUNC_EXIT__;
452 static int __ws_unpack_ay(unsigned char *dst, GVariant *src, int size)
454 GVariantIter *iter = NULL;
458 if (!dst || !src || size == 0) {
459 WDP_LOGE("Invalid parameter");
462 g_variant_get(src, "ay", &iter);
464 WDP_LOGE("failed to get iterator");
468 while (g_variant_iter_loop (iter, "y", &dst[length])) {
473 g_variant_iter_free(iter);
476 WDP_LOGE("array is shorter than size");
483 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
484 static int __parsing_wfd_info(unsigned char *wfd_dev_info,
485 wfd_oem_display_s *display )
487 __WDP_LOG_FUNC_ENTER__;
490 if (!wfd_dev_info || !display) {
491 WDP_LOGE("Invalid parameter");
492 __WDP_LOG_FUNC_EXIT__;
496 wfd_info = (wfd_dev_info[3]<<8 | wfd_dev_info[4]);
498 if (wfd_info & WS_WFD_INFO_PRIMARY_SINK)
499 display->type |= WS_WFD_INFO_PRIMARY_SINK;
500 if (wfd_info & WS_WFD_INFO_SECONDARY_SINK)
501 display->type |= WS_WFD_INFO_SECONDARY_SINK;
503 display->availablity = (wfd_info & WS_WFD_INFO_AVAILABLITY) >> 4;
504 display->hdcp_support = (wfd_info & WS_WFD_INFO_HDCP_SUPPORT) >> 8;
506 display->port = (wfd_dev_info[5]<<8 | wfd_dev_info[6]);
507 display->max_tput = (wfd_dev_info[7]<<8 | wfd_dev_info[8]);
509 WDP_LOGD("type [%d],availablity [%d],hdcp_support [%d],ctrl_port [%d] "
510 "max_tput[%d]", display->type, display->availablity,
511 display->hdcp_support, display->port,display->max_tput);
513 __WDP_LOG_FUNC_EXIT__;
516 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
518 static void _supplicant_signal_cb(GDBusConnection *connection,
519 const gchar *sender, const gchar *object_path, const gchar *interface,
520 const gchar *signal, GVariant *parameters, gpointer user_data)
522 DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
524 if (!g_strcmp0(signal,"InterfaceAdded")) {
525 WDP_LOGD("InterfaceAdded");
526 static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
527 const char *path = NULL;
528 GVariantIter *iter = NULL;
529 const char *ifname = NULL;
531 g_variant_get(parameters, "(oa{sv})", &path, &iter);
533 g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
534 WDP_LOGD("Retrive Added path [%s]", interface_path);
538 GVariant *value = NULL;
540 while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
541 CHECK_KEY_VALUE(key, value);
543 if (!g_strcmp0(key,"Ifname")) {
544 g_variant_get(value, "s", &ifname);
545 WDP_LOGD("Retrive added interface [%s]", ifname);
546 if(!g_strcmp0(ifname, GROUP_IFACE_NAME))
547 g_strlcpy(g_pd->group_iface_path, path, DBUS_OBJECT_PATH_MAX);
550 g_variant_iter_free(iter);
553 } else if (!g_strcmp0(signal,"InterfaceRemoved")) {
554 WDP_LOGE("InterfaceRemoved");
555 static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
556 const char *path = NULL;
558 g_variant_get(parameters, "(o)", &path);
559 g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
561 WDP_LOGD("Retrive removed path [%s]", interface_path);
562 if (!g_strcmp0(g_pd->group_iface_path, interface_path))
563 memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
565 } else if(!g_strcmp0(signal,"PropertiesChanged")){
566 WDP_LOGD("PropertiesChanged");
570 static void __ws_get_peer_property(const char *key, GVariant *value, void *user_data)
572 __WDP_LOG_FUNC_ENTER__;
574 wfd_oem_device_s *peer = (wfd_oem_device_s *)user_data;
576 __WDP_LOG_FUNC_EXIT__;
579 CHECK_KEY_VALUE(key, value);
581 if (g_strcmp0(key, "DeviceName") == 0) {
582 const char *name = NULL;
584 g_variant_get(value, "s", &name);
585 g_strlcpy(peer->dev_name, name, WS_SSID_LEN);
586 WDP_LOGD("[%s]", peer->dev_name);
588 } else if (g_strcmp0(key, "config_method") == 0) {
589 int config_methods = 0;
590 g_variant_get(value, "q", &config_methods);
592 if (config_methods & WS_CONFIG_METHOD_DISPLAY)
593 peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
594 if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
595 peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
596 if (config_methods & WS_CONFIG_METHOD_KEYPAD)
597 peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
598 WDP_LOGD("[0x%x]", peer->config_methods);
600 } else if (g_strcmp0(key, "level") == 0) {
602 } else if (g_strcmp0(key, "devicecapability") == 0) {
603 unsigned char devicecapability = 0;
605 g_variant_get(value, "y", &devicecapability);
606 peer->dev_flags = (int)devicecapability;
607 WDP_LOGD("[0x%02x]", peer->dev_flags);
609 } else if (g_strcmp0(key, "groupcapability") == 0) {
610 unsigned char groupcapability = 0;
612 g_variant_get(value, "y", &groupcapability);
613 WDP_LOGD("[0x%02x]", groupcapability);
614 if (groupcapability & WS_GROUP_CAP_GROUP_OWNER) {
615 peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
616 peer->dev_role = WFD_OEM_DEV_ROLE_GO;
618 if (groupcapability & WS_GROUP_CAP_PERSISTENT_GROUP)
619 peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
621 } else if (g_strcmp0(key, "PrimaryDeviceType") == 0) {
622 unsigned char primarydevicetype[WS_DEVTYPE_LEN] = {0,};
624 if(__ws_unpack_ay(primarydevicetype, value, WS_DEVTYPE_LEN)) {
625 peer->pri_dev_type = primarydevicetype[1];
626 peer->sec_dev_type = primarydevicetype[WS_DEVTYPE_LEN -1];
628 } else if (g_strcmp0(key, "SecondaryDeviceTypes") == 0) {
629 } else if (g_strcmp0(key, "VendorExtension") == 0) {
630 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
631 } else if (g_strcmp0(key, "IEs") == 0) {
632 unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
634 if(__ws_unpack_ay(ies, value, WFD_SUBELEM_LEN_DEV_INFO + 3))
635 __parsing_wfd_info(ies, &(peer->display));
636 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
637 } else if (g_strcmp0(key, "DeviceAddress") == 0) {
639 if (__ws_unpack_ay(peer->dev_addr, value, WS_MACADDR_LEN))
640 WDP_LOGD("[" MACSTR "]", MAC2STR(peer->dev_addr));
642 } else if (g_strcmp0(key, "InterfacedAddress") == 0) {
644 if (__ws_unpack_ay(peer->intf_addr, value, WS_MACADDR_LEN))
645 WDP_LOGE("[" MACSTR "]", MAC2STR(peer->intf_addr));
648 WDP_LOGE("Unknown value");
650 __WDP_LOG_FUNC_EXIT__;
653 static void __ws_peer_property(const char *key, GVariant *value, void *user_data)
655 __WDP_LOG_FUNC_ENTER__;
657 __WDP_LOG_FUNC_EXIT__;
661 wfd_oem_dev_data_s *peer = (wfd_oem_dev_data_s *)user_data;
663 CHECK_KEY_VALUE(key, value);
665 if (g_strcmp0(key, "DeviceName") == 0) {
666 const char *name = NULL;
668 g_variant_get(value, "s", &name);
669 g_strlcpy(peer->name, name, WS_SSID_LEN);
670 WDP_LOGD("[%s]", peer->name);
672 } else if (g_strcmp0(key, "config_method") == 0) {
673 int config_methods = 0;
675 g_variant_get(value, "q", &config_methods);
677 if (config_methods & WS_CONFIG_METHOD_DISPLAY)
678 peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
679 if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
680 peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
681 if (config_methods & WS_CONFIG_METHOD_KEYPAD)
682 peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
683 WDP_LOGD("[0x%x]", peer->config_methods);
685 } else if (g_strcmp0(key, "level") == 0) {
687 } else if (g_strcmp0(key, "devicecapability") == 0) {
688 unsigned char devicecapability = 0;
690 g_variant_get(value, "y", &devicecapability);
691 peer->dev_flags = (int)devicecapability;
692 WDP_LOGD("[0x%02x]", peer->dev_flags);
694 } else if (g_strcmp0(key, "groupcapability") == 0) {
695 unsigned char groupcapability = 0;
697 g_variant_get(value, "y", &groupcapability);
698 WDP_LOGD("[0x%02x]", groupcapability);
699 if (groupcapability & WS_GROUP_CAP_GROUP_OWNER) {
700 peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
701 peer->dev_role = WFD_OEM_DEV_ROLE_GO;
703 if (groupcapability & WS_GROUP_CAP_PERSISTENT_GROUP)
704 peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
706 } else if (g_strcmp0(key, "PrimaryDeviceType") == 0) {
707 unsigned char primarydevicetype[WS_DEVTYPE_LEN] = {0,};
709 if (__ws_unpack_ay(primarydevicetype, value, WS_DEVTYPE_LEN)) {
710 peer->pri_dev_type = primarydevicetype[1];
711 peer->sec_dev_type = primarydevicetype[WS_DEVTYPE_LEN -1];
713 } else if (g_strcmp0(key, "SecondaryDeviceTypes") == 0) {
714 } else if (g_strcmp0(key, "VendorExtension") == 0) {
715 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
716 } else if (g_strcmp0(key, "IEs") == 0) {
717 unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
719 if(__ws_unpack_ay(ies, value, WFD_SUBELEM_LEN_DEV_INFO + 3))
720 __parsing_wfd_info(ies, &(peer->display));
721 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
722 } else if (g_strcmp0(key, "DeviceAddress") == 0) {
724 if (__ws_unpack_ay(peer->p2p_dev_addr, value, WS_MACADDR_LEN))
725 WDP_LOGE("[" MACSTR "]", MAC2STR(peer->p2p_dev_addr));
727 } else if (g_strcmp0(key, "InterfacedAddress") == 0) {
729 if (__ws_unpack_ay(peer->p2p_intf_addr, value, WS_MACADDR_LEN))
730 WDP_LOGE("[" MACSTR "]", MAC2STR(peer->p2p_intf_addr));
733 WDP_LOGE("Unknown value");
735 __WDP_LOG_FUNC_EXIT__;
738 void __ws_interface_property(const char *key, GVariant *value, void *user_data)
740 __WDP_LOG_FUNC_ENTER__;
741 wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
745 CHECK_KEY_VALUE(key, value);
747 if (g_strcmp0(key, "Ifname") == 0) {
748 const char *ifname = NULL;
750 g_variant_get(value, "s", &ifname);
751 g_strlcpy(event->ifname, ifname, OEM_IFACE_NAME_LEN+1);
752 WDP_LOGE("Ifname [%s]", event->ifname);
756 __WDP_LOG_FUNC_EXIT__;
759 void __ws_group_property(const char *key, GVariant *value, void *user_data)
761 __WDP_LOG_FUNC_ENTER__;
762 wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
763 if(!event || !event->edata)
766 wfd_oem_group_data_s *group = (wfd_oem_group_data_s *)event->edata;
768 CHECK_KEY_VALUE(key, value);
770 if (g_strcmp0(key, "Role") == 0) {
771 const char *role = NULL;
773 g_variant_get(value, "s", &role);
774 WDP_LOGD("role [%s]", role);
776 if (!strncmp(role, "GO", 2))
777 event->dev_role = WFD_OEM_DEV_ROLE_GO;
778 else if (!strncmp(role, "client", 6))
779 event->dev_role = WFD_OEM_DEV_ROLE_GC;
781 } else if (g_strcmp0(key, "Frequency") == 0) {
784 g_variant_get(value, "q", &frequency);
785 group->freq = (int)frequency;
787 } else if (g_strcmp0(key, "Passphrase") == 0) {
788 const char *passphrase = NULL;
790 g_variant_get(value, "s", &passphrase);
791 g_strlcpy(group->pass, passphrase, OEM_PASS_PHRASE_LEN+1);
792 WDP_LOGD("passphrase [%s]", group->pass);
794 } else if (g_strcmp0(key, "Group") == 0) {
796 } else if (g_strcmp0(key, "SSID") == 0) {
797 unsigned char ssid[WS_SSID_LEN +1] = {0,};
799 __ws_unpack_ay(ssid, value, WS_SSID_LEN);
800 memcpy(group->ssid, ssid, WS_SSID_LEN+1);
801 WDP_LOGD("ssid [%s]", group->ssid);
803 } else if (g_strcmp0(key, "BSSID") == 0) {
805 if (__ws_unpack_ay(group->go_dev_addr, value, WS_MACADDR_LEN))
806 WDP_LOGE("[" MACSTR "]", MAC2STR(group->go_dev_addr));
809 WDP_LOGE("Unknown value");
811 __WDP_LOG_FUNC_EXIT__;
814 void __ws_extract_group_details(const char *key, GVariant *value, void *user_data)
817 __WDP_LOG_FUNC_ENTER__;
818 wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
819 if(!event || !event->edata)
822 CHECK_KEY_VALUE(key, value);
824 if (g_strcmp0(key, "interface_object") == 0) {
825 static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
826 const char *i_path = NULL;
828 g_variant_get(value, "o", &i_path);
829 g_strlcpy(interface_path, i_path, DBUS_OBJECT_PATH_MAX);
830 WDP_LOGD("Retrive Added path [%s]", interface_path);
831 g_strlcpy(g_pd->group_iface_path, interface_path, DBUS_OBJECT_PATH_MAX);
832 dbus_property_get_all(interface_path, g_pd->g_dbus,
833 SUPPLICANT_IFACE, __ws_interface_property, event);
835 } else if (g_strcmp0(key, "role") == 0) {
836 const char *role = NULL;
838 g_variant_get(value, "s", &role);
839 WDP_LOGD("role [%s]", role);
841 if (!strncmp(role, "GO", 2))
842 event->dev_role = WFD_OEM_DEV_ROLE_GO;
843 else if (!strncmp(role, "client", 6))
844 event->dev_role = WFD_OEM_DEV_ROLE_GC;
846 } else if (g_strcmp0(key, "group_object") == 0) {
847 static char group_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
850 g_variant_get(value, "o", &g_path);
851 g_strlcpy(group_path, g_path, DBUS_OBJECT_PATH_MAX);
852 WDP_LOGD("Retrive group path [%s]", group_path);
853 dbus_property_get_all(group_path, g_pd->g_dbus, SUPPLICANT_P2P_GROUP,
854 __ws_group_property, event);
857 g_dbus_connection_signal_subscribe(
859 SUPPLICANT_SERVICE, /* bus name */
860 SUPPLICANT_P2P_GROUP, /* interface */
862 group_path, /* object path */
864 G_DBUS_SIGNAL_FLAGS_NONE,
868 __WDP_LOG_FUNC_EXIT__;
871 void __ws_extract_gonegfailaure_details(const char *key, GVariant *value, void *user_data)
873 __WDP_LOG_FUNC_ENTER__;
874 wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
875 if(!event || !event->edata)
878 wfd_oem_conn_data_s *conn = (wfd_oem_conn_data_s *)event->edata;
880 CHECK_KEY_VALUE(key, value);
882 if (g_strcmp0(key, "peer_object") == 0) {
883 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
886 g_variant_get(value, "o", &path);
887 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
888 WDP_LOGD("Retrive peer path [%s]", peer_path);
890 } else if (g_strcmp0(key, "status") == 0) {
893 g_variant_get(value, "i", &status);
894 WDP_LOGD("Retrive status [%d]", status);
895 conn->status = status;
897 __WDP_LOG_FUNC_EXIT__;
900 void __ws_extract_gonegsuccess_details(const char *key, GVariant *value, void *user_data)
902 __WDP_LOG_FUNC_ENTER__;
903 wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
904 wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s *)event->edata;
908 CHECK_KEY_VALUE(key, value);
910 if (g_strcmp0(key, "peer_object") == 0) {
912 } else if (g_strcmp0(key, "status") == 0) {
914 } else if (g_strcmp0(key, "passphrase") == 0) {
916 } else if (g_strcmp0(key, "role_go") == 0) {
918 const char *role = NULL;
920 g_variant_get(value, "s", &role);
921 if (!strncmp(role, "GO", 2))
922 event->dev_role = WFD_OEM_DEV_ROLE_GO;
923 else if (!strncmp(role, "client", 6))
924 event->dev_role = WFD_OEM_DEV_ROLE_GC;
926 } else if (g_strcmp0(key, "ssid") == 0) {
927 unsigned char ssid[WS_SSID_LEN +1] = {0,};
929 __ws_unpack_ay(ssid, value, WS_SSID_LEN);
930 memcpy(edata->ssid, ssid, WS_SSID_LEN+1);
931 WDP_LOGD("ssid [%s]", edata->ssid);
933 } else if (g_strcmp0(key, "peer_device_addr") == 0) {
935 if(__ws_unpack_ay(edata->peer_device_addr, value, WS_MACADDR_LEN))
936 WDP_LOGD("[" MACSTR "]", MAC2STR(edata->peer_device_addr));
938 } else if(g_strcmp0(key, "peer_interface_addr") == 0) {
940 if(__ws_unpack_ay(edata->peer_intf_addr, value, WS_MACADDR_LEN))
941 WDP_LOGD("[" MACSTR "]", MAC2STR(edata->peer_intf_addr));
943 } else if (g_strcmp0(key, "wps_method") == 0) {
945 } else if (g_strcmp0(key, "frequency_list") == 0) {
947 } else if (g_strcmp0(key, "persistent_group") == 0) {
949 g_variant_get(value, "i", &(edata->persistent_group));
950 WDP_LOGD("persistent_group [%d]", edata->persistent_group);
952 } else if (g_strcmp0(key, "peer_config_timeout") == 0) {
955 __WDP_LOG_FUNC_EXIT__;
958 void __ws_extract_peer_service(wfd_oem_event_s *data, unsigned char *service_hex, int tlvs_len)
960 GList *services = NULL;
961 wfd_oem_new_service_s *new_service = NULL;
962 char *segment = NULL;
968 while(ptr + 2 < WS_MAX_SERVICE_LEN &&
969 (length = (service_hex[ptr+1]*256) + service_hex[ptr]) > 0) {
970 segment = (char*) g_try_malloc0(length*2+1);
972 __ws_byte_to_hex(segment, length * 2 + 1, &service_hex[ptr + 3], length);
973 res = __ws_segment_to_service(segment, &new_service);
975 WDP_LOGE("Failed to convert segment as service instance");
980 services = g_list_append(services, new_service);
986 data->edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
987 data->dev_role = count;
988 data->edata = (void*) services;
992 void __ws_extract_servicediscoveryresponse_details(const char *key, GVariant *value, void *user_data)
994 __WDP_LOG_FUNC_ENTER__;
995 wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
1000 CHECK_KEY_VALUE(key, value);
1002 if (g_strcmp0(key, "peer_object") == 0) {
1003 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1004 __ws_path_to_addr(peer_path, event->dev_addr, value);
1006 } else if (g_strcmp0(key, "update_indicator")) {
1008 } else if (g_strcmp0(key, "tlvs")) {
1009 GVariantIter *iter = NULL;
1010 unsigned char service_hex[WS_MAX_SERVICE_LEN];
1011 int byte_length = 0;
1013 g_variant_get(value, "ay", &iter);
1015 WDP_LOGE("failed to get iterator");
1019 memset(service_hex, 0x0, WS_MAX_SERVICE_LEN);
1020 while (g_variant_iter_loop (iter, "y", &service_hex[byte_length]))
1023 __ws_extract_peer_service(event, service_hex, byte_length);
1026 __WDP_LOG_FUNC_EXIT__;
1029 static void _ws_process_device_found(GDBusConnection *connection,
1030 const gchar *object_path, GVariant *parameters)
1032 __WDP_LOG_FUNC_ENTER__;
1033 wfd_oem_event_s event;
1034 wfd_oem_dev_data_s *edata = NULL;
1035 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1037 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1039 WDP_LOGF("Failed to allocate memory for event. [%s]",
1041 __WDP_LOG_FUNC_EXIT__;
1044 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1046 event.edata = (void*) edata;
1047 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1048 event.event_id = WFD_OEM_EVENT_PEER_FOUND;
1050 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1052 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1053 __ws_peer_property, event.edata);
1055 g_pd->callback(g_pd->user_data, &event);
1056 g_free(event.edata);
1058 __WDP_LOG_FUNC_EXIT__;
1061 static void _ws_process_device_lost(GDBusConnection *connection,
1062 const gchar *object_path, GVariant *parameters)
1064 __WDP_LOG_FUNC_ENTER__;
1065 wfd_oem_event_s event;
1066 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1068 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1070 event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
1071 event.event_id = WFD_OEM_EVENT_PEER_DISAPPEARED;
1073 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1075 g_pd->callback(g_pd->user_data, &event);
1077 __WDP_LOG_FUNC_EXIT__;
1080 static void _ws_process_find_stoppped(GDBusConnection *connection,
1081 const gchar *object_path, GVariant *parameters)
1083 __WDP_LOG_FUNC_ENTER__;
1084 wfd_oem_event_s event;
1086 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1088 event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
1089 event.event_id = WFD_OEM_EVENT_DISCOVERY_FINISHED;
1091 g_pd->callback(g_pd->user_data, &event);
1093 __WDP_LOG_FUNC_EXIT__;
1096 static void _ws_process_prov_disc_req_display_pin(GDBusConnection *connection,
1097 const gchar *object_path, GVariant *parameters)
1099 __WDP_LOG_FUNC_ENTER__;
1101 wfd_oem_event_s event;
1102 wfd_oem_dev_data_s *edata = NULL;
1104 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1105 static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
1106 const char *path = NULL;
1107 const char *pin = NULL;
1110 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1112 WDP_LOGF("Failed to allocate memory for event. [%s]",
1114 __WDP_LOG_FUNC_EXIT__;
1117 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1119 event.edata = (void*) edata;
1120 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1121 event.event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
1122 event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1124 g_variant_get(parameters, "(os)", &path, &pin);
1125 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
1126 WDP_LOGD("Retrive Added path [%s]", peer_path);
1128 loc = strrchr(peer_path,'/');
1129 __ws_mac_compact_to_normal(loc + 1, peer_dev);
1130 __ws_txt_to_mac(peer_dev, event.dev_addr);
1131 WDP_LOGD("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
1133 g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
1134 WDP_LOGD("Retrive pin [%s]", event.wps_pin);
1136 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1137 __ws_peer_property, event.edata);
1139 g_pd->callback(g_pd->user_data, &event);
1140 g_free(event.edata);
1142 __WDP_LOG_FUNC_EXIT__;
1145 static void _ws_process_prov_disc_resp_display_pin(GDBusConnection *connection,
1146 const gchar *object_path, GVariant *parameters)
1148 __WDP_LOG_FUNC_ENTER__;
1150 wfd_oem_event_s event;
1151 wfd_oem_dev_data_s *edata = NULL;
1153 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1154 static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
1155 const char *path = NULL;
1156 const char *pin = NULL;
1159 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1161 WDP_LOGF("Failed to allocate memory for event. [%s]",
1163 __WDP_LOG_FUNC_EXIT__;
1166 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1168 event.edata = (void*) edata;
1169 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1170 event.event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
1171 event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1173 g_variant_get(parameters, "(os)", &path, &pin);
1174 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
1175 WDP_LOGD("Retrive Added path [%s]", peer_path);
1177 loc = strrchr(peer_path,'/');
1178 __ws_mac_compact_to_normal(loc + 1, peer_dev);
1179 __ws_txt_to_mac(peer_dev, event.dev_addr);
1180 WDP_LOGD("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
1182 g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
1183 WDP_LOGE("Retrive pin [%s]", event.wps_pin);
1185 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1186 __ws_peer_property, event.edata);
1188 g_pd->callback(g_pd->user_data, &event);
1189 g_free(event.edata);
1191 __WDP_LOG_FUNC_EXIT__;
1194 static void _ws_process_prov_disc_req_enter_pin(GDBusConnection *connection,
1195 const gchar *object_path, GVariant *parameters)
1197 __WDP_LOG_FUNC_ENTER__;
1198 wfd_oem_event_s event;
1199 wfd_oem_dev_data_s *edata = NULL;
1200 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1202 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1204 WDP_LOGF("Failed to allocate memory for event. [%s]",
1206 __WDP_LOG_FUNC_EXIT__;
1209 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1211 event.edata = (void*) edata;
1212 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1213 event.event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
1214 event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1216 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1218 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1219 __ws_peer_property, event.edata);
1221 g_pd->callback(g_pd->user_data, &event);
1222 g_free(event.edata);
1224 __WDP_LOG_FUNC_EXIT__;
1227 static void _ws_process_prov_disc_resp_enter_pin(GDBusConnection *connection,
1228 const gchar *object_path, GVariant *parameters)
1230 __WDP_LOG_FUNC_ENTER__;
1231 wfd_oem_event_s event;
1232 wfd_oem_dev_data_s *edata = NULL;
1233 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1235 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1237 WDP_LOGF("Failed to allocate memory for event. [%s]",
1239 __WDP_LOG_FUNC_EXIT__;
1242 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1244 event.edata = (void*) edata;
1245 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1246 event.event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
1247 event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1249 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1251 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1252 __ws_peer_property, event.edata);
1254 g_pd->callback(g_pd->user_data, &event);
1255 g_free(event.edata);
1257 __WDP_LOG_FUNC_EXIT__;
1260 static void _ws_process_prov_disc_pbc_req(GDBusConnection *connection,
1261 const gchar *object_path, GVariant *parameters)
1263 __WDP_LOG_FUNC_ENTER__;
1264 wfd_oem_event_s event;
1265 wfd_oem_dev_data_s *edata = NULL;
1266 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1268 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1270 WDP_LOGF("Failed to allocate memory for event. [%s]",
1272 __WDP_LOG_FUNC_EXIT__;
1275 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1277 event.edata = (void*) edata;
1278 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1279 event.event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
1280 event.wps_mode = WFD_OEM_WPS_MODE_PBC;
1282 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1284 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1285 __ws_peer_property, event.edata);
1287 g_pd->callback(g_pd->user_data, &event);
1288 g_free(event.edata);
1290 __WDP_LOG_FUNC_EXIT__;
1293 static void _ws_process_prov_disc_pbc_resp(GDBusConnection *connection,
1294 const gchar *object_path, GVariant *parameters)
1296 __WDP_LOG_FUNC_ENTER__;
1297 wfd_oem_event_s event;
1298 wfd_oem_dev_data_s *edata = NULL;
1299 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1301 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1303 WDP_LOGF("Failed to allocate memory for event. [%s]",
1305 __WDP_LOG_FUNC_EXIT__;
1308 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1310 event.edata = (void*) edata;
1311 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1312 event.event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
1313 event.wps_mode = WFD_OEM_WPS_MODE_PBC;
1315 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1317 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1318 __ws_peer_property, event.edata);
1320 g_pd->callback(g_pd->user_data, &event);
1321 g_free(event.edata);
1323 __WDP_LOG_FUNC_EXIT__;
1326 static void _ws_process_prov_disc_failure(GDBusConnection *connection,
1327 const gchar *object_path, GVariant *parameters)
1329 __WDP_LOG_FUNC_ENTER__;
1330 wfd_oem_event_s event;
1331 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1332 static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
1333 const char *path = NULL;
1334 int prov_status = 0;
1337 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1339 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1340 event.event_id = WFD_OEM_EVENT_PROV_DISC_FAIL;
1342 g_variant_get(parameters, "(oi)", &path, &prov_status);
1343 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
1344 WDP_LOGD("Retrive Added path [%s]", peer_path);
1345 WDP_LOGD("Retrive Failure stateus [%d]", prov_status);
1347 loc = strrchr(peer_path,'/');
1348 __ws_mac_compact_to_normal(loc + 1, peer_dev);
1349 __ws_txt_to_mac(peer_dev, event.dev_addr);
1350 WDP_LOGE("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
1352 g_pd->callback(g_pd->user_data, &event);
1354 __WDP_LOG_FUNC_EXIT__;
1357 static void _ws_process_group_started(GDBusConnection *connection,
1358 const gchar *object_path, GVariant *parameters)
1360 __WDP_LOG_FUNC_ENTER__;
1361 GVariantIter *iter = NULL;
1362 wfd_oem_event_s event;
1363 wfd_oem_group_data_s *edata = NULL;
1365 edata = (wfd_oem_group_data_s*)calloc(1, sizeof(wfd_oem_group_data_s));
1367 WDP_LOGF("Failed to allocate memory for event. [%s]",
1369 __WDP_LOG_FUNC_EXIT__;
1372 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1374 event.edata = (void*) edata;
1375 event.edata_type = WFD_OEM_EDATA_TYPE_GROUP;
1376 event.event_id = WFD_OEM_EVENT_GROUP_CREATED;
1378 if(parameters != NULL){
1379 g_variant_get(parameters, "(a{sv})", &iter);
1382 dbus_property_foreach(iter, __ws_extract_group_details, &event);
1383 g_variant_iter_free(iter);
1386 WDP_LOGE("No properties");
1389 g_pd->callback(g_pd->user_data, &event);
1390 g_free(event.edata);
1392 __WDP_LOG_FUNC_EXIT__;
1395 static void _ws_process_go_neg_success(GDBusConnection *connection,
1396 const gchar *object_path, GVariant *parameters)
1398 __WDP_LOG_FUNC_ENTER__;
1399 GVariantIter *iter = NULL;
1400 wfd_oem_event_s event;
1401 wfd_oem_conn_data_s *edata = NULL;
1403 edata = (wfd_oem_conn_data_s*)calloc(1, sizeof(wfd_oem_conn_data_s));
1405 WDP_LOGF("Failed to allocate memory for event. [%s]",
1407 __WDP_LOG_FUNC_EXIT__;
1410 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1412 event.edata = edata;
1413 event.edata_type = WFD_OEM_EDATA_TYPE_CONN;
1414 event.event_id = WFD_OEM_EVENT_GO_NEG_DONE;
1416 if (parameters != NULL){
1417 g_variant_get(parameters, "(a{sv})", &iter);
1420 dbus_property_foreach(iter, __ws_extract_gonegsuccess_details, &event);
1421 g_variant_iter_free(iter);
1424 WDP_LOGE("No properties");
1427 g_pd->callback(g_pd->user_data, &event);
1430 __WDP_LOG_FUNC_EXIT__;
1433 static void _ws_process_go_neg_failure(GDBusConnection *connection,
1434 const gchar *object_path, GVariant *parameters)
1436 __WDP_LOG_FUNC_ENTER__;
1437 GVariantIter *iter = NULL;
1438 wfd_oem_event_s event;
1439 wfd_oem_conn_data_s *edata = NULL;
1441 edata = (wfd_oem_conn_data_s *) g_try_malloc0(sizeof(wfd_oem_conn_data_s));
1443 WDP_LOGF("Failed to allocate memory for event. [%s]",
1445 __WDP_LOG_FUNC_EXIT__;
1448 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1450 event.edata = (void*) edata;
1451 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1452 event.event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
1454 if (parameters != NULL) {
1455 g_variant_get(parameters, "(a{sv})", &iter);
1458 dbus_property_foreach(iter, __ws_extract_gonegfailaure_details, &event);
1459 g_variant_iter_free(iter);
1462 WDP_LOGE("No properties");
1465 g_pd->callback(g_pd->user_data, &event);
1466 g_free(event.edata);
1468 __WDP_LOG_FUNC_EXIT__;
1471 static void _ws_process_go_neg_request(GDBusConnection *connection,
1472 const gchar *object_path, GVariant *parameters)
1474 __WDP_LOG_FUNC_ENTER__;
1475 wfd_oem_event_s event;
1476 wfd_oem_dev_data_s *edata = NULL;
1477 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1478 static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
1479 const char *path = NULL;
1484 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1486 WDP_LOGF("Failed to allocate memory for event. [%s]",
1488 __WDP_LOG_FUNC_EXIT__;
1492 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1494 event.edata = (void*) edata;
1495 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1496 event.event_id = WFD_OEM_EVENT_GO_NEG_REQ;
1498 g_variant_get(parameters, "(oq)", &path, &dev_pwd_id);
1499 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
1500 WDP_LOGD("Retrive peer path [%s]", peer_path);
1502 WDP_LOGD("Retrive dev_passwd_id [%d]", dev_pwd_id);
1504 if (dev_pwd_id == WS_DEV_PASSWD_ID_PUSH_BUTTON)
1505 event.wps_mode = WFD_OEM_WPS_MODE_PBC;
1506 else if (dev_pwd_id == WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED)
1507 event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1508 else if (dev_pwd_id == WS_DEV_PASSWD_ID_USER_SPECIFIED)
1509 event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1511 event.wps_mode = WFD_OEM_WPS_MODE_NONE;
1513 g_variant_get(parameters, "(o)", &path);
1514 g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
1515 WDP_LOGD("Retrive Added path [%s]", peer_path);
1517 loc = strrchr(peer_path,'/');
1518 __ws_mac_compact_to_normal(loc + 1, peer_dev);
1519 __ws_txt_to_mac(peer_dev, event.dev_addr);
1520 WDP_LOGD("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
1522 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1523 __ws_peer_property, event.edata);
1525 g_pd->callback(g_pd->user_data, &event);
1526 g_free(event.edata);
1528 __WDP_LOG_FUNC_EXIT__;
1531 static void _ws_process_invitation_result(GDBusConnection *connection,
1532 const gchar *object_path, GVariant *parameters)
1534 __WDP_LOG_FUNC_ENTER__;
1535 wfd_oem_event_s event;
1536 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1538 // g_pd->callback(g_pd->user_data, event);
1540 __WDP_LOG_FUNC_EXIT__;
1543 static void _ws_process_group_finished(GDBusConnection *connection,
1544 const gchar *object_path, GVariant *parameters)
1546 __WDP_LOG_FUNC_ENTER__;
1547 wfd_oem_event_s event;
1549 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1551 event.event_id = WFD_OEM_EVENT_GROUP_DESTROYED;
1552 event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
1554 g_dbus_connection_signal_unsubscribe(g_pd->g_dbus, g_pd->group_sub_id);
1555 memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
1557 g_pd->callback(g_pd->user_data, &event);
1559 __WDP_LOG_FUNC_EXIT__;
1562 static void _ws_process_service_discovery_response(GDBusConnection *connection,
1563 const gchar *object_path, GVariant *parameters)
1565 __WDP_LOG_FUNC_ENTER__;
1566 GVariantIter *iter = NULL;
1567 wfd_oem_event_s event;
1569 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1571 event.event_id = WFD_OEM_EVENT_SERV_DISC_RESP;
1573 if(parameters != NULL) {
1574 g_variant_get(parameters, "(a{sv}", &iter);
1576 dbus_property_foreach(iter, __ws_extract_servicediscoveryresponse_details, &event);
1577 event.edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
1578 g_variant_iter_free(iter);
1581 WDP_LOGE("No Properties");
1584 g_pd->callback(g_pd->user_data, &event);
1586 if (event.edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE)
1587 g_list_free((GList*) event.edata);
1589 __WDP_LOG_FUNC_EXIT__;
1592 static void _ws_process_persistent_group_added(GDBusConnection *connection,
1593 const gchar *object_path, GVariant *parameters)
1595 __WDP_LOG_FUNC_ENTER__;
1596 wfd_oem_event_s event;
1597 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1599 // g_pd->callback(g_pd->user_data, &event);
1601 __WDP_LOG_FUNC_EXIT__;
1604 static void _ws_process_persistent_group_removed(GDBusConnection *connection,
1605 const gchar *object_path, GVariant *parameters)
1607 __WDP_LOG_FUNC_ENTER__;
1608 wfd_oem_event_s event;
1609 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1611 // g_pd->callback(g_pd->user_data, &event);
1613 __WDP_LOG_FUNC_EXIT__;
1616 static void _ws_process_wps_failed(GDBusConnection *connection,
1617 const gchar *object_path, GVariant *parameters)
1619 __WDP_LOG_FUNC_ENTER__;
1620 GVariantIter *iter = NULL;
1621 wfd_oem_event_s event;
1622 const char *name = NULL;
1624 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1626 event.event_id = WFD_OEM_EVENT_WPS_FAIL;
1628 g_variant_get(parameters, "(sa{sv})", &name, &iter);
1630 WDP_LOGD("code [%s]", name);
1635 GVariant *value = NULL;
1637 while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
1638 CHECK_KEY_VALUE(key, value);
1640 g_variant_iter_free(iter);
1643 g_pd->callback(g_pd->user_data, &event);
1645 __WDP_LOG_FUNC_EXIT__;
1649 const char *interface;
1651 void (*function) (GDBusConnection *connection,const gchar *object_path,
1652 GVariant *parameters);
1653 } ws_p2pdevice_signal_map[] = {
1655 SUPPLICNAT_P2PDEVICE,
1657 _ws_process_device_found
1660 SUPPLICNAT_P2PDEVICE,
1662 _ws_process_device_lost
1665 SUPPLICNAT_P2PDEVICE,
1667 _ws_process_find_stoppped
1670 SUPPLICNAT_P2PDEVICE,
1671 "ProvisionDiscoveryRequestDisplayPin",
1672 _ws_process_prov_disc_req_display_pin
1675 SUPPLICNAT_P2PDEVICE,
1676 "ProvisionDiscoveryResponseDisplayPin",
1677 _ws_process_prov_disc_resp_display_pin
1680 SUPPLICNAT_P2PDEVICE,
1681 "ProvisionDiscoveryRequestEnterPin",
1682 _ws_process_prov_disc_req_enter_pin
1685 SUPPLICNAT_P2PDEVICE,
1686 "ProvisionDiscoveryResponseEnterPin",
1687 _ws_process_prov_disc_resp_enter_pin
1690 SUPPLICNAT_P2PDEVICE,
1691 "ProvisionDiscoveryPBCRequest",
1692 _ws_process_prov_disc_pbc_req
1695 SUPPLICNAT_P2PDEVICE,
1696 "ProvisionDiscoveryPBCResponse",
1697 _ws_process_prov_disc_pbc_resp
1700 SUPPLICNAT_P2PDEVICE,
1701 "ProvisionDiscoveryFailure",
1702 _ws_process_prov_disc_failure
1705 SUPPLICNAT_P2PDEVICE,
1707 _ws_process_group_started
1710 SUPPLICNAT_P2PDEVICE,
1711 "GONegotiationSuccess",
1712 _ws_process_go_neg_success
1715 SUPPLICNAT_P2PDEVICE,
1716 "GONegotiationFailure",
1717 _ws_process_go_neg_failure
1720 SUPPLICNAT_P2PDEVICE,
1721 "GONegotiationRequest",
1722 _ws_process_go_neg_request
1725 SUPPLICNAT_P2PDEVICE,
1727 _ws_process_invitation_result
1730 SUPPLICNAT_P2PDEVICE,
1732 _ws_process_group_finished
1735 SUPPLICNAT_P2PDEVICE,
1736 "ServiceDiscoveryResponse",
1737 _ws_process_service_discovery_response
1740 SUPPLICNAT_P2PDEVICE,
1741 "PersistentGroupAdded",
1742 _ws_process_persistent_group_added
1745 SUPPLICNAT_P2PDEVICE,
1746 "PersistentGroupRemoved",
1747 _ws_process_persistent_group_removed
1750 SUPPLICNAT_P2PDEVICE,
1752 _ws_process_wps_failed
1761 static void _p2pdevice_signal_cb(GDBusConnection *connection,
1762 const gchar *sender, const gchar *object_path, const gchar *interface,
1763 const gchar *signal, GVariant *parameters, gpointer user_data)
1766 DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
1768 for (i = 0; ws_p2pdevice_signal_map[i].member != NULL; i++) {
1769 if (!g_strcmp0(signal, ws_p2pdevice_signal_map[i].member) &&
1770 ws_p2pdevice_signal_map[i].function != NULL)
1771 ws_p2pdevice_signal_map[i].function(connection, object_path, parameters);
1776 static void _group_signal_cb(GDBusConnection *connection,
1777 const gchar *sender, const gchar *object_path, const gchar *interface,
1778 const gchar *signal, GVariant *parameters, gpointer user_data)
1780 DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
1782 if(!g_strcmp0(signal,"PeerJoined")){
1784 wfd_oem_event_s event;
1785 wfd_oem_dev_data_s *edata = NULL;
1787 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1789 edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1791 WDP_LOGF("Failed to allocate memory for event. [%s]",
1793 __WDP_LOG_FUNC_EXIT__;
1796 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1798 event.edata = (void*) edata;
1799 event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1800 event.event_id = WFD_OEM_EVENT_STA_CONNECTED;
1802 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1804 dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
1805 __ws_peer_property, event.edata);
1807 g_pd->callback(g_pd->user_data, &event);
1810 } else if (!g_strcmp0(signal,"PeerDisconnected")) {
1812 wfd_oem_event_s event;
1814 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1816 memset(&event, 0x0, sizeof(wfd_oem_event_s));
1818 event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
1819 event.event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
1821 __ws_path_to_addr(peer_path, event.dev_addr, parameters);
1823 g_pd->callback(g_pd->user_data, &event);
1827 static void __register_p2pdevice_signal(GVariant *value, void *user_data)
1829 __WDP_LOG_FUNC_ENTER__;
1830 ws_dbus_plugin_data_s * pd_data;
1831 static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1832 const char *path = NULL;
1834 pd_data = (ws_dbus_plugin_data_s *)g_pd;
1836 g_variant_get(value, "(o)", &path);
1837 g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
1838 g_strlcpy(pd_data->iface_path, path, DBUS_OBJECT_PATH_MAX);
1840 WDP_LOGD("interface object path [%s]", interface_path);
1841 /* subscribe interface p2p signal */
1842 WDP_LOGD("register P2PDevice iface signal");
1843 pd_data->p2pdevice_sub_id = g_dbus_connection_signal_subscribe(
1845 SUPPLICANT_SERVICE, /* bus name */
1846 SUPPLICNAT_P2PDEVICE, /* interface */
1848 NULL, /* object path */
1850 G_DBUS_SIGNAL_FLAGS_NONE,
1851 _p2pdevice_signal_cb,
1853 __WDP_LOG_FUNC_EXIT__;
1856 static int _ws_create_interface(const char *iface_name)
1858 __WDP_LOG_FUNC_ENTER__;
1859 GDBusConnection *g_dbus = NULL;
1860 GVariantBuilder *builder = NULL;
1861 dbus_method_param_s params;
1865 g_dbus = g_pd->g_dbus;
1867 WDP_LOGE("DBus connection is NULL");
1870 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
1872 dbus_set_method_param(¶ms, "CreateInterface", SUPPLICANT_PATH, g_dbus);
1874 builder = g_variant_builder_new(G_VARIANT_TYPE ("a{sv}"));
1875 g_variant_builder_add(builder, "{sv}", "Ifname", g_variant_new_string(iface_name));
1876 g_variant_builder_add(builder, "{sv}", "Driver", g_variant_new_string("nl80211"));
1877 g_variant_builder_add(builder, "{sv}", "ConfigFile", g_variant_new_string(CONF_FILE_PATH));
1878 params.params = g_variant_new("(a{sv})", builder);
1879 g_variant_builder_unref(builder);
1881 res = dbus_method_call(¶ms, SUPPLICANT_INTERFACE, __register_p2pdevice_signal, NULL);
1883 WDP_LOGE("Failed to send command to wpa_supplicant");
1885 WDP_LOGD("Succeeded to CreateInterface");
1887 __WDP_LOG_FUNC_EXIT__;
1891 static int _ws_get_interface(const char *iface_name)
1893 __WDP_LOG_FUNC_ENTER__;
1894 GDBusConnection *g_dbus = NULL;
1895 dbus_method_param_s params;
1898 g_dbus = g_pd->g_dbus;
1900 WDP_LOGE("DBus connection is NULL");
1904 dbus_set_method_param(¶ms, SUPPLICANT_METHOD_GETINTERFACE,
1905 SUPPLICANT_PATH, g_pd->g_dbus);
1907 params.params = g_variant_new("(s)", iface_name);
1908 WDP_LOGE("param [%s]", g_variant_print(params.params,TRUE));
1910 res = dbus_method_call(¶ms, SUPPLICANT_INTERFACE,
1911 __register_p2pdevice_signal, g_pd);
1914 WDP_LOGE("Failed to send command to wpa_supplicant");
1916 WDP_LOGD("Succeeded to get interface");
1918 __WDP_LOG_FUNC_EXIT__;
1923 static int _ws_remove_interface(const char *iface_name)
1925 __WDP_LOG_FUNC_ENTER__;
1926 GDBusConnection *g_dbus = NULL;
1927 dbus_method_param_s params;
1928 static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
1931 g_dbus = g_pd->g_dbus;
1933 WDP_LOGE("DBus connection is NULL");
1937 res = _ws_get_interface(iface_name, interface_path);
1939 WDP_LOGE("Failed to get interface object");
1942 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
1944 dbus_set_method_param(¶ms, "RemoveInterface", SUPPLICANT_PATH, g_dbus);
1945 params.params = g_variant_new("(o)", interface_path);
1947 res = dbus_method_call(¶ms, SUPPLICANT_INTERFACE, NULL, NULL);
1949 WDP_LOGE("Failed to send command to wpa_supplicant");
1951 WDP_LOGD("Succeeded to RemoveInterface");
1953 __WDP_LOG_FUNC_EXIT__;
1958 static int _ws_init_dbus_connection(void)
1960 __WDP_LOG_FUNC_ENTER__;
1961 GDBusConnection *conn = NULL;
1962 GError *error = NULL;
1965 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1969 WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
1971 g_error_free(error);
1973 __WDP_LOG_FUNC_EXIT__;
1977 g_pd->g_dbus = conn;
1979 WDP_LOGD("register supplicant signal");
1980 /* subscribe supplicant signal */
1981 g_pd->supp_sub_id = g_dbus_connection_signal_subscribe(
1983 SUPPLICANT_SERVICE, /* bus name */
1984 SUPPLICANT_INTERFACE, /* interface */
1986 SUPPLICANT_PATH, /* object path */
1988 G_DBUS_SIGNAL_FLAGS_NONE,
1989 _supplicant_signal_cb,
1992 if(_ws_get_interface(COMMON_IFACE_NAME) < 0)
1993 res = _ws_create_interface(COMMON_IFACE_NAME);
1996 WDP_LOGE("Failed to subscribe interface signal");
1998 WDP_LOGI("Successfully register signal filters");
2000 __WDP_LOG_FUNC_EXIT__;
2003 static int _ws_deinit_dbus_connection(void)
2005 GDBusConnection *g_dbus = NULL;
2007 g_dbus = g_pd->g_dbus;
2009 WDP_LOGE("DBus connection is NULL");
2013 g_dbus_connection_signal_unsubscribe(g_dbus, g_pd->supp_sub_id);
2014 g_dbus_connection_signal_unsubscribe(g_dbus, g_pd->p2pdevice_sub_id);
2015 g_dbus_connection_signal_unsubscribe(g_dbus, g_pd->group_sub_id);
2018 g_object_unref(g_dbus);
2022 int wfd_plugin_load(wfd_oem_ops_s **ops)
2025 WDP_LOGE("Invalid parameter");
2029 *ops = &supplicant_ops;
2034 static int _ws_reset_plugin(ws_dbus_plugin_data_s *g_pd)
2036 __WDP_LOG_FUNC_ENTER__;
2039 WDP_LOGE("Invalid parameter");
2040 __WDP_LOG_FUNC_EXIT__;
2044 _ws_deinit_dbus_connection();
2046 if (g_pd->activated)
2047 ws_deactivate(g_pd->concurrent);
2051 __WDP_LOG_FUNC_EXIT__;
2056 static int __ws_check_net_interface(char* if_name)
2061 if (if_name == NULL) {
2062 WDP_LOGE("Invalid param");
2066 fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2068 WDP_LOGE("socket create error: %d", fd);
2072 memset(&ifr, 0, sizeof(ifr));
2073 strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
2074 ifr.ifr_name[IFNAMSIZ-1] = '\0';
2076 if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
2078 WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s", strerror(errno)); /* interface is not found. */
2084 if (ifr.ifr_flags & IFF_UP) {
2085 WDP_LOGD("%s interface is up", if_name);
2087 } else if (!(ifr.ifr_flags & IFF_UP)) {
2088 WDP_LOGD("%s interface is down", if_name);
2094 int ws_init(wfd_oem_event_cb callback, void *user_data)
2096 __WDP_LOG_FUNC_ENTER__;
2099 _ws_reset_plugin(g_pd);
2102 g_pd = (ws_dbus_plugin_data_s*) g_try_malloc0 (sizeof(ws_dbus_plugin_data_s));
2104 WDP_LOGE("Failed to allocate memory for plugin data. [%s]", strerror(errno));
2108 g_pd->callback = callback;
2109 g_pd->user_data = user_data;
2110 g_pd->initialized = TRUE;
2112 __WDP_LOG_FUNC_EXIT__;
2118 __WDP_LOG_FUNC_ENTER__;
2121 _ws_reset_plugin(g_pd);
2125 __WDP_LOG_FUNC_EXIT__;
2129 static int __ws_p2p_firmware_start(void)
2131 GError *error = NULL;
2132 GVariant *reply = NULL;
2133 GVariant *param = NULL;
2134 GDBusConnection *connection = NULL;
2135 const char *device = "p2p";
2137 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
2138 if (connection == NULL) {
2140 WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
2142 g_error_free(error);
2144 __WDP_LOG_FUNC_EXIT__;
2147 param = g_variant_new("(s)", device);
2149 reply = g_dbus_connection_call_sync (connection,
2150 NETCONFIG_SERVICE, /* bus name */
2151 NETCONFIG_WIFI_PATH, /* object path */
2152 NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
2153 "Start", /* method name */
2154 param, /* GVariant *params */
2155 NULL, /* reply_type */
2156 G_DBUS_CALL_FLAGS_NONE, /* flags */
2157 NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
2158 NULL, /* cancellable */
2159 &error); /* error */
2162 if(strstr(error->message, ".AlreadyExists") != NULL) {
2163 WDP_LOGD("p2p already enabled");
2164 g_error_free(error);
2167 WDP_LOGE("Error! Failed to call net-config method: [%s]",
2169 g_error_free(error);
2171 g_variant_unref(reply);
2172 g_object_unref(connection);
2173 __WDP_LOG_FUNC_EXIT__;
2178 g_variant_unref(reply);
2179 g_object_unref(connection);
2183 static int __ws_p2p_firmware_stop(void)
2185 GError *error = NULL;
2186 GVariant *reply = NULL;
2187 GVariant *param = NULL;
2188 GDBusConnection *connection = NULL;
2189 const char *device = "p2p";
2191 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
2192 if (connection == NULL) {
2194 WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
2196 g_error_free(error);
2198 __WDP_LOG_FUNC_EXIT__;
2201 param = g_variant_new("(s)", device);
2203 reply = g_dbus_connection_call_sync (connection,
2204 NETCONFIG_SERVICE, /* bus name */
2205 NETCONFIG_WIFI_PATH, /* object path */
2206 NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
2207 "Stop", /* method name */
2208 param, /* GVariant *params */
2209 NULL, /* reply_type */
2210 G_DBUS_CALL_FLAGS_NONE, /* flags */
2211 NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
2212 NULL, /* cancellable */
2213 &error); /* error */
2216 if(strstr(error->message, ".AlreadyExists") != NULL) {
2217 WDP_LOGD("p2p already disabled");
2218 g_error_free(error);
2221 WDP_LOGE("Error! Failed to call net-config method: [%s]",
2223 g_error_free(error);
2225 g_variant_unref(reply);
2226 g_object_unref(connection);
2227 __WDP_LOG_FUNC_EXIT__;
2232 g_variant_unref(reply);
2233 g_object_unref(connection);
2237 static int __ws_p2p_supplicant_start(void)
2239 gboolean rv = FALSE;
2240 const char *path = "/usr/sbin/p2p_supp.sh";
2241 char *const args[] = { "/usr/sbin/p2p_supp.sh", "start_dbus", NULL };
2242 char *const envs[] = { NULL };
2244 rv = _ws_util_execute_file(path, args, envs);
2247 WDP_LOGE("Failed to start p2p_supp.sh");
2251 WDP_LOGI("Successfully started p2p_supp.sh");
2256 static int __ws_if_up(void)
2258 gboolean rv = FALSE;
2259 const char *path = "/usr/sbin/ifconfig";
2260 char *const args[] = { "/usr/sbin/ifconfig", "wlan0", "up", NULL };
2261 char *const envs[] = { NULL };
2263 rv = _ws_util_execute_file(path, args, envs);
2266 WDP_LOGE("Failed to start if down");
2270 WDP_LOGI("Successfully if up");
2274 static int __ws_if_down(void)
2276 gboolean rv = FALSE;
2277 const char *path = "/usr/sbin/ifconfig";
2278 char *const args[] = { "/usr/sbin/ifconfig", "wlan0", "down", NULL };
2279 char *const envs[] = { NULL };
2281 rv = _ws_util_execute_file(path, args, envs);
2284 WDP_LOGE("Failed to start if down");
2288 WDP_LOGI("Successfully if down");
2292 static int __ws_p2p_supplicant_stop(void)
2294 gboolean rv = FALSE;
2295 const char *path = "/usr/sbin/p2p_supp.sh";
2296 char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
2297 char *const envs[] = { NULL };
2299 rv = _ws_util_execute_file(path, args, envs);
2302 WDP_LOGE("Failed to stop p2p_supp.sh");
2306 WDP_LOGI("Successfully stopped p2p_supp.sh");
2311 static int __ws_p2p_on(void)
2314 DBusMessage *reply = NULL;
2315 DBusMessage *message = NULL;
2316 DBusConnection *connection = NULL;
2318 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
2319 if (connection == NULL) {
2320 WDP_LOGE("Failed to get system bus");
2324 message = dbus_message_new_method_call(NETCONFIG_SERVICE,
2325 NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
2326 if (message == NULL) {
2327 WDP_LOGE("Failed DBus method call");
2328 dbus_connection_unref(connection);
2332 dbus_error_init(&error);
2334 reply = dbus_connection_send_with_reply_and_block(connection, message,
2335 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
2336 if (dbus_error_is_set(&error) == TRUE) {
2337 if (NULL != strstr(error.message, ".AlreadyExists")) {
2338 // p2p already enabled
2340 WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
2341 "DBus error [%s: %s]", error.name, error.message);
2343 dbus_error_free(&error);
2346 dbus_error_free(&error);
2350 dbus_message_unref(reply);
2352 dbus_message_unref(message);
2353 dbus_connection_unref(connection);
2358 static int __ws_p2p_off(void)
2361 DBusMessage *reply = NULL;
2362 DBusMessage *message = NULL;
2363 DBusConnection *connection = NULL;
2365 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
2366 if (connection == NULL) {
2367 WDP_LOGE("Failed to get system bus");
2371 message = dbus_message_new_method_call(NETCONFIG_SERVICE,
2372 NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
2373 if (message == NULL) {
2374 WDP_LOGE("Failed DBus method call");
2375 dbus_connection_unref(connection);
2379 dbus_error_init(&error);
2381 reply = dbus_connection_send_with_reply_and_block(connection, message,
2382 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
2383 if (dbus_error_is_set(&error) == TRUE) {
2384 if (NULL != strstr(error.message, ".AlreadyExists")) {
2385 // p2p already disabled
2387 WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
2388 "DBus error [%s: %s]", error.name, error.message);
2390 dbus_error_free(&error);
2393 dbus_error_free(&error);
2397 dbus_message_unref(reply);
2399 dbus_message_unref(message);
2400 dbus_connection_unref(connection);
2406 int ws_activate(int concurrent)
2408 __WDP_LOG_FUNC_ENTER__;
2410 int retry_count = 0;
2412 while (retry_count < WS_CONN_RETRY_COUNT) {
2413 /* load wlan driver */
2416 WDP_LOGE("Failed to load driver [ret=%d]", res);
2419 WDP_LOGI("P2P firmware started with error %d", res);
2421 if (__ws_check_net_interface(COMMON_IFACE_NAME) < 0) {
2422 usleep(150000); // wait for 150ms
2424 WDP_LOGE("interface is not up: retry, %d", retry_count);
2430 if (retry_count >= WS_CONN_RETRY_COUNT) {
2431 WDP_LOGE("Driver loading is failed", res);
2432 __WDP_LOG_FUNC_EXIT__;
2435 if (retry_count > 0) {
2436 // Give driver marginal time to config net
2437 WDP_LOGE("Driver loading is done. Wait marginal time for driver");
2441 g_pd->concurrent = concurrent;
2443 res = _ws_init_dbus_connection();
2445 res = __ws_p2p_supplicant_stop();
2446 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2447 res = __ws_if_down();
2448 WDP_LOGI("P2P firmware stopped with error %d", res);
2449 __WDP_LOG_FUNC_EXIT__;
2453 g_pd->activated = TRUE;
2455 __WDP_LOG_FUNC_EXIT__;
2459 int ws_deactivate(int concurrent)
2461 __WDP_LOG_FUNC_ENTER__;
2464 if (!g_pd->activated) {
2465 WDP_LOGE("Wi-Fi Direct is not activated");
2471 g_pd->concurrent = concurrent;
2473 _ws_deinit_dbus_connection();
2475 res = __ws_p2p_supplicant_stop();
2476 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2478 res = __ws_if_down();
2479 WDP_LOGI("P2P firmware stopped with error %d", res);
2480 g_pd->activated = FALSE;
2482 __WDP_LOG_FUNC_EXIT__;
2486 static int _ws_flush()
2488 __WDP_LOG_FUNC_ENTER__;
2489 GDBusConnection *g_dbus = NULL;
2490 dbus_method_param_s params;
2493 g_dbus = g_pd->g_dbus;
2495 WDP_LOGE("DBus connection is NULL");
2498 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2500 dbus_set_method_param(¶ms, "Flush", g_pd->iface_path, g_dbus);
2501 params.params = NULL;
2503 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2505 WDP_LOGE("Failed to send command to wpa_supplicant");
2507 WDP_LOGD("Succeeded to flush");
2509 __WDP_LOG_FUNC_EXIT__;
2513 static int _ws_cancel()
2515 __WDP_LOG_FUNC_ENTER__;
2516 GDBusConnection *g_dbus = NULL;
2517 dbus_method_param_s params;
2520 g_dbus = g_pd->g_dbus;
2522 WDP_LOGE("DBus connection is NULL");
2525 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2527 dbus_set_method_param(¶ms, "Cancel", g_pd->iface_path , g_dbus);
2528 params.params = NULL;
2530 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2532 WDP_LOGE("Failed to send command to wpa_supplicant");
2534 WDP_LOGD("Succeeded to cancel");
2536 __WDP_LOG_FUNC_EXIT__;
2541 static gboolean _retry_start_scan(gpointer data)
2543 __WDP_LOG_FUNC_ENTER__;
2545 WDP_LOGD("Succeeded to start scan");
2547 __WDP_LOG_FUNC_EXIT__;
2552 int ws_start_scan(wfd_oem_scan_param_s *param)
2554 __WDP_LOG_FUNC_ENTER__;
2555 GDBusConnection *g_dbus = NULL;
2556 GVariantBuilder *builder = NULL;
2557 GVariant *value = NULL;
2558 dbus_method_param_s params;
2562 WDP_LOGE("Invalid parameter");
2565 g_dbus = g_pd->g_dbus;
2567 WDP_LOGE("DBus connection is NULL");
2570 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2572 if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE) {
2574 dbus_set_method_param(¶ms, "Find", g_pd->iface_path, g_dbus);
2576 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
2578 if (param->scan_time)
2579 g_variant_builder_add (builder, "{sv}", "Timeout",
2580 g_variant_new_int32(param->scan_time));
2581 if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
2582 g_variant_builder_add (builder, "{sv}", "DiscoveryType",
2583 g_variant_new_string("social"));
2585 value = g_variant_new ("(a{sv})", builder);
2586 g_variant_builder_unref (builder);
2589 dbus_set_method_param(¶ms, "Listen", g_pd->iface_path, g_dbus);
2590 value = g_variant_new ("(i)", param->scan_time);
2593 params.params = value;
2595 WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
2596 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2597 g_variant_unref(value);
2599 WDP_LOGE("Failed to send command to wpa_supplicant");
2601 WDP_LOGD("Succeeded to start scan");
2603 __WDP_LOG_FUNC_EXIT__;
2607 int ws_restart_scan(int freq)
2609 __WDP_LOG_FUNC_ENTER__;
2610 GDBusConnection *g_dbus = NULL;
2611 GVariantBuilder *builder = NULL;
2612 GVariant *value = NULL;
2613 dbus_method_param_s params;
2616 g_dbus = g_pd->g_dbus;
2618 WDP_LOGE("DBus connection is NULL");
2621 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2623 dbus_set_method_param(¶ms, "Find", g_pd->iface_path, g_dbus);
2625 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
2626 g_variant_builder_add (builder, "{sv}", "Timeout", g_variant_new_int32(2));
2627 g_variant_builder_add (builder, "{sv}", "DiscoveryType",
2628 g_variant_new_string("social"));
2629 value = g_variant_new ("(a{sv})", builder);
2630 g_variant_builder_unref (builder);
2632 params.params = value;
2634 WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
2635 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2636 g_variant_unref(value);
2638 WDP_LOGE("Failed to send command to wpa_supplicant");
2640 WDP_LOGD("Succeeded to start scan");
2642 __WDP_LOG_FUNC_EXIT__;
2648 __WDP_LOG_FUNC_ENTER__;
2649 GDBusConnection *g_dbus = NULL;
2650 dbus_method_param_s params;
2653 g_dbus = g_pd->g_dbus;
2655 WDP_LOGE("DBus connection is NULL");
2658 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2660 dbus_set_method_param(¶ms, "StopFind", g_pd->iface_path, g_dbus);
2661 params.params = NULL;
2663 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2665 WDP_LOGE("Failed to send command to wpa_supplicant");
2667 WDP_LOGD("Succeeded to stop scan");
2669 __WDP_LOG_FUNC_EXIT__;
2673 int ws_get_visibility(int *visibility)
2675 __WDP_LOG_FUNC_ENTER__;
2677 __WDP_LOG_FUNC_EXIT__;
2681 int ws_set_visibility(int visibility)
2683 __WDP_LOG_FUNC_ENTER__;
2685 __WDP_LOG_FUNC_EXIT__;
2689 int ws_get_scan_result(GList **peers, int *peer_count)
2691 __WDP_LOG_FUNC_ENTER__;
2693 __WDP_LOG_FUNC_EXIT__;
2697 int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
2699 __WDP_LOG_FUNC_ENTER__;
2700 GDBusConnection *g_dbus = NULL;
2701 wfd_oem_device_s *ws_dev = NULL;
2702 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2705 if (!peer_addr || !peer) {
2706 WDP_LOGE("Invalid parameter");
2709 g_dbus = g_pd->g_dbus;
2711 WDP_LOGE("DBus connection is NULL");
2715 ws_dev = (wfd_oem_device_s *) g_try_malloc0(sizeof(wfd_oem_device_s));
2717 WDP_LOGF("Failed to allocate memory device. [%s]",
2719 __WDP_LOG_FUNC_EXIT__;
2723 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
2724 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
2726 WDP_LOGD("get peer path [%s]", peer_path);
2728 res = dbus_property_get_all(peer_path, g_dbus, SUPPLICANT_P2P_PEER,
2729 __ws_get_peer_property, ws_dev);
2732 WDP_LOGE("Failed to send command to wpa_supplicant");
2734 __WDP_LOG_FUNC_EXIT__;
2737 WDP_LOGD("succeeded to get peer info");
2740 __WDP_LOG_FUNC_EXIT__;
2744 int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
2746 __WDP_LOG_FUNC_ENTER__;
2747 GDBusConnection *g_dbus = NULL;
2748 GVariant *value = NULL;
2749 dbus_method_param_s params;
2750 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2754 WDP_LOGE("Invalid parameter");
2757 g_dbus = g_pd->g_dbus;
2759 WDP_LOGE("DBus connection is NULL");
2762 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2764 dbus_set_method_param(¶ms, "ProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
2766 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
2767 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
2768 WDP_LOGD("get peer path [%s]", peer_path);
2770 value = g_variant_new ("(os)", peer_path, __ws_wps_to_txt(wps_mode));
2771 WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
2773 params.params = value;
2775 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2776 g_variant_unref(value);
2778 WDP_LOGE("Failed to send command to wpa_supplicant");
2780 WDP_LOGD("Succeeded to send prov disc to peer[" MACSTR "]", MAC2STR(peer_addr));
2782 __WDP_LOG_FUNC_EXIT__;
2786 int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
2788 __WDP_LOG_FUNC_ENTER__;
2789 GDBusConnection *g_dbus = NULL;
2790 GVariantBuilder *builder = NULL;
2791 GVariant *value = NULL;
2792 dbus_method_param_s params;
2793 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2796 if (!peer_addr || !param) {
2797 WDP_LOGE("Invalid parameter");
2800 g_dbus = g_pd->g_dbus;
2802 WDP_LOGE("DBus connection is NULL");
2805 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2807 dbus_set_method_param(¶ms, "Connect", g_pd->iface_path, g_dbus);
2809 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
2810 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
2811 WDP_LOGD("get peer path [%s]", peer_path);
2813 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
2814 g_variant_builder_add (builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
2815 if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
2816 g_variant_builder_add (builder, "{sv}", "persistent", g_variant_new_boolean(TRUE));
2818 if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
2819 g_variant_builder_add (builder, "{sv}", "join", g_variant_new_boolean(TRUE));
2821 if (param->conn_flags& WFD_OEM_CONN_TYPE_AUTH)
2822 g_variant_builder_add (builder, "{sv}", "autorize_only", g_variant_new_boolean(TRUE));
2824 if (param->wps_pin[0] != '\0')
2825 g_variant_builder_add (builder, "{sv}", "pin", g_variant_new_string(param->wps_pin));
2827 g_variant_builder_add (builder, "{sv}", "wps_method",
2828 g_variant_new_string(__ws_wps_to_txt(param->wps_mode)));
2830 value = g_variant_new ("(a{sv})", builder);
2831 g_variant_builder_unref (builder);
2833 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
2835 params.params = value;
2837 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2838 g_variant_unref(value);
2840 WDP_LOGE("Failed to send command to wpa_supplicant");
2842 WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
2844 __WDP_LOG_FUNC_EXIT__;
2848 int ws_disconnect(unsigned char *peer_addr)
2850 __WDP_LOG_FUNC_ENTER__;
2851 GDBusConnection *g_dbus = NULL;
2852 GVariant *value = NULL;
2853 dbus_method_param_s params;
2854 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2858 WDP_LOGE("Invalid parameter");
2861 g_dbus = g_pd->g_dbus;
2863 WDP_LOGE("DBus connection is NULL");
2866 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2868 dbus_set_method_param(¶ms, "RemoveClient", g_pd->iface_path ,g_dbus);
2870 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
2871 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
2872 WDP_LOGE("get peer path [%s]", peer_path);
2874 value = g_variant_new ("(oi)", peer_path, 0);
2875 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
2877 params.params = value;
2879 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2880 g_variant_unref(value);
2882 WDP_LOGE("Failed to send command to wpa_supplicant");
2884 WDP_LOGD("Succeeded to stop scan");
2886 __WDP_LOG_FUNC_EXIT__;
2890 int ws_reject_connection(unsigned char *peer_addr)
2892 __WDP_LOG_FUNC_ENTER__;
2893 GDBusConnection *g_dbus = NULL;
2894 GVariant *value = NULL;
2895 dbus_method_param_s params;
2896 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
2900 WDP_LOGE("Invalid parameter");
2903 g_dbus = g_pd->g_dbus;
2905 WDP_LOGE("DBus connection is NULL");
2908 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2910 dbus_set_method_param(¶ms, "RejectPeer", g_pd->iface_path ,g_dbus);
2912 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
2913 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
2914 WDP_LOGE("get peer path [%s]", peer_path);
2916 value = g_variant_new ("(o)", peer_path);
2917 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
2919 params.params = value;
2921 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
2922 g_variant_unref(value);
2924 WDP_LOGE("Failed to send command to wpa_supplicant");
2926 WDP_LOGD("Succeeded to reject peer[" MACSTR "]", MAC2STR(peer_addr));
2928 __WDP_LOG_FUNC_EXIT__;
2932 int ws_cancel_connection(unsigned char *peer_addr)
2934 __WDP_LOG_FUNC_ENTER__;
2938 __WDP_LOG_FUNC_EXIT__;
2942 int ws_get_connected_peers(GList **peers, int *peer_count)
2944 __WDP_LOG_FUNC_ENTER__;
2946 __WDP_LOG_FUNC_EXIT__;
2950 int ws_get_pin(char *pin)
2952 __WDP_LOG_FUNC_ENTER__;
2954 __WDP_LOG_FUNC_EXIT__;
2958 int ws_set_pin(char *pin)
2960 __WDP_LOG_FUNC_ENTER__;
2962 __WDP_LOG_FUNC_EXIT__;
2966 int ws_get_supported_wps_mode()
2968 __WDP_LOG_FUNC_ENTER__;
2970 __WDP_LOG_FUNC_EXIT__;
2974 int ws_create_group(int persistent, int freq, const char *passphrase)
2976 __WDP_LOG_FUNC_ENTER__;
2977 GDBusConnection *g_dbus = NULL;
2978 GVariantBuilder *builder = NULL;
2979 GVariant *value = NULL;
2980 dbus_method_param_s params;
2983 g_dbus = g_pd->g_dbus;
2985 WDP_LOGE("DBus connection is NULL");
2988 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
2990 dbus_set_method_param(¶ms, "GroupAdd", g_pd->iface_path, g_dbus);
2992 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
2995 g_variant_builder_add (builder, "{sv}", "persistent", g_variant_new_boolean(TRUE));
2998 g_variant_builder_add (builder, "{sv}", "frequency", g_variant_new_int32(freq));
3000 g_variant_builder_add (builder, "{sv}", "frequency", g_variant_new_int32(2));
3002 value = g_variant_new ("(a{sv})", builder);
3003 g_variant_builder_unref (builder);
3005 WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
3007 params.params = value;
3009 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
3010 g_variant_unref(value);
3012 WDP_LOGE("Failed to send command to wpa_supplicant");
3014 WDP_LOGD("Succeeded to add group");
3016 __WDP_LOG_FUNC_EXIT__;
3020 int ws_destroy_group(const char *ifname)
3022 __WDP_LOG_FUNC_ENTER__;
3023 GDBusConnection *g_dbus = NULL;
3024 dbus_method_param_s params;
3028 WDP_LOGE("Invalid parameter");
3031 g_dbus = g_pd->g_dbus;
3033 WDP_LOGE("DBus connection is NULL");
3036 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3038 dbus_set_method_param(¶ms, "Disconnect", g_pd->group_iface_path, g_dbus);
3039 params.params = NULL;
3041 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
3043 WDP_LOGE("Failed to send command to wpa_supplicant");
3044 __WDP_LOG_FUNC_EXIT__;
3048 WDP_LOGD("Succeeded to remove group");
3051 __WDP_LOG_FUNC_EXIT__;
3055 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
3057 __WDP_LOG_FUNC_ENTER__;
3058 GDBusConnection *g_dbus = NULL;
3059 GVariantBuilder *builder = NULL;
3060 GVariant *value = NULL;
3061 dbus_method_param_s params;
3062 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
3065 if (!peer_addr || !param) {
3066 WDP_LOGE("Invalid parameter");
3069 g_dbus = g_pd->g_dbus;
3071 WDP_LOGE("DBus connection is NULL");
3074 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3076 dbus_set_method_param(¶ms, "Invite", g_pd->group_iface_path, g_dbus);
3078 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
3079 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
3080 WDP_LOGE("get peer path [%s]", peer_path);
3082 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
3083 g_variant_builder_add (builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
3084 value = g_variant_new ("(a{sv})", builder);
3085 g_variant_builder_unref (builder);
3087 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
3089 params.params = value;
3091 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
3092 g_variant_unref(value);
3094 WDP_LOGE("Failed to send command to wpa_supplicant");
3096 WDP_LOGD("Succeeded to invite peer[" MACSTR "]", MAC2STR(peer_addr));
3098 __WDP_LOG_FUNC_EXIT__;
3102 // Only group owner can use this command
3103 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
3105 __WDP_LOG_FUNC_ENTER__;
3106 GDBusConnection *g_dbus = NULL;
3107 GVariantBuilder *builder = NULL;
3108 GVariant *value = NULL;
3109 GVariant *dev_addr = NULL;
3110 dbus_method_param_s params;
3114 g_dbus = g_pd->g_dbus;
3116 WDP_LOGE("DBus connection is NULL");
3120 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3122 dbus_set_method_param(¶ms, "Start", g_pd->group_iface_path, g_dbus);
3124 if (peer_addr != NULL) {
3125 builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
3126 for(i = 0; i < WS_MACADDR_LEN; i++)
3127 g_variant_builder_add(builder, "y", peer_addr[i]);
3129 dev_addr = g_variant_new ("ay", builder);
3130 g_variant_builder_unref (builder);
3133 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
3134 g_variant_builder_add (builder, "{sv}", "Role", g_variant_new_string("enrollee"));
3135 if (peer_addr != NULL)
3136 g_variant_builder_add (builder, "{sv}", "P2PDeviceAddress", dev_addr);
3138 if (pin != NULL && pin[0] != '\0') {
3139 g_variant_builder_add (builder, "{sv}", "Type", g_variant_new_string("pin"));
3140 g_variant_builder_add (builder, "{sv}", "Pin", g_variant_new_string(pin));
3142 g_variant_builder_add (builder, "{sv}", "Type", g_variant_new_string("pbc"));
3145 value = g_variant_new ("(a{sv})", builder);
3146 g_variant_builder_unref (builder);
3148 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
3150 params.params = value;
3152 res = dbus_method_call(¶ms, SUPPLICNAT_WPS, NULL, NULL);
3153 g_variant_unref(params.params);
3155 if (peer_addr != NULL)
3156 g_variant_unref(dev_addr);
3158 WDP_LOGE("Failed to send command to wpa_supplicant");
3160 WDP_LOGD("Succeeded to run wps");
3162 __WDP_LOG_FUNC_EXIT__;
3166 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
3168 __WDP_LOG_FUNC_ENTER__;
3170 WDP_LOGD("Succeeded to start WPS");
3172 __WDP_LOG_FUNC_EXIT__;
3178 __WDP_LOG_FUNC_ENTER__;
3179 GDBusConnection *g_dbus = NULL;
3180 dbus_method_param_s params;
3183 g_dbus = g_pd->g_dbus;
3185 WDP_LOGE("DBus connection is NULL");
3188 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3190 dbus_set_method_param(¶ms, "Cancel", g_pd->group_iface_path, g_dbus);
3191 params.params = NULL;
3193 res = dbus_method_call(¶ms, SUPPLICNAT_WPS, NULL, NULL);
3195 WDP_LOGE("Failed to send command to wpa_supplicant");
3197 WDP_LOGD("Succeeded to cancel WPS");
3199 __WDP_LOG_FUNC_EXIT__;
3203 int ws_get_dev_name(char *dev_name)
3205 __WDP_LOG_FUNC_ENTER__;
3207 __WDP_LOG_FUNC_EXIT__;
3211 int ws_set_dev_name(char *dev_name)
3213 __WDP_LOG_FUNC_ENTER__;
3214 GDBusConnection *g_dbus = NULL;
3216 GVariant *value = NULL;
3217 GVariant *param = NULL;
3218 GVariantBuilder *builder = NULL;
3219 dbus_method_param_s params;
3223 WDP_LOGE("Invalid parameter");
3226 g_dbus = g_pd->g_dbus;
3228 WDP_LOGE("DBus connection is NULL");
3231 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3233 dbus_set_method_param(¶ms, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
3236 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
3237 g_variant_builder_add (builder, "{sv}", "DeviceName",
3238 g_variant_new_string(dev_name));
3239 g_variant_builder_add (builder, "{sv}", "SsidPostfix",
3240 g_variant_new_string(dev_name));
3241 value = g_variant_new ("a{sv}", builder);
3242 g_variant_builder_unref (builder);
3244 param = g_variant_new("(ssv)", SUPPLICNAT_P2PDEVICE,
3245 "P2PDeviceConfig", value);
3246 WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
3248 params.params = param;
3250 res = dbus_method_call(¶ms, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
3251 g_variant_unref(value);
3252 g_variant_unref(param);
3254 WDP_LOGE("Failed to send command to wpa_supplicant");
3256 WDP_LOGD("Succeeded to set device name");
3258 __WDP_LOG_FUNC_EXIT__;
3262 int ws_get_dev_mac(char *dev_mac)
3264 __WDP_LOG_FUNC_ENTER__;
3266 __WDP_LOG_FUNC_EXIT__;
3270 int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
3272 __WDP_LOG_FUNC_ENTER__;
3274 __WDP_LOG_FUNC_EXIT__;
3278 int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
3280 __WDP_LOG_FUNC_ENTER__;
3282 __WDP_LOG_FUNC_EXIT__;
3286 int ws_get_go_intent(int *go_intent)
3288 __WDP_LOG_FUNC_ENTER__;
3289 GDBusConnection *g_dbus = NULL;
3290 GVariant *param = NULL;
3291 GVariant *reply = NULL;
3292 GError *error = NULL;
3293 GVariantIter *iter = NULL;
3297 WDP_LOGE("Invalid parameter");
3300 g_dbus = g_pd->g_dbus;
3302 WDP_LOGE("DBus connection is NULL");
3306 param = g_variant_new("(ss)", SUPPLICNAT_P2PDEVICE, "P2PDeviceConfig");
3307 WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
3309 reply = g_dbus_connection_call_sync (
3311 SUPPLICANT_SERVICE, /* bus name */
3312 SUPPLICANT_INTERFACE, /* object path */
3313 DBUS_PROPERTIES_INTERFACE, /* interface name */
3314 DBUS_PROPERTIES_METHOD_GET, /* method name */
3315 param, /* GVariant *params */
3316 NULL, /* reply_type */
3317 G_DBUS_CALL_FLAGS_NONE, /* flags */
3318 SUPPLICANT_TIMEOUT , /* timeout */
3319 NULL, /* cancellable */
3320 &error); /* error */
3323 WDP_LOGE("Error! Failed to get interface State: [%s]",
3325 g_error_free(error);
3327 g_variant_unref(reply);
3328 __WDP_LOG_FUNC_EXIT__;
3331 g_variant_unref(param);
3335 g_variant_get(reply, "(a{sv})", &iter);
3340 GVariant *value = NULL;
3342 while(g_variant_iter_loop(iter, "{sv}", &key, &value)) {
3343 CHECK_KEY_VALUE(key, value);
3344 if(g_strcmp0(key, "GOIntent") == 0)
3345 g_variant_get(value, "u", go_intent);
3347 g_variant_iter_free(iter);
3349 g_variant_unref(reply);
3351 __WDP_LOG_FUNC_EXIT__;
3355 int ws_set_go_intent(int go_intent)
3357 __WDP_LOG_FUNC_ENTER__;
3358 GDBusConnection *g_dbus = NULL;
3360 GVariant *value = NULL;
3361 GVariant *param = NULL;
3362 GVariantBuilder *builder = NULL;
3363 dbus_method_param_s params;
3366 g_dbus = g_pd->g_dbus;
3368 WDP_LOGE("DBus connection is NULL");
3371 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3373 dbus_set_method_param(¶ms, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
3376 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
3377 g_variant_builder_add (builder, "{sv}", "GOIntent",
3378 g_variant_new_uint32(go_intent));
3379 value = g_variant_new ("a{sv}", builder);
3380 g_variant_builder_unref (builder);
3382 param = g_variant_new("(ssv)", SUPPLICNAT_P2PDEVICE, "P2PDeviceConfig", value);
3383 WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
3385 params.params = param;
3387 res = dbus_method_call(¶ms, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
3388 g_variant_unref(value);
3389 g_variant_unref(param);
3391 WDP_LOGE("Failed to send command to wpa_supplicant");
3393 WDP_LOGE("Succeeded to set go intent");
3394 __WDP_LOG_FUNC_EXIT__;
3398 int ws_set_country(char *ccode)
3400 __WDP_LOG_FUNC_ENTER__;
3401 __WDP_LOG_FUNC_ENTER__;
3402 GDBusConnection *g_dbus = NULL;
3404 GVariant *value = NULL;
3405 GVariant *param = NULL;
3407 dbus_method_param_s params;
3410 g_dbus = g_pd->g_dbus;
3412 WDP_LOGE("DBus connection is NULL");
3415 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3417 dbus_set_method_param(¶ms, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
3420 value = g_variant_new_string(ccode);
3422 param = g_variant_new("(ssv)", SUPPLICANT_IFACE, "Country", value);
3423 WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
3425 params.params = param;
3427 res = dbus_method_call(¶ms, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
3428 g_variant_unref(value);
3429 g_variant_unref(param);
3431 WDP_LOGE("Failed to send command to wpa_supplicant");
3433 WDP_LOGD("Succeeded to set country(%s)", ccode);
3435 __WDP_LOG_FUNC_EXIT__;
3439 int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
3441 __WDP_LOG_FUNC_ENTER__;
3443 __WDP_LOG_FUNC_EXIT__;
3447 void __parsing_networks (const char *key, GVariant *value, void *user_data)
3449 __WDP_LOG_FUNC_ENTER__;
3451 __WDP_LOG_FUNC_EXIT__;
3455 ws_network_info_s *network = (ws_network_info_s *)user_data;
3457 CHECK_KEY_VALUE(key, value);
3459 if (g_strcmp0(key, "ssid") == 0) {
3460 const char *ssid = NULL;
3461 g_variant_get(value, "s", &ssid);
3462 WDP_LOGD("ssid [%s]", ssid);
3463 g_strlcpy(network->ssid, ssid + 1, WS_SSID_LEN + 1);
3464 network->ssid[strlen(ssid) - 2] = '\0';
3466 } else if (g_strcmp0(key, "bssid") == 0) {
3467 unsigned char *bssid = NULL;
3468 g_variant_get(value, "s", &bssid);
3469 WDP_LOGD("bssid [%s]", bssid);
3470 __ws_txt_to_mac(bssid, network->bssid);
3472 } else if (g_strcmp0(key, "mode") == 0) {
3478 void __ws_extract_p2pdevice_details(const char *key, GVariant *value, void *user_data)
3481 __WDP_LOG_FUNC_ENTER__;
3483 CHECK_KEY_VALUE(key, value);
3485 if (g_strcmp0(key, "PersistentGroups") == 0) {
3486 GVariantIter *iter = NULL;
3487 const char *path = NULL;
3490 ws_network_info_s *networks = NULL;
3491 networks = (ws_network_info_s *)user_data;
3493 WDP_LOGE("network is NULL");
3494 __WDP_LOG_FUNC_EXIT__;
3498 g_variant_get(value, "ao", &iter);
3499 while(g_variant_iter_loop(iter, "o", &path)) {
3500 if(num >= WS_MAX_PERSISTENT_COUNT)
3502 WDP_LOGD("Retrive persistent path [%s]", path);
3503 g_strlcpy(networks[num].persistent_path, path, DBUS_OBJECT_PATH_MAX);
3504 WDP_LOGD("Retrive persistent path [%s]", networks[num].persistent_path);
3505 dbus_property_get_all(networks[num].persistent_path, g_pd->g_dbus,
3506 SUPPLICANT_P2P_PERSISTENTGROUP, __parsing_networks, &networks[num]);
3509 networks[0].total = num;
3510 WDP_LOGE("total number [%d]", num);
3513 __WDP_LOG_FUNC_EXIT__;
3517 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
3519 __WDP_LOG_FUNC_ENTER__;
3520 GDBusConnection *g_dbus = NULL;
3522 ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
3523 wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
3526 g_dbus = g_pd->g_dbus;
3528 WDP_LOGE("DBus connection is NULL");
3531 dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICNAT_P2PDEVICE, __ws_extract_p2pdevice_details, &networks[0]);
3533 cnt = networks[0].total;
3535 WDP_LOGD("Persistent Group Count=%d", cnt);
3536 if (cnt > WS_MAX_PERSISTENT_COUNT) {
3537 WDP_LOGE("Persistent group count exceeded or parsing error");
3538 __WDP_LOG_FUNC_EXIT__;
3542 wfd_persistent_groups = (wfd_oem_persistent_group_s*) g_try_malloc0(cnt * sizeof(wfd_oem_persistent_group_s));
3543 for(i = 0; i < cnt; i++) {
3544 WDP_LOGD("----persistent group [%d]----", i);
3545 WDP_LOGD("network_id=%d", networks[i].network_id);
3546 WDP_LOGD("ssid=%s", networks[i].ssid);
3547 WDP_LOGD("bssid=" MACSTR, MAC2STR(networks[i].bssid));
3549 wfd_persistent_groups[i].network_id = networks[i].network_id;
3550 g_strlcpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN + 1);
3551 memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
3555 *groups = wfd_persistent_groups;
3557 __WDP_LOG_FUNC_EXIT__;
3561 int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
3563 __WDP_LOG_FUNC_ENTER__;
3564 GDBusConnection *g_dbus = NULL;
3566 dbus_method_param_s params;
3567 ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
3571 g_dbus = g_pd->g_dbus;
3573 WDP_LOGE("DBus connection is NULL");
3576 dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICNAT_P2PDEVICE, __ws_extract_p2pdevice_details, networks);
3578 cnt = networks[0].total;
3580 WDP_LOGD("Persistent Group Count=%d", cnt);
3581 if (cnt > WS_MAX_PERSISTENT_COUNT) {
3582 WDP_LOGE("Persistent group count exceeded or parsing error");
3583 __WDP_LOG_FUNC_EXIT__;
3587 for(i=0;i<cnt;i++) {
3588 WDP_LOGD("----persistent group [%d]----", i);
3589 WDP_LOGD("network_id=%d", networks[i].network_id);
3590 WDP_LOGD("network ssid=%s", networks[i].ssid);
3591 WDP_LOGD("network bssid=" MACSTR, MAC2STR(networks[i].bssid));
3593 WDP_LOGD("ssid=%s", ssid);
3594 WDP_LOGD("bssid=" MACSTR, MAC2STR(bssid));
3597 if (!memcmp(bssid, networks[i].bssid, WS_MACADDR_LEN) &&
3598 !strcmp(ssid, networks[i].ssid)) {
3600 WDP_LOGD("Persistent group found [%d: %s]", networks[i].network_id, ssid);
3602 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3603 dbus_set_method_param(¶ms, "RemovePersistentGroup",
3604 g_pd->iface_path, g_dbus);
3605 params.params = g_variant_new ("(o)", networks[i].persistent_path);
3607 WDP_LOGD("params [%s]", g_variant_print(params.params, TRUE));
3608 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
3610 WDP_LOGE("Failed to send command to wpa_supplicant");
3611 __WDP_LOG_FUNC_EXIT__;
3614 WDP_LOGD("Succeeded to remove persistent group");;
3620 WDP_LOGE("Persistent group not found [%s]", ssid);
3624 __WDP_LOG_FUNC_EXIT__;
3628 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
3630 __WDP_LOG_FUNC_ENTER__;
3631 GDBusConnection *g_dbus = NULL;
3633 GVariant *value = NULL;
3634 GVariant *param = NULL;
3635 GVariantBuilder *builder = NULL;
3636 dbus_method_param_s params;
3639 g_dbus = g_pd->g_dbus;
3641 WDP_LOGE("DBus connection is NULL");
3644 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3646 dbus_set_method_param(¶ms, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
3649 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
3650 g_variant_builder_add (builder, "{sv}", "PersistentReconnect",
3651 g_variant_new_boolean(reconnect));
3652 value = g_variant_new ("a{sv}", builder);
3653 g_variant_builder_unref (builder);
3655 param = g_variant_new("(ssv)", SUPPLICNAT_P2PDEVICE, "P2PDeviceConfig", value);
3656 WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
3658 params.params = param;
3660 res = dbus_method_call(¶ms, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
3661 g_variant_unref(value);
3662 g_variant_unref(param);
3664 WDP_LOGE("Failed to send command to wpa_supplicant");
3666 WDP_LOGD("Succeeded to set persistent reconnect");
3668 __WDP_LOG_FUNC_EXIT__;
3672 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
3673 static int __ws_compress_query(char *compressed, char *query, int qtype)
3681 token = strtok_r(query, ".", &temp);
3683 if (!strcmp(token, "local")) {
3684 WDP_LOGD("Query conversion done");
3687 } else if (!strncmp(token, "_tcp", 4)) {
3688 memcpy(&compressed[length], WS_TCP_PTR_HEX, 2);
3691 } else if (!strncmp(token, "_udp", 4)) {
3692 memcpy(&compressed[length], WS_UDP_PTR_HEX, 2);
3696 WDP_LOGD("Token: [%s]", token);
3697 token_len = strlen(token);
3698 compressed[length] = token_len;
3701 memcpy(&compressed[length], token, token_len);
3705 token = strtok_r(NULL, ".", &temp);
3707 if(qtype == WS_QTYPE_PTR || token_num == 2) {
3708 memcpy(&compressed[length], WS_PTR_TYPE_HEX, 3);
3709 } else if (qtype == WS_QTYPE_TXT || token_num == 3) {
3710 memcpy(&compressed[length], WS_TXT_TYPE_HEX, 3);
3713 WDP_LOGD("converted query length [%d] token num [%d]", length, token_num);
3718 static int __ws_compress_rdata(char *compressed, char *rdata, int qtype)
3725 if (qtype == WS_QTYPE_PTR) {
3727 token = strtok_r(rdata, ".", &temp);
3729 WDP_LOGD("Token: %s", token);
3730 token_len = strlen(token);
3731 compressed[length] = token_len;
3734 memcpy(&compressed[length], token, token_len);
3738 compressed[length] = 0xc0;
3739 compressed[length+1] = 0x27;
3742 } else if (qtype == WS_QTYPE_TXT) {
3744 token = strtok_r(rdata, ",", &temp);
3747 WDP_LOGD("Token: [%s]", token);
3749 token_len = strlen(token);
3750 compressed[length] = token_len;
3753 memcpy(&compressed[length], token, token_len);
3756 token = strtok_r(NULL, ",", &temp);
3759 WDP_LOGD("RDATA is NULL");
3764 int _convert_bonjour_to_args(char *query, char *rdata, GVariantBuilder *builder)
3766 GVariantBuilder *args = NULL;
3767 char compressed[256] = {0, };
3773 if (!query || !builder) {
3774 WDP_LOGE("Invalid parameter");
3777 if (!rdata || !strlen(rdata)) {
3778 WDP_LOGD("RDATA is NULL\n");
3780 temp = strstr(rdata, query);
3782 if(temp != NULL && temp - rdata > 0)
3783 qtype = WS_QTYPE_PTR;
3785 qtype = WS_QTYPE_TXT;
3789 /* compress query */
3790 length = __ws_compress_query(compressed, query, qtype);
3792 args = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
3793 for (i = 0; i < length; i++)
3794 g_variant_builder_add(args, "y", compressed[i]);
3795 g_variant_builder_add (builder, "{sv}", "query", g_variant_new ("ay", args));
3796 g_variant_builder_unref (args);
3798 memset(compressed, 0x0, 256);
3803 length = __ws_compress_rdata(compressed, rdata, qtype);
3805 args = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
3806 for (i = 0; i < length; i++)
3807 g_variant_builder_add(args, "y", compressed[i]);
3808 g_variant_builder_add (builder, "{sv}", "response", g_variant_new ("ay", args));
3809 g_variant_builder_unref (args);
3815 int _check_service_query_exists(wfd_oem_service_s *service)
3818 wfd_oem_service_s *data = NULL;
3820 for (count = 0; count < g_list_length(service_list); count ++) {
3821 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
3822 if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
3823 WDP_LOGD("Query already exists");
3830 static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
3832 if (NULL == s_type || NULL == mac_str || NULL == query_id)
3836 wfd_oem_service_s *data = NULL;
3838 for (count = 0; count < g_list_length(service_list); count ++) {
3839 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
3840 if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
3841 memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
3842 strncpy(query_id, data->query_id, OEM_QUERY_ID_LEN);
3846 if (strlen(query_id) <= 0) {
3847 WDP_LOGD("!! Query ID not found !!");
3851 WDP_LOGD("query id :[0x%s]",query_id);
3856 void __add_service_query(GVariant *value, void *mac_addr)
3858 __WDP_LOG_FUNC_ENTER__;
3859 wfd_oem_service_s *service = NULL;
3861 long long unsigned ref = 0;
3862 unsigned char *mac_address = (unsigned char *)mac_addr;
3863 char mac_str[18] = {0, };
3867 g_variant_get(value, "(t)", &ref);
3869 service = (wfd_oem_service_s*) g_try_malloc0(sizeof(wfd_oem_service_s));
3871 WDP_LOGE("Failed to allocate memory for service");
3875 if (mac_address[0] == 0 && mac_address[1] == 0 && mac_address[2] == 0 &&
3876 mac_address[3] == 0 && mac_address[4] == 0 && mac_address[5] == 0) {
3877 g_snprintf(mac_str, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
3879 g_snprintf(mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_address));
3882 g_strlcpy(service->dev_addr, mac_str, OEM_MACSTR_LEN);
3883 g_snprintf(service->query_id, OEM_QUERY_ID_LEN + 1, "0x%llx", ref);
3885 res = _check_service_query_exists(service);
3889 service_list = g_list_append(service_list, service);
3892 __WDP_LOG_FUNC_EXIT__;
3897 /* for now, supplicant dbus interface only provides upnp service fully */
3898 int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
3900 __WDP_LOG_FUNC_ENTER__;
3901 GDBusConnection *g_dbus = NULL;
3902 GVariantBuilder *builder = NULL;
3903 GVariant *value = NULL;
3904 dbus_method_param_s params;
3905 static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
3909 g_dbus = g_pd->g_dbus;
3911 WDP_LOGE("DBus connection is NULL");
3914 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
3916 dbus_set_method_param(¶ms, "ServiceDiscoveryRequest", g_pd->iface_path, g_dbus);
3918 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
3921 g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
3922 COMPACT_MACSTR, g_pd->iface_path, MAC2STR(mac_addr));
3923 WDP_LOGD("get peer path [%s]", peer_path);
3924 g_variant_builder_add (builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
3927 if (service_type == WFD_OEM_SERVICE_TYPE_ALL) {
3929 char *service_all = "\x02\x00\x00\x01";
3930 GVariantBuilder *query = NULL;
3932 query = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
3933 for (i = 0; i < SERVICE_QUERY_LEN; i++)
3934 g_variant_builder_add(query, "y", service_all[i]);
3935 g_variant_builder_add (builder, "{sv}", "query", g_variant_new ("ay", query));
3936 g_variant_builder_unref (query);
3938 } else if (service_type == WFD_OEM_SERVICE_TYPE_UPNP) {
3940 g_variant_builder_add (builder, "{sv}", "service_type", g_variant_new_string("upnp"));
3941 g_variant_builder_add (builder, "{sv}", "version", g_variant_new_uint16(TRUE));
3943 } else if (service_type == WFD_OEM_SERVICE_TYPE_BONJOUR) {
3945 char *service_bonjour = "\x02\x00\x01\x01";
3946 GVariantBuilder *query = NULL;
3948 query = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
3949 for (i = 0; i < SERVICE_QUERY_LEN; i++)
3950 g_variant_builder_add(query, "y", service_bonjour[i]);
3951 g_variant_builder_add (builder, "{sv}", "query", g_variant_new ("ay", query));
3952 g_variant_builder_unref (query);
3955 value = g_variant_new ("(a{sv})", builder);
3956 g_variant_builder_unref (builder);
3958 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
3960 params.params = value;
3962 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, __add_service_query, mac_addr);
3964 WDP_LOGE("Failed to send command to wpa_supplicant");
3966 WDP_LOGD("Succeeded to start service discovery");
3968 __WDP_LOG_FUNC_EXIT__;
3972 int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
3974 __WDP_LOG_FUNC_ENTER__;
3975 GDBusConnection *g_dbus = NULL;
3976 dbus_method_param_s params;
3977 wfd_oem_service_s *data = NULL;
3978 char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
3979 char s_type[OEM_SERVICE_TYPE_LEN + 1] ={0, };
3980 char mac_str[18] = {0, };
3984 g_dbus = g_pd->g_dbus;
3986 WDP_LOGE("DBus connection is NULL");
3990 if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
3991 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
3992 snprintf(mac_str, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
3994 snprintf(mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
3997 switch(service_type) {
3998 case WFD_OEM_SERVICE_TYPE_ALL:
3999 strncpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN);
4001 case WFD_OEM_SERVICE_TYPE_BONJOUR:
4002 strncpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN);
4004 case WFD_OEM_SERVICE_TYPE_UPNP:
4005 strncpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN);
4007 case WFD_OEM_SERVICE_TYPE_BT_ADDR:
4008 strncpy(s_type, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
4010 case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
4011 strncpy(s_type, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
4014 __WDP_LOG_FUNC_EXIT__;
4015 WDP_LOGE("Invalid Service type");
4019 WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
4020 WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
4022 data = _remove_service_query(s_type, mac_str, query_id);
4026 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
4028 dbus_set_method_param(¶ms, "ServiceDiscoveryCancelRequest", g_pd->iface_path, g_dbus);
4030 params.params = g_variant_new ("(t)", strtoul(query_id, NULL, 16));
4032 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
4034 WDP_LOGE("Failed to send command to wpa_supplicant");
4036 WDP_LOGD("Succeeded to cancel service discovery");
4038 service_list = g_list_remove(service_list, data);
4041 __WDP_LOG_FUNC_EXIT__;
4045 int ws_serv_add(wfd_oem_new_service_s *service)
4047 __WDP_LOG_FUNC_ENTER__;
4048 GDBusConnection *g_dbus = NULL;
4049 GVariantBuilder *builder = NULL;
4050 GVariant *value = NULL;
4051 dbus_method_param_s params;
4054 g_dbus = g_pd->g_dbus;
4056 WDP_LOGE("DBus connection is NULL");
4059 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
4061 dbus_set_method_param(¶ms, "AddService", g_pd->iface_path, g_dbus);
4063 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
4065 if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
4067 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
4068 WDP_LOGD("Query: %s", service->data.bonjour.query);
4069 WDP_LOGD("RData: %s", service->data.bonjour.rdata);
4071 res = _convert_bonjour_to_args(service->data.bonjour.query,
4072 service->data.bonjour.rdata, builder);
4074 WDP_LOGE("Failed to convert Key string");
4075 g_variant_builder_unref (builder);
4079 } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
4080 g_variant_builder_add (builder, "{sv}", "service_type", g_variant_new_string("upnp"));
4081 g_variant_builder_add (builder, "{sv}", "version", g_variant_new_uint16(TRUE));
4082 g_variant_builder_add (builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
4085 value = g_variant_new ("(a{sv})", builder);
4086 g_variant_builder_unref (builder);
4088 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
4090 params.params = value;
4092 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
4094 WDP_LOGE("Failed to send command to wpa_supplicant");
4096 WDP_LOGD("Succeeded to add service");
4098 __WDP_LOG_FUNC_EXIT__;
4102 int ws_serv_del(wfd_oem_new_service_s *service)
4104 __WDP_LOG_FUNC_ENTER__;
4105 GDBusConnection *g_dbus = NULL;
4106 GVariantBuilder *builder = NULL;
4107 GVariant *value = NULL;
4108 dbus_method_param_s params;
4111 g_dbus = g_pd->g_dbus;
4113 WDP_LOGE("DBus connection is NULL");
4116 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
4118 dbus_set_method_param(¶ms, "DeleteService", g_pd->iface_path, g_dbus);
4120 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
4122 if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
4124 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
4125 WDP_LOGD("Query: %s", service->data.bonjour.query);
4127 res = _convert_bonjour_to_args(service->data.bonjour.query,
4130 WDP_LOGE("Failed to convert Key string");
4131 g_variant_builder_unref (builder);
4135 } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
4136 g_variant_builder_add (builder, "{sv}", "service_type", g_variant_new_string("upnp"));
4137 g_variant_builder_add (builder, "{sv}", "version", g_variant_new_uint16(TRUE));
4138 g_variant_builder_add (builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
4141 value = g_variant_new ("(a{sv})", builder);
4142 g_variant_builder_unref (builder);
4144 WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
4146 params.params = value;
4148 res = dbus_method_call(¶ms, SUPPLICNAT_P2PDEVICE, NULL, NULL);
4150 WDP_LOGE("Failed to send command to wpa_supplicant");
4152 WDP_LOGD("Succeeded to del service");
4154 __WDP_LOG_FUNC_EXIT__;
4157 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
4159 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
4161 int _ws_disable_display()
4163 __WDP_LOG_FUNC_ENTER__;
4164 GDBusConnection *g_dbus = NULL;
4165 GVariantBuilder *builder = NULL;
4166 GVariant *value = NULL;
4167 GVariant *param = NULL;
4168 dbus_method_param_s params;
4171 g_dbus = g_pd->g_dbus;
4173 WDP_LOGE("DBus connection is NULL");
4176 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
4178 dbus_set_method_param(¶ms, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
4181 builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
4182 value = g_variant_new ("ay", builder);
4183 g_variant_builder_unref (builder);
4185 param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
4186 WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
4188 params.params = param;
4190 res = dbus_method_call(¶ms, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4191 g_variant_unref(value);
4192 g_variant_unref(param);
4194 WDP_LOGE("Failed to send command to wpa_supplicant");
4196 WDP_LOGD("Succeeded to disable Wi-Fi display");
4198 __WDP_LOG_FUNC_EXIT__;
4202 int ws_miracast_init(int enable)
4204 __WDP_LOG_FUNC_ENTER__;
4205 wfd_oem_display_s wifi_display;
4208 memset(&wifi_display, 0x0, sizeof(wfd_oem_display_s));
4210 wifi_display.availablity = enable;
4211 wifi_display.hdcp_support = 1;
4212 wifi_display.port = 0x07E6;
4213 wifi_display.max_tput = 0x0028;
4215 res = ws_set_display(&wifi_display);
4217 WDP_LOGE("Failed to set miracast parameter(device info)");
4218 __WDP_LOG_FUNC_EXIT__;
4223 res = _ws_disable_display();
4225 WDP_LOGE("Failed to disable wifi display");
4227 WDP_LOGD("Succeeded to disable wifi display");
4229 __WDP_LOG_FUNC_EXIT__;
4233 int ws_set_display(wfd_oem_display_s *wifi_display)
4235 __WDP_LOG_FUNC_ENTER__;
4236 GDBusConnection *g_dbus = NULL;
4238 GVariant *value = NULL;
4239 GVariant *param = NULL;
4240 GVariantBuilder *builder = NULL;
4241 dbus_method_param_s params;
4245 unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
4247 if (!wifi_display) {
4248 WDP_LOGE("Invalid parameter");
4251 g_dbus = g_pd->g_dbus;
4253 WDP_LOGE("DBus connection is NULL");
4256 memset(¶ms, 0x0, sizeof(dbus_method_param_s));
4258 dbus_set_method_param(¶ms, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
4261 ies[2] = WFD_SUBELEM_LEN_DEV_INFO;
4262 ies[3] = wifi_display->hdcp_support;
4263 ies[4] = (wifi_display->type) | (wifi_display->availablity<<4);
4264 ies[5] = wifi_display->port>>8;
4265 ies[6] = wifi_display->port&0xff;
4266 ies[7] = wifi_display->max_tput>>8;
4267 ies[8] = wifi_display->max_tput&0xff;
4269 builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
4270 for(i = 0; i < WFD_SUBELEM_LEN_DEV_INFO + 3; i++)
4271 g_variant_builder_add(builder, "y", ies[i]);
4272 value = g_variant_new ("ay", builder);
4273 g_variant_builder_unref (builder);
4275 WDP_LOGD("value [%s]", g_variant_print(value,TRUE));
4277 param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
4278 WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
4280 params.params = param;
4282 res = dbus_method_call(¶ms, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
4283 g_variant_unref(value);
4284 g_variant_unref(param);
4286 WDP_LOGE("Failed to send command to wpa_supplicant");
4288 WDP_LOGD("Succeeded to set Wi-Fi Display");
4290 __WDP_LOG_FUNC_EXIT__;
4293 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
4297 __WDP_LOG_FUNC_ENTER__;
4302 __WDP_LOG_FUNC_EXIT__;