Added APIs get the tcp dump and network state 81/157281/12 accepted/tizen/unified/20171206.063059 submit/tizen/20171205.053202
authortaesub kim <taesub.kim@samsung.com>
Tue, 24 Oct 2017 05:02:08 +0000 (14:02 +0900)
committertaesub kim <taesub.kim@samsung.com>
Tue, 5 Dec 2017 00:42:18 +0000 (09:42 +0900)
Change-Id: Ife799113a9a77e3b18e777475347943ffa902c9e
Signed-off-by: Taesub Kim <taesub.kim@samsung.com>
13 files changed:
CMakeLists.txt
include/network-dump.h [new file with mode: 0755]
include/util.h
include/wifi.h
interfaces/netconfig-iface-network-state.xml
packaging/net-config.spec
resources/etc/dbus-1/system.d/net-config.conf
resources/opt/etc/dump.d/module.d/network_dump.sh [new file with mode: 0755]
src/main.c
src/network-dump.c [new file with mode: 0755]
src/network-state.c
src/signal-handler.c
src/utils/util.c

index 8ac8f89..960c0b1 100755 (executable)
@@ -73,6 +73,11 @@ IF(TIZEN_WEARABLE)
        ADD_DEFINITIONS(-DTIZEN_WEARABLE)
 ENDIF(TIZEN_WEARABLE)
 
+IF(TIZEN_DEBUG_ENABLE)
+       ADD_DEFINITIONS(-DTIZEN_DEBUG_ENABLE)
+       SET(SRCS ${SRCS} src/network-dump.c)
+ENDIF(TIZEN_DEBUG_ENABLE)
+
 INCLUDE(FindPkgConfig)
 PKG_CHECK_MODULES(pkgs REQUIRED
        dlog
diff --git a/include/network-dump.h b/include/network-dump.h
new file mode 100755 (executable)
index 0000000..7fb514b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Network Configuration Module
+ *
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __NETCONFIG_NETWORK_DUMP_H__
+#define __NETCONFIG_NETWORK_DUMP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <sys/time.h>
+
+#define DUMP_SERVICE_BUS_NAME           "org.tizen.system.dumpservice"
+#define DUMP_SERVICE_OBJECT_PATH        "/Org/Tizen/System/DumpService"
+#define DUMP_SERVICE_INTERFACE          "org.tizen.system.dumpservice"
+
+#define DUMP_SIGNAL                    "Dump"
+#define DUMP_START_SIGNAL              "Start"
+#define DUMP_FINISH_SIGNAL             "Finish"
+
+#define NETWORK_LOG_PATH "/opt/usr/data/network"
+#define KILLALL_EXEC_PATH "/usr/bin/killall"
+#define TCPDUMP_EXEC_PATH "/usr/sbin/tcpdump"
+
+gboolean handle_start_tcpdump(Tcpdump *object, GDBusMethodInvocation *context);
+gboolean handle_stop_tcpdump(Tcpdump *object, GDBusMethodInvocation *context);
+gboolean handle_get_tcpdump_state(Tcpdump *object, GDBusMethodInvocation *context);
+int netconfig_dump_log(const char *path);
+void check_dump_state_and_start(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 299d8d3..cc8a1a8 100755 (executable)
@@ -55,6 +55,8 @@ int __netconfig_get_interface_index(const char *interface_name);
 
 int netconfig_execute_cmd(const char *cmd);
 int netconfig_execute_file(const char *file_path, char *const args[], char *const env[]);
+int netconfig_execute_file_no_wait(const char *file_path,
+               char *const args[]);
 int netconfig_execute_clatd(const char *file_path, char *const args[]);
 int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len);
 int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len);
