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 plugin functions.
23 * @file wfd_plugin_wpasupplicant.c
24 * @author Gibyoung Kim (lastkgb.kim@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-wpasupplicant.h"
49 #define NETCONFIG_SERVICE "net.netconfig"
50 #define NETCONFIG_WIFI_INTERFACE "net.netconfig.wifi"
51 #define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
53 #define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
55 ws_string_s ws_event_strs[] = {
57 {"P2P-DEVICE-FOUND", WS_EVENT_DEVICE_FOUND},
58 {"P2P-DEVICE-LOST", WS_EVENT_DEVICE_LOST},
59 {"P2P-FIND-STOPPED", WS_EVENT_FIND_STOPED},
61 // provision discovery
62 {"P2P-PROV-DISC-PBC-REQ", WS_EVENT_PROV_DISC_PBC_REQ},
63 {"P2P-PROV-DISC-SHOW-PIN", WS_EVENT_PROV_DISC_SHOW_PIN},
64 {"P2P-PROV-DISC-ENTER-PIN", WS_EVENT_PROV_DISC_ENTER_PIN},
65 {"P2P-PROV-DISC-PBC-RESP", WS_EVENT_PROV_DISC_PBC_RESP},
66 {"P2P-PROV-DISC-FAILURE", WS_EVENT_PROV_DISC_FAILURE},
69 {"P2P-GO-NEG-REQUEST", WS_EVENT_GO_NEG_REQUEST},
70 {"P2P: Received GO Negotiation Request from", WS_EVENT_GO_NEG_REQUEST},
71 {"P2P-GO-NEG-FAILURE", WS_EVENT_GO_NEG_FAILURE},
72 {"P2P-GO-NEG-SUCCESS", WS_EVENT_GO_NEG_SUCCESS},
73 {"WPS-FAIL", WS_EVENT_WPS_FAIL},
74 {"P2P-GROUP-FORMATION-FAILURE", WS_EVENT_GROUP_FORMATION_FAILURE},
75 {"WPS-SUCCESS", WS_EVENT_WPS_SUCCESS},
76 {"WPS-REG-SUCCESS", WS_EVENT_WPS_REG_SUCCESS},
77 {"P2P-GROUP-FORMATION-SUCCESS", WS_EVENT_GROUP_FORMATION_SUCCESS},
79 {"CTRL-EVENT-CONNECTED", WS_EVENT_CONNECTED},
80 {"AP-STA-CONNECTED", WS_EVENT_STA_CONNECTED},
83 {"P2P-INVITATION-RECEIVED", WS_EVENT_INVITATION_RECEIVED},
84 {"P2P-INVITATION-RESULT", WS_EVENT_INVITATION_RESULT},
86 {"CTRL-EVENT-DISCONNECTED", WS_EVENT_DISCONNECTED},
87 {"AP-STA-DISCONNECTED", WS_EVENT_STA_DISCONNECTED},
90 {"P2P-GROUP-STARTED", WS_EVENT_GROUP_STARTED},
91 {"P2P-GROUP-REMOVED", WS_EVENT_GROUP_REMOVED},
93 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
94 {"P2P-SERV-DISC-RESP", WS_EVENT_SERV_DISC_RESP},
95 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
97 {"CTRL-EVENT-TERMINATING", WS_EVENT_TERMINATING},
102 ws_string_s ws_dev_info_strs[] = {
103 {"p2p_dev_addr", WS_DEV_INFO_P2P_DEV_ADDR},
104 {"name", WS_DEV_INFO_DEV_NAME},
105 {"pri_dev_type", WS_DEV_INFO_DEV_TYPE},
106 {"config_methods", WS_DEV_INFO_CONFIG_METHODS},
107 {"dev_capab", WS_DEV_INFO_DEV_CAP},
108 {"group_capab", WS_DEV_INFO_GROUP_CAP},
109 {"p2p_go_addr", WS_DEV_INFO_P2P_GO_ADDR},
110 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
111 {"wfd_dev_info", WS_DEV_INFO_WFD_DEV_INFO},
112 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
113 {"", WS_DEV_INFO_LIMIT},
116 ws_string_s ws_conn_info_strs[] = {
117 {"dev_passwd_id", WS_CONN_INFO_DEV_PWD_ID},
118 {"status", WS_CONN_INFO_STATUS},
119 {"config_error", WS_CONN_INFO_ERROR},
120 {"", WS_CONN_INFO_LIMIT},
123 ws_string_s ws_invite_info_strs[] = {
124 {"sa", WS_INVITE_INFO_SRC_ADDR},
125 {"go_dev_addr", WS_INVITE_INFO_GO_DEV_ADDR},
126 {"bssid", WS_INVITE_INFO_BSSID},
127 {"listen", WS_INVITE_INFO_LISTEN},
128 {"status", WS_INVITE_INFO_STATUS},
129 {"", WS_INVITE_INFO_LIMIT},
132 ws_string_s ws_group_info_strs[] = {
133 {"ssid", WS_GROUP_INFO_SSID},
134 {"freq", WS_GROUP_INFO_FREQ},
135 {"passphrase", WS_GROUP_INFO_PASS},
136 {"go_dev_addr", WS_GROUP_INFO_GO_DEV_ADDR},
137 {"status", WS_GROUP_INFO_STATUS},
138 {"", WS_GROUP_INFO_LIMIT},
142 ws_string_s ws_peer_info_strs[] = {
143 {"age", WS_PEER_INFO_AGE},
144 {"listen_freq", WS_PEER_INFO_LISTEN_FREQ},
145 {"level", WS_PEER_INFO_LEVEL},
146 {"wps_method", WS_PEER_INFO_WPS_METHOD},
147 {"interface_addr", WS_PEER_INFO_INTERFACE_ADDR},
148 {"member_in_go_dev", WS_PEER_INFO_MEMBER_IN_GO_DEV},
149 {"member_in_go_iface", WS_PEER_INFO_MEMBER_IN_GO_IFACE},
150 {"pri_dev_type", WS_PEER_INFO_PRI_DEV_TYPE},
151 {"device_name", WS_PEER_INFO_DEVICE_NAME},
152 {"manufacturer", WS_PEER_INFO_MANUFACTURER},
153 {"model_name", WS_PEER_INFO_MODEL_NAME},
154 {"model_number", WS_PEER_INFO_MODEL_NUMBER},
155 {"serial_number", WS_PEER_INFO_SERIAL_NUMBER},
156 {"config_methods", WS_PEER_INFO_CONFIG_METHODS},
157 {"dev_capab", WS_PEER_INFO_DEV_CAPAB},
158 {"group_capab", WS_PEER_INFO_GROUP_CAPAB},
159 {"go_neg_req_sent", WS_PEER_INFO_GO_NEG_REQ_SENT},
160 {"go_state", WS_PEER_INFO_GO_STATE},
161 {"dialog_token", WS_PEER_INFO_DIALOG_TOKEN},
162 {"intended_addr", WS_PEER_INFO_INTENDED_ADDR},
163 {"country", WS_PEER_INFO_COUNTRY},
164 {"oper_freq", WS_PEER_INFO_OPER_FREQ},
165 {"req_config_methods", WS_PEER_INFO_REQ_CONFIG_METHODS},
166 {"flags", WS_PEER_INFO_FLAGS},
167 {"status", WS_PEER_INFO_STATUS},
168 {"wait_count", WS_PEER_INFO_WAIT_COUNT},
169 {"invitation_reqs", WS_PEER_INFO_INVITATION_REQS},
170 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
171 {"wfd_subelems", WS_PEER_INFO_WFD_SUBELEMS},
172 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
175 ws_string_s ws_conf_attr_strs[] = {
176 {"device_name", WFD_OEM_CONFIG_ATTR_STR_DEVICE_NAME},
177 {"p2p_ssid_postfix", WFD_OEM_CONFIG_ATTR_STR_SSID_POSTFIX},
178 {"country", WFD_OEM_CONFIG_ATTR_STR_COUNTRY},
179 {"p2p_go_intent", WFD_OEM_CONFIG_ATTR_NUM_GO_INTENT},
180 {"p2p_listen_channel", WFD_OEM_CONFIG_ATTR_NUM_LISTEN_FREQ},
181 {"p2p_oper_channel", WFD_OEM_CONFIG_ATTR_NUM_OPER_FREQ},
182 {"p2p_pref_chan", WFD_OEM_CONFIG_ATTR_NUM_PREF_FREQ},
183 {"persistent_reconnect", WFD_OEM_CONFIG_ATTR_NUM_PERSIST_RECONN},
184 {"wifi_display", WFD_OEM_CONFIG_ATTR_NUM_WIFI_DISPLAY},
185 {"p2p_disabled", WFD_OEM_CONFIG_ATTR_NUM_P2P_DISABLED},
186 {"max_num_sta", WFD_OEM_CONFIG_ATTR_NUM_MAX_STA},
189 static wfd_oem_ops_s supplicant_ops = {
192 .activate = ws_activate,
193 .deactivate = ws_deactivate,
195 .start_scan = ws_start_scan,
196 .stop_scan = ws_stop_scan,
197 .get_visibility = ws_get_visibility,
198 .set_visibility = ws_set_visibility,
199 .get_scan_result = ws_get_scan_result,
200 .get_peer_info = ws_get_peer_info,
202 .prov_disc_req = ws_prov_disc_req,
204 .connect = ws_connect,
205 .disconnect = ws_disconnect,
206 .reject_connection = ws_reject_connection,
207 .cancel_connection = ws_cancel_connection,
209 .get_connected_peers = ws_get_connected_peers,
210 .get_pin = ws_get_pin,
211 .set_pin = ws_set_pin,
212 .get_supported_wps_mode = ws_get_supported_wps_mode,
214 .create_group = ws_create_group,
215 .destroy_group = ws_destroy_group,
217 .wps_start = ws_wps_start,
218 .enrollee_start = ws_enrollee_start,
219 .wps_cancel = ws_wps_cancel,
221 .get_dev_name = ws_get_dev_name,
222 .set_dev_name = ws_set_dev_name,
223 .get_dev_mac = ws_get_dev_mac,
224 .get_dev_type = ws_get_dev_type,
225 .set_dev_type = ws_set_dev_type,
226 .get_go_intent = ws_get_go_intent,
227 .set_go_intent = ws_set_go_intent,
228 .set_country = ws_set_country,
229 .get_persistent_groups = ws_get_persistent_groups,
230 .remove_persistent_group = ws_remove_persistent_group,
231 .set_persistent_reconnect = ws_set_persistent_reconnect,
233 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
234 .start_service_discovery = ws_start_service_discovery,
235 .cancel_service_discovery = ws_cancel_service_discovery,
237 .serv_add = ws_serv_add,
238 .serv_del = ws_serv_del,
239 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
241 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
242 .miracast_init = ws_miracast_init,
243 .set_display = ws_set_display,
244 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
246 .refresh = ws_refresh,
250 static ws_plugin_data_s *g_pd;
251 static unsigned char g_pd_out[OEM_MACADDR_LEN];
252 static unsigned char null_mac[OEM_MACADDR_LEN] = {0, 0, 0, 0, 0, 0};
254 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
255 static GList *service_list;
256 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
258 static gboolean ws_event_handler(GIOChannel *source,
259 GIOCondition condition,
262 int wfd_plugin_load(wfd_oem_ops_s **ops)
265 WDP_LOGE("Invalid parameter");
269 *ops = &supplicant_ops;
274 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
275 static int _change_str_order(char *src, int length, int unit, char *dest)
279 if (!src || length < 0 || length < unit || !dest) {
280 WDP_LOGE("Invalid parameter");
284 for (i=0; i<length/unit; i++)
285 memcpy(dest + length - (i+1)*unit, src + i*unit, unit);
291 static int _ws_hex_to_num(char *src, int len)
296 if (!src || len < 0) {
297 WDP_LOGE("Invalid parameter");
301 temp = (char*) calloc(1, len+1);
303 WDP_LOGE("Failed to allocate memory");
307 memcpy(temp, src, len);
308 num = strtoul(temp, NULL, 16);
314 static int _ws_hex_to_txt(char *src, int length, char *dest)
316 // TODO: check it is good to change dest parameter as double pointer.
317 // It could be better to allocate memory for dest parameter here.
323 if (!src || length < 0 || !dest) {
324 WDP_LOGE("Invalid parameter");
328 // TODO: flush destination memory
338 for (i=0; i<len/2 && *ptr!=0; i++) {
339 temp[i] = (char) _ws_hex_to_num(ptr, 2);
341 WDP_LOGE("Failed to convert hexa string to num");
349 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
351 static int _ws_txt_to_devtype(char *txt, int *pri, int *sec)
353 if (!txt || !pri || !sec) {
354 WDP_LOGE("Invalid parameter");
358 if (strlen(txt) > WS_DEVTYPESTR_LEN) {
359 WDP_LOGE("Device type string is invalid [%s]", txt);
363 *pri = (int) strtoul(txt, &txt, 0);
364 txt = strrchr(txt, '-');
365 *sec = (int) strtoul(txt+1, &txt, 16);
370 static int _ws_txt_to_mac(char *txt, unsigned char *mac)
375 WDP_LOGE("Invalid parameter");
380 mac[i++] = (char) strtoul(txt, &txt, 16);
381 if (!*txt++ || i == 6)
385 if (i != OEM_MACADDR_LEN)
391 static char *_ws_wps_to_txt(int wps_mode)
394 case WFD_OEM_WPS_MODE_PBC:
397 case WFD_OEM_WPS_MODE_DISPLAY:
398 return WS_STR_DISPLAY;
400 case WFD_OEM_WPS_MODE_KEYPAD:
401 return WS_STR_KEYPAD;
409 static int _ws_freq_to_channel(int freq)
411 if (freq < 2412 || freq > 5825 ||
412 (freq > 2484 && freq < 5180)) {
413 WDP_LOGE("Invalid parameter");
418 return 36 + (freq - 5180)/5;
419 else if (freq <= 2472)
420 return 1 + (freq - 2412)/5;
421 else if (freq == 2484)
427 gboolean _ws_util_execute_file(const char *file_path,
428 char *const args[], char *const envs[])
433 register unsigned int index = 0;
435 while (args[index] != NULL) {
436 WDP_LOGD("[%s]", args[index]);
440 if (!(pid = fork())) {
441 WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
442 WDP_LOGD("Inside child, exec (%s) command", file_path);
445 if (execve(file_path, args, envs) == -1) {
446 WDP_LOGE("Fail to execute command (%s)", strerror(errno));
449 } else if (pid > 0) {
450 if (waitpid(pid, &rv, 0) == -1)
451 WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
453 WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
454 } else if (WIFSIGNALED(rv)) {
455 WDP_LOGD("killed by signal %d", WTERMSIG(rv));
456 } else if (WIFSTOPPED(rv)) {
457 WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
458 } else if (WIFCONTINUED(rv)) {
459 WDP_LOGD("continued");
465 WDP_LOGE("failed to fork (%s)", strerror(errno));
469 static int _ws_check_socket(int sock)
475 p_fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL;
476 res = poll((struct pollfd *) &p_fd, 1, 1);
479 WDP_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
481 } else if (res == 0) {
482 WDP_LOGD( "poll timeout. socket is busy\n");
486 if (p_fd.revents & POLLERR) {
487 WDP_LOGE("Error! POLLERR from socket[%d]", sock);
489 } else if (p_fd.revents & POLLHUP) {
490 WDP_LOGE("Error! POLLHUP from socket[%d]", sock);
492 } else if (p_fd.revents & POLLNVAL) {
493 WDP_LOGE("Error! POLLNVAL from socket[%d]", sock);
495 } else if (p_fd.revents & POLLIN) {
496 WDP_LOGD("POLLIN from socket [%d]", sock);
498 } else if (p_fd.revents & POLLOUT) {
499 WDP_LOGD("POLLOUT from socket [%d]", sock);
504 WDP_LOGD("Unknown poll event [%d]", p_fd.revents);
508 static int _ws_read_sock(int sock, char *data, int data_len)
510 __WDP_LOG_FUNC_ENTER__;
515 if(sock < SOCK_FD_MIN || !data || data_len <= 0) {
516 WDP_LOGE("Invalid parameter");
521 p_fd.events = POLLIN | POLLERR | POLLHUP;
522 p_ret = poll(&p_fd, 1, WS_POLL_TIMEOUT);
526 if (p_fd.revents & POLLIN) {
527 WDP_LOGD("POLLIN from socket [%d]", sock);
529 rbytes = read(sock, data, data_len);
531 WDP_LOGE("Failed to read data from socket[%d]. [%s]", sock, strerror(errno));
534 data[data_len-1] = '\0';
535 __WDP_LOG_FUNC_EXIT__;
537 } else if (p_fd.revents & POLLERR) {
538 WDP_LOGE("Error! POLLERR from socket[%d]", sock);
540 } else if (p_fd.revents & POLLHUP) {
541 WDP_LOGE("Error! POLLHUP from socket[%d]", sock);
544 } else if (p_ret == 0) {
545 WDP_LOGE("Polling timeout from socket[%d]", sock);
547 WDP_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
550 __WDP_LOG_FUNC_EXIT__;
554 static int _ws_send_cmd(int sock, char *cmd, char *reply, int reply_len)
556 __WDP_LOG_FUNC_ENTER__;
560 if (sock < SOCK_FD_MIN || !cmd || !reply || reply_len < 0) {
561 WDP_LOGE("Invalid parameter");
564 WDP_SECLOGD("Sending command [%s]", cmd);
566 res = _ws_check_socket(sock);
568 WDP_LOGE("Socket error");
570 } else if (res > 0) {
571 WDP_LOGE("Socket is busy");
576 wbytes = write(sock, cmd, strlen(cmd));
578 WDP_LOGE("Failed to write into socket[%d]. [%s]", sock, strerror(errno));
582 res = _ws_read_sock(sock, reply, reply_len);
584 WDP_LOGE("Failed to read return for command");
585 __WDP_LOG_FUNC_EXIT__;
589 __WDP_LOG_FUNC_EXIT__;
593 static int _ws_flush()
595 __WDP_LOG_FUNC_ENTER__;
596 ws_sock_data_s *sock = g_pd->common;
597 char reply[1024]={0,};
601 WDP_LOGE("Socket is NULL");
605 res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_FLUSH, reply, sizeof(reply));
607 WDP_LOGE("Failed to send command to wpa_supplicant");
608 __WDP_LOG_FUNC_EXIT__;
612 if (strstr(reply, "FAIL")) {
613 WDP_LOGE("Failed to flush");
614 __WDP_LOG_FUNC_EXIT__;
617 WDP_LOGD("Succeeded to flush");
619 __WDP_LOG_FUNC_EXIT__;
623 static int _ws_cancel()
625 __WDP_LOG_FUNC_ENTER__;
626 ws_sock_data_s *sock = g_pd->common;
627 char reply[1024]={0,};
631 WDP_LOGE("Socket is NULL");
635 res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_CANCEL, reply, sizeof(reply));
637 WDP_LOGE("Failed to send command to wpa_supplicant");
638 __WDP_LOG_FUNC_EXIT__;
642 if (strstr(reply, "FAIL")) {
643 WDP_LOGE("Failed to cancel");
644 __WDP_LOG_FUNC_EXIT__;
647 WDP_LOGD("Succeeded to cancel");
649 __WDP_LOG_FUNC_EXIT__;
653 static int _create_ctrl_intf(char *ctrl_intf_path, char *supp_path)
655 __WDP_LOG_FUNC_ENTER__;
656 struct sockaddr_un srv_addr;
657 struct sockaddr_un local_addr;
661 if(!ctrl_intf_path || !supp_path) {
662 WDP_LOGE("Invalid parameter");
665 unlink(ctrl_intf_path);
668 sock = socket(AF_UNIX, SOCK_DGRAM, 0);
669 if (sock < SOCK_FD_MIN) {
670 WDP_LOGE("Failed to create socket. [%s]", strerror(errno));
673 __WDP_LOG_FUNC_EXIT__;
676 WDP_LOGI( "Succeeded to create socket [%d]\n", sock);
678 memset(&srv_addr, 0, sizeof(srv_addr));
679 srv_addr.sun_family = AF_UNIX;
680 snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", supp_path);
682 memset(&local_addr, 0, sizeof(local_addr));
683 local_addr.sun_family = AF_UNIX;
684 snprintf(local_addr.sun_path, sizeof(local_addr.sun_path), "%s", ctrl_intf_path);
686 res = bind(sock, (struct sockaddr*) &local_addr, sizeof(local_addr));
689 WDP_LOGE("Failed to bind local socket [%s]. Try again...", strerror(errno));
690 unlink(ctrl_intf_path);
693 __WDP_LOG_FUNC_EXIT__;
698 res = connect(sock, (struct sockaddr*) &srv_addr, sizeof(srv_addr));
700 WDP_LOGE("Failed to connect to server socket [%s]", strerror(errno));
702 __WDP_LOG_FUNC_EXIT__;
705 WDP_LOGI("Succeeded to connect to server socket [%d]", sock);
707 __WDP_LOG_FUNC_EXIT__;
711 static int _attach_mon_intf(int sock)
713 __WDP_LOG_FUNC_ENTER__;
718 if (sock < SOCK_FD_MIN) {
719 WDP_LOGE("Invalid parameter");
723 snprintf(cmd, sizeof(cmd), WS_CMD_ATTACH);
724 res = _ws_send_cmd(sock, cmd, reply, sizeof(reply));
726 WDP_LOGE("Failed to send command to wpa_supplicant");
727 __WDP_LOG_FUNC_EXIT__;
731 if (strstr(reply, "FAIL")) {
732 WDP_LOGE( "Failed to operate command(wpa_supplicant)");
733 __WDP_LOG_FUNC_EXIT__;
737 __WDP_LOG_FUNC_EXIT__;
741 static int _connect_to_supplicant(char *ifname, ws_sock_data_s **sock_data)
743 __WDP_LOG_FUNC_ENTER__;
744 ws_sock_data_s *sock = NULL;
747 char ctrl_path[32] = {0, };
748 char mon_path[32] = {0, };
749 char suppl_path[40] = {0, };
753 if (!ifname || !sock_data) {
754 WDP_LOGE("Invalie parameter");
755 __WDP_LOG_FUNC_EXIT__;
760 sock = (ws_sock_data_s*) calloc(1, sizeof(ws_sock_data_s));
762 WDP_LOGE("Failed to allocate memory for socket data", strerror(errno));
763 __WDP_LOG_FUNC_EXIT__;
767 snprintf(ctrl_path, sizeof(ctrl_path), "/tmp/%s_control", ifname);
768 snprintf(mon_path, sizeof(mon_path), "/tmp/%s_monitor", ifname);
769 if (strncmp(ifname, GROUP_IFACE_NAME, 11))
770 snprintf(suppl_path, sizeof(suppl_path), SUPPL_IFACE_PATH "%s", ifname);
772 snprintf(suppl_path, sizeof(suppl_path), SUPPL_GROUP_IFACE_PATH "%s", ifname);
775 for(i = 0; i < WS_CONN_RETRY_COUNT; i++) {
776 ctrl_sock = _create_ctrl_intf(ctrl_path, suppl_path);
777 if (ctrl_sock < SOCK_FD_MIN) {
778 WDP_LOGE("Failed to create control interface socket for %s", ifname);
781 WDP_LOGD("Succeeded to create control interface socket[%d] for %s", ctrl_sock, ifname);
783 mon_sock = _create_ctrl_intf(mon_path, suppl_path);
784 if (mon_sock < SOCK_FD_MIN) {
785 WDP_LOGE("Failed to create monitor interface socket for %s", ifname);
790 WDP_LOGD("Succeeded to create monitor interface socket[%d] for %s", mon_sock, ifname);
792 res = _attach_mon_intf(mon_sock);
794 WDP_LOGE("Failed to attach monitor interface for event");
801 WDP_LOGD("Succeeded to attach monitor interface for event");
805 if (i == WS_CONN_RETRY_COUNT) {
812 __WDP_LOG_FUNC_EXIT__;
816 sock->ctrl_sock = ctrl_sock;
817 sock->mon_sock = mon_sock;
818 sock->ifname = strdup(ifname);
822 gio = g_io_channel_unix_new(mon_sock);
823 if (!strstr(ifname, GROUP_IFACE_PREFIX))
824 gsource = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP, (GIOFunc) ws_event_handler, sock);
825 g_io_channel_unref(gio);
827 sock->gsource = gsource;
830 __WDP_LOG_FUNC_EXIT__;
834 static gboolean _remove_event_source(gpointer data)
836 __WDP_LOG_FUNC_ENTER__;
837 int source_id = (int) data;
841 WDP_LOGE("Invalid source ID [%d]", source_id);
845 res = g_source_remove(source_id);
847 WDP_LOGE("Failed to remove GSource(%d)", source_id);
850 WDP_LOGD("Succeeded to remove GSource");
852 __WDP_LOG_FUNC_EXIT__;
856 static int _disconnect_from_supplicant(char *ifname, ws_sock_data_s *sock_data)
858 __WDP_LOG_FUNC_ENTER__;
860 char ctrl_path[32] = {0, };
861 char mon_path[32] = {0, };
863 char reply[1024] = {0, };
865 if (!ifname || !sock_data) {
866 WDP_LOGE("Invalie parameter");
870 // detach monitor interface
871 snprintf(cmd, sizeof(cmd), WS_CMD_DETACH);
872 res = _ws_send_cmd(sock_data->mon_sock, cmd, reply, sizeof(reply));
874 WDP_LOGE("Failed to send command to wpa_supplicant. Keep going to close socket.");
876 if (!strncmp(reply, "FAIL", 4)) {
877 WDP_LOGE( "Failed to detach monitor sock [%d]", sock_data->mon_sock);
878 // TODO: I think there is no need to exit
879 __WDP_LOG_FUNC_EXIT__;
882 WDP_LOGD("Succeeded to detach monitor sock for %s", ifname ? ifname : "NULL");
885 if (sock_data->gsource > 0)
886 g_idle_add(_remove_event_source, (gpointer) sock_data->gsource);
887 sock_data->gsource = 0;
889 // close control interface
890 snprintf(ctrl_path, sizeof(ctrl_path), "/tmp/%s_control", ifname);
891 snprintf(mon_path, sizeof(mon_path), "/tmp/%s_monitor", ifname);
893 if (sock_data->ctrl_sock >= SOCK_FD_MIN)
894 close(sock_data->ctrl_sock);
895 sock_data->ctrl_sock = -1;
898 if (sock_data->mon_sock >= SOCK_FD_MIN)
899 close(sock_data->mon_sock);
900 sock_data->mon_sock = -1;
903 if (sock_data->ifname)
904 free(sock_data->ifname);
908 __WDP_LOG_FUNC_EXIT__;
912 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
913 int _check_service_query_exists(wfd_oem_service_s *service)
916 wfd_oem_service_s *data = NULL;
918 for (count = 0; count < g_list_length(service_list); count ++) {
919 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
920 if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
921 WDP_LOGD("Query already exists");
928 static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
930 if (NULL == s_type || NULL == mac_str || NULL == query_id)
934 wfd_oem_service_s *data = NULL;
936 for (count = 0; count < g_list_length(service_list); count ++) {
937 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
938 if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
939 memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
940 strncpy(query_id, data->query_id, OEM_QUERY_ID_LEN);
944 if (strlen(query_id) <= 0) {
945 WDP_LOGD("!! Query ID not found !!");
949 WDP_LOGD("query id :[0x%s]",query_id);
954 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
956 static int _extract_word(const char *data, char **value)
960 if(!data || !value) {
961 WDP_LOGE("Invalid parameter");
965 for(i = 0; data[i]; i++) {
966 if(data[i] == '\n' || data[i] == '\r' || data[i] == ' ' || data[i] == '\t') {
972 *value = (char*) calloc(1, i+1);
973 strncpy(*value, data, i);
975 WDP_LOGV("Extracted word: %s", *value);
981 static int _extract_value_str(const char *data, const char *key, char **value)
983 char *tmp_str = NULL;
986 if(!data || !key || !value) {
987 WDP_LOGE("Invalid parameter");
991 tmp_str = strstr(data, key);
993 WDP_LOGE("Key[%s] is not found", key);
996 tmp_str = tmp_str + strlen(key) + 1;
998 if (tmp_str[0] == '\'' || tmp_str[0] == '\"') {
1000 for(i = 0; tmp_str[i]; i++) {
1001 if(tmp_str[i] == '\'' || tmp_str[i] == '\"')
1005 for(i = 0; tmp_str[i]; i++) {
1006 if(tmp_str[i] == '\n' || tmp_str[i] == '\r' || tmp_str[i] == ' ')
1012 *value = (char*) calloc(1, i+1);
1013 strncpy(*value, tmp_str, i);
1015 WDP_LOGV("Extracted string: %s", *value);
1022 static int _extract_peer_value_str(const char *data, const char *key, char **value)
1024 char *tmp_str = NULL;
1027 if(!data || !key || !value) {
1028 WDP_LOGE("Invalid parameter");
1032 tmp_str = strstr(data, key);
1034 WDP_LOGE("Key[%s] is not found", key);
1037 tmp_str = tmp_str + strlen(key) + 1;
1039 for(i = 0; tmp_str[i]; i++) {
1040 if(tmp_str[i] == '\n' || tmp_str[i] == '\r')
1045 *value = (char*) calloc(1, i+1);
1046 strncpy(*value, tmp_str, i);
1048 WDP_LOGV("Extracted string: %s", *value);
1056 static int _check_dev_type(unsigned char *dev_addr, int *pri_dev_type, int *sec_dev_type)
1058 ws_sock_data_s *sock = g_pd->common;
1059 char cmd[32] = {0, };
1060 char reply[1024] = {0,};
1061 char *manufacturer = NULL;
1062 char *model_name = NULL;
1063 char *model_number = NULL;
1066 if (!dev_addr || !pri_dev_type || !sec_dev_type) {
1067 WDP_LOGE("Invalid parameter");
1072 WDP_LOGE("Socket is NULL");
1076 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER MACSTR, MAC2STR(dev_addr));
1077 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
1079 WDP_LOGE("Failed to send command to wpa_supplicant");
1080 __WDP_LOG_FUNC_EXIT__;
1084 if (strstr(reply, "FAIL")) {
1085 WDP_SECLOGD("Failed to get peer info [" MACSTR "]", MAC2STR(dev_addr));
1086 __WDP_LOG_FUNC_EXIT__;
1089 WDP_SECLOGD("Succeeded to get peer info [" MACSTR "]", MAC2STR(dev_addr));
1091 res = _extract_peer_value_str(reply, "model_number", &model_number);
1092 if (res > 0 && !strncmp(model_number, "EAD-T10", 7)) {
1096 WDP_LOGD("peer device type set as Dongle");
1102 _extract_peer_value_str(reply, "manufacturer", &manufacturer);
1103 _extract_peer_value_str(reply, "model_name", &model_name);
1104 if (!manufacturer || !model_name) {
1105 WDP_LOGE("parsing error");
1113 if (!strncmp(manufacturer, "SAMSUNG_ELECTRONICS", 19) &&
1114 !strncmp(model_name, "SAMSUNG_MOBILE", 14)) {
1117 WDP_LOGD("peer device type set as Homesync");
1131 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1132 static int _parsing_wfd_info(char *msg, wfd_oem_display_s *display )
1134 __WDP_LOG_FUNC_ENTER__;
1136 char wfd_info_msg[5] = {0, };
1137 char ctrl_port_msg[5] = {0, };
1138 char max_tput_msg[5] = {0, };
1140 if (!msg || strlen(msg) < 12) {
1141 WDP_LOGE("Invalid parameter");
1142 __WDP_LOG_FUNC_EXIT__;
1145 /*wfd_info_msg:0013 1c44 000a */
1146 WDP_LOGE("Message to parse: %s", msg);
1148 strncpy(wfd_info_msg, msg, 4);
1149 wfd_info = strtoul(wfd_info_msg, NULL, 16);
1151 if (wfd_info & WS_WFD_INFO_PRIMARY_SINK)
1152 display->type |= WS_WFD_INFO_PRIMARY_SINK;
1153 if (wfd_info & WS_WFD_INFO_SECONDARY_SINK)
1154 display->type |= WS_WFD_INFO_SECONDARY_SINK;
1156 display->availablity = (wfd_info & WS_WFD_INFO_AVAILABLITY) >> 4;
1157 display->hdcp_support = (wfd_info & WS_WFD_INFO_HDCP_SUPPORT) >> 8;
1159 strncpy(ctrl_port_msg, msg+4, 4);
1160 display->port = strtoul(ctrl_port_msg, NULL, 16);
1161 strncpy(max_tput_msg, msg+8, 4);
1162 display->max_tput = strtoul(max_tput_msg, NULL, 16);
1164 WDP_LOGE("type [%d],availablity [%d],hdcp_support [%d],ctrl_port [%d] max_tput[%d]",
1165 display->type,display->availablity,display->hdcp_support,
1166 display->port,display->max_tput);
1168 __WDP_LOG_FUNC_EXIT__;
1171 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1173 static int _parsing_peer_info(char *msg, wfd_oem_device_s *peer)
1175 __WDP_LOG_FUNC_ENTER__;
1176 int i, info_cnt = 0;
1177 ws_string_s infos[WS_PEER_INFO_LIMIT];
1178 int config_methods = 0x00;
1179 int group_capab = 0x00;
1182 if (!msg || !peer) {
1183 WDP_LOGE("Invalid parameter");
1187 _ws_txt_to_mac(msg, peer->dev_addr);
1188 msg += OEM_MACSTR_LEN;
1190 memset(infos, 0x0, (WS_PEER_INFO_LIMIT) * sizeof(ws_string_s));
1191 for (i = 0; i < WS_PEER_INFO_LIMIT; i++) {
1192 res = _extract_peer_value_str(msg, ws_peer_info_strs[i].string, &infos[info_cnt].string);
1194 infos[info_cnt].index = ws_peer_info_strs[i].index;
1199 for (i = 0; i < info_cnt; i++) {
1200 switch (infos[i].index){
1201 case WS_PEER_INFO_AGE:
1202 peer->age = (int) strtoul(infos[i].string, NULL, 10);
1204 case WS_PEER_INFO_LISTEN_FREQ:
1207 freq = (int) strtoul(infos[i].string, NULL, 10);
1208 peer->channel = _ws_freq_to_channel(freq);
1211 case WS_PEER_INFO_LEVEL:
1213 case WS_PEER_INFO_WPS_METHOD:
1215 case WS_PEER_INFO_INTERFACE_ADDR:
1217 case WS_PEER_INFO_MEMBER_IN_GO_DEV:
1219 res = _ws_txt_to_mac(infos[i].string, peer->go_dev_addr);
1221 memset(peer->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1223 if (memcmp(peer->go_dev_addr, null_mac, OEM_MACADDR_LEN))
1224 peer->dev_role = WFD_OEM_DEV_ROLE_GC;
1227 case WS_PEER_INFO_MEMBER_IN_GO_IFACE:
1229 case WS_PEER_INFO_PRI_DEV_TYPE:
1230 res = _ws_txt_to_devtype(infos[i].string, &peer->pri_dev_type, &peer->sec_dev_type);
1232 peer->pri_dev_type = 0;
1233 peer->sec_dev_type = 0;
1236 case WS_PEER_INFO_DEVICE_NAME:
1237 strncpy(peer->dev_name, infos[i].string, OEM_DEV_NAME_LEN);
1238 peer->dev_name[OEM_DEV_NAME_LEN] = '\0';
1240 case WS_PEER_INFO_MANUFACTURER:
1242 case WS_PEER_INFO_MODEL_NAME:
1244 case WS_PEER_INFO_MODEL_NUMBER:
1246 case WS_PEER_INFO_SERIAL_NUMBER:
1248 case WS_PEER_INFO_CONFIG_METHODS:
1249 config_methods = (int) strtoul(infos[i].string, NULL, 16);
1250 if (config_methods & WS_CONFIG_METHOD_DISPLAY)
1251 peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
1252 if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
1253 peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
1254 if (config_methods & WS_CONFIG_METHOD_KEYPAD)
1255 peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
1257 case WS_PEER_INFO_DEV_CAPAB:
1258 peer->dev_flags = (int) strtoul(infos[i].string, NULL, 16);
1260 case WS_PEER_INFO_GROUP_CAPAB:
1261 group_capab = (int) strtoul(infos[i].string, NULL, 16);
1262 if (group_capab & WS_GROUP_CAP_GROUP_OWNER) {
1263 peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
1264 peer->dev_role = WFD_OEM_DEV_ROLE_GO;
1266 if (group_capab & WS_GROUP_CAP_PERSISTENT_GROUP)
1267 peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1269 case WS_PEER_INFO_GO_NEG_REQ_SENT:
1271 case WS_PEER_INFO_GO_STATE:
1273 case WS_PEER_INFO_DIALOG_TOKEN:
1275 case WS_PEER_INFO_INTENDED_ADDR:
1276 res = _ws_txt_to_mac(infos[i].string, peer->intf_addr);
1278 memset(peer->intf_addr, 0x00, OEM_MACADDR_LEN);
1280 case WS_PEER_INFO_COUNTRY:
1282 case WS_PEER_INFO_OPER_FREQ:
1284 case WS_PEER_INFO_REQ_CONFIG_METHODS:
1286 case WS_PEER_INFO_FLAGS:
1288 case WS_PEER_INFO_STATUS:
1290 case WS_PEER_INFO_WAIT_COUNT:
1292 case WS_PEER_INFO_INVITATION_REQS:
1294 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1295 case WS_PEER_INFO_WFD_SUBELEMS:
1296 res = _parsing_wfd_info(infos[i].string+6,&peer->display);
1298 memset(&peer->display, 0x00, sizeof(wfd_oem_display_s));
1300 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1306 for(i = 0; i < info_cnt; i++) {
1307 if (infos[i].string)
1308 free(infos[i].string);
1311 __WDP_LOG_FUNC_EXIT__;
1315 static wfd_oem_dev_data_s *_convert_msg_to_dev_info(char *msg)
1317 __WDP_LOG_FUNC_ENTER__;
1320 ws_string_s infos[WS_DEV_INFO_LIMIT];
1321 wfd_oem_dev_data_s *edata = NULL;
1322 int config_methods = 0x00;
1323 int group_capab = 0x00;
1327 WDP_LOGE("Invalid parameter");
1330 WDP_SECLOGD("msg to be converted [%s]", msg);
1332 memset(infos, 0x0, (WS_DEV_INFO_LIMIT) * sizeof(ws_string_s));
1333 for (i = 0; ws_dev_info_strs[i].index < WS_DEV_INFO_LIMIT; i++) {
1334 res = _extract_value_str(msg, ws_dev_info_strs[i].string, &infos[info_cnt].string);
1336 infos[info_cnt].index = ws_dev_info_strs[i].index;
1337 if (infos[info_cnt].index == WS_DEV_INFO_P2P_DEV_ADDR)
1338 WDP_SECLOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
1340 WDP_LOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
1346 WDP_LOGE("There is no item converted");
1351 edata = (wfd_oem_dev_data_s*) calloc(1, sizeof(wfd_oem_dev_data_s));
1353 WDP_LOGE("Failed to allocate memory for device information [%s]", strerror(errno));
1357 for (i = 0; i < info_cnt; i++) {
1358 switch (infos[i].index) {
1359 case WS_DEV_INFO_P2P_DEV_ADDR:
1360 res = _ws_txt_to_mac(infos[i].string, edata->p2p_dev_addr);
1362 memset(edata->p2p_dev_addr, 0x00, OEM_MACADDR_LEN);
1364 case WS_DEV_INFO_DEV_NAME:
1365 strncpy(edata->name, infos[i].string, OEM_DEV_NAME_LEN);
1366 edata->name[OEM_DEV_NAME_LEN] = '\0';
1368 case WS_DEV_INFO_DEV_TYPE:
1369 res = _ws_txt_to_devtype(infos[i].string, &edata->pri_dev_type, &edata->sec_dev_type);
1371 edata->pri_dev_type = 0;
1372 edata->sec_dev_type = 0;
1375 case WS_DEV_INFO_CONFIG_METHODS:
1376 config_methods = (int) strtoul(infos[i].string, NULL, 16);
1377 if (config_methods & WS_CONFIG_METHOD_DISPLAY)
1378 edata->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
1379 if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
1380 edata->config_methods |= WFD_OEM_WPS_MODE_PBC;
1381 if (config_methods & WS_CONFIG_METHOD_KEYPAD)
1382 edata->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
1384 case WS_DEV_INFO_DEV_CAP:
1385 edata->dev_flags = (int) strtoul(infos[i].string, NULL, 16);
1387 case WS_DEV_INFO_GROUP_CAP:
1388 group_capab = (int) strtoul(infos[i].string, NULL, 16);
1389 if (group_capab & WS_GROUP_CAP_GROUP_OWNER) {
1390 edata->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
1391 edata->dev_role = WFD_OEM_DEV_ROLE_GO;
1393 if (group_capab & WS_GROUP_CAP_PERSISTENT_GROUP)
1394 edata->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1396 case WS_DEV_INFO_P2P_GO_ADDR:
1397 edata->dev_role = WFD_OEM_DEV_ROLE_GC;
1398 res = _ws_txt_to_mac(infos[i].string, edata->p2p_go_addr);
1400 memset(edata->p2p_go_addr, 0x00, OEM_MACADDR_LEN);
1402 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1403 case WS_DEV_INFO_WFD_DEV_INFO:
1404 /* wfd_dev_info=0x00 0006 015d 022a0032 */
1405 res = _parsing_wfd_info(infos[i].string+2,&edata->display);
1407 memset(&edata->display, 0x00, sizeof(wfd_oem_display_s));
1409 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1412 WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1415 if (infos[i].string)
1416 free(infos[i].string);
1419 __WDP_LOG_FUNC_EXIT__;
1423 static wfd_oem_conn_data_s *_convert_msg_to_conn_info(char *msg)
1425 __WDP_LOG_FUNC_ENTER__;
1428 ws_string_s infos[WS_CONN_INFO_LIMIT];
1429 wfd_oem_conn_data_s *edata = NULL;
1434 WDP_LOGE("Invalid parameter");
1437 WDP_LOGD("msg to convert [%s]", msg);
1439 memset(infos, 0x0, (WS_CONN_INFO_LIMIT) * sizeof(ws_string_s));
1440 for (i = 0; ws_conn_info_strs[i].index < WS_CONN_INFO_LIMIT; i++) {
1441 res = _extract_value_str(msg, ws_conn_info_strs[i].string, &infos[info_cnt].string);
1443 infos[info_cnt].index = ws_conn_info_strs[i].index;
1449 WDP_LOGE("There is no item converted");
1454 edata = (wfd_oem_conn_data_s*) calloc(1, sizeof(wfd_oem_conn_data_s));
1456 WDP_LOGE("Failed to allocate memory for connection information [%s]", strerror(errno));
1460 for (i = 0; i < info_cnt; i++) {
1461 switch (infos[i].index) {
1462 case WS_CONN_INFO_DEV_PWD_ID:
1463 dev_pwd_id = atoi(infos[i].string);
1464 if (dev_pwd_id == WS_DEV_PASSWD_ID_PUSH_BUTTON)
1465 edata->wps_mode = WFD_OEM_WPS_MODE_PBC;
1466 else if (dev_pwd_id == WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED)
1467 edata->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1468 else if (dev_pwd_id == WS_DEV_PASSWD_ID_USER_SPECIFIED)
1469 edata->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1471 edata->wps_mode = WFD_OEM_WPS_MODE_NONE;
1473 case WS_CONN_INFO_STATUS:
1474 edata->status = atoi(infos[i].string);
1476 case WS_CONN_INFO_ERROR:
1477 edata->error = atoi(infos[i].string);
1480 WDP_LOGE("Unknown information [%d:%s]", infos[i].index, infos[i].string);
1483 if (infos[i].string)
1484 free(infos[i].string);
1487 __WDP_LOG_FUNC_EXIT__;
1491 static wfd_oem_invite_data_s *_convert_msg_to_invite_info(char *msg)
1493 __WDP_LOG_FUNC_ENTER__;
1496 ws_string_s infos[WS_INVITE_INFO_LIMIT];
1497 wfd_oem_invite_data_s *edata = NULL;
1501 WDP_LOGE("Invalid parameter");
1504 WDP_LOGD("msg to convert [%s]", msg);
1506 memset(infos, 0x0, (WS_INVITE_INFO_LIMIT) * sizeof(ws_string_s));
1507 for (i = 0; ws_invite_info_strs[i].index < WS_INVITE_INFO_LIMIT; i++) {
1508 res = _extract_value_str(msg, ws_invite_info_strs[i].string, &infos[info_cnt].string);
1510 infos[info_cnt].index = ws_invite_info_strs[i].index;
1516 WDP_LOGE("There is no item converted");
1521 edata = (wfd_oem_invite_data_s*) calloc(1, sizeof(wfd_oem_invite_data_s));
1523 WDP_LOGE("Failed to allocate memory for invite information [%s]", strerror(errno));
1527 for (i = 0; i < info_cnt; i++) {
1528 switch (infos[i].index) {
1529 case WS_INVITE_INFO_GO_DEV_ADDR:
1530 res = _ws_txt_to_mac(infos[i].string, edata->go_dev_addr);
1532 memset(edata->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1534 case WS_INVITE_INFO_BSSID:
1535 res = _ws_txt_to_mac(infos[i].string, edata->bssid);
1537 memset(edata->bssid, 0x00, OEM_MACADDR_LEN);
1539 case WS_INVITE_INFO_LISTEN:
1540 edata->listen = atoi(infos[i].string);
1542 case WS_INVITE_INFO_STATUS:
1543 edata->status = atoi(infos[i].string);
1546 WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1549 if (infos[i].string)
1550 free(infos[i].string);
1553 __WDP_LOG_FUNC_EXIT__;
1557 static wfd_oem_group_data_s *_convert_msg_to_group_info(char *msg)
1559 __WDP_LOG_FUNC_ENTER__;
1562 ws_string_s infos[WS_GROUP_INFO_LIMIT];
1563 wfd_oem_group_data_s *edata = NULL;
1567 WDP_LOGE("Invalid parameter");
1570 WDP_LOGD("msg to convert [%s]", msg);
1572 memset(infos, 0x0, WS_GROUP_INFO_LIMIT * sizeof(ws_string_s));
1573 for (i = 0; ws_group_info_strs[i].index < WS_GROUP_INFO_LIMIT; i++) {
1574 res = _extract_value_str(msg, ws_group_info_strs[i].string, &infos[info_cnt].string);
1576 infos[info_cnt].index = ws_group_info_strs[i].index;
1582 WDP_LOGE("There is no item converted");
1587 edata = (wfd_oem_group_data_s*) calloc(1, sizeof(wfd_oem_group_data_s));
1589 WDP_LOGE("Failed to allocate memory for group information [%s]", strerror(errno));
1593 for (i = 0; i < info_cnt; i++) {
1594 switch (infos[i].index) {
1595 case WS_GROUP_INFO_SSID:
1596 strncpy(edata->ssid, infos[i].string, OEM_DEV_NAME_LEN);
1597 edata->ssid[OEM_DEV_NAME_LEN] = '\0';
1599 case WS_GROUP_INFO_FREQ:
1600 edata->freq = atoi(infos[i].string);
1602 case WS_GROUP_INFO_PASS:
1603 strncpy(edata->pass, infos[i].string, OEM_PASS_PHRASE_LEN);
1604 edata->pass[OEM_PASS_PHRASE_LEN] = '\0';
1606 case WS_GROUP_INFO_GO_DEV_ADDR:
1607 res = _ws_txt_to_mac(infos[i].string, edata->go_dev_addr);
1609 memset(edata->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1612 WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1615 if (infos[i].string)
1616 free(infos[i].string);
1619 __WDP_LOG_FUNC_EXIT__;
1623 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1624 static int _ws_segment_to_service(char *segment, wfd_oem_new_service_s **service)
1626 wfd_oem_new_service_s *serv_tmp = NULL;
1632 if (!segment || !service) {
1633 WDP_LOGE("Invalid parameter");
1638 WDP_LOGD("Segment: %s", segment);
1640 serv_tmp = (wfd_oem_new_service_s*) calloc(1, sizeof(wfd_oem_new_service_s));
1642 WDP_LOGE("Failed to allocate memory for service");
1646 serv_tmp->protocol = _ws_hex_to_num(ptr, 2);
1647 serv_tmp->trans_id = _ws_hex_to_num(ptr+2, 2);
1648 serv_tmp->status = _ws_hex_to_num(ptr+4, 2);
1650 WDP_LOGD("Protocol[%d], Transaction ID[%d], Status[%d]", serv_tmp->protocol, serv_tmp->trans_id, serv_tmp->status);
1652 if (serv_tmp->status != 0) {
1653 WDP_LOGE("Service status is not success");
1658 if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
1659 WDP_LOGD("===== Bonjour service =====");
1660 char compr[5] = {0, };
1661 char query[256] = {0, };
1662 char rdata[256] = {0, };
1665 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
1666 len = _ws_hex_to_num(ptr, 2);
1669 temp = (char*) calloc(1, len+2);
1671 for (i=0; i<len; i++) {
1672 temp[i+1] = (char) _ws_hex_to_num(ptr, 2);
1675 strncat(query, temp, len+1);
1681 if (!strncmp(ptr, "c0", 2)) {
1682 memcpy(compr, ptr, 4);
1685 if (!strncmp(ptr, "27", 2)) {
1686 WDP_LOGD("Segment ended");
1690 dns_type = _ws_hex_to_num(ptr, 4);
1692 if (dns_type == 12) {
1693 if (!strncmp(compr, "c011", 4))
1694 strncat(query, ".local.", 7);
1695 else if (!strncmp(compr, "c00c", 4))
1696 strncat(query, "._tcp.local.", 12);
1697 else if (!strncmp(compr, "c01c", 4))
1698 strncat(query, "._udp.local.", 12);
1702 serv_tmp->data.bonjour.query = strdup(query + 1);
1703 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
1704 len = _ws_hex_to_num(ptr, 2);
1707 temp = (char*) calloc(1, len+2);
1709 for (i=0; i<len; i++) {
1710 temp[i+1] = (char) _ws_hex_to_num(ptr, 2);
1713 strncat(rdata, temp, len+1);
1718 serv_tmp->data.bonjour.rdata = strdup(rdata + 1);
1720 WDP_LOGD("Query: %s", serv_tmp->data.bonjour.query);
1721 WDP_LOGD("RData: %s", serv_tmp->data.bonjour.rdata);
1722 } else if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_VENDOR) {
1723 WDP_LOGD("===== Vendor specific service =====");
1724 if (!strncmp(ptr, "0000f00b", 8)) {
1725 WDP_LOGD("\tSAMSUNG_BT_ADDR");
1727 serv_tmp->protocol = WFD_OEM_SERVICE_TYPE_BT_ADDR;
1728 serv_tmp->data.vendor.data1 = (char*) calloc(1, 9);
1729 g_strlcpy(serv_tmp->data.vendor.data1, "0000f00b", 9);
1730 serv_tmp->data.vendor.data2 = (char*) calloc(1, 18);
1731 _ws_hex_to_txt(ptr, 0, serv_tmp->data.vendor.data2);
1733 WDP_LOGD("Info1: %s", serv_tmp->data.vendor.data1);
1734 WDP_LOGD("Info2: %s", serv_tmp->data.vendor.data2);
1736 WDP_LOGE("Not supported yet. Only bonjour and samsung vendor service supproted [%d]",
1737 serv_tmp->protocol);
1742 *service = serv_tmp;
1746 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1748 static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
1750 __WDP_LOG_FUNC_ENTER__;
1753 char *info_str = NULL;
1755 if (!msg || !data) {
1756 WDP_LOGE("Invalid parameter");
1757 __WDP_LOG_FUNC_EXIT__;
1760 WDP_SECLOGD("Event message [%s]", msg);
1762 // parsing event string
1763 for(i = 0; ws_event_strs[i].index < WS_EVENT_LIMIT; i++) {
1764 if (!strncmp(ws_event_strs[i].string, msg, strlen(ws_event_strs[i].string))) {
1769 if (i == sizeof(ws_event_strs)) {
1770 WDP_LOGE("Unknown event [%d]", WS_EVENT_LIMIT);
1771 data->event_id = WS_EVENT_LIMIT;
1774 data->event_id = ws_event_strs[i].index;
1775 WDP_LOGD("Event ID [%d]", data->event_id);
1777 // parsing event info
1778 info_str = msg + strlen(ws_event_strs[i].string) + 1;
1779 if (!strlen(info_str)) {
1780 WDP_LOGD("Nothing to parse anymore");
1781 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1782 __WDP_LOG_FUNC_EXIT__;
1786 switch (data->event_id) {
1787 case WS_EVENT_DEVICE_FOUND:
1789 _ws_txt_to_mac(info_str, data->dev_addr);
1790 info_str += OEM_MACSTR_LEN;
1792 wfd_oem_dev_data_s *edata = NULL;
1793 edata = _convert_msg_to_dev_info(info_str);
1795 WDP_LOGE("Failed to convert information string to device data");
1796 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1800 if (edata->dev_role == WFD_OEM_DEV_ROLE_GO) {
1801 memcpy(edata->p2p_intf_addr, data->dev_addr, OEM_MACADDR_LEN);
1802 memcpy(data->dev_addr, edata->p2p_dev_addr, OEM_MACADDR_LEN);
1804 data->edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1805 data->edata = (void*) edata;
1809 case WS_EVENT_PROV_DISC_PBC_REQ:
1810 case WS_EVENT_PROV_DISC_SHOW_PIN:
1811 case WS_EVENT_PROV_DISC_ENTER_PIN:
1812 case WS_EVENT_PROV_DISC_PBC_RESP:
1814 _ws_txt_to_mac(info_str, data->dev_addr);
1815 info_str += OEM_MACSTR_LEN;
1817 if (data->event_id == WS_EVENT_PROV_DISC_PBC_REQ ||
1818 data->event_id == WS_EVENT_PROV_DISC_PBC_RESP) {
1819 data->wps_mode = WFD_OEM_WPS_MODE_PBC;
1820 } else if (data->event_id == WS_EVENT_PROV_DISC_ENTER_PIN) {
1821 data->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1822 } else if (data->event_id == WS_EVENT_PROV_DISC_SHOW_PIN) {
1823 data->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1824 strncpy(data->wps_pin, info_str, OEM_PINSTR_LEN);
1825 data->wps_pin[OEM_PINSTR_LEN] = '\0';
1826 info_str += OEM_PINSTR_LEN +1;
1829 WDP_LOGD("info string left [%s]", info_str ? info_str:"NULL");
1831 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1835 case WS_EVENT_DEVICE_LOST:
1837 char *temp_mac = NULL;
1838 res = _extract_value_str(info_str, "p2p_dev_addr", &temp_mac);
1840 WDP_LOGE("Failed to extract device address");
1843 _ws_txt_to_mac(temp_mac, data->dev_addr);
1846 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1849 case WS_EVENT_FIND_STOPED:
1851 case WS_EVENT_GO_NEG_REQUEST:
1853 _ws_txt_to_mac(info_str, data->dev_addr);
1854 info_str += OEM_MACSTR_LEN;
1856 if (!strlen(info_str)) {
1857 WDP_LOGD("Nothing to parse anymore");
1858 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1862 wfd_oem_conn_data_s *edata = NULL;
1863 edata = _convert_msg_to_conn_info(info_str);
1865 WDP_LOGE("Failed to convert information string to connection data");
1866 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1869 data->edata_type = WFD_OEM_EDATA_TYPE_CONN;
1870 data->edata = (void*) edata;
1873 case WS_EVENT_PROV_DISC_FAILURE:
1874 case WS_EVENT_WPS_FAIL: // M_id(msg), error(config_error)
1876 case WS_EVENT_GO_NEG_FAILURE:
1878 wfd_oem_conn_data_s *edata = NULL;
1879 edata = _convert_msg_to_conn_info(info_str);
1881 WDP_LOGE("Failed to convert information string to connection data");
1882 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1885 data->edata_type = WFD_OEM_EDATA_TYPE_CONN;
1886 data->edata = (void*) edata;
1889 case WS_EVENT_GROUP_FORMATION_FAILURE: // No incofmation sring
1890 case WS_EVENT_GO_NEG_SUCCESS:
1891 case WS_EVENT_WPS_SUCCESS:
1892 case WS_EVENT_GROUP_FORMATION_SUCCESS:
1893 /* No information string */
1894 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1896 case WS_EVENT_WPS_REG_SUCCESS: // "intf_addr"
1897 /* Interface address of peer will come up */
1899 case WS_EVENT_CONNECTED: // intf_addr(to)
1901 /* Interface address of connected peer will come up */
1902 char *temp_mac = NULL;
1903 res = _extract_value_str(info_str, "to", &temp_mac);
1905 WDP_LOGE("Failed to extract interface address");
1908 _ws_txt_to_mac(temp_mac, data->intf_addr);
1911 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1914 case WS_EVENT_DISCONNECTED:
1916 /* Interface address of disconnected peer will come up */
1917 char *temp_mac = NULL;
1918 res = _extract_value_str(info_str, "bssid", &temp_mac);
1920 WDP_LOGE("Failed to extract interface address");
1923 _ws_txt_to_mac(temp_mac, data->intf_addr);
1926 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1929 case WS_EVENT_STA_CONNECTED: // "intf_addr", dev_addr(dev_addr)
1930 case WS_EVENT_STA_DISCONNECTED:
1932 /* Interface address of connected peer will come up */
1933 _ws_txt_to_mac(info_str, data->intf_addr);
1935 char *temp_mac = NULL;
1936 res = _extract_value_str(info_str, "p2p_dev_addr", &temp_mac);
1938 WDP_LOGE("Failed to extract interface address");
1941 _ws_txt_to_mac(temp_mac, data->dev_addr);
1944 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1947 case WS_EVENT_INVITATION_RECEIVED:
1948 case WS_EVENT_INVITATION_RESULT:
1950 char *peer_addr_str = NULL;
1951 res = _extract_value_str(info_str, "sa", &peer_addr_str);
1952 if (res == 17/*(OEM_MACSTR_LEN-1)*/) {
1953 _ws_txt_to_mac(peer_addr_str, data->dev_addr);
1955 free(peer_addr_str);
1956 } else if (res < 0) {
1957 WDP_LOGE("Failed to extract source address");
1959 WDP_LOGE("Wrong source address");
1960 free(peer_addr_str);
1963 if (!strlen(info_str)) {
1964 WDP_LOGD("Nothing to parse anymore");
1965 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1969 wfd_oem_invite_data_s* edata = NULL;
1970 edata = _convert_msg_to_invite_info(info_str);
1972 WDP_LOGE("Failed to convert information string to invite data");
1973 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1977 data->edata_type = WFD_OEM_EDATA_TYPE_INVITE;
1978 data->edata = (void*) edata;
1982 case WS_EVENT_GROUP_STARTED:
1983 case WS_EVENT_GROUP_REMOVED:
1985 char *ifname_str = NULL;
1986 res = _extract_word(info_str, &ifname_str);
1988 WDP_LOGE("Failed to extract event param string");
1989 } else if (res == 0) {
1990 WDP_LOGE("Nothing extracted");
1995 WDP_LOGE("Parsing error(interface name)");
1998 strncpy(data->ifname, ifname_str, OEM_IFACE_NAME_LEN);
1999 data->ifname[OEM_IFACE_NAME_LEN] = '\0';
2001 info_str += strlen(ifname_str) + 1;
2006 char *dev_role_str = NULL;
2007 res = _extract_word(info_str, &dev_role_str);
2009 WDP_LOGE("Failed to extract event param string");
2010 } else if (res == 0) {
2011 WDP_LOGE("Nothing extracted");
2015 if (!dev_role_str) {
2016 WDP_LOGE("Parsing error(device role)");
2019 if (!strncmp(dev_role_str, "GO", 2))
2020 data->dev_role = WFD_OEM_DEV_ROLE_GO;
2021 else if (!strncmp(dev_role_str, "client", 6))
2022 data->dev_role = WFD_OEM_DEV_ROLE_GC;
2024 WDP_LOGE("Unknown device role [%s]", dev_role_str);
2026 info_str += strlen(dev_role_str) + 1;
2031 if (!strlen(info_str)) {
2032 WDP_LOGD("Nothing to parse anymore");
2033 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
2037 wfd_oem_group_data_s* edata = NULL;
2038 edata= _convert_msg_to_group_info(info_str);
2040 WDP_LOGE("Failed to convert information string to group data");
2041 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
2045 data->edata_type = WFD_OEM_EDATA_TYPE_GROUP;
2046 data->edata = (void*) edata;
2050 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
2051 case WS_EVENT_SERV_DISC_RESP:
2053 char mac_addr[OEM_MACSTR_LEN] ={0, };
2054 char *up_indic = NULL;
2057 _ws_txt_to_mac(info_str, data->dev_addr);
2058 info_str += OEM_MACSTR_LEN;
2059 snprintf(mac_addr, OEM_MACSTR_LEN, MACSTR, MAC2STR(data->dev_addr));
2061 _extract_word(info_str, &up_indic);
2063 WDP_LOGD("Update indicator: %s", up_indic);
2064 info_str += strlen(up_indic) + 1;
2067 WDP_LOGD("Info string [%s]", info_str);
2069 char seglen_str[5] = {0, };
2070 char *segment = NULL;
2071 char *ptr = info_str;
2072 GList *services = NULL;
2073 wfd_oem_new_service_s *new_service = NULL;
2076 while (*ptr != '\0') {
2077 _change_str_order(ptr, 4, 2, seglen_str);
2078 len = strtoul(seglen_str, NULL, 16);
2081 segment = (char*) calloc(1, len*2+1);
2082 memcpy(segment, ptr+4, len*2);
2083 ptr = ptr + 4 + len*2;
2084 res = _ws_segment_to_service(segment, &new_service);
2086 WDP_LOGE("Failed to convert segment as service instance");
2091 services = g_list_append(services, new_service);
2096 data->edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
2097 data->dev_role = count;
2098 data->edata = (void*) services;
2101 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
2104 WDP_LOGE("Unknown event");
2108 __WDP_LOG_FUNC_EXIT__;
2112 static gboolean ws_event_handler(GIOChannel *source,
2113 GIOCondition condition,
2116 __WDP_LOG_FUNC_ENTER__;
2117 ws_sock_data_s * sd = (ws_sock_data_s*) data;
2118 char msg[1024] = {0, };
2122 wfd_oem_event_s *event = NULL;
2126 WDP_LOGE("Invalid parameter");
2127 // TODO: if error count is more than 10, disconnect this interface and reset sock data
2131 res = _ws_read_sock(sd->mon_sock, msg, sizeof(msg));
2133 WDP_LOGE("Failed to read socket. [%d]", sd->mon_sock);
2138 event = (wfd_oem_event_s*) calloc(1, sizeof(wfd_oem_event_s));
2140 WDP_LOGE("Failed to allocate memory for event. [%s]", strerror(errno));
2144 if (!strncmp(msg, "IFNAME", 6)) {
2145 pos = strchr(msg, ' ');
2151 res = _parsing_event_info(sd->ifname, param, event);
2153 WDP_LOGE("Failed to parse event string");
2159 // This means event->event_data is NULL
2162 /* Converting WS event to OEM event */
2163 switch (event->event_id) {
2164 case WS_EVENT_DEVICE_FOUND:
2165 event_id = WFD_OEM_EVENT_PEER_FOUND;
2167 case WS_EVENT_DEVICE_LOST:
2168 event_id = WFD_OEM_EVENT_PEER_DISAPPEARED;
2170 case WS_EVENT_FIND_STOPED:
2171 event_id = WFD_OEM_EVENT_DISCOVERY_FINISHED;
2173 case WS_EVENT_PROV_DISC_PBC_REQ:
2174 event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
2176 case WS_EVENT_PROV_DISC_PBC_RESP:
2177 if (!memcmp(event->dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
2178 event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
2179 memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
2181 WDP_LOGE("Invalid peer mac address[" MACSTR "]", MAC2STR(event->dev_addr));
2185 case WS_EVENT_PROV_DISC_SHOW_PIN:
2186 case WS_EVENT_PROV_DISC_ENTER_PIN:
2187 if (!memcmp(event->dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
2188 event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
2189 memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
2190 WDP_LOGD("Peer mac address verified");
2191 } else if (!memcmp(g_pd_out, null_mac, OEM_MACADDR_LEN)) {
2192 event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
2193 WDP_LOGD(" PD request from peer[" MACSTR "]", MAC2STR(event->dev_addr));
2195 WDP_LOGE("Invalid peer mac address[" MACSTR "]", MAC2STR(event->dev_addr));
2200 case WS_EVENT_PROV_DISC_FAILURE:
2201 event_id = WFD_OEM_EVENT_PROV_DISC_FAIL;
2202 if (!memcmp(event->dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
2203 memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
2204 WDP_LOGD("Peer mac address verified, but PD failed");
2207 case WS_EVENT_GO_NEG_REQUEST:
2208 event_id = WFD_OEM_EVENT_GO_NEG_REQ;
2210 case WS_EVENT_GO_NEG_FAILURE:
2211 event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
2213 case WS_EVENT_GO_NEG_SUCCESS:
2214 event_id = WFD_OEM_EVENT_GO_NEG_DONE;
2216 case WS_EVENT_WPS_FAIL:
2217 case WS_EVENT_GROUP_FORMATION_FAILURE:
2218 event_id = WFD_OEM_EVENT_WPS_FAIL;
2220 case WS_EVENT_WPS_SUCCESS:
2221 case WS_EVENT_WPS_REG_SUCCESS:
2222 case WS_EVENT_GROUP_FORMATION_SUCCESS:
2223 event_id = WFD_OEM_EVENT_WPS_DONE;
2224 // TODO: connect to supplicant via group interface
2226 case WS_EVENT_CONNECTED:
2227 if (!memcmp(event->intf_addr, null_mac, OEM_MACADDR_LEN))
2229 event_id = WFD_OEM_EVENT_CONNECTED;
2231 case WS_EVENT_STA_CONNECTED:
2232 event_id = WFD_OEM_EVENT_STA_CONNECTED;
2234 case WS_EVENT_GROUP_STARTED:
2235 event_id = WFD_OEM_EVENT_GROUP_CREATED;
2236 res = _connect_to_supplicant(GROUP_IFACE_NAME, &g_pd->group);
2238 WDP_LOGE("Failed to connect to group interface of supplicant");
2242 case WS_EVENT_GROUP_REMOVED:
2243 event_id = WFD_OEM_EVENT_GROUP_DESTROYED;
2245 res = _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
2247 WDP_LOGE("Failed to disconnect from group interface of supplicant");
2253 case WS_EVENT_INVITATION_RECEIVED:
2254 event_id = WFD_OEM_EVENT_INVITATION_REQ;
2256 case WS_EVENT_INVITATION_RESULT:
2257 event_id = WFD_OEM_EVENT_INVITATION_RES;
2259 case WS_EVENT_DISCONNECTED:
2260 if (!memcmp(event->intf_addr, null_mac, OEM_MACADDR_LEN))
2262 event_id = WFD_OEM_EVENT_DISCONNECTED;
2264 case WS_EVENT_STA_DISCONNECTED:
2265 event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
2267 case WS_EVENT_TERMINATING:
2268 event_id = WFD_OEM_EVENT_DEACTIVATED;
2270 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
2271 case WS_EVENT_SERV_DISC_RESP:
2272 event_id = WFD_OEM_EVENT_SERV_DISC_RESP;
2274 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
2276 WDP_LOGD("Unknown event [%d]", event->event_id);
2280 event->event_id = event_id;
2281 g_pd->callback(g_pd->user_data, event);
2285 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
2286 if (event->edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE)
2287 g_list_free((GList*) event->edata);
2289 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
2294 __WDP_LOG_FUNC_EXIT__;
2298 static int _ws_reset_plugin(ws_plugin_data_s *pd)
2300 __WDP_LOG_FUNC_ENTER__;
2303 WDP_LOGE("Invalid parameter");
2304 __WDP_LOG_FUNC_EXIT__;
2309 ws_deactivate(g_pd->concurrent);
2313 __WDP_LOG_FUNC_EXIT__;
2318 static int __ws_check_net_interface(char* if_name)
2323 if (if_name == NULL) {
2324 WDP_LOGE("Invalid param");
2328 fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2330 WDP_LOGE("socket create error: %d", fd);
2334 memset(&ifr, 0, sizeof(ifr));
2335 strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
2336 ifr.ifr_name[IFNAMSIZ-1] = '\0';
2338 if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
2340 WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s", strerror(errno)); // interface is not found..
2346 if (ifr.ifr_flags & IFF_UP) {
2347 WDP_LOGD("%s interface is up", if_name);
2349 } else if (!(ifr.ifr_flags & IFF_UP)) {
2350 WDP_LOGD("%s interface is down", if_name);
2356 int ws_init(wfd_oem_event_cb callback, void *user_data)
2358 __WDP_LOG_FUNC_ENTER__;
2361 _ws_reset_plugin(g_pd);
2364 g_pd = (ws_plugin_data_s*) calloc(1, sizeof(ws_plugin_data_s));
2366 WDP_LOGE("Failed to allocate memory for plugin data. [%s]", strerror(errno));
2370 g_pd->callback = callback;
2371 g_pd->user_data = user_data;
2372 g_pd->initialized = TRUE;
2374 __WDP_LOG_FUNC_EXIT__;
2380 __WDP_LOG_FUNC_ENTER__;
2383 _ws_reset_plugin(g_pd);
2387 __WDP_LOG_FUNC_EXIT__;
2391 static int __ws_p2p_firmware_start(void)
2393 GError *error = NULL;
2394 GVariant *reply = NULL;
2395 GVariant *param = NULL;
2396 GDBusConnection *connection = NULL;
2397 const char *device = "p2p";
2399 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
2400 if (connection == NULL) {
2402 WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
2404 g_error_free(error);
2406 __WDP_LOG_FUNC_EXIT__;
2409 param = g_variant_new("(s)", device);
2411 reply = g_dbus_connection_call_sync (connection,
2412 NETCONFIG_SERVICE, /* bus name */
2413 NETCONFIG_WIFI_PATH, /* object path */
2414 NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
2415 "Start", /* method name */
2416 param, /* GVariant *params */
2417 NULL, /* reply_type */
2418 G_DBUS_CALL_FLAGS_NONE, /* flags */
2419 NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
2420 NULL, /* cancellable */
2421 &error); /* error */
2424 if(strstr(error->message, ".AlreadyExists") != NULL) {
2425 WDP_LOGD("p2p already enabled");
2426 g_error_free(error);
2429 WDP_LOGE("Error! Failed to call net-config method: [%s]",
2431 g_error_free(error);
2433 g_variant_unref(reply);
2434 g_object_unref(connection);
2435 __WDP_LOG_FUNC_EXIT__;
2440 g_variant_unref(reply);
2441 g_object_unref(connection);
2445 static int __ws_p2p_firmware_stop(void)
2447 GError *error = NULL;
2448 GVariant *reply = NULL;
2449 GVariant *param = NULL;
2450 GDBusConnection *connection = NULL;
2451 const char *device = "p2p";
2453 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
2454 if (connection == NULL) {
2456 WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
2458 g_error_free(error);
2460 __WDP_LOG_FUNC_EXIT__;
2463 param = g_variant_new("(s)", device);
2465 reply = g_dbus_connection_call_sync (connection,
2466 NETCONFIG_SERVICE, /* bus name */
2467 NETCONFIG_WIFI_PATH, /* object path */
2468 NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
2469 "Stop", /* method name */
2470 param, /* GVariant *params */
2471 NULL, /* reply_type */
2472 G_DBUS_CALL_FLAGS_NONE, /* flags */
2473 NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
2474 NULL, /* cancellable */
2475 &error); /* error */
2478 if(strstr(error->message, ".AlreadyExists") != NULL) {
2479 WDP_LOGD("p2p already disabled");
2480 g_error_free(error);
2483 WDP_LOGE("Error! Failed to call net-config method: [%s]",
2485 g_error_free(error);
2487 g_variant_unref(reply);
2488 g_object_unref(connection);
2489 __WDP_LOG_FUNC_EXIT__;
2494 g_variant_unref(reply);
2495 g_object_unref(connection);
2499 static int __ws_p2p_supplicant_start(void)
2501 gboolean rv = FALSE;
2502 const char *path = "/usr/sbin/p2p_supp.sh";
2503 char *const args[] = { "/usr/sbin/p2p_supp.sh", "start", NULL };
2504 char *const envs[] = { NULL };
2506 rv = _ws_util_execute_file(path, args, envs);
2509 WDP_LOGE("Failed to start p2p_supp.sh");
2513 WDP_LOGI("Successfully started p2p_supp.sh");
2517 static int __ws_p2p_supplicant_stop(void)
2519 gboolean rv = FALSE;
2520 const char *path = "/usr/sbin/p2p_supp.sh";
2521 char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
2522 char *const envs[] = { NULL };
2524 rv = _ws_util_execute_file(path, args, envs);
2527 WDP_LOGE("Failed to stop p2p_supp.sh");
2531 WDP_LOGI("Successfully stopped p2p_supp.sh");
2536 static int __ws_p2p_on(void)
2539 DBusMessage *reply = NULL;
2540 DBusMessage *message = NULL;
2541 DBusConnection *connection = NULL;
2543 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
2544 if (connection == NULL) {
2545 WDP_LOGE("Failed to get system bus");
2549 message = dbus_message_new_method_call(NETCONFIG_SERVICE,
2550 NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
2551 if (message == NULL) {
2552 WDP_LOGE("Failed DBus method call");
2553 dbus_connection_unref(connection);
2557 dbus_error_init(&error);
2559 reply = dbus_connection_send_with_reply_and_block(connection, message,
2560 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
2561 if (dbus_error_is_set(&error) == TRUE) {
2562 if (NULL != strstr(error.message, ".AlreadyExists")) {
2563 // p2p already enabled
2565 WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
2566 "DBus error [%s: %s]", error.name, error.message);
2568 dbus_error_free(&error);
2571 dbus_error_free(&error);
2575 dbus_message_unref(reply);
2577 dbus_message_unref(message);
2578 dbus_connection_unref(connection);
2583 static int __ws_p2p_off(void)
2586 DBusMessage *reply = NULL;
2587 DBusMessage *message = NULL;
2588 DBusConnection *connection = NULL;
2590 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
2591 if (connection == NULL) {
2592 WDP_LOGE("Failed to get system bus");
2596 message = dbus_message_new_method_call(NETCONFIG_SERVICE,
2597 NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
2598 if (message == NULL) {
2599 WDP_LOGE("Failed DBus method call");
2600 dbus_connection_unref(connection);
2604 dbus_error_init(&error);
2606 reply = dbus_connection_send_with_reply_and_block(connection, message,
2607 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
2608 if (dbus_error_is_set(&error) == TRUE) {
2609 if (NULL != strstr(error.message, ".AlreadyExists")) {
2610 // p2p already disabled
2612 WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
2613 "DBus error [%s: %s]", error.name, error.message);
2615 dbus_error_free(&error);
2618 dbus_error_free(&error);
2622 dbus_message_unref(reply);
2624 dbus_message_unref(message);
2625 dbus_connection_unref(connection);
2630 static int _ws_update_local_dev_addr_from_file()
2632 __WDP_LOG_FUNC_ENTER__;
2634 char local_mac[OEM_MACSTR_LEN] = {0, };
2639 fd = fopen(DEFAULT_MAC_FILE_PATH, "r");
2641 WDP_LOGE("Failed to open MAC info file (%s)", strerror(errno));
2642 __WDP_LOG_FUNC_EXIT__;
2647 ptr = fgets(local_mac, OEM_MACSTR_LEN, fd);
2649 WDP_LOGE("Failed to read file or no data read(%s)", strerror(errno));
2651 __WDP_LOG_FUNC_EXIT__;
2654 WDP_SECLOGD("Local MAC address [%s]", ptr);
2656 res = _ws_txt_to_mac(local_mac, g_pd->local_dev_addr);
2658 WDP_LOGE("Failed to convert text to MAC address");
2660 __WDP_LOG_FUNC_EXIT__;
2664 g_pd->local_dev_addr[0] |= 0x2;
2665 WDP_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(g_pd->local_dev_addr));
2668 __WDP_LOG_FUNC_EXIT__;
2672 static int _ws_update_local_dev_addr()
2675 char reply[96] = {0, };
2676 char *mac_str = NULL;
2678 res = _ws_send_cmd(g_pd->common->ctrl_sock, "status", reply, sizeof(reply));
2680 WDP_LOGE("Failed to send command to wpa_supplicant");
2684 res = _extract_value_str(reply, "p2p_device_address", &mac_str);
2686 WDP_LOGE("Failed to parsing p2p_device_address");
2690 res = _ws_txt_to_mac(mac_str, g_pd->local_dev_addr);
2692 WDP_LOGE("Failed to convert MAC string to address");
2702 res = _ws_update_local_dev_addr_from_file();
2704 WDP_LOGE("Failed to update local device address from file");
2711 int ws_activate(int concurrent)
2713 __WDP_LOG_FUNC_ENTER__;
2715 int retry_count = 0;
2717 while (retry_count < 10) {
2718 /* load wlan driver */
2719 res = __ws_p2p_firmware_start();
2721 WDP_LOGE("Failed to load driver [ret=%d]", res);
2724 WDP_LOGI("P2P firmware started with error %d", res);
2726 if (__ws_check_net_interface(COMMON_IFACE_NAME) < 0) {
2727 usleep(150000); // wait for 150ms
2729 WDP_LOGE("interface is not up: retry, %d", retry_count);
2735 if (retry_count >= 10) {
2736 WDP_LOGE("Driver loading is failed", res);
2737 __WDP_LOG_FUNC_EXIT__;
2740 if (retry_count > 0) {
2741 // Give driver marginal time to config net
2742 WDP_LOGE("Driver loading is done. Wait marginal time for driver");
2746 g_pd->concurrent = concurrent;
2749 /* load wpa_supplicant */
2750 res = __ws_p2p_supplicant_start();
2752 WDP_LOGE("Failed to start p2p_supplicant [%d: %s]", res, strerror(errno));
2753 res = __ws_p2p_firmware_stop();
2754 WDP_LOGI("P2P firmware stopped with error %d", res);
2755 __WDP_LOG_FUNC_EXIT__;
2759 res = _connect_to_supplicant(COMMON_IFACE_NAME, &g_pd->common);
2761 res = __ws_p2p_supplicant_stop();
2762 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2763 res = __ws_p2p_firmware_stop();
2764 WDP_LOGI("P2P firmware stopped with error %d", res);
2765 __WDP_LOG_FUNC_EXIT__;
2769 g_pd->activated = TRUE;
2771 _ws_update_local_dev_addr();
2773 __WDP_LOG_FUNC_EXIT__;
2777 int ws_deactivate(int concurrent)
2779 __WDP_LOG_FUNC_ENTER__;
2780 char cmd[32] = {0, };
2781 char reply[1024]={0,};
2784 if (!g_pd->activated) {
2785 WDP_LOGE("Wi-Fi Direct is not activated");
2791 g_pd->concurrent = concurrent;
2794 _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
2798 // terminate wpasupplicant
2799 snprintf(cmd, sizeof(cmd), WS_CMD_TERMINATE);
2800 res = _ws_send_cmd(g_pd->common->ctrl_sock, cmd, reply, sizeof(reply));
2802 WDP_LOGE("Failed to send command to wpa_supplicant");
2803 res = __ws_p2p_supplicant_stop();
2804 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2808 if (!strncmp(reply, "FAIL", 4)) {
2809 WDP_LOGE( "Failed to terminate wpa_supplicant");
2810 res = __ws_p2p_supplicant_stop();
2811 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2815 res = _disconnect_from_supplicant(COMMON_IFACE_NAME, g_pd->common);
2817 WDP_LOGE("Failed to disconnect common interface(%s) from supplicant. ",
2821 res = __ws_p2p_supplicant_stop();
2822 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2825 res = __ws_p2p_firmware_stop();
2826 WDP_LOGI("P2P firmware stopped with error %d", res);
2827 g_pd->activated = FALSE;
2829 __WDP_LOG_FUNC_EXIT__;
2833 static gboolean _retry_start_scan(gpointer data)
2835 ws_sock_data_s *sock = g_pd->common;
2836 char reply[1024] = {0, };
2837 static int retry_cnt = 0;
2839 char *cmd = (char *)data;
2841 if (NULL == sock || NULL == cmd) {
2842 WDP_LOGE("Data is NULL, Retry Scan Failed !!!");
2846 if (WS_SCAN_RETRY_COUNT == retry_cnt) {
2847 WDP_LOGE("Maximum Retry Reached. Aborting Scan.");
2851 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2853 WDP_LOGE("Failed to send command to wpa_supplicant");
2857 if (strstr(reply, "FAIL")) {
2858 WDP_LOGE("Retry Scan Failed, Retry after 100ms...");
2863 WDP_LOGD("Retry Scan Succeeded.");
2874 int ws_start_scan(wfd_oem_scan_param_s *param)
2876 __WDP_LOG_FUNC_ENTER__;
2877 ws_sock_data_s *sock = g_pd->common;
2878 char cmd[40] = {0, };
2879 char reply[1024] = {0, };
2880 char time_str[4] = {0, };
2881 char type_str[20] = {0, };
2883 char *retry_cmd = NULL;
2886 WDP_LOGE("Invalid parameter");
2891 WDP_LOGE("Socket is NULL");
2898 if (param->scan_time)
2899 snprintf(time_str, 4, " %d", param->scan_time);
2901 if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
2902 snprintf(type_str, 20, " type=social");
2903 else if (param->scan_type == WFD_OEM_SCAN_TYPE_SPECIFIC &&
2905 snprintf(type_str, 20, " freq=%d", param->freq);
2906 else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL1)
2907 snprintf(type_str, 20, " type=specific1");
2908 else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL6)
2909 snprintf(type_str, 20, " type=specific6");
2910 else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL11)
2911 snprintf(type_str, 20, " type=specific11");
2912 else if (param->scan_type == WFD_OEM_SCAN_TYPE_GO_FREQ)
2913 snprintf(type_str, 20, " type=frequency");
2915 if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE)
2916 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND "%s%s",
2917 (param->scan_time > 0) ? time_str : "",
2918 (param->scan_type) ? type_str : "");
2920 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_LISTEN);
2922 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2924 WDP_LOGE("Failed to send command to wpa_supplicant");
2925 __WDP_LOG_FUNC_EXIT__;
2929 if (strstr(reply, "FAIL")) {
2930 WDP_LOGE("Failed to start scan, Retry");
2931 retry_cmd = strdup(cmd);
2932 /* Add Timeout of 100ms for retry SCAN */
2933 g_timeout_add(100, _retry_start_scan, (gpointer) retry_cmd);
2934 __WDP_LOG_FUNC_EXIT__;
2937 WDP_LOGD("Succeeded to start scan");
2939 __WDP_LOG_FUNC_EXIT__;
2945 __WDP_LOG_FUNC_ENTER__;
2946 ws_sock_data_s *sock = g_pd->common;
2947 char reply[1024] = {0, };
2951 WDP_LOGE("Socket is NULL");
2955 res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_STOP_FIND, reply, sizeof(reply));
2957 WDP_LOGE("Failed to send command to wpa_supplicant");
2958 __WDP_LOG_FUNC_EXIT__;
2962 if (strstr(reply, "FAIL")) {
2963 WDP_LOGE("Failed to stop scan");
2964 __WDP_LOG_FUNC_EXIT__;
2967 WDP_LOGD("Succeeded to stop scan");
2970 __WDP_LOG_FUNC_EXIT__;
2974 int ws_get_visibility(int *visibility)
2976 __WDP_LOG_FUNC_ENTER__;
2978 __WDP_LOG_FUNC_EXIT__;
2982 int ws_set_visibility(int visibility)
2984 __WDP_LOG_FUNC_ENTER__;
2986 __WDP_LOG_FUNC_EXIT__;
2990 int ws_get_scan_result(GList **peers, int *peer_count)
2992 __WDP_LOG_FUNC_ENTER__;
2993 ws_sock_data_s *sock = g_pd->common;
2994 char cmd[32] = {0, };
2995 char reply[1024] = {0,};
2996 wfd_oem_device_s *peer = NULL;
2999 if (!peers || !peer_count) {
3000 WDP_LOGE("Invalid parameter");
3005 WDP_LOGE("Socket is NULL");
3009 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER_FIRST);
3010 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3012 WDP_LOGE("Failed to send command to wpa_supplicant");
3013 __WDP_LOG_FUNC_EXIT__;
3017 if (strstr(reply, "FAIL")) {
3018 WDP_LOGE("Failed to get first peer info");
3019 __WDP_LOG_FUNC_EXIT__;
3022 WDP_LOGD("Succeeded to get first peer info");
3024 peer = (wfd_oem_device_s *) calloc(1, sizeof(wfd_oem_device_s));
3026 res = _parsing_peer_info(reply, peer);
3028 WDP_LOGE("Failed to parsing peer info");
3030 __WDP_LOG_FUNC_EXIT__;
3034 *peers = g_list_prepend(*peers, peer);
3037 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER_NEXT MACSTR, MAC2STR(peer->dev_addr));
3038 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3040 WDP_LOGE("Failed to send command to wpa_supplicant");
3044 if (strstr(reply, "FAIL")) {
3045 WDP_LOGE("Failed to get first peer info");
3048 WDP_LOGD("Succeeded to get first peer info");
3050 peer = (wfd_oem_device_s *) calloc(1, sizeof(wfd_oem_device_s));
3052 res = _parsing_peer_info(reply, peer);
3054 WDP_LOGE("Failed to parsing peer info");
3059 *peers = g_list_prepend(*peers, peer);
3062 __WDP_LOG_FUNC_EXIT__;
3066 int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
3068 __WDP_LOG_FUNC_ENTER__;
3069 ws_sock_data_s *sock = g_pd->common;
3070 char cmd[32] = {0, };
3071 char reply[1024] = {0,};
3072 wfd_oem_device_s *ws_dev = NULL;
3075 if (!peer_addr || !peer) {
3076 WDP_LOGE("Invalid parameter");
3081 WDP_LOGE("Socket is NULL");
3085 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER MACSTR, MAC2STR(peer_addr));
3086 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3088 WDP_LOGE("Failed to send command to wpa_supplicant");
3089 __WDP_LOG_FUNC_EXIT__;
3093 if (strstr(reply, "FAIL")) {
3094 WDP_LOGD("Failed to get peer info [" MACSECSTR "]", MAC2SECSTR(peer_addr));
3095 __WDP_LOG_FUNC_EXIT__;
3098 WDP_LOGD("Succeeded to get peer info [" MACSECSTR "]", MAC2SECSTR(peer_addr));
3100 ws_dev = (wfd_oem_device_s*) calloc(1, sizeof(wfd_oem_device_s));
3102 res = _parsing_peer_info(reply, ws_dev);
3104 WDP_LOGE("Failed to parsing peer info");
3106 __WDP_LOG_FUNC_EXIT__;
3111 __WDP_LOG_FUNC_EXIT__;
3115 int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
3117 __WDP_LOG_FUNC_ENTER__;
3118 ws_sock_data_s *sock = g_pd->common;
3119 char cmd[64] = {0, };
3120 char reply[1024]={0,};
3124 WDP_LOGE("Socket is NULL");
3128 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PROV_DISC MACSTR "%s",
3129 MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
3132 strncat(cmd, WS_STR_JOIN, 5);
3134 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3136 WDP_LOGE("Failed to send command to wpa_supplicant");
3137 __WDP_LOG_FUNC_EXIT__;
3141 if (strstr(reply, "FAIL")) {
3142 WDP_LOGD("Failed to send provision discovery to peer[" MACSECSTR "]",
3143 MAC2SECSTR(peer_addr));
3144 __WDP_LOG_FUNC_EXIT__;
3147 WDP_LOGD("Succeeded to send provision discovery to peer[" MACSECSTR "]",
3148 MAC2SECSTR(peer_addr));
3149 memcpy(g_pd_out, peer_addr, OEM_MACADDR_LEN);
3151 __WDP_LOG_FUNC_EXIT__;
3155 int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
3157 __WDP_LOG_FUNC_ENTER__;
3158 ws_sock_data_s *sock = g_pd->common;
3159 char cmd[64] = {0, };
3160 char freq_str[11] ={0, };
3161 char reply[1024] = {0, };
3165 WDP_LOGE("Invalid parameter");
3170 WDP_LOGE("Socket is NULL");
3174 if (param->wps_pin[0] != '\0')
3175 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR " %s%s" ,
3176 MAC2STR(peer_addr), param->wps_pin,
3177 _ws_wps_to_txt(param->wps_mode));
3179 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR "%s",
3181 _ws_wps_to_txt(param->wps_mode));
3183 if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
3184 strncat(cmd, WS_STR_JOIN, 5);
3185 else if (param->conn_flags& WFD_OEM_CONN_TYPE_AUTH)
3186 strncat(cmd, WS_STR_AUTH, 5);
3188 if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
3189 strncat(cmd, WS_STR_PERSISTENT, 11);
3191 if (param->freq > 0) {
3192 snprintf(freq_str, sizeof(freq_str), WS_STR_FREQ "%d", param->freq);
3193 strncat(cmd, freq_str, sizeof(freq_str));
3196 WDP_LOGI("Connection command [%s]", cmd);
3198 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3200 WDP_LOGE("Failed to send command to wpa_supplicant");
3201 __WDP_LOG_FUNC_EXIT__;
3205 if (strstr(reply, "FAIL")) {
3206 WDP_LOGD("Failed to connect with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3207 __WDP_LOG_FUNC_EXIT__;
3210 WDP_LOGD("Succeeded to send connection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3212 __WDP_LOG_FUNC_EXIT__;
3216 int ws_disconnect(unsigned char *peer_addr)
3218 __WDP_LOG_FUNC_ENTER__;
3219 ws_sock_data_s *sock = g_pd->common;
3220 char cmd[48] = {0, };
3221 char reply[1024]={0,};
3225 WDP_LOGE("Invalid parameter");
3230 WDP_LOGE("Socket is NULL");
3234 WDP_LOGD("Peer address is [" MACSECSTR "]. Disconnect selected peer", MAC2SECSTR(peer_addr));
3236 snprintf(cmd, sizeof(cmd), WS_CMD_DISCONNECT MACSTR " %s", MAC2STR(peer_addr), GROUP_IFACE_NAME);
3237 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3239 WDP_LOGE("Failed to send command to wpa_supplicant");
3240 __WDP_LOG_FUNC_EXIT__;
3244 if (strstr(reply, "FAIL")) {
3245 WDP_LOGD("Failed to disconnect with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3246 __WDP_LOG_FUNC_EXIT__;
3249 WDP_LOGD("Succeeded to send disconnection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3251 __WDP_LOG_FUNC_EXIT__;
3255 int ws_reject_connection(unsigned char *peer_addr)
3257 __WDP_LOG_FUNC_ENTER__;
3258 ws_sock_data_s *sock = g_pd->common;
3259 char cmd[64] = {0, };
3260 char reply[1024]={0,};
3264 WDP_LOGE("Socket is NULL");
3268 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR "%s userReject", MAC2STR(peer_addr), WS_STR_PBC);
3269 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3271 WDP_LOGE("Failed to send command to wpa_supplicant");
3272 __WDP_LOG_FUNC_EXIT__;
3276 if (strstr(reply, "FAIL")) {
3277 WDP_LOGD("Failed to reject connection with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3278 __WDP_LOG_FUNC_EXIT__;
3281 WDP_LOGD("Succeeded to send reject connection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3283 __WDP_LOG_FUNC_EXIT__;
3287 int ws_cancel_connection(unsigned char *peer_addr)
3289 __WDP_LOG_FUNC_ENTER__;
3293 __WDP_LOG_FUNC_EXIT__;
3297 int ws_get_connected_peers(GList **peers, int *peer_count)
3299 __WDP_LOG_FUNC_ENTER__;
3301 __WDP_LOG_FUNC_EXIT__;
3305 int ws_get_pin(char *pin)
3307 __WDP_LOG_FUNC_ENTER__;
3309 __WDP_LOG_FUNC_EXIT__;
3313 int ws_set_pin(char *pin)
3315 __WDP_LOG_FUNC_ENTER__;
3317 __WDP_LOG_FUNC_EXIT__;
3321 int ws_get_supported_wps_mode()
3323 __WDP_LOG_FUNC_ENTER__;
3325 __WDP_LOG_FUNC_EXIT__;
3329 int ws_create_group(int persistent, int freq, const char *passphrase)
3331 __WDP_LOG_FUNC_ENTER__;
3332 ws_sock_data_s *sock = g_pd->common;
3333 char cmd[44] = {0, };
3334 char freq_str[11] = {0, };
3335 char reply[1024]={0,};
3339 WDP_LOGE("Socket is NULL");
3344 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD WS_STR_PERSISTENT);
3346 if (passphrase[0] != '\0') {
3348 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD " passphrase=%s", passphrase);
3351 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD);
3356 snprintf(freq_str, sizeof(freq_str), WS_STR_FREQ "%d", freq);
3357 strncat(cmd, freq_str, sizeof(freq_str));
3359 strncat(cmd, WS_STR_FREQ_2G, 8);
3362 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3364 WDP_LOGE("Failed to send command to wpa_supplicant");
3365 __WDP_LOG_FUNC_EXIT__;
3369 if (strstr(reply, "FAIL")) {
3370 WDP_LOGE("Failed to add group");
3371 __WDP_LOG_FUNC_EXIT__;
3374 WDP_LOGD("Succeeded to add group");
3376 __WDP_LOG_FUNC_EXIT__;
3380 int ws_destroy_group(const char *ifname)
3382 __WDP_LOG_FUNC_ENTER__;
3383 ws_sock_data_s *sock = g_pd->common;
3384 char cmd[32] = {0, };
3385 char reply[1024]={0,};
3389 WDP_LOGE("Invalid parameter");
3394 WDP_LOGE("Socket is NULL");
3398 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_REMOVE "%s", ifname);
3400 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3402 WDP_LOGE("Failed to send command to wpa_supplicant");
3403 __WDP_LOG_FUNC_EXIT__;
3407 if (strstr(reply, "FAIL")) {
3408 WDP_LOGE("Failed to remove group");
3409 __WDP_LOG_FUNC_EXIT__;
3412 WDP_LOGD("Succeeded to remove group");
3416 __WDP_LOG_FUNC_EXIT__;
3420 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
3422 __WDP_LOG_FUNC_ENTER__;
3423 ws_sock_data_s *sock = g_pd->common;
3424 char cmd[128] = {0, };
3425 char reply[1024]={0,};
3428 if (!peer_addr || !param) {
3429 WDP_LOGE("Invalid parameter");
3434 WDP_LOGE("Group interface not connected");
3438 WDP_LOGD("Invite: Peer[" MACSECSTR "], GO Addr[" MACSECSTR "]",
3439 MAC2SECSTR(peer_addr), MAC2SECSTR(param->go_dev_addr));
3442 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_INVITE "persistent=%d peer=" MACSTR " go_dev_addr=" MACSTR,
3443 param->net_id, MAC2STR(peer_addr),
3444 MAC2STR(param->go_dev_addr));
3446 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_INVITE "group=%s peer=" MACSTR " go_dev_addr=" MACSTR,
3447 param->ifname, MAC2STR(peer_addr),
3448 MAC2STR(param->go_dev_addr));
3450 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3452 WDP_LOGE("Failed to send command to wpa_supplicant");
3453 __WDP_LOG_FUNC_EXIT__;
3457 if (strstr(reply, "FAIL")) {
3458 WDP_LOGE("Failed to invite peer");
3459 __WDP_LOG_FUNC_EXIT__;
3462 WDP_LOGD("Succeeded to invite peer");
3464 __WDP_LOG_FUNC_EXIT__;
3468 // Only group owner can use this command
3469 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
3471 __WDP_LOG_FUNC_ENTER__;
3472 ws_sock_data_s *sock = g_pd->group;
3473 char cmd[40] = {0, };
3474 char reply[1024]={0,};
3477 if (!peer_addr || !pin) {
3478 WDP_LOGE("Invalid parameter");
3483 WDP_LOGE("Group interface not connected");
3487 if (wps_mode == WFD_OEM_WPS_MODE_PBC)
3488 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_PBC "p2p_dev_addr=" MACSTR, MAC2STR(peer_addr));
3490 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_PIN MACSTR " %s", MAC2STR(peer_addr), pin);
3492 res = _ws_send_cmd(sock->ctrl_sock, cmd,reply, sizeof(reply));
3494 WDP_LOGE("Failed to send command to wpa_supplicant");
3495 __WDP_LOG_FUNC_EXIT__;
3499 if (strstr(reply, "FAIL")) {
3500 WDP_LOGE("Failed to start WPS");
3501 __WDP_LOG_FUNC_EXIT__;
3504 WDP_LOGD("Succeeded to start WPS");
3506 __WDP_LOG_FUNC_EXIT__;
3510 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
3512 __WDP_LOG_FUNC_ENTER__;
3513 ws_sock_data_s *sock = g_pd->group;
3514 char cmd[64] = {0, };
3515 char reply[1024]={0,};
3518 if (!peer_addr || !pin) {
3519 WDP_LOGE("Invalid parameter");
3524 WDP_LOGE("Socket is NULL");
3528 if (wps_mode == WFD_OEM_WPS_MODE_PBC)
3529 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_ENROLLEE MACSTR "%s",
3530 MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
3532 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_ENROLLEE MACSTR " %s%s",
3533 MAC2STR(peer_addr), pin, _ws_wps_to_txt(wps_mode));
3535 res = _ws_send_cmd(sock->ctrl_sock, cmd,reply, sizeof(reply));
3537 WDP_LOGE("Failed to send command to wpa_supplicant");
3538 __WDP_LOG_FUNC_EXIT__;
3542 if (strstr(reply, "FAIL")) {
3543 WDP_LOGE("Failed to start WPS");
3544 __WDP_LOG_FUNC_EXIT__;
3547 WDP_LOGD("Succeeded to start WPS");
3549 __WDP_LOG_FUNC_EXIT__;
3555 __WDP_LOG_FUNC_ENTER__;
3556 ws_sock_data_s *sock = g_pd->group;
3557 char reply[1024]={0,};
3561 WDP_LOGE("Socket is NULL");
3565 res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_WPS_CANCEL, reply, sizeof(reply));
3567 WDP_LOGE("Failed to send command to wpa_supplicant");
3568 __WDP_LOG_FUNC_EXIT__;
3572 if (strstr(reply, "FAIL")) {
3573 WDP_LOGE("Failed to cancel WPS");
3574 __WDP_LOG_FUNC_EXIT__;
3577 WDP_LOGD("Succeeded to cancel WPS");
3579 __WDP_LOG_FUNC_EXIT__;
3583 int ws_get_dev_name(char *dev_name)
3585 __WDP_LOG_FUNC_ENTER__;
3587 __WDP_LOG_FUNC_EXIT__;
3591 int ws_set_dev_name(char *dev_name)
3593 __WDP_LOG_FUNC_ENTER__;
3594 ws_sock_data_s *sock = g_pd->common;
3595 char cmd[128] = {0, };
3596 char reply[1024]={0,};
3599 if (!dev_name || !strlen(dev_name)) {
3600 WDP_LOGE( "Invalid parameter");
3601 __WDP_LOG_FUNC_EXIT__;
3606 WDP_LOGE("Socket is NULL");
3610 snprintf(cmd, sizeof(cmd), WS_CMD_SET "device_name %s", dev_name);
3611 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3613 WDP_LOGE("Failed to send command to wpa_supplicant");
3614 __WDP_LOG_FUNC_EXIT__;
3618 if (strstr(reply, "FAIL")) {
3619 WDP_LOGE("Failed to set device name");
3620 __WDP_LOG_FUNC_EXIT__;
3623 WDP_LOGD("Succeeded to set device name");
3625 memset(cmd, 0x0, 128);
3626 memset(reply, 0x0, 1024);
3628 snprintf(cmd, sizeof(cmd), WS_CMD_SET "p2p_ssid_postfix %s", dev_name);
3629 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3631 WDP_LOGE("Failed to send command to wpa_supplicant");
3632 __WDP_LOG_FUNC_EXIT__;
3636 if (strstr(reply, "FAIL")) {
3637 WDP_LOGE("Failed to set SSID postfix");
3638 __WDP_LOG_FUNC_EXIT__;
3641 WDP_LOGD("Succeeded to set SSID postfix");
3643 __WDP_LOG_FUNC_EXIT__;
3647 int ws_get_dev_mac(char *dev_mac)
3649 __WDP_LOG_FUNC_ENTER__;
3651 __WDP_LOG_FUNC_EXIT__;
3655 int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
3657 __WDP_LOG_FUNC_ENTER__;
3659 __WDP_LOG_FUNC_EXIT__;
3663 int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
3665 __WDP_LOG_FUNC_ENTER__;
3667 __WDP_LOG_FUNC_EXIT__;
3671 int ws_get_go_intent(int *go_intent)
3673 __WDP_LOG_FUNC_ENTER__;
3675 ws_sock_data_s *sock = g_pd->common;
3676 char cmd[80] = {0, };
3677 char reply[1024]={0,};
3681 WDP_LOGE("Socket is NULL");
3685 if (go_intent == NULL)
3687 WDP_LOGE("p2p_go_intent is NULL");
3688 __WDP_LOG_FUNC_EXIT__;
3692 snprintf(cmd, sizeof(cmd), WS_CMD_GET "p2p_go_intent");
3693 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3695 WDP_LOGE("Failed to send command to wpa_supplicant");
3696 __WDP_LOG_FUNC_EXIT__;
3700 if (strstr(reply, "FAIL")) {
3701 WDP_LOGE("Failed to set go intent");
3702 __WDP_LOG_FUNC_EXIT__;
3706 *go_intent = atoi(reply);
3707 WDP_LOGD("Succeeded to get go intent(%d)", *go_intent);
3709 __WDP_LOG_FUNC_EXIT__;
3713 int ws_set_go_intent(int go_intent)
3715 __WDP_LOG_FUNC_ENTER__;
3717 ws_sock_data_s *sock = g_pd->common;
3718 char cmd[80] = {0, };
3719 char reply[1024]={0,};
3723 WDP_LOGE("Socket is NULL");
3727 snprintf(cmd, sizeof(cmd), WS_CMD_SET "p2p_go_intent %d", go_intent);
3729 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3731 WDP_LOGE("Failed to send command to wpa_supplicant");
3732 __WDP_LOG_FUNC_EXIT__;
3736 if (strstr(reply, "FAIL")) {
3737 WDP_LOGE("Failed to set go intent");
3738 __WDP_LOG_FUNC_EXIT__;
3741 WDP_LOGD("Succeeded to set go intent(%d)", go_intent);
3743 __WDP_LOG_FUNC_EXIT__;
3747 int ws_set_country(char *ccode)
3749 __WDP_LOG_FUNC_ENTER__;
3750 ws_sock_data_s *sock = g_pd->common;
3751 char cmd[80] = {0, };
3752 char reply[1024]={0,};
3756 WDP_LOGE("Socket is NULL");
3760 snprintf(cmd, sizeof(cmd), WS_CMD_SET "country %s", ccode);
3762 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3764 WDP_LOGE("Failed to send command to wpa_supplicant");
3765 __WDP_LOG_FUNC_EXIT__;
3769 if (strstr(reply, "FAIL")) {
3770 WDP_LOGE("Failed to set country");
3771 __WDP_LOG_FUNC_EXIT__;
3774 WDP_LOGD("Succeeded to set country(%s)", ccode);
3776 __WDP_LOG_FUNC_EXIT__;
3780 int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
3782 __WDP_LOG_FUNC_ENTER__;
3785 char *tmp_str = NULL;
3788 // Passing first line : "network id / ssid / bssid / flags"
3789 while (*ptr != '\n') {
3795 while(*ptr != '\0') {
3796 res = _extract_word(ptr, &tmp_str);
3798 networks[count].network_id = atoi(tmp_str);
3805 res = _extract_word(ptr, &tmp_str);
3807 snprintf(networks[count].ssid, WS_SSID_LEN, "%s", tmp_str);
3814 res = _extract_word(ptr, &tmp_str);
3816 _ws_txt_to_mac(tmp_str, networks[count].bssid);
3823 res = _extract_word(ptr, &tmp_str);
3825 if (strstr(tmp_str, "CURRENT"))
3826 networks[count].flags |= WFD_OEM_NETFLAG_CURRENT;
3827 if (strstr(tmp_str, "DISABLED"))
3828 networks[count].flags |= WFD_OEM_NETFLAG_DISABLED;
3829 if (strstr(tmp_str, "TEMP-DISABLED"))
3830 networks[count].flags |= WFD_OEM_NETFLAG_TEMP_DISABLED;
3831 if (strstr(tmp_str, "P2P-PERSISTENT"))
3832 networks[count].flags |= WFD_OEM_NETFLAG_P2P_PERSISTENT;
3842 *network_cnt = count;
3844 __WDP_LOG_FUNC_EXIT__;
3848 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
3850 __WDP_LOG_FUNC_ENTER__;
3851 ws_sock_data_s *sock = g_pd->common;
3852 char cmd[80] = {0, };
3853 char reply[1024]={0,};
3854 ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
3855 wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
3859 if (!groups || !group_count) {
3860 WDP_LOGE("Invalid parameter");
3865 WDP_LOGE("Socket is NULL");
3869 memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
3871 /* Reading lists the configured networks, including stored information for persistent groups.
3872 The identifier in this is used with p2p_group_add and p2p_invite to indicate witch persistent
3873 group is to be reinvoked. */
3874 snprintf(cmd, sizeof(cmd), WS_CMD_LIST_NETWORKS);
3875 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3877 WDP_LOGE("Failed to send command to wpa_supplicant");
3878 __WDP_LOG_FUNC_EXIT__;
3882 if (strstr(reply, "FAIL")) {
3883 WDP_LOGE("Failed to get list of networks");
3884 __WDP_LOG_FUNC_EXIT__;
3887 WDP_LOGD("Succeeded to get list of networks");
3889 _parsing_networks(reply, networks, &cnt);
3890 WDP_LOGD("Persistent Group Count=%d", cnt);
3891 if (cnt > WS_MAX_PERSISTENT_COUNT) {
3892 WDP_LOGE("Persistent group count exceeded or parsing error");
3893 __WDP_LOG_FUNC_EXIT__;
3897 wfd_persistent_groups = (wfd_oem_persistent_group_s*) calloc(1, cnt * sizeof(wfd_oem_persistent_group_s));
3898 for(i = 0; i < cnt; i++) {
3899 WDP_LOGD("----persistent group [%d]----", i);
3900 WDP_LOGD("network_id=%d", networks[i].network_id);
3901 WDP_LOGD("ssid=%s", networks[i].ssid);
3902 WDP_LOGD("bssid=" MACSECSTR, MAC2SECSTR(networks[i].bssid));
3903 WDP_LOGD("flags=%x", networks[i].flags);
3905 wfd_persistent_groups[i].network_id = networks[i].network_id;
3906 strncpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN);
3907 wfd_persistent_groups[i].ssid[WS_SSID_LEN] = '\0';
3908 memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
3912 *groups = wfd_persistent_groups;
3914 __WDP_LOG_FUNC_EXIT__;
3918 int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
3920 __WDP_LOG_FUNC_ENTER__;
3921 ws_sock_data_s *sock = g_pd->common;
3922 char cmd[80] = {0, };
3923 char reply[1024]={0,};
3926 ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
3929 if (!ssid || !bssid) {
3930 WDP_LOGE("Invalid parameter");
3935 WDP_LOGE("Socket is NULL");
3939 memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
3941 strncpy(cmd, WS_CMD_LIST_NETWORKS, sizeof(cmd));
3942 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3944 WDP_LOGE("Failed to send command to wpa_supplicant");
3945 __WDP_LOG_FUNC_EXIT__;
3949 if (strstr(reply, "FAIL")) {
3950 WDP_LOGE("Failed to get list of networks");
3951 __WDP_LOG_FUNC_EXIT__;
3954 WDP_LOGD("Succeeded to get list of networks");
3956 _parsing_networks(reply, networks, &network_count);
3958 for(i=0;i<network_count;i++) {
3959 WDP_LOGD("----persistent group [%d]----", i);
3960 WDP_LOGD("network_id=%d", networks[i].network_id);
3961 WDP_LOGD("ssid=%s", networks[i].ssid);
3962 WDP_LOGD("bssid=" MACSECSTR, MAC2SECSTR(networks[i].bssid));
3963 WDP_LOGD("flags=%x", networks[i].flags);
3965 if (!memcmp(bssid, networks[i].bssid, OEM_MACADDR_LEN) && !strcmp(ssid, networks[i].ssid)) {
3967 WDP_LOGD("Persistent group found [%d: %s]", networks[i].network_id, ssid);
3969 memset(cmd, 0x0, sizeof(cmd));
3970 memset(reply, 0x0, sizeof(reply));
3972 snprintf(cmd, sizeof(cmd), WS_CMD_REMOVE_NETWORK " %d", networks[i].network_id);
3973 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3975 WDP_LOGE("Failed to send command to wpa_supplicant");
3976 __WDP_LOG_FUNC_EXIT__;
3980 if (strstr(reply, "FAIL")) {
3981 WDP_LOGE("Failed to remove persistent group");
3982 __WDP_LOG_FUNC_EXIT__;
3985 WDP_LOGD("Succeeded to remove persistent group");
3991 if (i == network_count) {
3992 WDP_LOGE("Persistent group not found [%s]", ssid);
3996 __WDP_LOG_FUNC_EXIT__;
4000 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
4002 __WDP_LOG_FUNC_ENTER__;
4003 ws_sock_data_s *sock = g_pd->common;
4004 char cmd[80] = {0, };
4005 char reply[1024]={0,};
4009 WDP_LOGE("Socket is NULL");
4013 snprintf(cmd, sizeof(cmd), WS_CMD_SET "persistent_reconnect %d", reconnect);
4014 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4016 WDP_LOGE("Failed to send command to wpa_supplicant");
4017 __WDP_LOG_FUNC_EXIT__;
4021 if (strstr(reply, "FAIL")) {
4022 WDP_LOGE("Failed to register WFDS service");
4023 __WDP_LOG_FUNC_EXIT__;
4026 WDP_LOGD("Succeeded to register WFDS service");
4028 __WDP_LOG_FUNC_EXIT__;
4032 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
4033 int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
4035 __WDP_LOG_FUNC_ENTER__;
4036 ws_sock_data_s *sock = g_pd->common;
4037 char cmd[80] = {0, };
4038 char reply[1024]={0,};
4040 char query[30] = {'0','2','0','0','F','F','0','1'};
4041 char mac_str[18] = {0, };
4042 wfd_oem_service_s *service = NULL;
4045 WDP_LOGE("Socket is NULL");
4049 memset(cmd, 0x00, 80);
4050 memset(reply, 0x00, WS_REPLY_LEN);
4052 query[1] += OEM_SERVICE_TYPE_LEN /2;
4053 service = (wfd_oem_service_s*) calloc(1, sizeof(wfd_oem_service_s));
4055 WDP_LOGE("Failed to allocate memory for service");
4059 if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
4060 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
4061 snprintf(mac_str, OEM_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
4063 snprintf(mac_str, OEM_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
4066 switch(service_type) {
4067 case WFD_OEM_SERVICE_TYPE_ALL:
4068 snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_ALL);
4069 strncpy(service->service_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN);
4070 service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
4072 case WFD_OEM_SERVICE_TYPE_BONJOUR:
4073 snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_BONJOUR);
4074 strncpy(service->service_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN);
4075 service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
4077 case WFD_OEM_SERVICE_TYPE_UPNP:
4078 snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_UPNP);
4079 strncpy(service->service_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN);
4080 service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
4082 case WFD_OEM_SERVICE_TYPE_BT_ADDR:
4083 strncat(query, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
4084 snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, query);
4085 strncpy(service->service_type, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
4086 service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
4088 case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
4089 strncat(query, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
4090 snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, query);
4091 strncpy(service->service_type, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
4092 service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
4095 WDP_LOGE("Invalid Service type");
4096 __WDP_LOG_FUNC_EXIT__;
4102 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4104 WDP_LOGE("Failed to send command to wpa_supplicant");
4105 __WDP_LOG_FUNC_EXIT__;
4111 if (strstr(reply, "FAIL")) {
4112 WDP_LOGE("Failed to start service discovery");
4113 __WDP_LOG_FUNC_EXIT__;
4118 WDP_LOGD("Succeeded to start service discovery");
4120 strncpy(service->dev_addr, mac_str, OEM_MACSTR_LEN - 1);
4121 service->dev_addr[OEM_MACSTR_LEN - 1] = '\0';
4122 WDP_LOGD("query id :[0x%s]",reply);
4123 strncpy(service->query_id, reply, OEM_QUERY_ID_LEN);
4124 service->query_id[OEM_QUERY_ID_LEN] = '\0';
4126 res = _check_service_query_exists(service);
4130 service_list = g_list_append(service_list, service);
4133 __WDP_LOG_FUNC_EXIT__;
4137 int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
4139 __WDP_LOG_FUNC_ENTER__;
4140 ws_sock_data_s *sock = g_pd->common;
4141 char cmd[80] = {0, };
4142 char reply[1024]={0,};
4144 char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
4145 char mac_str[18] = {0, };
4146 wfd_oem_service_s *data = NULL;
4147 char s_type[OEM_SERVICE_TYPE_LEN + 1] ={0, };
4150 WDP_LOGE("Socket is NULL");
4154 memset(cmd, 0x00, 80);
4155 memset(reply, 0x00, WS_REPLY_LEN);
4157 if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
4158 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
4159 snprintf(mac_str, OEM_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
4161 snprintf(mac_str, OEM_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
4164 switch(service_type) {
4165 case WFD_OEM_SERVICE_TYPE_ALL:
4166 strncpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN);
4168 case WFD_OEM_SERVICE_TYPE_BONJOUR:
4169 strncpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN);
4171 case WFD_OEM_SERVICE_TYPE_UPNP:
4172 strncpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN);
4174 case WFD_OEM_SERVICE_TYPE_BT_ADDR:
4175 strncpy(s_type, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
4177 case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
4178 strncpy(s_type, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
4181 __WDP_LOG_FUNC_EXIT__;
4182 WDP_LOGE("Invalid Service type");
4186 WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
4187 WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
4189 data = _remove_service_query(s_type, mac_str, query_id);
4193 snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_CANCEL " %s", query_id);
4194 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4196 WDP_LOGE("Failed to send command to wpa_supplicant");
4197 __WDP_LOG_FUNC_EXIT__;
4201 if (strstr(reply, "FAIL")) {
4202 WDP_LOGE("Failed to cancel service discovery");
4203 __WDP_LOG_FUNC_EXIT__;
4206 WDP_LOGD("Succeeded to cancel service discovery");
4208 service_list = g_list_remove(service_list, data);
4211 __WDP_LOG_FUNC_EXIT__;
4215 int _convert_bonjour_to_hex(char *query, char *rdata, char **hex)
4217 char hex_key[256] = {0, };;
4218 char hex_value[256] = {0, };;
4224 char temp_str[256] = {0, };
4225 char *result_str = NULL;
4227 if (!query || !hex) {
4228 WDP_LOGE("Invalid parameter");
4232 token = strtok_r(query, ".", &temp);
4234 if (!strcmp(token, "local")) {
4235 WDP_LOGD("Query conversion done");
4238 WDP_LOGD("Token: %s", token);
4239 len = strlen(token);
4240 sprintf(temp_str, "%02x", len);
4241 for (i=0; i<len; i++) {
4242 sprintf(temp_str+i*2+2, "%02x", token[i]);
4244 strncat(hex_key, temp_str, 2+2*len);
4245 WDP_LOGD("Converting: %s", hex_key);
4246 memset(temp_str, 0x0, 256);
4248 token = strtok_r(NULL, ".", &temp);
4251 if (token && strstr(token, "local")) {
4252 strncat(hex_key, "c011", 4);
4253 strncat(hex_key, "000c", 4);
4254 strncat(hex_key, "01", 2);
4256 strncat(hex_key, "c011", 4);
4257 strncat(hex_key, "0010", 4);
4258 strncat(hex_key, "01", 2);
4261 if (!rdata || !strlen(rdata)) {
4262 WDP_LOGD("RDATA is NULL");
4263 strncat(hex_value, "00", 2);
4265 token = strtok_r(rdata, ".", &temp);
4267 WDP_LOGD("Token: %s", token);
4268 len = strlen(token);
4269 sprintf(temp_str, "%02x", len);
4270 for (i=0; i<len; i++) {
4271 sprintf(temp_str+i*2+2, "%02x", token[i]);
4273 strncat(hex_value, temp_str, 2+2*len);
4274 WDP_LOGD("Converting: %s", hex_value);
4275 memset(temp_str, 0x0, 256);
4277 token = strtok_r(NULL, ".", &temp);
4281 strncat(hex_value, "c027", 4);
4283 tot_len = strlen(hex_key) + strlen(hex_value);
4284 result_str = (char*) calloc(1, tot_len+2);
4286 WDP_LOGE("Failed to allocate memory for result string");
4289 snprintf(result_str, tot_len+2, "%s %s", hex_key, hex_value);
4296 int ws_serv_add(wfd_oem_new_service_s *service)
4298 __WDP_LOG_FUNC_ENTER__;
4299 ws_sock_data_s *sock = g_pd->common;
4300 char cmd[256] = {0, };
4301 char reply[1024]={0,};
4305 WDP_LOGE("Socket is NULL");
4309 switch (service->protocol) {
4310 case WFD_OEM_SERVICE_TYPE_BONJOUR:
4312 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
4313 WDP_LOGD("Query: %s", service->data.bonjour.query);
4314 WDP_LOGD("RData: %s", service->data.bonjour.rdata);
4317 res = _convert_bonjour_to_hex(service->data.bonjour.query,
4318 service->data.bonjour.rdata,
4321 WDP_LOGE("Failed to convert Key string as hex string");
4325 WDP_LOGD("Converted Hexadecimal string [%s]", hex);
4326 snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_ADD " bonjour %s", hex);
4331 case WFD_OEM_SERVICE_TYPE_UPNP:
4333 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_UPNP");
4335 snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_ADD " upnp %s %s",
4336 service->data.upnp.version, service->data.upnp.service);
4340 WDP_LOGE("This service type is not supported [%d]", service->protocol);
4341 __WDP_LOG_FUNC_EXIT__;
4345 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4347 WDP_LOGE("Failed to send command to wpa_supplicant");
4348 __WDP_LOG_FUNC_EXIT__;
4352 if (strstr(reply, "FAIL")) {
4353 WDP_LOGE("Failed to add service");
4354 __WDP_LOG_FUNC_EXIT__;
4357 WDP_LOGD("Succeeded to add service");
4359 __WDP_LOG_FUNC_EXIT__;
4363 int ws_serv_del(wfd_oem_new_service_s *service)
4365 __WDP_LOG_FUNC_ENTER__;
4366 ws_sock_data_s *sock = g_pd->common;
4367 char cmd[256] = {0, };
4368 char reply[1024]={0,};
4372 WDP_LOGE("Socket is NULL");
4376 switch (service->protocol) {
4377 case WFD_OEM_SERVICE_TYPE_BONJOUR:
4379 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR, Data: %s", service);
4380 char *hex_key = NULL;
4382 res = _convert_bonjour_to_hex(service->data.bonjour.query, NULL, &hex_key);
4384 WDP_LOGE("Failed to convert Key string as hex string");
4388 WDP_LOGD("Converted Hexadecimal string [%s]", hex_key);
4389 snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_DEL " bonjour %s", hex_key);
4393 case WFD_OEM_SERVICE_TYPE_UPNP:
4395 WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_UPNP");
4397 snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_DEL " upnp %s %s",
4398 service->data.upnp.version, service->data.upnp.service);
4402 WDP_LOGE("This service type is not supported");
4403 __WDP_LOG_FUNC_EXIT__;
4407 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4409 WDP_LOGE("Failed to send command to wpa_supplicant");
4410 __WDP_LOG_FUNC_EXIT__;
4414 if (strstr(reply, "FAIL")) {
4415 WDP_LOGE("Failed to add service");
4416 __WDP_LOG_FUNC_EXIT__;
4419 WDP_LOGD("Succeeded to add service");
4421 __WDP_LOG_FUNC_EXIT__;
4424 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
4426 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
4427 int ws_miracast_init(int enable)
4429 __WDP_LOG_FUNC_ENTER__;
4430 ws_sock_data_s *sock = g_pd->common;
4431 char cmd[80] = {0, };
4432 char reply[1024]={0,};
4435 unsigned int length = 0x0006;
4436 unsigned int dev_info = 0x0110;
4437 unsigned int ctrl_port = 0x07E6;
4438 unsigned int max_tput = 0x0028;
4439 //unsigned int bssid = 0x00;
4440 unsigned int cpled_sink_status = 0x00;
4441 /* param : enable or disable*/
4444 WDP_LOGE("Socket is NULL");
4448 snprintf(cmd, sizeof(cmd), WS_CMD_SET "wifi_display %d", enable);
4450 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4452 WDP_LOGE("Failed to send command to wpa_supplicant");
4453 __WDP_LOG_FUNC_EXIT__;
4457 if (strstr(reply, "FAIL")) {
4458 WDP_LOGE("Failed to initialize miracast");
4459 __WDP_LOG_FUNC_EXIT__;
4462 WDP_LOGD("Succeeded to initialize miracast");
4465 /* param : dev_info */
4466 memset(cmd, 0x0, 80);
4467 memset(reply, 0x0, WS_REPLY_LEN);
4469 snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x%04x%04x",
4470 WFD_SUBELM_ID_DEV_INFO, length, dev_info, ctrl_port, max_tput);
4471 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4473 WDP_LOGE("Failed to send command to wpa_supplicant");
4474 __WDP_LOG_FUNC_EXIT__;
4478 if (strstr(reply, "FAIL")) {
4479 WDP_LOGE("Failed to set miracast parameter(device info)");
4480 __WDP_LOG_FUNC_EXIT__;
4483 WDP_LOGD("Succeeded to set miracast parameter(device info)");
4485 /* param : Associated BSSID Subelement */
4486 memset(cmd, 0x0, 80);
4487 memset(reply, 0x0, WS_REPLY_LEN);
4489 snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%s",
4490 WFD_SUBELM_ID_ASSOC_BSSID, WFD_SUBELM_LEN_ASSOC_BSSID, "000000000000");
4491 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4493 WDP_LOGE("Failed to send command to wpa_supplicant");
4494 __WDP_LOG_FUNC_EXIT__;
4498 if (strstr(reply, "FAIL")) {
4499 WDP_LOGE("Failed to set miracast parameter(BSSID subelement)");
4500 __WDP_LOG_FUNC_EXIT__;
4503 WDP_LOGD("Succeeded to set miracast parameter(BSSID subelement)");
4505 /* param : cpled_sink_status */
4506 memset(cmd, 0x0, 80);
4507 memset(reply, 0x0, WS_REPLY_LEN);
4509 snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%02x",
4510 WFD_SUBELM_ID_CUPLED_SYNC_INFO, 0x01, cpled_sink_status);
4511 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4513 WDP_LOGE("Failed to send command to wpa_supplicant");
4514 __WDP_LOG_FUNC_EXIT__;
4518 if (strstr(reply, "FAIL")) {
4519 WDP_LOGE("Failed to set miracast parameter(Cuppled sink status)");
4520 __WDP_LOG_FUNC_EXIT__;
4523 WDP_LOGD("Succeeded to set miracast parameter(Cuppled sink status)");
4526 /* param : WFD Extended Capability */
4527 memset(cmd, 0x0, 80);
4528 memset(reply, 0x0, WS_REPLY_LEN);
4530 snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x",
4531 WFD_SUBELM_ID_EXT_CAPAB, 0x02, 0x00);
4532 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4534 WDP_LOGE("Failed to send command to wpa_supplicant");
4535 __WDP_LOG_FUNC_EXIT__;
4539 if (strstr(reply, "FAIL")) {
4540 WDP_LOGE("Failed to set miracast parameter(Extended Capability)");
4541 __WDP_LOG_FUNC_EXIT__;
4544 WDP_LOGD("Succeeded to set miracast parameter(Extended Capability)");
4548 __WDP_LOG_FUNC_EXIT__;
4552 int ws_set_display(wfd_oem_display_s *wifi_display)
4554 __WDP_LOG_FUNC_ENTER__;
4555 ws_sock_data_s *sock = g_pd->common;
4556 char cmd[80] = {0, };
4557 char reply[1024]={0,};
4559 unsigned int device_info = 0;
4562 WDP_LOGE("Socket is NULL");
4566 WDP_LOGD("Wi-Fi Display type: [%d]", wifi_display->type);
4567 WDP_LOGD("Wi-Fi Display avai: [%d]", wifi_display->availablity);
4568 WDP_LOGD("Wi-Fi Display hdcp: [%d]", wifi_display->hdcp_support);
4569 WDP_LOGD("Wi-Fi Display hdcp: [%d]", wifi_display->port);
4570 WDP_LOGD("Wi-Fi Display sync: [%d]", wifi_display->max_tput);
4572 device_info = wifi_display->type;
4573 device_info+= (wifi_display->hdcp_support)<<8;
4574 device_info+= (wifi_display->availablity)<<4; //for availability bit
4576 snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x%04x%04x",
4577 WFD_SUBELM_ID_DEV_INFO, WFD_SUBELEM_LEN_DEV_INFO,
4578 device_info, wifi_display->port, wifi_display->max_tput);
4580 WDP_LOGD("Wi-Fi Display set command: [%s]", cmd);
4581 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4583 WDP_LOGE("Failed to send command to wpa_supplicant");
4584 __WDP_LOG_FUNC_EXIT__;
4588 if (strstr(reply, "FAIL")) {
4589 WDP_LOGE("Failed to set wifi display");
4590 __WDP_LOG_FUNC_EXIT__;
4593 WDP_LOGD("Succeeded to set wifi display");
4595 __WDP_LOG_FUNC_EXIT__;
4598 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
4602 __WDP_LOG_FUNC_ENTER__;
4607 __WDP_LOG_FUNC_EXIT__;