X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Futils%2Futil.c;h=27c2238441ba2292c0a5a077cc0605938cc02d57;hb=fd6e2995141fffefb2a78ee290a6cea694690d5e;hp=001cdb6f0c9010f88dbcf116193663f32f36b43f;hpb=db59e2447e8c2f564f5666acbc41ed51aa5d23ea;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git diff --git a/src/utils/util.c b/src/utils/util.c old mode 100644 new mode 100755 index 001cdb6..27c2238 --- a/src/utils/util.c +++ b/src/utils/util.c @@ -1,7 +1,7 @@ /* * Network Configuration Module * - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,27 +17,82 @@ * */ -#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include -#include #include -#include -#include +#include #include -#include -#include -#include +#include +#include #include "log.h" #include "util.h" #include "neterror.h" #include "wifi-state.h" +#include "netdbus.h" + +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +#define MAC_INFO_FILEPATH tzplatform_mkpath(TZ_SYS_ETC, "/.mac.info") +#define MAC_ADDRESS_FILEPATH "/sys/class/net/wlan0/address" +#define MAC_ADDRESS_MAX_LEN 18 +#define HEADED_PLUGIN_FILEPATH "/usr/lib/net-config-plugin-headed.so" +#define TELEPHONY_PLUGIN_FILEPATH "/usr/lib/net-config-plugin-telephony.so" + +static gboolean netconfig_device_picker_test = FALSE; +static int mdnsd_ref_count = 0; +typedef struct { + char *conn_name; + int conn_id; +} dnssd_conn_destroy_data; + +static gboolean netconfig_plugin_headed_enabled = FALSE; +static gboolean netconfig_plugin_telephony_enabled = FALSE; +static void *handle_headed; +static void *handle_telephony; +static struct netconfig_headed_plugin_t *headed_plugin; +static struct netconfig_telephony_plugin_t *telephony_plugin; + +static bool is_feature_checked[NETCONFIG_SUPPORTED_FEATURE_MAX] = {0, }; +static bool feature_supported[NETCONFIG_SUPPORTED_FEATURE_MAX] = {0, }; + +gboolean netconfig_check_passphrase(const gchar *service, const char *passphrase) +{ + gsize length; -#define WIFI_MAC_INFO_FILE "/opt/etc/.mac.info" -#define WIFI_MAC_INFO_LENGTH 17 -#define WIFI_DEV_NAME "wlan0" + if (!passphrase) + return FALSE; + + length = strlen(passphrase); + + if (g_str_has_suffix(service, "psk") == TRUE) { + if (length == 64) { + for (int i = 0; i < 64; i++) + if (!isxdigit((unsigned char)passphrase[i])) + return FALSE; + } else if (length < 8 || length > 63) + return FALSE; + } else if (g_str_has_suffix(service, "wep") == TRUE) { + if (length == 10 || length == 26) { + for (int i = 0; i < length; i++) + if (!isxdigit((unsigned char)passphrase[i])) + return FALSE; + } else if (length != 5 && length != 13) + return FALSE; + } + + return TRUE; +} GKeyFile *netconfig_keyfile_load(const char *pathname) { @@ -53,6 +108,7 @@ GKeyFile *netconfig_keyfile_load(const char *pathname) keyfile = NULL; } + DBG("loaded keyfile %s", pathname); return keyfile; } @@ -71,6 +127,7 @@ void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname) if (directory == NULL || (*directory) == '\0') { g_free(directory); + ERR("directory is NULL"); return; } @@ -78,6 +135,7 @@ void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname) if (g_mkdir_with_parents(directory, S_IRUSR | S_IWUSR | S_IXUSR) != 0) { g_free(directory); + ERR("failed to make directory"); return; } } @@ -85,16 +143,14 @@ void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname) keydata = g_key_file_to_data(keyfile, &size, &error); if (g_file_set_contents(pathname, keydata, size, &error) != TRUE) { - DBG("Unable to save %s, error %s", pathname, error->message); + ERR("Unable to save %s, error %s", pathname, error->message); g_error_free(error); } - if (chmod(pathname, S_IRUSR | S_IWUSR) != 0) - DBG("Unable to change permission of %s", pathname); + chmod(pathname, S_IRUSR | S_IWUSR); + DBG("Successfully saved keyfile %s", pathname); g_free(keydata); - - g_key_file_free(keyfile); } void netconfig_start_timer_seconds(guint secs, @@ -168,8 +224,9 @@ static gboolean __netconfig_test_device_picker() { char *favorite_wifi_service = NULL; - favorite_wifi_service = netconfig_wifi_get_favorite_service(); + favorite_wifi_service = wifi_get_favorite_service(); if (favorite_wifi_service != NULL) { + ERR("favorite_wifi_service is existed[%s] : Donot launch device picker", favorite_wifi_service); g_free(favorite_wifi_service); return FALSE; } @@ -179,20 +236,13 @@ static gboolean __netconfig_test_device_picker() static void __netconfig_pop_device_picker(void) { - int rv = 0; - bundle *b = NULL; - int wifi_ug_state = 0; - - vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state); - if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) + if (!netconfig_plugin_headed_enabled) return; - b = bundle_create(); - - DBG("Launch Wi-Fi device picker"); - rv = syspopup_launch("wifi-qs", b); + if (!headed_plugin) + return; - bundle_free(b); + headed_plugin->pop_device_picker(); } static gboolean __netconfig_wifi_try_device_picker(gpointer data) @@ -203,8 +253,7 @@ static gboolean __netconfig_wifi_try_device_picker(gpointer data) return FALSE; } -static guint __netconfig_wifi_device_picker_timer_id(gboolean is_set_method, - guint timer_id) +static guint __netconfig_wifi_device_picker_timer_id(gboolean is_set_method, guint timer_id) { static guint netconfig_wifi_device_picker_service_timer = 0; @@ -227,29 +276,29 @@ static guint __netconfig_wifi_device_picker_get_timer_id(void) return __netconfig_wifi_device_picker_timer_id(FALSE, -1); } +void netconfig_wifi_enable_device_picker_test(void) +{ + netconfig_device_picker_test = TRUE; +} + void netconfig_wifi_device_picker_service_start(void) { - int wifi_ug_state; const int NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL = 700; - int hotspot_wifi_state = VCONFKEY_MOBILE_HOTSPOT_WIFI_OFF; guint timer_id = 0; - vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state); - if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) + if (netconfig_device_picker_test == TRUE) + netconfig_device_picker_test = FALSE; + else return; - /* If Wi-Fi tethering is pending on, don't show device picker UI*/ - vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_WIFI_STATE, &hotspot_wifi_state); - if (hotspot_wifi_state == VCONFKEY_MOBILE_HOTSPOT_WIFI_PENDING_ON) { - DBG("hotspot_wifi_state %d", hotspot_wifi_state); - return; - } + int wifi_ug_state; - DBG("Register device picker timer with %d milliseconds", - NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL); + netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state); + if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) + return; - netconfig_start_timer(NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL, - __netconfig_wifi_try_device_picker, NULL, &timer_id); + DBG("Register device picker timer with %d milliseconds", NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL); + netconfig_start_timer(NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL, __netconfig_wifi_try_device_picker, NULL, &timer_id); __netconfig_wifi_device_picker_set_timer_id(timer_id); } @@ -271,9 +320,12 @@ void netconfig_wifi_device_picker_service_stop(void) gboolean netconfig_is_wifi_direct_on(void) { + if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT)) + return FALSE; + int wifi_direct_state = 0; - vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state); + netconfig_vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state); DBG("Wi-Fi direct mode %d", wifi_direct_state); return (wifi_direct_state != 0) ? TRUE : FALSE; @@ -281,192 +333,1033 @@ gboolean netconfig_is_wifi_direct_on(void) gboolean netconfig_is_wifi_tethering_on(void) { - int wifi_tethering_state = 0; + if (netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING)) { + int wifi_tethering_state = 0; + + netconfig_vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &wifi_tethering_state); + DBG("Wi-Ti tethering mode %d", wifi_tethering_state); + if ((wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) + || (wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP)) { + DBG("Mobile AP is on"); + return TRUE; + } + } - vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &wifi_tethering_state); + DBG("Mobile AP is off"); + return FALSE; +} - DBG("Wi-Ti tethering mode %d", wifi_tethering_state); - if (wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) - return TRUE; +gboolean netconfig_interface_up(const char *ifname) +{ + int fd; + struct ifreq ifr; - return FALSE; + fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) + return FALSE; + + memset(&ifr, 0, sizeof(ifr)); + g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + close(fd); + return FALSE; + } + + ifr.ifr_flags |= (IFF_UP | IFF_DYNAMIC); + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + close(fd); + return FALSE; + } + + close(fd); + + DBG("Successfully activated wireless interface %s", ifname); + return TRUE; } -/* args[] and env[] should be terminated with NULL pointer */ -gboolean netconfig_execute_file(const char *file_path, - char *const args[], char *const env[]) +gboolean netconfig_interface_down(const char *ifname) +{ + int fd; + struct ifreq ifr; + + fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) + return FALSE; + + memset(&ifr, 0, sizeof(ifr)); + g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + close(fd); + return FALSE; + } + + ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC; + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + close(fd); + return FALSE; + } + + close(fd); + + DBG("Successfully de-activated wireless interface %s", ifname); + return TRUE; +} + +int netconfig_execute_file(const char *file_path, + char *const args[], char *const envs[]) { pid_t pid = 0; + int status = 0; int rv = 0; errno = 0; + register unsigned int index = 0; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + + while (args[index] != NULL) { + DBG("%s", args[index]); + index++; + } if (!(pid = fork())) { - register unsigned int index = 0; - INFO("pid(%d), ppid (%d)", getpid(), getppid()); - INFO("Inside child, exec (%s) command", file_path); - - index = 0; - while (args[index] != NULL) { - INFO(" %s", args[index]); - index++; + DBG("pid(%d), ppid (%d)", getpid(), getppid()); + DBG("Inside child, exec (%s) command", file_path); + + errno = 0; + if (execve(file_path, args, envs) == -1) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Fail to execute command (%s)", error_buf); + exit(1); } + } else if (pid > 0) { + if (waitpid(pid, &status, 0) == -1) + DBG("wait pid (%u) status (%d)", pid, status); + + if (WIFEXITED(status)) { + rv = WEXITSTATUS(status); + DBG("exited, status=%d", rv); + } else if (WIFSIGNALED(status)) { + DBG("killed by signal %d", WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + DBG("stopped by signal %d", WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + DBG("continued"); + } + + return rv; + } + + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("failed to fork(%s)", error_buf); + return -EIO; +} + +int netconfig_execute_cmd(const char *cmd) +{ + if (cmd == NULL) + return -EIO; + + pid_t pid = 0; + int status = 0; + int rv = 0; + errno = 0; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + gchar **args = NULL; + + DBG("command: %s", cmd); + + args = g_strsplit_set(cmd, " ", -1); + + if (!(pid = fork())) { + DBG("pid(%d), ppid (%d)", getpid(), getppid()); errno = 0; - if (execve(file_path, args, env) == -1) { - DBG("Fail to execute command...(%s)", - strerror(errno)); - return FALSE; + if (execv(args[0], args) == -1) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Fail to execute command (%s)", error_buf); + g_strfreev(args); + exit(1); } } else if (pid > 0) { - if (waitpid(pid, &rv, 0) == -1) { - DBG("wait pid (%u) rv (%d)", pid, rv); - - if (WIFEXITED(rv)) { - DBG("exited, rv=%d", WEXITSTATUS(rv)); - } else if (WIFSIGNALED(rv)) { - DBG("killed by signal %d", WTERMSIG(rv)); - } else if (WIFSTOPPED(rv)) { - DBG("stopped by signal %d", WSTOPSIG(rv)); - } else if (WIFCONTINUED(rv)) { - DBG("continued"); - } + if (waitpid(pid, &status, 0) == -1) + DBG("wait pid (%u) status (%d)", pid, status); + + if (WIFEXITED(status)) { + rv = WEXITSTATUS(status); + DBG("exited, status=%d", rv); + } else if (WIFSIGNALED(status)) { + DBG("killed by signal %d", WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + DBG("stopped by signal %d", WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + DBG("continued"); } - return TRUE; + + g_strfreev(args); + return rv; } - DBG("failed to fork()...(%s)", strerror(errno)); - return FALSE; + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("failed to fork(%s)", error_buf); + g_strfreev(args); + + return -EIO; } -gboolean netconfig_iface_wifi_launch_direct(NetconfigWifi *wifi, GError **error) +static void on_clat_handler() { - gboolean ret = TRUE; + pid_t clat_pid = 0; + int state = 0; - DBG("Launch Wi-Fi direct daemon"); + clat_pid = waitpid(-1, &state, WNOHANG); - const char *path = "/usr/bin/wifi-direct-server.sh"; - char *const args[] = { "wifi-direct-server.sh", "start", NULL}; - char *const env[] = { NULL }; + DBG("clat(%d) state(%d)", clat_pid, WEXITSTATUS(state)); +} - ret = netconfig_execute_file(path, args, env); +int netconfig_execute_clatd(const char *file_path, char *const args[]) +{ + pid_t pid = 0; + int rv = 0; + errno = 0; + register unsigned int index = 0; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; - if (ret != TRUE) { - INFO("Failed to launch Wi-Fi direct daemon"); + struct sigaction act; + int state = 0; + + act.sa_handler = on_clat_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + state = sigaction(SIGCHLD, &act, 0); + if (state != 0) { + DBG("sigaction() : %d"); + return -1; + } - netconfig_error_wifi_direct_failed(error); + while (args[index] != NULL) { + DBG("%s", args[index]); + index++; } - return ret; + if (!(pid = fork())) { + DBG("pid(%d), ppid (%d)", getpid(), getppid()); + DBG("Inside child, exec (%s) command", file_path); + + errno = 0; + if (execvp(file_path, args) == -1) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + ERR("Fail to execute command (%s)", error_buf); + return -1; + } + } else if (pid > 0) { + ERR("Success to launch clatd"); + return rv; + } + + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("failed to fork(%s)", error_buf); + return -EIO; +} + +static void no_wait_signal_handler() +{ + pid_t child_pid = 0; + int state = 0; + + child_pid = waitpid(-1, &state, WNOHANG); + + DBG("child_id(%d) state(%d)", child_pid, WEXITSTATUS(state)); } -void netconfig_add_wifi_found_notification(void) +int netconfig_execute_file_no_wait(const char *file_path, char *const args[]) { - int ret; - bundle *b = bundle_create(); + pid_t pid = 0; + int rv = 0; + errno = 0; + register unsigned int index = 0; - bundle_add(b, "_SYSPOPUP_TYPE_", "add_found_ap_noti"); + struct sigaction act; + int state = 0; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; - ret = aul_launch_app("org.tizen.net-popup", b); + act.sa_handler = no_wait_signal_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; - bundle_free(b); + state = sigaction(SIGCHLD, &act, 0); + if (state != 0) { + DBG("sigaction() : %d"); + return -1; + } - if (ret >= 0) - DBG("Successfully added notification"); - else - ERR("Unable to launch noti-popup. Err = %d", ret); + while (args[index] != NULL) { + DBG("%s", args[index]); + index++; + } + + if (!(pid = fork())) { + DBG("pid(%d), ppid (%d)", getpid(), getppid()); + DBG("Inside child, exec (%s) command", file_path); + + errno = 0; + if (execvp(file_path, args) == -1) { + ERR("Fail to execute command (%s)", + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER)); + return -1; + } + } else if (pid > 0) { + ERR("Successfully launched child process"); + return rv; + } + + DBG("failed to fork(%s)", + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER)); + return -EIO; } -void netconfig_del_wifi_found_notification(void) +int __netconfig_get_interface_index(const char *interface_name) { - int ret; - bundle *b = bundle_create(); + struct ifreq ifr; + int sock = 0; + int result = 0; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; - bundle_add(b, "_SYSPOPUP_TYPE_", "del_found_ap_noti"); + if (interface_name == NULL) { + DBG("Inteface name is NULL"); + return -1; + } + + errno = 0; + sock = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sock < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to create socket : %s", error_buf); + return -1; + } - ret = aul_launch_app("org.tizen.net-popup", b); + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1); + result = ioctl(sock, SIOCGIFINDEX, &ifr); + close(sock); - bundle_free(b); + if (result < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to get ifr index: %s", error_buf); + return -1; + } - if (ret >= 0) - DBG("Successfully deleted notification"); - else - ERR("Unable to launch noti-popup. Err = %d", ret); + return ifr.ifr_ifindex; } +int netconfig_add_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family) +{ + struct ifreq ifr; + struct rtentry rt; + struct sockaddr_in addr_in; + int sock; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_ifindex = __netconfig_get_interface_index(interface); + + if (ifr.ifr_ifindex < 0) + return -1; + + strncpy(ifr.ifr_name, interface, IFNAMSIZ-1); + + memset(&rt, 0, sizeof(rt)); + + rt.rt_flags = RTF_UP | RTF_HOST; + memset(&addr_in, 0, sizeof(struct sockaddr_in)); + addr_in.sin_family = address_family; + addr_in.sin_addr.s_addr = inet_addr(ip_addr); + memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst)); + + memset(&addr_in, 0, sizeof(struct sockaddr_in)); + addr_in.sin_family = address_family; + addr_in.sin_addr.s_addr = INADDR_ANY; + memcpy(&rt.rt_gateway, &addr_in, sizeof(rt.rt_gateway)); -void netconfig_set_wifi_mac_address(void) + memset(&addr_in, 0, sizeof(struct sockaddr_in)); + addr_in.sin_family = AF_INET; + addr_in.sin_addr.s_addr = inet_addr(subnet); + memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask)); + + rt.rt_dev = ifr.ifr_name; + + errno = 0; + sock = socket(PF_INET, SOCK_DGRAM, 0); + + if (sock < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to create socket : %s", error_buf); + return -1; + } + + if (ioctl(sock, SIOCADDRT, &rt) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to set route address : %s", error_buf); + close(sock); + return -1; + } + + close(sock); + + return 1; +} + +int netconfig_del_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family) { - FILE *fp = NULL; struct ifreq ifr; - int ctl_sk = -1; - char buf[WIFI_MAC_INFO_LENGTH + 1]; - char *mac_info; + struct rtentry rt; + struct sockaddr_in addr_in; + int sock; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = __netconfig_get_interface_index(interface); + + if (ifr.ifr_ifindex < 0) + return -1; - mac_info = vconf_get_str(VCONFKEY_WIFI_BSSID_ADDRESS); - if (mac_info == NULL) { - ERR("Failed to open vconf key %s", VCONFKEY_WIFI_BSSID_ADDRESS); + strncpy(ifr.ifr_name, interface, IFNAMSIZ-1); + + memset(&rt, 0, sizeof(rt)); + + rt.rt_flags = RTF_UP; + memset(&addr_in, 0, sizeof(struct sockaddr_in)); + addr_in.sin_family = address_family; + addr_in.sin_addr.s_addr = inet_addr(ip_addr); + memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst)); + + memset(&addr_in, 0, sizeof(struct sockaddr_in)); + addr_in.sin_family = address_family; + addr_in.sin_addr.s_addr = inet_addr(subnet); + memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask)); + rt.rt_dev = ifr.ifr_name; + + errno = 0; + sock = socket(PF_INET, SOCK_DGRAM, 0); + + if (sock < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to create socket : %s", error_buf); + return -1; } - INFO("%s : %s", VCONFKEY_WIFI_BSSID_ADDRESS, mac_info); + if (ioctl(sock, SIOCDELRT, &rt) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to set route address : %s", error_buf); + close(sock); + return -1; + } + + close(sock); + + return 1; +} + +int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len) +{ + struct in6_rtmsg rt; + int fd = 0; + int err = 0; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + + memset(&rt, 0, sizeof(rt)); + + rt.rtmsg_dst_len = prefix_len; + + rt.rtmsg_flags = RTF_UP | RTF_HOST; + + errno = 0; + if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("inet_pton failed : %s", error_buf); + return -1; + } + + if (gateway != NULL) { + rt.rtmsg_flags |= RTF_GATEWAY; + if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("inet_pton failed : %s", error_buf); + return -1; + } + } + + rt.rtmsg_metric = 1; + + fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (fd < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to create socket : %s", error_buf); + return -1; + } + + rt.rtmsg_ifindex = 0; + + if (interface) { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1); + ioctl(fd, SIOCGIFINDEX, &ifr); + rt.rtmsg_ifindex = ifr.ifr_ifindex; + } + + if ((err = ioctl(fd, SIOCADDRT, &rt)) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to add route: %s", error_buf); + close(fd); + return -1; + } + + close(fd); + + return 1; +} + +int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len) +{ + struct in6_rtmsg rt; + int fd = 0; + int err = 0; + + memset(&rt, 0, sizeof(rt)); + + rt.rtmsg_dst_len = prefix_len; - fp = fopen(WIFI_MAC_INFO_FILE, "r"); - if (fp != NULL) { - if (fgets(buf, sizeof(buf), fp) == NULL) { - ERR("Failed to get MAC info from %s", WIFI_MAC_INFO_FILE); - goto done; + rt.rtmsg_flags = RTF_UP | RTF_HOST; + + if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) { + err = -errno; + return err; + } + + if (gateway != NULL) { + rt.rtmsg_flags |= RTF_GATEWAY; + if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) { + err = -errno; + return err; } + } + + rt.rtmsg_metric = 1; + + fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (fd < 0) + return -1; + + rt.rtmsg_ifindex = 0; + + if (interface) { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1); + ioctl(fd, SIOCGIFINDEX, &ifr); + rt.rtmsg_ifindex = ifr.ifr_ifindex; + } + + if ((err = ioctl(fd, SIOCDELRT, &rt)) < 0) { + DBG("Failed to del route: %d\n", err); + close(fd); + return -1; + } + + close(fd); + + return 1; +} + +gboolean handle_launch_direct(Wifi *wifi, GDBusMethodInvocation *context) +{ + if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT)) { + wifi_complete_launch_direct(wifi, context); + return TRUE; + } + + int ret = 0; + DBG("Launch Wi-Fi direct daemon"); + + const char *path = "/usr/bin/wifi-direct-server.sh"; + char *const args[] = { "wifi-direct-server.sh", "start", NULL }; + char *const envs[] = { NULL }; + + ret = netconfig_execute_file(path, args, envs); + if (ret < 0) { + ERR("Failed to launch Wi-Fi direct daemon"); + netconfig_error_wifi_direct_failed(context); + return TRUE; + } - INFO("%s : %s", WIFI_MAC_INFO_FILE, buf); + wifi_complete_launch_direct(wifi, context); + return TRUE; +} + +int execute_mdnsd_script(char* op) +{ + const char *path = "/usr/bin/mdnsresponder-server.sh"; + char *const args[] = { "mdnsresponder-server.sh", op, NULL }; + char *const envs[] = { NULL }; - if (strlen(buf) < WIFI_MAC_INFO_LENGTH) { - ERR("Failed to get MAC info from %s", WIFI_MAC_INFO_FILE); - goto done; + return netconfig_execute_file(path, args, envs); +} + +static void __dnssd_conn_destroyed_cb(GDBusConnection *conn, + const gchar *Name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + gchar *name = NULL; + gchar *old = NULL; + gchar *new = NULL; + dnssd_conn_destroy_data *data = user_data; + GDBusConnection *connection = NULL; + connection = netdbus_get_connection(); + + if (param == NULL) + return; + + g_variant_get(param, "(sss)", &name, &old, &new); + + if (g_strcmp0(name, data->conn_name) == 0 && *new == '\0') { + DBG("Connection %s Destroyed: name %s id %d", data->conn_name, name, + data->conn_id); + mdnsd_ref_count--; + g_dbus_connection_signal_unsubscribe(connection, data->conn_id); + if (mdnsd_ref_count == 0) { + if (execute_mdnsd_script("stop") < 0) + ERR("Failed to stop mdnsresponder daemon"); } + } + g_free(name); + g_free(old); + g_free(new); + g_free(data->conn_name); + g_free(data); + return; +} - buf[WIFI_MAC_INFO_LENGTH] = '\0'; - } else { - // not MAC into file use ioctl to get MAC - ctl_sk = socket(PF_INET,SOCK_DGRAM,0); - if (ctl_sk < 0 ) { - ERR("Failed to open socket"); - goto done; +static void register_dnssd_conn_destroy_signal(gchar *name) +{ + dnssd_conn_destroy_data *data; + GDBusConnection *connection = NULL; + connection = netdbus_get_connection(); + + if (connection == NULL) { + ERR("Failed to get GDbus Connection"); + return; + } + + data = g_try_malloc0(sizeof(dnssd_conn_destroy_data)); + + if (data == NULL) { + ERR("Out of Memory!"); + return; + } + + data->conn_name = g_strdup(name); + + data->conn_id = g_dbus_connection_signal_subscribe(connection, + DBUS_SERVICE_DBUS, DBUS_INTERFACE_DBUS, + "NameOwnerChanged", NULL, name, + G_DBUS_SIGNAL_FLAGS_NONE, __dnssd_conn_destroyed_cb, + data, NULL); + return; +} + +gboolean handle_launch_mdns(Network *object, GDBusMethodInvocation *context, + gchar *name) +{ + DBG("Launch mdnsresponder daemon"); + + if (execute_mdnsd_script("start") < 0) { + ERR("Failed to launch mdnsresponder daemon"); + netconfig_error_invalid_parameter(context); + return TRUE; + } + + mdnsd_ref_count++; + register_dnssd_conn_destroy_signal(name); + DBG("Ref mdnsresponder daemon. ref count: %d", mdnsd_ref_count); + + network_complete_launch_mdns(object, context); + return TRUE; +} + +gboolean netconfig_send_notification_to_net_popup(const char * noti, const char * ssid) +{ + if (!netconfig_plugin_headed_enabled) + return FALSE; + + if (!headed_plugin) + return FALSE; + + return headed_plugin->send_notification_to_net_popup(noti, ssid); +} + +int netconfig_send_message_to_net_popup(const char *title, + const char *content, const char *type, const char *ssid) +{ + if (!netconfig_plugin_headed_enabled) + return 0; + + if (!headed_plugin) + return 0; + + return headed_plugin->send_message_to_net_popup(title, content, type, ssid); +} + +int netconfig_send_restriction_to_net_popup(const char *title, + const char *type, const char *restriction) +{ + if (!netconfig_plugin_headed_enabled) + return 0; + + if (!headed_plugin) + return 0; + + return headed_plugin->send_restriction_to_net_popup(title, type, restriction); +} + +void netconfig_set_system_event(int sys_evt, int evt_key, int evt_val) +{ + if (!netconfig_plugin_headed_enabled) + return; + + if (!headed_plugin) + return; + + headed_plugin->set_system_event(sys_evt, evt_key, evt_val); +} + +void __netconfig_pop_wifi_connected_poppup(const char *ssid) +{ + if (!netconfig_plugin_headed_enabled) + return; + + if (!headed_plugin) + return; + + headed_plugin->pop_wifi_connected_poppup(ssid); +} + +void netconfig_get_telephony_network_type(int *svctype, int *pstype) +{ + if (!netconfig_plugin_telephony_enabled) + return; + + if (!telephony_plugin) + return; + + telephony_plugin->get_telephony_network_type(svctype, pstype); +} + +gboolean __netconfig_wifi_get_sim_imsi(Wifi *wifi, GDBusMethodInvocation *context) +{ + if (!netconfig_plugin_telephony_enabled) + return FALSE; + + if (!telephony_plugin) + return FALSE; + + return telephony_plugin->wifi_get_sim_imsi(wifi, context); +} + +netconfig_error_e __netconfig_wifi_req_aka_auth(GArray *rand_data, GArray *autn_data, + GDBusMethodInvocation *context, struct wifi_authentication_data **data) +{ + if (!netconfig_plugin_telephony_enabled) + return NETCONFIG_ERROR_INTERNAL; + + if (!telephony_plugin) + return NETCONFIG_ERROR_INTERNAL; + + return telephony_plugin->wifi_req_aka_auth(rand_data, autn_data, context, data); +} + +gboolean __netconfig_wifi_req_sim_auth(GArray *rand_data, + GDBusMethodInvocation *context, struct wifi_authentication_data **data) +{ + if (!netconfig_plugin_telephony_enabled) + return FALSE; + + if (!telephony_plugin) + return FALSE; + + return telephony_plugin->wifi_req_sim_auth(rand_data, context, data); +} + +gboolean netconfig_tapi_check_sim_state(void) +{ + if (!netconfig_plugin_telephony_enabled) + return FALSE; + + if (!telephony_plugin) + return FALSE; + + return telephony_plugin->tapi_check_sim_state(); +} + +gboolean __netconfig_wifi_get_aka_authdata(Wifi *wifi, + GDBusMethodInvocation *context, struct wifi_authentication_data **data) +{ + if (!netconfig_plugin_telephony_enabled) + return FALSE; + + if (!telephony_plugin) + return FALSE; + + return telephony_plugin->wifi_get_aka_authdata(wifi, context, data); +} + +gboolean __netconfig_wifi_get_sim_authdata(Wifi *wifi, + GDBusMethodInvocation *context, struct wifi_authentication_data **data) +{ + if (!netconfig_plugin_telephony_enabled) + return FALSE; + + if (!telephony_plugin) + return FALSE; + + return telephony_plugin->wifi_get_sim_authdata(wifi, context, data); +} + +void netconfig_set_vconf_int(const char * key, int value) +{ + int ret = 0; + + DBG("[%s: %d]", key, value); + + ret = vconf_set_int(key, value); + if (ret != VCONF_OK) + ERR("Failed to set"); +} + +void netconfig_set_vconf_str(const char * key, const char * value) +{ + int ret = 0; + + DBG("[%s: %s]", key, value); + + ret = vconf_set_str(key, value); + if (ret != VCONF_OK) + ERR("Failed to set"); +} + +int netconfig_vconf_get_int(const char * key, int *value) +{ + int ret = 0; + + ret = vconf_get_int(key, value); + if (ret != VCONF_OK) { + ERR("Failed to get vconfkey [%s] value", key); + return -1; + } + + return 0; +} + +int netconfig_vconf_get_bool(const char * key, int *value) +{ + int ret = 0; + + ret = vconf_get_bool(key, value); + if (ret != VCONF_OK) { + ERR("Failed to get vconfkey [%s] value", key); + return -1; + } + + return 0; +} + +char* netconfig_get_env(const char *key) +{ + FILE *fp; + char buf[256], *entry = NULL, *value = NULL, *last; + int len = 0; + + if (!key) + return NULL; + + fp = fopen(NETCONFIG_TIZEN_SYSTEM_ENV, "r"); + if (!fp) + return NULL; + + while (fgets(buf, sizeof(buf), fp)) { + entry = buf; + entry = strtok_r(entry, "=", &last); + if (entry) { + if (strstr(entry, key)) { + entry = strtok_r(NULL, "\n", &last); + if (entry) { + len = strlen(entry); + value = (char*)malloc(len+1); + g_strlcpy(value, entry, len+1); + } else { + value = (char*)malloc(sizeof(char)); + g_strlcpy(value, "\n", sizeof(char)); + } + break; + } } + } - memset(&ifr, 0, sizeof(struct ifreq)); - strncpy(ifr.ifr_name, WIFI_DEV_NAME, sizeof(ifr.ifr_name) - 1); - ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0; + fclose(fp); + return value; +} - if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr) != 0) { - ERR("Failed to SIOCGIFHWADDR ioctl"); - goto done; +void netconfig_set_mac_address_from_file(void) +{ + FILE *file = NULL; + char mac_str[MAC_ADDRESS_MAX_LEN]; + gchar *mac_lower_str = NULL; + int mac_len = 0; + + file = fopen(MAC_INFO_FILEPATH, "r"); + if (file == NULL) { + ERR("Fail to open %s", MAC_INFO_FILEPATH); + file = fopen(MAC_ADDRESS_FILEPATH, "r"); + if (file == NULL) { + ERR("Fail to open %s", MAC_ADDRESS_FILEPATH); + return; } + } + if (fgets(mac_str, sizeof(mac_str), file) == NULL) { + ERR("Fail to read mac address"); + fclose(file); + return; + } + + mac_len = strlen(mac_str); + if (mac_len < 17) { + ERR("mac.info is empty"); + fclose(file); + return; + } + + mac_lower_str = g_ascii_strup(mac_str, (gssize)mac_len); + netconfig_set_vconf_str(VCONFKEY_WIFI_BSSID_ADDRESS, mac_lower_str); - snprintf(buf, WIFI_MAC_INFO_LENGTH + 1, - "%02x:%02x:%02x:%02x:%02x:%02x", - (unsigned char)ifr.ifr_hwaddr.sa_data[0], - (unsigned char)ifr.ifr_hwaddr.sa_data[1], - (unsigned char)ifr.ifr_hwaddr.sa_data[2], - (unsigned char)ifr.ifr_hwaddr.sa_data[3], - (unsigned char)ifr.ifr_hwaddr.sa_data[4], - (unsigned char)ifr.ifr_hwaddr.sa_data[5]); + g_free(mac_lower_str); + fclose(file); +} - INFO("%s MAC address: %s", WIFI_DEV_NAME, buf); +tizen_profile_t _get_tizen_profile() +{ + static tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN; + if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1)) + return profile; + + char *profileName; + system_info_get_platform_string("http://tizen.org/feature/profile", &profileName); + switch (*profileName) { + case 'm': + case 'M': + profile = TIZEN_PROFILE_MOBILE; + break; + case 'w': + case 'W': + profile = TIZEN_PROFILE_WEARABLE; + break; + case 't': + case 'T': + profile = TIZEN_PROFILE_TV; + break; + case 'i': + case 'I': + profile = TIZEN_PROFILE_IVI; + break; + default: // common or unknown ==> ALL ARE COMMON. + profile = TIZEN_PROFILE_COMMON; } + free(profileName); + + return profile; +} - if (mac_info && (g_str_equal(mac_info, buf) == TRUE)) - goto done; +void netconfig_plugin_init() +{ + handle_headed = dlopen(HEADED_PLUGIN_FILEPATH, RTLD_NOW); + if (!handle_headed) { + ERR("Can't load %s: %s", HEADED_PLUGIN_FILEPATH, dlerror()); + } else { + headed_plugin = dlsym(handle_headed, "netconfig_headed_plugin"); + if (!headed_plugin) { + ERR("Can't load symbol: %s", dlerror()); + dlclose(handle_headed); + } else { + netconfig_plugin_headed_enabled = TRUE; + } + } - if (vconf_set_str(VCONFKEY_WIFI_BSSID_ADDRESS, buf) != 0) - ERR("Failed to set MAC info to %s", VCONFKEY_WIFI_BSSID_ADDRESS); + handle_telephony = dlopen(TELEPHONY_PLUGIN_FILEPATH, RTLD_NOW); + if (!handle_telephony) { + ERR("Can't load %s: %s", TELEPHONY_PLUGIN_FILEPATH, dlerror()); + } else { + telephony_plugin = dlsym(handle_telephony, "netconfig_telephony_plugin"); + if (!telephony_plugin) { + ERR("Can't load symbol: %s", dlerror()); + dlclose(handle_telephony); + } else { + netconfig_plugin_telephony_enabled = TRUE; + } + } +} -done: - g_free(mac_info); +void netconfig_plugin_deinit() +{ + if (netconfig_plugin_headed_enabled) { + netconfig_plugin_headed_enabled = FALSE; + dlclose(handle_headed); + } - if (fp != NULL) { - fclose(fp); + if (netconfig_plugin_telephony_enabled) { + netconfig_plugin_telephony_enabled = FALSE; + dlclose(handle_telephony); } +} + +gboolean netconfig_get_headed_plugin_flag() +{ + return netconfig_plugin_headed_enabled; +} + +gboolean netconfig_get_telephony_plugin_flag() +{ + return netconfig_plugin_telephony_enabled; +} + +bool netconfig_check_feature_supported(netconfig_supported_feature_e feature) +{ + const char *key = NULL; + + if (!is_feature_checked[feature]) { + switch (feature) { + case NETCONFIG_SUPPORTED_FEATURE_ETHERNET: + key = ETHERNET_FEATURE; + break; + case NETCONFIG_SUPPORTED_FEATURE_TETHERING: + key = TETHERING_FEATURE; + break; + case NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT: + key = WIFI_DIRECT_FEATURE; + break; + case NETCONFIG_SUPPORTED_FEATURE_WIFI_SOFTAP: + key = WIFI_SOFTAP_FEATURE; + break; + default: + ERR("Uknown feature"); + return false; + } - if (ctl_sk >= 0) { - close(ctl_sk); + if (system_info_get_platform_bool(key, &feature_supported[feature]) < 0) { + ERR("Get feature is failed"); + return false; + } + is_feature_checked[feature] = true; } + return feature_supported[feature]; }