Remove UI Dependency for headless devices
[platform/core/connectivity/net-config.git] / src / utils / util.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 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 #include <dlfcn.h>
21 #include <errno.h>
22 #include <vconf.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <net/if.h>
28 #include <net/route.h>
29 #include <arpa/inet.h>
30 #include <sys/wait.h>
31 #include <sys/stat.h>
32 #include <sys/ioctl.h>
33 #include <vconf-keys.h>
34 #include <tzplatform_config.h>
35 #include <system_info.h>
36
37 #include "log.h"
38 #include "util.h"
39 #include "neterror.h"
40 #include "wifi-state.h"
41 #include "netdbus.h"
42
43 #define DBUS_SERVICE_DBUS               "org.freedesktop.DBus"
44 #define DBUS_INTERFACE_DBUS             "org.freedesktop.DBus"
45 #define MAC_INFO_FILEPATH               tzplatform_mkpath(TZ_SYS_ETC, "/.mac.info")
46 #define MAC_ADDRESS_FILEPATH    "/sys/class/net/wlan0/address"
47 #define MAC_ADDRESS_MAX_LEN             18
48 #define HEADED_PLUGIN_FILEPATH          "/usr/lib/net-config-plugin-headed.so"
49
50 static gboolean netconfig_device_picker_test = FALSE;
51 static int mdnsd_ref_count = 0;
52 typedef struct {
53         char *conn_name;
54         int conn_id;
55 } dnssd_conn_destroy_data;
56
57 static gboolean netconfig_plugin_headed_enabled = FALSE;
58 static void *handle_headed;
59 static struct netconfig_headed_plugin_t *headed_plugin;
60
61 GKeyFile *netconfig_keyfile_load(const char *pathname)
62 {
63         GKeyFile *keyfile = NULL;
64         GError *error = NULL;
65
66         keyfile = g_key_file_new();
67         if (g_key_file_load_from_file(keyfile, pathname, 0, &error) != TRUE) {
68                 DBG("Unable to open %s, error %s", pathname, error->message);
69                 g_error_free(error);
70
71                 g_key_file_free(keyfile);
72                 keyfile = NULL;
73         }
74
75         DBG("loaded keyfile %s", pathname);
76         return keyfile;
77 }
78
79 void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname)
80 {
81         gsize size = 0;
82         GError *error = NULL;
83         gchar *keydata = NULL;
84         gchar *needle = NULL, *directory = NULL;
85
86         directory = g_strdup(pathname);
87         needle = g_strrstr(directory, "/");
88
89         if (needle != NULL)
90                 *needle = '\0';
91
92         if (directory == NULL || (*directory) == '\0') {
93                 g_free(directory);
94                 ERR("directory is NULL");
95                 return;
96         }
97
98         if (g_file_test(directory, G_FILE_TEST_IS_DIR) != TRUE) {
99                 if (g_mkdir_with_parents(directory,
100                                 S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
101                         g_free(directory);
102                         ERR("failed to make directory");
103                         return;
104                 }
105         }
106         g_free(directory);
107
108         keydata = g_key_file_to_data(keyfile, &size, &error);
109         if (g_file_set_contents(pathname, keydata, size, &error) != TRUE) {
110                 ERR("Unable to save %s, error %s", pathname, error->message);
111                 g_error_free(error);
112         }
113
114         chmod(pathname, S_IRUSR | S_IWUSR);
115         DBG("Successfully saved keyfile %s", pathname);
116
117         g_free(keydata);
118 }
119
120 void netconfig_start_timer_seconds(guint secs,
121                 gboolean(*callback) (gpointer), void *user_data, guint *timer_id)
122 {
123         guint t_id = 0;
124
125         if (callback == NULL) {
126                 ERR("callback function is NULL");
127                 return;
128         }
129
130         if ((timer_id != NULL && *timer_id != 0)) {
131                 ERR("timer already is registered");
132                 return;
133         }
134
135         t_id = g_timeout_add_seconds(secs, callback, user_data);
136
137         if (t_id == 0) {
138                 ERR("Can't add timer");
139                 return;
140         }
141
142         if (timer_id != NULL)
143                 *timer_id = t_id;
144 }
145
146 void netconfig_start_timer(guint msecs,
147                 gboolean(*callback) (gpointer), void *user_data, guint *timer_id)
148 {
149         guint t_id = 0;
150
151         INFO("Register timer with callback pointer (%p)", callback);
152
153         if (callback == NULL) {
154                 ERR("callback function is NULL");
155                 return;
156         }
157
158         if ((timer_id != NULL && *timer_id != 0)) {
159                 ERR("timer already is registered");
160                 return;
161         }
162
163         t_id = g_timeout_add(msecs, callback, user_data);
164
165         if (t_id == 0) {
166                 ERR("Can't add timer");
167                 return;
168         }
169
170         if (timer_id != NULL)
171                 *timer_id = t_id;
172 }
173
174 void netconfig_stop_timer(guint *timer_id)
175 {
176         if (timer_id == NULL) {
177                 ERR("timer is NULL");
178                 return;
179         }
180
181         if (*timer_id != 0) {
182                 g_source_remove(*timer_id);
183                 *timer_id = 0;
184         }
185 }
186
187 static gboolean __netconfig_test_device_picker()
188 {
189         char *favorite_wifi_service = NULL;
190
191         favorite_wifi_service = wifi_get_favorite_service();
192         if (favorite_wifi_service != NULL) {
193                 ERR("favorite_wifi_service is existed[%s] : Donot launch device picker", favorite_wifi_service);
194                 g_free(favorite_wifi_service);
195                 return FALSE;
196         }
197
198         return TRUE;
199 }
200
201 static void __netconfig_pop_device_picker(void)
202 {
203         if (!netconfig_plugin_headed_enabled)
204                 return;
205
206         if (!headed_plugin)
207                 return;
208
209         headed_plugin->pop_device_picker();
210 }
211
212 static gboolean __netconfig_wifi_try_device_picker(gpointer data)
213 {
214         if (__netconfig_test_device_picker() == TRUE)
215                 __netconfig_pop_device_picker();
216
217         return FALSE;
218 }
219
220 static guint __netconfig_wifi_device_picker_timer_id(gboolean is_set_method, guint timer_id)
221 {
222         static guint netconfig_wifi_device_picker_service_timer = 0;
223
224         if (is_set_method != TRUE)
225                 return netconfig_wifi_device_picker_service_timer;
226
227         if (netconfig_wifi_device_picker_service_timer != timer_id)
228                 netconfig_wifi_device_picker_service_timer = timer_id;
229
230         return netconfig_wifi_device_picker_service_timer;
231 }
232
233 static void __netconfig_wifi_device_picker_set_timer_id(guint timer_id)
234 {
235         __netconfig_wifi_device_picker_timer_id(TRUE, timer_id);
236 }
237
238 static guint __netconfig_wifi_device_picker_get_timer_id(void)
239 {
240         return __netconfig_wifi_device_picker_timer_id(FALSE, -1);
241 }
242
243 void netconfig_wifi_enable_device_picker_test(void)
244 {
245         netconfig_device_picker_test = TRUE;
246 }
247
248 void netconfig_wifi_device_picker_service_start(void)
249 {
250         const int NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL = 700;
251         guint timer_id = 0;
252
253         if (netconfig_device_picker_test == TRUE)
254                 netconfig_device_picker_test = FALSE;
255         else
256                 return;
257
258         int wifi_ug_state;
259
260         netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state);
261         if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
262                 return;
263
264         DBG("Register device picker timer with %d milliseconds", NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL);
265         netconfig_start_timer(NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL, __netconfig_wifi_try_device_picker, NULL, &timer_id);
266
267         __netconfig_wifi_device_picker_set_timer_id(timer_id);
268 }
269
270 void netconfig_wifi_device_picker_service_stop(void)
271 {
272         guint timer_id = 0;
273
274         timer_id = __netconfig_wifi_device_picker_get_timer_id();
275         if (timer_id == 0)
276                 return;
277
278         DBG("Clear device picker timer with timer_id %d", timer_id);
279
280         netconfig_stop_timer(&timer_id);
281
282         __netconfig_wifi_device_picker_set_timer_id(timer_id);
283 }
284
285 gboolean netconfig_is_wifi_direct_on(void)
286 {
287 #if defined TIZEN_P2P_ENABLE
288         int wifi_direct_state = 0;
289
290         netconfig_vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state);
291
292         DBG("Wi-Fi direct mode %d", wifi_direct_state);
293         return (wifi_direct_state != 0) ? TRUE : FALSE;
294 #else
295         return FALSE;
296 #endif
297 }
298
299 gboolean netconfig_is_wifi_tethering_on(void)
300 {
301 #if defined TIZEN_TETHERING_ENABLE
302         int wifi_tethering_state = 0;
303
304         netconfig_vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &wifi_tethering_state);
305         DBG("Wi-Ti tethering mode %d", wifi_tethering_state);
306         if ((wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)
307                 || (wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP)) {
308                 DBG("Mobile AP is on");
309                 return TRUE;
310         }
311 #endif
312         DBG("Mobile AP is off");
313         return FALSE;
314 }
315
316 gboolean netconfig_interface_up(const char *ifname)
317 {
318         int fd;
319         struct ifreq ifr;
320
321         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
322         if (fd < 0)
323                 return FALSE;
324
325         memset(&ifr, 0, sizeof(ifr));
326         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
327
328         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
329                 close(fd);
330                 return FALSE;
331         }
332
333         ifr.ifr_flags |= (IFF_UP | IFF_DYNAMIC);
334         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
335                 close(fd);
336                 return FALSE;
337         }
338
339         close(fd);
340
341         DBG("Successfully activated wireless interface %s", ifname);
342         return TRUE;
343 }
344
345 gboolean netconfig_interface_down(const char *ifname)
346 {
347         int fd;
348         struct ifreq ifr;
349
350         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
351         if (fd < 0)
352                 return FALSE;
353
354         memset(&ifr, 0, sizeof(ifr));
355         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
356
357         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
358                 close(fd);
359                 return FALSE;
360         }
361
362         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
363         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
364                 close(fd);
365                 return FALSE;
366         }
367
368         close(fd);
369
370         DBG("Successfully de-activated wireless interface %s", ifname);
371         return TRUE;
372 }
373
374 int netconfig_execute_file(const char *file_path,
375                 char *const args[], char *const envs[])
376 {
377         pid_t pid = 0;
378         int status = 0;
379         int rv = 0;
380         errno = 0;
381         register unsigned int index = 0;
382         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
383
384         while (args[index] != NULL) {
385                 DBG("%s", args[index]);
386                 index++;
387         }
388
389         if (!(pid = fork())) {
390                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
391                 DBG("Inside child, exec (%s) command", file_path);
392
393                 errno = 0;
394                 if (execve(file_path, args, envs) == -1) {
395                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
396                         DBG("Fail to execute command (%s)", error_buf);
397                         exit(1);
398                 }
399         } else if (pid > 0) {
400                 if (waitpid(pid, &status, 0) == -1)
401                         DBG("wait pid (%u) status (%d)", pid, status);
402
403                 if (WIFEXITED(status)) {
404                         rv = WEXITSTATUS(status);
405                         DBG("exited, status=%d", rv);
406                 } else if (WIFSIGNALED(status)) {
407                         DBG("killed by signal %d", WTERMSIG(status));
408                 } else if (WIFSTOPPED(status)) {
409                         DBG("stopped by signal %d", WSTOPSIG(status));
410                 } else if (WIFCONTINUED(status)) {
411                         DBG("continued");
412                 }
413
414                 return rv;
415         }
416
417         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
418         DBG("failed to fork(%s)", error_buf);
419         return -EIO;
420 }
421
422 static void on_clat_handler()
423 {
424         pid_t clat_pid = 0;
425         int state = 0;
426
427         clat_pid = waitpid(-1, &state, WNOHANG);
428
429         DBG("clat(%d) state(%d)", clat_pid, WEXITSTATUS(state));
430 }
431
432 int netconfig_execute_clatd(const char *file_path, char *const args[])
433 {
434         pid_t pid = 0;
435         int rv = 0;
436         errno = 0;
437         register unsigned int index = 0;
438         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
439
440         struct sigaction act;
441         int state = 0;
442
443         act.sa_handler = on_clat_handler;
444         sigemptyset(&act.sa_mask);
445         act.sa_flags = 0;
446
447         state = sigaction(SIGCHLD, &act, 0);
448         if (state != 0) {
449                 DBG("sigaction() : %d");
450                 return -1;
451         }
452
453         while (args[index] != NULL) {
454                 DBG("%s", args[index]);
455                 index++;
456         }
457
458         if (!(pid = fork())) {
459                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
460                 DBG("Inside child, exec (%s) command", file_path);
461
462                 errno = 0;
463                 if (execvp(file_path, args) == -1) {
464                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
465                         ERR("Fail to execute command (%s)", error_buf);
466                         return -1;
467                 }
468         } else if (pid > 0) {
469                 ERR("Success to launch clatd");
470                 return rv;
471         }
472
473         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
474         DBG("failed to fork(%s)", error_buf);
475         return -EIO;
476 }
477
478 int __netconfig_get_interface_index(const char *interface_name)
479 {
480         struct ifreq ifr;
481         int sock = 0;
482         int result = 0;
483         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
484
485         if (interface_name == NULL) {
486                 DBG("Inteface name is NULL");
487                 return -1;
488         }
489
490         errno = 0;
491         sock = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
492         if (sock < 0) {
493                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
494                 DBG("Failed to create socket : %s", error_buf);
495                 return -1;
496         }
497
498         memset(&ifr, 0, sizeof(ifr));
499         strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1);
500         result = ioctl(sock, SIOCGIFINDEX, &ifr);
501         close(sock);
502
503         if (result < 0) {
504                 DBG("Failed to get ifr index: %s", error_buf);
505                 return -1;
506         }
507
508         return ifr.ifr_ifindex;
509 }
510
511 int netconfig_add_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family)
512 {
513         struct ifreq ifr;
514         struct rtentry rt;
515         struct sockaddr_in addr_in;
516         int sock;
517         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
518
519         memset(&ifr, 0, sizeof(ifr));
520
521         ifr.ifr_ifindex = __netconfig_get_interface_index(interface);
522
523         if (ifr.ifr_ifindex < 0)
524                 return -1;
525
526         strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
527
528         memset(&rt, 0, sizeof(rt));
529
530         rt.rt_flags = RTF_UP | RTF_HOST;
531         memset(&addr_in, 0, sizeof(struct sockaddr_in));
532         addr_in.sin_family = address_family;
533         addr_in.sin_addr.s_addr = inet_addr(ip_addr);
534         memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst));
535
536         memset(&addr_in, 0, sizeof(struct sockaddr_in));
537         addr_in.sin_family = address_family;
538         addr_in.sin_addr.s_addr = INADDR_ANY;
539         memcpy(&rt.rt_gateway, &addr_in, sizeof(rt.rt_gateway));
540
541         memset(&addr_in, 0, sizeof(struct sockaddr_in));
542         addr_in.sin_family = AF_INET;
543         addr_in.sin_addr.s_addr = inet_addr(subnet);
544         memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask));
545
546         rt.rt_dev = ifr.ifr_name;
547
548         errno = 0;
549         sock = socket(PF_INET, SOCK_DGRAM, 0);
550
551         if (sock < 0) {
552                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
553                 DBG("Failed to create socket : %s", error_buf);
554                 return -1;
555         }
556
557         if (ioctl(sock, SIOCADDRT, &rt) < 0) {
558                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
559                 DBG("Failed to set route address : %s", error_buf);
560                 close(sock);
561                 return -1;
562         }
563
564         close(sock);
565
566         return 1;
567 }
568
569 int netconfig_del_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family)
570 {
571         struct ifreq ifr;
572         struct rtentry rt;
573         struct sockaddr_in addr_in;
574         int sock;
575         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
576
577         memset(&ifr, 0, sizeof(ifr));
578         ifr.ifr_ifindex = __netconfig_get_interface_index(interface);
579
580         if (ifr.ifr_ifindex < 0)
581                 return -1;
582
583         strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
584
585         memset(&rt, 0, sizeof(rt));
586
587         rt.rt_flags = RTF_UP;
588         memset(&addr_in, 0, sizeof(struct sockaddr_in));
589         addr_in.sin_family = address_family;
590         addr_in.sin_addr.s_addr = inet_addr(ip_addr);
591         memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst));
592
593         memset(&addr_in, 0, sizeof(struct sockaddr_in));
594         addr_in.sin_family = address_family;
595         addr_in.sin_addr.s_addr = inet_addr(subnet);
596         memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask));
597         rt.rt_dev = ifr.ifr_name;
598
599         errno = 0;
600         sock = socket(PF_INET, SOCK_DGRAM, 0);
601
602         if (sock < 0) {
603                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
604                 DBG("Failed to create socket : %s", error_buf);
605                 return -1;
606         }
607
608         if (ioctl(sock, SIOCDELRT, &rt) < 0) {
609                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
610                 DBG("Failed to set route address : %s", error_buf);
611                 close(sock);
612                 return -1;
613         }
614
615         close(sock);
616
617         return 1;
618 }
619
620 int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len)
621 {
622         struct in6_rtmsg rt;
623         int fd = 0;
624         int err = 0;
625         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
626
627         memset(&rt, 0, sizeof(rt));
628
629         rt.rtmsg_dst_len = prefix_len;
630
631         rt.rtmsg_flags = RTF_UP | RTF_HOST;
632
633         errno = 0;
634         if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) {
635                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
636                 DBG("inet_pton failed : %s", error_buf);
637                 return -1;
638         }
639
640         if (gateway != NULL) {
641                 rt.rtmsg_flags |= RTF_GATEWAY;
642                 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
643                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
644                         DBG("inet_pton failed : %s", error_buf);
645                         return -1;
646                 }
647         }
648
649         rt.rtmsg_metric = 1;
650
651         fd = socket(AF_INET6, SOCK_DGRAM, 0);
652         if (fd < 0) {
653                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
654                 DBG("Failed to create socket : %s", error_buf);
655                 return -1;
656         }
657
658         rt.rtmsg_ifindex = 0;
659
660         if (interface) {
661                 struct ifreq ifr;
662                 memset(&ifr, 0, sizeof(ifr));
663                 strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1);
664                 ioctl(fd, SIOCGIFINDEX, &ifr);
665                 rt.rtmsg_ifindex = ifr.ifr_ifindex;
666         }
667
668         if ((err = ioctl(fd, SIOCADDRT, &rt)) < 0) {
669                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
670                 DBG("Failed to add route: %s", error_buf);
671                 close(fd);
672                 return -1;
673         }
674
675         close(fd);
676
677         return 1;
678 }
679
680 int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len)
681 {
682         struct in6_rtmsg rt;
683         int fd = 0;
684         int err = 0;
685
686         memset(&rt, 0, sizeof(rt));
687
688         rt.rtmsg_dst_len = prefix_len;
689
690         rt.rtmsg_flags = RTF_UP | RTF_HOST;
691
692         if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) {
693                 err = -errno;
694                 return err;
695         }
696
697         if (gateway != NULL) {
698                 rt.rtmsg_flags |= RTF_GATEWAY;
699                 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
700                         err = -errno;
701                         return err;
702                 }
703         }
704
705         rt.rtmsg_metric = 1;
706
707         fd = socket(AF_INET6, SOCK_DGRAM, 0);
708         if (fd < 0)
709                 return -1;
710
711         rt.rtmsg_ifindex = 0;
712
713         if (interface) {
714                 struct ifreq ifr;
715                 memset(&ifr, 0, sizeof(ifr));
716                 strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1);
717                 ioctl(fd, SIOCGIFINDEX, &ifr);
718                 rt.rtmsg_ifindex = ifr.ifr_ifindex;
719         }
720
721         if ((err = ioctl(fd, SIOCDELRT, &rt)) < 0) {
722                 DBG("Failed to del route: %d\n", err);
723                 close(fd);
724                 return -1;
725         }
726
727         close(fd);
728
729         return 1;
730 }
731
732 gboolean handle_launch_direct(Wifi *wifi, GDBusMethodInvocation *context)
733 {
734 #if defined TIZEN_P2P_ENABLE
735         int ret = 0;
736         DBG("Launch Wi-Fi direct daemon");
737
738         const char *path = "/usr/bin/wifi-direct-server.sh";
739         char *const args[] = { "wifi-direct-server.sh", "start", NULL };
740         char *const envs[] = { NULL };
741
742         ret = netconfig_execute_file(path, args, envs);
743         if (ret < 0) {
744                 ERR("Failed to launch Wi-Fi direct daemon");
745                 netconfig_error_wifi_direct_failed(context);
746                 return FALSE;
747         }
748
749         wifi_complete_launch_direct(wifi, context);
750         return TRUE;
751 #else
752         wifi_complete_launch_direct(wifi, context);
753         return FALSE;
754 #endif
755 }
756
757 int execute_mdnsd_script(char* op)
758 {
759         const char *path = "/usr/bin/mdnsresponder-server.sh";
760         char *const args[] = { "mdnsresponder-server.sh", op, NULL };
761         char *const envs[] = { NULL };
762
763         return netconfig_execute_file(path, args, envs);
764 }
765
766 static void __dnssd_conn_destroyed_cb(GDBusConnection *conn,
767                 const gchar *Name, const gchar *path, const gchar *interface,
768                 const gchar *sig, GVariant *param, gpointer user_data)
769 {
770         gchar *name = NULL;
771         gchar *old = NULL;
772         gchar *new = NULL;
773         dnssd_conn_destroy_data *data = user_data;
774         GDBusConnection *connection = NULL;
775         connection = netdbus_get_connection();
776
777         if (param == NULL)
778                 return;
779
780         g_variant_get(param, "(sss)", &name, &old, &new);
781
782         if (g_strcmp0(name, data->conn_name) == 0 && *new == '\0') {
783                 DBG("Connection %s Destroyed: name %s id %d", data->conn_name, name,
784                         data->conn_id);
785                 mdnsd_ref_count--;
786                 g_dbus_connection_signal_unsubscribe(connection, data->conn_id);
787                 if (mdnsd_ref_count == 0) {
788                         if (execute_mdnsd_script("stop") < 0)
789                                 ERR("Failed to stop mdnsresponder daemon");
790                 }
791         }
792         g_free(name);
793         g_free(old);
794         g_free(new);
795         g_free(data->conn_name);
796         g_free(data);
797         return;
798 }
799
800 static void register_dnssd_conn_destroy_signal(gchar *name)
801 {
802         dnssd_conn_destroy_data *data;
803         GDBusConnection *connection = NULL;
804         connection = netdbus_get_connection();
805
806         if (connection == NULL) {
807                 ERR("Failed to get GDbus Connection");
808                 return;
809         }
810
811         data = g_try_malloc0(sizeof(dnssd_conn_destroy_data));
812         data->conn_name = g_strdup(name);
813
814         data->conn_id = g_dbus_connection_signal_subscribe(connection,
815                                                         DBUS_SERVICE_DBUS, DBUS_INTERFACE_DBUS,
816                                                         "NameOwnerChanged", NULL, name,
817                                                         G_DBUS_SIGNAL_FLAGS_NONE, __dnssd_conn_destroyed_cb,
818                                                         data, NULL);
819         return;
820 }
821
822 gboolean handle_launch_mdns(Network *object, GDBusMethodInvocation *context,
823                                                         gchar *name)
824 {
825         DBG("Launch mdnsresponder daemon");
826
827         if (execute_mdnsd_script("start") < 0) {
828                 ERR("Failed to launch mdnsresponder daemon");
829                 netconfig_error_invalid_parameter(context);
830                 return FALSE;
831         }
832
833         mdnsd_ref_count++;
834         register_dnssd_conn_destroy_signal(name);
835         DBG("Ref mdnsresponder daemon. ref count: %d", mdnsd_ref_count);
836
837         network_complete_launch_mdns(object, context);
838         return TRUE;
839 }
840
841 gboolean netconfig_send_notification_to_net_popup(const char * noti, const char * ssid)
842 {
843         if (!netconfig_plugin_headed_enabled)
844                 return FALSE;
845
846         if (!headed_plugin)
847                 return FALSE;
848
849         return headed_plugin->send_notification_to_net_popup(noti, ssid);
850 }
851
852 int netconfig_send_message_to_net_popup(const char *title,
853                 const char *content, const char *type, const char *ssid)
854 {
855         if (!netconfig_plugin_headed_enabled)
856                 return 0;
857
858         if (!headed_plugin)
859                 return 0;
860
861         return headed_plugin->send_message_to_net_popup(title, content, type, ssid);
862 }
863
864 int netconfig_send_restriction_to_net_popup(const char *title,
865                 const char *type, const char *restriction)
866 {
867         if (!netconfig_plugin_headed_enabled)
868                 return 0;
869
870         if (!headed_plugin)
871                 return 0;
872
873         return headed_plugin->send_restriction_to_net_popup(title, type, restriction);
874 }
875
876 void netconfig_set_system_event(int sys_evt, int evt_key, int evt_val)
877 {
878         if (!netconfig_plugin_headed_enabled)
879                 return;
880
881         if (!headed_plugin)
882                 return;
883
884         headed_plugin->set_system_event(sys_evt, evt_key, evt_val);
885 }
886
887 void __netconfig_pop_wifi_connected_poppup(const char *ssid)
888 {
889         if (!netconfig_plugin_headed_enabled)
890                 return;
891
892         if (!headed_plugin)
893                 return;
894
895         headed_plugin->pop_wifi_connected_poppup(ssid);
896 }
897
898 void netconfig_set_vconf_int(const char * key, int value)
899 {
900         int ret = 0;
901
902         DBG("[%s: %d]", key, value);
903
904         ret = vconf_set_int(key, value);
905         if (ret != VCONF_OK)
906                 ERR("Failed to set");
907 }
908
909 void netconfig_set_vconf_str(const char * key, const char * value)
910 {
911         int ret = 0;
912
913         DBG("[%s: %s]", key, value);
914
915         ret = vconf_set_str(key, value);
916         if (ret != VCONF_OK)
917                 ERR("Failed to set");
918 }
919
920 int netconfig_vconf_get_int(const char * key, int *value)
921 {
922         int ret = 0;
923
924         ret = vconf_get_int(key, value);
925         if (ret != VCONF_OK) {
926                 ERR("Failed to get vconfkey [%s] value", key);
927                 return -1;
928         }
929
930         return 0;
931 }
932
933 int netconfig_vconf_get_bool(const char * key, int *value)
934 {
935         int ret = 0;
936
937         ret = vconf_get_bool(key, value);
938         if (ret != VCONF_OK) {
939                 ERR("Failed to get vconfkey [%s] value", key);
940                 return -1;
941         }
942
943         return 0;
944 }
945
946 char* netconfig_get_env(const char *key)
947 {
948         FILE *fp;
949         char buf[256], *entry = NULL, *value = NULL, *last;
950         int len = 0;
951
952         if (!key)
953                 return NULL;
954
955         fp = fopen(NETCONFIG_TIZEN_SYSTEM_ENV, "r");
956         if (!fp)
957                 return NULL;
958
959         while (fgets(buf, sizeof(buf), fp)) {
960                 entry = buf;
961                 entry = strtok_r(entry, "=", &last);
962                 if (entry) {
963                         if (strstr(entry, key)) {
964                                 entry = strtok_r(NULL, "\n", &last);
965                                 if (entry) {
966                                         len = strlen(entry);
967                                         value = (char*)malloc(len+1);
968                                         g_strlcpy(value, entry, len+1);
969                                 } else {
970                                         value = (char*)malloc(sizeof(char));
971                                         g_strlcpy(value, "\n", sizeof(char));
972                                 }
973                                 break;
974                         }
975                 }
976         }
977
978         fclose(fp);
979         return value;
980 }
981
982 void netconfig_set_mac_address_from_file(void)
983 {
984         FILE *file = NULL;
985         char mac_str[MAC_ADDRESS_MAX_LEN];
986         gchar *mac_lower_str = NULL;
987         int mac_len = 0;
988
989         file = fopen(MAC_INFO_FILEPATH, "r");
990         if (file == NULL) {
991                 ERR("Fail to open %s", MAC_INFO_FILEPATH);
992                 file = fopen(MAC_ADDRESS_FILEPATH, "r");
993                 if (file == NULL) {
994                         ERR("Fail to open %s", MAC_ADDRESS_FILEPATH);
995                         return;
996                 }
997         }
998         if (fgets(mac_str, sizeof(mac_str), file) == NULL) {
999                 ERR("Fail to read mac address");
1000                 fclose(file);
1001                 return;
1002         }
1003
1004         mac_len = strlen(mac_str);
1005         if (mac_len < 17) {
1006                 ERR("mac.info is empty");
1007                 fclose(file);
1008                 return;
1009         }
1010
1011         mac_lower_str = g_ascii_strup(mac_str, (gssize)mac_len);
1012         netconfig_set_vconf_str(VCONFKEY_WIFI_BSSID_ADDRESS, mac_lower_str);
1013
1014         g_free(mac_lower_str);
1015         fclose(file);
1016 }
1017
1018 tizen_profile_t _get_tizen_profile()
1019 {
1020         static tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
1021         if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
1022                 return profile;
1023
1024         char *profileName;
1025         system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
1026         switch (*profileName) {
1027         case 'm':
1028         case 'M':
1029                 profile = TIZEN_PROFILE_MOBILE;
1030                 break;
1031         case 'w':
1032         case 'W':
1033                 profile = TIZEN_PROFILE_WEARABLE;
1034                 break;
1035         case 't':
1036         case 'T':
1037                 profile = TIZEN_PROFILE_TV;
1038                 break;
1039         case 'i':
1040         case 'I':
1041                 profile = TIZEN_PROFILE_IVI;
1042                 break;
1043         default: // common or unknown ==> ALL ARE COMMON.
1044                 profile = TIZEN_PROFILE_COMMON;
1045         }
1046         free(profileName);
1047
1048         return profile;
1049 }
1050
1051 void netconfig_plugin_init()
1052 {
1053         handle_headed = dlopen(HEADED_PLUGIN_FILEPATH, RTLD_NOW);
1054         if (!handle_headed) {
1055                 ERR("Can't load %s: %s", HEADED_PLUGIN_FILEPATH, dlerror());
1056                 return;
1057         }
1058
1059         headed_plugin = dlsym(handle_headed, "netconfig_headed_plugin");
1060         if (!headed_plugin) {
1061                 ERR("Can't load symbol: %s", dlerror());
1062                 dlclose(handle_headed);
1063                 return;
1064         }
1065
1066         netconfig_plugin_headed_enabled = TRUE;
1067 }
1068
1069 void netconfig_plugin_deinit()
1070 {
1071         if (!netconfig_plugin_headed_enabled)
1072                 return;
1073
1074         netconfig_plugin_headed_enabled = FALSE;
1075         dlclose(handle_headed);
1076 }
1077
1078 gboolean netconfig_get_headed_plugin_flag()
1079 {
1080         return netconfig_plugin_headed_enabled;
1081 }
1082