Replace file execution method
[platform/core/connectivity/wifi-direct-manager.git] / plugin / wpasupplicant / 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/socket.h>
33 #include <sys/un.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #define _GNU_SOURCE
37 #include <poll.h>
38 #include <errno.h>
39 #include <sys/ioctl.h>
40 #include <net/if.h>
41
42 #include <glib.h>
43
44 #include "wifi-direct-oem.h"
45 #include "wfd-plugin-wpasupplicant.h"
46
47 ws_string_s ws_event_strs[] = {
48         // discovery
49         {"P2P-DEVICE-FOUND", WS_EVENT_DEVICE_FOUND},
50         {"P2P-DEVICE-LOST", WS_EVENT_DEVICE_LOST},
51         {"P2P-FIND-STOPPED", WS_EVENT_FIND_STOPED},
52
53         // provision discovery
54         {"P2P-PROV-DISC-PBC-REQ", WS_EVENT_PROV_DISC_PBC_REQ},
55         {"P2P-PROV-DISC-SHOW-PIN", WS_EVENT_PROV_DISC_SHOW_PIN},
56         {"P2P-PROV-DISC-ENTER-PIN", WS_EVENT_PROV_DISC_ENTER_PIN},
57         {"P2P-PROV-DISC-PBC-RESP", WS_EVENT_PROV_DISC_PBC_RESP},
58         {"P2P-PROV-DISC-FAILURE", WS_EVENT_PROV_DISC_FAILURE},
59
60         // connection
61         {"P2P-GO-NEG-REQUEST", WS_EVENT_GO_NEG_REQUEST},
62         {"P2P-GO-NEG-FAILURE", WS_EVENT_GO_NEG_FAILURE},
63         {"P2P-GO-NEG-SUCCESS", WS_EVENT_GO_NEG_SUCCESS},
64         {"WPS-FAIL", WS_EVENT_WPS_FAIL},
65         {"P2P-GROUP-FORMATION-FAILURE", WS_EVENT_GROUP_FORMATION_FAILURE},
66         {"WPS-SUCCESS", WS_EVENT_WPS_SUCCESS},
67         {"WPS-REG-SUCCESS", WS_EVENT_WPS_REG_SUCCESS},
68         {"P2P-GROUP-FORMATION-SUCCESS", WS_EVENT_GROUP_FORMATION_SUCCESS},
69
70         {"CTRL-EVENT-CONNECTED", WS_EVENT_CONNECTED},
71         {"AP-STA-CONNECTED", WS_EVENT_STA_CONNECTED},
72
73         // invite
74         {"P2P-INVITATION-RECEIVED", WS_EVENT_INVITATION_RECEIVED},
75         {"P2P-INVITATION-RESULT", WS_EVENT_INVITATION_RESULT},
76
77         {"CTRL-EVENT-DISCONNECTED", WS_EVENT_DISCONNECTED},
78         {"AP-STA-DISCONNECTED", WS_EVENT_STA_DISCONNECTED},
79
80         // group
81         {"P2P-GROUP-STARTED", WS_EVENT_GROUP_STARTED},
82         {"P2P-GROUP-REMOVED", WS_EVENT_GROUP_REMOVED},
83
84         {"CTRL-EVENT-TERMINATING", WS_EVENT_TERMINATING},
85         };
86
87 ws_string_s ws_dev_info_strs[] = {
88         {"p2p_dev_addr", WS_DEV_INFO_P2P_DEV_ADDR},
89         {"name", WS_DEV_INFO_DEV_NAME},
90         {"pri_dev_type", WS_DEV_INFO_DEV_TYPE},
91         {"config_methods", WS_DEV_INFO_CONFIG_METHODS},
92         {"dev_capab", WS_DEV_INFO_DEV_CAP},
93         {"group_capab", WS_DEV_INFO_GROUP_CAP},
94         {"p2p_go_addr", WS_DEV_INFO_P2P_GO_ADDR},
95         {"", WS_DEV_INFO_LIMIT},
96         };
97
98 ws_string_s ws_conn_info_strs[] = {
99         {"dev_passwd_id", WS_CONN_INFO_DEV_PWD_ID},
100         {"status", WS_CONN_INFO_STATUS},
101         {"config_error", WS_CONN_INFO_ERROR},
102         {"", WS_CONN_INFO_LIMIT},
103         };
104
105 ws_string_s ws_invite_info_strs[] = {
106         {"sa", WS_INVITE_INFO_SRC_ADDR},
107         {"go_dev_addr", WS_INVITE_INFO_GO_DEV_ADDR},
108         {"bssid", WS_INVITE_INFO_BSSID},
109         {"listen", WS_INVITE_INFO_LISTEN},
110         {"status", WS_INVITE_INFO_STATUS},
111         {"", WS_INVITE_INFO_LIMIT},
112         };
113
114 ws_string_s ws_group_info_strs[] = {
115         {"ssid", WS_GROUP_INFO_SSID},
116         {"freq", WS_GROUP_INFO_FREQ},
117         {"passphrase", WS_GROUP_INFO_PASS},
118         {"go_dev_addr", WS_GROUP_INFO_GO_DEV_ADDR},
119         {"status", WS_GROUP_INFO_STATUS},
120         {"", WS_GROUP_INFO_LIMIT},
121
122         };
123
124 ws_string_s ws_peer_info_strs[] = {
125         {"age", WS_PEER_INFO_AGE},
126         {"listen_freq", WS_PEER_INFO_LISTEN_FREQ},
127         {"level", WS_PEER_INFO_LEVEL},
128         {"wps_method", WS_PEER_INFO_WPS_METHOD},
129         {"interface_addr", WS_PEER_INFO_INTERFACE_ADDR},
130         {"member_in_go_dev", WS_PEER_INFO_MEMBER_IN_GO_DEV},
131         {"member_in_go_iface", WS_PEER_INFO_MEMBER_IN_GO_IFACE},
132         {"pri_dev_type", WS_PEER_INFO_PRI_DEV_TYPE},
133         {"device_name", WS_PEER_INFO_DEVICE_NAME},
134         {"manufacturer", WS_PEER_INFO_MANUFACTURER},
135         {"model_name", WS_PEER_INFO_MODEL_NAME},
136         {"model_number", WS_PEER_INFO_MODEL_NUMBER},
137         {"serial_number", WS_PEER_INFO_SERIAL_NUMBER},
138         {"config_methods", WS_PEER_INFO_CONFIG_METHODS},
139         {"dev_capab", WS_PEER_INFO_DEV_CAPAB},
140         {"group_capab", WS_PEER_INFO_GROUP_CAPAB},
141         {"is_wfd_device", WS_PEER_INFO_IS_WFD_DEVICE},
142         {"go_neg_req_sent", WS_PEER_INFO_GO_NEG_REQ_SENT},
143         {"go_state", WS_PEER_INFO_GO_STATE},
144         {"dialog_token", WS_PEER_INFO_DIALOG_TOKEN},
145         {"intended_addr", WS_PEER_INFO_INTENDED_ADDR},
146         {"country", WS_PEER_INFO_COUNTRY},
147         {"oper_freq", WS_PEER_INFO_OPER_FREQ},
148         {"req_config_methods", WS_PEER_INFO_REQ_CONFIG_METHODS},
149         {"flags", WS_PEER_INFO_FLAGS},
150         {"status", WS_PEER_INFO_STATUS},
151         {"wait_count", WS_PEER_INFO_WAIT_COUNT},
152         {"invitation_reqs", WS_PEER_INFO_INVITATION_REQS},
153         };
154
155 static wfd_oem_ops_s supplicant_ops = {
156         .init = ws_init,
157         .deinit = ws_deinit,
158         .activate = ws_activate,
159         .deactivate = ws_deactivate,
160
161         .start_scan = ws_start_scan,
162         .stop_scan = ws_stop_scan,
163         .get_visibility = ws_get_visibility,
164         .set_visibility = ws_set_visibility,
165         .get_scan_result = ws_get_scan_result,
166         .get_peer_info = ws_get_peer_info,
167
168         .prov_disc_req = ws_prov_disc_req,
169
170         .connect = ws_connect,
171         .disconnect = ws_disconnect,
172         .reject_connection = ws_reject_connection,
173         .cancel_connection = ws_cancel_connection,
174
175         .get_connected_peers = ws_get_connected_peers,
176         .get_pin = ws_get_pin,
177         .set_pin = ws_set_pin,
178         .get_supported_wps_mode = ws_get_supported_wps_mode,
179
180         .create_group = ws_create_group,
181         .destroy_group = ws_destroy_group,
182         .invite = ws_invite,
183         .wps_start = ws_wps_start,
184         .enrollee_start = ws_enrollee_start,
185         .wps_cancel = ws_wps_cancel,
186
187         .get_dev_name = ws_get_dev_name,
188         .set_dev_name = ws_set_dev_name,
189         .get_dev_mac = ws_get_dev_mac,
190         .get_dev_type = ws_get_dev_type,
191         .set_dev_type = ws_set_dev_type,
192         .get_go_intent = ws_get_go_intent,
193         .set_go_intent = ws_set_go_intent,
194         .get_persistent_groups = ws_get_persistent_groups,
195         .remove_persistent_group = ws_remove_persistent_group,
196         .set_persistent_reconnect = ws_set_persistent_reconnect,
197         };
198
199 static ws_plugin_data_s *g_pd;
200
201 static gboolean ws_event_handler(GIOChannel *source,
202                                                            GIOCondition condition,
203                                                            gpointer data);
204
205 int wfd_plugin_load(wfd_oem_ops_s **ops)
206 {
207         if (!ops) {
208                 WDP_LOGE("Invalid parameter");
209                 return -1;
210         }
211
212         *ops = &supplicant_ops;
213
214         return 0;
215 }
216
217 static int _ws_txt_to_devtype(char *txt, int *pri, int *sec)
218 {
219         if (!txt || !pri || !sec) {
220                 WDP_LOGE("Invalid parameter");
221                 return -1;
222         }
223
224         if (strlen(txt) > WS_DEVTYPESTR_LEN) {
225                 WDP_LOGE("Device type string is invalid [%s]", txt);
226                 return -1;
227         }
228
229         *pri = (int) strtoul(txt, &txt, 0);
230         txt = strrchr(txt, '-');
231         *sec = (int) strtoul(txt+1, &txt, 16);
232
233         return 0;
234 }
235
236 static int _ws_txt_to_mac(char *txt, unsigned char *mac)
237 {
238         int i = 0;
239
240         if (!txt || !mac) {
241                 WDP_LOGE("Invalid parameter");
242                 return -1;
243         }
244
245         for (;;) {
246                 mac[i++] = (char) strtoul(txt, &txt, 16);
247                 if (!*txt++ || i == 6)
248                         break;
249         }
250
251         if (i != OEM_MACADDR_LEN)
252                 return -1;
253
254         return 0;
255 }
256
257 static char *_ws_wps_to_txt(int wps_mode)
258 {
259         switch (wps_mode) {
260         case WFD_OEM_WPS_MODE_PBC:
261                 return WS_STR_PBC;
262                 break;
263         case WFD_OEM_WPS_MODE_DISPLAY:
264                 return WS_STR_DISPLAY;
265                 break;
266         case WFD_OEM_WPS_MODE_KEYPAD:
267                 return WS_STR_KEYPAD;
268                 break;
269         default:
270                 return "";
271                 break;
272         }
273 }
274
275 static int _ws_freq_to_channel(int freq)
276 {
277         if (freq < 2412 || freq > 5825) {
278                 WDP_LOGE("Invalid parameter");
279                 return -1;
280         }
281
282         if (freq >= 5180)
283                 return 36 + (freq - 5180)/5;
284         else if (freq <= 2472)
285                 return 1 + (freq - 2412)/5;
286         else if (freq == 2484)
287                 return 14;
288         else
289                 return -1;
290 }
291
292 gboolean _ws_util_execute_file(const char *file_path,
293         char *const args[], char *const envs[])
294 {
295         pid_t pid = 0;
296         int rv = 0;
297         errno = 0;
298         register unsigned int index = 0;
299
300         while (args[index] != NULL) {
301                 WDP_LOGD("[%s]", args[index]);
302                 index++;
303         }
304
305         if (!(pid = fork())) {
306                 WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
307                 WDP_LOGD("Inside child, exec (%s) command", file_path);
308
309                 errno = 0;
310                 if (execve(file_path, args, envs) == -1) {
311                         WDP_LOGE("Fail to execute command (%s)", strerror(errno));
312                         exit(1);
313                 }
314         } else if (pid > 0) {
315                 if (waitpid(pid, &rv, 0) == -1)
316                         WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
317                 if (WIFEXITED(rv)) {
318                         WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
319                 } else if (WIFSIGNALED(rv)) {
320                         WDP_LOGD("killed by signal %d", WTERMSIG(rv));
321                 } else if (WIFSTOPPED(rv)) {
322                         WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
323                 } else if (WIFCONTINUED(rv)) {
324                         WDP_LOGD("continued");
325                 }
326
327                 return TRUE;
328         }
329
330         WDP_LOGE("failed to fork (%s)", strerror(errno));
331         return FALSE;
332 }
333
334 static int _ws_check_socket(int sock)
335 {
336         struct pollfd p_fd;
337         int res = 0;
338
339         p_fd.fd = sock;
340         p_fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL;
341         res = poll((struct pollfd *) &p_fd, 1, 1);
342
343         if (res < 0) {
344                 WDP_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
345                 return -1;
346         } else if (res == 0) {
347                 WDP_LOGD( "poll timeout. socket is busy\n");
348                 return 1;
349         } else {
350
351                 if (p_fd.revents & POLLERR) {
352                         WDP_LOGF("Error! POLLERR from socket[%d]", sock);
353                         return -1;
354                 } else if (p_fd.revents & POLLHUP) {
355                         WDP_LOGF("Error! POLLHUP from socket[%d]", sock);
356                         return -1;
357                 } else if (p_fd.revents & POLLNVAL) {
358                         WDP_LOGF("Error! POLLNVAL from socket[%d]", sock);
359                         return -1;
360                 } else if (p_fd.revents & POLLIN) {
361                         WDP_LOGD("POLLIN from socket [%d]", sock);
362                         return 0;
363                 } else if (p_fd.revents & POLLOUT) {
364                         WDP_LOGD("POLLOUT from socket [%d]", sock);
365                         return 0;
366                 }
367         }
368
369         WDP_LOGD("Unknown poll event [%d]", p_fd.revents);
370         return -1;
371 }
372
373 static int _ws_read_sock(int sock, char *data, int data_len)
374 {
375         __WDP_LOG_FUNC_ENTER__;
376         struct pollfd p_fd;
377         int p_ret = 0;
378         int rbytes = 0;
379
380         if(sock < SOCK_FD_MIN || !data || data_len <= 0) {
381                 WDP_LOGE("Invalid parameter");
382                 return -1;
383         }
384
385         p_fd.fd = sock;
386         p_fd.events = POLLIN | POLLERR | POLLHUP;
387         p_ret = poll(&p_fd, 1, WS_POLL_TIMEOUT);
388
389         errno = 0;
390         if (p_ret > 0) {
391                 if (p_fd.revents & POLLIN) {
392                         WDP_LOGD("POLLIN from socket [%d]", sock);
393                         errno = 0;
394                         rbytes = read(sock, data, data_len);
395                         if (rbytes < 0) {
396                                 WDP_LOGE("Failed to read data from socket[%d]. [%s]", sock, strerror(errno));
397                                 return -1;
398                         }
399                         WDP_LOGD("===== Read Data =====\n%s", data);
400                         data[data_len-1] = '\0';
401                         __WDP_LOG_FUNC_EXIT__;
402                         return rbytes;
403                 } else if (p_fd.revents & POLLERR) {
404                         WDP_LOGE("Error! POLLERR from socket[%d]", sock);
405                         return -1;
406                 } else if (p_fd.revents & POLLHUP) {
407                         WDP_LOGE("Error! POLLHUP from socket[%d]", sock);
408                         return -1;
409                 }
410         } else if (p_ret == 0) {
411                 WDP_LOGE("Polling timeout from socket[%d]", sock);
412         } else {
413                 WDP_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
414         }
415
416         __WDP_LOG_FUNC_EXIT__;
417         return -1;
418 }
419
420 static int _ws_send_cmd(int sock, char *cmd, char *reply, int reply_len)
421 {
422         __WDP_LOG_FUNC_ENTER__;
423         int wbytes = 0;
424         int res = 0;
425
426         if (sock < SOCK_FD_MIN || !cmd || !reply || reply_len < 0) {
427                 WDP_LOGE("Invalid parameter");
428                 return -1;
429         }
430         WDP_LOGI("Sending command [%s]", cmd);
431
432         res = _ws_check_socket(sock);
433         if (res < 0) {
434                 WDP_LOGE("Socket error");
435                 return -1;
436         } else if (res > 0) {
437                 WDP_LOGE("Socket is busy");
438                 return -2;
439         }
440
441         errno = 0;
442         wbytes = write(sock, cmd, strlen(cmd));
443         if (wbytes < 0) {
444                 WDP_LOGE("Failed to write into socket[%d]. [%s]", sock, strerror(errno));
445                 return -1;
446         }
447
448         res = _ws_read_sock(sock, reply, reply_len);
449         if (res < 0) {
450                 WDP_LOGE("Failed to read return for command");
451                 __WDP_LOG_FUNC_EXIT__;
452                 return -1;
453         }
454
455         __WDP_LOG_FUNC_EXIT__;
456         return 0;
457 }
458
459 static int _ws_flush()
460 {
461         __WDP_LOG_FUNC_ENTER__;
462         ws_sock_data_s *sock = g_pd->common;
463         char reply[1024]={0,};
464         int res = 0;
465
466         if (!sock) {
467                 WDP_LOGE("Socket is NULL");
468                 return -1;
469         }
470
471         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_FLUSH, reply, sizeof(reply));
472         if (res < 0) {
473                         WDP_LOGE("Failed to send command to wpa_supplicant");
474                         __WDP_LOG_FUNC_EXIT__;
475                         return -1;
476         }
477
478         if (strstr(reply, "FAIL")) {
479                 WDP_LOGE("Failed to flush");
480                 __WDP_LOG_FUNC_EXIT__;
481                 return -1;
482         }
483         WDP_LOGD("Succeeded to flush");
484
485         __WDP_LOG_FUNC_EXIT__;
486         return 0;
487 }
488
489 static int _ws_cancel()
490 {
491         __WDP_LOG_FUNC_ENTER__;
492         ws_sock_data_s *sock = g_pd->common;
493         char reply[1024]={0,};
494         int res = 0;
495
496         if (!sock) {
497                 WDP_LOGE("Socket is NULL");
498                 return -1;
499         }
500
501         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_CANCEL, reply, sizeof(reply));
502         if (res < 0) {
503                         WDP_LOGE("Failed to send command to wpa_supplicant");
504                         __WDP_LOG_FUNC_EXIT__;
505                         return -1;
506         }
507
508         if (strstr(reply, "FAIL")) {
509                 WDP_LOGE("Failed to cancel");
510                 __WDP_LOG_FUNC_EXIT__;
511                 return -1;
512         }
513         WDP_LOGD("Succeeded to cancel");
514
515         __WDP_LOG_FUNC_EXIT__;
516         return 0;
517 }
518
519 static int _create_ctrl_intf(char *ctrl_intf_path, char *supp_path)
520 {
521         __WDP_LOG_FUNC_ENTER__;
522         struct sockaddr_un srv_addr;
523         struct sockaddr_un local_addr;
524         int sock = 0;
525         int res = 0;
526
527         if(!ctrl_intf_path || !supp_path) {
528                 WDP_LOGE("Invalid parameter");
529                 return -1;
530         }
531         unlink(ctrl_intf_path);
532
533         errno = 0;
534         sock = socket(AF_UNIX, SOCK_DGRAM, 0);
535         if (sock < SOCK_FD_MIN) {
536                 WDP_LOGE("Failed to create socket. [%s]", strerror(errno));
537                 if (sock >= 0)
538                         close(sock);
539                 __WDP_LOG_FUNC_EXIT__;
540                 return -1;
541         }
542         WDP_LOGI( "Succeeded to create socket [%d]\n", sock);
543
544         memset(&srv_addr, 0, sizeof(srv_addr));
545         srv_addr.sun_family = AF_UNIX;
546         snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), supp_path);
547
548         memset(&local_addr, 0, sizeof(local_addr));
549         local_addr.sun_family = AF_UNIX;
550         snprintf(local_addr.sun_path, sizeof(local_addr.sun_path), ctrl_intf_path);
551
552         res = bind(sock, (struct sockaddr*) &local_addr, sizeof(local_addr));
553         if (res < 0)
554         {
555                 WDP_LOGE("Failed to bind local socket [%s]. Try again...", strerror(errno));
556                 unlink(ctrl_intf_path);
557
558                 close(sock);
559                 __WDP_LOG_FUNC_EXIT__;
560                 return -1;
561         }
562
563         errno = 0;
564         res = connect(sock, (struct sockaddr*) &srv_addr, sizeof(srv_addr));
565         if (res < 0) {
566                 WDP_LOGE("Failed to connect to server socket [%s]", strerror(errno));
567                 close(sock);
568                 __WDP_LOG_FUNC_EXIT__;
569                 return -1;
570         }
571         WDP_LOGI("Succeeded to connect to server socket [%d]", sock);
572
573         __WDP_LOG_FUNC_EXIT__;
574         return sock;
575 }
576
577 static int _attach_mon_intf(int sock)
578 {
579         __WDP_LOG_FUNC_ENTER__;
580         char cmd[8] = {0};
581         char reply[8]={0,};
582         int res= 0;
583
584         if (sock < SOCK_FD_MIN) {
585                 WDP_LOGE("Invalid parameter");
586                 return -1;
587         }
588
589         snprintf(cmd, sizeof(cmd), WS_CMD_ATTACH);
590         res = _ws_send_cmd(sock, cmd, reply,  sizeof(reply));
591         if (res < 0) {
592                 WDP_LOGE("Failed to send command to wpa_supplicant");
593                 __WDP_LOG_FUNC_EXIT__;
594                 return -1;
595         }
596
597         if (strstr(reply, "FAIL")) {
598                 WDP_LOGE( "Failed to operate command(wpa_supplicant)");
599                 __WDP_LOG_FUNC_EXIT__;
600                 return -1;
601         }
602
603         __WDP_LOG_FUNC_EXIT__;
604         return 0;
605 }
606
607 static int _connect_to_supplicant(char *ifname, ws_sock_data_s **sock_data)
608 {
609         __WDP_LOG_FUNC_ENTER__;
610         ws_sock_data_s *sock = NULL;
611         int ctrl_sock = -1;
612         int mon_sock = -1;
613         char ctrl_path[32] = {0, };
614         char mon_path[32] = {0, };
615         char suppl_path[40] = {0, };
616         int res = 0;
617         int i = 0;
618
619         if (!ifname || !sock_data) {
620                 WDP_LOGE("Invalie parameter");
621                 __WDP_LOG_FUNC_EXIT__;
622                 return -1;
623         }
624
625         if (sock && sock->ctrl_sock > SOCK_FD_MIN) {
626                 WDP_LOGE("Socket already connected [%d]", sock->ctrl_sock);
627                 return -1;
628         }
629
630         errno = 0;
631         sock = (ws_sock_data_s*) calloc(1, sizeof(ws_sock_data_s));
632         if (!sock) {
633                 WDP_LOGE("Failed to allocate memory for socket data", strerror(errno));
634                 __WDP_LOG_FUNC_EXIT__;
635                 return -1;
636         }
637
638         snprintf(ctrl_path, sizeof(ctrl_path), "/tmp/%s_control", ifname);
639         snprintf(mon_path, sizeof(mon_path), "/tmp/%s_monitor", ifname);
640         snprintf(suppl_path, sizeof(suppl_path), SUPPL_IFACE_PATH "%s", ifname);
641
642         for(i = 0; i < WS_CONN_RETRY_COUNT; i++) {
643                 ctrl_sock = _create_ctrl_intf(ctrl_path, suppl_path);
644                 if (ctrl_sock < SOCK_FD_MIN) {
645                         WDP_LOGE("Failed to create control interface socket for %s", ifname);
646                         continue;
647                 }
648                 WDP_LOGD("Succeeded to create control interface socket[%d] for %s", ctrl_sock, ifname);
649
650                 mon_sock = _create_ctrl_intf(mon_path, suppl_path);
651                 if (mon_sock < SOCK_FD_MIN) {
652                         WDP_LOGE("Failed to create monitor interface socket for %s", ifname);
653                         close(ctrl_sock);
654                         ctrl_sock = -1;
655                         continue;
656                 }
657                 WDP_LOGD("Succeeded to create monitor interface socket[%d] for %s", mon_sock, ifname);
658
659                 res = _attach_mon_intf(mon_sock);
660                 if (res < 0) {
661                         WDP_LOGE("Failed to attach monitor interface for event");
662                         close(ctrl_sock);
663                         ctrl_sock = -1;
664                         close(mon_sock);
665                         mon_sock = -1;
666                         continue;
667                 }
668                 WDP_LOGD("Succeeded to attach monitor interface for event");
669                 break;
670         }
671
672         if (i == WS_CONN_RETRY_COUNT) {
673                 if (ctrl_sock >= 0)
674                         close(ctrl_sock);
675                 if (mon_sock >= 0)
676                         close(mon_sock);
677
678                 free(sock);
679                 __WDP_LOG_FUNC_EXIT__;
680                 return -1;
681         }
682
683         sock->ctrl_sock = ctrl_sock;
684         sock->mon_sock = mon_sock;
685         sock->ifname = strdup(ifname);
686
687         GIOChannel *gio;
688         int gsource = 0;
689         gio = g_io_channel_unix_new(mon_sock);
690         gsource = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP, (GIOFunc) ws_event_handler, sock);
691         g_io_channel_unref(gio);
692
693         sock->gsource = gsource;
694
695         *sock_data = sock;
696         __WDP_LOG_FUNC_EXIT__;
697         return 0;
698 }
699
700 static gboolean _remove_event_source(gpointer data)
701 {
702         __WDP_LOG_FUNC_ENTER__;
703         int source_id = (int) data;
704         int res = 0;
705
706         if (source_id < 0) {
707                 WDP_LOGE("Invalid source ID [%d]", source_id);
708                 return FALSE;
709         }
710
711         res = g_source_remove(source_id);
712         if (!res) {
713                 WDP_LOGE("Failed to remove GSource");
714                 return FALSE;
715         }
716         WDP_LOGD("Succeeded to remove GSource");
717
718         __WDP_LOG_FUNC_EXIT__;
719         return FALSE;
720 }
721
722 static int _disconnect_from_supplicant(char *ifname, ws_sock_data_s *sock_data)
723 {
724         __WDP_LOG_FUNC_ENTER__;
725         int res = 0;
726         char ctrl_path[32] = {0, };
727         char mon_path[32] = {0, };
728         char cmd[8] = {0, };
729         char reply[1024] = {0, };
730
731         if (!ifname || !sock_data) {
732                 WDP_LOGE("Invalie parameter");
733                 return -1;
734         }
735
736         // detach monitor interface
737         snprintf(cmd, sizeof(cmd), WS_CMD_DETACH);
738         res = _ws_send_cmd(sock_data->mon_sock, cmd, reply, sizeof(reply));
739         if (res < 0) {
740                 WDP_LOGE("Failed to send command to wpa_supplicant. Keep going to close socket.");
741         } else {
742                 if (!strncmp(reply, "FAIL", 4)) {
743                         WDP_LOGE( "Failed to detach monitor sock [%d]", sock_data->mon_sock);
744                         // TODO: I think there is no need to exit
745                         __WDP_LOG_FUNC_EXIT__;
746                         return -1;
747                 }
748                 WDP_LOGD("Succeeded to detach monitor sock for %s", ifname ? ifname : "NULL");
749         }
750
751         if (sock_data->gsource > 0)
752                 g_idle_add(_remove_event_source, (gpointer) sock_data->gsource);
753         sock_data->gsource = 0;
754
755         // close control interface
756         snprintf(ctrl_path, sizeof(ctrl_path), "/tmp/%s_control", ifname);
757         snprintf(mon_path, sizeof(mon_path), "/tmp/%s_monitor", ifname);
758
759         if (sock_data->ctrl_sock >= SOCK_FD_MIN)
760                 close(sock_data->ctrl_sock);
761         sock_data->ctrl_sock = -1;
762         unlink(ctrl_path);
763
764         if (sock_data->mon_sock >= SOCK_FD_MIN)
765                 close(sock_data->mon_sock);
766         sock_data->mon_sock = -1;
767         unlink(mon_path);
768
769         if (sock_data->ifname)
770                 free(sock_data->ifname);
771
772         free(sock_data);
773
774         __WDP_LOG_FUNC_EXIT__;
775         return 0;
776 }
777
778 static int _extract_word(const char *data, char **value)
779 {
780         int i = 0;
781
782         if(!data || !value) {
783                 WDP_LOGE("Invalid parameter");
784                 return -1;
785         }
786
787         for(i = 0; data[i]; i++) {
788                 if(data[i] == '\n' || data[i] == '\r' || data[i] == ' ' || data[i] == '\t') {
789                         break;
790                 }
791         }
792
793         if (i > 0) {
794                 *value = (char*) calloc(1, i+1);
795                 strncpy(*value, data, i);
796                 (*value)[i] = '\0';
797         }
798
799         return i;
800 }
801
802 static int _extract_value_str(const char *data, const char *key, char **value)
803 {
804         char *tmp_str = NULL;
805         int i = 0;
806
807         if(!data || !key || !value) {
808                 WDP_LOGE("Invalid parameter");
809                 return -1;
810         }
811
812         tmp_str = strstr(data, key);
813         if(!tmp_str) {
814                 WDP_LOGE("Key[%s] is not found", key);
815                 return -1;
816         }
817         tmp_str = tmp_str + strlen(key) + 1;
818
819         if (tmp_str[0] == '\'' || tmp_str[0] == '\"') {
820                 tmp_str +=1;
821                 for(i = 0; tmp_str[i]; i++) {
822                         if(tmp_str[i] == '\'' || tmp_str[i] == '\"')
823                                 break;
824                 }
825         } else {
826                 for(i = 0; tmp_str[i]; i++) {
827                         if(tmp_str[i] == '\n' || tmp_str[i] == '\r' || tmp_str[i] == ' ')
828                                 break;
829                 }
830         }
831
832         if (i > 0) {
833                 *value = (char*) calloc(1, i+1);
834                 strncpy(*value, tmp_str, i);
835                 (*value)[i] = '\0';
836                 WDP_LOGV("Extracted string: %s", *value);
837                 return i;
838         }
839
840         return 0;
841 }
842
843 static int _extract_peer_value_str(const char *data, const char *key, char **value)
844 {
845         char *tmp_str = NULL;
846         int i = 0;
847
848         if(!data || !key || !value) {
849                 WDP_LOGE("Invalid parameter");
850                 return -1;
851         }
852
853         tmp_str = strstr(data, key);
854         if(!tmp_str) {
855                 WDP_LOGE("Key[%s] is not found", key);
856                 return -1;
857         }
858         tmp_str = tmp_str + strlen(key) + 1;
859
860         for(i = 0; tmp_str[i]; i++) {
861                 if(tmp_str[i] == '\n' || tmp_str[i] == '\r')
862                         break;
863         }
864
865         if (i > 0) {
866                 *value = (char*) calloc(1, i+1);
867                 strncpy(*value, tmp_str, i);
868                 (*value)[i] = '\0';
869                 WDP_LOGV("Extracted string: %s", *value);
870                 return i;
871         }
872
873         return 0;
874 }
875
876 static int _parsing_peer_info(char *msg, wfd_oem_device_s *peer)
877 {
878         __WDP_LOG_FUNC_ENTER__;
879         int i, info_cnt = 0;
880         ws_string_s infos[WS_PEER_INFO_LIMIT];
881         int config_methods = 0x00;
882         int group_capab = 0x00;
883         int res = 0;
884
885         if (!msg || !peer) {
886                 WDP_LOGE("Invalid parameter");
887                 return -1;
888         }
889
890         _ws_txt_to_mac(msg, peer->dev_addr);
891         msg += OEM_MACSTR_LEN;
892
893         memset(infos, 0x0, (WS_PEER_INFO_LIMIT) * sizeof(ws_string_s));
894         for (i = 0; i < WS_PEER_INFO_LIMIT; i++) {
895                 res = _extract_peer_value_str(msg, ws_peer_info_strs[i].string, &infos[info_cnt].string);
896                 if (res > 0) {
897                         infos[info_cnt].index = ws_peer_info_strs[i].index;
898                         info_cnt++;
899                 }
900         }
901
902         for (i = 0; i < info_cnt; i++) {
903                 switch (infos[i].index){
904                 case WS_PEER_INFO_AGE:
905                         peer->age = (int) strtoul(infos[i].string, NULL, 10);
906                         break;
907                 case WS_PEER_INFO_LISTEN_FREQ:
908                         {
909                                 int freq = 0;
910                                 freq = (int) strtoul(infos[i].string, NULL, 10);
911                                 peer->channel = _ws_freq_to_channel(freq);
912                         }
913                         break;
914                 case WS_PEER_INFO_LEVEL:
915                         break;
916                 case WS_PEER_INFO_WPS_METHOD:
917                         break;
918                 case WS_PEER_INFO_INTERFACE_ADDR:
919                         break;
920                 case WS_PEER_INFO_MEMBER_IN_GO_DEV:
921                         {
922                                 res = _ws_txt_to_mac(infos[i].string, peer->go_dev_addr);
923                                 if (res < 0)
924                                         memset(peer->go_dev_addr, 0x00, OEM_MACADDR_LEN);
925
926                                 unsigned char null_mac[OEM_MACADDR_LEN] = {0, 0, 0, 0, 0, 0};
927                                 if (memcmp(peer->go_dev_addr, null_mac, OEM_MACADDR_LEN))
928                                         peer->dev_role = WFD_OEM_DEV_ROLE_GC;
929                         }
930                         break;
931                 case WS_PEER_INFO_MEMBER_IN_GO_IFACE:
932                         break;
933                 case WS_PEER_INFO_PRI_DEV_TYPE:
934                         res = _ws_txt_to_devtype(infos[i].string, &peer->pri_dev_type, &peer->sec_dev_type);
935                         if (res < 0) {
936                                 peer->pri_dev_type = 0;
937                                 peer->sec_dev_type = 0;
938                         }
939                         break;
940                 case WS_PEER_INFO_DEVICE_NAME:
941                         strncpy(peer->dev_name, infos[i].string, OEM_DEV_NAME_LEN);
942                         peer->dev_name[OEM_DEV_NAME_LEN] = '\0';
943                         break;
944                 case WS_PEER_INFO_MANUFACTURER:
945                         break;
946                 case WS_PEER_INFO_MODEL_NAME:
947                         break;
948                 case WS_PEER_INFO_MODEL_NUMBER:
949                         break;
950                 case WS_PEER_INFO_SERIAL_NUMBER:
951                         break;
952                 case WS_PEER_INFO_CONFIG_METHODS:
953                         config_methods = (int) strtoul(infos[i].string, NULL, 16);
954                         if (config_methods & WS_CONFIG_METHOD_DISPLAY)
955                                 peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
956                         if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
957                                 peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
958                         if (config_methods & WS_CONFIG_METHOD_KEYPAD)
959                                 peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
960                         break;
961                 case WS_PEER_INFO_DEV_CAPAB:
962                         peer->dev_flags = (int) strtoul(infos[i].string, NULL, 16);
963                         break;
964                 case WS_PEER_INFO_GROUP_CAPAB:
965                         group_capab = (int) strtoul(infos[i].string, NULL, 16);
966                         if (group_capab & WS_GROUP_CAP_GROUP_OWNER) {
967                                 peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
968                                 peer->dev_role = WFD_OEM_DEV_ROLE_GO;
969                         }
970                         if (group_capab & WS_GROUP_CAP_PERSISTENT_GROUP)
971                                 peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
972                         break;
973                 case WS_PEER_INFO_IS_WFD_DEVICE:
974                         break;
975                 case WS_PEER_INFO_GO_NEG_REQ_SENT:
976                         break;
977                 case WS_PEER_INFO_GO_STATE:
978                         break;
979                 case WS_PEER_INFO_DIALOG_TOKEN:
980                         break;
981                 case WS_PEER_INFO_INTENDED_ADDR:
982                         res = _ws_txt_to_mac(infos[i].string, peer->intf_addr);
983                         if (res < 0)
984                                 memset(peer->intf_addr, 0x00, OEM_MACADDR_LEN);
985                         break;
986                 case WS_PEER_INFO_COUNTRY:
987                         break;
988                 case WS_PEER_INFO_OPER_FREQ:
989                         break;
990                 case WS_PEER_INFO_REQ_CONFIG_METHODS:
991                         break;
992                 case WS_PEER_INFO_FLAGS:
993                         break;
994                 case WS_PEER_INFO_STATUS:
995                         break;
996                 case WS_PEER_INFO_WAIT_COUNT:
997                         break;
998                 case WS_PEER_INFO_INVITATION_REQS:
999                         break;
1000                 default:
1001                         break;
1002                 }
1003         }
1004
1005         for(i = 0; i < info_cnt; i++) {
1006                 if (infos[i].string)
1007                         free(infos[i].string);
1008         }
1009
1010         __WDP_LOG_FUNC_EXIT__;
1011         return 0;
1012 }
1013
1014 static wfd_oem_dev_data_s *_convert_msg_to_dev_info(char *msg)
1015 {
1016         __WDP_LOG_FUNC_ENTER__;
1017         int i;
1018         int info_cnt = 0;
1019         ws_string_s infos[WS_DEV_INFO_LIMIT];
1020         wfd_oem_dev_data_s *edata = NULL;
1021         int config_methods = 0x00;
1022         int group_capab = 0x00;
1023         int res = 0;
1024
1025         if (!msg) {
1026                 WDP_LOGE("Invalid parameter");
1027                 return NULL;
1028         }
1029         WDP_LOGD("msg to be converted [%s]", msg);
1030
1031         memset(infos, 0x0, (WS_DEV_INFO_LIMIT) * sizeof(ws_string_s));
1032         for (i = 0; i < WS_DEV_INFO_LIMIT; i++) {
1033                 res = _extract_value_str(msg, ws_dev_info_strs[i].string, &infos[info_cnt].string);
1034                 if (res > 0) {
1035                         infos[info_cnt].index = ws_dev_info_strs[i].index;
1036                         WDP_LOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
1037                         info_cnt++;
1038                 }
1039         }
1040
1041         if (!info_cnt) {
1042                 WDP_LOGE("There is no item converted");
1043                 return NULL;
1044         }
1045
1046         errno = 0;
1047         edata = (wfd_oem_dev_data_s*) calloc(1, sizeof(wfd_oem_dev_data_s));
1048         if (!edata) {
1049                 WDP_LOGE("Failed to allocate memory for device information [%s]", strerror(errno));
1050                 return NULL;
1051         }
1052
1053         for (i = 0; i < info_cnt; i++) {
1054                 switch (infos[i].index) {
1055                 case WS_DEV_INFO_P2P_DEV_ADDR:
1056                         res = _ws_txt_to_mac(infos[i].string, edata->p2p_dev_addr);
1057                         if (res < 0)
1058                                 memset(edata->p2p_dev_addr, 0x00, OEM_MACADDR_LEN);
1059                         break;
1060                 case WS_DEV_INFO_DEV_NAME:
1061                         strncpy(edata->name, infos[i].string, OEM_DEV_NAME_LEN);
1062                         edata->name[OEM_DEV_NAME_LEN] = '\0';
1063                         break;
1064                 case WS_DEV_INFO_DEV_TYPE:
1065                         res = _ws_txt_to_devtype(infos[i].string, &edata->pri_dev_type, &edata->sec_dev_type);
1066                         if (res < 0) {
1067                                 edata->pri_dev_type = 0;
1068                                 edata->sec_dev_type = 0;
1069                         }
1070                         break;
1071                 case WS_DEV_INFO_CONFIG_METHODS:
1072                         config_methods = (int) strtoul(infos[i].string, NULL, 16);
1073                         if (config_methods & WS_CONFIG_METHOD_DISPLAY)
1074                                 edata->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
1075                         if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
1076                                 edata->config_methods |= WFD_OEM_WPS_MODE_PBC;
1077                         if (config_methods & WS_CONFIG_METHOD_KEYPAD)
1078                                 edata->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
1079                         break;
1080                 case WS_DEV_INFO_DEV_CAP:
1081                         edata->dev_flags = (int) strtoul(infos[i].string, NULL, 16);
1082                         break;
1083                 case WS_DEV_INFO_GROUP_CAP:
1084                         group_capab = (int) strtoul(infos[i].string, NULL, 16);
1085                         if (group_capab & WS_GROUP_CAP_GROUP_OWNER) {
1086                                 edata->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
1087                                 edata->dev_role = WFD_OEM_DEV_ROLE_GO;
1088                         }
1089                         if (group_capab & WS_GROUP_CAP_PERSISTENT_GROUP)
1090                                 edata->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1091                         break;
1092                 case WS_DEV_INFO_P2P_GO_ADDR:
1093                         edata->dev_role = WFD_OEM_DEV_ROLE_GC;
1094                         res = _ws_txt_to_mac(infos[i].string, edata->p2p_go_addr);
1095                         if (res < 0)
1096                                 memset(edata->p2p_go_addr, 0x00, OEM_MACADDR_LEN);
1097                         break;
1098                 default:
1099                         WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1100                         break;
1101                 }
1102                 if (infos[i].string)
1103                         free(infos[i].string);
1104         }
1105
1106         __WDP_LOG_FUNC_EXIT__;
1107         return edata;
1108 }
1109
1110 static wfd_oem_conn_data_s *_convert_msg_to_conn_info(char *msg)
1111 {
1112         __WDP_LOG_FUNC_ENTER__;
1113         int i;
1114         int info_cnt = 0;
1115         ws_string_s infos[WS_CONN_INFO_LIMIT];
1116         wfd_oem_conn_data_s *edata = NULL;
1117         int res = 0;
1118
1119         if (!msg) {
1120                 WDP_LOGE("Invalid parameter");
1121                 return NULL;
1122         }
1123         WDP_LOGD("msg to convert [%s]", msg);
1124
1125         memset(infos, 0x0, (WS_CONN_INFO_LIMIT) * sizeof(ws_string_s));
1126         for (i = 0; i < WS_CONN_INFO_LIMIT; i++) {
1127                 res = _extract_value_str(msg, ws_conn_info_strs[i].string, &infos[info_cnt].string);
1128                 if (res > 0) {
1129                         infos[info_cnt].index = ws_conn_info_strs[i].index;
1130                         info_cnt++;
1131                 }
1132         }
1133
1134         if (!info_cnt) {
1135                 WDP_LOGE("There is no item converted");
1136                 return NULL;
1137         }
1138
1139         errno = 0;
1140         edata = (wfd_oem_conn_data_s*) calloc(1, sizeof(wfd_oem_conn_data_s));
1141         if (!edata) {
1142                 WDP_LOGE("Failed to allocate memory for connection information [%s]", strerror(errno));
1143                 return NULL;
1144         }
1145
1146         for (i = 0; i < info_cnt; i++) {
1147                 switch (infos[i].index) {
1148                 case WS_CONN_INFO_DEV_PWD_ID:
1149                         edata->dev_pwd_id = atoi(infos[i].string);
1150                         break;
1151                 case WS_CONN_INFO_STATUS:
1152                         edata->status = atoi(infos[i].string);
1153                         break;
1154                 case WS_CONN_INFO_ERROR:
1155                         edata->error = atoi(infos[i].string);
1156                         break;
1157                 default:
1158                         WDP_LOGE("Unknown information [%d:%s]", infos[i].index, infos[i].string);
1159                         break;
1160                 }
1161                 if (infos[i].string)
1162                         free(infos[i].string);
1163         }
1164
1165         __WDP_LOG_FUNC_EXIT__;
1166         return edata;
1167 }
1168
1169 static wfd_oem_invite_data_s *_convert_msg_to_invite_info(char *msg)
1170 {
1171         __WDP_LOG_FUNC_ENTER__;
1172         int i;
1173         int info_cnt = 0;
1174         ws_string_s infos[WS_INVITE_INFO_LIMIT];
1175         wfd_oem_invite_data_s *edata = NULL;
1176         int res = 0;
1177
1178         if (!msg) {
1179                 WDP_LOGE("Invalid parameter");
1180                 return NULL;
1181         }
1182         WDP_LOGD("msg to convert [%s]", msg);
1183
1184         memset(infos, 0x0, (WS_INVITE_INFO_LIMIT) * sizeof(ws_string_s));
1185         for (i = 0; i < WS_INVITE_INFO_LIMIT; i++) {
1186                 res = _extract_value_str(msg, ws_invite_info_strs[i].string, &infos[info_cnt].string);
1187                 if (res > 0) {
1188                         infos[info_cnt].index = ws_invite_info_strs[i].index;
1189                         info_cnt++;
1190                 }
1191         }
1192
1193         if (!info_cnt) {
1194                 WDP_LOGE("There is no item converted");
1195                 return NULL;
1196         }
1197
1198         errno = 0;
1199         edata = (wfd_oem_invite_data_s*) calloc(1, sizeof(wfd_oem_invite_data_s));
1200         if (!edata) {
1201                 WDP_LOGE("Failed to allocate memory for invite information [%s]", strerror(errno));
1202                 return NULL;
1203         }
1204
1205         for (i = 0; i < info_cnt; i++) {
1206                 switch (infos[i].index) {
1207                 case WS_INVITE_INFO_GO_DEV_ADDR:
1208                         res = _ws_txt_to_mac(infos[i].string, edata->go_dev_addr);
1209                         if (res < 0)
1210                                 memset(edata->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1211                         break;
1212                 case WS_INVITE_INFO_BSSID:
1213                         res = _ws_txt_to_mac(infos[i].string, edata->bssid);
1214                         if (res < 0)
1215                                 memset(edata->bssid, 0x00, OEM_MACADDR_LEN);
1216                         break;
1217                 case WS_INVITE_INFO_LISTEN:
1218                         edata->listen = atoi(infos[i].string);
1219                         break;
1220                 case WS_INVITE_INFO_STATUS:
1221                         edata->status = atoi(infos[i].string);
1222                         break;
1223                 default:
1224                         WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1225                         break;
1226                 }
1227                 if (infos[i].string)
1228                         free(infos[i].string);
1229         }
1230
1231         __WDP_LOG_FUNC_EXIT__;
1232         return edata;
1233 }
1234
1235 static wfd_oem_group_data_s *_convert_msg_to_group_info(char *msg)
1236 {
1237         __WDP_LOG_FUNC_ENTER__;
1238         int i;
1239         int info_cnt = 0;
1240         ws_string_s infos[WS_GROUP_INFO_LIMIT];
1241         wfd_oem_group_data_s *edata = NULL;
1242         int res = 0;
1243
1244         if (!msg) {
1245                 WDP_LOGE("Invalid parameter");
1246                 return NULL;
1247         }
1248         WDP_LOGD("msg to convert [%s]", msg);
1249
1250         memset(infos, 0x0, WS_GROUP_INFO_LIMIT * sizeof(ws_string_s));
1251         for (i = 0; i < WS_GROUP_INFO_LIMIT; i++) {
1252                 res = _extract_value_str(msg, ws_group_info_strs[i].string, &infos[info_cnt].string);
1253                 if (res > 0) {
1254                         infos[info_cnt].index = ws_group_info_strs[i].index;
1255                         info_cnt++;
1256                 }
1257         }
1258
1259         if (!info_cnt) {
1260                 WDP_LOGE("There is no item converted");
1261                 return NULL;
1262         }
1263
1264         errno = 0;
1265         edata = (wfd_oem_group_data_s*) calloc(1, sizeof(wfd_oem_group_data_s));
1266         if (!edata) {
1267                 WDP_LOGE("Failed to allocate memory for group information [%s]", strerror(errno));
1268                 return NULL;
1269         }
1270
1271         for (i = 0; i < info_cnt; i++) {
1272                 switch (infos[i].index) {
1273                 case WS_GROUP_INFO_SSID:
1274                         strncpy(edata->ssid, infos[i].string, OEM_DEV_NAME_LEN);
1275                         edata->ssid[OEM_DEV_NAME_LEN] = '\0';
1276                         break;
1277                 case WS_GROUP_INFO_FREQ:
1278                         edata->freq = atoi(infos[i].string);
1279                         break;
1280                 case WS_GROUP_INFO_PASS:
1281                         strncpy(edata->pass, infos[i].string, OEM_PASS_PHRASE_LEN);
1282                         edata->pass[OEM_PASS_PHRASE_LEN] = '\0';
1283                         break;
1284                 case WS_GROUP_INFO_GO_DEV_ADDR:
1285                         res = _ws_txt_to_mac(infos[i].string, edata->go_dev_addr);
1286                         if (res < 0)
1287                                 memset(edata->go_dev_addr, 0x00, OEM_MACADDR_LEN);
1288                         break;
1289                 default:
1290                         WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
1291                         break;
1292                 }
1293                 if (infos[i].string)
1294                         free(infos[i].string);
1295         }
1296
1297         __WDP_LOG_FUNC_EXIT__;
1298         return edata;
1299 }
1300
1301 static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
1302 {
1303         __WDP_LOG_FUNC_ENTER__;
1304         int i;
1305         int res = 0;
1306         char *info_str = NULL;
1307
1308         if (!msg || !data) {
1309                 WDP_LOGE("Invalid parameter");
1310                 __WDP_LOG_FUNC_EXIT__;
1311                 return -1;
1312         }
1313         WDP_LOGD("Event message [%s]", msg);
1314
1315         // parsing event string
1316         for(i = 0; i < WS_EVENT_LIMIT; i++) {
1317                 if (!strncmp(ws_event_strs[i].string, msg, strlen(ws_event_strs[i].string))) {
1318                         break;
1319                 }
1320         }
1321         data->event_id = i;
1322         WDP_LOGD("Event ID [%d]", i);
1323
1324         if (i == WS_EVENT_LIMIT) {
1325                 WDP_LOGE("Unknown event [%d]", i);
1326                 return 1;
1327         }
1328
1329         // parsing event info
1330         info_str = msg + strlen(ws_event_strs[i].string) + 1;
1331         if (!strlen(info_str)) {
1332                 WDP_LOGD("Nothing to parse anymore");
1333                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1334                 __WDP_LOG_FUNC_EXIT__;
1335                 return 0;
1336         }
1337
1338         switch (data->event_id) {
1339         case WS_EVENT_DEVICE_FOUND:
1340                 {
1341                         _ws_txt_to_mac(info_str, data->dev_addr);
1342                         info_str += OEM_MACSTR_LEN;
1343
1344                         wfd_oem_dev_data_s *edata = NULL;
1345                         edata = _convert_msg_to_dev_info(info_str);
1346                         if (!edata) {
1347                                 WDP_LOGE("Failed to convert information string to device data");
1348                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1349                                 break;
1350                         }
1351
1352                         if (edata->dev_role == WFD_OEM_DEV_ROLE_GO) {
1353                                 memcpy(edata->p2p_intf_addr, data->dev_addr, OEM_MACADDR_LEN);
1354                                 memcpy(data->dev_addr, edata->p2p_dev_addr, OEM_MACADDR_LEN);
1355                         }
1356                         data->edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
1357                         data->edata = (void*) edata;
1358
1359                 }
1360                 break;
1361         case WS_EVENT_PROV_DISC_PBC_REQ:
1362         case WS_EVENT_PROV_DISC_SHOW_PIN:
1363         case WS_EVENT_PROV_DISC_ENTER_PIN:
1364         case WS_EVENT_PROV_DISC_PBC_RESP:
1365                 {
1366                         _ws_txt_to_mac(info_str, data->dev_addr);
1367                         info_str += OEM_MACSTR_LEN;
1368
1369                         if (data->event_id == WS_EVENT_PROV_DISC_PBC_REQ) {
1370                                 data->wps_mode = WFD_OEM_WPS_MODE_PBC;
1371                         } else if (data->event_id == WS_EVENT_PROV_DISC_ENTER_PIN) {
1372                                 data->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
1373                         } else if (data->event_id == WS_EVENT_PROV_DISC_SHOW_PIN) {
1374                                 data->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
1375                                 strncpy(data->wps_pin, info_str, OEM_PINSTR_LEN);
1376                                 data->wps_pin[OEM_PINSTR_LEN] = '\0';
1377                                 info_str += OEM_PINSTR_LEN +1;
1378                         }
1379
1380                         data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1381
1382                 }
1383                 break;
1384         case WS_EVENT_DEVICE_LOST:
1385                 {
1386                         char *temp_mac = NULL;
1387                         res = _extract_value_str(info_str, "p2p_dev_addr", &temp_mac);
1388                         if (res < 0) {
1389                                 WDP_LOGE("Failed to extract device address");
1390                                 break;
1391                         }
1392                         _ws_txt_to_mac(temp_mac, data->dev_addr);
1393                         if (temp_mac)
1394                                 free(temp_mac);
1395                         data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1396                 }
1397                 break;
1398         case WS_EVENT_FIND_STOPED:
1399                 break;
1400         case WS_EVENT_GO_NEG_REQUEST:
1401                 {
1402                         _ws_txt_to_mac(info_str, data->dev_addr);
1403                         info_str += OEM_MACSTR_LEN;
1404
1405                         if (!strlen(info_str)) {
1406                                 WDP_LOGD("Nothing to parse anymore");
1407                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1408                                 break;
1409                         }
1410
1411                         wfd_oem_conn_data_s *edata = NULL;
1412                         edata = _convert_msg_to_conn_info(info_str);
1413                         if (!edata) {
1414                                 WDP_LOGE("Failed to convert information string to connection data");
1415                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1416                                 break;
1417                         }
1418                         data->edata_type = WFD_OEM_EDATA_TYPE_CONN;
1419                         data->edata = (void*) edata;
1420
1421                 }
1422                 break;
1423         case WS_EVENT_PROV_DISC_FAILURE:
1424         case WS_EVENT_GO_NEG_FAILURE:
1425         case WS_EVENT_WPS_FAIL:         // M_id(msg), error(config_error)
1426                 break;
1427         case WS_EVENT_GROUP_FORMATION_FAILURE:  // No incofmation sring
1428         case WS_EVENT_GO_NEG_SUCCESS:
1429         case WS_EVENT_WPS_SUCCESS:
1430         case WS_EVENT_GROUP_FORMATION_SUCCESS:
1431                 /* No information string */
1432                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1433                 break;
1434         case WS_EVENT_WPS_REG_SUCCESS:  // "intf_addr"
1435                 /* Interface address of peer will come up */
1436                 break;
1437         case WS_EVENT_CONNECTED:        // intf_addr(to)
1438         case WS_EVENT_DISCONNECTED:
1439                 {
1440                         /* Interface address of connected peer will come up */
1441                         char *temp_mac = NULL;
1442                         res = _extract_value_str(info_str, "to", &temp_mac);
1443                         if (res < 0) {
1444                                 WDP_LOGE("Failed to extract interface address");
1445                                 break;
1446                         }
1447                         _ws_txt_to_mac(temp_mac, data->intf_addr);
1448                         if (temp_mac)
1449                                 free(temp_mac);
1450                         data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1451                 }
1452                 break;
1453         case WS_EVENT_STA_CONNECTED:    // "intf_addr", dev_addr(dev_addr)
1454         case WS_EVENT_STA_DISCONNECTED:
1455                 {
1456                         /* Interface address of connected peer will come up */
1457                         _ws_txt_to_mac(info_str, data->intf_addr);
1458
1459                         char *temp_mac = NULL;
1460                         res = _extract_value_str(info_str, "p2p_dev_addr", &temp_mac);
1461                         if (res < 0) {
1462                                 WDP_LOGE("Failed to extract interface address");
1463                                 break;
1464                         }
1465                         _ws_txt_to_mac(temp_mac, data->dev_addr);
1466                         if (temp_mac)
1467                                 free(temp_mac);
1468                         data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1469                 }
1470                 break;
1471         case WS_EVENT_INVITATION_RECEIVED:
1472         case WS_EVENT_INVITATION_RESULT:
1473                 {
1474                         char *peer_addr_str = NULL;
1475                         res = _extract_value_str(info_str, "sa", &peer_addr_str);
1476                         if (res == 17/*(OEM_MACSTR_LEN-1)*/) {
1477                                 _ws_txt_to_mac(peer_addr_str, data->dev_addr);
1478                                 if (peer_addr_str)
1479                                         free(peer_addr_str);
1480                         } else if (res < 0) {
1481                                 WDP_LOGE("Failed to extract source address");
1482                         } else {
1483                                 WDP_LOGE("Wrong source address");
1484                                 free(peer_addr_str);
1485                         }
1486
1487                         if (!strlen(info_str)) {
1488                                 WDP_LOGD("Nothing to parse anymore");
1489                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1490                                 break;
1491                         }
1492
1493                         wfd_oem_invite_data_s* edata = NULL;
1494                         edata = _convert_msg_to_invite_info(info_str);
1495                         if (!edata) {
1496                                 WDP_LOGE("Failed to convert information string to invite data");
1497                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1498                                 break;
1499                         }
1500
1501                         data->edata_type = WFD_OEM_EDATA_TYPE_INVITE;
1502                         data->edata = (void*) edata;
1503
1504                 }
1505                 break;
1506         case WS_EVENT_GROUP_STARTED:
1507         case WS_EVENT_GROUP_REMOVED:
1508                 {
1509                         char *ifname_str = NULL;
1510                         res = _extract_word(info_str, &ifname_str);
1511                         if (res < 0) {
1512                                 WDP_LOGE("Failed to extract event param string");
1513                         } else if (res == 0) {
1514                                 WDP_LOGE("Nothing extracted");
1515                                 if (ifname_str)
1516                                         free(ifname_str);
1517                         } else {
1518                                 if (!ifname_str) {
1519                                         WDP_LOGE("Parsing error(interface name)");
1520                                         return -1;
1521                                 }
1522                                 strncpy(data->ifname, ifname_str, OEM_IFACE_NAME_LEN);
1523                                 data->ifname[OEM_IFACE_NAME_LEN] = '\0';
1524
1525                                 info_str += strlen(ifname_str) + 1;
1526                                 if (ifname_str)
1527                                         free(ifname_str);
1528                         }
1529
1530                         char *dev_role_str = NULL;
1531                         res = _extract_word(info_str, &dev_role_str);
1532                         if (res < 0) {
1533                                 WDP_LOGE("Failed to extract event param string");
1534                         } else if (res == 0) {
1535                                 WDP_LOGE("Nothing extracted");
1536                                 if (dev_role_str)
1537                                         free(dev_role_str);
1538                         } else {
1539                                 if (!dev_role_str) {
1540                                         WDP_LOGE("Parsing error(device role)");
1541                                         return -1;
1542                                 }
1543                                 if (!strncmp(dev_role_str, "GO", 2))
1544                                         data->dev_role = WFD_OEM_DEV_ROLE_GO;
1545                                 else if (!strncmp(dev_role_str, "client", 6))
1546                                         data->dev_role = WFD_OEM_DEV_ROLE_GC;
1547                                 else
1548                                         WDP_LOGE("Unknown device role [%s]", dev_role_str);
1549
1550                                 info_str += strlen(dev_role_str) + 1;
1551                                 if (dev_role_str)
1552                                         free(dev_role_str);
1553                         }
1554
1555                         if (!strlen(info_str)) {
1556                                 WDP_LOGD("Nothing to parse anymore");
1557                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1558                                 break;
1559                         }
1560
1561                         wfd_oem_group_data_s* edata = NULL;
1562                         edata= _convert_msg_to_group_info(info_str);
1563                         if (!edata) {
1564                                 WDP_LOGE("Failed to convert information string to group data");
1565                                 data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
1566                                 break;
1567                         }
1568
1569                         data->edata_type = WFD_OEM_EDATA_TYPE_GROUP;
1570                         data->edata = (void*) edata;
1571
1572                 }
1573                 break;
1574         default:
1575                 WDP_LOGE("Unknown event");
1576                 break;
1577         }
1578
1579         __WDP_LOG_FUNC_EXIT__;
1580         return 0;
1581 }
1582
1583 static gboolean ws_event_handler(GIOChannel *source,
1584                                                                 GIOCondition condition,
1585                                                                 gpointer data)
1586 {
1587         __WDP_LOG_FUNC_ENTER__;
1588         ws_sock_data_s * sd = (ws_sock_data_s*) data;
1589         char msg[1024] = {0, };
1590         char *param;
1591         int event_id = -1;
1592         wfd_oem_event_s *event = NULL;
1593         int res = 0;
1594
1595         if (!sd) {
1596                 WDP_LOGE("Invalid parameter");
1597                 // TODO: if error count is more than 10, disconnect this interface and reset sock data
1598                 return FALSE;
1599         }
1600
1601         res = _ws_read_sock(sd->mon_sock, msg, sizeof(msg));
1602         if (res < 0) {
1603                 WDP_LOGE("Failed to read socket. [%d]", sd->mon_sock);
1604                 return FALSE;
1605         }
1606
1607         errno = 0;
1608         event = (wfd_oem_event_s*) calloc(1, sizeof(wfd_oem_event_s));
1609         if (!event) {
1610                 WDP_LOGE("Failed to allocate memory for event. [%s]", strerror(errno));
1611                 return FALSE;
1612         }
1613
1614         param = &msg[3];
1615         res = _parsing_event_info(sd->ifname, param, event);
1616         if (res < 0) {
1617                 WDP_LOGE("Failed to parse event string");
1618                 free(event);
1619                 return FALSE;
1620         }
1621
1622         if (res == 1) {
1623                 // This means event->event_data is NULL
1624         }
1625
1626         switch (event->event_id) {
1627         case WS_EVENT_DEVICE_FOUND:
1628                 event_id = WFD_OEM_EVENT_PEER_FOUND;
1629                 break;
1630         case WS_EVENT_DEVICE_LOST:
1631                 event_id = WFD_OEM_EVENT_PEER_DISAPPEARED;
1632                 break;
1633         case WS_EVENT_FIND_STOPED:
1634                 event_id = WFD_OEM_EVENT_DISCOVERY_FINISHED;
1635                 break;
1636         case WS_EVENT_PROV_DISC_PBC_REQ:
1637                 event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
1638                 break;
1639         case WS_EVENT_PROV_DISC_PBC_RESP:
1640                 event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
1641                 break;
1642         case WS_EVENT_PROV_DISC_SHOW_PIN:
1643                 event_id = WFD_OEM_EVENT_PROV_DISC_DISPLAY;
1644                 break;
1645         case WS_EVENT_PROV_DISC_ENTER_PIN:
1646                 event_id = WFD_OEM_EVENT_PROV_DISC_KEYPAD;
1647                 break;
1648         case WS_EVENT_GO_NEG_REQUEST:
1649                 event_id = WFD_OEM_EVENT_GO_NEG_REQ;
1650                 break;
1651         case WS_EVENT_GO_NEG_FAILURE:
1652                 event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
1653                 _ws_cancel();
1654                 _ws_flush();
1655                 break;
1656         case WS_EVENT_GO_NEG_SUCCESS:
1657                 event_id = WFD_OEM_EVENT_GO_NEG_DONE;
1658                 break;
1659         case WS_EVENT_WPS_FAIL:
1660         case WS_EVENT_GROUP_FORMATION_FAILURE:
1661                 event_id = WFD_OEM_EVENT_WPS_FAIL;
1662                 break;
1663         case WS_EVENT_WPS_SUCCESS:
1664         case WS_EVENT_WPS_REG_SUCCESS:
1665         case WS_EVENT_GROUP_FORMATION_SUCCESS:
1666                 event_id = WFD_OEM_EVENT_WPS_DONE;
1667                 // TODO: connect to supplicant via group interface
1668                 break;
1669         case WS_EVENT_CONNECTED:
1670                 {
1671                         unsigned char null_mac[OEM_MACADDR_LEN] = {0, 0, 0, 0, 0, 0};
1672                         if (!memcmp(event->intf_addr, null_mac, OEM_MACADDR_LEN))
1673                                 goto done;
1674                         event_id = WFD_OEM_EVENT_CONNECTED;
1675                 }
1676                 break;
1677         case WS_EVENT_STA_CONNECTED:
1678                 event_id = WFD_OEM_EVENT_STA_CONNECTED;
1679                 break;
1680         case WS_EVENT_GROUP_STARTED:
1681                 event_id = WFD_OEM_EVENT_GROUP_CREATED;
1682                 res = _connect_to_supplicant(GROUP_IFACE_NAME, &g_pd->group);
1683                 if (res < 0) {
1684                         WDP_LOGE("Failed to connect to group interface of supplicant");
1685                         goto done;
1686                 }
1687                 break;
1688         case WS_EVENT_GROUP_REMOVED:
1689                 event_id = WFD_OEM_EVENT_GROUP_DESTROYED;
1690                 if (g_pd->group) {
1691                         res = _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
1692                         if (res < 0) {
1693                                 WDP_LOGE("Failed to disconnect from group interface of supplicant");
1694                                 goto done;
1695                         }
1696                         g_pd->group = NULL;
1697                 }
1698                 break;
1699         case WS_EVENT_INVITATION_RECEIVED:
1700                 {
1701                         wfd_oem_invite_data_s* edata = NULL;
1702                         edata = (wfd_oem_invite_data_s*) event->edata;
1703                         event_id = WFD_OEM_EVENT_INVITATION_REQ;
1704                 }
1705                 break;
1706         case WS_EVENT_INVITATION_RESULT:
1707                 event_id = WFD_OEM_EVENT_INVITATION_RES;
1708                 break;
1709         case WS_EVENT_DISCONNECTED:
1710                 event_id = WFD_OEM_EVENT_DISCONNECTED;
1711                 break;
1712         case WS_EVENT_STA_DISCONNECTED:
1713                 event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
1714                 break;
1715         case WS_EVENT_TERMINATING:
1716                 event_id = WFD_OEM_EVENT_TERMINATING;
1717                 break;
1718         default:
1719                 WDP_LOGD("Unknown event [%d]", event->event_id);
1720                 goto done;
1721                 break;
1722         }
1723         event->event_id = event_id;
1724         g_pd->callback(g_pd->user_data, event);
1725
1726 done:
1727         if (event->edata)
1728                 free(event->edata);
1729         free(event);
1730
1731         __WDP_LOG_FUNC_EXIT__;
1732         return TRUE;
1733 }
1734
1735 static int _ws_reset_plugin(ws_plugin_data_s *pd)
1736 {
1737         __WDP_LOG_FUNC_ENTER__;
1738
1739         if (!pd) {
1740                 WDP_LOGE("Invalid parameter");
1741                 __WDP_LOG_FUNC_EXIT__;
1742                 return -1;
1743         }
1744
1745         if (pd->activated)
1746                 ws_deactivate();
1747
1748         free(pd);
1749
1750         __WDP_LOG_FUNC_EXIT__;
1751         return 0;
1752 }
1753
1754 int ws_init(wfd_oem_event_cb callback, void *user_data)
1755 {
1756         __WDP_LOG_FUNC_ENTER__;
1757
1758         if (g_pd)
1759                 _ws_reset_plugin(g_pd);
1760
1761         errno = 0;
1762         g_pd = (ws_plugin_data_s*) calloc(1, sizeof(ws_plugin_data_s));
1763         if (!g_pd) {
1764                 WDP_LOGE("Failed to allocate memory for plugin data. [%s]", strerror(errno));
1765                 return -1;
1766         }
1767
1768         g_pd->callback = callback;
1769         g_pd->user_data = user_data;
1770         g_pd->initialized = TRUE;
1771
1772         __WDP_LOG_FUNC_EXIT__;
1773         return 0;
1774 }
1775
1776 int ws_deinit()
1777 {
1778         __WDP_LOG_FUNC_ENTER__;
1779
1780         if (g_pd) {
1781                 _ws_reset_plugin(g_pd);
1782                 g_pd = NULL;
1783         }
1784
1785         __WDP_LOG_FUNC_EXIT__;
1786         return 0;
1787 }
1788
1789 int ws_activate()
1790 {
1791         __WDP_LOG_FUNC_ENTER__;
1792         int global_sock = -1;
1793         int res = 0;
1794         char cmd[128] = {0, };
1795         char reply[1024] = {0, };
1796
1797         /* load wlan driver and wpa_supplicant */
1798         system("/usr/bin/wlan.sh p2p");
1799         system("/usr/sbin/p2p_supp.sh start");
1800
1801         global_sock = _create_ctrl_intf(GLOBAL_INTF_PATH, SUPPL_GLOBAL_INTF_PATH);
1802         if (global_sock < SOCK_FD_MIN) {
1803                 WDP_LOGE("Failed to create global socket");
1804                 __WDP_LOG_FUNC_EXIT__;
1805                 return -1;
1806         }
1807         WDP_LOGD("Succeeded to create global socket. [%d]", global_sock);
1808
1809         res = _ws_send_cmd(global_sock, WS_CMD_INTERFACES, reply, sizeof(reply));
1810         if (res < 0) {
1811                 WDP_LOGE("Failed to send command to wpa_supplicant");
1812                 __WDP_LOG_FUNC_EXIT__;
1813                 return -1;
1814         }
1815
1816         if (!strstr(reply, COMMON_IFACE_NAME)){
1817                 memset(cmd, 0x0, 128);
1818                 memset(reply, 0x0, 1024);
1819
1820                 snprintf(cmd, sizeof(cmd), WS_CMD_INTERFACE_ADD "%s%s",
1821                                 COMMON_IFACE_NAME, "\t/usr/etc/wifi-direct/p2p_supp.conf\tnl80211\t/var/run/wpa_supplicant");
1822                 res = _ws_send_cmd(global_sock, cmd, reply, sizeof(reply));
1823                 if (res < 0) {
1824                         WDP_LOGE("Failed to send command to wpa_supplicant");
1825                         close(global_sock);
1826                         system("/usr/sbin/p2p_supp.sh stop");
1827                         system("/usr/bin/wlan.sh stop");
1828                         __WDP_LOG_FUNC_EXIT__;
1829                         return -1;
1830                 }
1831
1832                 if (strstr(reply, "FAIL")) {
1833                         WDP_LOGE("Failed to create %s interface", COMMON_IFACE_NAME);
1834                         close(global_sock);
1835                         system("/usr/sbin/p2p_supp.sh stop");
1836                         system("/usr/bin/wlan.sh stop");
1837                         __WDP_LOG_FUNC_EXIT__;
1838                         return -1;
1839                 }
1840                 WDP_LOGD("Succeeded to create %s interface", COMMON_IFACE_NAME);
1841         }
1842         WDP_LOGD("%s interface exist", COMMON_IFACE_NAME);
1843
1844         res = _connect_to_supplicant(COMMON_IFACE_NAME, &g_pd->common);
1845         if (res < 0) {
1846                 close(global_sock);
1847                 system("/usr/sbin/p2p_supp.sh stop");
1848                 system("/usr/bin/wlan.sh stop");
1849                 __WDP_LOG_FUNC_EXIT__;
1850                 return -1;
1851         }
1852
1853         g_pd->global_sock = global_sock;
1854         g_pd->activated = TRUE;
1855
1856         __WDP_LOG_FUNC_EXIT__;
1857         return 0;
1858 }
1859
1860 int ws_deactivate()
1861 {
1862         __WDP_LOG_FUNC_ENTER__;
1863         char cmd[32] = {0, };
1864         char reply[1024]={0,};
1865         int res = 0;
1866         char ifname[OEM_IFACE_NAME_LEN];
1867
1868         if (!g_pd->activated) {
1869                 WDP_LOGE("Wi-Fi Direct is not activated");
1870                 return -1;
1871         }
1872
1873         if (g_pd->group) {
1874                 _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
1875                 g_pd->group = NULL;
1876         }
1877
1878         res = _disconnect_from_supplicant("wlan0", g_pd->common);
1879         if (res < 0)
1880                 WDP_LOGE("Failed to disconnect common interface(%s) from supplicant. ", ifname);
1881         g_pd->common = NULL;
1882
1883         // terminate wpasupplicant
1884         snprintf(cmd, sizeof(cmd), WS_CMD_TERMINATE);
1885         res = _ws_send_cmd(g_pd->global_sock, cmd, reply, sizeof(reply));
1886         if (res < 0) {
1887                 WDP_LOGE("Failed to send command to wpa_supplicant");
1888                 system("/usr/sbin/p2p_supp.sh stop");
1889                 goto done;
1890         }
1891
1892         if (!strncmp(reply, "FAIL", 4)) {
1893                 WDP_LOGE("Failed to terminate wpa_supplicant");
1894                 system("/usr/sbin/p2p_supp.sh stop");
1895         }
1896
1897 done:
1898         unlink(GLOBAL_INTF_PATH);
1899         if (g_pd->global_sock >= SOCK_FD_MIN)
1900                 close(g_pd->global_sock);
1901         g_pd->global_sock = -1;
1902
1903         system("/usr/bin/wlan.sh stop");
1904         g_pd->activated = FALSE;
1905
1906         __WDP_LOG_FUNC_EXIT__;
1907         return 0;
1908 }
1909
1910 int ws_start_scan(wfd_oem_scan_param_s *param)
1911 {
1912         __WDP_LOG_FUNC_ENTER__;
1913         ws_sock_data_s *sock = g_pd->common;
1914         char cmd[32] = {0, };
1915         char reply[1024] = {0, };
1916         char time_str[4] = {0, };
1917         int res = 0;
1918
1919         if (!param) {
1920                 WDP_LOGE("Invalid parameter");
1921                 return -1;
1922         }
1923
1924         if (!sock) {
1925                 WDP_LOGE("Socket is NULL");
1926                 return -1;
1927         }
1928
1929         if (param->refresh)
1930                 _ws_flush();
1931
1932         if (param->scan_time)
1933                 snprintf(time_str, 4, " %d", param->scan_time);
1934
1935         if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE)
1936                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND "%s", (param->scan_time > 0) ? time_str : "");
1937         else
1938                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_LISTEN);
1939
1940         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
1941         if (res < 0) {
1942                 WDP_LOGE("Failed to send command to wpa_supplicant");
1943                 __WDP_LOG_FUNC_EXIT__;
1944                 return -1;
1945         }
1946
1947         if (strstr(reply, "FAIL")) {
1948                 WDP_LOGE("Failed to start scan");
1949                 __WDP_LOG_FUNC_EXIT__;
1950                 return -1;
1951         }
1952         WDP_LOGD("Succeeded to start scan");
1953
1954         __WDP_LOG_FUNC_EXIT__;
1955         return 0;
1956 }
1957
1958 int ws_restart_scan(int freq)
1959 {
1960         __WDP_LOG_FUNC_ENTER__;
1961         ws_sock_data_s *sock = g_pd->common;
1962         char cmd[32] = {0, };
1963         char reply[1024] = {0, };
1964         int res = 0;
1965
1966         if (!sock) {
1967                 WDP_LOGE("Socket is NULL");
1968                 return -1;
1969         }
1970
1971         if (freq)
1972                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND " 2 freq=%d", freq);
1973         else
1974                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND " 2");
1975
1976         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
1977         if (res < 0) {
1978                         WDP_LOGE("Failed to send command to wpa_supplicant");
1979                         __WDP_LOG_FUNC_EXIT__;
1980                         return -1;
1981         }
1982
1983         if (strstr(reply, "FAIL")) {
1984                 WDP_LOGE("Failed to start scan");
1985                 __WDP_LOG_FUNC_EXIT__;
1986                 return -1;
1987         }
1988         WDP_LOGD("Succeeded to start scan");
1989
1990         __WDP_LOG_FUNC_EXIT__;
1991         return 0;
1992 }
1993
1994 int ws_stop_scan()
1995 {
1996         __WDP_LOG_FUNC_ENTER__;
1997         ws_sock_data_s *sock = g_pd->common;
1998         char reply[1024] = {0, };
1999         int res = 0;
2000
2001         if (!sock) {
2002                 WDP_LOGE("Socket is NULL");
2003                 return -1;
2004         }
2005
2006         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_P2P_STOP_FIND, reply, sizeof(reply));
2007         if (res < 0) {
2008                         WDP_LOGE("Failed to send command to wpa_supplicant");
2009                         __WDP_LOG_FUNC_EXIT__;
2010                         return -1;
2011         }
2012
2013         if (strstr(reply, "FAIL")) {
2014                 WDP_LOGE("Failed to stop scan");
2015                 __WDP_LOG_FUNC_EXIT__;
2016                 return -1;
2017         }
2018         WDP_LOGD("Succeeded to stop scan");
2019
2020
2021         __WDP_LOG_FUNC_EXIT__;
2022         return 0;
2023 }
2024
2025 int ws_get_visibility(int *visibility)
2026 {
2027         __WDP_LOG_FUNC_ENTER__;
2028
2029         __WDP_LOG_FUNC_EXIT__;
2030         return 0;
2031 }
2032
2033 int ws_set_visibility(int visibility)
2034 {
2035         __WDP_LOG_FUNC_ENTER__;
2036
2037         __WDP_LOG_FUNC_EXIT__;
2038         return 0;
2039 }
2040
2041 int ws_get_scan_result(GList **peers, int *peer_count)
2042 {
2043         __WDP_LOG_FUNC_ENTER__;
2044         ws_sock_data_s *sock = g_pd->common;
2045         char cmd[32] = {0, };
2046         char reply[1024] = {0,};
2047         wfd_oem_device_s *peer = NULL;
2048         int res = 0;
2049
2050         if (!peers || !peer_count) {
2051                 WDP_LOGE("Invalid parameter");
2052                 return -1;
2053         }
2054
2055         if (!sock) {
2056                 WDP_LOGE("Socket is NULL");
2057                 return -1;
2058         }
2059
2060         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER_FIRST);
2061         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2062         if (res < 0) {
2063                         WDP_LOGE("Failed to send command to wpa_supplicant");
2064                         __WDP_LOG_FUNC_EXIT__;
2065                         return -1;
2066         }
2067
2068         if (strstr(reply, "FAIL")) {
2069                 WDP_LOGE("Failed to get first peer info");
2070                 __WDP_LOG_FUNC_EXIT__;
2071                 return -1;
2072         }
2073         WDP_LOGD("Succeeded to get first peer info");
2074
2075         peer = (wfd_oem_device_s *) calloc(1, sizeof(wfd_oem_device_s));
2076
2077         res = _parsing_peer_info(reply, peer);
2078         if (res < 0) {
2079                         WDP_LOGE("Failed to parsing peer info");
2080                         free(peer);
2081                         __WDP_LOG_FUNC_EXIT__;
2082                         return -1;
2083         }
2084
2085         *peers = g_list_prepend(*peers, peer);
2086
2087         do {
2088                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER_NEXT MACSTR, MAC2STR(peer->dev_addr));
2089                 res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2090                 if (res < 0) {
2091                                 WDP_LOGE("Failed to send command to wpa_supplicant");
2092                                 break;
2093                 }
2094
2095                 if (strstr(reply, "FAIL")) {
2096                         WDP_LOGE("Failed to get first peer info");
2097                         break;
2098                 }
2099                 WDP_LOGD("Succeeded to get first peer info");
2100
2101                 peer = (wfd_oem_device_s *) calloc(1, sizeof(wfd_oem_device_s));
2102
2103                 res = _parsing_peer_info(reply, peer);
2104                 if (res < 0) {
2105                         WDP_LOGE("Failed to parsing peer info");
2106                         free(peer);
2107                         break;
2108                 }
2109
2110                 *peers = g_list_prepend(*peers, peer);
2111         } while(1);
2112
2113         __WDP_LOG_FUNC_EXIT__;
2114         return 0;
2115 }
2116
2117 int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
2118 {
2119         __WDP_LOG_FUNC_ENTER__;
2120         ws_sock_data_s *sock = g_pd->common;
2121         char cmd[32] = {0, };
2122         char reply[1024] = {0,};
2123         wfd_oem_device_s *ws_dev = NULL;
2124         int res = 0;
2125
2126         if (!peer_addr || !peer) {
2127                 WDP_LOGE("Invalid parameter");
2128                 return -1;
2129         }
2130
2131         if (!sock) {
2132                 WDP_LOGE("Socket is NULL");
2133                 return -1;
2134         }
2135
2136         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER MACSTR, MAC2STR(peer_addr));
2137         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2138         if (res < 0) {
2139                         WDP_LOGE("Failed to send command to wpa_supplicant");
2140                         __WDP_LOG_FUNC_EXIT__;
2141                         return -1;
2142         }
2143
2144         if (strstr(reply, "FAIL")) {
2145                 WDP_LOGE("Failed to get peer info [" MACSTR "]", MAC2STR(peer_addr));
2146                 __WDP_LOG_FUNC_EXIT__;
2147                 return -1;
2148         }
2149         WDP_LOGD("Succeeded to get peer info [" MACSTR "]", MAC2STR(peer_addr));
2150
2151         ws_dev = (wfd_oem_device_s*) calloc(1, sizeof(wfd_oem_device_s));
2152
2153         // TODO: parsing peer info
2154         res = _parsing_peer_info(reply, ws_dev);
2155         if (res < 0) {
2156                 WDP_LOGE("Failed to parsing peer info");
2157                 free(ws_dev);
2158                 __WDP_LOG_FUNC_EXIT__;
2159                 return -1;
2160         }
2161
2162         *peer = ws_dev;
2163         __WDP_LOG_FUNC_EXIT__;
2164         return 0;
2165 }
2166
2167 int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
2168 {
2169         __WDP_LOG_FUNC_ENTER__;
2170         ws_sock_data_s *sock = g_pd->common;
2171         char cmd[64] = {0, };
2172         char reply[1024]={0,};
2173         int res;
2174
2175         if (!sock) {
2176                 WDP_LOGE("Socket is NULL");
2177                 return -1;
2178         }
2179
2180
2181         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PROV_DISC MACSTR "%s",
2182                                                         MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
2183
2184         if (join)
2185                 strncat(cmd, WS_STR_JOIN, 5);
2186
2187         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2188         if (res < 0) {
2189                         WDP_LOGE("Failed to send command to wpa_supplicant");
2190                         __WDP_LOG_FUNC_EXIT__;
2191                         return -1;
2192         }
2193
2194         if (strstr(reply, "FAIL")) {
2195                 WDP_LOGE("Failed to send provision discovery to peer[" MACSTR "]", MAC2STR(peer_addr));
2196                 __WDP_LOG_FUNC_EXIT__;
2197                 return -1;
2198         }
2199         WDP_LOGD("Succeeded to send provision discovery to peer[" MACSTR "]", MAC2STR(peer_addr));
2200
2201         __WDP_LOG_FUNC_EXIT__;
2202         return 0;
2203 }
2204
2205 int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
2206 {
2207         __WDP_LOG_FUNC_ENTER__;
2208         ws_sock_data_s *sock = g_pd->common;
2209         char cmd[64] = {0, };
2210         char reply[1024] = {0, };
2211         int res = 0;
2212
2213         if (!peer_addr) {
2214                 WDP_LOGE("Invalid parameter");
2215                 return -1;
2216         }
2217
2218         if (!sock) {
2219                 WDP_LOGE("Socket is NULL");
2220                 return -1;
2221         }
2222
2223         if (param->wps_pin[0] != '\0')
2224                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR " %s%s" ,
2225                                                         MAC2STR(peer_addr), param->wps_pin,
2226                                                         _ws_wps_to_txt(param->wps_mode));
2227         else
2228                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR "%s",
2229                                                         MAC2STR(peer_addr),
2230                                                         _ws_wps_to_txt(param->wps_mode));
2231
2232         if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
2233                 strncat(cmd, WS_STR_JOIN, 5);
2234         else if (param->conn_flags& WFD_OEM_CONN_TYPE_AUTH)
2235                 strncat(cmd, WS_STR_AUTH, 5);
2236
2237         if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
2238                 strncat(cmd, WS_STR_PERSISTENT, 11);
2239
2240         WDP_LOGI("Connection command [%s]", cmd);
2241
2242         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2243         if (res < 0) {
2244                         WDP_LOGE("Failed to send command to wpa_supplicant");
2245                         __WDP_LOG_FUNC_EXIT__;
2246                         return -1;
2247         }
2248
2249         if (strstr(reply, "FAIL")) {
2250                 WDP_LOGE("Failed to connect with peer[" MACSTR "]", MAC2STR(peer_addr));
2251                 __WDP_LOG_FUNC_EXIT__;
2252                 return -1;
2253         }
2254         WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
2255
2256         __WDP_LOG_FUNC_EXIT__;
2257         return 0;
2258 }
2259
2260 int ws_disconnect(unsigned char *peer_addr)
2261 {
2262         __WDP_LOG_FUNC_ENTER__;
2263         ws_sock_data_s *sock = g_pd->common;
2264         char cmd[32] = {0, };
2265         char reply[1024]={0,};
2266         int res;
2267
2268         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_REMOVE "%s", GROUP_IFACE_NAME);
2269         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2270         if (res < 0) {
2271                 WDP_LOGE("Failed to send command to wpa_supplicant");
2272                 __WDP_LOG_FUNC_EXIT__;
2273                 return -1;
2274         }
2275
2276         if (strstr(reply, "FAIL")) {
2277                 WDP_LOGE("Failed to disconnect with peer[" MACSTR "]", MAC2STR(peer_addr));
2278                 __WDP_LOG_FUNC_EXIT__;
2279                 return -1;
2280         }
2281         WDP_LOGD("Succeeded to send disconnection command to peer[" MACSTR "]", MAC2STR(peer_addr));
2282
2283         __WDP_LOG_FUNC_EXIT__;
2284         return 0;
2285 }
2286
2287 int ws_reject_connection(unsigned char *peer_addr)
2288 {
2289         __WDP_LOG_FUNC_ENTER__;
2290         ws_sock_data_s *sock = g_pd->common;
2291         char cmd[40] = {0, };
2292         char reply[1024]={0,};
2293         int res;
2294
2295         if (!sock) {
2296                 WDP_LOGE("Socket is NULL");
2297                 return -1;
2298         }
2299
2300         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_REJECT MACSTR, MAC2STR(peer_addr));
2301         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2302         if (res < 0) {
2303                         WDP_LOGE("Failed to send command to wpa_supplicant");
2304                         __WDP_LOG_FUNC_EXIT__;
2305                         return -1;
2306         }
2307
2308         if (strstr(reply, "FAIL")) {
2309                 WDP_LOGE("Failed to reject connection with peer[" MACSTR "]", MAC2STR(peer_addr));
2310                 __WDP_LOG_FUNC_EXIT__;
2311                 return -1;
2312         }
2313         WDP_LOGD("Succeeded to send reject connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
2314
2315         __WDP_LOG_FUNC_EXIT__;
2316         return 0;
2317 }
2318
2319 int ws_cancel_connection(unsigned char *peer_addr)
2320 {
2321         __WDP_LOG_FUNC_ENTER__;
2322
2323         _ws_cancel();
2324
2325         __WDP_LOG_FUNC_EXIT__;
2326         return 0;
2327 }
2328
2329 int ws_get_connected_peers(GList **peers, int *peer_count)
2330 {
2331         __WDP_LOG_FUNC_ENTER__;
2332
2333         __WDP_LOG_FUNC_EXIT__;
2334         return 0;
2335 }
2336
2337 int ws_get_pin(char *pin)
2338 {
2339         __WDP_LOG_FUNC_ENTER__;
2340
2341         __WDP_LOG_FUNC_EXIT__;
2342         return 0;
2343 }
2344
2345 int ws_set_pin(char *pin)
2346 {
2347         __WDP_LOG_FUNC_ENTER__;
2348
2349         __WDP_LOG_FUNC_EXIT__;
2350         return 0;
2351 }
2352
2353 int ws_get_supported_wps_mode()
2354 {
2355         __WDP_LOG_FUNC_ENTER__;
2356
2357         __WDP_LOG_FUNC_EXIT__;
2358         return 0;
2359 }
2360
2361 int ws_create_group(int persistent, int freq)
2362 {
2363         __WDP_LOG_FUNC_ENTER__;
2364         ws_sock_data_s *sock = g_pd->common;
2365         char cmd[44] = {0, };
2366         char reply[1024]={0,};
2367         int res = 0;
2368
2369         if (!sock) {
2370                 WDP_LOGE("Socket is NULL");
2371                 return -1;
2372         }
2373
2374         if (persistent)
2375                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD WS_STR_PERSISTENT);
2376         else
2377                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD WS_STR_FREQ_2G);
2378
2379         // TODO: add frequency option
2380
2381         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2382         if (res < 0) {
2383                         WDP_LOGE("Failed to send command to wpa_supplicant");
2384                         __WDP_LOG_FUNC_EXIT__;
2385                         return -1;
2386         }
2387
2388         if (strstr(reply, "FAIL")) {
2389                 WDP_LOGE("Failed to add group");
2390                 __WDP_LOG_FUNC_EXIT__;
2391                 return -1;
2392         }
2393         WDP_LOGD("Succeeded to add group");
2394
2395         __WDP_LOG_FUNC_EXIT__;
2396         return 0;
2397 }
2398
2399 int ws_destroy_group(const char *ifname)
2400 {
2401         __WDP_LOG_FUNC_ENTER__;
2402         ws_sock_data_s *sock = g_pd->common;
2403         char cmd[32] = {0, };
2404         char reply[1024]={0,};
2405         int res = 0;
2406
2407         if (!ifname) {
2408                 WDP_LOGE("Invalid parameter");
2409                 return -1;
2410         }
2411
2412         if (!sock) {
2413                 WDP_LOGE("Socket is NULL");
2414                 return -1;
2415         }
2416
2417         snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_REMOVE "%s", ifname);
2418
2419         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2420         if (res < 0) {
2421                         WDP_LOGE("Failed to send command to wpa_supplicant");
2422                         __WDP_LOG_FUNC_EXIT__;
2423                         return -1;
2424         }
2425
2426         if (strstr(reply, "FAIL")) {
2427                 WDP_LOGE("Failed to remove group");
2428                 __WDP_LOG_FUNC_EXIT__;
2429                 return -1;
2430         }
2431         WDP_LOGD("Succeeded to remove group");
2432
2433         _ws_flush();
2434
2435         __WDP_LOG_FUNC_EXIT__;
2436         return 0;
2437 }
2438
2439 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
2440 {
2441         __WDP_LOG_FUNC_ENTER__;
2442         ws_sock_data_s *sock = g_pd->group;
2443         char cmd[128] = {0, };
2444         char reply[1024]={0,};
2445         int res = 0;
2446
2447         if (!peer_addr || !param) {
2448                 WDP_LOGE("Invalid parameter");
2449                 return -1;
2450         }
2451
2452         if (!sock) {
2453                 WDP_LOGE("Group interface not connected");
2454                 return -1;
2455         }
2456
2457         WDP_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]", MAC2STR(peer_addr), MAC2STR(param->go_dev_addr));
2458
2459         if (param->net_id)
2460                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_INVITE "persistent=%d peer=" MACSTR " go_dev_addr=" MACSTR,
2461                                                                 param->net_id, MAC2STR(peer_addr),
2462                                                                 MAC2STR(param->go_dev_addr));
2463         else
2464                 snprintf(cmd, sizeof(cmd), WS_CMD_P2P_INVITE "group=%s peer=" MACSTR " go_dev_addr=" MACSTR,
2465                                                                 param->ifname, MAC2STR(peer_addr),
2466                                                                 MAC2STR(param->go_dev_addr));
2467
2468         res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
2469         if (res < 0) {
2470                         WDP_LOGE("Failed to send command to wpa_supplicant");
2471                         __WDP_LOG_FUNC_EXIT__;
2472                         return -1;
2473         }
2474
2475         if (strstr(reply, "FAIL")) {
2476                 WDP_LOGE("Failed to invite peer");
2477                 __WDP_LOG_FUNC_EXIT__;
2478                 return -1;
2479         }
2480         WDP_LOGD("Succeeded to invite peer");
2481
2482         __WDP_LOG_FUNC_EXIT__;
2483         return 0;
2484 }
2485
2486 // Only group owner can use this command
2487 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
2488 {
2489         __WDP_LOG_FUNC_ENTER__;
2490         ws_sock_data_s *sock = g_pd->group;
2491         char cmd[40] = {0, };
2492         char reply[1024]={0,};
2493         int res;
2494
2495         if (!peer_addr || !pin) {
2496                 WDP_LOGE("Invalid parameter");
2497                 return -1;
2498         }
2499
2500         if (!sock) {
2501                 WDP_LOGE("Group interface not connected");
2502                 return -1;
2503         }
2504
2505         if (wps_mode == WFD_OEM_WPS_MODE_PBC)
2506                 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_PBC "p2p_dev_addr=" MACSTR, MAC2STR(peer_addr));
2507         else
2508                 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_PIN MACSTR " %s", MAC2STR(peer_addr), pin);
2509
2510         res = _ws_send_cmd(sock->ctrl_sock, cmd,reply, sizeof(reply));
2511         if (res < 0) {
2512                         WDP_LOGE("Failed to send command to wpa_supplicant");
2513                         __WDP_LOG_FUNC_EXIT__;
2514                         return -1;
2515         }
2516
2517         if (strstr(reply, "FAIL")) {
2518                 WDP_LOGE("Failed to start WPS");
2519                 __WDP_LOG_FUNC_EXIT__;
2520                 return -1;
2521         }
2522         WDP_LOGD("Succeeded to start WPS");
2523
2524         __WDP_LOG_FUNC_EXIT__;
2525         return 0;
2526 }
2527
2528 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
2529 {
2530         __WDP_LOG_FUNC_ENTER__;
2531         ws_sock_data_s *sock = g_pd->common;
2532         char cmd[64] = {0, };
2533         char reply[1024]={0,};
2534         int res;
2535
2536         if (!peer_addr || !pin) {
2537                 WDP_LOGE("Invalid parameter");
2538                 return -1;
2539         }
2540
2541         if (!sock) {
2542                 WDP_LOGE("Socket is NULL");
2543                 return -1;
2544         }
2545
2546         if (wps_mode == WFD_OEM_WPS_MODE_PBC)
2547                 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_ENROLLEE MACSTR "%s",
2548                                         MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
2549         else
2550                 snprintf(cmd, sizeof(cmd), WS_CMD_WPS_ENROLLEE MACSTR " %s%s",
2551                                         MAC2STR(peer_addr), pin, _ws_wps_to_txt(wps_mode));
2552
2553         res = _ws_send_cmd(sock->ctrl_sock, cmd,reply, sizeof(reply));
2554         if (res < 0) {
2555                         WDP_LOGE("Failed to send command to wpa_supplicant");
2556                         __WDP_LOG_FUNC_EXIT__;
2557                         return -1;
2558         }
2559
2560         if (strstr(reply, "FAIL")) {
2561                 WDP_LOGE("Failed to start WPS");
2562                 __WDP_LOG_FUNC_EXIT__;
2563                 return -1;
2564         }
2565         WDP_LOGD("Succeeded to start WPS");
2566
2567         __WDP_LOG_FUNC_EXIT__;
2568         return 0;
2569 }
2570
2571 int ws_wps_cancel()
2572 {
2573         __WDP_LOG_FUNC_ENTER__;
2574         ws_sock_data_s *sock = g_pd->common;
2575         char reply[1024]={0,};
2576         int res;
2577
2578         if (!sock) {
2579                 WDP_LOGE("Socket is NULL");
2580                 return -1;
2581         }
2582
2583         res = _ws_send_cmd(sock->ctrl_sock, WS_CMD_WPS_CANCEL, reply, sizeof(reply));
2584         if (res < 0) {
2585                         WDP_LOGE("Failed to send command to wpa_supplicant");
2586                         __WDP_LOG_FUNC_EXIT__;
2587                         return -1;
2588         }
2589
2590         if (strstr(reply, "FAIL")) {
2591                 WDP_LOGE("Failed to cancel WPS");
2592                 __WDP_LOG_FUNC_EXIT__;
2593                 return -1;
2594         }
2595         WDP_LOGD("Succeeded to cancel WPS");
2596
2597         __WDP_LOG_FUNC_EXIT__;
2598         return 0;
2599 }
2600
2601 int ws_get_dev_name(char *dev_name)
2602 {
2603         __WDP_LOG_FUNC_ENTER__;
2604
2605         __WDP_LOG_FUNC_EXIT__;
2606         return 0;
2607 }
2608
2609 int ws_set_dev_name(char *dev_name)
2610 {
2611         __WDP_LOG_FUNC_ENTER__;
2612         ws_sock_data_s *sock = g_pd->common;
2613         char cmd[128] = {0, };
2614         char reply[1024]={0,};
2615         int res;
2616
2617         if (!dev_name || !strlen(dev_name)) {
2618                 WDP_LOGE( "Invalid parameter");
2619                 __WDP_LOG_FUNC_EXIT__;
2620                 return 1;
2621         }
2622
2623         if (!sock) {
2624                 WDP_LOGE("Socket is NULL");
2625                 return -1;
2626         }
2627
2628         snprintf(cmd, sizeof(cmd), WS_CMD_SET "device_name %s", dev_name);
2629         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2630         if (res < 0) {
2631                 WDP_LOGE("Failed to send command to wpa_supplicant");
2632                 __WDP_LOG_FUNC_EXIT__;
2633                 return -1;
2634         }
2635
2636         if (strstr(reply, "FAIL")) {
2637                 WDP_LOGE("Failed to set device name");
2638                 __WDP_LOG_FUNC_EXIT__;
2639                 return -1;
2640         }
2641         WDP_LOGD("Succeeded to set device name");
2642
2643         memset(cmd, 0x0, 128);
2644         memset(reply, 0x0, 1024);
2645
2646         snprintf(cmd, sizeof(cmd), WS_CMD_SET "p2p_ssid_postfix %s", dev_name);
2647         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2648         if (res < 0) {
2649                         WDP_LOGE("Failed to send command to wpa_supplicant");
2650                         __WDP_LOG_FUNC_EXIT__;
2651                         return -1;
2652         }
2653
2654         if (strstr(reply, "FAIL")) {
2655                 WDP_LOGE("Failed to set SSID postfix");
2656                 __WDP_LOG_FUNC_EXIT__;
2657                 return -1;
2658         }
2659         WDP_LOGD("Succeeded to set SSID postfix");
2660
2661         __WDP_LOG_FUNC_EXIT__;
2662         return 0;
2663 }
2664
2665 int ws_get_dev_mac(char *dev_mac)
2666 {
2667         __WDP_LOG_FUNC_ENTER__;
2668
2669         __WDP_LOG_FUNC_EXIT__;
2670         return 0;
2671 }
2672
2673 int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
2674 {
2675         __WDP_LOG_FUNC_ENTER__;
2676
2677         __WDP_LOG_FUNC_EXIT__;
2678         return 0;
2679 }
2680
2681 int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
2682 {
2683         __WDP_LOG_FUNC_ENTER__;
2684
2685         __WDP_LOG_FUNC_EXIT__;
2686         return 0;
2687 }
2688
2689 int ws_get_go_intent(int *go_intent)
2690 {
2691         __WDP_LOG_FUNC_ENTER__;
2692         ws_sock_data_s *sock = g_pd->common;
2693         char cmd[80] = {0, };
2694         char reply[1024]={0,};
2695         int res;
2696
2697         if (!sock) {
2698                 WDP_LOGE("Socket is NULL");
2699                 return -1;
2700         }
2701
2702         if (go_intent == NULL)
2703         {
2704                 WDP_LOGE("p2p_go_intent is NULL");
2705                 __WDP_LOG_FUNC_EXIT__;
2706                 return -1;
2707         }
2708
2709         snprintf(cmd, sizeof(cmd), WS_CMD_GET "p2p_go_intent");
2710         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2711         if (res < 0) {
2712                 WDP_LOGE("Failed to send command to wpa_supplicant");
2713                 __WDP_LOG_FUNC_EXIT__;
2714                 return -1;
2715         }
2716
2717         if (strstr(reply, "FAIL")) {
2718                 WDP_LOGE("Failed to set go intent");
2719                 __WDP_LOG_FUNC_EXIT__;
2720                 return -1;
2721         }
2722
2723         *go_intent = atoi(reply);
2724         WDP_LOGD("Succeeded to get go intent(%d)", *go_intent);
2725
2726         __WDP_LOG_FUNC_EXIT__;
2727         return 0;
2728 }
2729
2730 int ws_set_go_intent(int go_intent)
2731 {
2732         __WDP_LOG_FUNC_ENTER__;
2733         ws_sock_data_s *sock = g_pd->common;
2734         char cmd[80] = {0, };
2735         char reply[1024]={0,};
2736         int res;
2737
2738         if (!sock) {
2739                 WDP_LOGE("Socket is NULL");
2740                 return -1;
2741         }
2742
2743         snprintf(cmd, sizeof(cmd), WS_CMD_SET "p2p_go_intent %d", go_intent);
2744
2745         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2746         if (res < 0) {
2747                 WDP_LOGE("Failed to send command to wpa_supplicant");
2748                 __WDP_LOG_FUNC_EXIT__;
2749                 return -1;
2750         }
2751
2752         if (strstr(reply, "FAIL")) {
2753                 WDP_LOGE("Failed to set go intent");
2754                 __WDP_LOG_FUNC_EXIT__;
2755                 return -1;
2756         }
2757         WDP_LOGD("Succeeded to set go intent(%d)", go_intent);
2758
2759         __WDP_LOG_FUNC_EXIT__;
2760         return 0;
2761 }
2762
2763 int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
2764 {
2765         __WDP_LOG_FUNC_ENTER__;
2766         char *ptr = buf;
2767         int count = 0;
2768         char *tmp_str = NULL;
2769         int res = 0;
2770
2771         // Passing first line : "network id / ssid / bssid / flags"
2772         while (*ptr != '\n') {
2773                 ptr++;
2774         }
2775         ptr++;
2776
2777         count = 0;
2778         while(*ptr != '\0') {
2779                 res = _extract_word(ptr, &tmp_str);
2780                 if (res > 0) {
2781                         networks[count].network_id = atoi(tmp_str);
2782                         free(tmp_str);
2783                         tmp_str = NULL;
2784                         ptr += res;
2785                 }
2786                 ptr++;
2787
2788                 res = _extract_word(ptr, &tmp_str);
2789                 if (res > 0) {
2790                         snprintf(networks[count].ssid, WS_SSID_LEN, tmp_str);
2791                         free(tmp_str);
2792                         tmp_str = NULL;
2793                         ptr += res;
2794                 }
2795                 ptr++;
2796
2797                 res = _extract_word(ptr, &tmp_str);
2798                 if (res > 0) {
2799                         _ws_txt_to_mac(tmp_str, networks[count].bssid);
2800                         free(tmp_str);
2801                         tmp_str = NULL;
2802                         ptr += res;
2803                 }
2804                 ptr++;
2805
2806                 res = _extract_word(ptr, &tmp_str);
2807                 if (res > 0) {
2808                         if (strstr(tmp_str, "CURRENT"))
2809                                 networks[count].flags |= WFD_OEM_NETFLAG_CURRENT;
2810                         if (strstr(tmp_str, "DISABLED"))
2811                                 networks[count].flags |= WFD_OEM_NETFLAG_DISABLED;
2812                         if (strstr(tmp_str, "TEMP-DISABLED"))
2813                                 networks[count].flags |= WFD_OEM_NETFLAG_TEMP_DISABLED;
2814                         if (strstr(tmp_str, "P2P-PERSISTENT"))
2815                                 networks[count].flags |= WFD_OEM_NETFLAG_P2P_PERSISTENT;
2816                         free(tmp_str);
2817                         tmp_str = NULL;
2818                         ptr += res;
2819                 }
2820                 ptr++;
2821
2822                 count++;
2823         }
2824
2825         *network_cnt = count;
2826
2827         __WDP_LOG_FUNC_EXIT__;
2828         return 0;
2829 }
2830
2831 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
2832 {
2833         __WDP_LOG_FUNC_ENTER__;
2834         ws_sock_data_s *sock = g_pd->common;
2835         char cmd[80] = {0, };
2836         char reply[1024]={0,};
2837         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
2838         wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
2839         int res;
2840         int i, cnt;
2841
2842         if (!groups || !group_count) {
2843                 WDP_LOGE("Invalid parameter");
2844                 return -1;
2845         }
2846
2847         if (!sock) {
2848                 WDP_LOGE("Socket is NULL");
2849                 return -1;
2850         }
2851
2852         memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
2853
2854         /* Reading lists the configured networks, including stored information for persistent groups.
2855         The identifier in this is used with p2p_group_add and p2p_invite to indicate witch persistent
2856         group is to be reinvoked. */
2857         snprintf(cmd, sizeof(cmd), WS_CMD_LIST_NETWORKS);
2858         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2859         if (res < 0) {
2860                 WDP_LOGE("Failed to send command to wpa_supplicant");
2861                 __WDP_LOG_FUNC_EXIT__;
2862                 return -1;
2863         }
2864
2865         if (strstr(reply, "FAIL")) {
2866                 WDP_LOGE("Failed to get list of networks");
2867                 __WDP_LOG_FUNC_EXIT__;
2868                 return -1;
2869         }
2870         WDP_LOGD("Succeeded to get list of networks");
2871
2872         _parsing_networks(reply, networks, &cnt);
2873         WDP_LOGD("Persistent Group Count=%d", cnt);
2874         if (cnt > WS_MAX_PERSISTENT_COUNT) {
2875                 WDP_LOGE("Persistent group count exceeded or parsing error");
2876                 __WDP_LOG_FUNC_EXIT__;
2877                 return -1;
2878         }
2879
2880         wfd_persistent_groups = (wfd_oem_persistent_group_s*) calloc(1, cnt * sizeof(wfd_oem_persistent_group_s));
2881         for(i = 0; i < cnt; i++) {
2882                 WDP_LOGD("----persistent group [%d]----", i);
2883                 WDP_LOGD("network_id=%d", networks[i].network_id);
2884                 WDP_LOGD("ssid=%s", networks[i].ssid);
2885                 WDP_LOGD("bssid=" MACSTR, MAC2STR(networks[i].bssid));
2886                 WDP_LOGD("flags=%x", networks[i].flags);
2887
2888                 wfd_persistent_groups[i].network_id = networks[i].network_id;
2889                 strncpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN);
2890                 wfd_persistent_groups[i].ssid[WS_SSID_LEN] = '\0';
2891                 memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
2892         }
2893
2894         *group_count = cnt;
2895         *groups = wfd_persistent_groups;
2896
2897         __WDP_LOG_FUNC_EXIT__;
2898         return 0;
2899 }
2900
2901 int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
2902 {
2903         __WDP_LOG_FUNC_ENTER__;
2904         ws_sock_data_s *sock = g_pd->common;
2905         char cmd[80] = {0, };
2906         char reply[1024]={0,};
2907         int res;
2908         int i;
2909         ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
2910         int network_count;
2911
2912         if (!ssid || !bssid) {
2913                 WDP_LOGE("Invalid parameter");
2914                 return -1;
2915         }
2916
2917         if (!sock) {
2918                 WDP_LOGE("Socket is NULL");
2919                 return -1;
2920         }
2921
2922         memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
2923
2924         strncpy(cmd, WS_CMD_LIST_NETWORKS, sizeof(cmd));
2925         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2926         if (res < 0) {
2927                 WDP_LOGE("Failed to send command to wpa_supplicant");
2928                 __WDP_LOG_FUNC_EXIT__;
2929                 return -1;
2930         }
2931
2932         if (strstr(reply, "FAIL")) {
2933                 WDP_LOGE("Failed to get list of networks");
2934                 __WDP_LOG_FUNC_EXIT__;
2935                 return -1;
2936         }
2937         WDP_LOGD("Succeeded to get list of networks");
2938
2939         _parsing_networks(reply, networks, &network_count);
2940
2941         for(i=0;i<network_count;i++) {
2942                 WDP_LOGD("----persistent group [%d]----", i);
2943                 WDP_LOGD("network_id=%d", networks[i].network_id);
2944                 WDP_LOGD("ssid=%s", networks[i].ssid);
2945                 WDP_LOGD("bssid=" MACSTR, MAC2STR(networks[i].bssid));
2946                 WDP_LOGD("flags=%x", networks[i].flags);
2947
2948                 if (!memcmp(bssid, networks[i].bssid, WS_MACADDR_LEN) && !strcmp(ssid, networks[i].ssid)) {
2949
2950                         WDP_LOGD("Persistent group found [%d: %s]", networks[i].network_id, ssid);
2951
2952                         memset(cmd, 0x0, sizeof(cmd));
2953                         memset(reply, 0x0, sizeof(reply));
2954
2955                         snprintf(cmd, sizeof(cmd), WS_CMD_REMOVE_NETWORK " %d", networks[i].network_id);
2956                         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2957                         if (res < 0) {
2958                                 WDP_LOGE("Failed to send command to wpa_supplicant");
2959                                 __WDP_LOG_FUNC_EXIT__;
2960                                 return -1;
2961                         }
2962
2963                         if (strstr(reply, "FAIL")) {
2964                                 WDP_LOGE("Failed to remove persistent group");
2965                                 __WDP_LOG_FUNC_EXIT__;
2966                                 return -1;
2967                         }
2968                         WDP_LOGD("Succeeded to remove persistent group");
2969
2970                         break;
2971                 }
2972         }
2973
2974         if (i == network_count) {
2975                 WDP_LOGE("Persistent group not found [%s]", ssid);
2976                 return -1;
2977         }
2978
2979         __WDP_LOG_FUNC_EXIT__;
2980         return 0;
2981 }
2982
2983 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
2984 {
2985         __WDP_LOG_FUNC_ENTER__;
2986         ws_sock_data_s *sock = g_pd->common;
2987         char cmd[80] = {0, };
2988         char reply[1024]={0,};
2989         int res;
2990
2991         if (!sock) {
2992                 WDP_LOGE("Socket is NULL");
2993                 return -1;
2994         }
2995
2996         snprintf(cmd, sizeof(cmd), "%s persistent_reconnect %d", WS_CMD_SET, reconnect);
2997         res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
2998         if (res < 0) {
2999                 WDP_LOGE("Failed to send command to wpa_supplicant");
3000                 __WDP_LOG_FUNC_EXIT__;
3001                 return -1;
3002         }
3003
3004         if (strstr(reply, "FAIL")) {
3005                 WDP_LOGE("Failed to register WFDS service");
3006                 __WDP_LOG_FUNC_EXIT__;
3007                 return -1;
3008         }
3009         WDP_LOGD("Succeeded to register WFDS service");
3010
3011         __WDP_LOG_FUNC_EXIT__;
3012         return 0;
3013 }