Add multi interfaces function
[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 <linux/limits.h>
34 #include <ctype.h>
35 #include <vconf-keys.h>
36 #include <tzplatform_config.h>
37 #include <system_info.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <dirent.h>
41 #include <time.h>
42
43 #include "log.h"
44 #include "util.h"
45 #include "neterror.h"
46 #include "wifi-state.h"
47 #include "netdbus.h"
48
49 #define DBUS_SERVICE_DBUS               "org.freedesktop.DBus"
50 #define DBUS_INTERFACE_DBUS             "org.freedesktop.DBus"
51 #define MAC_INFO_FILEPATH               tzplatform_mkpath(TZ_SYS_ETC, "/.mac.info")
52 #define MAC_ADDRESS_FILEPATH    "/sys/class/net/wlan0/address"
53 #define HEADED_PLUGIN_FILEPATH          "/usr/lib/net-config-plugin-headed.so"
54 #define TELEPHONY_PLUGIN_FILEPATH       "/usr/lib/net-config-plugin-telephony.so"
55 #define STC_PLUGIN_FILEPATH             "/usr/lib/net-config-plugin-stc.so"
56 #define BATTERY_PLUGIN_FILEPATH     "/usr/lib/net-config-plugin-battery.so"
57
58 static gboolean netconfig_device_picker_test = FALSE;
59 static int mdnsd_ref_count = 0;
60 typedef struct {
61         char *conn_name;
62         int conn_id;
63 } dnssd_conn_destroy_data;
64
65 static gboolean netconfig_plugin_headed_enabled = FALSE;
66 static gboolean netconfig_plugin_telephony_enabled = FALSE;
67 static gboolean netconfig_plugin_stc_enabled = FALSE;
68 static gboolean netconfig_plugin_battery_enabled = FALSE;
69 static void *handle_headed;
70 static void *handle_telephony;
71 static void *handle_stc;
72 static void *handle_battery;
73 static struct netconfig_headed_plugin_t *headed_plugin;
74 static struct netconfig_telephony_plugin_t *telephony_plugin;
75 static struct netconfig_stc_plugin_t *stc_plugin;
76 static struct netconfig_battery_plugin_t *battery_plugin;
77
78 static bool is_feature_checked[NETCONFIG_SUPPORTED_FEATURE_MAX] = {0, };
79 static bool feature_supported[NETCONFIG_SUPPORTED_FEATURE_MAX] = {0, };
80
81 gboolean netconfig_check_mac_address(const char *service, const char *mac_address)
82 {
83         int service_index = 0;
84         int mac_index = 0;
85         const char *org = NULL;
86         const char *dst = NULL;
87         int i = 0;
88
89         if (g_str_has_prefix(service, "wifi_") == FALSE)
90                 return FALSE;
91
92         service_index = strlen("wifi_");
93         for (i = 0; i < 6; i++) {
94                 org = &service[service_index];
95                 dst = &mac_address[mac_index];
96
97                 if (g_ascii_strncasecmp(org, dst, 2) != 0)
98                         return FALSE;
99
100                 service_index += 2;
101                 mac_index += 3;
102         }
103
104         return TRUE;
105 }
106
107 gboolean netconfig_check_passphrase(const gchar *service, const char *passphrase)
108 {
109         gsize length;
110
111         if (!passphrase)
112                 return FALSE;
113
114         length = strlen(passphrase);
115
116         if (g_str_has_suffix(service, "psk") == TRUE) {
117                 if (length == 64) {
118                         for (int i = 0; i < 64; i++)
119                                 if (!isxdigit((unsigned char)passphrase[i]))
120                                         return FALSE;
121                 } else if (length < 8 || length > 63)
122                         return FALSE;
123         } else if (g_str_has_suffix(service, "wep") == TRUE) {
124                 if (length == 10 || length == 26) {
125                         for (int i = 0; i < length; i++)
126                                 if (!isxdigit((unsigned char)passphrase[i]))
127                                         return FALSE;
128                 } else if (length != 5 && length != 13)
129                         return FALSE;
130         }
131
132         return TRUE;
133 }
134
135 GKeyFile *netconfig_keyfile_load(const char *pathname)
136 {
137         GKeyFile *keyfile = NULL;
138         GError *error = NULL;
139
140         keyfile = g_key_file_new();
141         if (g_key_file_load_from_file(keyfile, pathname, 0, &error) != TRUE) {
142                 DBG("Unable to open %s, error %s", pathname, error->message);
143                 g_error_free(error);
144
145                 g_key_file_free(keyfile);
146                 keyfile = NULL;
147         }
148
149         DBG("loaded keyfile %s", pathname);
150         return keyfile;
151 }
152
153 void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname)
154 {
155         gsize size = 0;
156         GError *error = NULL;
157         gchar *keydata = NULL;
158         gchar *needle = NULL, *directory = NULL;
159
160         directory = g_strdup(pathname);
161         needle = g_strrstr(directory, "/");
162
163         if (needle != NULL)
164                 *needle = '\0';
165
166         if (directory == NULL || (*directory) == '\0') {
167                 g_free(directory);
168                 ERR("directory is NULL");
169                 return;
170         }
171
172         if (g_file_test(directory, G_FILE_TEST_IS_DIR) != TRUE) {
173                 if (g_mkdir_with_parents(directory,
174                                 S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
175                         g_free(directory);
176                         ERR("failed to make directory");
177                         return;
178                 }
179         }
180         g_free(directory);
181
182         keydata = g_key_file_to_data(keyfile, &size, &error);
183         if (g_file_set_contents(pathname, keydata, size, &error) != TRUE) {
184                 ERR("Unable to save %s, error %s", pathname, error->message);
185                 g_error_free(error);
186         }
187
188         if (chmod(pathname, S_IRUSR | S_IWUSR) < 0)
189                 DBG("Failed to change mode");
190         else
191                 DBG("Successfully saved keyfile %s", pathname);
192
193         g_free(keydata);
194 }
195
196 void netconfig_start_timer_seconds(guint secs,
197                 gboolean(*callback) (gpointer), void *user_data, guint *timer_id)
198 {
199         guint t_id = 0;
200
201         if (callback == NULL) {
202                 ERR("callback function is NULL");
203                 return;
204         }
205
206         if ((timer_id != NULL && *timer_id != 0)) {
207                 ERR("timer already is registered");
208                 return;
209         }
210
211         t_id = g_timeout_add_seconds(secs, callback, user_data);
212
213         if (t_id == 0) {
214                 ERR("Can't add timer");
215                 return;
216         }
217
218         if (timer_id != NULL)
219                 *timer_id = t_id;
220 }
221
222 void netconfig_start_timer(guint msecs,
223                 gboolean(*callback) (gpointer), void *user_data, guint *timer_id)
224 {
225         guint t_id = 0;
226
227         INFO("Register timer with callback pointer (%p)", callback);
228
229         if (callback == NULL) {
230                 ERR("callback function is NULL");
231                 return;
232         }
233
234         if ((timer_id != NULL && *timer_id != 0)) {
235                 ERR("timer already is registered");
236                 return;
237         }
238
239         t_id = g_timeout_add(msecs, callback, user_data);
240
241         if (t_id == 0) {
242                 ERR("Can't add timer");
243                 return;
244         }
245
246         if (timer_id != NULL)
247                 *timer_id = t_id;
248 }
249
250 void netconfig_stop_timer(guint *timer_id)
251 {
252         if (timer_id == NULL) {
253                 ERR("timer is NULL");
254                 return;
255         }
256
257         if (*timer_id != 0) {
258                 g_source_remove(*timer_id);
259                 *timer_id = 0;
260         }
261 }
262
263 static gboolean __netconfig_test_device_picker()
264 {
265         char *favorite_wifi_service = NULL;
266
267         favorite_wifi_service = wifi_get_favorite_service();
268         if (favorite_wifi_service != NULL) {
269                 ERR("favorite_wifi_service is existed[%s] : Donot launch device picker", favorite_wifi_service);
270                 g_free(favorite_wifi_service);
271                 return FALSE;
272         }
273
274         return TRUE;
275 }
276
277 static void __netconfig_pop_device_picker(void)
278 {
279         if (!netconfig_plugin_headed_enabled)
280                 return;
281
282         if (!headed_plugin)
283                 return;
284
285         headed_plugin->pop_device_picker();
286 }
287
288 static gboolean __netconfig_wifi_try_device_picker(gpointer data)
289 {
290         if (__netconfig_test_device_picker() == TRUE)
291                 __netconfig_pop_device_picker();
292
293         return FALSE;
294 }
295
296 static guint __netconfig_wifi_device_picker_timer_id(gboolean is_set_method, guint timer_id)
297 {
298         static guint netconfig_wifi_device_picker_service_timer = 0;
299
300         if (is_set_method != TRUE)
301                 return netconfig_wifi_device_picker_service_timer;
302
303         if (netconfig_wifi_device_picker_service_timer != timer_id)
304                 netconfig_wifi_device_picker_service_timer = timer_id;
305
306         return netconfig_wifi_device_picker_service_timer;
307 }
308
309 static void __netconfig_wifi_device_picker_set_timer_id(guint timer_id)
310 {
311         __netconfig_wifi_device_picker_timer_id(TRUE, timer_id);
312 }
313
314 static guint __netconfig_wifi_device_picker_get_timer_id(void)
315 {
316         return __netconfig_wifi_device_picker_timer_id(FALSE, -1);
317 }
318
319 void netconfig_wifi_enable_device_picker_test(void)
320 {
321         netconfig_device_picker_test = TRUE;
322 }
323
324 void netconfig_wifi_device_picker_service_start(void)
325 {
326         const int NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL = 700;
327         guint timer_id = 0;
328
329         if (netconfig_device_picker_test == TRUE)
330                 netconfig_device_picker_test = FALSE;
331         else
332                 return;
333
334         int wifi_ug_state;
335
336         netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state);
337         if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
338                 return;
339
340         DBG("Register device picker timer with %d milliseconds", NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL);
341         netconfig_start_timer(NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL, __netconfig_wifi_try_device_picker, NULL, &timer_id);
342
343         __netconfig_wifi_device_picker_set_timer_id(timer_id);
344 }
345
346 void netconfig_wifi_device_picker_service_stop(void)
347 {
348         guint timer_id = 0;
349
350         timer_id = __netconfig_wifi_device_picker_get_timer_id();
351         if (timer_id == 0)
352                 return;
353
354         DBG("Clear device picker timer with timer_id %d", timer_id);
355
356         netconfig_stop_timer(&timer_id);
357
358         __netconfig_wifi_device_picker_set_timer_id(timer_id);
359 }
360
361 gboolean netconfig_is_wifi_direct_on(void)
362 {
363         if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
364                 return FALSE;
365
366         int wifi_direct_state = 0;
367
368         netconfig_vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state);
369
370         DBG("Wi-Fi direct mode %d", wifi_direct_state);
371         return (wifi_direct_state != 0) ? TRUE : FALSE;
372 }
373
374 gboolean netconfig_is_wifi_tethering_on(void)
375 {
376         if (netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING)) {
377                 int wifi_tethering_state = 0;
378
379                 netconfig_vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &wifi_tethering_state);
380                 DBG("Wi-Ti tethering mode %d", wifi_tethering_state);
381                 if ((wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)
382                                 || (wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP)) {
383                         DBG("Mobile AP is on");
384                         return TRUE;
385                 }
386         }
387
388         DBG("Mobile AP is off");
389         return FALSE;
390 }
391
392 gboolean netconfig_interface_up(const char *ifname)
393 {
394         int fd;
395         struct ifreq ifr;
396
397         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
398         if (fd < 0) {
399                 ERR("socket failed %d", errno);
400                 return FALSE;
401         }
402
403         memset(&ifr, 0, sizeof(ifr));
404         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
405
406         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
407                 ERR("Fail to get IFFLAGS %d", errno);
408                 close(fd);
409                 return FALSE;
410         }
411
412         DBG("IFFLAGS: %x", ifr.ifr_flags);
413         ifr.ifr_flags |= (IFF_UP | IFF_DYNAMIC);
414         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
415                 ERR("Fail to set IFFLAGS %d", errno);
416                 close(fd);
417                 return FALSE;
418         }
419
420         close(fd);
421
422         DBG("Successfully activated wireless interface %s", ifname);
423         return TRUE;
424 }
425
426 gboolean netconfig_interface_down(const char *ifname)
427 {
428         int fd;
429         struct ifreq ifr;
430
431         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
432         if (fd < 0) {
433                 ERR("socket failed %d", errno);
434                 return FALSE;
435         }
436
437         memset(&ifr, 0, sizeof(ifr));
438         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
439
440         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
441                 ERR("Fail to get IFFLAGS %d", errno);
442                 close(fd);
443                 return FALSE;
444         }
445
446         DBG("IFFLAGS: %x", ifr.ifr_flags);
447         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
448         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
449                 ERR("Fail to set IFFLAGS %d", errno);
450                 close(fd);
451                 return FALSE;
452         }
453
454         close(fd);
455
456         DBG("Successfully de-activated wireless interface %s", ifname);
457         return TRUE;
458 }
459
460 int netconfig_execute_file(const char *file_path,
461                 char *const args[], char *const envs[])
462 {
463         pid_t pid = 0;
464         int status = 0;
465         int rv = 0;
466         errno = 0;
467         register unsigned int index = 0;
468         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
469
470         while (args[index] != NULL) {
471                 DBG("%s", args[index]);
472                 index++;
473         }
474
475         if (!(pid = fork())) {
476                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
477                 DBG("Inside child, exec (%s) command", file_path);
478
479                 errno = 0;
480                 if (execve(file_path, args, envs) == -1) {
481                         DBG("Fail to execute command (%s)",
482                                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
483                         exit(1);
484                 }
485         } else if (pid > 0) {
486                 if (waitpid(pid, &status, 0) == -1)
487                         DBG("wait pid (%u) status (%d)", pid, status);
488
489                 if (WIFEXITED(status)) {
490                         rv = WEXITSTATUS(status);
491                         DBG("exited, status=%d", rv);
492                 } else if (WIFSIGNALED(status)) {
493                         DBG("killed by signal %d", WTERMSIG(status));
494                 } else if (WIFSTOPPED(status)) {
495                         DBG("stopped by signal %d", WSTOPSIG(status));
496                 } else if (WIFCONTINUED(status)) {
497                         DBG("continued");
498                 }
499
500                 return rv;
501         }
502
503         DBG("failed to fork(%s)",
504                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
505         return -EIO;
506 }
507
508 int netconfig_execute_cmd(const char *cmd)
509 {
510         if (cmd == NULL)
511                 return -EIO;
512
513         pid_t pid = 0;
514         int status = 0;
515         int rv = 0;
516         errno = 0;
517         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
518         gchar **args = NULL;
519
520         DBG("command: %s", cmd);
521
522         args = g_strsplit_set(cmd, " ", -1);
523
524         if (!(pid = fork())) {
525                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
526
527                 errno = 0;
528                 if (execv(args[0], args) == -1) {
529                         DBG("Fail to execute command (%s)",
530                                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
531                         g_strfreev(args);
532                         exit(1);
533                 }
534         } else if (pid > 0) {
535                 if (waitpid(pid, &status, 0) == -1)
536                         DBG("wait pid (%u) status (%d)", pid, status);
537
538                 if (WIFEXITED(status)) {
539                         rv = WEXITSTATUS(status);
540                         DBG("exited, status=%d", rv);
541                 } else if (WIFSIGNALED(status)) {
542                         DBG("killed by signal %d", WTERMSIG(status));
543                 } else if (WIFSTOPPED(status)) {
544                         DBG("stopped by signal %d", WSTOPSIG(status));
545                 } else if (WIFCONTINUED(status)) {
546                         DBG("continued");
547                 }
548
549                 g_strfreev(args);
550                 return rv;
551         }
552
553         DBG("failed to fork(%s)",
554                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
555         g_strfreev(args);
556
557         return -EIO;
558 }
559
560 static void on_clat_handler()
561 {
562         pid_t clat_pid = 0;
563         int state = 0;
564
565         clat_pid = waitpid(-1, &state, WNOHANG);
566
567         DBG("clat(%d) state(%d)", clat_pid, WEXITSTATUS(state));
568 }
569
570 int netconfig_execute_clatd(const char *file_path, char *const args[])
571 {
572         pid_t pid = 0;
573         int rv = 0;
574         errno = 0;
575         register unsigned int index = 0;
576         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
577
578         struct sigaction act;
579         int state = 0;
580
581         act.sa_handler = on_clat_handler;
582         sigemptyset(&act.sa_mask);
583         act.sa_flags = 0;
584
585         state = sigaction(SIGCHLD, &act, 0);
586         if (state != 0) {
587                 DBG("sigaction() : %d", state);
588                 return -1;
589         }
590
591         while (args[index] != NULL) {
592                 DBG("%s", args[index]);
593                 index++;
594         }
595
596         if (!(pid = fork())) {
597                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
598                 DBG("Inside child, exec (%s) command", file_path);
599
600                 errno = 0;
601                 if (execvp(file_path, args) == -1) {
602                         ERR("Fail to execute command (%s)",
603                                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
604                         return -1;
605                 }
606         } else if (pid > 0) {
607                 ERR("Success to launch clatd");
608                 return rv;
609         }
610
611         DBG("failed to fork(%s)",
612                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
613         return -EIO;
614 }
615
616 static void no_wait_signal_handler()
617 {
618         pid_t child_pid = 0;
619         int state = 0;
620
621         child_pid = waitpid(-1, &state, WNOHANG);
622
623         DBG("child_id(%d) state(%d)", child_pid, WEXITSTATUS(state));
624 }
625
626 int netconfig_execute_file_no_wait(const char *file_path, char *const args[])
627 {
628         pid_t pid = 0;
629         int rv = 0;
630         errno = 0;
631         register unsigned int index = 0;
632
633         struct sigaction act;
634         int state = 0;
635         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
636
637         act.sa_handler = no_wait_signal_handler;
638         sigemptyset(&act.sa_mask);
639         act.sa_flags = 0;
640
641         state = sigaction(SIGCHLD, &act, 0);
642         if (state != 0) {
643                 DBG("sigaction() : %d", state);
644                 return -1;
645         }
646
647         while (args[index] != NULL) {
648                 DBG("%s", args[index]);
649                 index++;
650         }
651
652         if (!(pid = fork())) {
653                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
654                 DBG("Inside child, exec (%s) command", file_path);
655
656                 errno = 0;
657                 if (execvp(file_path, args) == -1) {
658                         ERR("Fail to execute command (%s)",
659                                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
660                         return -1;
661                 }
662         } else if (pid > 0) {
663                 ERR("Successfully launched child process");
664                 return rv;
665         }
666
667         DBG("failed to fork(%s)",
668                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
669         return -EIO;
670 }
671
672 int __netconfig_get_interface_index(const char *interface_name)
673 {
674         struct ifreq ifr;
675         int sock = 0;
676         int result = 0;
677         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
678
679         if (interface_name == NULL) {
680                 DBG("Inteface name is NULL");
681                 return -1;
682         }
683
684         errno = 0;
685         sock = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
686         if (sock < 0) {
687                 DBG("Failed to create socket : %s",
688                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
689                 return -1;
690         }
691
692         memset(&ifr, 0, sizeof(ifr));
693         strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1);
694         result = ioctl(sock, SIOCGIFINDEX, &ifr);
695         close(sock);
696
697         if (result < 0) {
698                 DBG("Failed to get ifr index: %s",
699                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
700                 return -1;
701         }
702
703         return ifr.ifr_ifindex;
704 }
705
706 int netconfig_add_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family)
707 {
708         struct ifreq ifr;
709         struct rtentry rt;
710         struct sockaddr_in addr_in;
711         int sock;
712         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
713
714         memset(&ifr, 0, sizeof(ifr));
715
716         ifr.ifr_ifindex = __netconfig_get_interface_index(interface);
717
718         if (ifr.ifr_ifindex < 0)
719                 return -1;
720
721         strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
722
723         memset(&rt, 0, sizeof(rt));
724
725         rt.rt_flags = RTF_UP | RTF_HOST;
726         memset(&addr_in, 0, sizeof(struct sockaddr_in));
727         addr_in.sin_family = address_family;
728         addr_in.sin_addr.s_addr = inet_addr(ip_addr);
729         memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst));
730
731         memset(&addr_in, 0, sizeof(struct sockaddr_in));
732         addr_in.sin_family = address_family;
733         addr_in.sin_addr.s_addr = INADDR_ANY;
734         memcpy(&rt.rt_gateway, &addr_in, sizeof(rt.rt_gateway));
735
736         memset(&addr_in, 0, sizeof(struct sockaddr_in));
737         addr_in.sin_family = AF_INET;
738         addr_in.sin_addr.s_addr = inet_addr(subnet);
739         memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask));
740
741         rt.rt_dev = ifr.ifr_name;
742
743         errno = 0;
744         sock = socket(PF_INET, SOCK_DGRAM, 0);
745
746         if (sock < 0) {
747                 DBG("Failed to create socket : %s",
748                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
749                 return -1;
750         }
751
752         if (ioctl(sock, SIOCADDRT, &rt) < 0) {
753                 DBG("Failed to set route address : %s",
754                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
755                 close(sock);
756                 return -1;
757         }
758
759         close(sock);
760
761         return 1;
762 }
763
764 int netconfig_del_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family)
765 {
766         struct ifreq ifr;
767         struct rtentry rt;
768         struct sockaddr_in addr_in;
769         int sock;
770         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
771
772         memset(&ifr, 0, sizeof(ifr));
773         ifr.ifr_ifindex = __netconfig_get_interface_index(interface);
774
775         if (ifr.ifr_ifindex < 0)
776                 return -1;
777
778         strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
779
780         memset(&rt, 0, sizeof(rt));
781
782         rt.rt_flags = RTF_UP;
783         memset(&addr_in, 0, sizeof(struct sockaddr_in));
784         addr_in.sin_family = address_family;
785         addr_in.sin_addr.s_addr = inet_addr(ip_addr);
786         memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst));
787
788         memset(&addr_in, 0, sizeof(struct sockaddr_in));
789         addr_in.sin_family = address_family;
790         addr_in.sin_addr.s_addr = inet_addr(subnet);
791         memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask));
792         rt.rt_dev = ifr.ifr_name;
793
794         errno = 0;
795         sock = socket(PF_INET, SOCK_DGRAM, 0);
796
797         if (sock < 0) {
798                 DBG("Failed to create socket : %s",
799                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
800                 return -1;
801         }
802
803         if (ioctl(sock, SIOCDELRT, &rt) < 0) {
804                 DBG("Failed to set route address : %s",
805                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
806                 close(sock);
807                 return -1;
808         }
809
810         close(sock);
811
812         return 1;
813 }
814
815 int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len)
816 {
817         struct in6_rtmsg rt;
818         int fd = 0;
819         int err = 0;
820         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
821
822         memset(&rt, 0, sizeof(rt));
823
824         rt.rtmsg_dst_len = prefix_len;
825
826         rt.rtmsg_flags = RTF_UP | RTF_HOST;
827
828         errno = 0;
829         if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) {
830                 DBG("inet_pton failed : %s",
831                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
832                 return -1;
833         }
834
835         if (gateway != NULL) {
836                 rt.rtmsg_flags |= RTF_GATEWAY;
837                 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
838                         DBG("inet_pton failed : %s",
839                                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
840                         return -1;
841                 }
842         }
843
844         rt.rtmsg_metric = 1;
845
846         fd = socket(AF_INET6, SOCK_DGRAM, 0);
847         if (fd < 0) {
848                 DBG("Failed to create socket : %s",
849                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
850                 return -1;
851         }
852
853         rt.rtmsg_ifindex = 0;
854
855         if (interface) {
856                 struct ifreq ifr;
857                 memset(&ifr, 0, sizeof(ifr));
858                 strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1);
859                 ioctl(fd, SIOCGIFINDEX, &ifr);
860                 rt.rtmsg_ifindex = ifr.ifr_ifindex;
861         }
862
863         if ((err = ioctl(fd, SIOCADDRT, &rt)) < 0) {
864                 DBG("Failed to add route: %s",
865                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
866                 close(fd);
867                 return -1;
868         }
869
870         close(fd);
871
872         return 1;
873 }
874
875 int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len)
876 {
877         struct in6_rtmsg rt;
878         int fd = 0;
879         int err = 0;
880
881         memset(&rt, 0, sizeof(rt));
882
883         rt.rtmsg_dst_len = prefix_len;
884
885         rt.rtmsg_flags = RTF_UP | RTF_HOST;
886
887         if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) {
888                 err = -errno;
889                 return err;
890         }
891
892         if (gateway != NULL) {
893                 rt.rtmsg_flags |= RTF_GATEWAY;
894                 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
895                         err = -errno;
896                         return err;
897                 }
898         }
899
900         rt.rtmsg_metric = 1;
901
902         fd = socket(AF_INET6, SOCK_DGRAM, 0);
903         if (fd < 0)
904                 return -1;
905
906         rt.rtmsg_ifindex = 0;
907
908         if (interface) {
909                 struct ifreq ifr;
910                 memset(&ifr, 0, sizeof(ifr));
911                 strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1);
912                 ioctl(fd, SIOCGIFINDEX, &ifr);
913                 rt.rtmsg_ifindex = ifr.ifr_ifindex;
914         }
915
916         if ((err = ioctl(fd, SIOCDELRT, &rt)) < 0) {
917                 DBG("Failed to del route: %d\n", err);
918                 close(fd);
919                 return -1;
920         }
921
922         close(fd);
923
924         return 1;
925 }
926
927 gboolean handle_launch_direct(Wifi *wifi, GDBusMethodInvocation *context)
928 {
929         if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT)) {
930                 wifi_complete_launch_direct(wifi, context);
931                 return TRUE;
932         }
933
934         int ret = 0;
935         DBG("Launch Wi-Fi direct daemon");
936
937         const char *path = "/usr/bin/wifi-direct-server.sh";
938         char *const args[] = { "wifi-direct-server.sh", "start", NULL };
939         char *const envs[] = { NULL };
940
941         ret = netconfig_execute_file(path, args, envs);
942         if (ret < 0) {
943                 ERR("Failed to launch Wi-Fi direct daemon");
944                 netconfig_error_wifi_direct_failed(context);
945                 return TRUE;
946         }
947
948         wifi_complete_launch_direct(wifi, context);
949         return TRUE;
950 }
951
952 int execute_mdnsd_script(char* op)
953 {
954         const char *path = "/usr/bin/mdnsresponder-server.sh";
955         char *const args[] = { "mdnsresponder-server.sh", op, NULL };
956         char *const envs[] = { NULL };
957
958         return netconfig_execute_file(path, args, envs);
959 }
960
961 static void __dnssd_conn_destroyed_cb(GDBusConnection *conn,
962                 const gchar *Name, const gchar *path, const gchar *interface,
963                 const gchar *sig, GVariant *param, gpointer user_data)
964 {
965         gchar *name = NULL;
966         gchar *old = NULL;
967         gchar *new = NULL;
968         dnssd_conn_destroy_data *data = user_data;
969         GDBusConnection *connection = NULL;
970         connection = netdbus_get_connection();
971
972         if (param == NULL)
973                 return;
974
975         g_variant_get(param, "(sss)", &name, &old, &new);
976
977         if (g_strcmp0(name, data->conn_name) == 0 && *new == '\0') {
978                 DBG("Connection %s Destroyed: name %s id %d", data->conn_name, name,
979                         data->conn_id);
980                 mdnsd_ref_count--;
981                 g_dbus_connection_signal_unsubscribe(connection, data->conn_id);
982                 if (mdnsd_ref_count == 0) {
983                         if (execute_mdnsd_script("stop") < 0)
984                                 ERR("Failed to stop mdnsresponder daemon");
985                 }
986         }
987         g_free(name);
988         g_free(old);
989         g_free(new);
990         g_free(data->conn_name);
991         g_free(data);
992         return;
993 }
994
995 static void register_dnssd_conn_destroy_signal(gchar *name)
996 {
997         dnssd_conn_destroy_data *data;
998         GDBusConnection *connection = NULL;
999         connection = netdbus_get_connection();
1000
1001         if (connection == NULL) {
1002                 ERR("Failed to get GDbus Connection");
1003                 return;
1004         }
1005
1006         data = g_try_malloc0(sizeof(dnssd_conn_destroy_data));
1007
1008         if (data == NULL) {
1009                 ERR("Out of Memory!");
1010                 return;
1011         }
1012
1013         data->conn_name = g_strdup(name);
1014
1015         data->conn_id = g_dbus_connection_signal_subscribe(connection,
1016                                                         DBUS_SERVICE_DBUS, DBUS_INTERFACE_DBUS,
1017                                                         "NameOwnerChanged", NULL, name,
1018                                                         G_DBUS_SIGNAL_FLAGS_NONE, __dnssd_conn_destroyed_cb,
1019                                                         data, NULL);
1020         return;
1021 }
1022
1023 gboolean handle_launch_mdns(Network *object, GDBusMethodInvocation *context,
1024                                                         gchar *name)
1025 {
1026         DBG("Launch mdnsresponder daemon");
1027
1028         if (execute_mdnsd_script("start") < 0) {
1029                 ERR("Failed to launch mdnsresponder daemon");
1030                 netconfig_error_invalid_parameter(context);
1031                 return TRUE;
1032         }
1033
1034         mdnsd_ref_count++;
1035         register_dnssd_conn_destroy_signal(name);
1036         DBG("Ref mdnsresponder daemon. ref count: %d", mdnsd_ref_count);
1037
1038         network_complete_launch_mdns(object, context);
1039         return TRUE;
1040 }
1041
1042 gboolean netconfig_send_notification_to_net_popup(const char * noti, const char * ssid)
1043 {
1044         if (!netconfig_plugin_headed_enabled)
1045                 return FALSE;
1046
1047         if (!headed_plugin)
1048                 return FALSE;
1049
1050         return headed_plugin->send_notification_to_net_popup(noti, ssid);
1051 }
1052
1053 int netconfig_send_message_to_net_popup(const char *title,
1054                 const char *content, const char *type, const char *ssid)
1055 {
1056         if (!netconfig_plugin_headed_enabled)
1057                 return 0;
1058
1059         if (!headed_plugin)
1060                 return 0;
1061
1062         return headed_plugin->send_message_to_net_popup(title, content, type, ssid);
1063 }
1064
1065 int netconfig_send_restriction_to_net_popup(const char *title,
1066                 const char *type, const char *restriction)
1067 {
1068         if (!netconfig_plugin_headed_enabled)
1069                 return 0;
1070
1071         if (!headed_plugin)
1072                 return 0;
1073
1074         return headed_plugin->send_restriction_to_net_popup(title, type, restriction);
1075 }
1076
1077 void netconfig_set_system_event(int sys_evt, int evt_key, int evt_val)
1078 {
1079         if (!netconfig_plugin_headed_enabled)
1080                 return;
1081
1082         if (!headed_plugin)
1083                 return;
1084
1085         headed_plugin->set_system_event(sys_evt, evt_key, evt_val);
1086 }
1087
1088 void __netconfig_pop_wifi_connected_poppup(const char *ssid)
1089 {
1090         if (!netconfig_plugin_headed_enabled)
1091                 return;
1092
1093         if (!headed_plugin)
1094                 return;
1095
1096         headed_plugin->pop_wifi_connected_poppup(ssid);
1097 }
1098
1099 void netconfig_get_telephony_network_type(int *svctype, int *pstype)
1100 {
1101         if (!netconfig_plugin_telephony_enabled)
1102                 return;
1103
1104         if (!telephony_plugin)
1105                 return;
1106
1107         telephony_plugin->get_telephony_network_type(svctype, pstype);
1108 }
1109
1110 gboolean __netconfig_wifi_get_sim_imsi(Wifi *wifi, GDBusMethodInvocation *context)
1111 {
1112         if (!netconfig_plugin_telephony_enabled)
1113                 return FALSE;
1114
1115         if (!telephony_plugin)
1116                 return FALSE;
1117
1118         return telephony_plugin->wifi_get_sim_imsi(wifi, context);
1119 }
1120
1121 netconfig_error_e __netconfig_wifi_req_aka_auth(GArray *rand_data, GArray *autn_data,
1122                 GDBusMethodInvocation *context, struct wifi_authentication_data **data)
1123 {
1124         if (!netconfig_plugin_telephony_enabled)
1125                 return NETCONFIG_ERROR_INTERNAL;
1126
1127         if (!telephony_plugin)
1128                 return NETCONFIG_ERROR_INTERNAL;
1129
1130         return telephony_plugin->wifi_req_aka_auth(rand_data, autn_data, context, data);
1131 }
1132
1133 gboolean __netconfig_wifi_req_sim_auth(GArray *rand_data,
1134                 GDBusMethodInvocation *context, struct wifi_authentication_data **data)
1135 {
1136         if (!netconfig_plugin_telephony_enabled)
1137                 return FALSE;
1138
1139         if (!telephony_plugin)
1140                 return FALSE;
1141
1142         return telephony_plugin->wifi_req_sim_auth(rand_data, context, data);
1143 }
1144
1145 gboolean netconfig_tapi_check_sim_state(void)
1146 {
1147         if (!netconfig_plugin_telephony_enabled)
1148                 return FALSE;
1149
1150         if (!telephony_plugin)
1151                 return FALSE;
1152
1153         return telephony_plugin->tapi_check_sim_state();
1154 }
1155
1156 gboolean __netconfig_wifi_get_aka_authdata(Wifi *wifi,
1157                 GDBusMethodInvocation *context, struct wifi_authentication_data **data)
1158 {
1159         if (!netconfig_plugin_telephony_enabled)
1160                 return FALSE;
1161
1162         if (!telephony_plugin)
1163                 return FALSE;
1164
1165         return telephony_plugin->wifi_get_aka_authdata(wifi, context, data);
1166 }
1167
1168 gboolean __netconfig_wifi_get_sim_authdata(Wifi *wifi,
1169                 GDBusMethodInvocation *context, struct wifi_authentication_data **data)
1170 {
1171         if (!netconfig_plugin_telephony_enabled)
1172                 return FALSE;
1173
1174         if (!telephony_plugin)
1175                 return FALSE;
1176
1177         return telephony_plugin->wifi_get_sim_authdata(wifi, context, data);
1178 }
1179
1180 static void __netconfig_stc_get_dn_stats(time_t from, time_t to, GSList **list)
1181 {
1182         if (!netconfig_plugin_stc_enabled)
1183                 return;
1184
1185         if (!stc_plugin)
1186                 return;
1187
1188         return stc_plugin->get_stc_dn_stats(from, to, list);
1189 }
1190
1191 static void __netconfig_stc_get_wifi_stats(time_t from, time_t to, GSList **list)
1192 {
1193         if (!netconfig_plugin_stc_enabled)
1194                 return;
1195
1196         if (!stc_plugin)
1197                 return;
1198
1199         return stc_plugin->get_stc_wifi_stats(from, to, list);
1200 }
1201
1202 void netconfig_battery_start_dn(void)
1203 {
1204         if (!netconfig_plugin_battery_enabled)
1205                 return;
1206
1207         if (!battery_plugin)
1208                 return;
1209
1210         return battery_plugin->start_dn_data();
1211 }
1212
1213 void netconfig_battery_end_dn(void)
1214 {
1215         if (!netconfig_plugin_battery_enabled)
1216                 return;
1217
1218         if (!battery_plugin)
1219                 return;
1220
1221         return battery_plugin->end_dn_data(0, __netconfig_stc_get_dn_stats);
1222 }
1223
1224 void netconfig_battery_update_dn_rssi(int rssi)
1225 {
1226         if (!netconfig_plugin_battery_enabled)
1227                 return;
1228
1229         if (!battery_plugin)
1230                 return;
1231
1232         return battery_plugin->update_dn_rssi(rssi);
1233 }
1234
1235 void netconfig_battery_start_wifi(void)
1236 {
1237         if (!netconfig_plugin_battery_enabled)
1238                 return;
1239
1240         if (!battery_plugin)
1241                 return;
1242
1243         return battery_plugin->start_wifi_data();
1244 }
1245
1246 void netconfig_battery_end_wifi(void)
1247 {
1248         if (!netconfig_plugin_battery_enabled)
1249                 return;
1250
1251         if (!battery_plugin)
1252                 return;
1253
1254         return battery_plugin->end_wifi_data(0, __netconfig_stc_get_wifi_stats);
1255 }
1256
1257 void netconfig_battery_update_wifi_scan(int state)
1258 {
1259         if (!netconfig_plugin_battery_enabled)
1260                 return;
1261
1262         if (!battery_plugin)
1263                 return;
1264
1265         return battery_plugin->update_wifi_scan(state);
1266 }
1267
1268 void netconfig_battery_update_wifi_rssi(int rssi)
1269 {
1270         if (!netconfig_plugin_battery_enabled)
1271                 return;
1272
1273         if (!battery_plugin)
1274                 return;
1275
1276         return battery_plugin->update_wifi_rssi(rssi);
1277 }
1278
1279 void netconfig_battery_get_dn_list(void *data)
1280 {
1281         if (!netconfig_plugin_battery_enabled)
1282                 return;
1283
1284         if (!battery_plugin)
1285                 return;
1286
1287         return battery_plugin->get_battery_dn_list(data, __netconfig_stc_get_dn_stats);
1288 }
1289
1290 void netconfig_battery_get_wifi_list(void *data)
1291 {
1292         if (!netconfig_plugin_battery_enabled)
1293                 return;
1294
1295         if (!battery_plugin)
1296                 return;
1297
1298         return battery_plugin->get_battery_wifi_list(data, __netconfig_stc_get_wifi_stats);
1299 }
1300
1301 void netconfig_set_vconf_int(const char * key, int value)
1302 {
1303         int ret = 0;
1304
1305         if (g_strcmp0(key, VCONFKEY_WIFI_TRANSFER_STATE) != 0)
1306                 DBG("[%s: %d]", key, value);
1307
1308         ret = vconf_set_int(key, value);
1309         if (ret != VCONF_OK)
1310                 ERR("Failed to set");
1311 }
1312
1313 void netconfig_set_vconf_str(const char * key, const char * value)
1314 {
1315         int ret = 0;
1316
1317         DBG("[%s: %s]", key, value);
1318
1319         ret = vconf_set_str(key, value);
1320         if (ret != VCONF_OK)
1321                 ERR("Failed to set");
1322 }
1323
1324 int netconfig_vconf_get_int(const char * key, int *value)
1325 {
1326         int ret = 0;
1327
1328         ret = vconf_get_int(key, value);
1329         if (ret != VCONF_OK) {
1330                 ERR("Failed to get vconfkey [%s] value", key);
1331                 return -1;
1332         }
1333
1334         return 0;
1335 }
1336
1337 int netconfig_vconf_get_bool(const char * key, int *value)
1338 {
1339         int ret = 0;
1340
1341         ret = vconf_get_bool(key, value);
1342         if (ret != VCONF_OK) {
1343                 ERR("Failed to get vconfkey [%s] value", key);
1344                 return -1;
1345         }
1346
1347         return 0;
1348 }
1349
1350 char* netconfig_get_env(const char *key)
1351 {
1352         FILE *fp;
1353         char buf[256], *entry = NULL, *value = NULL, *last;
1354         int len = 0;
1355
1356         if (!key)
1357                 return NULL;
1358
1359         fp = fopen(NETCONFIG_TIZEN_SYSTEM_ENV, "r");
1360         if (!fp)
1361                 return NULL;
1362
1363         while (fgets(buf, sizeof(buf), fp)) {
1364                 entry = buf;
1365                 entry = strtok_r(entry, "=", &last);
1366                 if (entry) {
1367                         if (strstr(entry, key)) {
1368                                 entry = strtok_r(NULL, "\n", &last);
1369                                 if (entry) {
1370                                         len = strlen(entry);
1371                                         value = (char*)malloc(len+1);
1372                                         g_strlcpy(value, entry, len+1);
1373                                 } else {
1374                                         value = (char*)malloc(sizeof(char));
1375                                         g_strlcpy(value, "\n", sizeof(char));
1376                                 }
1377                                 break;
1378                         }
1379                 }
1380         }
1381
1382         fclose(fp);
1383         return value;
1384 }
1385
1386 void netconfig_set_mac_address_from_file(void)
1387 {
1388         FILE *file = NULL;
1389         char mac_str[MAC_ADDRESS_MAX_LEN];
1390         gchar *mac_lower_str = NULL;
1391         int mac_len = 0;
1392
1393         file = fopen(MAC_INFO_FILEPATH, "r");
1394         if (file == NULL) {
1395                 ERR("Fail to open %s", MAC_INFO_FILEPATH);
1396                 file = fopen(MAC_ADDRESS_FILEPATH, "r");
1397                 if (file == NULL) {
1398                         ERR("Fail to open %s", MAC_ADDRESS_FILEPATH);
1399                         return;
1400                 }
1401         }
1402         if (fgets(mac_str, sizeof(mac_str), file) == NULL) {
1403                 ERR("Fail to read mac address");
1404                 fclose(file);
1405                 return;
1406         }
1407
1408         mac_len = strlen(mac_str);
1409         if (mac_len < 17) {
1410                 ERR("mac.info is empty");
1411                 fclose(file);
1412                 return;
1413         }
1414
1415         mac_lower_str = g_ascii_strup(mac_str, (gssize)mac_len);
1416         netconfig_set_vconf_str(VCONFKEY_WIFI_BSSID_ADDRESS, mac_lower_str);
1417
1418         g_free(mac_lower_str);
1419         fclose(file);
1420 }
1421
1422 char *netconfig_get_mac_address_from_file(const char *ifname)
1423 {
1424         FILE *file = NULL;
1425         char file_path[PATH_MAX] = {0, };
1426         char mac_str[MAC_ADDRESS_MAX_LEN];
1427         int mac_len = 0;
1428
1429         if (!ifname)
1430                 return NULL;
1431
1432         g_snprintf(file_path, sizeof(file_path),
1433                         "/sys/class/net/%s/address", ifname);
1434
1435         DBG("ifname: %s", ifname);
1436         DBG("file_path: %s", file_path);
1437         file = fopen(file_path, "r");
1438         if (file == NULL) {
1439                 ERR("Fail to open %s", file_path);
1440                 return NULL;
1441         }
1442         if (fgets(mac_str, sizeof(mac_str), file) == NULL) {
1443                 ERR("Fail to read mac address");
1444                 fclose(file);
1445                 return NULL;
1446         }
1447
1448         mac_len = strlen(mac_str);
1449         if (mac_len < 17) {
1450                 ERR("mac is empty");
1451                 fclose(file);
1452                 return NULL;
1453         }
1454         DBG("address: %s", mac_str);
1455
1456         fclose(file);
1457         return g_strdup(mac_str);
1458 }
1459
1460 int netconfig_freq_to_channel(int freq)
1461 {
1462         if (freq < 2412 || freq > 5825 ||
1463                 (freq > 2484 && freq < 5180)) {
1464                 ERR("Invalid Frequence Range");
1465                 return 0;
1466         }
1467         if (freq >= 5180)
1468                 return 36 + (freq - 5180)/5;
1469         else if (freq <= 2472)
1470                 return 1 + (freq - 2412)/5;
1471         else if (freq == 2484)
1472                 return 14;
1473         else
1474                 return 0;
1475 }
1476
1477 int netconfig_get_operating_class(int freq)
1478 {
1479         int channel = 0;
1480         int oper_class = 0;
1481
1482         channel = netconfig_freq_to_channel(freq);
1483
1484         if (channel) {
1485                 /* Operating class 81 - 2.4 GHz band channels 1..13 */
1486                 if (channel >= 1 && channel <= 13)
1487                         oper_class = 81;
1488                 /* Operating class 115 - 5 GHz, channels 36-48 */
1489                 else if (channel >= 36 && channel <= 48)
1490                         oper_class = 115;
1491                 /* Operating class 124 - 5 GHz, channels 149,153,157,161 */
1492                 else
1493                         oper_class = 124;
1494
1495                 INFO("Operating Class  is [%d]", oper_class);
1496                 return oper_class;
1497         }
1498         return 0;
1499 }
1500
1501 tizen_profile_t _get_tizen_profile()
1502 {
1503         static tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
1504         if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
1505                 return profile;
1506
1507         char *profileName;
1508         system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
1509         switch (*profileName) {
1510         case 'm':
1511         case 'M':
1512                 profile = TIZEN_PROFILE_MOBILE;
1513                 break;
1514         case 'w':
1515         case 'W':
1516                 profile = TIZEN_PROFILE_WEARABLE;
1517                 break;
1518         case 't':
1519         case 'T':
1520                 profile = TIZEN_PROFILE_TV;
1521                 break;
1522         case 'i':
1523         case 'I':
1524                 profile = TIZEN_PROFILE_IVI;
1525                 break;
1526         default: // common or unknown ==> ALL ARE COMMON.
1527                 profile = TIZEN_PROFILE_COMMON;
1528         }
1529         free(profileName);
1530
1531         return profile;
1532 }
1533
1534 void netconfig_plugin_init()
1535 {
1536         handle_headed = dlopen(HEADED_PLUGIN_FILEPATH, RTLD_NOW);
1537         if (!handle_headed) {
1538                 ERR("Can't load %s: %s", HEADED_PLUGIN_FILEPATH, dlerror());
1539         } else {
1540                 headed_plugin = dlsym(handle_headed, "netconfig_headed_plugin");
1541                 if (!headed_plugin) {
1542                         ERR("Can't load symbol: %s", dlerror());
1543                         dlclose(handle_headed);
1544                 } else {
1545                         netconfig_plugin_headed_enabled = TRUE;
1546                 }
1547         }
1548
1549         handle_telephony = dlopen(TELEPHONY_PLUGIN_FILEPATH, RTLD_NOW);
1550         if (!handle_telephony) {
1551                 ERR("Can't load %s: %s", TELEPHONY_PLUGIN_FILEPATH, dlerror());
1552         } else {
1553                 telephony_plugin = dlsym(handle_telephony, "netconfig_telephony_plugin");
1554                 if (!telephony_plugin) {
1555                         ERR("Can't load symbol: %s", dlerror());
1556                         dlclose(handle_telephony);
1557                 } else {
1558                         netconfig_plugin_telephony_enabled = TRUE;
1559                 }
1560         }
1561
1562         handle_stc = dlopen(STC_PLUGIN_FILEPATH, RTLD_NOW);
1563         if (!handle_stc) {
1564                 ERR("Can't load %s: %s", STC_PLUGIN_FILEPATH, dlerror());
1565         } else {
1566                 stc_plugin = dlsym(handle_stc, "netconfig_stc_plugin");
1567                 if (!stc_plugin) {
1568                         ERR("Can't load symbol: %s", dlerror());
1569                         dlclose(handle_stc);
1570                 } else {
1571                         netconfig_plugin_stc_enabled = TRUE;
1572                 }
1573         }
1574
1575         handle_battery = dlopen(BATTERY_PLUGIN_FILEPATH, RTLD_NOW);
1576         if (!handle_battery) {
1577                 ERR("Can't load %s: %s", BATTERY_PLUGIN_FILEPATH, dlerror());
1578         } else {
1579                 battery_plugin = dlsym(handle_battery, "netconfig_battery_plugin");
1580                 if (!battery_plugin) {
1581                         ERR("Can't load symbol: %s", dlerror());
1582                         dlclose(handle_battery);
1583                 } else {
1584                         netconfig_plugin_battery_enabled = TRUE;
1585                 }
1586         }
1587
1588 }
1589
1590 void netconfig_plugin_deinit()
1591 {
1592         if (netconfig_plugin_headed_enabled) {
1593                 netconfig_plugin_headed_enabled = FALSE;
1594                 dlclose(handle_headed);
1595         }
1596
1597         if (netconfig_plugin_telephony_enabled) {
1598                 netconfig_plugin_telephony_enabled = FALSE;
1599                 dlclose(handle_telephony);
1600         }
1601
1602         if (netconfig_plugin_stc_enabled) {
1603                 netconfig_plugin_stc_enabled = FALSE;
1604                 dlclose(handle_stc);
1605         }
1606
1607         if (netconfig_plugin_battery_enabled) {
1608                 netconfig_plugin_battery_enabled = FALSE;
1609                 dlclose(handle_battery);
1610         }
1611
1612 }
1613
1614 gboolean netconfig_get_headed_plugin_flag()
1615 {
1616         return netconfig_plugin_headed_enabled;
1617 }
1618
1619 gboolean netconfig_get_telephony_plugin_flag()
1620 {
1621         return netconfig_plugin_telephony_enabled;
1622 }
1623
1624 bool netconfig_check_feature_supported(netconfig_supported_feature_e feature)
1625 {
1626         const char *key = NULL;
1627
1628         if (!is_feature_checked[feature]) {
1629                 switch (feature) {
1630                 case NETCONFIG_SUPPORTED_FEATURE_ETHERNET:
1631                         key = ETHERNET_FEATURE;
1632                         break;
1633                 case NETCONFIG_SUPPORTED_FEATURE_TETHERING:
1634                         key = TETHERING_FEATURE;
1635                         break;
1636                 case NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT:
1637                         key = WIFI_DIRECT_FEATURE;
1638                         break;
1639                 case NETCONFIG_SUPPORTED_FEATURE_WIFI_SOFTAP:
1640                         key = WIFI_SOFTAP_FEATURE;
1641                         break;
1642                 default:
1643                         ERR("Uknown feature");
1644                         return false;
1645                 }
1646
1647                 if (system_info_get_platform_bool(key, &feature_supported[feature]) < 0) {
1648                         ERR("Get feature is failed");
1649                         return false;
1650                 }
1651                 is_feature_checked[feature] = true;
1652         }
1653         return feature_supported[feature];
1654 }
1655
1656 void netconfig_convert_bytes_to_hexstr(const char *bin, int blen, gchar* hexstr)
1657 {
1658         char t;
1659
1660         while (blen) {
1661                 t = (*bin >> 4) & 0x0f;
1662
1663                 if (t <= 9)
1664                         *hexstr = t + '0';
1665                 else if (t >= 10 && t <= 16)
1666                         *hexstr = (t - 10) + 'a';
1667
1668                 hexstr++;
1669
1670                 t = *bin & 0x0f;
1671
1672                 if (t <= 9)
1673                         *hexstr = t + '0';
1674                 else if (t >= 10 && t <= 16)
1675                         *hexstr = (t - 10) + 'a';
1676
1677                 hexstr++;
1678                 bin++;
1679                 blen--;
1680         }
1681
1682         *hexstr = '\0';
1683 }
1684
1685 bool __is_hidden_file(const  char *file)
1686 {
1687         /* exclude "." ,  "..", "settings" and hidden files */
1688         if( g_strcmp0( file, "." ) == 0 ||
1689                         g_strcmp0( file, ".." ) == 0 || file[0]=='.' || g_strcmp0(file, "settings")==0 )
1690         {
1691                 return true;
1692         }
1693
1694         return false;
1695 }
1696
1697 int get_files_count(const char *path)
1698 {
1699         DIR *dfd = NULL;
1700         struct dirent *dir = NULL;
1701         int file_count = 0;
1702         dfd = opendir(path);
1703         if (dfd) {
1704                 while ((dir = readdir(dfd)) != NULL) {
1705                         if (__is_hidden_file(dir->d_name))
1706                                 continue;
1707
1708                         if (strncmp(dir->d_name, "wifi_", 5) != 0)
1709                                 continue;
1710
1711                         ++file_count;
1712                 }
1713                 closedir(dfd);
1714         }
1715
1716         return file_count;
1717 }
1718
1719 char * get_least_recently_profile(const char *path)
1720 {
1721         DIR *dfd = NULL;
1722         struct dirent *dir = NULL;
1723         unsigned long lastModified =  (unsigned long)~0;
1724         char *file = NULL;
1725         dfd = opendir(path);
1726         if (dfd) {
1727                 while ((dir = readdir(dfd)) != NULL) {
1728                         if (__is_hidden_file(dir->d_name))
1729                                 continue;
1730
1731                         if (strncmp(dir->d_name, "wifi_", 5) != 0)
1732                                 continue;
1733
1734                         struct stat attr;
1735                         gchar *full_path = g_strdup_printf("%s/%s", path, dir->d_name);
1736                         if (stat(full_path, &attr)== 0) {
1737                                 if(lastModified > attr.st_mtime)
1738                                 {
1739                                         lastModified = attr.st_mtime;
1740                                         file = dir->d_name;
1741                                 }
1742                         } else {
1743                                 ERR("stat failed");
1744                         }
1745                         g_free(full_path);
1746                 }
1747                 closedir(dfd);
1748         }
1749
1750         DBG("least recently path: [%s]",  file);
1751
1752         return file;
1753 }