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