Fix dlog format error
[platform/core/connectivity/net-config.git] / src / utils / util.c
index 6efd972..d80c743 100755 (executable)
@@ -30,6 +30,7 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <ctype.h>
 #include <vconf-keys.h>
 #include <tzplatform_config.h>
 #include <system_info.h>
@@ -46,6 +47,7 @@
 #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;
@@ -55,8 +57,42 @@ typedef struct {
 } 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;
+
+       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)
 {
@@ -284,31 +320,31 @@ void netconfig_wifi_device_picker_service_stop(void)
 
 gboolean netconfig_is_wifi_direct_on(void)
 {
-#if defined TIZEN_P2P_ENABLE
+       if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
+               return FALSE;
+
        int wifi_direct_state = 0;
 
        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;
-#else
-       return FALSE;
-#endif
 }
 
 gboolean netconfig_is_wifi_tethering_on(void)
 {
-#if defined TIZEN_TETHERING_ENABLE
-       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;
+       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;
+               }
        }
-#endif
+
        DBG("Mobile AP is off");
        return FALSE;
 }
@@ -392,8 +428,8 @@ int netconfig_execute_file(const char *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);
+                       DBG("Fail to execute command (%s)",
+                                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                        exit(1);
                }
        } else if (pid > 0) {
@@ -414,8 +450,60 @@ int netconfig_execute_file(const char *file_path,
                return rv;
        }
 
-       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
-       DBG("failed to fork(%s)", error_buf);
+       DBG("failed to fork(%s)",
+               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+       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 (execv(args[0], args) == -1) {
+                       DBG("Fail to execute command (%s)",
+                               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+                       g_strfreev(args);
+                       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");
+               }
+
+               g_strfreev(args);
+               return rv;
+       }
+
+       DBG("failed to fork(%s)",
+               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+       g_strfreev(args);
+
        return -EIO;
 }
 
@@ -446,7 +534,7 @@ int netconfig_execute_clatd(const char *file_path, char *const args[])
 
        state = sigaction(SIGCHLD, &act, 0);
        if (state != 0) {
-               DBG("sigaction() : %d");
+               DBG("sigaction() : %d", state);
                return -1;
        }
 
@@ -461,8 +549,8 @@ int netconfig_execute_clatd(const char *file_path, char *const args[])
 
                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);
+                       ERR("Fail to execute command (%s)",
+                               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                        return -1;
                }
        } else if (pid > 0) {
@@ -470,8 +558,64 @@ int netconfig_execute_clatd(const char *file_path, char *const args[])
                return rv;
        }
 
-       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
-       DBG("failed to fork(%s)", error_buf);
+       DBG("failed to fork(%s)",
+               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+       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));
+}
+
+int netconfig_execute_file_no_wait(const char *file_path, char *const args[])
+{
+       pid_t pid = 0;
+       int rv = 0;
+       errno = 0;
+       register unsigned int index = 0;
+
+       struct sigaction act;
+       int state = 0;
+       char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
+
+       act.sa_handler = no_wait_signal_handler;
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = 0;
+
+       state = sigaction(SIGCHLD, &act, 0);
+       if (state != 0) {
+               DBG("sigaction() : %d", state);
+               return -1;
+       }
+
+       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;
 }
 
@@ -490,8 +634,8 @@ int __netconfig_get_interface_index(const char *interface_name)
        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);
+               DBG("Failed to create socket : %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                return -1;
        }
 
@@ -501,7 +645,8 @@ int __netconfig_get_interface_index(const char *interface_name)
        close(sock);
 
        if (result < 0) {
-               DBG("Failed to get ifr index: %s", error_buf);
+               DBG("Failed to get ifr index: %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                return -1;
        }
 
@@ -549,14 +694,14 @@ int netconfig_add_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gi
        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);
+               DBG("Failed to create socket : %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                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);
+               DBG("Failed to set route address : %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                close(sock);
                return -1;
        }
@@ -600,14 +745,14 @@ int netconfig_del_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gi
        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);
+               DBG("Failed to create socket : %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                return -1;
        }
 
        if (ioctl(sock, SIOCDELRT, &rt) < 0) {
-               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
-               DBG("Failed to set route address : %s", error_buf);
+               DBG("Failed to set route address : %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                close(sock);
                return -1;
        }
@@ -632,16 +777,16 @@ int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, u
 
        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);
+               DBG("inet_pton failed : %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                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);
+                       DBG("inet_pton failed : %s",
+                               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                        return -1;
                }
        }
@@ -650,8 +795,8 @@ int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, u
 
        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);
+               DBG("Failed to create socket : %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                return -1;
        }
 
@@ -666,8 +811,8 @@ int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, u
        }
 
        if ((err = ioctl(fd, SIOCADDRT, &rt)) < 0) {
-               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
-               DBG("Failed to add route: %s", error_buf);
+               DBG("Failed to add route: %s",
+                       strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                close(fd);
                return -1;
        }
@@ -731,7 +876,11 @@ int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, u
 
 gboolean handle_launch_direct(Wifi *wifi, GDBusMethodInvocation *context)
 {
-#if defined TIZEN_P2P_ENABLE
+       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");
 
@@ -743,15 +892,11 @@ gboolean handle_launch_direct(Wifi *wifi, GDBusMethodInvocation *context)
        if (ret < 0) {
                ERR("Failed to launch Wi-Fi direct daemon");
                netconfig_error_wifi_direct_failed(context);
-               return FALSE;
+               return TRUE;
        }
 
        wifi_complete_launch_direct(wifi, context);
        return TRUE;
-#else
-       wifi_complete_launch_direct(wifi, context);
-       return FALSE;
-#endif
 }
 
 int execute_mdnsd_script(char* op)
@@ -809,6 +954,12 @@ static void register_dnssd_conn_destroy_signal(gchar *name)
        }
 
        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,
@@ -827,7 +978,7 @@ gboolean handle_launch_mdns(Network *object, GDBusMethodInvocation *context,
        if (execute_mdnsd_script("start") < 0) {
                ERR("Failed to launch mdnsresponder daemon");
                netconfig_error_invalid_parameter(context);
-               return FALSE;
+               return TRUE;
        }
 
        mdnsd_ref_count++;
@@ -895,6 +1046,87 @@ void __netconfig_pop_wifi_connected_poppup(const char *ssid)
        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;
@@ -1053,26 +1285,41 @@ 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());
-               return;
+       } 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;
+               }
        }
 
-       headed_plugin = dlsym(handle_headed, "netconfig_headed_plugin");
-       if (!headed_plugin) {
-               ERR("Can't load symbol: %s", dlerror());
-               dlclose(handle_headed);
-               return;
+       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;
+               }
        }
-
-       netconfig_plugin_headed_enabled = TRUE;
 }
 
 void netconfig_plugin_deinit()
 {
-       if (!netconfig_plugin_headed_enabled)
-               return;
+       if (netconfig_plugin_headed_enabled) {
+               netconfig_plugin_headed_enabled = FALSE;
+               dlclose(handle_headed);
+       }
 
-       netconfig_plugin_headed_enabled = FALSE;
-       dlclose(handle_headed);
+       if (netconfig_plugin_telephony_enabled) {
+               netconfig_plugin_telephony_enabled = FALSE;
+               dlclose(handle_telephony);
+       }
 }
 
 gboolean netconfig_get_headed_plugin_flag()
@@ -1080,3 +1327,39 @@ 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 (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];
+}