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