Bug Fix and Code Cleanup
[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 <string.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <sys/socket.h>
34 #include <sys/ioctl.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <net/if.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <time.h>
41 #include <errno.h>
42
43 #include <glib.h>
44
45 #include <vconf.h>
46 #include <tzplatform_config.h>
47 #if defined(TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT)
48 #include <systemd/sd-login.h>
49 #include <aul.h>
50 #endif
51 #include <wifi-direct.h>
52
53 #include "wifi-direct-ipc.h"
54 #include "wifi-direct-manager.h"
55 #include "wifi-direct-state.h"
56 #include "wifi-direct-util.h"
57 #include "wifi-direct-oem.h"
58 #include "wifi-direct-group.h"
59 #include "wifi-direct-session.h"
60 #include "wifi-direct-error.h"
61 #include "wifi-direct-log.h"
62 #include "wifi-direct-dbus.h"
63 #if defined(TIZEN_FEATURE_ASP)
64 #include "wifi-direct-asp.h"
65 #endif
66
67 #include <linux/unistd.h>
68 #include <asm/types.h>
69 #include <linux/netlink.h>
70 #include <linux/rtnetlink.h>
71
72 #include <netlink/netlink.h>
73 #include <netlink/socket.h>
74 #include <netlink/route/neighbour.h>
75
76 #define TIZEN_P2P_GO_IPADDR "192.168.49.1"
77 #define MAX_SIZE_ERROR_BUFFER 256
78
79 #if defined TIZEN_PROFILE_TV
80 #       if defined TIZEN_WIFI_MODULE_BUNDLE
81 #               define DEFAULT_MAC_FILE_PATH "/sys/class/net/wlan0/address"
82 #       else /* TIZEN_WIFI_MODULE_BUNDLE */
83 #               define DEFAULT_MAC_FILE_PATH "/sys/class/net/p2p0/address"
84 #       endif /* TIZEN_WIFI_MODULE_BUNDLE */
85 #endif /* TIZEN_PROFILE_TV */
86
87 #ifndef DEFAULT_MAC_FILE_PATH
88 #       define DEFAULT_MAC_FILE_PATH "/sys/class/net/p2p0/address"
89 #endif
90
91 #define COUNTRY_CODE_FILE tzplatform_mkpath(TZ_SYS_RO_ETC, "wifi-direct/ccode.conf")
92
93 static int _txt_to_mac(char *txt, unsigned char *mac)
94 {
95         int i = 0;
96
97         for (;;) {
98                 mac[i++] = (char) strtoul(txt, &txt, 16);
99                 if (i == MACADDR_LEN || !*txt++)
100                         break;
101         }
102
103         if (i != MACADDR_LEN)
104                 return -1;
105
106         WDS_LOGD("Converted MAC address [" MACSECSTR "]",
107                                         MAC2SECSTR(mac));
108         return 0;
109 }
110
111 static int _txt_to_ip(char *txt, unsigned char *ip)
112 {
113         int i = 0;
114
115         for (;;) {
116                 ip[i++] = (char) strtoul(txt, &txt, 10);
117                 if (i == IPADDR_LEN || !*txt++)
118                         break;
119         }
120
121         if (i != IPADDR_LEN)
122                 return -1;
123
124         WDS_LOGD("Converted IP address [" IPSECSTR "]", IP2SECSTR(ip));
125         return 0;
126 }
127
128 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
129 int wfd_util_get_current_time(unsigned long *cur_time)
130 {
131         struct timespec time;
132         int res;
133         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
134
135         errno = 0;
136         res = clock_gettime(CLOCK_REALTIME, &time);
137         if (!res) {
138                 WDS_LOGD("Succeeded to get current real time");
139                 *cur_time = time.tv_sec;
140                 return 0;
141         }
142         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
143         WDS_LOGE("Failed to get current real time(%s)", error_buf);
144
145         errno = 0;
146         res = clock_gettime(CLOCK_MONOTONIC, &time);
147         if (!res) {
148                 WDS_LOGD("Succeeded to get current system time");
149                 *cur_time = time.tv_sec;
150                 return 0;
151         }
152         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
153         WDS_LOGE("Failed to get current system time(%s)", error_buf);
154
155         return -1;
156 }
157 #endif
158
159 #if defined(TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT)
160 static int __wfd_util_find_login_user(uid_t *uid)
161 {
162         uid_t *uids;
163         int ret, i;
164         char *state;
165
166         ret = sd_get_uids(&uids);
167         if (ret <= 0)
168                 return -1;
169
170         for (i = 0; i < ret ; i++) {
171                 if (sd_uid_get_state(uids[i], &state) < 0) {
172                         free(uids);
173                         return -1;
174                 } else {
175                         if (!strncmp(state, "online", 6)) {
176                                 *uid = uids[i];
177                                 free(uids);
178                                 free(state);
179                                 return 0;
180                         }
181                 }
182          }
183         free(uids);
184         free(state);
185         return -1;
186 }
187 #endif
188
189 gboolean wfd_util_execute_file(const char *file_path,
190         char *const args[], char *const envs[])
191 {
192         pid_t pid = 0;
193         int rv = 0;
194         errno = 0;
195         register unsigned int index = 0;
196         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
197
198         while (args[index] != NULL) {
199                 WDS_LOGD("[%s]", args[index]);
200                 index++;
201         }
202
203         if (!(pid = fork())) {
204                 WDS_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
205                 WDS_LOGD("Inside child, exec (%s) command", file_path);
206
207                 errno = 0;
208                 if (execve(file_path, args, envs) == -1) {
209                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
210                         WDS_LOGE("Fail to execute command (%s)", error_buf);
211                         exit(1);
212                 }
213         } else if (pid > 0) {
214                 if (waitpid(pid, &rv, 0) == -1)
215                         WDS_LOGD("wait pid (%u) rv (%d)", pid, rv);
216                 if (WIFEXITED(rv))
217                         WDS_LOGD("exited, rv=%d", WEXITSTATUS(rv));
218                 else if (WIFSIGNALED(rv))
219                         WDS_LOGD("killed by signal %d", WTERMSIG(rv));
220                 else if (WIFSTOPPED(rv))
221                         WDS_LOGD("stopped by signal %d", WSTOPSIG(rv));
222                 else if (WIFCONTINUED(rv))
223                         WDS_LOGD("continued");
224                 return TRUE;
225         }
226
227         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
228         WDS_LOGE("failed to fork (%s)", error_buf);
229         return FALSE;
230 }
231
232 int wfd_util_channel_to_freq(int channel)
233 {
234         if (channel < 1 || channel > 161 ||
235                 (channel > 48 && channel < 149) ||
236                 (channel > 14 && channel < 36)) {
237                 WDS_LOGE("Unsupported channel[%d]", channel);
238                 return -1;
239         }
240
241         if (channel >= 36)
242                 return 5000 + 5*channel;
243         else if (channel == 14)
244                 return 2484;
245         else
246                 return 2407 + 5*channel;
247 }
248
249 int wfd_util_freq_to_channel(int freq)
250 {
251         if (freq < 2412 || freq > 5825 ||
252                 (freq > 2484 && freq < 5180)) {
253                 WDS_LOGE("Unsupported frequency[%d]", freq);
254                 return -1;
255         }
256
257         if (freq >= 5180)
258                 return 36 + (freq - 5180)/5;
259         else if (freq <= 2472)
260                 return 1 + (freq - 2412)/5;
261         else if (freq == 2484)
262                 return 14;
263         else
264                 return -1;
265 }
266
267 int wfd_util_get_phone_name(char *phone_name)
268 {
269         __WDS_LOG_FUNC_ENTER__;
270         char *name = NULL;
271
272         name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
273         if (!name) {
274                 WDS_LOGE("Failed to get vconf value for %s", VCONFKEY_SETAPPL_DEVICE_NAME_STR);
275                 return -1;
276         }
277         g_strlcpy(phone_name, name, DEV_NAME_LEN + 1);
278         WDS_LOGD("[%s: %s]", VCONFKEY_SETAPPL_DEVICE_NAME_STR, phone_name);
279         g_free(name);
280         __WDS_LOG_FUNC_EXIT__;
281         return 0;
282 }
283
284 void _wfd_util_dev_name_changed_cb(keynode_t *key, void *data)
285 {
286         __WDS_LOG_FUNC_ENTER__;
287         char dev_name[DEV_NAME_LEN+1] = {0, };
288         int res = 0;
289
290         res = wfd_util_get_phone_name(dev_name);
291         if (res < 0) {
292                 WDS_LOGE("Failed to get phone name(vconf)");
293                 return;
294         }
295         WDS_LOGD("Device name changed as [%s]", dev_name);
296
297         res = wfd_local_set_dev_name(dev_name);
298         if (res < 0)
299                 WDS_LOGE("Failed to set device name");
300         __WDS_LOG_FUNC_EXIT__;
301         return;
302 }
303
304 void wfd_util_set_dev_name_notification()
305 {
306         __WDS_LOG_FUNC_ENTER__;
307         int res = 0;
308
309         res = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb, NULL);
310         if (res) {
311                 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
312                 return;
313         }
314
315         __WDS_LOG_FUNC_EXIT__;
316         return;
317 }
318
319 void wfd_util_unset_dev_name_notification()
320 {
321         __WDS_LOG_FUNC_ENTER__;
322         int res = 0;
323
324         res = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb);
325         if (res) {
326                 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
327                 return;
328         }
329
330         __WDS_LOG_FUNC_EXIT__;
331         return;
332 }
333
334
335 void _wfd_util_check_country_cb(keynode_t *key, void *data)
336 {
337         __WDS_LOG_FUNC_ENTER__;
338         wfd_manager_s *manager = (wfd_manager_s*) data;
339         int res = 0;
340         int plmn = 0;
341         char mcc[4] = {0, };
342         char *ccode;
343         GKeyFile *keyfile = NULL;
344         const char *file_path = COUNTRY_CODE_FILE;
345         GError * err = NULL;
346
347         if (!manager) {
348                 WDS_LOGE("Invalid parameter");
349                 return;
350         }
351
352         res = vconf_get_int(VCONFKEY_TELEPHONY_PLMN, &plmn);
353         if (res) {
354                 WDS_LOGE("Failed to get vconf value for PLMN(%d)", res);
355                 return;
356         }
357
358         snprintf(mcc, 4, "%d", plmn);
359
360         keyfile = g_key_file_new();
361         res = g_key_file_load_from_file(keyfile, file_path, 0, &err);
362         if (!res) {
363                 WDS_LOGE("Failed to load key file(%s)", err->message);
364                 g_key_file_free(keyfile);
365                 return;
366         }
367
368         ccode = g_key_file_get_string(keyfile, "ccode_map", mcc, &err);
369         if (!ccode) {
370                 WDS_LOGE("Failed to get country code string(%s)", err->message);
371                 g_key_file_free(keyfile);
372                 return;
373         }
374
375         res = wfd_oem_set_country(manager->oem_ops, ccode);
376         if (res < 0)
377                 WDS_LOGE("Failed to set contry code");
378         else
379                 WDS_LOGD("Succeeded to set country code(%s)", ccode);
380
381         g_key_file_free(keyfile);
382         g_free(ccode);
383
384         __WDS_LOG_FUNC_EXIT__;
385         return;
386 }
387
388 int wfd_util_set_country()
389 {
390         __WDS_LOG_FUNC_ENTER__;
391         wfd_manager_s *manager = wfd_get_manager();
392         int res = 0;
393
394         _wfd_util_check_country_cb(NULL, manager);
395
396         res = vconf_notify_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb, manager);
397         if (res) {
398                 WDS_LOGE("Failed to set vconf notification callback(TELEPHONY_PLMN)");
399                 return -1;
400         }
401
402         __WDS_LOG_FUNC_EXIT__;
403         return 0;
404 }
405
406 int wfd_util_unset_country()
407 {
408         __WDS_LOG_FUNC_ENTER__;
409         int res = 0;
410
411         res = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb);
412         if (res) {
413                 WDS_LOGE("Failed to unset vconf notification callback(TELEPHONY_PLMN)");
414                 return -1;
415         }
416
417         __WDS_LOG_FUNC_EXIT__;
418         return 0;
419 }
420
421 int wfd_util_check_wifi_state()
422 {
423         __WDS_LOG_FUNC_ENTER__;
424         int wifi_state = 0;
425         int res = 0;
426
427 /* vconf key and value (vconf-keys.h)
428 #define VCONFKEY_WIFI_STATE     "memory/wifi/state"
429 enum {
430         VCONFKEY_WIFI_OFF = 0x00,
431         VCONFKEY_WIFI_UNCONNECTED,
432         VCONFKEY_WIFI_CONNECTED,
433         VCONFKEY_WIFI_TRANSFER,
434         VCONFKEY_WIFI_STATE_MAX
435 };
436 */
437         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
438         if (res < 0) {
439                 WDS_LOGE("Failed to get vconf value [%s]", VCONFKEY_WIFI_STATE);
440                 __WDS_LOG_FUNC_EXIT__;
441                 return -1;
442         }
443         WDS_LOGD("[%s: %d]", VCONFKEY_WIFI_STATE, wifi_state);
444
445         if (wifi_state > VCONFKEY_WIFI_OFF) {
446                 WDS_LOGD("Wi-Fi is on");
447                 __WDS_LOG_FUNC_EXIT__;
448                 return 1;
449         }
450         WDS_LOGD("OK. Wi-Fi is off\n");
451
452         __WDS_LOG_FUNC_EXIT__;
453         return 0;
454 }
455
456 int wfd_util_check_mobile_ap_state()
457 {
458         __WDS_LOG_FUNC_ENTER__;
459         int mobile_ap_state = 0;
460         int res = 0;
461
462         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobile_ap_state);
463         if (res < 0) {
464                 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
465                 __WDS_LOG_FUNC_EXIT__;
466                 return -1;
467         }
468         WDS_LOGD("[%s: %d]", VCONFKEY_MOBILE_HOTSPOT_MODE, mobile_ap_state);
469
470         if ((mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)
471                 || (mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP)) {
472                 WDS_LOGD("Mobile AP is on");
473                 __WDS_LOG_FUNC_EXIT__;
474                 return 1;
475         }
476         WDS_LOGD("OK. Mobile AP is off\n");
477
478         __WDS_LOG_FUNC_EXIT__;
479         return 0;
480 }
481
482 int wfd_util_wifi_direct_activatable()
483 {
484         __WDS_LOG_FUNC_ENTER__;
485
486 #ifndef TIZEN_WLAN_CONCURRENT_ENABLE
487         int res_wifi = 0;
488
489         res_wifi = wfd_util_check_wifi_state();
490         if (res_wifi < 0) {
491                 WDS_LOGE("Failed to check Wi-Fi state");
492                 __WDS_LOG_FUNC_EXIT__;
493                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
494         } else if (res_wifi > 0) {
495                 WDS_LOGE("Wi-Fi is On");
496                 __WDS_LOG_FUNC_EXIT__;
497                 return WIFI_DIRECT_ERROR_WIFI_USED;
498         } else {
499                 WDS_LOGE("Wi-Fi is Off");
500                 __WDS_LOG_FUNC_EXIT__;
501                 return WIFI_DIRECT_ERROR_NONE;
502         }
503 #endif
504
505 #if defined TIZEN_TETHERING_ENABLE
506         int res_mobap = 0;
507
508         res_mobap = wfd_util_check_mobile_ap_state();
509         if (res_mobap < 0) {
510                 WDS_LOGE("Failed to check Mobile AP state");
511                 __WDS_LOG_FUNC_EXIT__;
512                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
513         } else if (res_mobap > 0) {
514                 WDS_LOGE("Mobile AP is On");
515                 __WDS_LOG_FUNC_EXIT__;
516                 return WIFI_DIRECT_ERROR_MOBILE_AP_USED;
517         } else {
518                 WDS_LOGE("Mobile AP is Off");
519                 __WDS_LOG_FUNC_EXIT__;
520                 return WIFI_DIRECT_ERROR_NONE;
521         }
522 #endif
523
524         __WDS_LOG_FUNC_EXIT__;
525         return WIFI_DIRECT_ERROR_NONE;
526 }
527
528 #if 0
529 int wfd_util_get_wifi_direct_state()
530 {
531         __WDS_LOG_FUNC_ENTER__;
532         int state = 0;
533         int res = 0;
534
535         res = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &state);
536         if (res < 0) {
537                 WDS_LOGE("Failed to get vconf value [%s]\n", VCONFKEY_WIFI_DIRECT_STATE);
538                 __WDS_LOG_FUNC_EXIT__;
539                 return -1;
540         }
541
542         __WDS_LOG_FUNC_EXIT__;
543         return state;
544 }
545 #endif
546
547 int wfd_util_set_wifi_direct_state(int state)
548 {
549         __WDS_LOG_FUNC_ENTER__;
550         static int last_state = WIFI_DIRECT_STATE_DEACTIVATED;
551         int vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATED;
552         int res = 0;
553
554         if (state < WIFI_DIRECT_STATE_DEACTIVATED ||
555             state > WIFI_DIRECT_STATE_GROUP_OWNER) {
556                 WDS_LOGE("Invalid parameter");
557                 __WDS_LOG_FUNC_EXIT__;
558                 return -1;
559         }
560
561         if (last_state == state) {
562                 WDS_LOGD("No change in state, not updating vconf [%s]",
563                          VCONFKEY_WIFI_DIRECT_STATE);
564                 __WDS_LOG_FUNC_EXIT__;
565                 return 0;
566         }
567
568         if (state == WIFI_DIRECT_STATE_ACTIVATED)
569                 vconf_state = VCONFKEY_WIFI_DIRECT_ACTIVATED;
570         else if (state == WIFI_DIRECT_STATE_DEACTIVATED)
571                 vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATED;
572         else if (state == WIFI_DIRECT_STATE_CONNECTED)
573                 vconf_state = VCONFKEY_WIFI_DIRECT_CONNECTED;
574         else if (state == WIFI_DIRECT_STATE_GROUP_OWNER)
575                 vconf_state = VCONFKEY_WIFI_DIRECT_GROUP_OWNER;
576         else if (state == WIFI_DIRECT_STATE_DISCOVERING)
577                 vconf_state = VCONFKEY_WIFI_DIRECT_DISCOVERING;
578         else if (state == WIFI_DIRECT_STATE_DEACTIVATING)
579                 vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATING;
580         else if (state == WIFI_DIRECT_STATE_ACTIVATING)
581                 vconf_state = VCONFKEY_WIFI_DIRECT_ACTIVATING;
582         else if (state == WIFI_DIRECT_STATE_CONNECTING)
583                 vconf_state = VCONFKEY_WIFI_DIRECT_CONNECTING;
584         else if (state == WIFI_DIRECT_STATE_DISCONNECTING)
585                 vconf_state = VCONFKEY_WIFI_DIRECT_DISCONNECTING;
586         else {
587                 WDS_LOGE("This state cannot be set as wifi_direct vconf state[%d]", state);
588                 return 0;
589         }
590
591         WDS_LOGD("Vconf key set [%s: %d]", VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
592
593         res = vconf_set_int(VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
594         if (res < 0) {
595                 WDS_LOGE("Failed to set vconf [%s]", VCONFKEY_WIFI_DIRECT_STATE);
596                 __WDS_LOG_FUNC_EXIT__;
597                 return -1;
598         }
599
600         last_state = state;
601
602         __WDS_LOG_FUNC_EXIT__;
603         return 0;
604 }
605
606 int wfd_util_get_local_dev_mac(unsigned char *dev_mac)
607 {
608         __WDS_LOG_FUNC_ENTER__;
609         const char *file_path = DEFAULT_MAC_FILE_PATH;
610         FILE *fd = NULL;
611         char local_mac[MACSTR_LEN] = {0, };
612         char *ptr = NULL;
613         int res = 0;
614         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
615
616         errno = 0;
617         fd = fopen(file_path, "r");
618         if (!fd) {
619                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
620                 WDS_LOGE("Failed to open MAC info file [%s] (%s)", file_path , error_buf);
621                 __WDS_LOG_FUNC_EXIT__;
622                 return -1;
623         }
624
625         errno = 0;
626         ptr = fgets(local_mac, MACSTR_LEN, fd);
627         if (!ptr) {
628                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
629                 WDS_LOGE("Failed to read file or no data read(%s)", error_buf);
630                 fclose(fd);
631                 __WDS_LOG_FUNC_EXIT__;
632                 return -1;
633         }
634         WDS_SECLOGD("Local MAC address [%s]", ptr);
635
636         res = _txt_to_mac(local_mac, dev_mac);
637         if (res < 0) {
638                 WDS_LOGE("Failed to convert text to MAC address");
639                 fclose(fd);
640                 __WDS_LOG_FUNC_EXIT__;
641                 return -1;
642         }
643
644         WDS_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(dev_mac));
645
646         fclose(fd);
647         __WDS_LOG_FUNC_EXIT__;
648         return 0;
649 }
650
651 #ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
652 int wfd_util_start_wifi_direct_popup()
653 {
654         __WDS_LOG_FUNC_ENTER__;
655
656         uid_t uid = 0;
657         int ret = 0;
658         ret = __wfd_util_find_login_user(&uid);
659         if (ret < 0) {
660                 WDS_LOGE("__wfd_util_find_login_user Failed !");
661                 return -1;
662         }
663
664         if (AUL_R_OK != aul_launch_app_for_uid(
665                 "org.tizen.wifi-direct-popup", NULL, uid)) {
666                 WDS_LOGE("aul_launch_for_uid Failed !");
667                 return -1;
668         }
669
670         WDS_LOGD("Succeeded to launch wifi-direct-popup");
671         __WDS_LOG_FUNC_EXIT__;
672         return 0;
673 }
674
675 int wfd_util_stop_wifi_direct_popup()
676 {
677         __WDS_LOG_FUNC_ENTER__;
678
679         uid_t uid = 0;
680         int ret = 0;
681         ret = __wfd_util_find_login_user(&uid);
682         if (ret < 0) {
683                 WDS_LOGE("__wfd_util_find_login_user Failed !");
684                 return -1;
685         }
686
687         int pid = aul_app_get_pid_for_uid("org.tizen.wifi-direct-popup", uid);
688         if (pid > 0) {
689                 if (aul_terminate_pid_for_uid(pid, uid) != AUL_R_OK) {
690                         WDS_LOGD("Failed to destroy wifi-direct-popup pid[%d]", pid);
691                         return -1;
692                 } else {
693                         WDS_LOGD("Succeeded to destroy wifi-direct-popup");
694                 }
695         } else {
696                 WDS_LOGD("Wifi-direct-popup not running");
697         }
698
699         __WDS_LOG_FUNC_EXIT__;
700         return 0;
701 }
702 #endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
703
704 int _connect_remote_device(char *ip_str)
705 {
706         int sock;
707         int flags;
708         int res = 0;
709         struct sockaddr_in remo_addr;
710         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
711
712         errno = 0;
713         sock = socket(PF_INET, SOCK_STREAM, 0);
714         if (sock == -1) {
715                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
716                 WDS_LOGE("Failed to create socket to remote device(%s)", error_buf);
717                 return -1;
718         }
719
720         flags = fcntl(sock, F_GETFL, 0);
721         res = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
722         if (res < 0) {
723                 WDS_LOGE("File descriptor create failed");
724                 close(sock);
725                 __WDS_LOG_FUNC_EXIT__;
726                 return -1;
727         }
728
729         memset(&remo_addr, 0x0, sizeof(remo_addr));
730         remo_addr.sin_family = AF_INET;
731         remo_addr.sin_addr.s_addr = inet_addr(ip_str);
732         remo_addr.sin_port = htons(9999);
733
734         errno = 0;
735         res = connect(sock, (struct sockaddr*) &remo_addr, sizeof(remo_addr));
736         if (res < 0) {
737                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
738                 WDS_LOGE("Failed to connect to server socket [%s]", error_buf);
739                 close(sock);
740                 __WDS_LOG_FUNC_EXIT__;
741                 return -1;
742         }
743
744         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
745         WDS_SECLOGD("Status of connection to remote device[%s] - (%s)", ip_str, error_buf);
746
747         close(sock);
748
749         return 0;
750 }
751
752 static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
753 {
754         __WDS_LOG_FUNC_ENTER__;
755         wfd_device_s *peer = (wfd_device_s*) data;
756         FILE *fp = NULL;
757         char buf[MAX_DHCP_DUMP_SIZE];
758         char ip_str[IPSTR_LEN] = {0, };
759         char intf_str[MACSTR_LEN];
760         unsigned char intf_addr[MACADDR_LEN];
761         char peer_mac_address[MACSTR_LEN+1] = {0,};
762         char assigned_ip_address[IPSTR_LEN+1] = {0,};
763         int n = 0;
764         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
765
766         if (!peer) {
767                 WDS_LOGD("Invalid parameter");
768                 return;
769         }
770         WDS_LOGD("DHCP server: IP leased");
771
772         errno = 0;
773         fp = fopen(DHCP_DUMP_FILE, "r");
774         if (NULL == fp) {
775                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
776                 WDS_LOGE("Could not read the file(%s). [%s]", DHCP_DUMP_FILE, error_buf);
777                 return;
778         }
779
780         while (fgets(buf, MAX_DHCP_DUMP_SIZE, fp) != NULL) {
781                 WDS_LOGD("Read line [%s]", buf);
782                 n = sscanf(buf, "%17s %15s", intf_str, ip_str);
783                 WDS_LOGD("ip=[%s], mac=[%s]", ip_str, intf_str);
784                 if (n != 2)
785                         continue;
786
787                 _txt_to_mac(intf_str, intf_addr);
788                 if (!memcmp(peer->intf_addr, intf_addr, MACADDR_LEN)) {
789                         WDS_LOGD("Peer intf mac found");
790                         _txt_to_ip(ip_str, peer->ip_addr);
791                         _connect_remote_device(ip_str);
792                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
793                         g_snprintf(assigned_ip_address, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
794                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
795                                                      "PeerIPAssigned",
796                                                      g_variant_new("(ss)", peer_mac_address,
797                                                                            assigned_ip_address));
798                         break;
799                 } else {
800                         WDS_LOGD("Different interface address peer[" MACSECSTR "] vs dhcp[" MACSECSTR "]",
801                                                 MAC2SECSTR(peer->intf_addr), MAC2SECSTR(intf_addr));
802                 }
803         }
804         fclose(fp);
805
806         vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
807         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
808
809         __WDS_LOG_FUNC_EXIT__;
810         return;
811 }
812
813 static gboolean _polling_ip(gpointer user_data)
814 {
815         __WDS_LOG_FUNC_ENTER__;
816         wfd_manager_s *manager = wfd_get_manager();
817         wfd_device_s *local = (wfd_device_s*) manager->local;
818         wfd_device_s *peer = (wfd_device_s*) user_data;
819         char *ifname = NULL;
820         char ip_str[IPSTR_LEN] = {0, };
821         static int count = 0;
822         int res = 0;
823
824         if (!peer) {
825                 WDS_LOGE("peer data is not exists");
826                 return FALSE;
827         }
828
829         res = wfd_manager_get_goup_ifname(&ifname);
830         if (res < 0 || !ifname) {
831                 WDS_LOGE("Failed to get group interface name");
832                 return FALSE;
833         }
834
835         if (count > 28) {
836                 WDS_LOGE("Failed to get IP");
837                 count = 0;
838                 wfd_oem_destroy_group(manager->oem_ops, ifname);
839                 __WDS_LOG_FUNC_EXIT__;
840                 return FALSE;
841         }
842         res = wfd_util_local_get_ip(ifname, local->ip_addr, 0);
843         if (res < 0) {
844                 WDS_LOGE("Failed to get local IP for interface %s(count=%d)", ifname, count++);
845                 __WDS_LOG_FUNC_EXIT__;
846                 return TRUE;
847         }
848         WDS_LOGD("Succeeded to get local(client) IP [" IPSECSTR "] for iface[%s]",
849                                     IP2SECSTR(local->ip_addr), ifname);
850
851         res = wfd_util_dhcpc_get_server_ip(peer->ip_addr);
852         if (res < 0) {
853                 WDS_LOGE("Failed to get peer(server) IP(count=%d)", count++);
854                 __WDS_LOG_FUNC_EXIT__;
855                 return TRUE;
856         }
857         WDS_LOGD("Succeeded to get server IP [" IPSECSTR "]", IP2SECSTR(peer->ip_addr));
858         count = 0;
859
860         g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
861         _connect_remote_device(ip_str);
862
863         char peer_mac_address[MACSTR_LEN+1] = {0, };
864
865         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
866         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
867                                      "Connection",
868                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
869                                                             WFD_EVENT_CONNECTION_RSP,
870                                                             peer_mac_address));
871
872 #if defined(TIZEN_FEATURE_ASP)
873         wfd_session_s *session = manager->session;
874         if (session && !ISZEROMACADDR(session->session_mac))
875                 wfd_asp_connect_status(session->session_mac,
876                                                         session->session_id,
877                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
878                                                         NULL);
879 #endif
880
881         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
882         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
883         wfd_destroy_session(manager);
884
885         __WDS_LOG_FUNC_EXIT__;
886         return FALSE;
887 }
888
889 int wfd_util_dhcps_start(char *ifname)
890 {
891         __WDS_LOG_FUNC_ENTER__;
892         gboolean rv = FALSE;
893         char *const iface = ifname;
894         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
895         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "server", iface, NULL };
896         char *const envs[] = { NULL };
897         wfd_manager_s *manager = wfd_get_manager();
898
899         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
900
901         rv = wfd_util_execute_file(path, args, envs);
902
903         if (rv != TRUE) {
904                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh server");
905                 return -1;
906         }
907
908         /*
909          * As we are GO so IP should be updated
910          * before sending Group Created Event
911          */
912         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_IFNAME, GROUP_IFNAME);
913         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_LOCAL_IP, "192.168.49.1");
914         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_SUBNET_MASK, "255.255.255.0");
915         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_GATEWAY, "192.168.49.1");
916
917         WDS_LOGD("Successfully started wifi-direct-dhcp.sh server");
918
919         _txt_to_ip(TIZEN_P2P_GO_IPADDR, manager->local->ip_addr);
920
921         __WDS_LOG_FUNC_EXIT__;
922         return 0;
923 }
924
925 int wfd_util_dhcps_wait_ip_leased(wfd_device_s *peer)
926 {
927         __WDS_LOG_FUNC_ENTER__;
928
929         if (!peer) {
930                 WDS_LOGE("Invalid parameter");
931                 return -1;
932         }
933
934         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
935         vconf_notify_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb, peer);
936
937         __WDS_LOG_FUNC_EXIT__;
938         return 0;
939 }
940
941 int wfd_util_dhcps_stop(char *ifname)
942 {
943         __WDS_LOG_FUNC_ENTER__;
944         gboolean rv = FALSE;
945         char *const iface = ifname;
946         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
947         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", iface, NULL };
948         char *const envs[] = { NULL };
949
950         vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
951         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
952
953         rv = wfd_util_execute_file(path, args, envs);
954
955         if (rv != TRUE) {
956                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
957                 return -1;
958         }
959         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
960
961         __WDS_LOG_FUNC_EXIT__;
962         return 0;
963 }
964
965 int wfd_util_dhcpc_start(char *ifname, wfd_device_s *peer)
966 {
967         __WDS_LOG_FUNC_ENTER__;
968         gboolean rv = FALSE;
969         char *const iface = ifname;
970         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
971         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "client", iface, NULL };
972         char *const envs[] = { NULL };
973
974         if (!peer) {
975                 WDS_LOGE("Invalid parameter");
976                 return -1;
977         }
978
979         rv = wfd_util_execute_file(path, args, envs);
980         if (rv != TRUE) {
981                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh client");
982                 return -1;
983         }
984         WDS_LOGD("Successfully started wifi-direct-dhcp.sh client");
985
986         g_timeout_add(250, (GSourceFunc) _polling_ip, peer);
987
988         __WDS_LOG_FUNC_EXIT__;
989         return 0;
990 }
991
992 int wfd_util_dhcpc_stop(char *ifname)
993 {
994         __WDS_LOG_FUNC_ENTER__;
995         gboolean rv = FALSE;
996         char *const iface = ifname;
997         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
998         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", iface, NULL };
999         char *const envs[] = { NULL };
1000
1001         rv = wfd_util_execute_file(path, args, envs);
1002
1003         if (rv != TRUE) {
1004                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
1005                 return -1;
1006         }
1007         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
1008
1009         __WDS_LOG_FUNC_EXIT__;
1010         return 0;
1011 }
1012
1013 int wfd_util_local_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6)
1014 {
1015         __WDS_LOG_FUNC_ENTER__;
1016         struct ifreq ifr;
1017         struct sockaddr_in *sin = NULL;
1018         char *ip_str = NULL;
1019         int sock = -1;
1020         int res = -1;
1021         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1022
1023         if (!ifname || !ip_addr) {
1024                 WDS_LOGE("Invalid parameter");
1025                 __WDS_LOG_FUNC_EXIT__;
1026                 return -1;
1027         }
1028
1029         errno = 0;
1030         sock = socket(AF_INET, SOCK_DGRAM, 0);
1031         if (sock < SOCK_FD_MIN) {
1032                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1033                 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1034                 if (sock >= 0)
1035                         close(sock);
1036                 __WDS_LOG_FUNC_EXIT__;
1037                 return -1;
1038         }
1039
1040         ifr.ifr_addr.sa_family = AF_INET;
1041         memset(ifr.ifr_name, 0x00, IFNAMSIZ);
1042         g_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
1043
1044         errno = 0;
1045         res = ioctl(sock, SIOCGIFADDR, &ifr);
1046         if (res < 0) {
1047                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1048                 WDS_LOGE("Failed to get IP from socket. [%s]", error_buf);
1049                 close(sock);
1050                 __WDS_LOG_FUNC_EXIT__;
1051                 return -1;
1052         }
1053         close(sock);
1054
1055         sin = (struct sockaddr_in*) &ifr.ifr_broadaddr;
1056         ip_str = inet_ntoa(sin->sin_addr);
1057         _txt_to_ip(ip_str, ip_addr);
1058         __WDS_LOG_FUNC_EXIT__;
1059         return 0;
1060 }
1061
1062 int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr)
1063 {
1064         __WDS_LOG_FUNC_ENTER__;
1065         char* get_str = NULL;
1066         int count = 0;
1067
1068         if (!ip_addr) {
1069                 WDS_LOGE("Invalid parameter");
1070                 __WDS_LOG_FUNC_EXIT__;
1071                 return -1;
1072         }
1073
1074         while (count < 10) {
1075                 get_str = vconf_get_str(VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1076                 if (!get_str) {
1077                         WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1078                         __WDS_LOG_FUNC_EXIT__;
1079                         return -1;
1080                 }
1081
1082                 if (strcmp(get_str, ZEROIP) == 0) {
1083                         WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1084                         g_free(get_str);
1085                         __WDS_LOG_FUNC_EXIT__;
1086                         return -1;
1087                 }
1088
1089                 WDS_LOGD("VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP(%s) : %s\n", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP, get_str);
1090                 _txt_to_ip(get_str, ip_addr);
1091                 g_free(get_str);
1092                 if (*ip_addr)
1093                         break;
1094                 count++;
1095         }
1096
1097         __WDS_LOG_FUNC_EXIT__;
1098         return 0;
1099 }
1100
1101 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
1102 static int _wfd_util_set_vconf_for_static_ip(const char *ifname, char *static_ip)
1103 {
1104         __WDS_LOG_FUNC_ENTER__;
1105
1106         if (!ifname || !static_ip)
1107                 return -1;
1108
1109         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_IFNAME, ifname);
1110         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_LOCAL_IP, static_ip);
1111         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_SUBNET_MASK, "255.255.255.0");
1112         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_GATEWAY, "192.168.49.1");
1113
1114         __WDS_LOG_FUNC_EXIT__;
1115
1116         return 0;
1117 }
1118
1119
1120 static int _wfd_util_static_ip_set(const char *ifname, unsigned char *static_ip)
1121 {
1122         __WDS_LOG_FUNC_ENTER__;
1123         int res = 0;
1124         unsigned char ip_addr[IPADDR_LEN];
1125         char ip_str[IPSTR_LEN] = {0, };
1126
1127         int if_index;
1128         int nl_sock = -1;
1129         struct sockaddr_nl dst_addr;
1130
1131         struct {
1132                 struct nlmsghdr     nh;
1133                 struct ifaddrmsg    ifa;
1134                 char            attrbuf[1024];
1135         } req;
1136         struct rtattr *rta;
1137         struct iovec iov;
1138         struct msghdr nl_msg;
1139
1140         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1141
1142         if (!ifname || !static_ip) {
1143                 WDS_LOGE("Invalid parameter");
1144                 __WDS_LOG_FUNC_EXIT__;
1145                 return -1;
1146         }
1147
1148         /* Get index of interface */
1149         if_index = if_nametoindex(ifname);
1150         if (if_index < 0) {
1151                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1152                 WDS_LOGE("Failed to get interface index. [%s]", error_buf);
1153                 __WDS_LOG_FUNC_EXIT__;
1154                 return -1;
1155         }
1156
1157         WDS_LOGD("Creating a Netlink Socket");
1158         nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1159         if (nl_sock < 0) {
1160                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1161                 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1162                 __WDS_LOG_FUNC_EXIT__;
1163                 return -1;
1164         }
1165
1166         memset(&dst_addr, 0, sizeof(dst_addr));
1167         dst_addr.nl_family =  AF_NETLINK;
1168         dst_addr.nl_pid = 0;
1169
1170         memset(&req, 0, sizeof(req));
1171         req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1172         req.nh.nlmsg_type = RTM_NEWADDR;
1173         req.nh.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL | NLM_F_REQUEST;
1174
1175         req.ifa.ifa_family = AF_INET;
1176         req.ifa.ifa_prefixlen = 24;
1177         req.ifa.ifa_flags = IFA_F_PERMANENT;
1178         req.ifa.ifa_scope = 0;
1179         req.ifa.ifa_index = if_index;
1180
1181         rta = (struct rtattr *)(req.attrbuf);
1182         rta->rta_type = IFA_LOCAL;
1183         rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1184         memcpy(RTA_DATA(rta), static_ip, IPADDR_LEN);
1185         req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
1186
1187         rta = (struct rtattr *)(req.attrbuf + rta->rta_len);
1188         rta->rta_type = IFA_BROADCAST;
1189         rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1190         memcpy(ip_addr, static_ip, IPADDR_LEN);
1191         ip_addr[3] = 0xff;
1192         memcpy(RTA_DATA(rta), ip_addr, IPADDR_LEN);
1193         req.nh.nlmsg_len += rta->rta_len;
1194
1195         memset(&iov, 0, sizeof(iov));
1196         iov.iov_base = &req;
1197         iov.iov_len = req.nh.nlmsg_len;
1198
1199         memset(&nl_msg, 0, sizeof(nl_msg));
1200         nl_msg.msg_name = (void *)&dst_addr;
1201         nl_msg.msg_namelen = sizeof(dst_addr);
1202         nl_msg.msg_iov = &iov;
1203         nl_msg.msg_iovlen = 1;
1204
1205         res = sendmsg(nl_sock, &nl_msg, 0);
1206         if (res < 0) {
1207                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1208                 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1209         } else {
1210                 WDS_LOGD("Succed to sendmsg. [%d]", res);
1211         }
1212
1213         close(nl_sock);
1214         WDS_LOGE("Succeeded to set local(client) IP [" IPSTR "] for iface[%s]",
1215                                 IP2STR(static_ip), ifname);
1216
1217         snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(static_ip));
1218         _wfd_util_set_vconf_for_static_ip(ifname, ip_str);
1219
1220         __WDS_LOG_FUNC_EXIT__;
1221         return res;
1222 }
1223
1224 int wfd_util_ip_over_eap_assign(wfd_device_s *peer, const char *ifname)
1225 {
1226         __WDS_LOG_FUNC_ENTER__;
1227         wfd_manager_s *manager = wfd_get_manager();
1228         wfd_device_s *local = (wfd_device_s*) manager->local;
1229
1230         char ip_str[IPSTR_LEN] = {0, };
1231
1232         if (!peer) {
1233                 WDS_LOGE("Invalid paramater");
1234                 return -1;
1235         }
1236
1237         _wfd_util_static_ip_set(ifname, peer->client_ip_addr);
1238         memcpy(peer->ip_addr, peer->go_ip_addr, IPADDR_LEN);
1239         memcpy(local->ip_addr, peer->client_ip_addr, IPADDR_LEN);
1240
1241         g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1242         _connect_remote_device(ip_str);
1243
1244         __WDS_LOG_FUNC_EXIT__;
1245         return 0;
1246 }
1247 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
1248
1249 int wfd_util_ip_unset(const char *ifname)
1250 {
1251         __WDS_LOG_FUNC_ENTER__;
1252         int res = 0;
1253         unsigned char ip_addr[IPADDR_LEN];
1254         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1255
1256         int if_index;
1257         int nl_sock = -1;
1258         struct sockaddr_nl dst_addr;
1259
1260         struct {
1261                 struct nlmsghdr     nh;
1262                 struct ifaddrmsg    ifa;
1263                 char            attrbuf[1024];
1264         } req;
1265         struct rtattr *rta;
1266         struct iovec iov;
1267         struct msghdr nl_msg;
1268
1269         if (!ifname) {
1270                 WDS_LOGE("Invalid parameter");
1271                 __WDS_LOG_FUNC_EXIT__;
1272                 return -1;
1273         }
1274
1275         res = wfd_util_local_get_ip((char *)ifname, ip_addr, 0);
1276         if (res < 0) {
1277                 WDS_LOGE("Failed to get local IP for interface %s", ifname);
1278                 __WDS_LOG_FUNC_EXIT__;
1279                 return -1;
1280         }
1281         WDS_LOGE("Succeeded to get local(client) IP [" IPSTR "] for iface[%s]",
1282                         IP2STR(ip_addr), ifname);
1283
1284         if_index = if_nametoindex(ifname);
1285         if (if_index < 0) {
1286                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1287                 WDS_LOGE("Failed to get interface index. [%s]", error_buf);
1288                 __WDS_LOG_FUNC_EXIT__;
1289                 return -1;
1290         }
1291
1292         WDS_LOGD("Creating a Netlink Socket");
1293         nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1294         if (nl_sock < 0) {
1295                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1296                 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1297                 __WDS_LOG_FUNC_EXIT__;
1298                 return -1;
1299         }
1300
1301         WDS_LOGD("Set dst socket address to kernel");
1302         memset(&dst_addr, 0, sizeof(dst_addr));
1303         dst_addr.nl_family =  AF_NETLINK;
1304         dst_addr.nl_pid = 0;
1305
1306         memset(&req, 0, sizeof(req));
1307         req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1308         req.nh.nlmsg_type = RTM_DELADDR;
1309         req.nh.nlmsg_flags = NLM_F_REQUEST;
1310
1311         req.ifa.ifa_family = AF_INET;
1312         req.ifa.ifa_prefixlen = 32;
1313         req.ifa.ifa_flags = IFA_F_PERMANENT;
1314         req.ifa.ifa_scope = 0;
1315         req.ifa.ifa_index = if_index;
1316
1317         rta = (struct rtattr *)(req.attrbuf);
1318         rta->rta_type = IFA_LOCAL;
1319         rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1320         memcpy(RTA_DATA(rta), ip_addr, IPADDR_LEN);
1321         req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
1322
1323         memset(&iov, 0, sizeof(iov));
1324         iov.iov_base = &req;
1325         iov.iov_len = req.nh.nlmsg_len;
1326
1327         memset(&nl_msg, 0, sizeof(nl_msg));
1328         nl_msg.msg_name = (void *)&dst_addr;
1329         nl_msg.msg_namelen = sizeof(dst_addr);
1330         nl_msg.msg_iov = &iov;
1331         nl_msg.msg_iovlen = 1;
1332
1333         res = sendmsg(nl_sock, &nl_msg, 0);
1334         if (res < 0) {
1335                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1336                 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1337         } else {
1338                 WDS_LOGD("Succeed to sendmsg. [%d]", res);
1339         }
1340
1341         close(nl_sock);
1342
1343         __WDS_LOG_FUNC_EXIT__;
1344         return res;
1345 }
1346
1347 gboolean wfd_util_is_remove_group_allowed(void)
1348 {
1349         wfd_manager_s *manager = wfd_get_manager();
1350
1351         if (!manager->auto_group_remove_enable)
1352                 return FALSE;
1353
1354         return TRUE;
1355 }