[Support Legacy Connection] Update peer disconnection logic.
[platform/core/connectivity/wifi-direct-manager.git] / plugin / wpasupplicant / ctrl_iface_sock / wfd-plugin-wpasupplicant.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /**
21  * This file implements wifi direct wpasupplicant plugin functions.
22  *
23  * @file                wfd_plugin_wpasupplicant.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <sys/socket.h>
34 #include <sys/un.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #define _GNU_SOURCE
38 #include <poll.h>
39 #include <errno.h>
40 #include <sys/ioctl.h>
41 #include <net/if.h>
42 #include <arpa/inet.h>
43
44 #include <glib.h>
45 #include <gio/gio.h>
46
47 #include <tzplatform_config.h>
48
49 #include "wifi-direct-oem.h"
50 #include "wfd-plugin-log.h"
51 #include "wfd-plugin-wpasupplicant.h"
52
53 #define NETCONFIG_SERVICE                               "net.netconfig"
54 #define NETCONFIG_WIFI_INTERFACE                "net.netconfig.wifi"
55 #define NETCONFIG_WIFI_PATH                             "/net/netconfig/wifi"
56
57 #define NETCONFIG_DBUS_REPLY_TIMEOUT    (10 * 1000)
58
59 #define SUPPL_GLOBAL_INTF_PATH tzplatform_mkpath(TZ_SYS_RUN, "wpa_global/")
60 #define SUPPL_IFACE_PATH tzplatform_mkpath(TZ_SYS_RUN, "wpa_supplicant/")
61 #define SUPPL_GROUP_IFACE_PATH tzplatform_mkpath(TZ_SYS_RUN, "wpa_supplicant/")
62
63 #if defined TIZEN_MOBILE
64 #define DEFAULT_MAC_FILE_PATH tzplatform_mkpath(TZ_SYS_ETC, ".mac.info")
65 #endif
66
67 #if defined TIZEN_WIFI_MODULE_BUNDLE
68 #define DEFAULT_MAC_FILE_PATH "/sys/class/net/wlan0/address"
69 #endif
70
71 #ifndef DEFAULT_MAC_FILE_PATH
72 #define DEFAULT_MAC_FILE_PATH "/sys/class/net/p2p0/address"
73 #endif
74
75 ws_string_s ws_event_strs[] = {
76         /* discovery */
77         {"P2P-DEVICE-FOUND", WS_EVENT_DEVICE_FOUND},
78         {"P2P-DEVICE-LOST", WS_EVENT_DEVICE_LOST},
79         {"P2P-FIND-STOPPED", WS_EVENT_FIND_STOPED},
80
81         /* provision discovery */
82         {"P2P-PROV-DISC-PBC-REQ", WS_EVENT_PROV_DISC_PBC_REQ},
83         {"P2P-PROV-DISC-SHOW-PIN", WS_EVENT_PROV_DISC_SHOW_PIN},
84         {"P2P-PROV-DISC-ENTER-PIN", WS_EVENT_PROV_DISC_ENTER_PIN},
85         {"P2P-PROV-DISC-PBC-RESP", WS_EVENT_PROV_DISC_PBC_RESP},
86         {"P2P-PROV-DISC-FAILURE", WS_EVENT_PROV_DISC_FAILURE},
87
88         /* connection */
89         {"P2P-GO-NEG-REQUEST", WS_EVENT_GO_NEG_REQUEST},
90         {"P2P: Received GO Negotiation Request from", WS_EVENT_GO_NEG_REQUEST},
91         {"P2P-GO-NEG-FAILURE", WS_EVENT_GO_NEG_FAILURE},
92         {"P2P-GO-NEG-SUCCESS", WS_EVENT_GO_NEG_SUCCESS},
93         {"WPS-FAIL", WS_EVENT_WPS_FAIL},
94         {"P2P-GROUP-FORMATION-FAILURE", WS_EVENT_GROUP_FORMATION_FAILURE},
95         {"WPS-SUCCESS", WS_EVENT_WPS_SUCCESS},
96         {"WPS-REG-SUCCESS", WS_EVENT_WPS_REG_SUCCESS},
97         {"P2P-GROUP-FORMATION-SUCCESS", WS_EVENT_GROUP_FORMATION_SUCCESS},
98
99         {"AP-STA-CONNECTED", WS_EVENT_STA_CONNECTED},
100
101         /* invite */
102         {"P2P-INVITATION-RECEIVED", WS_EVENT_INVITATION_RECEIVED},
103         {"P2P-INVITATION-RESULT", WS_EVENT_INVITATION_RESULT},
104
105         {"AP-STA-DISCONNECTED", WS_EVENT_STA_DISCONNECTED},
106
107         /* group */
108         {"P2P-GROUP-STARTED", WS_EVENT_GROUP_STARTED},
109         {"P2P-GROUP-REMOVED", WS_EVENT_GROUP_REMOVED},
110
111 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
112         {"P2P-SERV-DISC-RESP", WS_EVENT_SERV_DISC_RESP},
113 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
114
115         {"CTRL-EVENT-TERMINATING", WS_EVENT_TERMINATING},
116
117         {"", WS_EVENT_LIMIT},
118         };
119
120 ws_string_s ws_dev_info_strs[] = {
121         {"p2p_dev_addr", WS_DEV_INFO_P2P_DEV_ADDR},
122         {"name", WS_DEV_INFO_DEV_NAME},
123         {"pri_dev_type", WS_DEV_INFO_DEV_TYPE},
124         {"config_methods", WS_DEV_INFO_CONFIG_METHODS},
125         {"dev_capab", WS_DEV_INFO_DEV_CAP},
126         {"group_capab", WS_DEV_INFO_GROUP_CAP},
127         {"p2p_go_addr", WS_DEV_INFO_P2P_GO_ADDR},
128 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
129         {"wfd_dev_info", WS_DEV_INFO_WFD_DEV_INFO},
130 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
131         {"", WS_DEV_INFO_LIMIT},
132         };
133
134 ws_string_s ws_conn_info_strs[] = {
135         {"dev_passwd_id", WS_CONN_INFO_DEV_PWD_ID},
136         {"status", WS_CONN_INFO_STATUS},
137         {"config_error", WS_CONN_INFO_ERROR},
138         {"", WS_CONN_INFO_LIMIT},
139         };
140
141 ws_string_s ws_invite_info_strs[] = {
142         {"sa", WS_INVITE_INFO_SRC_ADDR},
143         {"go_dev_addr", WS_INVITE_INFO_GO_DEV_ADDR},
144         {"bssid", WS_INVITE_INFO_BSSID},
145         {"listen", WS_INVITE_INFO_LISTEN},
146         {"op_freq", WS_INVITE_INFO_FREQ},
147         {"persistent_id", WS_INVITE_INFO_PERSISTENT_ID},
148         {"status", WS_INVITE_INFO_STATUS},
149         {"", WS_INVITE_INFO_LIMIT},
150         };
151
152 ws_string_s ws_group_info_strs[] = {
153         {"ssid", WS_GROUP_INFO_SSID},
154         {"freq", WS_GROUP_INFO_FREQ},
155         {"passphrase", WS_GROUP_INFO_PASS},
156         {"go_dev_addr", WS_GROUP_INFO_GO_DEV_ADDR},
157         {"status", WS_GROUP_INFO_STATUS},
158         {"[PERSISTENT]", WS_GROUP_INFO_PERSISTENT},
159 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
160         {"ip_addr", WS_GROUP_INFO_IP_ADDR},
161         {"ip_mask", WS_GROUP_INFO_IP_MASK},
162         {"go_ip_addr", WS_GROUP_INFO_GO_IP_ADDR},
163 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
164         {"", WS_GROUP_INFO_LIMIT},
165
166         };
167
168 ws_string_s ws_peer_info_strs[] = {
169         {"age", WS_PEER_INFO_AGE},
170         {"listen_freq", WS_PEER_INFO_LISTEN_FREQ},
171         {"level", WS_PEER_INFO_LEVEL},
172         {"wps_method", WS_PEER_INFO_WPS_METHOD},
173         {"interface_addr", WS_PEER_INFO_INTERFACE_ADDR},
174         {"member_in_go_dev", WS_PEER_INFO_MEMBER_IN_GO_DEV},
175         {"member_in_go_iface", WS_PEER_INFO_MEMBER_IN_GO_IFACE},
176         {"pri_dev_type", WS_PEER_INFO_PRI_DEV_TYPE},
177         {"device_name", WS_PEER_INFO_DEVICE_NAME},
178         {"manufacturer", WS_PEER_INFO_MANUFACTURER},
179         {"model_name", WS_PEER_INFO_MODEL_NAME},
180         {"model_number", WS_PEER_INFO_MODEL_NUMBER},
181         {"serial_number", WS_PEER_INFO_SERIAL_NUMBER},
182         {"config_methods", WS_PEER_INFO_CONFIG_METHODS},
183         {"dev_capab", WS_PEER_INFO_DEV_CAPAB},
184         {"group_capab", WS_PEER_INFO_GROUP_CAPAB},
185         {"go_neg_req_sent", WS_PEER_INFO_GO_NEG_REQ_SENT},
186         {"go_state", WS_PEER_INFO_GO_STATE},
187         {"dialog_token", WS_PEER_INFO_DIALOG_TOKEN},
188         {"intended_addr", WS_PEER_INFO_INTENDED_ADDR},
189         {"country", WS_PEER_INFO_COUNTRY},
190         {"oper_freq", WS_PEER_INFO_OPER_FREQ},
191         {"req_config_methods", WS_PEER_INFO_REQ_CONFIG_METHODS},
192         {"flags", WS_PEER_INFO_FLAGS},
193         {"status", WS_PEER_INFO_STATUS},
194         {"wait_count", WS_PEER_INFO_WAIT_COUNT},
195         {"invitation_reqs", WS_PEER_INFO_INVITATION_REQS},
196 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
197         {"wfd_subelems", WS_PEER_INFO_WFD_SUBELEMS},
198 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
199         };
200
201 ws_string_s ws_conf_attr_strs[] = {
202         {"device_name", WFD_OEM_CONFIG_ATTR_STR_DEVICE_NAME},
203         {"p2p_ssid_postfix", WFD_OEM_CONFIG_ATTR_STR_SSID_POSTFIX},
204         {"country", WFD_OEM_CONFIG_ATTR_STR_COUNTRY},
205         {"p2p_go_intent", WFD_OEM_CONFIG_ATTR_NUM_GO_INTENT},
206         {"p2p_listen_channel", WFD_OEM_CONFIG_ATTR_NUM_LISTEN_FREQ},
207         {"p2p_oper_channel", WFD_OEM_CONFIG_ATTR_NUM_OPER_FREQ},
208         {"p2p_pref_chan", WFD_OEM_CONFIG_ATTR_NUM_PREF_FREQ},
209         {"persistent_reconnect", WFD_OEM_CONFIG_ATTR_NUM_PERSIST_RECONN},
210         {"wifi_display", WFD_OEM_CONFIG_ATTR_NUM_WIFI_DISPLAY},
211         {"p2p_disabled", WFD_OEM_CONFIG_ATTR_NUM_P2P_DISABLED},
212         {"max_num_sta", WFD_OEM_CONFIG_ATTR_NUM_MAX_STA},
213         };
214
215 static wfd_oem_ops_s supplicant_ops = {
216         .init = ws_init,
217         .deinit = ws_deinit,
218         .activate = ws_activate,
219         .deactivate = ws_deactivate,
220
221         .start_scan = ws_start_scan,
222         .stop_scan = ws_stop_scan,
223         .get_visibility = ws_get_visibility,
224         .set_visibility = ws_set_visibility,
225         .get_scan_result = ws_get_scan_result,
226         .get_peer_info = ws_get_peer_info,
227
228         .prov_disc_req = ws_prov_disc_req,
229
230         .connect = ws_connect,
231         .disconnect = ws_disconnect,
232         .reject_connection = ws_reject_connection,
233         .cancel_connection = ws_cancel_connection,
234
235         .get_connected_peers = ws_get_connected_peers,
236         .get_pin = ws_get_pin,
237         .set_pin = ws_set_pin,
238         .generate_pin = ws_generate_pin,
239         .get_supported_wps_mode = ws_get_supported_wps_mode,
240
241         .create_group = ws_create_group,
242         .destroy_group = ws_destroy_group,
243         .invite = ws_invite,
244         .wps_start = ws_wps_start,
245         .enrollee_start = ws_enrollee_start,
246         .wps_cancel = ws_wps_cancel,
247
248         .get_dev_name = ws_get_dev_name,
249         .set_dev_name = ws_set_dev_name,
250         .get_dev_mac = ws_get_dev_mac,
251         .get_dev_type = ws_get_dev_type,
252         .set_dev_type = ws_set_dev_type,
253         .get_go_intent = ws_get_go_intent,
254         .set_go_intent = ws_set_go_intent,
255         .set_country = ws_set_country,
256         .get_persistent_groups = ws_get_persistent_groups,
257         .remove_persistent_group = ws_remove_persistent_group,
258         .set_persistent_reconnect = ws_set_persistent_reconnect,
259
260 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
261         .start_service_discovery = ws_start_service_discovery,
262         .cancel_service_discovery = ws_cancel_service_discovery,
263
264         .serv_add = ws_serv_add,
265         .serv_del = ws_serv_del,
266 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
267
268 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
269         .miracast_init = ws_miracast_init,
270         .set_display = ws_set_display,
271 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
272
273         .refresh = ws_refresh,
274         .save_config = ws_save_config,
275         .set_operating_channel = ws_set_operating_channel,
276         .remove_all_network = ws_remove_all_network,
277         .get_wpa_status = ws_get_wpa_status,
278
279 #if defined(TIZEN_FEATURE_ASP)
280         .advertise_service = ws_advertise_service,
281         .cancel_advertise_service = ws_cancel_advertise_service,
282         .seek_service = ws_seek_service,
283         .cancel_seek_service = ws_cancel_seek_service,
284         .asp_prov_disc_req = ws_asp_prov_disc_req,
285 #endif /* TIZEN_FEATURE_ASP */
286         };
287
288 static ws_plugin_data_s *g_pd;
289 static unsigned char g_pd_out[OEM_MACADDR_LEN];
290 static unsigned char null_mac[OEM_MACADDR_LEN] = {0, 0, 0, 0, 0, 0};
291
292 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
293 static GList *service_list;
294 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
295
296 static gboolean ws_event_handler(GIOChannel *source,
297                                                            GIOCondition condition,
298                                                            gpointer data);
299
300 int wfd_plugin_load(wfd_oem_ops_s **ops)
301 {
302         if (!ops) {
303                 WDP_LOGE("Invalid parameter");
304                 return -1;
305         }
306
307         *ops = &supplicant_ops;
308
309         return 0;
310 }
311
312 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
313 static int _change_str_order(char *src, int length, int unit, char *dest)
314 {
315         int i = 0;
316
317         if (!src || length < 0 || length < unit || !dest) {
318                 WDP_LOGE("Invalid parameter");
319                 return -1;
320         }
321
322         for (i = 0; i < (length / unit); i++)
323                 memcpy(dest + length - (i + 1) * unit, src + (i * unit), unit);
324
325         return 0;
326 }
327
328
329 static int _ws_hex_to_num(char *src, int len)
330 {
331         char *temp = NULL;
332         int num = 0;
333
334         if (!src || len < 0) {
335                 WDP_LOGE("Invalid parameter");
336                 return -1;
337         }
338
339         temp = (char*) g_try_malloc0(len + 1);
340         if (!temp) {
341                 WDP_LOGE("Failed to allocate memory");
342                 return -1;
343         }
344
345         memcpy(temp, src, len);
346         num = strtoul(temp, NULL, 16);
347         free(temp);
348
349         return num;
350 }
351 #if 0
352 static int _ws_hex_to_txt(char *src, int length, char *dest)
353 {
354         char *temp = NULL;
355         char *ptr = NULL;
356         int len = 0;
357         int i = 0;
358
359         if (!src || length < 0 || !dest) {
360                 WDP_LOGE("Invalid parameter");
361                 return -1;
362         }
363
364         ptr = src;
365         temp = dest;
366
367         if (!length)
368                 len = strlen(src);
369         else
370                 len = length;
371
372         for (i = 0; i < (len / 2) && *ptr != 0; i++) {
373                 temp[i] = (char) _ws_hex_to_num(ptr, 2);
374                 if (temp[i] < 0) {
375                         WDP_LOGE("Failed to convert hexa string to num");
376                         return -1;
377                 }
378                 ptr += 2;
379         }
380
381         return 0;
382 }
383 #endif
384 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
385
386 static int _ws_txt_to_devtype(char *txt, int *pri, int *sec)
387 {
388         if (!txt || !pri || !sec) {
389                 WDP_LOGE("Invalid parameter");
390                 return -1;
391         }
392
393         if (strlen(txt) > WS_DEVTYPESTR_LEN) {
394                 WDP_LOGE("Device type string is invalid [%s]", txt);
395                 return -1;
396         }
397
398         *pri = (int) strtoul(txt, &txt, 0);
399         txt = strrchr(txt, '-');
400         *sec = (int) strtoul(txt+1, &txt, 16);
401
402         return 0;
403 }
404
405 static int _ws_txt_to_mac(char *txt, unsigned char *mac)
406 {
407         int i = 0;
408
409         if (!txt || !mac) {
410                 WDP_LOGE("Invalid parameter");
411                 return -1;
412         }
413
414         for (;;) {
415                 mac[i++] = (char) strtoul(txt, &txt, 16);
416                 if (!*txt++ || i == 6)
417                         break;
418         }
419
420         if (i != OEM_MACADDR_LEN)
421                 return -1;
422
423         return 0;
424 }
425
426 static char *_ws_wps_to_txt(int wps_mode)
427 {
428         switch (wps_mode) {
429         case WFD_OEM_WPS_MODE_PBC:
430                 return WS_STR_PBC;
431                 break;
432         case WFD_OEM_WPS_MODE_DISPLAY:
433                 return WS_STR_DISPLAY;
434                 break;
435         case WFD_OEM_WPS_MODE_KEYPAD:
436                 return WS_STR_KEYPAD;
437                 break;
438         default:
439                 return "";
440                 break;
441         }
442 }
443
444 static int _ws_freq_to_channel(int freq)
445 {
446         if (freq < 2412 || freq > 5825 ||
447                 (freq > 2484 && freq < 5180)) {
448                 WDP_LOGE("Invalid parameter");
449                 return -1;
450         }
451
452         if (freq >= 5180)
453                 return 36 + (freq - 5180)/5;
454         else if (freq <= 2472)
455                 return 1 + (freq - 2412)/5;
456         else if (freq == 2484)
457                 return 14;
458         else
459                 return -1;
460 }
461
462 gboolean _ws_util_execute_file(const char *file_path,
463         char *const args[], char *const envs[])
464 {
465         pid_t pid = 0;
466         int rv = 0;
467         errno = 0;
468         register unsigned int index = 0;
469
470         while (args[index] != NULL) {
471                 WDP_LOGD("[%s]", args[index]);
472                 index++;
473         }
474
475         if (!(pid = fork())) {
476                 WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
477                 WDP_LOGD("Inside child, exec (%s) command", file_path);
478
479                 errno = 0;
480                 if (execve(file_path, args, envs) == -1) {
481                         WDP_LOGE("Fail to execute command (%s)", strerror(errno));
482                         exit(1);
483                 }
484         } else if (pid > 0) {
485                 if (waitpid(pid, &rv, 0) == -1)
486                         WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
487                 if (WIFEXITED(rv))
488                         WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
489                 else if (WIFSIGNALED(rv))
490                         WDP_LOGD("killed by signal %d", WTERMSIG(rv));
491                 else if (WIFSTOPPED(rv))
492                         WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
493                 else if (WIFCONTINUED(rv))
494                         WDP_LOGD("continued");
495
496                 return TRUE;
497         }
498
499         WDP_LOGE("failed to fork (%s)", strerror(errno));
500         return FALSE;
501 }
502
503 static int _ws_check_socket(int sock)
504 {
505         struct pollfd p_fd;
506         int res = 0;
507
508         p_fd.fd = sock;
509         p_fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL;
510         res = poll((struct pollfd *) &p_fd, 1, 1);
511
512         if (res < 0) {
513                 WDP_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
514                 return -1;
515         } else if (res == 0) {
516                 WDP_LOGD("poll timeout. socket is busy\n");
517                 return 1;
518         } else {
519
520                 if (p_fd.revents & POLLERR) {
521                         WDP_LOGE("Error! POLLERR from socket[%d]", sock);
522                         return -1;
523                 } else if (p_fd.revents & POLLHUP) {
524                         WDP_LOGE("Error! POLLHUP from socket[%d]", sock);
525                         return -1;
526                 } else if (p_fd.revents & POLLNVAL) {
527                         WDP_LOGE("Error! POLLNVAL from socket[%d]", sock);
528                         return -1;
529                 } else if (p_fd.revents & POLLIN) {
530                         WDP_LOGD("POLLIN from socket [%d]", sock);
531                         return 0;
532                 } else if (p_fd.revents & POLLOUT) {
533                         WDP_LOGD("POLLOUT from socket [%d]", sock);
534                         return 0;
535                 }
536         }
537
538         WDP_LOGD("Unknown poll event [%d]", p_fd.revents);
539         return -1;
540 }
541
542 static int _ws_read_sock(int sock, char *data, int data_len)
543 {
544         __WDP_LOG_FUNC_ENTER__;
545         struct pollfd p_fd;
546         int p_ret = 0;
547         int rbytes = 0;
548
549         if (sock < SOCK_FD_MIN || !data || data_len <= 0) {
550                 WDP_LOGE("Invalid parameter");
551                 return -1;
552         }
553
554         p_fd.fd = sock;
555         p_fd.events = POLLIN | POLLERR | POLLHUP;
556         p_ret = poll(&p_fd, 1, WS_POLL_TIMEOUT);
557
558         errno = 0;
559         if (p_ret > 0) {
560                 if (p_fd.revents & POLLIN) {
561                         WDP_LOGD("POLLIN from socket [%d]", sock);
562                         errno = 0;
563                         rbytes = read(sock, data, data_len);
564                         if (rbytes < 0) {
565                                 WDP_LOGE("Failed to read data from socket[%d]. [%s]", sock, strerror(errno));
566                                 return -1;
567                         }
568                         data[data_len-1] = '\0';
569                         __WDP_LOG_FUNC_EXIT__;
570                         return rbytes;
571                 } else if (p_fd.revents & POLLERR) {
572                         WDP_LOGE("Error! POLLERR from socket[%d]", sock);
573                         return -1;
574                 } else if (p_fd.revents & POLLHUP) {
575                         WDP_LOGE("Error! POLLHUP from socket[%d]", sock);
576                         return -1;
577                 }
578         } else if (p_ret == 0) {
579                 WDP_LOGE("Polling timeout from socket[%d]", sock);
580         } else {
581                 WDP_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
582         }
583
584         __WDP_LOG_FUNC_EXIT__;
585         return -1;
586 }
587
588 static int _ws_send_cmd(int sock, char *cmd, char *reply, int reply_len)
589 {
590         __WDP_LOG_FUNC_ENTER__;
591         int wbytes = 0;
592         int res = 0;
593
594         if (sock < SOCK_FD_MIN || !cmd || !reply || reply_len < 0) {
595                 WDP_LOGE("Invalid parameter");
596                 return -1;
597         }
598         WDP_SECLOGD("Sending command [%s]", cmd);
599
600         res = _ws_check_socket(sock);
601         if (res < 0) {
602                 WDP_LOGE("Socket error");
603                 return -1;
604         } else if (res > 0) {
605                 WDP_LOGE("Socket is busy");
606                 return -2;
607         }
608
609         errno = 0;
610         wbytes = write(sock, cmd, strlen(cmd));
611         if (wbytes < 0) {
612                 WDP_LOGE("Failed to write into socket[%d]. [%s]", sock, strerror(errno));
613                 return -1;
614         }
615
616         res = _ws_read_sock(sock, reply, reply_len);
617         if (res < 0) {
618                 WDP_LOGE("Failed to read return for command");
619                 __WDP_LOG_FUNC_EXIT__;
620                 return -1;
621         }
622
623         __WDP_LOG_FUNC_EXIT__;
624         return 0;
625 }
626
627 static int _ws_flush()
628 {
629         __WDP_LOG_FUNC_ENTER__;
630         ws_sock_data_s *sock = g_pd->common;
631         char reply[1024] = {0,};
632         int res = 0;
633
634         if (!sock) {
635                 WDP_LOGE("Socket is NULL");
636                 return -1;
637         }
638
639         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_FLUSH, reply, sizeof(reply));
640         if (res < 0) {
641                         WDP_LOGE("Failed to send command to wpa_supplicant");
642                         __WDP_LOG_FUNC_EXIT__;
643                         return -1;
644         }
645
646         if (strstr(reply, "FAIL")) {
647                 WDP_LOGE("Failed to flush");
648                 __WDP_LOG_FUNC_EXIT__;
649                 return -1;
650         }
651         WDP_LOGD("Succeeded to flush");
652
653         __WDP_LOG_FUNC_EXIT__;
654         return 0;
655 }
656
657 static int _ws_cancel()
658 {
659         __WDP_LOG_FUNC_ENTER__;
660         ws_sock_data_s *sock = g_pd->common;
661         char reply[1024] = {0,};
662         int res = 0;
663
664         if (!sock) {
665                 WDP_LOGE("Socket is NULL");
666                 return -1;
667         }
668
669         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_CANCEL, reply, sizeof(reply));
670         if (res < 0) {
671                         WDP_LOGE("Failed to send command to wpa_supplicant");
672                         __WDP_LOG_FUNC_EXIT__;
673                         return -1;
674         }
675
676         if (strstr(reply, "FAIL")) {
677                 WDP_LOGE("Failed to cancel");
678                 __WDP_LOG_FUNC_EXIT__;
679                 return -1;
680         }
681         WDP_LOGD("Succeeded to cancel");
682
683         __WDP_LOG_FUNC_EXIT__;
684         return 0;
685 }
686
687 static int _create_ctrl_intf(char *ctrl_intf_path, char *supp_path)
688 {
689         __WDP_LOG_FUNC_ENTER__;
690         struct sockaddr_un srv_addr;
691         struct sockaddr_un local_addr;
692         int sock = 0;
693         int res = 0;
694
695         if (!ctrl_intf_path || !supp_path) {
696                 WDP_LOGE("Invalid parameter");
697                 return -1;
698         }
699         unlink(ctrl_intf_path);
700
701         errno = 0;
702         sock = socket(AF_UNIX, SOCK_DGRAM, 0);
703         if (sock < SOCK_FD_MIN) {
704                 WDP_LOGE("Failed to create socket. [%s]", strerror(errno));
705                 if (sock >= 0)
706                         close(sock);
707                 __WDP_LOG_FUNC_EXIT__;
708                 return -1;
709         }
710         WDP_LOGI("Succeeded to create socket [%d]\n", sock);
711
712         memset(&srv_addr, 0, sizeof(srv_addr));
713         srv_addr.sun_family = AF_UNIX;
714         snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", supp_path);
715
716         memset(&local_addr, 0, sizeof(local_addr));
717         local_addr.sun_family = AF_UNIX;
718         snprintf(local_addr.sun_path, sizeof(local_addr.sun_path), "%s", ctrl_intf_path);
719
720         res = bind(sock, (struct sockaddr*) &local_addr, sizeof(local_addr));
721         if (res < 0) {
722                 WDP_LOGE("Failed to bind local socket [%s]. Try again...", strerror(errno));
723                 unlink(ctrl_intf_path);
724
725                 close(sock);
726                 __WDP_LOG_FUNC_EXIT__;
727                 return -1;
728         }
729
730         errno = 0;
731         res = connect(sock, (struct sockaddr*) &srv_addr, sizeof(srv_addr));
732         if (res < 0) {
733                 WDP_LOGE("Failed to connect to server socket [%s]", strerror(errno));
734                 close(sock);
735                 __WDP_LOG_FUNC_EXIT__;
736                 return -1;
737         }
738         WDP_LOGI("Succeeded to connect to server socket [%d]", sock);
739
740         __WDP_LOG_FUNC_EXIT__;
741         return sock;
742 }
743
744 static int _attach_mon_intf(int sock)
745 {
746         __WDP_LOG_FUNC_ENTER__;
747         char cmd[8] = {0};
748         char reply[8] = {0,};
749         int res = 0;
750
751         if (sock < SOCK_FD_MIN) {
752                 WDP_LOGE("Invalid parameter");
753                 return -1;
754         }
755
756         snprintf(cmd, sizeof(cmd), WS_CMD_ATTACH);
757         res = _ws_send_cmd(sock, cmd, reply,  sizeof(reply));
758         if (res < 0) {
759                 WDP_LOGE("Failed to send command to wpa_supplicant");
760                 __WDP_LOG_FUNC_EXIT__;
761                 return -1;
762         }
763
764         if (strstr(reply, "FAIL")) {
765                 WDP_LOGE("Failed to operate command(wpa_supplicant)");
766                 __WDP_LOG_FUNC_EXIT__;
767                 return -1;
768         }
769
770         __WDP_LOG_FUNC_EXIT__;
771         return 0;
772 }
773
774 static int _connect_to_supplicant(char *ifname, ws_sock_data_s **sock_data)
775 {
776         __WDP_LOG_FUNC_ENTER__;
777         ws_sock_data_s *sock = NULL;
778         int ctrl_sock = -1;
779         int mon_sock = -1;
780         char ctrl_path[32] = {0, };
781         char mon_path[32] = {0, };
782         char suppl_path[40] = {0, };
783         int res = 0;
784         int i = 0;
785
786         const char *supp_iface_path = SUPPL_IFACE_PATH;
787         const char *supp_group_iface_path = SUPPL_GROUP_IFACE_PATH;
788
789         if (!ifname || !sock_data) {
790                 WDP_LOGE("Invalie parameter");
791                 __WDP_LOG_FUNC_EXIT__;
792                 return -1;
793         }
794
795         errno = 0;
796         sock = (ws_sock_data_s*) g_try_malloc0(sizeof(ws_sock_data_s));
797         if (!sock) {
798                 WDP_LOGE("Failed to allocate memory for socket data", strerror(errno));
799                 __WDP_LOG_FUNC_EXIT__;
800                 return -1;
801         }
802
803         snprintf(ctrl_path, sizeof(ctrl_path), "/tmp/%s_control", ifname);
804         snprintf(mon_path, sizeof(mon_path), "/tmp/%s_monitor", ifname);
805         if (strncmp(ifname, GROUP_IFACE_NAME, 11))
806                 g_snprintf(suppl_path, sizeof(suppl_path), "%s%s", supp_iface_path, ifname);
807         else
808                 g_snprintf(suppl_path, sizeof(suppl_path), "%s%s", supp_group_iface_path, ifname);
809
810
811         for (i = 0; i < WS_CONN_RETRY_COUNT; i++) {
812                 ctrl_sock = _create_ctrl_intf(ctrl_path, suppl_path);
813                 if (ctrl_sock < SOCK_FD_MIN) {
814                         WDP_LOGE("Failed to create control interface socket for %s", ifname);
815                         continue;
816                 }
817                 WDP_LOGD("Succeeded to create control interface socket[%d] for %s", ctrl_sock, ifname);
818
819                 mon_sock = _create_ctrl_intf(mon_path, suppl_path);
820                 if (mon_sock < SOCK_FD_MIN) {
821                         WDP_LOGE("Failed to create monitor interface socket for %s", ifname);
822                         close(ctrl_sock);
823                         ctrl_sock = -1;
824                         continue;
825                 }
826                 WDP_LOGD("Succeeded to create monitor interface socket[%d] for %s", mon_sock, ifname);
827
828                 res = _attach_mon_intf(mon_sock);
829                 if (res < 0) {
830                         WDP_LOGE("Failed to attach monitor interface for event");
831                         close(ctrl_sock);
832                         ctrl_sock = -1;
833                         close(mon_sock);
834                         mon_sock = -1;
835                         continue;
836                 }
837                 WDP_LOGD("Succeeded to attach monitor interface for event");
838                 break;
839         }
840
841         if (i == WS_CONN_RETRY_COUNT) {
842                 if (ctrl_sock >= 0)
843                         close(ctrl_sock);
844                 if (mon_sock >= 0)
845                         close(mon_sock);
846
847                 free(sock);
848                 __WDP_LOG_FUNC_EXIT__;
849                 return -1;
850         }
851
852         sock->ctrl_sock = ctrl_sock;
853         sock->mon_sock = mon_sock;
854         sock->ifname = strdup(ifname);
855
856         GIOChannel *gio;
857         int gsource = 0;
858         gio = g_io_channel_unix_new(mon_sock);
859         if (!strstr(ifname, GROUP_IFACE_PREFIX))
860                 gsource = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP, (GIOFunc) ws_event_handler, sock);
861         g_io_channel_unref(gio);
862
863         sock->gsource = gsource;
864
865         *sock_data = sock;
866         __WDP_LOG_FUNC_EXIT__;
867         return 0;
868 }
869
870 static gboolean _remove_event_source(gpointer data)
871 {
872         __WDP_LOG_FUNC_ENTER__;
873         ws_sock_data_s *sock_data = NULL;
874         int res = 0;
875
876         sock_data = (ws_sock_data_s *) data;
877         if (sock_data == NULL) {
878                 WDP_LOGE("Invalid sock_data");
879                 return FALSE;
880         }
881
882         if (sock_data->gsource < 0) {
883                 WDP_LOGE("Invalid source ID [%d]", sock_data->gsource);
884                 return FALSE;
885         }
886
887         res = g_source_remove(sock_data->gsource);
888         if (!res) {
889                 WDP_LOGE("Failed to remove GSource(%d)", sock_data->gsource);
890                 return FALSE;
891         }
892         WDP_LOGD("Succeeded to remove GSource");
893
894         __WDP_LOG_FUNC_EXIT__;
895         return FALSE;
896 }
897
898 static int _disconnect_from_supplicant(char *ifname, ws_sock_data_s *sock_data)
899 {
900         __WDP_LOG_FUNC_ENTER__;
901         int res = 0;
902         char ctrl_path[32] = {0, };
903         char mon_path[32] = {0, };
904         char cmd[8] = {0, };
905         char reply[1024] = {0, };
906
907         if (!ifname || !sock_data) {
908                 WDP_LOGE("Invalie parameter");
909                 return -1;
910         }
911
912         /* detach monitor interface */
913         g_snprintf(cmd, sizeof(cmd), WS_CMD_DETACH);
914         res = _ws_send_cmd(sock_data->mon_sock, cmd, reply, sizeof(reply));
915         if (res < 0) {
916                 WDP_LOGE("Failed to send command to wpa_supplicant. Keep going to close socket.");
917         } else {
918                 if (!strncmp(reply, "FAIL", 4)) {
919                         WDP_LOGE("Failed to detach monitor sock [%d]", sock_data->mon_sock);
920                         /* TODO: I think there is no need to exit */
921                         __WDP_LOG_FUNC_EXIT__;
922                         return -1;
923                 }
924                 WDP_LOGD("Succeeded to detach monitor sock for %s", ifname ? ifname : "NULL");
925         }
926
927         if (sock_data->gsource > 0)
928                 g_idle_add(_remove_event_source, (gpointer) sock_data);
929         sock_data->gsource = 0;
930
931         /* close control interface */
932         g_snprintf(ctrl_path, sizeof(ctrl_path), "/tmp/%s_control", ifname);
933         snprintf(mon_path, sizeof(mon_path), "/tmp/%s_monitor", ifname);
934
935         if (sock_data->ctrl_sock >= SOCK_FD_MIN)
936                 close(sock_data->ctrl_sock);
937         sock_data->ctrl_sock = -1;
938         unlink(ctrl_path);
939
940         if (sock_data->mon_sock >= SOCK_FD_MIN)
941                 close(sock_data->mon_sock);
942         sock_data->mon_sock = -1;
943         unlink(mon_path);
944
945         if (sock_data->ifname)
946                 free(sock_data->ifname);
947
948         free(sock_data);
949
950         __WDP_LOG_FUNC_EXIT__;
951         return 0;
952 }
953
954 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
955 int _check_service_query_exists(wfd_oem_service_s *service)
956 {
957         int count = 0;
958         wfd_oem_service_s *data = NULL;
959
960         for (count = 0; count < g_list_length(service_list); count++) {
961                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
962                 if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
963                         WDP_LOGD("Query already exists");
964                         return 1;
965                 }
966         }
967         return 0;
968 }
969
970 static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
971 {
972         if (NULL == s_type || NULL == mac_str || NULL == query_id)
973                 return NULL;
974
975         int count = 0;
976         wfd_oem_service_s *data = NULL;
977
978         for (count = 0; count < g_list_length(service_list); count++) {
979                 data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
980                 if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
981                                 memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
982                         strncpy(query_id, data->query_id, OEM_QUERY_ID_LEN);
983                         break;
984                 }
985         }
986         if (strlen(query_id) <= 0) {
987                 WDP_LOGD("!! Query ID not found !!");
988                 return NULL;
989         }
990
991         WDP_LOGD("query id :[0x%s]", query_id);
992
993         return data;
994
995 }
996 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
997
998 static int _extract_word(const char *data, char **value)
999 {
1000         int i = 0;
1001
1002         if (!data || !value) {
1003                 WDP_LOGE("Invalid parameter");
1004                 return -1;
1005         }
1006
1007         for (i = 0; data[i]; i++)
1008                 if (data[i] == '\n' || data[i] == '\r' || data[i] == ' ' || data[i] == '\t')
1009                         break;
1010
1011         if (i > 0) {
1012                 *value = (char*) g_try_malloc0(i + 1);
1013                 if (!(*value)) {
1014                         WDP_LOGE("Failed to allocate memory for value");
1015                         return -1;
1016                 }
1017                 strncpy(*value, data, i);
1018                 (*value)[i] = '\0';
1019                 WDP_LOGV("Extracted word: %s", *value);
1020         }
1021
1022         return i;
1023 }
1024
1025 static int _extract_value_str(const char *data, const char *key, char **value)
1026 {
1027         char *tmp_str = NULL;
1028         int i = 0;
1029
1030         if (!data || !key || !value) {
1031                 WDP_LOGE("Invalid parameter");
1032                 return -1;
1033         }
1034
1035         tmp_str = strstr(data, key);
1036         if (!tmp_str) {
1037                 WDP_LOGE("Key[%s] is not found", key);
1038                 return -1;
1039         }
1040         tmp_str = tmp_str + strlen(key) + 1;
1041
1042         if (tmp_str[0] == '\'' || tmp_str[0] == '\"') {
1043                 tmp_str += 1;
1044                 for (i = 0; tmp_str[i]; i++) {
1045                         if (tmp_str[i] == '\'' || tmp_str[i] == '\"')
1046                                 break;
1047                 }
1048         } else {
1049                 for (i = 0; tmp_str[i]; i++) {
1050                         if (tmp_str[i] == '\n' || tmp_str[i] == '\r' || tmp_str[i] == ' ')
1051                                 break;
1052                 }
1053         }
1054
1055         if (i > 0) {
1056                 *value = (char*) g_try_malloc0(i + 1);
1057                 if (!(*value)) {
1058                         WDP_LOGE("Failed to allocate memory for value");
1059                         return -1;
1060                 }
1061                 strncpy(*value, tmp_str, i);
1062                 (*value)[i] = '\0';
1063                 WDP_LOGV("Extracted string: %s", *value);
1064                 return i;
1065         }
1066
1067         return 0;
1068 }
1069
1070 static int _extract_peer_value_str(const char *data, const char *key, char **value)
1071 {
1072         char *tmp_str = NULL;
1073         int i = 0;
1074
1075         if (!data || !key || !value) {
1076                 WDP_LOGE("Invalid parameter");
1077                 return -1;
1078         }
1079
1080         tmp_str = strstr(data, key);
1081         if (!tmp_str) {
1082                 WDP_LOGE("Key[%s] is not found", key);
1083                 return -1;
1084         }
1085         tmp_str = tmp_str + strlen(key) + 1;
1086
1087         for (i = 0; tmp_str[i]; i++) {
1088                 if (tmp_str[i] == '\n' || tmp_str[i] == '\r')
1089                         break;
1090         }
1091
1092         if (i > 0) {
1093                 *value = (char*) g_try_malloc0(i + 1);
1094                 if (!(*value)) {
1095                         WDP_LOGE("Failed to allocate memory for value");
1096                         return -1;
1097                 }
1098                 strncpy(*value, tmp_str, i);
1099                 (*value)[i] = '\0';
1100                 WDP_LOGV("Extracted string: %s", *value);
1101                 return i;
1102         }
1103
1104         return 0;
1105 }
1106
1107 #if 0
1108 static int _check_dev_type(unsigned char *dev_addr, int *pri_dev_type, int *sec_dev_type)
1109 {
1110         ws_sock_data_s *sock = g_pd->common;
1111         char cmd[32] = {0, };
1112         char reply[1024] = {0,};
1113         char *manufacturer = NULL;
1114         char *model_name = NULL;
1115         char *model_number = NULL;
1116         int res = 0;
1117
1118         if (!dev_addr || !pri_dev_type || !sec_dev_type) {
1119                 WDP_LOGE("Invalid parameter");
1120                 return -1;
1121         }
1122
1123         if (!sock) {
1124                 WDP_LOGE("Socket is NULL");
1125                 return -1;
1126         }
1127
1128         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER MACSTR, MAC2STR(dev_addr));
1129         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
1130         if (res < 0) {
1131                         WDP_LOGE("Failed to send command to wpa_supplicant");
1132                         __WDP_LOG_FUNC_EXIT__;
1133                         return -1;
1134         }
1135
1136         if (strstr(reply, "FAIL")) {
1137                 WDP_SECLOGD("Failed to get peer info [" MACSTR "]", MAC2STR(dev_addr));
1138                 __WDP_LOG_FUNC_EXIT__;
1139                 return -1;
1140         }
1141         WDP_SECLOGD("Succeeded to get peer info [" MACSTR "]", MAC2STR(dev_addr));
1142
1143         res = _extract_peer_value_str(reply, "model_number", &model_number);
1144         if (res > 0 && !strncmp(model_number, "EAD-T10", 7)) {
1145                 *pri_dev_type = 8;
1146                 *sec_dev_type = 5;
1147                 free(model_number);
1148                 WDP_LOGD("peer device type set as Dongle");
1149                 return 0;
1150         }
1151         if (model_number)
1152                 free(model_number);
1153
1154         _extract_peer_value_str(reply, "manufacturer", &manufacturer);
1155         _extract_peer_value_str(reply, "model_name", &model_name);
1156         if (!manufacturer || !model_name) {
1157                 WDP_LOGE("parsing error");
1158                 if (manufacturer)
1159                         free(manufacturer);
1160                 if (model_name)
1161                         free(model_name);
1162                 return -1;
1163         }
1164
1165         if (!strncmp(manufacturer, "SAMSUNG_ELECTRONICS", 19) &&
1166                                 !strncmp(model_name, "SAMSUNG_MOBILE", 14)) {
1167                 *pri_dev_type = 8;
1168                 *sec_dev_type = 4;
1169                 WDP_LOGD("peer device type set as Homesync");
1170                 free(manufacturer);
1171                 free(model_name);
1172                 return 0;
1173         }
1174         if (manufacturer)
1175                 free(manufacturer);
1176         if (model_name)
1177                 free(model_name);
1178
1179         return -1;
1180 }
1181 #endif
1182
1183 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1184 static int _parsing_wfd_info(char *msg, wfd_oem_display_s *display)
1185 {
1186         __WDP_LOG_FUNC_ENTER__;
1187
1188         char wfd_info_msg[5] = {0, };
1189         char ctrl_port_msg[5] = {0, };
1190         char max_tput_msg[5] = {0, };
1191         int wfd_info = 0;
1192         if (!msg || strlen(msg) < 12) {
1193                 WDP_LOGE("Invalid parameter");
1194                 __WDP_LOG_FUNC_EXIT__;
1195                 return -1;
1196         }
1197         /*wfd_info_msg:0013 1c44 000a */
1198         WDP_LOGE("Message to parse: %s", msg);
1199
1200         strncpy(wfd_info_msg, msg, 4);
1201         wfd_info = strtoul(wfd_info_msg, NULL, 16);
1202
1203         if (wfd_info & WS_WFD_INFO_PRIMARY_SINK)
1204                 display->type |= WS_WFD_INFO_PRIMARY_SINK;
1205         if (wfd_info & WS_WFD_INFO_SECONDARY_SINK)
1206                 display->type |= WS_WFD_INFO_SECONDARY_SINK;
1207
1208         display->availability = (wfd_info & WS_WFD_INFO_AVAILABILITY) >> 4;
1209         display->hdcp_support = (wfd_info & WS_WFD_INFO_HDCP_SUPPORT) >> 8;
1210
1211         strncpy(ctrl_port_msg, msg+4, 4);
1212         display->port =  strtoul(ctrl_port_msg, NULL, 16);
1213         strncpy(max_tput_msg, msg+8, 4);
1214         display->max_tput =  strtoul(max_tput_msg, NULL, 16);
1215
1216         WDP_LOGE("type [%d],availability [%d],hdcp_support [%d],ctrl_port [%d] max_tput[%d]",
1217                         display->type, display->availability, display->hdcp_support,
1218                         display->port, display->max_tput);
1219
1220         __WDP_LOG_FUNC_EXIT__;
1221         return 0;
1222 }
1223 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1224
1225 static int _parsing_peer_info(char *msg, wfd_oem_device_s *peer)
1226 {
1227         __WDP_LOG_FUNC_ENTER__;
1228         int i, info_cnt = 0;
1229         ws_string_s infos[WS_PEER_INFO_LIMIT];
1230         int config_methods = 0x00;
1231         int group_capab = 0x00;
1232         int res = 0;
1233
1234         if (!msg || !peer) {
1235                 WDP_LOGE("Invalid parameter");
1236                 __WDP_LOG_FUNC_EXIT__;
1237                 return -1;
1238         }
1239
1240         _ws_txt_to_mac(msg, peer->dev_addr);
1241         msg += OEM_MACSTR_LEN;
1242
1243         memset(infos, 0x0, (WS_PEER_INFO_LIMIT) * sizeof(ws_string_s));
1244         for (i = 0; i < WS_PEER_INFO_LIMIT; i++) {
1245                 res = _extract_peer_value_str(msg, ws_peer_info_strs[i].string, &infos[info_cnt].string);
1246                 if (res > 0) {
1247                         infos[info_cnt].index = ws_peer_info_strs[i].index;
1248                         info_cnt++;
1249                 }
1250         }
1251         if (info_cnt == 0) {
1252                 WDP_LOGD("Device info ids have no valid information");
1253                 __WDP_LOG_FUNC_EXIT__;
1254                 return -1;
1255         }
1256
1257         for (i = 0; i < info_cnt; i++) {
1258                 switch (infos[i].index) {
1259                 case WS_PEER_INFO_AGE:
1260                         peer->age = (int) strtoul(infos[i].string, NULL, 10);
1261                         break;
1262                 case WS_PEER_INFO_LISTEN_FREQ:
1263                         {
1264                                 int freq = 0;
1265                                 freq = (int) strtoul(infos[i].string, NULL, 10);
1266                                 peer->channel = _ws_freq_to_channel(freq);
1267                         }
1268                         break;
1269                 case WS_PEER_INFO_LEVEL:
1270                         break;
1271                 case WS_PEER_INFO_WPS_METHOD:
1272                         break;
1273                 case WS_PEER_INFO_INTERFACE_ADDR:
1274                         break;
1275                 case WS_PEER_INFO_MEMBER_IN_GO_DEV:
1276                         {
1277                                 res = _ws_txt_to_mac(infos[i].string, peer->go_dev_addr);
1278                                 if (res < 0)
1279                                         memset(peer->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1280
1281                                 if (memcmp(peer->go_dev_addr, null_mac, OEM_MACADDR_LEN))
1282                                         peer->dev_role = WFD_OEM_DEV_ROLE_GC;
1283                         }
1284                         break;
1285                 case WS_PEER_INFO_MEMBER_IN_GO_IFACE:
1286                         break;
1287                 case WS_PEER_INFO_PRI_DEV_TYPE:
1288                         res = _ws_txt_to_devtype(infos[i].string, &peer->pri_dev_type, &peer->sec_dev_type);
1289                         if (res < 0) {
1290                                 peer->pri_dev_type = 0;
1291                                 peer->sec_dev_type = 0;
1292                         }
1293                         break;
1294                 case WS_PEER_INFO_DEVICE_NAME:
1295                         strncpy(peer->dev_name, infos[i].string, OEM_DEV_NAME_LEN);
1296                         peer->dev_name[OEM_DEV_NAME_LEN] = '\0';
1297                         break;
1298                 case WS_PEER_INFO_MANUFACTURER:
1299                         break;
1300                 case WS_PEER_INFO_MODEL_NAME:
1301                         break;
1302                 case WS_PEER_INFO_MODEL_NUMBER:
1303                         break;
1304                 case WS_PEER_INFO_SERIAL_NUMBER:
1305                         break;
1306                 case WS_PEER_INFO_CONFIG_METHODS:
1307                         config_methods = (int) strtoul(infos[i].string, NULL, 16);
1308                         if (config_methods & WS_CONFIG_METHOD_DISPLAY)
1309                                 peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
1310                         if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
1311                                 peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
1312                         if (config_methods & WS_CONFIG_METHOD_KEYPAD)
1313                                 peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
1314                         break;
1315                 case WS_PEER_INFO_DEV_CAPAB:
1316                         peer->dev_flags = (int) strtoul(infos[i].string, NULL, 16);
1317                         break;
1318                 case WS_PEER_INFO_GROUP_CAPAB:
1319                         group_capab = (int) strtoul(infos[i].string, NULL, 16);
1320                         if (group_capab & WS_GROUP_CAP_GROUP_OWNER) {
1321                                 peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
1322                                 peer->dev_role = WFD_OEM_DEV_ROLE_GO;
1323                         }
1324                         if (group_capab & WS_GROUP_CAP_PERSISTENT_GROUP)
1325                                 peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1326                         break;
1327                 case WS_PEER_INFO_GO_NEG_REQ_SENT:
1328                         break;
1329                 case WS_PEER_INFO_GO_STATE:
1330                         break;
1331                 case WS_PEER_INFO_DIALOG_TOKEN:
1332                         break;
1333                 case WS_PEER_INFO_INTENDED_ADDR:
1334                         res = _ws_txt_to_mac(infos[i].string, peer->intf_addr);
1335                         if (res < 0)
1336                                 memset(peer->intf_addr, 0x00, OEM_MACADDR_LEN);
1337                         break;
1338                 case WS_PEER_INFO_COUNTRY:
1339                         break;
1340                 case WS_PEER_INFO_OPER_FREQ:
1341                         break;
1342                 case WS_PEER_INFO_REQ_CONFIG_METHODS:
1343                         break;
1344                 case WS_PEER_INFO_FLAGS:
1345                         break;
1346                 case WS_PEER_INFO_STATUS:
1347                         break;
1348                 case WS_PEER_INFO_WAIT_COUNT:
1349                         break;
1350                 case WS_PEER_INFO_INVITATION_REQS:
1351                         break;
1352 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1353                 case WS_PEER_INFO_WFD_SUBELEMS:
1354                         res = _parsing_wfd_info(infos[i].string+6, &peer->display);
1355                         if (res < 0)
1356                                 memset(&peer->display, 0x00, sizeof(wfd_oem_display_s));
1357                         break;
1358 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1359                 default:
1360                         break;
1361                 }
1362         }
1363
1364         for (i = 0; i < info_cnt; i++) {
1365                 if (infos[i].string)
1366                         free(infos[i].string);
1367         }
1368
1369         __WDP_LOG_FUNC_EXIT__;
1370         return 0;
1371 }
1372
1373 static wfd_oem_dev_data_s *_convert_msg_to_dev_info(char *msg)
1374 {
1375         __WDP_LOG_FUNC_ENTER__;
1376         int i;
1377         int info_cnt = 0;
1378         ws_string_s infos[WS_DEV_INFO_LIMIT];
1379         wfd_oem_dev_data_s *edata = NULL;
1380         int config_methods = 0x00;
1381         int group_capab = 0x00;
1382         int res = 0;
1383
1384         if (!msg) {
1385                 WDP_LOGE("Invalid parameter");
1386                 return NULL;
1387         }
1388         WDP_SECLOGD("msg to be converted [%s]", msg);
1389
1390         memset(infos, 0x0, (WS_DEV_INFO_LIMIT) * sizeof(ws_string_s));
1391         for (i = 0; ws_dev_info_strs[i].index < WS_DEV_INFO_LIMIT; i++) {
1392                 res = _extract_value_str(msg, ws_dev_info_strs[i].string, &infos[info_cnt].string);
1393                 if (res > 0) {
1394                         infos[info_cnt].index = ws_dev_info_strs[i].index;
1395                         if (infos[info_cnt].index == WS_DEV_INFO_P2P_DEV_ADDR)
1396                                 WDP_SECLOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
1397                         else
1398                                 WDP_LOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
1399                         info_cnt++;
1400                 }
1401         }
1402
1403         if (!info_cnt) {
1404                 WDP_LOGE("There is no item converted");
1405                 return NULL;
1406         }
1407
1408         errno = 0;
1409         edata = (wfd_oem_dev_data_s*) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
1410         if (!edata) {
1411                 WDP_LOGE("Failed to allocate memory for device information [%s]", strerror(errno));
1412                 return NULL;
1413         }
1414
1415         for (i = 0; i < info_cnt; i++) {
1416                 switch (infos[i].index) {
1417                 case WS_DEV_INFO_P2P_DEV_ADDR:
1418                         res = _ws_txt_to_mac(infos[i].string, edata->p2p_dev_addr);
1419                         if (res < 0)
1420                                 memset(edata->p2p_dev_addr, 0x00, OEM_MACADDR_LEN);
1421                         break;
1422                 case WS_DEV_INFO_DEV_NAME:
1423                         strncpy(edata->name, infos[i].string, OEM_DEV_NAME_LEN);
1424                         edata->name[OEM_DEV_NAME_LEN] = '\0';
1425                         break;
1426                 case WS_DEV_INFO_DEV_TYPE:
1427                         res = _ws_txt_to_devtype(infos[i].string, &edata->pri_dev_type, &edata->sec_dev_type);
1428                         if (res < 0) {
1429                                 edata->pri_dev_type = 0;
1430                                 edata->sec_dev_type = 0;
1431                         }
1432                         break;
1433                 case WS_DEV_INFO_CONFIG_METHODS:
1434                         config_methods = (int) strtoul(infos[i].string, NULL, 16);
1435                         if (config_methods & WS_CONFIG_METHOD_DISPLAY)
1436                                 edata->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
1437                         if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
1438                                 edata->config_methods |= WFD_OEM_WPS_MODE_PBC;
1439                         if (config_methods & WS_CONFIG_METHOD_KEYPAD)
1440                                 edata->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
1441                         break;
1442                 case WS_DEV_INFO_DEV_CAP:
1443                         edata->dev_flags = (int) strtoul(infos[i].string, NULL, 16);
1444                         break;
1445                 case WS_DEV_INFO_GROUP_CAP:
1446                         group_capab = (int) strtoul(infos[i].string, NULL, 16);
1447                         if (group_capab & WS_GROUP_CAP_GROUP_OWNER) {
1448                                 edata->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
1449                                 edata->dev_role = WFD_OEM_DEV_ROLE_GO;
1450                         }
1451                         if (group_capab & WS_GROUP_CAP_PERSISTENT_GROUP)
1452                                 edata->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1453                         break;
1454                 case WS_DEV_INFO_P2P_GO_ADDR:
1455                         res = _ws_txt_to_mac(infos[i].string, edata->p2p_go_addr);
1456                         if (res < 0)
1457                                 memset(edata->p2p_go_addr, 0x00, OEM_MACADDR_LEN);
1458                         if (memcmp(edata->p2p_go_addr, null_mac, OEM_MACADDR_LEN))
1459                                 edata->dev_role = WFD_OEM_DEV_ROLE_GC;
1460                         break;
1461 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1462                 case WS_DEV_INFO_WFD_DEV_INFO:
1463                         /* wfd_dev_info=0x00 0006 015d 022a0032 */
1464                         res = _parsing_wfd_info(infos[i].string+2, &edata->display);
1465                         if (res < 0)
1466                                 memset(&edata->display, 0x00, sizeof(wfd_oem_display_s));
1467                         break;
1468 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1469
1470                 default:
1471                         WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1472                         break;
1473                 }
1474                 if (infos[i].string)
1475                         free(infos[i].string);
1476         }
1477
1478         __WDP_LOG_FUNC_EXIT__;
1479         return edata;
1480 }
1481
1482 static wfd_oem_conn_data_s *_convert_msg_to_conn_info(char *msg)
1483 {
1484         __WDP_LOG_FUNC_ENTER__;
1485         int i;
1486         int info_cnt = 0;
1487         ws_string_s infos[WS_CONN_INFO_LIMIT];
1488         wfd_oem_conn_data_s *edata = NULL;
1489         int dev_pwd_id;
1490         int res = 0;
1491
1492         if (!msg) {
1493                 WDP_LOGE("Invalid parameter");
1494                 return NULL;
1495         }
1496         WDP_LOGD("msg to convert [%s]", msg);
1497
1498         memset(infos, 0x0, (WS_CONN_INFO_LIMIT) * sizeof(ws_string_s));
1499         for (i = 0; ws_conn_info_strs[i].index < WS_CONN_INFO_LIMIT; i++) {
1500                 res = _extract_value_str(msg, ws_conn_info_strs[i].string, &infos[info_cnt].string);
1501                 if (res > 0) {
1502                         infos[info_cnt].index = ws_conn_info_strs[i].index;
1503                         info_cnt++;
1504                 }
1505         }
1506
1507         if (!info_cnt) {
1508                 WDP_LOGE("There is no item converted");
1509                 return NULL;
1510         }
1511
1512         errno = 0;
1513         edata = (wfd_oem_conn_data_s*) g_try_malloc0(sizeof(wfd_oem_conn_data_s));
1514         if (!edata) {
1515                 WDP_LOGE("Failed to allocate memory for connection information [%s]", strerror(errno));
1516                 return NULL;
1517         }
1518
1519         for (i = 0; i < info_cnt; i++) {
1520                 switch (infos[i].index) {
1521                 case WS_CONN_INFO_DEV_PWD_ID:
1522                         dev_pwd_id = atoi(infos[i].string);
1523                         if (dev_pwd_id == WS_DEV_PASSWD_ID_PUSH_BUTTON)
1524                                 edata->wps_mode = WFD_OEM_WPS_MODE_PBC;
1525                         else if (dev_pwd_id == WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED)
1526                                 edata->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1527                         else if (dev_pwd_id == WS_DEV_PASSWD_ID_USER_SPECIFIED)
1528                                 edata->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1529                         else
1530                                 edata->wps_mode = WFD_OEM_WPS_MODE_NONE;
1531                         break;
1532                 case WS_CONN_INFO_STATUS:
1533                         edata->status = atoi(infos[i].string);
1534                         break;
1535                 case WS_CONN_INFO_ERROR:
1536                         edata->error = atoi(infos[i].string);
1537                         break;
1538                 default:
1539                         WDP_LOGE("Unknown information [%d:%s]", infos[i].index, infos[i].string);
1540                         break;
1541                 }
1542                 if (infos[i].string)
1543                         free(infos[i].string);
1544         }
1545
1546         __WDP_LOG_FUNC_EXIT__;
1547         return edata;
1548 }
1549
1550 static wfd_oem_invite_data_s *_convert_msg_to_invite_info(char *msg)
1551 {
1552         __WDP_LOG_FUNC_ENTER__;
1553         int i;
1554         int info_cnt = 0;
1555         ws_string_s infos[WS_INVITE_INFO_LIMIT];
1556         wfd_oem_invite_data_s *edata = NULL;
1557         int res = 0;
1558
1559         if (!msg) {
1560                 WDP_LOGE("Invalid parameter");
1561                 return NULL;
1562         }
1563         WDP_LOGD("msg to convert [%s]", msg);
1564
1565         memset(infos, 0x0, (WS_INVITE_INFO_LIMIT) * sizeof(ws_string_s));
1566         for (i = 0; ws_invite_info_strs[i].index < WS_INVITE_INFO_LIMIT; i++) {
1567                 res = _extract_value_str(msg, ws_invite_info_strs[i].string, &infos[info_cnt].string);
1568                 if (res > 0) {
1569                         infos[info_cnt].index = ws_invite_info_strs[i].index;
1570                         info_cnt++;
1571                 }
1572         }
1573
1574         if (!info_cnt) {
1575                 WDP_LOGE("There is no item converted");
1576                 return NULL;
1577         }
1578
1579         errno = 0;
1580         edata = (wfd_oem_invite_data_s*) g_try_malloc0(sizeof(wfd_oem_invite_data_s));
1581         if (!edata) {
1582                 WDP_LOGE("Failed to allocate memory for invite information [%s]", strerror(errno));
1583                 return NULL;
1584         }
1585
1586         for (i = 0; i < info_cnt; i++) {
1587                 switch (infos[i].index) {
1588                 case WS_INVITE_INFO_GO_DEV_ADDR:
1589                         res = _ws_txt_to_mac(infos[i].string, edata->go_dev_addr);
1590                         if (res < 0)
1591                                 memset(edata->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1592                         break;
1593                 case WS_INVITE_INFO_BSSID:
1594                         res = _ws_txt_to_mac(infos[i].string, edata->bssid);
1595                         if (res < 0)
1596                                 memset(edata->bssid, 0x00, OEM_MACADDR_LEN);
1597                         break;
1598                 case WS_INVITE_INFO_LISTEN:
1599                         edata->listen = atoi(infos[i].string);
1600                         break;
1601                 case WS_INVITE_INFO_STATUS:
1602                         edata->status = atoi(infos[i].string);
1603                         break;
1604                 default:
1605                         WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1606                         break;
1607                 }
1608                 if (infos[i].string)
1609                         free(infos[i].string);
1610         }
1611
1612         __WDP_LOG_FUNC_EXIT__;
1613         return edata;
1614 }
1615
1616 static wfd_oem_group_data_s *_convert_msg_to_group_info(char *msg)
1617 {
1618         __WDP_LOG_FUNC_ENTER__;
1619         int i;
1620         int info_cnt = 0;
1621         ws_string_s infos[WS_GROUP_INFO_LIMIT];
1622         wfd_oem_group_data_s *edata = NULL;
1623
1624 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
1625         unsigned int addr = 0;
1626 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
1627         int res = 0;
1628         if (!msg) {
1629                 WDP_LOGE("Invalid parameter");
1630                 return NULL;
1631         }
1632         WDP_LOGD("msg to convert [%s]", msg);
1633
1634         memset(infos, 0x0, WS_GROUP_INFO_LIMIT * sizeof(ws_string_s));
1635         for (i = 0; ws_group_info_strs[i].index < WS_GROUP_INFO_LIMIT; i++) {
1636                 res = _extract_value_str(msg, ws_group_info_strs[i].string, &infos[info_cnt].string);
1637                 if (res > 0) {
1638                         infos[info_cnt].index = ws_group_info_strs[i].index;
1639                         info_cnt++;
1640                 }
1641         }
1642
1643         if (!info_cnt) {
1644                 WDP_LOGE("There is no item converted");
1645                 return NULL;
1646         }
1647
1648         errno = 0;
1649         edata = (wfd_oem_group_data_s*) g_try_malloc0(sizeof(wfd_oem_group_data_s));
1650         if (!edata) {
1651                 WDP_LOGE("Failed to allocate memory for group information [%s]", strerror(errno));
1652                 return NULL;
1653         }
1654
1655         for (i = 0; i < info_cnt; i++) {
1656                 switch (infos[i].index) {
1657                 case WS_GROUP_INFO_SSID:
1658                         g_strlcpy(edata->ssid, infos[i].string, OEM_DEV_NAME_LEN + 1);
1659                         WDP_LOGD("ssid [%s]", edata->ssid);
1660                         break;
1661                 case WS_GROUP_INFO_FREQ:
1662                         edata->freq = atoi(infos[i].string);
1663                         break;
1664                 case WS_GROUP_INFO_PASS:
1665                         g_strlcpy(edata->pass, infos[i].string, OEM_PASS_PHRASE_LEN + 1);
1666                         WDP_LOGD("passphrase [%s]", edata->pass);
1667                         break;
1668                 case WS_GROUP_INFO_GO_DEV_ADDR:
1669                         res = _ws_txt_to_mac(infos[i].string, edata->go_dev_addr);
1670                         if (res < 0)
1671                                 memset(edata->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1672                         break;
1673                 case WS_GROUP_INFO_PERSISTENT:
1674                         edata->is_persistent = TRUE;
1675                         WDP_LOGD("Is Persistent : [%s]", edata->is_persistent ? "YES" : "NO");
1676                         break;
1677 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
1678                 case WS_GROUP_INFO_IP_ADDR:
1679                         WDP_LOGD("Extracted peer ip = %s", infos[i].string);
1680                         res = inet_aton(infos[i].string, (struct in_addr *)&addr);
1681                         if (res == 1)
1682                                 memcpy(&(edata->ip_addr), &addr, sizeof(edata->ip_addr));
1683                         break;
1684                 case WS_GROUP_INFO_IP_MASK:
1685                         WDP_LOGD("Extracted ip mask= %s", infos[i].string);
1686                         res = inet_aton(infos[i].string, (struct in_addr *)&addr);
1687                         if (res == 1)
1688                                 memcpy(&(edata->ip_addr_mask), &addr, sizeof(edata->ip_addr_mask));
1689                         break;
1690                 case WS_GROUP_INFO_GO_IP_ADDR:
1691                         WDP_LOGD("Extracted peer go ip = %s", infos[i].string);
1692                         res = inet_aton(infos[i].string, (struct in_addr *)&addr);
1693                         if (res == 1)
1694                                 memcpy(&(edata->ip_addr_go), &addr, sizeof(edata->ip_addr_go));
1695                         break;
1696 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
1697                 default:
1698                         WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1699                         break;
1700                 }
1701                 g_free(infos[i].string);
1702         }
1703
1704         __WDP_LOG_FUNC_EXIT__;
1705         return edata;
1706 }
1707
1708 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1709 static int _ws_segment_to_service(char *segment, wfd_oem_new_service_s **service)
1710 {
1711         wfd_oem_new_service_s *serv_tmp = NULL;
1712         char *ptr = NULL;
1713         char *temp = NULL;
1714         int len = 0;
1715         int i = 0;
1716
1717         if (!segment || !service) {
1718                 WDP_LOGE("Invalid parameter");
1719                 return -1;
1720         }
1721
1722         ptr = segment;
1723         WDP_LOGD("Segment: %s", segment);
1724
1725         serv_tmp = (wfd_oem_new_service_s*) g_try_malloc0(sizeof(wfd_oem_new_service_s));
1726         if (!serv_tmp) {
1727                 WDP_LOGE("Failed to allocate memory for service");
1728                 return -1;
1729         }
1730
1731         serv_tmp->protocol = _ws_hex_to_num(ptr, 2);
1732         serv_tmp->trans_id = _ws_hex_to_num(ptr+2, 2);
1733         serv_tmp->status = _ws_hex_to_num(ptr+4, 2);
1734         ptr += 6;
1735         WDP_LOGD("Protocol[%d], Transaction ID[%d], Status[%d]", serv_tmp->protocol, serv_tmp->trans_id, serv_tmp->status);
1736
1737         if (serv_tmp->status != 0) {
1738                 WDP_LOGE("Service status is not success");
1739                 g_free(serv_tmp);
1740                 return -1;
1741         }
1742
1743         if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
1744                 WDP_LOGD("===== Bonjour service =====");
1745                 char compr[5] = {0, };
1746                 char query[256] = {0, };
1747                 char rdata[256] = {0, };
1748                 int dns_type = 0;
1749
1750                 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
1751                         len = _ws_hex_to_num(ptr, 2);
1752                         ptr += 2;
1753                         if (len) {
1754                                 temp = (char*) g_try_malloc0(len + 2);
1755                                 if (!temp) {
1756                                         WDP_LOGE("Failed to allocate memory for temp");
1757                                         g_free(serv_tmp);
1758                                         return -1;
1759                                 }
1760                                 temp[0] = '.';
1761                                 for (i = 0; i  < len; i++) {
1762                                         temp[i+1] = (char) _ws_hex_to_num(ptr, 2);
1763                                         ptr += 2;
1764                                 }
1765                                 strncat(query, temp, len+1);
1766                                 g_free(temp);
1767                                 temp = NULL;
1768                         }
1769                 }
1770
1771                 if (!strncmp(ptr, "c0", 2)) {
1772                         memcpy(compr, ptr, 4);
1773                         ptr += 2;
1774
1775                         if (!strncmp(ptr, "27", 2)) {
1776                                 WDP_LOGD("Segment ended");
1777                                 ptr += 2;
1778                         } else {
1779                                 ptr += 2;
1780                                 dns_type = _ws_hex_to_num(ptr, 4);
1781                                 ptr += 6;
1782                                 if (dns_type == 12) {
1783                                         if (!strncmp(compr, "c011", 4))
1784                                                 strncat(query, ".local.", 7);
1785                                         else if (!strncmp(compr, "c00c", 4))
1786                                                 strncat(query, "._tcp.local.", 12);
1787                                         else if (!strncmp(compr, "c01c", 4))
1788                                                 strncat(query, "._udp.local.", 12);
1789                                 }
1790                         }
1791                 }
1792                 serv_tmp->data.bonjour.query = strdup(query + 1);
1793                 while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
1794                         len = _ws_hex_to_num(ptr, 2);
1795                         ptr += 2;
1796                         if (len) {
1797                                 temp = (char*) g_try_malloc0(len + 2);
1798                                 if (!temp) {
1799                                         WDP_LOGE("Failed to allocate memory for temp");
1800                                         g_free(serv_tmp);
1801                                         return -1;
1802                                 }
1803                                 temp[0] = '.';
1804                                 for (i = 0; i < len; i++) {
1805                                         temp[i + 1] = (char) _ws_hex_to_num(ptr, 2);
1806                                         ptr += 2;
1807                                 }
1808                                 strncat(rdata, temp, len+1);
1809                                 g_free(temp);
1810                                 temp = NULL;
1811                         }
1812                 }
1813                 serv_tmp->data.bonjour.rdata = strdup(rdata + 1);
1814
1815                 WDP_LOGD("Query: %s", serv_tmp->data.bonjour.query);
1816                 WDP_LOGD("RData: %s", serv_tmp->data.bonjour.rdata);
1817         } else if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_VENDOR) {
1818                 WDP_LOGD("===== Vendor specific service =====");
1819         } else {
1820                 WDP_LOGE("Not supported yet. Only bonjour service supproted [%d]",
1821                                         serv_tmp->protocol);
1822                 g_free(serv_tmp);
1823                 return -1;
1824         }
1825
1826         *service = serv_tmp;
1827
1828         return 0;
1829 }
1830 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1831
1832 static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
1833 {
1834         __WDP_LOG_FUNC_ENTER__;
1835         int i;
1836         int res = 0;
1837         char *info_str = NULL;
1838
1839         if (!msg || !data) {
1840                 WDP_LOGE("Invalid parameter");
1841                 __WDP_LOG_FUNC_EXIT__;
1842                 return -1;
1843         }
1844         WDP_SECLOGD("Event message [%s]", msg);
1845
1846         /* parsing event string */
1847         for (i = 0; ws_event_strs[i].index < WS_EVENT_LIMIT; i++) {
1848                 if (!strncmp(ws_event_strs[i].string, msg, strlen(ws_event_strs[i].string)))
1849                         break;
1850         }
1851
1852         if (i == sizeof(ws_event_strs)) {
1853                 WDP_LOGE("Unknown event [%d]", WS_EVENT_LIMIT);
1854                 data->event_id = WS_EVENT_LIMIT;
1855                 return 1;
1856         }
1857         data->event_id = ws_event_strs[i].index;
1858         WDP_LOGD("Event ID [%d]", data->event_id);
1859
1860         /* parsing event info */
1861         info_str = msg + strlen(ws_event_strs[i].string) + 1;
1862         if (!strlen(info_str)) {
1863                 WDP_LOGD("Nothing to parse anymore");
1864                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1865                 __WDP_LOG_FUNC_EXIT__;
1866                 return 0;
1867         }
1868
1869         switch (data->event_id) {
1870         case WS_EVENT_DEVICE_FOUND:
1871                 {
1872                         _ws_txt_to_mac(info_str, data->dev_addr);
1873                         info_str += OEM_MACSTR_LEN;
1874
1875                         wfd_oem_dev_data_s *edata = NULL;
1876                         edata = _convert_msg_to_dev_info(info_str);
1877                         if (!edata) {
1878                                 WDP_LOGE("Failed to convert information string to device data");
1879                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1880                                 break;
1881                         }
1882
1883                         if (edata->dev_role == WFD_OEM_DEV_ROLE_GO) {
1884                                 memcpy(edata->p2p_intf_addr, data->dev_addr, OEM_MACADDR_LEN);
1885                                 memcpy(data->dev_addr, edata->p2p_dev_addr, OEM_MACADDR_LEN);
1886                         }
1887                         data->edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1888                         data->edata = (void*) edata;
1889
1890                 }
1891                 break;
1892         case WS_EVENT_PROV_DISC_PBC_REQ:
1893         case WS_EVENT_PROV_DISC_SHOW_PIN:
1894         case WS_EVENT_PROV_DISC_ENTER_PIN:
1895         case WS_EVENT_PROV_DISC_PBC_RESP:
1896                 {
1897                         _ws_txt_to_mac(info_str, data->dev_addr);
1898                         info_str += OEM_MACSTR_LEN;
1899
1900                         if (data->event_id == WS_EVENT_PROV_DISC_PBC_REQ ||
1901                                 data->event_id == WS_EVENT_PROV_DISC_PBC_RESP) {
1902                                 data->wps_mode = WFD_OEM_WPS_MODE_PBC;
1903                         } else if (data->event_id == WS_EVENT_PROV_DISC_ENTER_PIN) {
1904                                 data->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1905                         } else if (data->event_id == WS_EVENT_PROV_DISC_SHOW_PIN) {
1906                                 data->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1907                                 strncpy(data->wps_pin, info_str, OEM_PINSTR_LEN);
1908                                 data->wps_pin[OEM_PINSTR_LEN] = '\0';
1909                                 info_str += OEM_PINSTR_LEN +1;
1910                         }
1911
1912                         WDP_LOGD("info string left [%s]", info_str ? info_str : "NULL");
1913
1914                         data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1915
1916                 }
1917                 break;
1918         case WS_EVENT_DEVICE_LOST:
1919                 {
1920                         char *temp_mac = NULL;
1921                         res = _extract_value_str(info_str, "p2p_dev_addr", &temp_mac);
1922                         if (res < 0) {
1923                                 WDP_LOGE("Failed to extract device address");
1924                                 break;
1925                         }
1926                         _ws_txt_to_mac(temp_mac, data->dev_addr);
1927                         if (temp_mac)
1928                                 g_free(temp_mac);
1929                         data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1930                 }
1931                 break;
1932         case WS_EVENT_FIND_STOPED:
1933                 break;
1934         case WS_EVENT_GO_NEG_REQUEST:
1935                 {
1936                         _ws_txt_to_mac(info_str, data->dev_addr);
1937                         info_str += OEM_MACSTR_LEN;
1938
1939                         if (!strlen(info_str)) {
1940                                 WDP_LOGD("Nothing to parse anymore");
1941                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1942                                 break;
1943                         }
1944
1945                         wfd_oem_conn_data_s *edata = NULL;
1946                         edata = _convert_msg_to_conn_info(info_str);
1947                         if (!edata) {
1948                                 WDP_LOGE("Failed to convert information string to connection data");
1949                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1950                                 break;
1951                         }
1952                         data->edata_type = WFD_OEM_EDATA_TYPE_CONN;
1953                         data->edata = (void*) edata;
1954                 }
1955                 break;
1956         case WS_EVENT_PROV_DISC_FAILURE:
1957         case WS_EVENT_WPS_FAIL:         /* M_id(msg), error(config_error) */
1958                 break;
1959         case WS_EVENT_GO_NEG_FAILURE:
1960                 {
1961                         wfd_oem_conn_data_s *edata = NULL;
1962                         edata = _convert_msg_to_conn_info(info_str);
1963                         if (!edata) {
1964                                 WDP_LOGE("Failed to convert information string to connection data");
1965                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1966                                 break;
1967                         }
1968                         data->edata_type = WFD_OEM_EDATA_TYPE_CONN;
1969                         data->edata = (void*) edata;
1970                 }
1971                 break;
1972         case WS_EVENT_GROUP_FORMATION_FAILURE:  /* No incofmation sring */
1973         case WS_EVENT_GO_NEG_SUCCESS:
1974         case WS_EVENT_WPS_SUCCESS:
1975         case WS_EVENT_GROUP_FORMATION_SUCCESS:
1976                 /* No information string */
1977                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1978                 break;
1979         case WS_EVENT_WPS_REG_SUCCESS:  /* "intf_addr" */
1980                 /* Interface address of peer will come up */
1981                 break;
1982         case WS_EVENT_STA_CONNECTED:    /* "intf_addr", dev_addr(dev_addr) */
1983         case WS_EVENT_STA_DISCONNECTED:
1984                 {
1985                         /* Interface address of connected peer will come up */
1986                         _ws_txt_to_mac(info_str, data->intf_addr);
1987
1988                         char *temp = NULL;
1989                         res = _extract_value_str(info_str, "p2p_dev_addr", &temp);
1990                         if (res < 0) {
1991                                 WDP_LOGE("Failed to extract interface address");
1992                                 break;
1993                         }
1994                         _ws_txt_to_mac(temp, data->dev_addr);
1995                         if (temp)
1996                                 free(temp);
1997 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
1998                         res = _extract_value_str(info_str, "ip_addr", &temp);
1999                         if (res > 0 && temp) {
2000                                 unsigned int addr = 0;
2001                                 WDP_LOGD("Extracted peer ip = %s", temp);
2002                                 res = inet_aton(temp, (struct in_addr *)&addr);
2003                                 if (res == 1)
2004                                         memcpy(&(data->ip_addr_peer), &addr, sizeof(data->ip_addr_peer));
2005                         }
2006 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
2007                         data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
2008                 }
2009                 break;
2010         case WS_EVENT_INVITATION_RECEIVED:
2011         case WS_EVENT_INVITATION_RESULT:
2012                 {
2013                         char *peer_addr_str = NULL;
2014                         res = _extract_value_str(info_str, "sa", &peer_addr_str);
2015                         if (res == 17/*(OEM_MACSTR_LEN-1)*/) {
2016                                 _ws_txt_to_mac(peer_addr_str, data->dev_addr);
2017                                 if (peer_addr_str)
2018                                         g_free(peer_addr_str);
2019                         } else if (res < 0) {
2020                                 WDP_LOGE("Failed to extract source address");
2021                         } else {
2022                                 WDP_LOGE("Wrong source address");
2023                                 g_free(peer_addr_str);
2024                         }
2025
2026                         if (!strlen(info_str)) {
2027                                 WDP_LOGD("Nothing to parse anymore");
2028                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
2029                                 break;
2030                         }
2031
2032                         wfd_oem_invite_data_s* edata = NULL;
2033                         edata = _convert_msg_to_invite_info(info_str);
2034                         if (!edata) {
2035                                 WDP_LOGE("Failed to convert information string to invite data");
2036                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
2037                                 break;
2038                         }
2039
2040                         data->edata_type = WFD_OEM_EDATA_TYPE_INVITE;
2041                         data->edata = (void*) edata;
2042
2043                 }
2044                 break;
2045         case WS_EVENT_GROUP_STARTED:
2046         case WS_EVENT_GROUP_REMOVED:
2047                 {
2048                         char *ifname_str = NULL;
2049                         res = _extract_word(info_str, &ifname_str);
2050                         if (res < 0) {
2051                                 WDP_LOGE("Failed to extract event param string");
2052                         } else if (res == 0) {
2053                                 WDP_LOGE("Nothing extracted");
2054                                 g_free(ifname_str);
2055                         } else {
2056                                 if (!ifname_str) {
2057                                         WDP_LOGE("Parsing error(interface name)");
2058                                         return -1;
2059                                 }
2060                                 strncpy(data->ifname, ifname_str, OEM_IFACE_NAME_LEN);
2061                                 data->ifname[OEM_IFACE_NAME_LEN] = '\0';
2062
2063                                 info_str += strlen(ifname_str) + 1;
2064                                 g_free(ifname_str);
2065                         }
2066
2067                         char *dev_role_str = NULL;
2068                         res = _extract_word(info_str, &dev_role_str);
2069                         if (res < 0) {
2070                                 WDP_LOGE("Failed to extract event param string");
2071                         } else if (res == 0) {
2072                                 WDP_LOGE("Nothing extracted");
2073                                 g_free(dev_role_str);
2074                         } else {
2075                                 if (!dev_role_str) {
2076                                         WDP_LOGE("Parsing error(device role)");
2077                                         return -1;
2078                                 }
2079                                 if (!strncmp(dev_role_str, "GO", 2))
2080                                         data->dev_role = WFD_OEM_DEV_ROLE_GO;
2081                                 else if (!strncmp(dev_role_str, "client", 6))
2082                                         data->dev_role = WFD_OEM_DEV_ROLE_GC;
2083                                 else
2084                                         WDP_LOGE("Unknown device role [%s]", dev_role_str);
2085
2086                                 info_str += strlen(dev_role_str) + 1;
2087                                 g_free(dev_role_str);
2088                         }
2089
2090                         if (!strlen(info_str)) {
2091                                 WDP_LOGD("Nothing to parse anymore");
2092                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
2093                                 break;
2094                         }
2095
2096                         wfd_oem_group_data_s* edata = NULL;
2097                         edata = _convert_msg_to_group_info(info_str);
2098                         if (!edata) {
2099                                 WDP_LOGE("Failed to convert information string to group data");
2100                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
2101                                 break;
2102                         }
2103
2104                         data->edata_type = WFD_OEM_EDATA_TYPE_GROUP;
2105                         data->edata = (void*) edata;
2106
2107                 }
2108                 break;
2109 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
2110         case WS_EVENT_SERV_DISC_RESP:
2111                 {
2112                         char mac_addr[OEM_MACSTR_LEN] = {0, };
2113                         char *up_indic = NULL;
2114                         int len = 0;
2115                         int ret = 0;
2116
2117                         _ws_txt_to_mac(info_str, data->dev_addr);
2118                         info_str += OEM_MACSTR_LEN;
2119                         g_snprintf(mac_addr, OEM_MACSTR_LEN, MACSTR, MAC2STR(data->dev_addr));
2120
2121                         ret = _extract_word(info_str, &up_indic);
2122                         if (ret < 0)
2123                                 WDP_LOGE("_extract_word is failed");
2124
2125                         if (up_indic) {
2126                                 WDP_LOGD("Update indicator: %s", up_indic);
2127                                 info_str += strlen(up_indic) + 1;
2128                                 g_free(up_indic);
2129                         }
2130                         WDP_LOGD("Info string [%s]", info_str);
2131
2132                         char seglen_str[5] = {0, };
2133                         char *segment = NULL;
2134                         char *ptr = info_str;
2135                         GList *services = NULL;
2136                         wfd_oem_new_service_s *new_service = NULL;
2137                         int count = 0;
2138
2139                         while (*ptr != '\0') {
2140                                 _change_str_order(ptr, 4, 2, seglen_str);
2141                                 len = strtoul(seglen_str, NULL, 16);
2142                                 if (len == 0)
2143                                         break;
2144                                 segment = (char*) g_try_malloc0(len * 2 + 1);
2145                                 if (!segment) {
2146                                         WDP_LOGE("Failed to allocate memory for segment");
2147                                         return -1;
2148                                 }
2149                                 memcpy(segment, ptr+4, len*2);
2150                                 ptr = ptr + 4 + len*2;
2151                                 res = _ws_segment_to_service(segment, &new_service);
2152                                 if (res < 0) {
2153                                         WDP_LOGE("Failed to convert segment as service instance");
2154                                         g_free(segment);
2155                                         segment = NULL;
2156                                         continue;
2157                                 }
2158                                 services = g_list_append(services, new_service);
2159                                 count++;
2160                                 g_free(segment);
2161                                 segment = NULL;
2162                         }
2163                         data->edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
2164                         data->dev_role = count;
2165                         data->edata = (void*) services;
2166                 }
2167                 break;
2168 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
2169
2170         default:
2171                 WDP_LOGE("Unknown event");
2172                 break;
2173         }
2174
2175         __WDP_LOG_FUNC_EXIT__;
2176         return 0;
2177 }
2178
2179 static gboolean ws_event_handler(GIOChannel *source,
2180                                                                 GIOCondition condition,
2181                                                                 gpointer data)
2182 {
2183         __WDP_LOG_FUNC_ENTER__;
2184         ws_sock_data_s * sd = (ws_sock_data_s*) data;
2185         char msg[1024] = {0, };
2186         char *pos = NULL;
2187         char *param = NULL;
2188         int event_id = -1;
2189         wfd_oem_event_s event;
2190         int res = 0;
2191
2192         if (!sd) {
2193                 WDP_LOGE("Invalid parameter");
2194                 /* TODO: if error count is more than 10, disconnect this interface and reset sock data */
2195                 return FALSE;
2196         }
2197
2198         res = _ws_read_sock(sd->mon_sock, msg, sizeof(msg));
2199         if (res < 0) {
2200                 WDP_LOGE("Failed to read socket. [%d]", sd->mon_sock);
2201                 return FALSE;
2202         }
2203
2204         errno = 0;
2205         memset(&event, 0, sizeof(wfd_oem_event_s));
2206
2207         if (!strncmp(msg, "IFNAME", 6)) {
2208                 pos = strchr(msg, ' ');
2209                 param = pos+4;
2210         } else {
2211                 param = &msg[3];
2212         }
2213
2214         res = _parsing_event_info(sd->ifname, param, &event);
2215         if (res < 0) {
2216                 WDP_LOGE("Failed to parse event string");
2217                 return FALSE;
2218         }
2219
2220         if (res == 1)
2221                 WDP_LOGD("This means event->event_data is NULL");
2222
2223         /* Converting WS event to OEM event */
2224         switch (event.event_id) {
2225         case WS_EVENT_DEVICE_FOUND:
2226                 event_id = WFD_OEM_EVENT_PEER_FOUND;
2227                 break;
2228         case WS_EVENT_DEVICE_LOST:
2229                 event_id = WFD_OEM_EVENT_PEER_DISAPPEARED;
2230                 break;
2231         case WS_EVENT_FIND_STOPED:
2232                 event_id = WFD_OEM_EVENT_DISCOVERY_FINISHED;
2233                 break;
2234         case WS_EVENT_PROV_DISC_PBC_REQ:
2235                 event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
2236                 break;
2237         case WS_EVENT_PROV_DISC_PBC_RESP:
2238                 if (!memcmp(event.dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
2239                         event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
2240                         memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
2241                 } else {
2242                         WDP_LOGE("Invalid peer mac address[" MACSTR "]", MAC2STR(event.dev_addr));
2243                         goto done;
2244                 }
2245                 break;
2246         case WS_EVENT_PROV_DISC_SHOW_PIN:
2247         case WS_EVENT_PROV_DISC_ENTER_PIN:
2248                 if (!memcmp(event.dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
2249                         event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
2250                         memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
2251                         WDP_LOGD("Peer mac address verified");
2252                 } else if (!memcmp(g_pd_out, null_mac, OEM_MACADDR_LEN)) {
2253                         event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
2254                         WDP_LOGD("      PD request from peer[" MACSTR "]", MAC2STR(event.dev_addr));
2255                 } else {
2256                         WDP_LOGE("Invalid peer mac address[" MACSTR "]", MAC2STR(event.dev_addr));
2257                         goto done;
2258                 }
2259
2260                 break;
2261         case WS_EVENT_PROV_DISC_FAILURE:
2262                 event_id = WFD_OEM_EVENT_PROV_DISC_FAIL;
2263                 if (!memcmp(event.dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
2264                         memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
2265                         WDP_LOGD("Peer mac address verified, but PD failed");
2266                 }
2267                 break;
2268         case WS_EVENT_GO_NEG_REQUEST:
2269                 event_id = WFD_OEM_EVENT_GO_NEG_REQ;
2270                 break;
2271         case WS_EVENT_GO_NEG_FAILURE:
2272                 event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
2273                 break;
2274         case WS_EVENT_GO_NEG_SUCCESS:
2275                 event_id = WFD_OEM_EVENT_GO_NEG_DONE;
2276                 break;
2277         case WS_EVENT_WPS_FAIL:
2278         case WS_EVENT_GROUP_FORMATION_FAILURE:
2279                 event_id = WFD_OEM_EVENT_WPS_FAIL;
2280                 break;
2281         case WS_EVENT_WPS_SUCCESS:
2282         case WS_EVENT_WPS_REG_SUCCESS:
2283         case WS_EVENT_GROUP_FORMATION_SUCCESS:
2284                 event_id = WFD_OEM_EVENT_WPS_DONE;
2285                 /* TODO: connect to supplicant via group interface */
2286                 break;
2287         case WS_EVENT_STA_CONNECTED:
2288                 event_id = WFD_OEM_EVENT_STA_CONNECTED;
2289                 break;
2290         case WS_EVENT_GROUP_STARTED:
2291                 event_id = WFD_OEM_EVENT_GROUP_CREATED;
2292                 res = _connect_to_supplicant(GROUP_IFACE_NAME, &g_pd->group);
2293                 if (res < 0) {
2294                         WDP_LOGE("Failed to connect to group interface of supplicant");
2295                         /* goto done; */
2296                 }
2297                 break;
2298         case WS_EVENT_GROUP_REMOVED:
2299                 event_id = WFD_OEM_EVENT_GROUP_DESTROYED;
2300                 if (g_pd->group) {
2301                         res = _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
2302                         if (res < 0) {
2303                                 WDP_LOGE("Failed to disconnect from group interface of supplicant");
2304                                 /* goto done; */
2305                         }
2306                         g_pd->group = NULL;
2307                         _ws_flush();
2308                 }
2309                 break;
2310         case WS_EVENT_INVITATION_RECEIVED:
2311                 event_id = WFD_OEM_EVENT_INVITATION_REQ;
2312                 break;
2313         case WS_EVENT_INVITATION_RESULT:
2314                 event_id = WFD_OEM_EVENT_INVITATION_RES;
2315                 break;
2316         case WS_EVENT_STA_DISCONNECTED:
2317                 event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
2318                 break;
2319         case WS_EVENT_TERMINATING:
2320                 event_id = WFD_OEM_EVENT_DEACTIVATED;
2321                 break;
2322 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
2323         case WS_EVENT_SERV_DISC_RESP:
2324                 event_id = WFD_OEM_EVENT_SERV_DISC_RESP;
2325                 break;
2326 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
2327         default:
2328                 WDP_LOGD("Unknown event [%d]", event.event_id);
2329                 goto done;
2330                 break;
2331         }
2332         event.event_id = event_id;
2333         g_pd->callback(g_pd->user_data, &event);
2334
2335 done:
2336         if (event.edata) {
2337 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
2338                 if (event.edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE)
2339                         g_list_free((GList*) event.edata);
2340                 else
2341 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
2342                 g_free(event.edata);
2343         }
2344
2345         __WDP_LOG_FUNC_EXIT__;
2346         return TRUE;
2347 }
2348
2349 static int _ws_reset_plugin(ws_plugin_data_s *pd)
2350 {
2351         __WDP_LOG_FUNC_ENTER__;
2352
2353         if (!pd) {
2354                 WDP_LOGE("Invalid parameter");
2355                 __WDP_LOG_FUNC_EXIT__;
2356                 return -1;
2357         }
2358
2359         if (pd->activated)
2360                 ws_deactivate(g_pd->concurrent);
2361
2362         g_free(pd);
2363
2364         __WDP_LOG_FUNC_EXIT__;
2365         return 0;
2366 }
2367
2368
2369 static int __ws_check_net_interface(char* if_name)
2370 {
2371         struct ifreq ifr;
2372         int fd;
2373
2374         if (if_name == NULL) {
2375                 WDP_LOGE("Invalid param");
2376                 return -1;
2377         }
2378
2379         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2380         if (fd < 0) {
2381                 WDP_LOGE("socket create error: %d", fd);
2382                 return -2;
2383         }
2384
2385         memset(&ifr, 0, sizeof(ifr));
2386         g_strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) + 1);
2387
2388         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
2389                 close(fd);
2390                 WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s", strerror(errno));  /* interface is not found.. */
2391                 return -3;
2392         }
2393
2394         close(fd);
2395
2396         if (ifr.ifr_flags & IFF_UP) {
2397                 WDP_LOGD("%s interface is up", if_name);
2398                 return 1;
2399         } else if (!(ifr.ifr_flags & IFF_UP)) {
2400                 WDP_LOGD("%s interface is down", if_name);
2401                 return 0;
2402         }
2403         return 0;
2404 }
2405
2406 int ws_init(wfd_oem_event_cb callback, void *user_data)
2407 {
2408         __WDP_LOG_FUNC_ENTER__;
2409
2410         if (g_pd)
2411                 _ws_reset_plugin(g_pd);
2412
2413         errno = 0;
2414         g_pd = (ws_plugin_data_s*) g_try_malloc0(sizeof(ws_plugin_data_s));
2415         if (!g_pd) {
2416                 WDP_LOGE("Failed to allocate memory for plugin data. [%s]", strerror(errno));
2417                 return -1;
2418         }
2419
2420         g_pd->callback = callback;
2421         g_pd->user_data = user_data;
2422         g_pd->initialized = TRUE;
2423
2424         __WDP_LOG_FUNC_EXIT__;
2425         return 0;
2426 }
2427
2428 int ws_deinit()
2429 {
2430         __WDP_LOG_FUNC_ENTER__;
2431
2432         if (g_pd) {
2433                 _ws_reset_plugin(g_pd);
2434                 g_pd = NULL;
2435         }
2436
2437         __WDP_LOG_FUNC_EXIT__;
2438         return 0;
2439 }
2440
2441 gboolean _ws_util_interface_up(const char *ifname)
2442 {
2443         int fd;
2444         struct ifreq ifr;
2445
2446         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2447         if (fd < 0)
2448                 return FALSE;
2449
2450         memset(&ifr, 0, sizeof(ifr));
2451         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2452
2453         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
2454                 close(fd);
2455                 return FALSE;
2456         }
2457
2458         ifr.ifr_flags |= (IFF_UP | IFF_DYNAMIC);
2459         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
2460                 close(fd);
2461                 return FALSE;
2462         }
2463
2464         close(fd);
2465
2466         WDP_LOGI("Successfully activated [%s] interface", ifname);
2467         return TRUE;
2468 }
2469
2470 gboolean _ws_util_interface_down(const char *ifname)
2471 {
2472         int fd;
2473         struct ifreq ifr;
2474
2475         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2476         if (fd < 0)
2477                 return FALSE;
2478
2479         memset(&ifr, 0, sizeof(ifr));
2480         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2481
2482         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
2483                 close(fd);
2484                 return FALSE;
2485         }
2486
2487         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
2488         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
2489                 close(fd);
2490                 return FALSE;
2491         }
2492
2493         close(fd);
2494
2495         WDP_LOGI("Successfully de-activated [%s] interface", ifname);
2496         return TRUE;
2497 }
2498
2499 static int __ws_p2p_firmware_start(void)
2500 {
2501         gboolean rv = FALSE;
2502         const char *path = "/usr/bin/wlan.sh";
2503         char *const args[] = { "/usr/bin/wlan.sh", "p2p", NULL };
2504         char *const envs[] = { NULL };
2505
2506         rv = _ws_util_execute_file(path, args, envs);
2507         if (rv != TRUE)
2508                 return -1;
2509
2510         rv = _ws_util_interface_up(COMMON_IFACE_NAME);
2511         if (rv != TRUE)
2512                 return -1;
2513
2514         WDP_LOGI("Successfully loaded p2p device driver");
2515         return 0;
2516 }
2517
2518 static int __ws_p2p_firmware_stop(void)
2519 {
2520         gboolean rv = FALSE;
2521         const char *path = "/usr/bin/wlan.sh";
2522         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
2523         char *const envs[] = { NULL };
2524
2525         rv = _ws_util_interface_down(COMMON_IFACE_NAME);
2526         if (rv != TRUE)
2527                 return -1;
2528
2529         rv = _ws_util_execute_file(path, args, envs);
2530         if (rv < 0)
2531                 return -1;
2532
2533         WDP_LOGI("Successfully removed p2p device driver");
2534         return 0;
2535 }
2536
2537 static int __ws_p2p_supplicant_start(void)
2538 {
2539         gboolean rv = FALSE;
2540         const char *path = "/usr/sbin/p2p_supp.sh";
2541         char *const args[] = { "/usr/sbin/p2p_supp.sh", "start", NULL };
2542         char *const envs[] = { NULL };
2543
2544         rv = _ws_util_execute_file(path, args, envs);
2545
2546         if (rv != TRUE) {
2547                 WDP_LOGE("Failed to start p2p_supp.sh");
2548                 return -1;
2549         }
2550
2551         WDP_LOGI("Successfully started p2p_supp.sh");
2552         return 0;
2553 }
2554
2555 static int __ws_p2p_supplicant_stop(void)
2556 {
2557         gboolean rv = FALSE;
2558         const char *path = "/usr/sbin/p2p_supp.sh";
2559         char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
2560         char *const envs[] = { NULL };
2561
2562         rv = _ws_util_execute_file(path, args, envs);
2563
2564         if (rv != TRUE) {
2565                 WDP_LOGE("Failed to stop p2p_supp.sh");
2566                 return -1;
2567         }
2568
2569         WDP_LOGI("Successfully stopped p2p_supp.sh");
2570         return 0;
2571 }
2572
2573 #if 0
2574 static int __ws_p2p_on(void)
2575 {
2576         DBusError error;
2577         DBusMessage *reply = NULL;
2578         DBusMessage *message = NULL;
2579         DBusConnection *connection = NULL;
2580
2581         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
2582         if (connection == NULL) {
2583                 WDP_LOGE("Failed to get system bus");
2584                 return -EIO;
2585         }
2586
2587         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
2588                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
2589         if (message == NULL) {
2590                 WDP_LOGE("Failed DBus method call");
2591                 dbus_connection_unref(connection);
2592                 return -EIO;
2593         }
2594
2595         dbus_error_init(&error);
2596
2597         reply = dbus_connection_send_with_reply_and_block(connection, message,
2598                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
2599         if (dbus_error_is_set(&error) == TRUE) {
2600                 if (NULL != strstr(error.message, ".AlreadyExists")) {
2601                         /* p2p already enabled */
2602                 } else {
2603                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
2604                                         "DBus error [%s: %s]", error.name, error.message);
2605
2606                         dbus_error_free(&error);
2607                 }
2608
2609                 dbus_error_free(&error);
2610         }
2611
2612         if (reply != NULL)
2613                 dbus_message_unref(reply);
2614
2615         dbus_message_unref(message);
2616         dbus_connection_unref(connection);
2617
2618         return 0;
2619 }
2620
2621 static int __ws_p2p_off(void)
2622 {
2623         DBusError error;
2624         DBusMessage *reply = NULL;
2625         DBusMessage *message = NULL;
2626         DBusConnection *connection = NULL;
2627
2628         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
2629         if (connection == NULL) {
2630                 WDP_LOGE("Failed to get system bus");
2631                 return -EIO;
2632         }
2633
2634         message = dbus_message_new_method_call(NETCONFIG_SERVICE,
2635                         NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
2636         if (message == NULL) {
2637                 WDP_LOGE("Failed DBus method call");
2638                 dbus_connection_unref(connection);
2639                 return -EIO;
2640         }
2641
2642         dbus_error_init(&error);
2643
2644         reply = dbus_connection_send_with_reply_and_block(connection, message,
2645                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
2646         if (dbus_error_is_set(&error) == TRUE) {
2647                 if (NULL != strstr(error.message, ".AlreadyExists")) {
2648                         /* p2p already disabled */
2649                 } else {
2650                         WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
2651                                         "DBus error [%s: %s]", error.name, error.message);
2652
2653                         dbus_error_free(&error);
2654                 }
2655
2656                 dbus_error_free(&error);
2657         }
2658
2659         if (reply != NULL)
2660                 dbus_message_unref(reply);
2661
2662         dbus_message_unref(message);
2663         dbus_connection_unref(connection);
2664
2665         return 0;
2666 }
2667 #endif
2668 static int _ws_update_local_dev_addr_from_file()
2669 {
2670         __WDP_LOG_FUNC_ENTER__;
2671         FILE *fd = NULL;
2672         const char *file_path = DEFAULT_MAC_FILE_PATH;
2673         char local_mac[OEM_MACSTR_LEN] = {0, };
2674         char *ptr = NULL;
2675         int res = 0;
2676
2677         errno = 0;
2678         fd = fopen(file_path, "r");
2679         if (!fd) {
2680                 WDP_LOGE("Failed to open MAC info file [%s] (%s)", file_path, strerror(errno));
2681                 __WDP_LOG_FUNC_EXIT__;
2682                 return -1;
2683         }
2684
2685         errno = 0;
2686         ptr = fgets(local_mac, OEM_MACSTR_LEN, fd);
2687         if (!ptr) {
2688                 WDP_LOGE("Failed to read file or no data read(%s)", strerror(errno));
2689                 fclose(fd);
2690                 __WDP_LOG_FUNC_EXIT__;
2691                 return -1;
2692         }
2693         WDP_SECLOGD("Local MAC address [%s]", ptr);
2694
2695         res = _ws_txt_to_mac(local_mac, g_pd->local_dev_addr);
2696         if (res < 0) {
2697                 WDP_LOGE("Failed to convert text to MAC address");
2698                 fclose(fd);
2699                 __WDP_LOG_FUNC_EXIT__;
2700                 return -1;
2701         }
2702
2703         g_pd->local_dev_addr[0] |= 0x2;
2704         WDP_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(g_pd->local_dev_addr));
2705
2706         fclose(fd);
2707         __WDP_LOG_FUNC_EXIT__;
2708         return 0;
2709 }
2710
2711 static int _ws_update_local_dev_addr()
2712 {
2713         int res = 0;
2714         char reply[96] = {0, };
2715         char *mac_str = NULL;
2716
2717         res = _ws_send_cmd(g_pd->common->ctrl_sock, "status", reply, sizeof(reply));
2718         if (res < 0) {
2719                 WDP_LOGE("Failed to send command to wpa_supplicant");
2720                 goto failed;
2721         }
2722
2723         res = _extract_value_str(reply, "p2p_device_address", &mac_str);
2724         if (res < 0) {
2725                 WDP_LOGE("Failed to parsing p2p_device_address");
2726                 goto failed;
2727         }
2728
2729         res = _ws_txt_to_mac(mac_str, g_pd->local_dev_addr);
2730         if (res < 0) {
2731                 WDP_LOGE("Failed to convert MAC string to address");
2732                 free(mac_str);
2733                 goto failed;
2734         }
2735
2736         g_free(mac_str);
2737
2738         return 0;
2739
2740 failed:
2741         res = _ws_update_local_dev_addr_from_file();
2742         if (res < 0) {
2743                 WDP_LOGE("Failed to update local device address from file");
2744                 return -1;
2745         }
2746
2747         return 1;
2748 }
2749
2750 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
2751 int _ws_set_default_eapol_over_ip()
2752 {
2753         __WDP_LOG_FUNC_ENTER__;
2754
2755         ws_sock_data_s *sock = g_pd->common;
2756         char cmd[80] = {0, };
2757         char reply[1024] = {0,};
2758         int res;
2759
2760         if (!sock) {
2761                 WDP_LOGE("Socket is NULL");
2762                 return -1;
2763         }
2764
2765         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "ip_addr_go %s",
2766                         DEFAULT_IP_GO);
2767
2768         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2769         if (res < 0) {
2770                 WDP_LOGE("Failed to send command to wpa_supplicant");
2771                 __WDP_LOG_FUNC_EXIT__;
2772                 return -1;
2773         }
2774
2775         if (strstr(reply, "FAIL")) {
2776                 WDP_LOGE("Failed to set go intent");
2777                 __WDP_LOG_FUNC_EXIT__;
2778                 return -1;
2779         }
2780
2781         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "ip_addr_mask %s",
2782                         DEFAULT_IP_MASK);
2783
2784         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2785         if (res < 0) {
2786                 WDP_LOGE("Failed to send command to wpa_supplicant");
2787                 __WDP_LOG_FUNC_EXIT__;
2788                 return -1;
2789         }
2790
2791         if (strstr(reply, "FAIL")) {
2792                 WDP_LOGE("Failed to set go intent");
2793                 __WDP_LOG_FUNC_EXIT__;
2794                 return -1;
2795         }
2796
2797         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "ip_addr_start %s",
2798                         DEFAULT_IP_START);
2799
2800         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2801         if (res < 0) {
2802                 WDP_LOGE("Failed to send command to wpa_supplicant");
2803                 __WDP_LOG_FUNC_EXIT__;
2804                 return -1;
2805         }
2806
2807         if (strstr(reply, "FAIL")) {
2808                 WDP_LOGE("Failed to set go intent");
2809                 __WDP_LOG_FUNC_EXIT__;
2810                 return -1;
2811         }
2812
2813         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "ip_addr_end %s",
2814                         DEFAULT_IP_END);
2815
2816         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2817         if (res < 0) {
2818                 WDP_LOGE("Failed to send command to wpa_supplicant");
2819                 __WDP_LOG_FUNC_EXIT__;
2820                 return -1;
2821         }
2822
2823         if (strstr(reply, "FAIL")) {
2824                 WDP_LOGE("Failed to set go intent");
2825                 __WDP_LOG_FUNC_EXIT__;
2826                 return -1;
2827         }
2828         WDP_LOGD("Succeeded to set default EAPol over IP");
2829
2830         __WDP_LOG_FUNC_EXIT__;
2831         return 0;
2832 }
2833 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
2834
2835 int ws_activate(int concurrent)
2836 {
2837         __WDP_LOG_FUNC_ENTER__;
2838         int res = 0;
2839         int retry_count = 0;
2840
2841         while (retry_count < 10) {
2842                 /* load wlan driver */
2843                 res = __ws_p2p_firmware_start();
2844                 if (res < 0) {
2845                         WDP_LOGE("Failed to load driver [ret=%d]", res);
2846                         return -1;
2847                 }
2848                 WDP_LOGI("P2P firmware started with error %d", res);
2849
2850                 if (__ws_check_net_interface(COMMON_IFACE_NAME) < 0) {
2851                         usleep(150000); /* wait for 150ms */
2852                         retry_count++;
2853                         WDP_LOGE("interface is not up: retry, %d", retry_count);
2854                 } else {
2855                         break;
2856                 }
2857         }
2858
2859         if (retry_count >= 10) {
2860                 WDP_LOGE("Driver loading is failed", res);
2861                 __WDP_LOG_FUNC_EXIT__;
2862                 return -1;
2863         }
2864         if (retry_count > 0) {
2865                 /*  Give driver marginal time to config net */
2866                 WDP_LOGE("Driver loading is done. Wait marginal time for driver");
2867                 sleep(1); /* 1s */
2868         }
2869
2870         g_pd->concurrent = concurrent;
2871
2872
2873         /* load wpa_supplicant */
2874         res = __ws_p2p_supplicant_start();
2875         if (res == -1) {
2876                 WDP_LOGE("Failed to start p2p_supplicant [%d: %s]", res, strerror(errno));
2877                 res = __ws_p2p_firmware_stop();
2878                 WDP_LOGI("P2P firmware stopped with error %d", res);
2879                 __WDP_LOG_FUNC_EXIT__;
2880                 return -1;
2881         }
2882
2883         res = _connect_to_supplicant(COMMON_IFACE_NAME, &g_pd->common);
2884         if (res < 0) {
2885                 res = __ws_p2p_supplicant_stop();
2886                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2887                 res = __ws_p2p_firmware_stop();
2888                 WDP_LOGI("P2P firmware stopped with error %d", res);
2889                 __WDP_LOG_FUNC_EXIT__;
2890                 return -1;
2891         }
2892
2893         g_pd->activated = TRUE;
2894
2895         _ws_update_local_dev_addr();
2896 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
2897         _ws_set_default_eapol_over_ip();
2898 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
2899
2900         __WDP_LOG_FUNC_EXIT__;
2901         return 0;
2902 }
2903
2904 int ws_deactivate(int concurrent)
2905 {
2906         __WDP_LOG_FUNC_ENTER__;
2907         char cmd[32] = {0, };
2908         char reply[1024] = {0,};
2909         int res = 0;
2910
2911         if (!g_pd->activated) {
2912                 WDP_LOGE("Wi-Fi Direct is not activated");
2913                 return -1;
2914         }
2915
2916         ws_stop_scan();
2917
2918         g_pd->concurrent = concurrent;
2919
2920         if (g_pd->group) {
2921                 _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
2922                 g_pd->group = NULL;
2923         }
2924
2925         /*  terminate wpasupplicant */
2926         snprintf(cmd, sizeof(cmd), WS_CMD_TERMINATE);
2927         res = _ws_send_cmd(g_pd->common->ctrl_sock, cmd, reply, sizeof(reply));
2928         if (res < 0) {
2929                 WDP_LOGE("Failed to send command to wpa_supplicant");
2930                 res = __ws_p2p_supplicant_stop();
2931                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2932                 goto done;
2933         }
2934
2935         if (!strncmp(reply, "FAIL", 4)) {
2936                 WDP_LOGE("Failed to terminate wpa_supplicant");
2937                 res = __ws_p2p_supplicant_stop();
2938                 WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2939                 goto done;
2940         }
2941
2942         res = _disconnect_from_supplicant(COMMON_IFACE_NAME, g_pd->common);
2943         if (res < 0) {
2944                 WDP_LOGE("Failed to disconnect common interface(%s) from supplicant. ",
2945                         COMMON_IFACE_NAME);
2946         }
2947
2948         res = __ws_p2p_supplicant_stop();
2949         WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
2950
2951 done:
2952         res = __ws_p2p_firmware_stop();
2953         WDP_LOGI("P2P firmware stopped with error %d", res);
2954         g_pd->activated = FALSE;
2955
2956         __WDP_LOG_FUNC_EXIT__;
2957         return 0;
2958 }
2959
2960 static gboolean _retry_start_scan(gpointer data)
2961 {
2962         ws_sock_data_s *sock = g_pd->common;
2963         char reply[1024] = {0, };
2964         static int retry_cnt = 0;
2965         int res = 0;
2966         char *cmd = (char *)data;
2967
2968         if (NULL == sock || NULL == cmd) {
2969                 WDP_LOGE("Data is NULL, Retry Scan Failed !!!");
2970                 goto done;
2971         }
2972
2973         if (WS_SCAN_RETRY_COUNT == retry_cnt) {
2974                 WDP_LOGE("Maximum Retry Reached. Aborting Scan.");
2975                 goto done;
2976         }
2977
2978         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2979         if (res < 0) {
2980                 WDP_LOGE("Failed to send command to wpa_supplicant");
2981                 goto done;
2982         }
2983
2984         if (strstr(reply, "FAIL")) {
2985                 WDP_LOGE("Retry Scan Failed, Retry after 100ms...");
2986                 retry_cnt++;
2987                 return TRUE;
2988         }
2989
2990         WDP_LOGD("Retry Scan Succeeded.");
2991
2992 done:
2993         retry_cnt = 0;
2994         if (NULL != cmd) {
2995                 free(cmd);
2996                 cmd = NULL;
2997         }
2998         return FALSE;
2999 }
3000
3001 int ws_start_scan(wfd_oem_scan_param_s *param)
3002 {
3003         __WDP_LOG_FUNC_ENTER__;
3004         ws_sock_data_s *sock = g_pd->common;
3005         char cmd[40] = {0, };
3006         char reply[1024] = {0, };
3007         char time_str[4] = {0, };
3008         char type_str[20] = {0, };
3009         int res = 0;
3010         char *retry_cmd = NULL;
3011
3012         if (!param) {
3013                 WDP_LOGE("Invalid parameter");
3014                 return -1;
3015         }
3016
3017         if (!sock) {
3018                 WDP_LOGE("Socket is NULL");
3019                 return -1;
3020         }
3021
3022         if (param->refresh)
3023                 _ws_flush();
3024
3025         if (param->scan_time)
3026                 g_snprintf(time_str, 4, " %d", param->scan_time);
3027
3028         if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
3029                 g_snprintf(type_str, 20, " type=social");
3030         else if (param->scan_type == WFD_OEM_SCAN_TYPE_SPECIFIC &&
3031                         param->freq > 0)
3032                 g_snprintf(type_str, 20, " freq=%d", param->freq);
3033         else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL1)
3034                 g_snprintf(type_str, 20, " type=specific1");
3035         else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL6)
3036                 g_snprintf(type_str, 20, " type=specific6");
3037         else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL11)
3038                 g_snprintf(type_str, 20, " type=specific11");
3039         else if (param->scan_type == WFD_OEM_SCAN_TYPE_GO_FREQ)
3040                 g_snprintf(type_str, 20, " type=frequency");
3041
3042         if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE)
3043                 g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND "%s%s",
3044                                         (param->scan_time > 0) ? time_str : "",
3045                                         (param->scan_type) ? type_str : "");
3046         else
3047                 g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_LISTEN);
3048
3049         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3050         if (res < 0) {
3051                 WDP_LOGE("Failed to send command to wpa_supplicant");
3052                 __WDP_LOG_FUNC_EXIT__;
3053                 return -1;
3054         }
3055
3056         if (strstr(reply, "FAIL")) {
3057                 WDP_LOGE("Failed to start scan, Retry");
3058                 retry_cmd = strdup(cmd);
3059                 /* Add Timeout of 100ms for retry SCAN */
3060                 g_timeout_add(100, _retry_start_scan, (gpointer) retry_cmd);
3061                 __WDP_LOG_FUNC_EXIT__;
3062                 return 0;
3063         }
3064         WDP_LOGD("Succeeded to start scan");
3065
3066         __WDP_LOG_FUNC_EXIT__;
3067         return 0;
3068 }
3069
3070 int ws_stop_scan()
3071 {
3072         __WDP_LOG_FUNC_ENTER__;
3073         ws_sock_data_s *sock = g_pd->common;
3074         char reply[1024] = {0, };
3075         int res = 0;
3076
3077         if (!sock) {
3078                 WDP_LOGE("Socket is NULL");
3079                 return -1;
3080         }
3081
3082         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_STOP_FIND, reply, sizeof(reply));
3083         if (res < 0) {
3084                         WDP_LOGE("Failed to send command to wpa_supplicant");
3085                         __WDP_LOG_FUNC_EXIT__;
3086                         return -1;
3087         }
3088
3089         if (strstr(reply, "FAIL")) {
3090                 WDP_LOGE("Failed to stop scan");
3091                 __WDP_LOG_FUNC_EXIT__;
3092                 return -1;
3093         }
3094         WDP_LOGD("Succeeded to stop scan");
3095
3096
3097         __WDP_LOG_FUNC_EXIT__;
3098         return 0;
3099 }
3100
3101 int ws_get_visibility(int *visibility)
3102 {
3103         __WDP_LOG_FUNC_ENTER__;
3104
3105         __WDP_LOG_FUNC_EXIT__;
3106         return 0;
3107 }
3108
3109 int ws_set_visibility(int visibility)
3110 {
3111         __WDP_LOG_FUNC_ENTER__;
3112
3113         __WDP_LOG_FUNC_EXIT__;
3114         return 0;
3115 }
3116
3117 int ws_get_scan_result(GList **peers, int *peer_count)
3118 {
3119         __WDP_LOG_FUNC_ENTER__;
3120         ws_sock_data_s *sock = g_pd->common;
3121         char cmd[32] = {0, };
3122         char reply[1024] = {0,};
3123         wfd_oem_device_s *peer = NULL;
3124         int res = 0;
3125
3126         if (!peers || !peer_count) {
3127                 WDP_LOGE("Invalid parameter");
3128                 return -1;
3129         }
3130
3131         if (!sock) {
3132                 WDP_LOGE("Socket is NULL");
3133                 return -1;
3134         }
3135
3136         g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER_FIRST);
3137         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3138         if (res < 0) {
3139                         WDP_LOGE("Failed to send command to wpa_supplicant");
3140                         __WDP_LOG_FUNC_EXIT__;
3141                         return -1;
3142         }
3143
3144         if (strstr(reply, "FAIL")) {
3145                 WDP_LOGE("Failed to get first peer info");
3146                 __WDP_LOG_FUNC_EXIT__;
3147                 return -1;
3148         }
3149         WDP_LOGD("Succeeded to get first peer info");
3150
3151         peer = (wfd_oem_device_s *) g_try_malloc0(sizeof(wfd_oem_device_s));
3152         if (!peer) {
3153                 WDP_LOGF("Failed to allocate memory for peer.");
3154                 return -1;
3155         }
3156
3157         res = _parsing_peer_info(reply, peer);
3158         if (res < 0) {
3159                         WDP_LOGE("Failed to parsing peer info");
3160                         g_free(peer);
3161                         __WDP_LOG_FUNC_EXIT__;
3162                         return -1;
3163         }
3164
3165         *peers = g_list_prepend(*peers, peer);
3166
3167         do {
3168                 g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER_NEXT MACSTR, MAC2STR(peer->dev_addr));
3169                 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3170                 if (res < 0) {
3171                                 WDP_LOGE("Failed to send command to wpa_supplicant");
3172                                 break;
3173                 }
3174
3175                 if (strstr(reply, "FAIL")) {
3176                         WDP_LOGE("Failed to get first peer info");
3177                         break;
3178                 }
3179                 WDP_LOGD("Succeeded to get first peer info");
3180
3181                 peer = (wfd_oem_device_s *) g_try_malloc0(sizeof(wfd_oem_device_s));
3182                 if (!peer) {
3183                         WDP_LOGF("Failed to allocate memory for peer");
3184                         break;
3185                 }
3186
3187                 res = _parsing_peer_info(reply, peer);
3188                 if (res < 0) {
3189                         WDP_LOGE("Failed to parsing peer info");
3190                         g_free(peer);
3191                         break;
3192                 }
3193
3194                 *peers = g_list_prepend(*peers, peer);
3195         } while (1);
3196
3197         __WDP_LOG_FUNC_EXIT__;
3198         return 0;
3199 }
3200
3201 int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
3202 {
3203         __WDP_LOG_FUNC_ENTER__;
3204         ws_sock_data_s *sock = g_pd->common;
3205         char cmd[32] = {0, };
3206         char reply[1024] = {0,};
3207         wfd_oem_device_s *ws_dev = NULL;
3208         int res = 0;
3209
3210         if (!peer_addr || !peer) {
3211                 WDP_LOGE("Invalid parameter");
3212                 return -1;
3213         }
3214
3215         if (!sock) {
3216                 WDP_LOGE("Socket is NULL");
3217                 return -1;
3218         }
3219
3220         g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER MACSTR, MAC2STR(peer_addr));
3221         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3222         if (res < 0) {
3223                         WDP_LOGE("Failed to send command to wpa_supplicant");
3224                         __WDP_LOG_FUNC_EXIT__;
3225                         return -1;
3226         }
3227
3228         if (strstr(reply, "FAIL")) {
3229                 WDP_LOGD("Failed to get peer info [" MACSECSTR "]", MAC2SECSTR(peer_addr));
3230                 __WDP_LOG_FUNC_EXIT__;
3231                 return -1;
3232         }
3233         WDP_LOGD("Succeeded to get peer info [" MACSECSTR "]", MAC2SECSTR(peer_addr));
3234
3235         ws_dev = (wfd_oem_device_s*) g_try_malloc0(sizeof(wfd_oem_device_s));
3236         if (!ws_dev) {
3237                 WDP_LOGF("Failed to allocate memory for device");
3238                 return -1;
3239         }
3240
3241         res = _parsing_peer_info(reply, ws_dev);
3242         if (res < 0) {
3243                 WDP_LOGE("Failed to parsing peer info");
3244                 g_free(ws_dev);
3245                 __WDP_LOG_FUNC_EXIT__;
3246                 return -1;
3247         }
3248
3249         *peer = ws_dev;
3250         __WDP_LOG_FUNC_EXIT__;
3251         return 0;
3252 }
3253
3254 int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
3255 {
3256         __WDP_LOG_FUNC_ENTER__;
3257         ws_sock_data_s *sock = g_pd->common;
3258         char cmd[64] = {0, };
3259         char reply[1024] = {0,};
3260         int res;
3261
3262         if (!sock) {
3263                 WDP_LOGE("Socket is NULL");
3264                 return -1;
3265         }
3266
3267         g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PROV_DISC MACSTR "%s",
3268                                         MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
3269
3270         if (join)
3271                 strncat(cmd, WS_STR_JOIN, 5);
3272
3273         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3274         if (res < 0) {
3275                         WDP_LOGE("Failed to send command to wpa_supplicant");
3276                         __WDP_LOG_FUNC_EXIT__;
3277                         return -1;
3278         }
3279
3280         if (strstr(reply, "FAIL")) {
3281                 WDP_LOGD("Failed to send provision discovery to peer[" MACSECSTR "]",
3282                                                                 MAC2SECSTR(peer_addr));
3283                 __WDP_LOG_FUNC_EXIT__;
3284                 return -1;
3285         }
3286         WDP_LOGD("Succeeded to send provision discovery to peer[" MACSECSTR "]",
3287                                                                 MAC2SECSTR(peer_addr));
3288         memcpy(g_pd_out, peer_addr, OEM_MACADDR_LEN);
3289
3290         __WDP_LOG_FUNC_EXIT__;
3291         return 0;
3292 }
3293
3294 int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
3295 {
3296         __WDP_LOG_FUNC_ENTER__;
3297         ws_sock_data_s *sock = g_pd->common;
3298         char cmd[64] = {0, };
3299         char freq_str[11] = {0, };
3300         char reply[1024] = {0, };
3301         int res = 0;
3302
3303         if (!peer_addr) {
3304                 WDP_LOGE("Invalid parameter");
3305                 return -1;
3306         }
3307
3308         if (!sock) {
3309                 WDP_LOGE("Socket is NULL");
3310                 return -1;
3311         }
3312
3313         if (param->wps_pin[0] != '\0')
3314                 g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR " %s%s" ,
3315                                                         MAC2STR(peer_addr), param->wps_pin,
3316                                                         _ws_wps_to_txt(param->wps_mode));
3317         else
3318                 g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR "%s",
3319                                                         MAC2STR(peer_addr),
3320                                                         _ws_wps_to_txt(param->wps_mode));
3321
3322         if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
3323                 strncat(cmd, WS_STR_JOIN, 5);
3324         else if (param->conn_flags & WFD_OEM_CONN_TYPE_AUTH)
3325                 strncat(cmd, WS_STR_AUTH, 5);
3326
3327         if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
3328                 strncat(cmd, WS_STR_PERSISTENT, 11);
3329
3330         if (param->freq > 0) {
3331                 g_snprintf(freq_str, sizeof(freq_str), WS_STR_FREQ "%d", param->freq);
3332                 strncat(cmd, freq_str, sizeof(freq_str));
3333         }
3334
3335         WDP_LOGI("Connection command [%s]", cmd);
3336
3337         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3338         if (res < 0) {
3339                         WDP_LOGE("Failed to send command to wpa_supplicant");
3340                         __WDP_LOG_FUNC_EXIT__;
3341                         return -1;
3342         }
3343
3344         if (strstr(reply, "FAIL")) {
3345                 WDP_LOGD("Failed to connect with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3346                 __WDP_LOG_FUNC_EXIT__;
3347                 return -1;
3348         }
3349         WDP_LOGD("Succeeded to send connection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3350
3351         __WDP_LOG_FUNC_EXIT__;
3352         return 0;
3353 }
3354
3355 int ws_disconnect(unsigned char *peer_addr, int is_iface_addr)
3356 {
3357         __WDP_LOG_FUNC_ENTER__;
3358         ws_sock_data_s *sock = g_pd->common;
3359         char cmd[48] = {0, };
3360         char reply[1024] = {0,};
3361         int res;
3362
3363         if (!peer_addr) {
3364                 WDP_LOGE("Invalid parameter");
3365                 return -1;
3366         }
3367
3368         if (!sock) {
3369                 WDP_LOGE("Socket is NULL");
3370                 return -1;
3371         }
3372
3373         WDP_LOGD("Peer address is [" MACSECSTR "]. Disconnect selected peer",
3374                         MAC2SECSTR(peer_addr));
3375
3376         if (is_iface_addr)
3377                 g_snprintf(cmd, sizeof(cmd),
3378                                 WS_CMD_P2P_REMOVE_CLIENT "iface=" MACSTR,
3379                                 MAC2STR(peer_addr));
3380         else
3381                 g_snprintf(cmd, sizeof(cmd),
3382                                 WS_CMD_P2P_REMOVE_CLIENT MACSTR,
3383                                 MAC2STR(peer_addr));
3384
3385         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3386         if (res < 0) {
3387                 WDP_LOGE("Failed to send command to wpa_supplicant");
3388                 __WDP_LOG_FUNC_EXIT__;
3389                 return -1;
3390         }
3391
3392         if (strstr(reply, "FAIL")) {
3393                 WDP_LOGD("Failed to disconnect with peer[" MACSECSTR "]",
3394                                 MAC2SECSTR(peer_addr));
3395                 __WDP_LOG_FUNC_EXIT__;
3396                 return -1;
3397         }
3398         WDP_LOGD("Succeeded to send disconnection command to peer[" MACSECSTR "]",
3399                         MAC2SECSTR(peer_addr));
3400
3401         __WDP_LOG_FUNC_EXIT__;
3402         return 0;
3403 }
3404
3405 int ws_reject_connection(unsigned char *peer_addr)
3406 {
3407         __WDP_LOG_FUNC_ENTER__;
3408         ws_sock_data_s *sock = g_pd->common;
3409         char cmd[64] = {0, };
3410         char reply[1024] = {0,};
3411         int res;
3412
3413         if (!sock) {
3414                 WDP_LOGE("Socket is NULL");
3415                 return -1;
3416         }
3417
3418         g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR "%s userReject", MAC2STR(peer_addr), WS_STR_PBC);
3419         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3420         if (res < 0) {
3421                         WDP_LOGE("Failed to send command to wpa_supplicant");
3422                         __WDP_LOG_FUNC_EXIT__;
3423                         return -1;
3424         }
3425
3426         if (strstr(reply, "FAIL")) {
3427                 WDP_LOGD("Failed to reject connection with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3428                 __WDP_LOG_FUNC_EXIT__;
3429                 return -1;
3430         }
3431         WDP_LOGD("Succeeded to send reject connection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
3432
3433         __WDP_LOG_FUNC_EXIT__;
3434         return 0;
3435 }
3436
3437 int ws_cancel_connection(unsigned char *peer_addr)
3438 {
3439         __WDP_LOG_FUNC_ENTER__;
3440
3441         _ws_cancel();
3442
3443         __WDP_LOG_FUNC_EXIT__;
3444         return 0;
3445 }
3446
3447 int ws_get_connected_peers(GList **peers, int *peer_count)
3448 {
3449         __WDP_LOG_FUNC_ENTER__;
3450
3451         __WDP_LOG_FUNC_EXIT__;
3452         return 0;
3453 }
3454
3455 int ws_get_pin(char *pin)
3456 {
3457         __WDP_LOG_FUNC_ENTER__;
3458
3459         __WDP_LOG_FUNC_EXIT__;
3460         return 0;
3461 }
3462
3463 int ws_set_pin(char *pin)
3464 {
3465         __WDP_LOG_FUNC_ENTER__;
3466
3467         __WDP_LOG_FUNC_EXIT__;
3468         return 0;
3469 }
3470
3471 int ws_generate_pin(char **pin)
3472 {
3473         __WDP_LOG_FUNC_ENTER__;
3474         ws_sock_data_s *sock = g_pd->common;
3475         char cmd[32] = {0, };
3476         char reply[1024] = {0,};
3477         int res = 0;
3478         if (!pin) {
3479                 WDP_LOGE("Invalid parameter");
3480                 return -1;
3481         }
3482
3483         if (!sock) {
3484                 WDP_LOGE("Socket is NULL");
3485                 return -1;
3486         }
3487
3488         snprintf(cmd, sizeof(cmd), WS_CMD_WPS_PIN "get");
3489         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3490         if (res < 0) {
3491                 WDP_LOGE("Failed to send command to wpa_supplicant");
3492                 __WDP_LOG_FUNC_EXIT__;
3493                 return -1;
3494         }
3495
3496         if (strstr(reply, "FAIL")) {
3497                 WDP_LOGE("Failed to generate the pin");
3498                 __WDP_LOG_FUNC_EXIT__;
3499                 return -1;
3500         }
3501         WDP_LOGE("Succeeded to generate the pin [ %s ]", reply);
3502
3503         *pin = strndup(reply, OEM_PINSTR_LEN);
3504
3505         __WDP_LOG_FUNC_EXIT__;
3506         return 0;
3507 }
3508
3509 int ws_get_supported_wps_mode()
3510 {
3511         __WDP_LOG_FUNC_ENTER__;
3512
3513         __WDP_LOG_FUNC_EXIT__;
3514         return 0;
3515 }
3516
3517 int ws_create_group(wfd_oem_group_param_s *param)
3518 {
3519         __WDP_LOG_FUNC_ENTER__;
3520         ws_sock_data_s *sock = g_pd->common;
3521         char cmd[44] = {0, };
3522         char freq_str[11] = {0, };
3523         char passphrase[21] = {0, };
3524         char reply[1024] = {0,};
3525         int res = 0;
3526
3527         if (!sock) {
3528                 WDP_LOGE("Socket is NULL");
3529                 return -1;
3530         }
3531
3532         if (param->persistent) {
3533                 if (param->persistent == 2)
3534                         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD WS_STR_PERSISTENT "=%d",
3535                                         param->persistent_group_id);
3536                 else
3537                         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD WS_STR_PERSISTENT);
3538         }
3539
3540         if (param->freq > 0) {
3541                 g_snprintf(freq_str, sizeof(freq_str), WS_STR_FREQ "%d", param->freq);
3542                 strncat(cmd, freq_str, sizeof(freq_str));
3543         } else {
3544 #ifndef TIZEN_WLAN_BOARD_SPRD
3545                 strncat(cmd, WS_STR_FREQ_2G, 8);
3546 #endif /* TIZEN_WLAN_BOARD_SPRD */
3547         }
3548
3549         if (param->passphrase[0] != '\0') {
3550                 g_snprintf(passphrase, sizeof(passphrase), WS_STR_PASSPHRASE "%s", param->passphrase);
3551                 strncat(cmd, passphrase, sizeof(passphrase));
3552         }
3553
3554         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3555         if (res < 0) {
3556                         WDP_LOGE("Failed to send command to wpa_supplicant");
3557                         __WDP_LOG_FUNC_EXIT__;
3558                         return -1;
3559         }
3560
3561         if (strstr(reply, "FAIL")) {
3562                 WDP_LOGE("Failed to add group");
3563                 __WDP_LOG_FUNC_EXIT__;
3564                 return -1;
3565         }
3566         WDP_LOGD("Succeeded to add group");
3567
3568         __WDP_LOG_FUNC_EXIT__;
3569         return 0;
3570 }
3571
3572 int ws_destroy_group(const char *ifname)
3573 {
3574         __WDP_LOG_FUNC_ENTER__;
3575         ws_sock_data_s *sock = g_pd->common;
3576         char cmd[32] = {0, };
3577         char reply[1024] = {0,};
3578         int res = 0;
3579
3580         if (!ifname) {
3581                 WDP_LOGE("Invalid parameter");
3582                 return -1;
3583         }
3584
3585         if (!sock) {
3586                 WDP_LOGE("Socket is NULL");
3587                 return -1;
3588         }
3589
3590         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_REMOVE "%s", ifname);
3591
3592         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3593         if (res < 0) {
3594                         WDP_LOGE("Failed to send command to wpa_supplicant");
3595                         __WDP_LOG_FUNC_EXIT__;
3596                         return -1;
3597         }
3598
3599         if (strstr(reply, "FAIL")) {
3600                 WDP_LOGE("Failed to remove group");
3601                 __WDP_LOG_FUNC_EXIT__;
3602                 return -1;
3603         }
3604         WDP_LOGD("Succeeded to remove group");
3605
3606         _ws_flush();
3607
3608         __WDP_LOG_FUNC_EXIT__;
3609         return 0;
3610 }
3611
3612 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
3613 {
3614         __WDP_LOG_FUNC_ENTER__;
3615         ws_sock_data_s *sock = g_pd->common;
3616         char cmd[128] = {0, };
3617         char reply[1024] = {0,};
3618         int res = 0;
3619
3620         if (!peer_addr || !param) {
3621                 WDP_LOGE("Invalid parameter");
3622                 return -1;
3623         }
3624
3625         if (!sock) {
3626                 WDP_LOGE("Group interface not connected");
3627                 return -1;
3628         }
3629
3630         WDP_LOGD("Invite: Peer[" MACSECSTR "], GO Addr[" MACSECSTR "]",
3631                                 MAC2SECSTR(peer_addr), MAC2SECSTR(param->go_dev_addr));
3632
3633         if (param->net_id)
3634                 g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_INVITE "persistent=%d peer=" MACSTR " go_dev_addr=" MACSTR,
3635                                                                 param->net_id, MAC2STR(peer_addr),
3636                                                                 MAC2STR(param->go_dev_addr));
3637         else
3638                 g_snprintf(cmd, sizeof(cmd), WS_CMD_P2P_INVITE "group=%s peer=" MACSTR " go_dev_addr=" MACSTR,
3639                                                                 param->ifname, MAC2STR(peer_addr),
3640                                                                 MAC2STR(param->go_dev_addr));
3641
3642         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3643         if (res < 0) {
3644                         WDP_LOGE("Failed to send command to wpa_supplicant");
3645                         __WDP_LOG_FUNC_EXIT__;
3646                         return -1;
3647         }
3648
3649         if (strstr(reply, "FAIL")) {
3650                 WDP_LOGE("Failed to invite peer");
3651                 __WDP_LOG_FUNC_EXIT__;
3652                 return -1;
3653         }
3654         WDP_LOGD("Succeeded to invite peer");
3655
3656         __WDP_LOG_FUNC_EXIT__;
3657         return 0;
3658 }
3659
3660 /* Only group owner can use this command */
3661 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
3662 {
3663         __WDP_LOG_FUNC_ENTER__;
3664         ws_sock_data_s *sock = g_pd->group;
3665         char cmd[40] = {0, };
3666         char reply[1024] = {0,};
3667         int res;
3668
3669         if (!peer_addr || !pin) {
3670                 WDP_LOGE("Invalid parameter");
3671                 return -1;
3672         }
3673
3674         if (!sock) {
3675                 WDP_LOGE("Group interface not connected");
3676                 return -1;
3677         }
3678
3679         if (wps_mode == WFD_OEM_WPS_MODE_PBC)
3680                 g_snprintf(cmd, sizeof(cmd), WS_CMD_WPS_PBC "p2p_dev_addr=" MACSTR, MAC2STR(peer_addr));
3681         else
3682                 g_snprintf(cmd, sizeof(cmd), WS_CMD_WPS_PIN MACSTR " %s", MAC2STR(peer_addr), pin);
3683
3684         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3685         if (res < 0) {
3686                         WDP_LOGE("Failed to send command to wpa_supplicant");
3687                         __WDP_LOG_FUNC_EXIT__;
3688                         return -1;
3689         }
3690
3691         if (strstr(reply, "FAIL")) {
3692                 WDP_LOGE("Failed to start WPS");
3693                 __WDP_LOG_FUNC_EXIT__;
3694                 return -1;
3695         }
3696         WDP_LOGD("Succeeded to start WPS");
3697
3698         __WDP_LOG_FUNC_EXIT__;
3699         return 0;
3700 }
3701
3702 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
3703 {
3704         __WDP_LOG_FUNC_ENTER__;
3705         ws_sock_data_s *sock = g_pd->group;
3706         char cmd[64] = {0, };
3707         char reply[1024] = {0,};
3708         int res;
3709
3710         if (!peer_addr || !pin) {
3711                 WDP_LOGE("Invalid parameter");
3712                 return -1;
3713         }
3714
3715         if (!sock) {
3716                 WDP_LOGE("Socket is NULL");
3717                 return -1;
3718         }
3719
3720         if (wps_mode == WFD_OEM_WPS_MODE_PBC)
3721                 g_snprintf(cmd, sizeof(cmd), WS_CMD_WPS_ENROLLEE MACSTR "%s",
3722                                         MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
3723         else
3724                 g_snprintf(cmd, sizeof(cmd), WS_CMD_WPS_ENROLLEE MACSTR " %s%s",
3725                                         MAC2STR(peer_addr), pin, _ws_wps_to_txt(wps_mode));
3726
3727         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
3728         if (res < 0) {
3729                         WDP_LOGE("Failed to send command to wpa_supplicant");
3730                         __WDP_LOG_FUNC_EXIT__;
3731                         return -1;
3732         }
3733
3734         if (strstr(reply, "FAIL")) {
3735                 WDP_LOGE("Failed to start WPS");
3736                 __WDP_LOG_FUNC_EXIT__;
3737                 return -1;
3738         }
3739         WDP_LOGD("Succeeded to start WPS");
3740
3741         __WDP_LOG_FUNC_EXIT__;
3742         return 0;
3743 }
3744
3745 int ws_wps_cancel()
3746 {
3747         __WDP_LOG_FUNC_ENTER__;
3748         ws_sock_data_s *sock = g_pd->group;
3749         char reply[1024] = {0,};
3750         int res;
3751
3752         if (!sock) {
3753                 WDP_LOGE("Socket is NULL");
3754                 return -1;
3755         }
3756
3757         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_WPS_CANCEL, reply, sizeof(reply));
3758         if (res < 0) {
3759                         WDP_LOGE("Failed to send command to wpa_supplicant");
3760                         __WDP_LOG_FUNC_EXIT__;
3761                         return -1;
3762         }
3763
3764         if (strstr(reply, "FAIL")) {
3765                 WDP_LOGE("Failed to cancel WPS");
3766                 __WDP_LOG_FUNC_EXIT__;
3767                 return -1;
3768         }
3769         WDP_LOGD("Succeeded to cancel WPS");
3770
3771         __WDP_LOG_FUNC_EXIT__;
3772         return 0;
3773 }
3774
3775 int ws_get_dev_name(char *dev_name)
3776 {
3777         __WDP_LOG_FUNC_ENTER__;
3778
3779         __WDP_LOG_FUNC_EXIT__;
3780         return 0;
3781 }
3782
3783 int ws_set_dev_name(char *dev_name)
3784 {
3785         __WDP_LOG_FUNC_ENTER__;
3786         ws_sock_data_s *sock = g_pd->common;
3787         char cmd[128] = {0, };
3788         char reply[1024] = {0,};
3789         int res;
3790
3791         if (!dev_name || !strlen(dev_name)) {
3792                 WDP_LOGE("Invalid parameter");
3793                 __WDP_LOG_FUNC_EXIT__;
3794                 return 1;
3795         }
3796
3797         if (!sock) {
3798                 WDP_LOGE("Socket is NULL");
3799                 return -1;
3800         }
3801
3802         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "device_name %s", dev_name);
3803         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3804         if (res < 0) {
3805                 WDP_LOGE("Failed to send command to wpa_supplicant");
3806                 __WDP_LOG_FUNC_EXIT__;
3807                 return -1;
3808         }
3809
3810         if (strstr(reply, "FAIL")) {
3811                 WDP_LOGE("Failed to set device name");
3812                 __WDP_LOG_FUNC_EXIT__;
3813                 return -1;
3814         }
3815         WDP_LOGD("Succeeded to set device name");
3816
3817         memset(cmd, 0x0, 128);
3818         memset(reply, 0x0, 1024);
3819
3820         snprintf(cmd, sizeof(cmd), WS_CMD_SET "p2p_ssid_postfix %s", dev_name);
3821         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3822         if (res < 0) {
3823                         WDP_LOGE("Failed to send command to wpa_supplicant");
3824                         __WDP_LOG_FUNC_EXIT__;
3825                         return -1;
3826         }
3827
3828         if (strstr(reply, "FAIL")) {
3829                 WDP_LOGE("Failed to set SSID postfix");
3830                 __WDP_LOG_FUNC_EXIT__;
3831                 return -1;
3832         }
3833         WDP_LOGD("Succeeded to set SSID postfix");
3834
3835         __WDP_LOG_FUNC_EXIT__;
3836         return 0;
3837 }
3838
3839 int ws_get_dev_mac(char *dev_mac)
3840 {
3841         __WDP_LOG_FUNC_ENTER__;
3842
3843         __WDP_LOG_FUNC_EXIT__;
3844         return 0;
3845 }
3846
3847 int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
3848 {
3849         __WDP_LOG_FUNC_ENTER__;
3850
3851         __WDP_LOG_FUNC_EXIT__;
3852         return 0;
3853 }
3854
3855 int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
3856 {
3857         __WDP_LOG_FUNC_ENTER__;
3858
3859         __WDP_LOG_FUNC_EXIT__;
3860         return 0;
3861 }
3862
3863 int ws_get_go_intent(int *go_intent)
3864 {
3865         __WDP_LOG_FUNC_ENTER__;
3866
3867         ws_sock_data_s *sock = g_pd->common;
3868         char cmd[80] = {0, };
3869         char reply[1024] = {0,};
3870         int res;
3871
3872         if (!sock) {
3873                 WDP_LOGE("Socket is NULL");
3874                 return -1;
3875         }
3876
3877         if (go_intent == NULL) {
3878                 WDP_LOGE("p2p_go_intent is NULL");
3879                 __WDP_LOG_FUNC_EXIT__;
3880                 return -1;
3881         }
3882
3883         g_snprintf(cmd, sizeof(cmd), WS_CMD_GET "p2p_go_intent");
3884         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3885         if (res < 0) {
3886                 WDP_LOGE("Failed to send command to wpa_supplicant");
3887                 __WDP_LOG_FUNC_EXIT__;
3888                 return -1;
3889         }
3890
3891         if (strstr(reply, "FAIL")) {
3892                 WDP_LOGE("Failed to set go intent");
3893                 __WDP_LOG_FUNC_EXIT__;
3894                 return -1;
3895         }
3896
3897         *go_intent = atoi(reply);
3898         WDP_LOGD("Succeeded to get go intent(%d)", *go_intent);
3899
3900         __WDP_LOG_FUNC_EXIT__;
3901         return 0;
3902 }
3903
3904 int ws_set_go_intent(int go_intent)
3905 {
3906         __WDP_LOG_FUNC_ENTER__;
3907
3908         ws_sock_data_s *sock = g_pd->common;
3909         char cmd[80] = {0, };
3910         char reply[1024] = {0,};
3911         int res;
3912
3913         if (!sock) {
3914                 WDP_LOGE("Socket is NULL");
3915                 return -1;
3916         }
3917
3918         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "p2p_go_intent %d", go_intent);
3919
3920         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3921         if (res < 0) {
3922                 WDP_LOGE("Failed to send command to wpa_supplicant");
3923                 __WDP_LOG_FUNC_EXIT__;
3924                 return -1;
3925         }
3926
3927         if (strstr(reply, "FAIL")) {
3928                 WDP_LOGE("Failed to set go intent");
3929                 __WDP_LOG_FUNC_EXIT__;
3930                 return -1;
3931         }
3932         WDP_LOGD("Succeeded to set go intent(%d)", go_intent);
3933
3934         __WDP_LOG_FUNC_EXIT__;
3935         return 0;
3936 }
3937
3938 int ws_set_country(char *ccode)
3939 {
3940         __WDP_LOG_FUNC_ENTER__;
3941         ws_sock_data_s *sock = g_pd->common;
3942         char cmd[80] = {0, };
3943         char reply[1024] = {0,};
3944         int res;
3945
3946         if (!sock) {
3947                 WDP_LOGE("Socket is NULL");
3948                 return -1;
3949         }
3950
3951         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "country %s", ccode);
3952
3953         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
3954         if (res < 0) {
3955                 WDP_LOGE("Failed to send command to wpa_supplicant");
3956                 __WDP_LOG_FUNC_EXIT__;
3957                 return -1;
3958         }
3959
3960         if (strstr(reply, "FAIL")) {
3961                 WDP_LOGE("Failed to set country");
3962                 __WDP_LOG_FUNC_EXIT__;
3963                 return -1;
3964         }
3965         WDP_LOGD("Succeeded to set country(%s)", ccode);
3966
3967         __WDP_LOG_FUNC_EXIT__;
3968         return 0;
3969 }
3970
3971 int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
3972 {
3973         __WDP_LOG_FUNC_ENTER__;
3974         char *ptr = buf;
3975         int count = 0;
3976         char *tmp_str = NULL;
3977         int res = 0;
3978
3979         /* Passing first line : "network id / ssid / bssid / flags" */
3980         while (*ptr != '\n')
3981                 ptr++;
3982
3983         ptr++;
3984
3985         count = 0;
3986         while (*ptr != '\0') {
3987                 res = _extract_word(ptr, &tmp_str);
3988                 if (res > 0) {
3989                         networks[count].network_id = atoi(tmp_str);
3990                         g_free(tmp_str);
3991                         tmp_str = NULL;
3992                         ptr += res;
3993                 }
3994                 ptr++;
3995
3996                 res = _extract_word(ptr, &tmp_str);
3997                 if (res > 0) {
3998                         snprintf(networks[count].ssid, WS_SSID_LEN, "%s", tmp_str);
3999                         free(tmp_str);
4000                         tmp_str = NULL;
4001                         ptr += res;
4002                 }
4003                 ptr++;
4004
4005                 res = _extract_word(ptr, &tmp_str);
4006                 if (res > 0) {
4007                         _ws_txt_to_mac(tmp_str, networks[count].bssid);
4008                         g_free(tmp_str);
4009                         tmp_str = NULL;
4010                         ptr += res;
4011                 }
4012                 ptr++;
4013
4014                 res = _extract_word(ptr, &tmp_str);
4015                 if (res > 0) {
4016                         if (strstr(tmp_str, "CURRENT"))
4017                                 networks[count].flags |= WFD_OEM_NETFLAG_CURRENT;
4018                         if (strstr(tmp_str, "DISABLED"))
4019                                 networks[count].flags |= WFD_OEM_NETFLAG_DISABLED;
4020                         if (strstr(tmp_str, "TEMP-DISABLED"))
4021                                 networks[count].flags |= WFD_OEM_NETFLAG_TEMP_DISABLED;
4022                         if (strstr(tmp_str, "P2P-PERSISTENT"))
4023                                 networks[count].flags |= WFD_OEM_NETFLAG_P2P_PERSISTENT;
4024                         g_free(tmp_str);
4025                         tmp_str = NULL;
4026                         ptr += res;
4027                 }
4028                 ptr++;
4029
4030                 count++;
4031         }
4032
4033         *network_cnt = count;
4034
4035         __WDP_LOG_FUNC_EXIT__;
4036         return 0;
4037 }
4038
4039 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
4040 {
4041         __WDP_LOG_FUNC_ENTER__;
4042         ws_sock_data_s *sock = g_pd->common;
4043         char cmd[80] = {0, };
4044         char reply[1024] = {0,};
4045         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
4046         wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
4047         int res;
4048         int i, cnt;
4049
4050         if (!groups || !group_count) {
4051                 WDP_LOGE("Invalid parameter");
4052                 return -1;
4053         }
4054
4055         if (!sock) {
4056                 WDP_LOGE("Socket is NULL");
4057                 return -1;
4058         }
4059
4060         memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
4061
4062         /* Reading lists the configured networks, including stored information for persistent groups.
4063         The identifier in this is used with p2p_group_add and p2p_invite to indicate witch persistent
4064         group is to be reinvoked. */
4065         snprintf(cmd, sizeof(cmd), WS_CMD_LIST_NETWORKS);
4066         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4067         if (res < 0) {
4068                 WDP_LOGE("Failed to send command to wpa_supplicant");
4069                 __WDP_LOG_FUNC_EXIT__;
4070                 return -1;
4071         }
4072
4073         if (strstr(reply, "FAIL")) {
4074                 WDP_LOGE("Failed to get list of networks");
4075                 __WDP_LOG_FUNC_EXIT__;
4076                 return -1;
4077         }
4078         WDP_LOGD("Succeeded to get list of networks");
4079
4080         _parsing_networks(reply, networks, &cnt);
4081         WDP_LOGD("Persistent Group Count=%d", cnt);
4082         if (cnt > WS_MAX_PERSISTENT_COUNT) {
4083                 WDP_LOGE("Persistent group count exceeded or parsing error");
4084                 __WDP_LOG_FUNC_EXIT__;
4085                 return -1;
4086         }
4087
4088         if (cnt == 0) {
4089                 *group_count = cnt;
4090                 *groups = wfd_persistent_groups;
4091
4092                 __WDP_LOG_FUNC_EXIT__;
4093                 return 0;
4094         }
4095
4096         wfd_persistent_groups = (wfd_oem_persistent_group_s*) g_try_malloc0(cnt * sizeof(wfd_oem_persistent_group_s));
4097         if (wfd_persistent_groups == NULL) {
4098                 WDP_LOGE("Failed to allocate memory for wfd_persistent_groups ");
4099                 return -1;
4100         }
4101
4102         for (i = 0; i < cnt; i++) {
4103                 WDP_LOGD("----persistent group [%d]----", i);
4104                 WDP_LOGD("network_id=%d", networks[i].network_id);
4105                 WDP_LOGD("ssid=%s", networks[i].ssid);
4106                 WDP_LOGD("bssid=" MACSECSTR, MAC2SECSTR(networks[i].bssid));
4107                 WDP_LOGD("flags=%x", networks[i].flags);
4108
4109                 wfd_persistent_groups[i].network_id = networks[i].network_id;
4110                 g_strlcpy(wfd_persistent_groups[i].ssid, networks[i].ssid, OEM_DEV_NAME_LEN + 1);
4111                 wfd_persistent_groups[i].ssid[WS_SSID_LEN] = '\0';
4112                 memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
4113         }
4114
4115         *group_count = cnt;
4116         *groups = wfd_persistent_groups;
4117
4118         __WDP_LOG_FUNC_EXIT__;
4119         return 0;
4120 }
4121
4122 int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
4123 {
4124         __WDP_LOG_FUNC_ENTER__;
4125         ws_sock_data_s *sock = g_pd->common;
4126         char cmd[80] = {0, };
4127         char reply[1024] = {0,};
4128         int res;
4129         int i;
4130         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
4131         int network_count;
4132
4133         if (!ssid || !bssid) {
4134                 WDP_LOGE("Invalid parameter");
4135                 return -1;
4136         }
4137
4138         if (!sock) {
4139                 WDP_LOGE("Socket is NULL");
4140                 return -1;
4141         }
4142
4143         memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
4144
4145         strncpy(cmd, WS_CMD_LIST_NETWORKS, sizeof(cmd));
4146         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4147         if (res < 0) {
4148                 WDP_LOGE("Failed to send command to wpa_supplicant");
4149                 __WDP_LOG_FUNC_EXIT__;
4150                 return -1;
4151         }
4152
4153         if (strstr(reply, "FAIL")) {
4154                 WDP_LOGE("Failed to get list of networks");
4155                 __WDP_LOG_FUNC_EXIT__;
4156                 return -1;
4157         }
4158         WDP_LOGD("Succeeded to get list of networks");
4159
4160         _parsing_networks(reply, networks, &network_count);
4161
4162         for (i = 0; i < network_count; i++) {
4163                 WDP_LOGD("----persistent group [%d]----", i);
4164                 WDP_LOGD("network_id=%d", networks[i].network_id);
4165                 WDP_LOGD("ssid=%s", networks[i].ssid);
4166                 WDP_LOGD("bssid=" MACSECSTR, MAC2SECSTR(networks[i].bssid));
4167                 WDP_LOGD("flags=%x", networks[i].flags);
4168
4169                 if (!memcmp(bssid, networks[i].bssid, OEM_MACADDR_LEN) && !strcmp(ssid, networks[i].ssid)) {
4170
4171                         WDP_LOGD("Persistent group found [%d: %s]", networks[i].network_id, ssid);
4172
4173                         memset(cmd, 0x0, sizeof(cmd));
4174                         memset(reply, 0x0, sizeof(reply));
4175
4176                         g_snprintf(cmd, sizeof(cmd), WS_CMD_REMOVE_NETWORK " %d", networks[i].network_id);
4177                         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4178                         if (res < 0) {
4179                                 WDP_LOGE("Failed to send command to wpa_supplicant");
4180                                 __WDP_LOG_FUNC_EXIT__;
4181                                 return -1;
4182                         }
4183
4184                         if (strstr(reply, "FAIL")) {
4185                                 WDP_LOGE("Failed to remove persistent group");
4186                                 __WDP_LOG_FUNC_EXIT__;
4187                                 return -1;
4188                         }
4189                         WDP_LOGD("Succeeded to remove persistent group");
4190
4191                         break;
4192                 }
4193         }
4194
4195         if (i == network_count) {
4196                 WDP_LOGE("Persistent group not found [%s]", ssid);
4197                 return -1;
4198         }
4199
4200         __WDP_LOG_FUNC_EXIT__;
4201         return 0;
4202 }
4203
4204 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
4205 {
4206         __WDP_LOG_FUNC_ENTER__;
4207         ws_sock_data_s *sock = g_pd->common;
4208         char cmd[80] = {0, };
4209         char reply[1024] = {0,};
4210         int res;
4211
4212         if (!sock) {
4213                 WDP_LOGE("Socket is NULL");
4214                 return -1;
4215         }
4216
4217         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "persistent_reconnect %d", reconnect);
4218         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4219         if (res < 0) {
4220                 WDP_LOGE("Failed to send command to wpa_supplicant");
4221                 __WDP_LOG_FUNC_EXIT__;
4222                 return -1;
4223         }
4224
4225         if (strstr(reply, "FAIL")) {
4226                 WDP_LOGE("Failed to register WFDS service");
4227                 __WDP_LOG_FUNC_EXIT__;
4228                 return -1;
4229         }
4230         WDP_LOGD("Succeeded to register WFDS service");
4231
4232         __WDP_LOG_FUNC_EXIT__;
4233         return 0;
4234 }
4235
4236 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
4237 int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
4238 {
4239         __WDP_LOG_FUNC_ENTER__;
4240         ws_sock_data_s *sock = g_pd->common;
4241         char cmd[80] = {0, };
4242         char reply[1024] = {0,};
4243         int res;
4244         char query[30] = {'0', '2', '0', '0', 'F', 'F', '0', '1'};
4245         char mac_str[18] = {0, };
4246         wfd_oem_service_s *service = NULL;
4247
4248         if (!sock) {
4249                 WDP_LOGE("Socket is NULL");
4250                 return -1;
4251         }
4252
4253         memset(cmd, 0x00, 80);
4254         memset(reply, 0x00, WS_REPLY_LEN);
4255
4256         query[1] += OEM_SERVICE_TYPE_LEN /2;
4257         service = (wfd_oem_service_s*) g_try_malloc0(sizeof(wfd_oem_service_s));
4258         if (!service) {
4259                 WDP_LOGE("Failed to allocate memory for service");
4260                 return -1;
4261         }
4262         if (!service) {
4263                 WDP_LOGE("Failed to allocate memory for service");
4264                 return -1;
4265         }
4266
4267         if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
4268                 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
4269                 g_snprintf(mac_str, OEM_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
4270         } else {
4271                 g_snprintf(mac_str, OEM_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
4272         }
4273
4274         switch (service_type) {
4275         case WFD_OEM_SERVICE_TYPE_ALL:
4276         {
4277                 g_snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_ALL);
4278                 g_strlcpy(service->service_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
4279         }
4280         break;
4281         case WFD_OEM_SERVICE_TYPE_BONJOUR:
4282         {
4283                 g_snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_BONJOUR);
4284                 g_strlcpy(service->service_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
4285         }
4286         break;
4287         case WFD_OEM_SERVICE_TYPE_UPNP:
4288         {
4289                 g_snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_UPNP);
4290                 g_strlcpy(service->service_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
4291         }
4292         break;
4293         default:
4294                 WDP_LOGE("Invalid Service type");
4295                 __WDP_LOG_FUNC_EXIT__;
4296                 g_free(service);
4297                 return -1;
4298         }
4299
4300         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4301         if (res < 0) {
4302                 WDP_LOGE("Failed to send command to wpa_supplicant");
4303                 __WDP_LOG_FUNC_EXIT__;
4304                 g_free(service);
4305                 return -1;
4306         }
4307
4308         if (strstr(reply, "FAIL")) {
4309                 WDP_LOGE("Failed to start service discovery");
4310                 __WDP_LOG_FUNC_EXIT__;
4311                 g_free(service);
4312                 return -1;
4313         }
4314         WDP_LOGD("Succeeded to start service discovery");
4315
4316         g_strlcpy(service->dev_addr, mac_str, OEM_MACSTR_LEN);
4317         WDP_LOGD("query id :[0x%s]", reply);
4318         g_strlcpy(service->query_id, reply, OEM_QUERY_ID_LEN + 1);
4319
4320         res = _check_service_query_exists(service);
4321         if (res)
4322                 g_free(service);
4323         else
4324                 service_list = g_list_append(service_list, service);
4325
4326         __WDP_LOG_FUNC_EXIT__;
4327         return 0;
4328 }
4329
4330 int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
4331 {
4332         __WDP_LOG_FUNC_ENTER__;
4333         ws_sock_data_s *sock = g_pd->common;
4334         char cmd[80] = {0, };
4335         char reply[1024] = {0,};
4336         int res;
4337         char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
4338         char mac_str[18] = {0, };
4339         wfd_oem_service_s *data = NULL;
4340         char s_type[OEM_SERVICE_TYPE_LEN + 1] = {0, };
4341
4342         if (!sock) {
4343                 WDP_LOGE("Socket is NULL");
4344                 return -1;
4345         }
4346
4347         memset(cmd, 0x00, 80);
4348         memset(reply, 0x00, WS_REPLY_LEN);
4349
4350         if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
4351                 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
4352                 g_snprintf(mac_str, OEM_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
4353         } else {
4354                 g_snprintf(mac_str, OEM_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
4355         }
4356
4357         switch (service_type) {
4358         case WFD_OEM_SERVICE_TYPE_ALL:
4359                 g_strlcpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN + 1);
4360                 break;
4361         case WFD_OEM_SERVICE_TYPE_BONJOUR:
4362                 g_strlcpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN + 1);
4363                 break;
4364         case WFD_OEM_SERVICE_TYPE_UPNP:
4365                 g_strlcpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN + 1);
4366                 break;
4367         default:
4368                 __WDP_LOG_FUNC_EXIT__;
4369                 WDP_LOGE("Invalid Service type");
4370                 return -1;
4371         }
4372
4373         WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
4374         WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
4375
4376         data = _remove_service_query(s_type, mac_str, query_id);
4377         if (NULL == data)
4378                 return -1;
4379
4380         g_snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_CANCEL " %s", query_id);
4381         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4382         if (res < 0) {
4383                 WDP_LOGE("Failed to send command to wpa_supplicant");
4384                 __WDP_LOG_FUNC_EXIT__;
4385                 return -1;
4386         }
4387
4388         if (strstr(reply, "FAIL")) {
4389                 WDP_LOGE("Failed to cancel service discovery");
4390                 __WDP_LOG_FUNC_EXIT__;
4391                 return -1;
4392         }
4393         WDP_LOGD("Succeeded to cancel service discovery");
4394
4395         service_list = g_list_remove(service_list, data);
4396         g_free(data);
4397
4398         __WDP_LOG_FUNC_EXIT__;
4399         return 0;
4400 }
4401
4402 int _convert_bonjour_query_to_hex(char *query, char **hex)
4403 {
4404         char hex_key[256] = {0, };;
4405         char *token = NULL;
4406         char *temp = NULL;
4407         int len = 0;
4408         int tot_len = 0;
4409         int i = 0;
4410         char temp_str[256] = {0, };
4411         char *result_str = NULL;
4412         char *str_query = NULL;
4413
4414         if (!query || !hex) {
4415                 WDP_LOGE("Invalid parameter");
4416                 return -1;
4417         }
4418
4419         str_query = strdup(query);
4420         if (!str_query) {
4421                 WDP_LOGE("Memory allocation failed");
4422                 return -1;
4423         }
4424
4425         token = strtok_r(str_query, ".", &temp);
4426         while (token) {
4427                 if (!strcmp(token, "local") || !strcmp(token, "_tcp") || !strcmp(token, "_udp")) {
4428                         WDP_LOGD("Query conversion done");
4429                         break;
4430                 }
4431                 WDP_LOGD("Token: %s", token);
4432                 len = strlen(token);
4433                 sprintf(temp_str, "%02x", len);
4434                 for (i = 0; i < len; i++)
4435                         sprintf(temp_str + i * 2 + 2, "%02x", token[i]);
4436
4437                 strncat(hex_key, temp_str, 2+2*len);
4438                 WDP_LOGD("Converting: %s", hex_key);
4439                 memset(temp_str, 0x0, 256);
4440
4441                 token = strtok_r(NULL, ".", &temp);
4442         }
4443
4444         if (token && strstr(token, "_tcp")) {
4445                 token = strtok_r(NULL, ".", &temp);
4446                 if (token && strstr(token, "local")) {
4447                         strncat(hex_key, "c00c", 4);
4448                         strncat(hex_key, "000c", 4);
4449                         strncat(hex_key, "01", 2);
4450                         goto next;
4451                 }
4452         } else if (token && strstr(token, "_udp")) {
4453                 token = strtok_r(NULL, ".", &temp);
4454                 if (token && strstr(token, "local")) {
4455                         strncat(hex_key, "c01c", 4);
4456                         strncat(hex_key, "000c", 4);
4457                         strncat(hex_key, "01", 2);
4458                         goto next;
4459                 }
4460         } else if (token && strstr(token, "local")) {
4461                 strncat(hex_key, "c011", 4);
4462                 strncat(hex_key, "000c", 4);
4463                 strncat(hex_key, "01", 2);
4464                 goto next;
4465         }
4466
4467         strncat(hex_key, "c00c", 4);
4468         strncat(hex_key, "0010", 4);
4469         strncat(hex_key, "01", 2);
4470
4471 next:
4472         g_free(str_query);
4473
4474         tot_len = strlen(hex_key);
4475         result_str = (char*) calloc(1, tot_len+1);
4476         if (!result_str) {
4477                 WDP_LOGE("Failed to allocate memory for result string");
4478                 return -1;
4479         }
4480         sprintf(result_str, "%s", hex_key);
4481
4482         *hex = result_str;
4483
4484         return 0;
4485 }
4486
4487
4488 int _convert_bonjour_to_hex(char *query, char *rdata,
4489                                                 wfd_oem_bonjour_rdata_type_e rdata_type, char **hex)
4490 {
4491         char *hex_key = NULL;
4492         char hex_value[256] = {0, };
4493         char *token = NULL;
4494         char *temp = NULL;
4495         int len = 0;
4496         int tot_len = 0;
4497         int i = 0;
4498         char temp_str[256] = {0, };
4499         char *result_str = NULL;
4500         char *str_rdata = NULL;
4501
4502         if (!query || !hex) {
4503                 WDP_LOGE("Invalid parameter");
4504                 return -1;
4505         }
4506
4507         if (_convert_bonjour_query_to_hex(query, &hex_key) < 0 || !hex_key) {
4508                 WDP_LOGE("_convert_bonjour_query_to_hex failed");
4509                 return -1;
4510         }
4511
4512         if (!rdata || !strlen(rdata)) {
4513                 WDP_LOGD("RDATA is NULL");
4514                 strncat(hex_value, "00", 2);
4515         } else {
4516                 str_rdata = strdup(rdata);
4517                 if (!str_rdata) {
4518                         WDP_LOGE("Memory allocation failed");
4519                         g_free(hex_key);
4520                         return -1;
4521                 }
4522                 token = strtok_r(str_rdata, ".", &temp);
4523                 while (token) {
4524                         WDP_LOGD("Token: %s", token);
4525                         len = strlen(token);
4526                         sprintf(temp_str, "%02x", len);
4527                         for (i = 0; i < len; i++)
4528                                 sprintf(temp_str + i * 2 + 2, "%02x", token[i]);
4529
4530                         strncat(hex_value, temp_str, 2+2*len);
4531                         WDP_LOGD("Converting: %s", hex_value);
4532                         memset(temp_str, 0x0, 256);
4533
4534                         token = strtok_r(NULL, ".", &temp);
4535                 }
4536                 g_free(str_rdata);
4537         }
4538
4539         if (rdata_type == WFD_OEM_BONJOUR_RDATA_PTR)
4540                 strncat(hex_value, "c027", 4);
4541
4542         tot_len = strlen(hex_key) + strlen(hex_value);
4543         result_str = (char*) g_try_malloc0(tot_len+2);
4544         if (!result_str) {
4545                 WDP_LOGE("Failed to allocate memory for result string");
4546                 g_free(hex_key);
4547                 return -1;
4548         }
4549         g_snprintf(result_str, tot_len+2, "%s %s", hex_key, hex_value);
4550
4551         *hex = result_str;
4552
4553         g_free(hex_key);
4554
4555         return 0;
4556 }
4557
4558 int ws_serv_add(wfd_oem_new_service_s *service)
4559 {
4560         __WDP_LOG_FUNC_ENTER__;
4561         ws_sock_data_s *sock = g_pd->common;
4562         char cmd[256] = {0, };
4563         char reply[1024] = {0,};
4564         int res;
4565
4566         if (!sock) {
4567                 WDP_LOGE("Socket is NULL");
4568                 return -1;
4569         }
4570
4571         switch (service->protocol) {
4572         case WFD_OEM_SERVICE_TYPE_BONJOUR:
4573                 {
4574                         WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
4575                         WDP_LOGD("Query: %s", service->data.bonjour.query);
4576                         WDP_LOGD("RData: %s", service->data.bonjour.rdata);
4577                         char *hex = NULL;
4578
4579                         res = _convert_bonjour_to_hex(service->data.bonjour.query,
4580                                                                     service->data.bonjour.rdata,
4581                                                                     service->data.bonjour.rdata_type,
4582                                                                     &hex);
4583
4584                         if (res < 0) {
4585                                 WDP_LOGE("Failed to convert Key string as hex string");
4586                                 return -1;
4587                         }
4588
4589                         WDP_LOGD("Converted Hexadecimal string [%s]", hex);
4590                         g_snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_ADD " bonjour %s", hex);
4591                         g_free(hex);
4592
4593                 }
4594                 break;
4595         case WFD_OEM_SERVICE_TYPE_UPNP:
4596                 {
4597                         WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_UPNP");
4598
4599                         g_snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_ADD " upnp %s %s",
4600                                         service->data.upnp.version, service->data.upnp.service);
4601                 }
4602                 break;
4603         default:
4604                 WDP_LOGE("This service type is not supported [%d]", service->protocol);
4605                 __WDP_LOG_FUNC_EXIT__;
4606                 return -1;
4607         }
4608
4609         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4610         if (res < 0) {
4611                 WDP_LOGE("Failed to send command to wpa_supplicant");
4612                 __WDP_LOG_FUNC_EXIT__;
4613                 return -1;
4614         }
4615
4616         if (strstr(reply, "FAIL")) {
4617                 WDP_LOGE("Failed to add service");
4618                 __WDP_LOG_FUNC_EXIT__;
4619                 return -1;
4620         }
4621         WDP_LOGD("Succeeded to add service");
4622
4623         __WDP_LOG_FUNC_EXIT__;
4624         return 0;
4625 }
4626
4627 int ws_serv_del(wfd_oem_new_service_s *service)
4628 {
4629         __WDP_LOG_FUNC_ENTER__;
4630         ws_sock_data_s *sock = g_pd->common;
4631         char cmd[256] = {0, };
4632         char reply[1024] = {0,};
4633         int res;
4634
4635         if (!sock) {
4636                 WDP_LOGE("Socket is NULL");
4637                 return -1;
4638         }
4639
4640         switch (service->protocol) {
4641         case WFD_OEM_SERVICE_TYPE_BONJOUR:
4642                 {
4643                         WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR, Data: %s", service);
4644                         char *hex_key = NULL;
4645
4646                         res = _convert_bonjour_query_to_hex(service->data.bonjour.query, &hex_key);
4647                         if (res != 0) {
4648                                 WDP_LOGE("Failed to convert Key string as hex string");
4649                                 return -1;
4650                         }
4651
4652                         WDP_LOGD("Converted Hexadecimal string [%s]", hex_key);
4653                         g_snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_DEL " bonjour %s", hex_key);
4654                         g_free(hex_key);
4655                 }
4656                 break;
4657         case WFD_OEM_SERVICE_TYPE_UPNP:
4658                 {
4659                         WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_UPNP");
4660
4661                         g_snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_DEL " upnp %s %s",
4662                                         service->data.upnp.version, service->data.upnp.service);
4663                 }
4664                 break;
4665         default:
4666                 WDP_LOGE("This service type is not supported");
4667                 __WDP_LOG_FUNC_EXIT__;
4668                 return -1;
4669         }
4670
4671         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4672         if (res < 0) {
4673                 WDP_LOGE("Failed to send command to wpa_supplicant");
4674                 __WDP_LOG_FUNC_EXIT__;
4675                 return -1;
4676         }
4677
4678         if (strstr(reply, "FAIL")) {
4679                 WDP_LOGE("Failed to delete service");
4680                 __WDP_LOG_FUNC_EXIT__;
4681                 return -1;
4682         }
4683         WDP_LOGD("Succeeded to del service");
4684
4685         __WDP_LOG_FUNC_EXIT__;
4686         return 0;
4687 }
4688 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
4689
4690 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
4691 int ws_miracast_init(int enable)
4692 {
4693         __WDP_LOG_FUNC_ENTER__;
4694         ws_sock_data_s *sock = g_pd->common;
4695         char cmd[80] = {0, };
4696         char reply[1024] = {0,};
4697         int res;
4698
4699         unsigned int length = 0x0006;
4700         unsigned int dev_info = 0x0110;
4701         unsigned int ctrl_port = 0x07E6;
4702         unsigned int max_tput = 0x0028;
4703         /* unsigned int bssid = 0x00; */
4704         unsigned int cpled_sink_status = 0x00;
4705         /* param : enable or disable*/
4706
4707         if (!sock) {
4708                 WDP_LOGE("Socket is NULL");
4709                 return -1;
4710         }
4711
4712         g_snprintf(cmd, sizeof(cmd), WS_CMD_SET "wifi_display %d", enable);
4713
4714         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4715         if (res < 0) {
4716                 WDP_LOGE("Failed to send command to wpa_supplicant");
4717                 __WDP_LOG_FUNC_EXIT__;
4718                 return -1;
4719         }
4720
4721         if (strstr(reply, "FAIL")) {
4722                 WDP_LOGE("Failed to initialize miracast");
4723                 __WDP_LOG_FUNC_EXIT__;
4724                 return -1;
4725         }
4726         WDP_LOGD("Succeeded to initialize miracast");
4727
4728         if (enable) {
4729                 /* param : dev_info */
4730                 memset(cmd, 0x0, 80);
4731                 memset(reply, 0x0, WS_REPLY_LEN);
4732
4733                 g_snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x%04x%04x",
4734                                                                 WFD_SUBELM_ID_DEV_INFO, length, dev_info, ctrl_port, max_tput);
4735                 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4736                 if (res < 0) {
4737                         WDP_LOGE("Failed to send command to wpa_supplicant");
4738                         __WDP_LOG_FUNC_EXIT__;
4739                         return -1;
4740                 }
4741
4742                 if (strstr(reply, "FAIL")) {
4743                         WDP_LOGE("Failed to set miracast parameter(device info)");
4744                         __WDP_LOG_FUNC_EXIT__;
4745                         return -1;
4746                 }
4747                 WDP_LOGD("Succeeded to set miracast parameter(device info)");
4748
4749                 /* param : Associated BSSID Subelement */
4750                 memset(cmd, 0x0, 80);
4751                 memset(reply, 0x0, WS_REPLY_LEN);
4752
4753                 snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%s",
4754                                                                 WFD_SUBELM_ID_ASSOC_BSSID, WFD_SUBELM_LEN_ASSOC_BSSID, "000000000000");
4755                 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4756                 if (res < 0) {
4757                         WDP_LOGE("Failed to send command to wpa_supplicant");
4758                         __WDP_LOG_FUNC_EXIT__;
4759                         return -1;
4760                 }
4761
4762                 if (strstr(reply, "FAIL")) {
4763                         WDP_LOGE("Failed to set miracast parameter(BSSID subelement)");
4764                         __WDP_LOG_FUNC_EXIT__;
4765                         return -1;
4766                 }
4767                 WDP_LOGD("Succeeded to set miracast parameter(BSSID subelement)");
4768
4769                 /* param : cpled_sink_status */
4770                 memset(cmd, 0x0, 80);
4771                 memset(reply, 0x0, WS_REPLY_LEN);
4772
4773                 g_snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%02x",
4774                                                                 WFD_SUBELM_ID_CUPLED_SYNC_INFO, 0x01, cpled_sink_status);
4775                 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4776                 if (res < 0) {
4777                         WDP_LOGE("Failed to send command to wpa_supplicant");
4778                         __WDP_LOG_FUNC_EXIT__;
4779                         return -1;
4780                 }
4781
4782                 if (strstr(reply, "FAIL")) {
4783                         WDP_LOGE("Failed to set miracast parameter(Cuppled sink status)");
4784                         __WDP_LOG_FUNC_EXIT__;
4785                         return -1;
4786                 }
4787                 WDP_LOGD("Succeeded to set miracast parameter(Cuppled sink status)");
4788
4789
4790                 /* param : WFD Extended Capability */
4791                 memset(cmd, 0x0, 80);
4792                 memset(reply, 0x0, WS_REPLY_LEN);
4793
4794                 g_snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x",
4795                                                                 WFD_SUBELM_ID_EXT_CAPAB, 0x02, 0x00);
4796                 res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4797                 if (res < 0) {
4798                         WDP_LOGE("Failed to send command to wpa_supplicant");
4799                         __WDP_LOG_FUNC_EXIT__;
4800                         return -1;
4801                 }
4802
4803                 if (strstr(reply, "FAIL")) {
4804                         WDP_LOGE("Failed to set miracast parameter(Extended Capability)");
4805                         __WDP_LOG_FUNC_EXIT__;
4806                         return -1;
4807                 }
4808                 WDP_LOGD("Succeeded to set miracast parameter(Extended Capability)");
4809
4810         }
4811
4812         __WDP_LOG_FUNC_EXIT__;
4813         return 0;
4814 }
4815
4816 int ws_set_display(wfd_oem_display_s *wifi_display)
4817 {
4818         __WDP_LOG_FUNC_ENTER__;
4819         ws_sock_data_s *sock = g_pd->common;
4820         char cmd[80] = {0, };
4821         char reply[1024] = {0,};
4822         int res;
4823         unsigned int device_info = 0;
4824
4825         if (!sock) {
4826                 WDP_LOGE("Socket is NULL");
4827                 return -1;
4828         }
4829
4830         WDP_LOGD("Wi-Fi Display type: [%d]", wifi_display->type);
4831         WDP_LOGD("Wi-Fi Display avai: [%d]", wifi_display->availability);
4832         WDP_LOGD("Wi-Fi Display hdcp: [%d]", wifi_display->hdcp_support);
4833         WDP_LOGD("Wi-Fi Display hdcp: [%d]", wifi_display->port);
4834         WDP_LOGD("Wi-Fi Display sync: [%d]", wifi_display->max_tput);
4835
4836         device_info = wifi_display->type;
4837         device_info += (wifi_display->hdcp_support) << 8;
4838         device_info += (wifi_display->availability) << 4;               /* for availability bit */
4839
4840         g_snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x%04x%04x",
4841                                                         WFD_SUBELM_ID_DEV_INFO, WFD_SUBELEM_LEN_DEV_INFO,
4842                                                         device_info, wifi_display->port, wifi_display->max_tput);
4843
4844         WDP_LOGD("Wi-Fi Display set command: [%s]", cmd);
4845         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
4846         if (res < 0) {
4847                 WDP_LOGE("Failed to send command to wpa_supplicant");
4848                 __WDP_LOG_FUNC_EXIT__;
4849                 return -1;
4850         }
4851
4852         if (strstr(reply, "FAIL")) {
4853                 WDP_LOGE("Failed to set wifi display");
4854                 __WDP_LOG_FUNC_EXIT__;
4855                 return -1;
4856         }
4857         WDP_LOGD("Succeeded to set wifi display");
4858
4859         __WDP_LOG_FUNC_EXIT__;
4860         return 0;
4861 }
4862 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
4863
4864 int ws_refresh()
4865 {
4866         __WDP_LOG_FUNC_ENTER__;
4867
4868         _ws_cancel();
4869         _ws_flush();
4870
4871         __WDP_LOG_FUNC_EXIT__;
4872         return 0;
4873 }
4874
4875 int ws_save_config()
4876 {
4877         __WDP_LOG_FUNC_ENTER__;
4878
4879         __WDP_LOG_FUNC_EXIT__;
4880         return 0;
4881 }
4882
4883 int ws_set_operating_channel(int channel)
4884 {
4885         __WDP_LOG_FUNC_ENTER__;
4886
4887         char cmd[80] = {0, };
4888         char reply[WS_REPLY_LEN] = {0, };
4889         int res = 0;
4890         ws_sock_data_s *sock = g_pd->common;
4891
4892         if (!sock) {
4893                 WDP_LOGE("Socket is NULL");
4894                 return -1;
4895         }
4896
4897         snprintf(cmd, sizeof(cmd), WS_CMD_SET "p2p_oper_channel %d", channel);
4898
4899         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
4900         if (res < 0) {
4901                 WDP_LOGE("Failed to send command to wpa_supplicant");
4902                 __WDP_LOG_FUNC_EXIT__;
4903                 return -1;
4904         }
4905
4906         if (strstr(reply, "FAIL")) {
4907                 WDP_LOGE("Failed to set Operating channel");
4908                 __WDP_LOG_FUNC_EXIT__;
4909                 return -1;
4910         }
4911
4912         WDP_LOGD("Succeeded to set P2P Operating Channel");
4913         __WDP_LOG_FUNC_EXIT__;
4914         return 0;
4915 }
4916
4917 int ws_remove_all_network()
4918 {
4919         __WDP_LOG_FUNC_ENTER__;
4920
4921         __WDP_LOG_FUNC_EXIT__;
4922         return 0;
4923 }
4924
4925 int ws_get_wpa_status(int *wpa_status)
4926 {
4927         __WDP_LOG_FUNC_ENTER__;
4928
4929         __WDP_LOG_FUNC_EXIT__;
4930         return 0;
4931 }
4932
4933 #if defined(TIZEN_FEATURE_ASP)
4934 int ws_advertise_service(wfd_oem_asp_service_s *service, int replace)
4935 {
4936         __WDP_LOG_FUNC_ENTER__;
4937
4938         __WDP_LOG_FUNC_EXIT__;
4939         return -1;
4940 }
4941
4942 int ws_cancel_advertise_service(wfd_oem_asp_service_s *service)
4943 {
4944         __WDP_LOG_FUNC_ENTER__;
4945
4946         __WDP_LOG_FUNC_EXIT__;
4947         return -1;
4948 }
4949
4950 int ws_seek_service(wfd_oem_asp_service_s *service)
4951 {
4952         __WDP_LOG_FUNC_ENTER__;
4953
4954         __WDP_LOG_FUNC_EXIT__;
4955         return -1;
4956 }
4957
4958 int ws_cancel_seek_service(wfd_oem_asp_service_s *service)
4959 {
4960         __WDP_LOG_FUNC_ENTER__;
4961
4962         __WDP_LOG_FUNC_EXIT__;
4963         return -1;
4964 }
4965
4966 int ws_asp_prov_disc_req(wfd_oem_asp_prov_s *asp_params)
4967 {
4968         __WDP_LOG_FUNC_ENTER__;
4969
4970         __WDP_LOG_FUNC_EXIT__;
4971         return -1;
4972 }
4973 #endif /* TIZEN_FEATURE_ASP */