index 3025156..84d030f 100755 (executable)
@@ -30,8 +30,8 @@ extern "C" {
 
 #include "generated-code.h"
 
-#define WIFI_STORAGEDIR                        "/var/lib/misc/wifi"
-#define WIFI_CERT_STORAGEDIR   "/var/lib/misc/wifi/cert"
+#define WIFI_STORAGEDIR                        "/var/lib/wifi"
+#define WIFI_CERT_STORAGEDIR   "/var/lib/wifi/cert"
 #define CONNMAN_STORAGEDIR             "/var/lib/connman"
 
 void __netconfig_wifi_connect_reply(GObject *source_object, GAsyncResult *res,
index f0000a3..41b65e0 100755 (executable)
                        <arg type="s" name="address" direction="out"/>
                </method>
        </interface>
+       <interface name="net.netconfig.tcpdump">
+               <method name="StartTCPDump">
+               </method>
+               <method name="StopTCPDump">
+               </method>
+               <method name="GetTCPDumpState">
+                       <arg type="b" name="state" direction="out"/>
+               </method>
+       </interface>
 </node>
index 15ef805..4b1b85b 100755 (executable)
@@ -73,6 +73,7 @@ TIZEN Network Configuration service extension for telephony FW.
 cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \
        -DTIZEN_WLAN_PASSPOINT=1 \
        -DTIZEN_WLAN_USE_P2P_INTERFACE=1 \
+       -DTIZEN_DEBUG_ENABLE=1 \
 %if 0%{?model_build_feature_wlan_concurrent_mode}
        -DWLAN_CONCURRENT_MODE=1 \
 %endif
@@ -132,6 +133,12 @@ ln -s %{TZ_SYS_ETC}/resolv.conf %{buildroot}%{_sysconfdir}/resolv.conf
 mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d
 cp resources/etc/dbus-1/system.d/net-config.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/net-config.conf
 
+#log dump
+mkdir -p %{buildroot}/opt/etc/dump.d/module.d/
+cp resources/opt/etc/dump.d/module.d/network_dump.sh %{buildroot}/opt/etc/dump.d/module.d/network_dump.sh
+mkdir -p %{buildroot}/opt/var/lib/net-config/
+cp resources/opt/etc/dump.d/module.d/network_dump.sh %{buildroot}/opt/var/lib/net-config/network_dump.sh
+
 %if 0%{?model_build_feature_wlan_wearable} == 1
 #softreset scripts
 mkdir -p %{buildroot}/usr/system/RestoreDir/softreset
@@ -181,6 +188,8 @@ ln -sf %{_unitdir}/net-config.service %{_sysconfdir}/systemd/default-extra-depen
 %attr(644,root,root) %{_unitdir}/multi-user.target.wants/net-config.service
 %endif
 %license LICENSE
+%attr(500,root,root) /opt/etc/dump.d/module.d/network_dump.sh
+%attr(500,network_fw,network_fw) /opt/var/lib/net-config/network_dump.sh
 %if 0%{?model_build_feature_wlan_wearable} == 1
 %attr(700,network_fw,network_fw) /usr/system/RestoreDir/softreset/network_softreset.sh
 %endif
index dcef481..87d4161 100755 (executable)
                <allow send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="SetIpConflictPeriod" />
                <allow send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="GetIpConflictPeriod" />
 
+               <allow send_destination="net.netconfig" send_interface="net.netconfig.tcpdump" send_member="StartTCPDump" />
+               <allow send_destination="net.netconfig" send_interface="net.netconfig.tcpdump" send_member="StopTCPDump" />
+               <allow send_destination="net.netconfig" send_interface="net.netconfig.tcpdump" send_member="CheckTCPDumpStatus" />
+
                <check send_destination="net.netconfig" send_interface="net.netconfig.network" send_member="AddRoute" privilege="http://tizen.org/privilege/network.set" />
                <check send_destination="net.netconfig" send_interface="net.netconfig.network" send_member="RemoveRoute" privilege="http://tizen.org/privilege/network.set" />
                <check send_destination="net.netconfig" send_interface="net.netconfig.network" send_member="EthernetCableState" privilege="http://tizen.org/privilege/network.get" />
diff --git a/resources/opt/etc/dump.d/module.d/network_dump.sh b/resources/opt/etc/dump.d/module.d/network_dump.sh
new file mode 100755 (executable)
index 0000000..cf46685
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+
+#--------------------------------------
+#   network dump
+#--------------------------------------
+
+# not allow to use relative path
+if [[ $1 == "/"* ]]; then
+       echo "Absolute path"
+else
+       echo "Relative path"
+       exit -1
+fi
+
+export DISPLAY=:0.0
+NETWORK_DATA_DIR=/opt/usr/data/network
+NETWORK_DEBUG=$1/network
+
+@BIN_DIR@/mkdir -p ${NETWORK_DEBUG}
+
+@BIN_DIR@/netstat -na > ${NETWORK_DEBUG}/netstat
+@SBIN_DIR@/route -n > ${NETWORK_DEBUG}/route
+@SBIN_DIR@/route -A inet6 -n > ${NETWORK_DEBUG}/route6
+@BIN_DIR@/cat /proc/net/wireless > ${NETWORK_DEBUG}/wireless
+@BIN_DIR@/cat /etc/resolv.conf > ${NETWORK_DEBUG}/resolv.conf
+@SBIN_DIR@/ifconfig -a > ${NETWORK_DEBUG}/ifconfig
+/usr/sbin/iptables -L > ${NETWORK_DEBUG}/iptables
+/usr/sbin/ip6tables -L > ${NETWORK_DEBUG}/ip6tables
+@BIN_DIR@/cat /proc/net/tcp > ${NETWORK_DEBUG}/tcp
+@BIN_DIR@/cat /proc/net/tcp6 > ${NETWORK_DEBUG}/tcp6
+@BIN_DIR@/cat /proc/net/route > ${NETWORK_DEBUG}/proc_route
+@SBIN_DIR@/ip -4 rule > ${NETWORK_DEBUG}/ip4_rule
+@SBIN_DIR@/ip -6 rule > ${NETWORK_DEBUG}/ip6_rule
+@SBIN_DIR@/ip -4 route show table all > ${NETWORK_DEBUG}/ip4_route
+@SBIN_DIR@/ip -6 route show table all > ${NETWORK_DEBUG}/ip6_route
+/usr/bin/vconftool -r get memory/dnet >> ${NETWORK_DEBUG}/status
+/usr/bin/vconftool -r get memory/wifi >> ${NETWORK_DEBUG}/status
+/usr/bin/vconftool -r get file/private/wifi >> ${NETWORK_DEBUG}/status
+/usr/bin/vconftool -r get db/wifi >> ${NETWORK_DEBUG}/status
+@BIN_DIR@/mv ${NETWORK_DATA_DIR}/tcpdump*.pcap* ${NETWORK_DEBUG}
+@BIN_DIR@/tar -czf ${NETWORK_DEBUG}/network_file_log.tar.gz -C ${NETWORK_DATA_DIR} .
index 3e864b1..26451f6 100755 (executable)
@@ -38,6 +38,7 @@
 #include "network-monitor.h"
 #include "signal-handler.h"
 #include "network-statistics.h"
+#include "network-dump.h"
 
 static GMainLoop *main_loop = NULL;
 
@@ -127,6 +128,9 @@ int main(int argc, char *argv[])
        /* For device policy manager */
        netconfig_dpm_init();
 
+       /* Start tcpdump if dump state is on */
+       check_dump_state_and_start();
+
        /*In case no emulator, set the ETH0 Mac address*/
        if (TIZEN_TV && emulator_is_emulated() == FALSE)
                __netconfig_set_ether_macaddr();
diff --git a/src/network-dump.c b/src/network-dump.c
new file mode 100755 (executable)
index 0000000..ea4a416
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Network Configuration Module
+ *
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+
+#include "log.h"
+
+#include "util.h"
+#include "netdbus.h"
+#include "neterror.h"
+#include "network-dump.h"
+#include <unistd.h>
+
+#define NETWORK_DUMP_SCRIPT  "/opt/var/lib/net-config/network_dump.sh"
+
+#define TCP_DUMP_IN_BOOT_TIME "/opt/usr/data/tcp_dump_mode"
+
+static gboolean tcpdump_running = FALSE;
+
+static const char *get_current_time(void)
+{
+       struct timeval mytime;
+       struct tm stTempTime;
+       static char time_string[128];
+
+
+       struct tm {
+               int tm_sec; // Seconds
+               int tm_min; // Minutes
+               int tm_hour; // Hour (0--23)
+               int tm_mday; // Day of month (1--31)
+               int tm_mon; // Month (0--11)
+               int tm_year; // Year (calendar year minus 1900)
+               int tm_wday; // Weekday (0--6; Sunday = 0)
+               int tm_yday; // Day of year (0--365)
+               int tm_isdst; // 0 if daylight savings time is not in effect)
+       };
+
+       gettimeofday(&mytime, NULL);
+       localtime_r(&mytime.tv_sec, &stTempTime);
+       g_snprintf(time_string, 128, "%04d.%02d.%02d-%02d_%02d_%02d",
+                       stTempTime.tm_year + 1900, stTempTime.tm_mon + 1, stTempTime.tm_mday,
+                       stTempTime.tm_hour, stTempTime.tm_min, stTempTime.tm_sec);
+       time_string[127] = '\0';
+
+       return time_string;
+}
+
+static int _start_dump(gchar *dump_path)
+{
+       int rv = 0;
+       gchar *path = NETWORK_DUMP_SCRIPT;
+       char *const args[] = { NETWORK_DUMP_SCRIPT, dump_path, NULL };
+       char *const envs[] = { NULL };
+
+       rv = netconfig_execute_file(path, args, envs);
+       if (rv < 0) {
+               ERR("Fail to execute network log dump shell");
+               return -EIO;
+       }
+       return 0;
+}
+
+static gboolean _stop_tcpdump(void)
+{
+       int ret;
+       const char *path = KILLALL_EXEC_PATH;
+       char *const args[] = { KILLALL_EXEC_PATH, "tcpdump", NULL };
+       char *const envs[] = { NULL };
+
+       if (!tcpdump_running) {
+               DBG("tcpdump is not running");
+               return FALSE;
+       }
+
+       ret = netconfig_execute_file(path, args, envs);
+       if (ret < 0) {
+               DBG("Failed to Kill tcpdump, ret : %d\n", ret);
+               return FALSE;
+       }
+
+       tcpdump_running = FALSE;
+
+       return TRUE;
+}
+
+static gboolean _start_tcpdump(void)
+{
+       int ret;
+       const char *start_path = TCPDUMP_EXEC_PATH;
+       char filename[128] = { 0, };
+       g_snprintf(filename, 128, "%s/tcpdump-%s.pcap", NETWORK_LOG_PATH, get_current_time());
+       char *const start_args[] = { TCPDUMP_EXEC_PATH,
+                       "-W", "5", "-C", "50", "-i", "any", "-s", "0", "-w", filename, NULL};
+
+       if (tcpdump_running) {
+               DBG("kill tcpdump.");
+               gboolean ret = _stop_tcpdump();
+               if (!ret)
+                       DBG("Failed to kill tcpdump.. ret : %d", ret);
+       }
+
+       ret = netconfig_execute_file_no_wait(start_path, start_args);
+       if (ret < 0) {
+               DBG("Failed to start tcpdump, ret : %d", ret);
+               return FALSE;
+       }
+
+       tcpdump_running = TRUE;
+
+       return tcpdump_running;
+}
+
+static gboolean _get_dump_state(void)
+{
+       int ret = access(TCP_DUMP_IN_BOOT_TIME, F_OK);
+       if (ret != 0) {
+               ERR("Dumpstate Get Failed (%d).", ret);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+gboolean handle_start_tcpdump(Tcpdump *object,
+               GDBusMethodInvocation *context)
+{
+       gboolean ret = FALSE;
+
+       ret = _start_tcpdump();
+       if (!ret) {
+               netconfig_error_dbus_method_return(context,
+                               NETCONFIG_ERROR_INTERNAL, "StartTCPDumpFailed");
+               return TRUE;
+       }
+
+       DBG("Successfully started tcpdump and running..");
+       tcpdump_complete_start_tcpdump(object, context);
+
+       return TRUE;
+}
+
+gboolean handle_stop_tcpdump(Tcpdump *object, GDBusMethodInvocation *context)
+{
+       gboolean ret = FALSE;
+
+       if (!tcpdump_running) {
+               DBG("tcpdump not running");
+               tcpdump_complete_stop_tcpdump(object, context);
+               return TRUE;
+       }
+
+       ret = _stop_tcpdump();
+       if (!ret) {
+               netconfig_error_dbus_method_return(context,
+                               NETCONFIG_ERROR_INTERNAL, "StopTCPDumpFailed");
+               return TRUE;
+       }
+
+       DBG("Successfully stopped tcpdump");
+       tcpdump_complete_stop_tcpdump(object, context);
+
+       return TRUE;
+}
+
+gboolean handle_get_tcpdump_state(Tcpdump *object, GDBusMethodInvocation *context)
+{
+       DBG("tcpdump %s running", tcpdump_running ? "is" : "is not");
+
+       tcpdump_complete_get_tcpdump_state(object, context, tcpdump_running);
+
+       return TRUE;
+}
+
+static void _send_dump_signal(const gchar *sig_name)
+{
+       gboolean reply;
+       GVariant *params;
+       GDBusConnection *connection = NULL;
+       GError *error = NULL;
+
+       connection = netdbus_get_connection();
+       if (connection == NULL) {
+               DBG("GDBusconnection is NULL");
+               return;
+       }
+
+       params = g_variant_new("(i)", getpid());
+       reply = g_dbus_connection_emit_signal(connection,
+                       NULL,
+                       DUMP_SERVICE_OBJECT_PATH,
+                       DUMP_SERVICE_INTERFACE,
+                       sig_name,
+                       params,
+                       &error);
+       if (reply != TRUE) {
+               if (error != NULL) {
+                       ERR("Failed to send signal [%s]", error->message);
+                       g_error_free(error);
+               }
+               return;
+       }
+}
+
+int netconfig_dump_log(const char *path)
+{
+       gchar *dump_path = NULL;
+
+       if (!path) {
+               ERR("path is NULL. Dump Fail");
+               return -1;
+       }
+       ERR("Dump is started");
+       _send_dump_signal(DUMP_START_SIGNAL);
+
+       dump_path = g_strdup(path);
+       _start_dump(dump_path);
+       _stop_tcpdump();
+       g_free(dump_path);
+
+       _send_dump_signal(DUMP_FINISH_SIGNAL);
+       ERR("Dump is finished");
+       return 0;
+}
+
+void check_dump_state_and_start(void)
+{
+       if (!_get_dump_state())
+               return;
+
+       if (!_start_tcpdump()) {
+               ERR("Failed to start tcpdump");
+               return;
+       }
+       DBG("Successfully started tcpdump and running..");
+
+}
index 794db9f..99b2d62 100755 (executable)
@@ -38,6 +38,9 @@
 #include "network-dpm.h"
 #include "network-monitor.h"
 #include "netsupplicant.h"
+#if defined TIZEN_DEBUG_ENABLE
+#include "network-dump.h"
+#endif
 
 #include "generated-code.h"
 /* Define TCP buffer sizes for various networks */
@@ -88,6 +91,9 @@ typedef struct {
 } net_profile_name_t;
 
 static Network *netconfigstate = NULL;
+#if defined TIZEN_DEBUG_ENABLE
+static Tcpdump *tcpdump_object = NULL;
+#endif
 
 struct netconfig_default_connection {
        char *profile;
@@ -1409,6 +1415,9 @@ void state_object_create_and_init(void)
 {
        DBG("Creating network state object");
        GDBusInterfaceSkeleton *interface_network = NULL;
+#if defined TIZEN_DEBUG_ENABLE
+       GDBusInterfaceSkeleton *interface_tcpdump = NULL;
+#endif
        GDBusConnection *connection = NULL;
        GDBusObjectManagerServer *server = netdbus_get_state_manager();
        if (server == NULL)
@@ -1452,9 +1461,30 @@ void state_object_create_and_init(void)
                        NETCONFIG_NETWORK_STATE_PATH, NULL)) {
                ERR("Export with path failed");
        }
+
+#if defined TIZEN_DEBUG_ENABLE
+       /*Interface netconfig.tcpdump*/
+       tcpdump_object = tcpdump_skeleton_new();
+
+       interface_tcpdump = G_DBUS_INTERFACE_SKELETON(tcpdump_object);
+       g_signal_connect(tcpdump_object, "handle-start-tcpdump",
+                               G_CALLBACK(handle_start_tcpdump), NULL);
+       g_signal_connect(tcpdump_object, "handle-stop-tcpdump",
+                               G_CALLBACK(handle_stop_tcpdump), NULL);
+       g_signal_connect(tcpdump_object, "handle-get-tcpdump-state",
+                               G_CALLBACK(handle_get_tcpdump_state), NULL);
+
+       if (!g_dbus_interface_skeleton_export(interface_tcpdump, connection,
+                       NETCONFIG_NETWORK_STATE_PATH, NULL)) {
+               ERR("Export with path failed");
+       }
+#endif
 }
 
 void state_object_deinit(void)
 {
        g_object_unref(netconfigstate);
+#if defined TIZEN_DEBUG_ENABLE
+       g_object_unref(tcpdump_object);
+#endif
 }
index a858856..f53b49a 100755 (executable)
@@ -39,6 +39,9 @@
 #include "wifi-background-scan.h"
 #include "wifi-tdls.h"
 #include "ip-conflict-detect.h"
+#if defined TIZEN_DEBUG_ENABLE
+#include "network-dump.h"
+#endif
 
 #define DBUS_SERVICE_DBUS                      "org.freedesktop.DBus"
 #define DBUS_INTERFACE_DBUS                    "org.freedesktop.DBus"
@@ -91,6 +94,9 @@ static const char supplicant_signals[SIG_MAX][MAX_SIG_LEN] = {
 };
 
 static int supp_subscription_ids[SIG_MAX] = {0};
+#if defined TIZEN_DEBUG_ENABLE
+static int dumpservice_subscription_id = 0;
+#endif
 
 typedef void (*supplicant_signal_cb)(GDBusConnection *conn,
                const gchar *name, const gchar *path, const gchar *interface,
@@ -585,9 +591,14 @@ static void _supplicant_driver_hanged(GDBusConnection *conn,
        DBG("Driver Hanged handling!");
        ERR("Critical. Wi-Fi firmware crashed");
 
+#if !defined TIZEN_WEARABLE
+       netconfig_send_message_to_net_popup("Wi-Fi Error",
+               "Wi-Fi Driver Hanged. Please get log dump and report", "popup", NULL);
+#endif
        wifi_power_recover_firmware();
 
        return;
+
 }
 
 static void _supplicant_session_overlapped(GDBusConnection *conn,
@@ -604,6 +615,28 @@ static void _supplicant_session_overlapped(GDBusConnection *conn,
 #endif
 }
 
+#if defined TIZEN_DEBUG_ENABLE
+static void __netconfig_dumpservice_handler(GDBusConnection *conn,
+               const gchar *name, const gchar *path, const gchar *interface,
+               const gchar *sig, GVariant *param, gpointer user_data)
+{
+       int mode;
+       gchar *signal_path = NULL;
+
+       if (param == NULL)
+               return;
+
+       g_variant_get(param, "(is)", &mode, &signal_path);
+       DBG("Path: %s and mode: %d", signal_path, mode);
+
+       netconfig_dump_log(signal_path);
+       if (signal_path)
+               g_free(signal_path);
+
+       return;
+}
+#endif
+
 static void _supplicant_tdls_connected(GDBusConnection *conn,
                const gchar *name, const gchar *path, const gchar *interface,
                const gchar *sig, GVariant *param, gpointer user_data)
@@ -941,6 +974,22 @@ void register_gdbus_signal(void)
 
        INFO("Successfully register Supplicant DBus signal filters");
 
+#if defined TIZEN_DEBUG_ENABLE
+       dumpservice_subscription_id = g_dbus_connection_signal_subscribe(
+                       connection,
+                       NULL,
+                       DUMP_SERVICE_INTERFACE,
+                       DUMP_SIGNAL,
+                       NULL,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       __netconfig_dumpservice_handler,
+                       NULL,
+                       NULL);
+
+       INFO("Successfully registered Dumpservice DBus signal filter");
+#endif
+
        /* In case ConnMan precedes this signal register,
         * net-config should update the default connected profile.
         */
@@ -972,4 +1021,8 @@ void deregister_gdbus_signal(void)
                }
        }
 
+#if defined TIZEN_DEBUG_ENABLE
+       g_dbus_connection_signal_unsubscribe(connection,
+                       dumpservice_subscription_id);
+#endif
 }
index 762fe24..77c2d2d 100755 (executable)
@@ -160,7 +160,7 @@ void netconfig_start_timer(guint msecs,
        }
 
        if ((timer_id != NULL && *timer_id != 0)) {
-               DBG("timer already is registered");
+               ERR("timer already is registered");
                return;
        }
 
@@ -531,6 +531,59 @@ int netconfig_execute_clatd(const char *file_path, char *const args[])
        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;
+
+       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");
+               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(errno));
+                       return -1;
+               }
+       } else if (pid > 0) {
+               ERR("Successfully launched child process");
+               return rv;
+       }
+
+       DBG("failed to fork(%s)", strerror(errno));
+       return -EIO;
+}
+
 int __netconfig_get_interface_index(const char *interface_name)
 {
        struct ifreq ifr;