22e80855e9f227c0eb2375a1e4537da569c2e4db
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-util.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 utility functions.
22  *
23  * @file                wifi-direct-util.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/ioctl.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <net/if.h>
36 #include <unistd.h>
37 #include <errno.h>
38
39 #include <glib.h>
40
41 #include <vconf.h>
42 #include <app_service.h>
43 #include <wifi-direct.h>
44 #include <wifi-direct-internal.h>
45
46 #include "wifi-direct-manager.h"
47 #include "wifi-direct-state.h"
48 #include "wifi-direct-client.h"
49 #include "wifi-direct-util.h"
50
51 static int _txt_to_mac(char *txt, unsigned char *mac)
52 {
53         int i = 0;
54
55         for (;;) {
56                 mac[i++] = (char) strtoul(txt, &txt, 16);
57                 if (!*txt++ || i == 6)
58                         break;
59         }
60
61         if (i != MACADDR_LEN)
62                 return -1;
63
64         WDS_LOGD("Converted MAC address [" MACSTR "]", MAC2STR(mac));
65         return 0;
66 }
67
68 static int _txt_to_ip(char *txt, unsigned char *ip)
69 {
70         int i = 0;
71
72         for (;;) {
73                 ip[i++] = (char) strtoul(txt, &txt, 10);
74                 if (!*txt++ || i == 4)
75                         break;
76         }
77
78         if (i != 4)
79                 return -1;
80
81         WDS_LOGD("Converted IP address [" IPSTR "]", IP2STR(ip));
82         return 0;
83 }
84
85 gboolean wfd_util_execute_file(const char *file_path,
86         char *const args[], char *const envs[])
87 {
88         pid_t pid = 0;
89         int rv = 0;
90         errno = 0;
91         register unsigned int index = 0;
92
93         while (args[index] != NULL) {
94                 WDS_LOGD("[%s]", args[index]);
95                 index++;
96         }
97
98         if (!(pid = fork())) {
99                 WDS_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
100                 WDS_LOGD("Inside child, exec (%s) command", file_path);
101
102                 errno = 0;
103                 if (execve(file_path, args, envs) == -1) {
104                         WDS_LOGE("Fail to execute command (%s)", strerror(errno));
105                         exit(1);
106                 }
107         } else if (pid > 0) {
108                 if (waitpid(pid, &rv, 0) == -1)
109                         WDS_LOGD("wait pid (%u) rv (%d)", pid, rv);
110                 if (WIFEXITED(rv)) {
111                         WDS_LOGD("exited, rv=%d", WEXITSTATUS(rv));
112                 } else if (WIFSIGNALED(rv)) {
113                         WDS_LOGD("killed by signal %d", WTERMSIG(rv));
114                 } else if (WIFSTOPPED(rv)) {
115                         WDS_LOGD("stopped by signal %d", WSTOPSIG(rv));
116                 } else if (WIFCONTINUED(rv)) {
117                         WDS_LOGD("continued");
118                 }
119
120                 return TRUE;
121         }
122
123         WDS_LOGE("failed to fork (%s)", strerror(errno));
124         return FALSE;
125 }
126
127 int wfd_util_freq_to_channel(int freq)
128 {
129         if (freq < 2412 || freq > 5825) {
130                 WDS_LOGE("Invalid parameter");
131                 return -1;
132         }
133
134         if (freq >= 5180)
135                 return 36 + (freq - 5180)/5;
136         else if (freq <= 2472)
137                 return 1 + (freq - 2412)/5;
138         else if (freq == 2484)
139                 return 14;
140         else
141                 return -1;
142 }
143
144 int wfd_util_get_phone_name(char *phone_name)
145 {
146         __WDS_LOG_FUNC_ENTER__;
147         char *name = NULL;
148
149         name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
150         if (!name) {
151                 WDS_LOGE( "Failed to get vconf value for %s", VCONFKEY_SETAPPL_DEVICE_NAME_STR);
152                 return -1;
153         }
154         strncpy(phone_name, name, DEV_NAME_LEN);
155         phone_name[DEV_NAME_LEN] = '\0';
156
157         WDS_LOGD( "[%s: %s]", VCONFKEY_SETAPPL_DEVICE_NAME_STR, phone_name);
158         free(name);
159         __WDS_LOG_FUNC_EXIT__;
160         return 0;
161 }
162
163 void _wfd_util_dev_name_changed_cb(keynode_t *key, void* data)
164 {
165         __WDS_LOG_FUNC_ENTER__;
166         char dev_name[DEV_NAME_LEN+1] = {0, };
167         int res = 0;
168
169         res = wfd_util_get_phone_name(dev_name);
170         if (res < 0) {
171                 WDS_LOGE("Failed to get phone name(vconf)");
172                 return;
173         }
174         WDS_LOGD("Device name changed as [%s]", dev_name);
175
176         res = wfd_local_set_dev_name(dev_name);
177         if (res < 0)
178                 WDS_LOGE("Failed to set device name");
179         __WDS_LOG_FUNC_EXIT__;
180         return;
181 }
182
183 void wfd_util_set_dev_name_notification()
184 {
185         __WDS_LOG_FUNC_ENTER__;
186
187         vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb, NULL);
188
189         __WDS_LOG_FUNC_EXIT__;
190         return;
191 }
192
193 void wfd_util_unset_dev_name_notification()
194 {
195         __WDS_LOG_FUNC_ENTER__;
196
197         vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb);
198
199         __WDS_LOG_FUNC_EXIT__;
200         return;
201 }
202
203 int wfd_util_check_wifi_state()
204 {
205         __WDS_LOG_FUNC_ENTER__;
206         int wifi_state = 0;
207         int res = 0;
208
209         /* vconf key and value (vconf-keys.h)
210 #define VCONFKEY_WIFI_STATE "memory/wifi/state"
211 enum {
212         VCONFKEY_WIFI_OFF = 0x00,
213         VCONFKEY_WIFI_UNCONNECTED,
214         VCONFKEY_WIFI_CONNECTED,
215         VCONFKEY_WIFI_TRANSFER,
216         VCONFKEY_WIFI_STATE_MAX
217 };
218          */
219
220         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
221         if (res < 0) {
222                 WDS_LOGE("Failed to get vconf value [%s]", VCONFKEY_WIFI_STATE);
223                 __WDS_LOG_FUNC_EXIT__;
224                 return -1;
225         }
226         WDS_LOGD("[%s: %d]", VCONFKEY_WIFI_STATE, wifi_state);
227
228         if (wifi_state > VCONFKEY_WIFI_OFF) {
229                 WDS_LOGD("Wi-Fi is on");
230                 __WDS_LOG_FUNC_EXIT__;
231                 return 1;
232         }
233         WDS_LOGD( "OK. Wi-Fi is off\n");
234
235         __WDS_LOG_FUNC_EXIT__;
236         return 0;
237 }
238
239 int wfd_util_check_mobile_ap_state()
240 {
241         __WDS_LOG_FUNC_ENTER__;
242         int mobile_ap_state = 0;
243         int res = 0;
244
245         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobile_ap_state);
246         if (res < 0) {
247                 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
248                 __WDS_LOG_FUNC_EXIT__;
249                 return -1;
250         }
251         WDS_LOGD("[%s: %d]", VCONFKEY_MOBILE_HOTSPOT_MODE, mobile_ap_state);
252
253         if (mobile_ap_state != VCONFKEY_MOBILE_HOTSPOT_MODE_NONE) {
254                 WDS_LOGD("Mobile AP is on");
255                 __WDS_LOG_FUNC_EXIT__;
256                 return 1;
257         }
258         WDS_LOGD( "OK. Mobile AP is off\n");
259
260         __WDS_LOG_FUNC_EXIT__;
261         return 0;
262 }
263
264 int wfd_util_wifi_direct_activatable()
265 {
266         __WDS_LOG_FUNC_ENTER__;
267         int res = 0;
268
269         res = wfd_util_check_wifi_state();
270         if (res < 0) {
271                 WDS_LOGE("Failed to check Wi-Fi state");
272                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
273         } else if (res > 0) {
274                 WDS_LOGE("Wi-Fi is On");
275                 return WIFI_DIRECT_ERROR_WIFI_USED;
276         } else {
277                 WDS_LOGE("Wi-Fi is Off");
278                 return WIFI_DIRECT_ERROR_NONE;
279         }
280
281         res = wfd_util_check_mobile_ap_state();
282         if (res < 0) {
283                 WDS_LOGE("Failed to check Mobile AP state");
284                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
285         } else if (res > 0) {
286                 WDS_LOGE("Mobile AP is On");
287                 return WIFI_DIRECT_ERROR_MOBILE_AP_USED;
288         } else {
289                 WDS_LOGE("Mobile AP is Off");
290                 return WIFI_DIRECT_ERROR_NONE;
291         }
292 }
293
294 int wfd_util_get_wifi_direct_state()
295 {
296         __WDS_LOG_FUNC_ENTER__;
297         int state = 0;
298         int res = 0;
299
300         res = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &state);
301         if (res < 0) {
302                 WDS_LOGE("Failed to get vconf value [%s]\n", VCONFKEY_WIFI_DIRECT_STATE);
303                 __WDS_LOG_FUNC_EXIT__;
304                 return -1;
305         }
306
307         __WDS_LOG_FUNC_EXIT__;
308         return state;
309 }
310
311 int wfd_util_set_wifi_direct_state(int state)
312 {
313         __WDS_LOG_FUNC_ENTER__;
314         int vconf_state = 0;
315         int res = 0;
316
317         // TODO: check validity of state
318
319         if (state == WIFI_DIRECT_STATE_ACTIVATED)
320                 vconf_state = VCONFKEY_WIFI_DIRECT_ACTIVATED;
321         else if (state == WIFI_DIRECT_STATE_DEACTIVATED)
322                 vconf_state= VCONFKEY_WIFI_DIRECT_DEACTIVATED;
323         else if (state == WIFI_DIRECT_STATE_CONNECTED)
324                 vconf_state = VCONFKEY_WIFI_DIRECT_CONNECTED;
325         else if (state == WIFI_DIRECT_STATE_GROUP_OWNER)
326                 vconf_state = VCONFKEY_WIFI_DIRECT_GROUP_OWNER;
327         else if (state == WIFI_DIRECT_STATE_DISCOVERING)
328                 vconf_state = VCONFKEY_WIFI_DIRECT_DISCOVERING;
329         WDS_LOGD("Vconf key set [%s: %d]", VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
330
331         res = vconf_set_int(VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
332         if (res < 0) {
333                 WDS_LOGE("Failed to set vconf [%s]", VCONFKEY_WIFI_DIRECT_STATE);
334                 __WDS_LOG_FUNC_EXIT__;
335                 return -1;
336         }
337
338         __WDS_LOG_FUNC_EXIT__;
339         return 0;
340 }
341
342 int wfd_util_get_local_dev_mac(unsigned char *dev_mac)
343 {
344         __WDS_LOG_FUNC_ENTER__;
345         FILE *fd = NULL;
346         char local_mac[MACSTR_LEN] = {0, };
347         char *ptr = NULL;
348         int res = 0;
349
350         errno = 0;
351         fd = fopen(DEFAULT_MAC_FILE_PATH, "r");
352         if (!fd) {
353                 WDS_LOGE("Failed to open MAC info file (%s)", strerror(errno));
354                 __WDS_LOG_FUNC_EXIT__;
355                 return -1;
356         }
357
358         errno = 0;
359         ptr = fgets(local_mac, MACSTR_LEN, fd);
360         if (!ptr) {
361                 WDS_LOGE("Failed to read file or no data read(%s)", strerror(errno));
362                 fclose(fd);
363                 __WDS_LOG_FUNC_EXIT__;
364                 return -1;
365         }
366         WDS_LOGD("Local MAC address [%s]", ptr);
367
368         res = _txt_to_mac(local_mac, dev_mac);
369         if (res < 0) {
370                 WDS_LOGE("Failed to convert text to MAC address");
371                 fclose(fd);
372                 __WDS_LOG_FUNC_EXIT__;
373                 return -1;
374         }
375
376         dev_mac[0] |= 0x2;
377         WDS_LOGD("Local Device MAC address [" MACSTR "]", MAC2STR(dev_mac));
378
379         fclose(fd);
380         __WDS_LOG_FUNC_EXIT__;
381         return 0;
382 }
383
384 int wfd_util_get_access_list(GList **access_list)
385 {
386         __WDS_LOG_FUNC_ENTER__;
387
388         wfd_access_list_info_s * device = NULL;
389         char device_info[MACSTR_LEN + DEV_NAME_LEN + 1] = {0, };
390         char dev_mac[MACADDR_LEN] = {0, };
391         int info_str_len = 0;
392
393         FILE *fd = NULL;
394         int res = 0;
395
396
397         fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "r");
398         if (!fd) {
399                 WDS_LOGE("Failed to open access list file (%s)", strerror(errno));
400                 __WDS_LOG_FUNC_EXIT__;
401                 return -1;
402         }
403
404         while ((res = fgets(device_info, MACSTR_LEN + DEV_NAME_LEN + 2, fd)) != NULL)
405         {
406                 if (device_info[0] == '\0') {
407                         printf("end of list\n");
408                         fclose(fd);
409                         return 0;
410                 }
411
412                 info_str_len = strlen(device_info);
413                 if(info_str_len > MACSTR_LEN)
414                         device_info[info_str_len -1] = '\0';
415
416                 res = _txt_to_mac(device_info, dev_mac);
417                 if (res < 0) {
418                         WDS_LOGE("Failed to convert text to MAC address");
419                         continue;
420                 }
421
422                 device = calloc(1, sizeof(wfd_access_list_info_s));
423                 memcpy(device->mac_address, dev_mac, MACADDR_LEN);
424                 strncpy(device->device_name, &device_info[MACSTR_LEN], strlen(&device_info[MACSTR_LEN]));
425                 device->allowed = (device_info[MACSTR_LEN - 1] == 'O');
426
427                 *access_list = g_list_append(*access_list, device);
428         }
429         fclose(fd);
430         __WDS_LOG_FUNC_EXIT__;
431         return 0;
432 }
433
434 int wfd_util_rewrite_device_list_to_file(GList *access_list)
435 {
436         __WDS_LOG_FUNC_ENTER__;
437         FILE *fd = NULL;
438         GList *temp = NULL;
439         wfd_access_list_info_s * device = NULL;
440
441         int list_cnt =0;
442         char * buf = NULL;
443         char * ptr = NULL;
444
445         int res = 0;
446         int i;
447
448         list_cnt =  g_list_length(access_list);
449
450         fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "w");
451         if (!fd) {
452                 WDS_LOGE("Failed to open access list file (%s)", strerror(errno));
453                 free(buf);
454                 __WDS_LOG_FUNC_EXIT__;
455                 return -1;
456         }
457         if(list_cnt > 0)
458         {
459                 buf = calloc(1,(MACSTR_LEN + DEV_NAME_LEN + 1)*list_cnt +1);
460                 ptr = buf;
461                 temp = g_list_first(access_list);
462
463                 for(i =0; i < list_cnt; i++)
464                 {
465                         device = (wfd_access_list_info_s *)temp->data;
466                         snprintf(ptr, MACSTR_LEN + DEV_NAME_LEN + 2, MACSTR "%c%s\n",
467                                           MAC2STR(device->mac_address), device->allowed?'O':'X', device->device_name);
468                         ptr+=strlen(ptr);
469                         temp = g_list_next(temp);
470                 }
471                 res = fprintf(fd, "%s",buf);
472         }
473
474         fclose(fd);
475         if(buf != NULL)
476                 free(buf);
477         __WDS_LOG_FUNC_EXIT__;
478         return res;
479 }
480
481 int wfd_util_add_device_to_list(wfd_device_s *peer, int allowed)
482 {
483         __WDS_LOG_FUNC_ENTER__;
484         FILE *fd = NULL;
485         char buf[MACSTR_LEN + DEV_NAME_LEN + 2] = {0, };
486         int res = 0;
487
488         if(peer == NULL)
489         {
490                 WDS_LOGD("There is nothing to add to list");
491                 return -1;
492         }
493
494         snprintf(buf, MACSTR_LEN + DEV_NAME_LEN + 2, MACSTR "%c%s\n",
495                         MAC2STR(peer->dev_addr), allowed?'O':'X', peer->dev_name);
496
497         fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "a");
498         if (!fd) {
499                 WDS_LOGE("Failed to open access list file (%s)", strerror(errno));
500                 __WDS_LOG_FUNC_EXIT__;
501                 return -1;
502         }
503         res = fprintf(fd,"%s", buf);
504
505         if(res < 0)
506                 WDS_LOGE("Failed to write to access list file (%s)", strerror(errno));
507
508         fclose(fd);
509         __WDS_LOG_FUNC_EXIT__;
510         return res;
511 }
512
513 int wfd_util_reset_access_list_file()
514 {
515         __WDS_LOG_FUNC_ENTER__;
516         int res = 0;
517
518         FILE *fd = NULL;
519         fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "w");
520
521         if (!fd) {
522                 WDS_LOGE("Failed to open reset access list file (%s)", strerror(errno));
523                 res = -1;
524         }
525         fclose(fd);
526
527         __WDS_LOG_FUNC_EXIT__;
528         return 0;
529
530 }
531
532 int wfd_util_start_wifi_direct_popup()
533 {
534         __WDS_LOG_FUNC_ENTER__;
535
536         service_h service;
537         service_create(&service);
538         service_set_operation(service, SERVICE_OPERATION_DEFAULT);
539         service_set_package(service, "org.tizen.wifi-direct-popup");
540         service_send_launch_request(service, NULL, NULL);
541         service_destroy(service);
542         WDS_LOGD("Succeeded to launch wifi-direct-popup");
543         __WDS_LOG_FUNC_EXIT__;
544         return 0;
545 }
546
547
548 static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
549 {
550         __WDS_LOG_FUNC_ENTER__;
551         wfd_manager_s *manager = wfd_get_manager();
552         wfd_device_s *peer = (wfd_device_s*) data;
553         wifi_direct_client_noti_s noti;
554         FILE *fp = NULL;
555         char buf[MAX_DHCP_DUMP_SIZE];
556         char ip_str[IPSTR_LEN];
557         char intf_str[MACSTR_LEN];
558         unsigned char intf_addr[MACADDR_LEN];
559         int n = 0;
560
561         if (!peer) {
562                 WDS_LOGD("Invalid parameter");
563                 return;
564         }
565         WDS_LOGD("DHCP server: IP leased");
566         memset(&noti, 0, sizeof(wifi_direct_client_noti_s));
567
568         errno = 0;
569         fp = fopen(DHCP_DUMP_FILE, "r");
570         if (NULL == fp) {
571                 WDS_LOGE("Could not read the file(%s). [%s]", DHCP_DUMP_FILE, strerror(errno));
572                 return;
573         }
574
575         while(fgets(buf, MAX_DHCP_DUMP_SIZE, fp) != NULL) {
576                 WDS_LOGD("Read line [%s]", buf);
577                 n = sscanf(buf,"%s %s", intf_str, ip_str);
578                 WDS_LOGD("ip=[%s], mac=[%s]",ip_str, intf_str);
579                 if (n != 2) {
580                         continue;
581                 }
582                 _txt_to_mac(intf_str, intf_addr);
583                 if (!memcmp(peer->intf_addr, intf_addr, MACADDR_LEN)) {
584                         WDS_LOGD("Peer intf mac found");
585                         _txt_to_ip(ip_str, peer->ip_addr);
586                         noti.event = WIFI_DIRECT_CLI_EVENT_IP_LEASED_IND;
587                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
588                         snprintf(noti.param2, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
589                         wfd_client_send_event(manager, &noti);
590                         break;
591                 } else {
592                         WDS_LOGE("Different interface address peer[" MACSTR "] vs dhcp[" MACSTR "]", MAC2STR(peer->intf_addr), MAC2STR(intf_addr));
593                 }
594         }
595         fclose(fp);
596
597         __WDS_LOG_FUNC_EXIT__;
598         return;
599 }
600
601 static gboolean _polling_ip(gpointer user_data)
602 {
603         __WDS_LOG_FUNC_ENTER__;
604         wfd_manager_s *manager = wfd_get_manager();
605         wfd_device_s *local = (wfd_device_s*) manager->local;
606         wfd_device_s *peer = (wfd_device_s*) user_data;
607         char *ifname = NULL;
608         static int count = 0;
609         int res = 0;
610
611         if (count > 28) {
612                 WDS_LOGE("Failed to get IP");
613                 count = 0;
614                 __WDS_LOG_FUNC_EXIT__;
615                 return FALSE;
616         }
617         res = wfd_manager_get_goup_ifname(&ifname);
618         if (res < 0 || !ifname) {
619                 WDS_LOGE("Failed to get group interface name");
620                 return FALSE;
621         }
622
623         res = wfd_util_dhcpc_get_ip(ifname, local->ip_addr, 0);
624         if (res < 0) {
625                 WDS_LOGE("Failed to get local IP for interface %s(count=%d)", ifname, count++);
626                 __WDS_LOG_FUNC_EXIT__;
627                 return TRUE;
628         }
629         WDS_LOGD("Succeeded to get local(client) IP [" IPSTR "] for iface[%s]",
630                                     IP2STR(local->ip_addr), ifname);
631
632         res = wfd_util_dhcpc_get_server_ip(peer->ip_addr);
633         if (res < 0) {
634                 WDS_LOGE("Failed to get peer(server) IP(count=%d)", count++);
635                 __WDS_LOG_FUNC_EXIT__;
636                 return TRUE;
637         }
638         WDS_LOGD("Succeeded to get server IP [" IPSTR "]", IP2STR(peer->ip_addr));
639         count = 0;
640
641         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
642         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
643         wifi_direct_client_noti_s noti;
644         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
645         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
646         noti.error = WIFI_DIRECT_ERROR_NONE;
647         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
648         wfd_client_send_event(manager, &noti);
649
650         __WDS_LOG_FUNC_EXIT__;
651         return FALSE;
652 }
653
654 int wfd_util_dhcps_start()
655 {
656         __WDS_LOG_FUNC_ENTER__;
657         gboolean rv = FALSE;
658         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
659         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "server", NULL };
660         char *const envs[] = { NULL };
661
662         vconf_set_int(VCONFKEY_DHCPS_IP_LEASE, 0);
663
664         rv = wfd_util_execute_file(path, args, envs);
665
666         if (rv != TRUE) {
667                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh server");
668                 return -1;
669         }
670         WDS_LOGD("Successfully started wifi-direct-dhcp.sh server");
671
672         __WDS_LOG_FUNC_EXIT__;
673         return 0;
674 }
675
676 int wfd_util_dhcps_wait_ip_leased(wfd_device_s *peer)
677 {
678         __WDS_LOG_FUNC_ENTER__;
679
680         if (!peer) {
681                 WDS_LOGE("Invalid parameter");
682                 return -1;
683         }
684
685         vconf_set_int(VCONFKEY_DHCPS_IP_LEASE, 0);
686         vconf_notify_key_changed(VCONFKEY_DHCPS_IP_LEASE, _dhcps_ip_leased_cb, peer);
687
688         __WDS_LOG_FUNC_EXIT__;
689         return 0;
690 }
691
692 int wfd_util_dhcps_stop()
693 {
694         __WDS_LOG_FUNC_ENTER__;
695         gboolean rv = FALSE;
696         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
697         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", NULL };
698         char *const envs[] = { NULL };
699
700         vconf_ignore_key_changed(VCONFKEY_DHCPS_IP_LEASE, _dhcps_ip_leased_cb);
701         vconf_set_int(VCONFKEY_DHCPS_IP_LEASE, 0);
702
703         rv = wfd_util_execute_file(path, args, envs);
704
705         if (rv != TRUE) {
706                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
707                 return -1;
708         }
709         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
710
711         __WDS_LOG_FUNC_EXIT__;
712         return 0;
713 }
714
715 int wfd_util_dhcpc_start(wfd_device_s *peer)
716 {
717         __WDS_LOG_FUNC_ENTER__;
718         gboolean rv = FALSE;
719         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
720         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "client", NULL };
721         char *const envs[] = { NULL };
722
723         if (!peer) {
724                 WDS_LOGE("Invalid parameter");
725                 return -1;
726         }
727
728         rv = wfd_util_execute_file(path, args, envs);
729
730         if (rv != TRUE) {
731                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh client");
732                 return -1;
733         }
734         WDS_LOGD("Successfully started wifi-direct-dhcp.sh client");
735
736         g_timeout_add(250, (GSourceFunc) _polling_ip, peer);
737
738         __WDS_LOG_FUNC_EXIT__;
739         return 0;
740 }
741
742 int wfd_util_dhcpc_stop()
743 {
744         __WDS_LOG_FUNC_ENTER__;
745         gboolean rv = FALSE;
746         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
747         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", NULL };
748         char *const envs[] = { NULL };
749
750         rv = wfd_util_execute_file(path, args, envs);
751
752         if (rv != TRUE) {
753                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
754                 return -1;
755         }
756         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
757
758         __WDS_LOG_FUNC_EXIT__;
759         return 0;
760 }
761
762 int wfd_util_dhcpc_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6)
763 {
764         __WDS_LOG_FUNC_ENTER__;
765         struct ifreq ifr;
766         struct sockaddr_in *sin = NULL;
767         char *ip_str = NULL;
768         int sock = -1;
769         int res = -1;
770
771         if (!ifname || !ip_addr) {
772                 WDS_LOGE("Invalid parameter");
773                 __WDS_LOG_FUNC_EXIT__;
774                 return -1;
775         }
776
777         errno = 0;
778         sock = socket(AF_INET, SOCK_DGRAM, 0);
779         if (sock < SOCK_FD_MIN) {
780                 WDS_LOGE("Failed to create socket. [%s]", strerror(errno));
781                 if (sock >= 0)
782                         close(sock);
783                 __WDS_LOG_FUNC_EXIT__;
784                 return -1;
785         }
786
787         ifr.ifr_addr.sa_family = AF_INET;
788         memset(ifr.ifr_name, 0x00, 16);
789         strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
790
791         errno = 0;
792         res = ioctl(sock, SIOCGIFADDR, &ifr);
793         if (res < 0) {
794                 WDS_LOGE("Failed to get IP from socket. [%s]", strerror(errno));
795                 close(sock);
796                 __WDS_LOG_FUNC_EXIT__;
797                 return -1;
798         }
799         close(sock);
800
801         sin = (struct sockaddr_in*) &ifr.ifr_broadaddr;
802         ip_str = inet_ntoa(sin->sin_addr);
803         _txt_to_ip(ip_str, ip_addr);
804
805         __WDS_LOG_FUNC_EXIT__;
806         return 0;
807 }
808
809 int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr)
810 {
811         __WDS_LOG_FUNC_ENTER__;
812         char* get_str = NULL;
813         int count = 0;
814
815         if (!ip_addr) {
816                 WDS_LOGE("Invalid parameter");
817                 __WDS_LOG_FUNC_EXIT__;
818                 return -1;
819         }
820
821         while(count < 10) {
822                 get_str = vconf_get_str(VCONFKEY_DHCPC_SERVER_IP);
823                 if (!get_str) {
824                         WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_DHCPC_SERVER_IP);
825                         __WDS_LOG_FUNC_EXIT__;
826                         return -1;
827                 }
828                 WDS_LOGD("VCONFKEY_DHCPC_SERVER_IP(%s) : %s\n", VCONFKEY_DHCPC_SERVER_IP, get_str);
829                 _txt_to_ip(get_str, ip_addr);
830                 if (*ip_addr)
831                         break;
832                 count++;
833         }
834
835         __WDS_LOG_FUNC_EXIT__;
836         return 0;
837 }
838