X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fsignal-handler.c;h=80fd0836e2552e49728b83f2271ddc26d45e4e99;hb=7545661a1bd62733bb4334e630b84bbf64ffdfe0;hp=81a657e3f259499727bbc763e9fed4b610ba4f9b;hpb=c25daf55a3f87084d8816b469670404d6ee57549;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git diff --git a/src/signal-handler.c b/src/signal-handler.c index 81a657e..80fd083 100755 --- a/src/signal-handler.c +++ b/src/signal-handler.c @@ -18,15 +18,18 @@ */ #include +#include #include #include #include +#include #include "log.h" #include "util.h" #include "netdbus.h" #include "neterror.h" #include "wifi-wps.h" +#include "wifi-bssid-scan.h" #include "wifi-agent.h" #include "wifi-power.h" #include "wifi-state.h" @@ -34,9 +37,14 @@ #include "network-state.h" #include "cellular-state.h" #include "signal-handler.h" -#include "wifi-ssid-scan.h" #include "wifi-background-scan.h" #include "wifi-tdls.h" +#include "ip-conflict-detect.h" +#if defined TIZEN_DEBUG_ENABLE +#include "network-dump.h" +#define NETWORK_LOG_DUMP_SCRIPT "/opt/var/lib/net-config/network_log_dump.sh" +#define MAX_SIZE_ERROR_BUFFER 256 +#endif #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" @@ -60,6 +68,7 @@ #define MAX_SIG_LEN 64 #define TOTAL_CONN_SIGNALS 5 +#define MAX_SOCKET_OPEN_RETRY 5 typedef enum { SIG_INTERFACE_REMOVED = 0, @@ -88,6 +97,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, @@ -96,56 +108,157 @@ typedef void (*connman_signal_cb)(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data); -static void __netconfig_extract_ipv4_signal_data(GVariant *dictionary, const gchar *profile) +static void __netconfig_extract_ipv4_signal_data(GVariant *dictionary, + const gchar *profile) { gchar *key = NULL; const gchar *value = NULL; GVariant *var = NULL; GVariantIter iter; + GVariantBuilder *builder; + GVariant *params; g_variant_iter_init(&iter, dictionary); while (g_variant_iter_loop(&iter, "{sv}", &key, &var)) { if (g_strcmp0(key, "Address") == 0) { - value = g_variant_get_string(var, NULL); + g_variant_get(var, "&s", &value); char *old_ip = vconf_get_str(VCONFKEY_NETWORK_IP); - DBG("Old IPv4.Address [%s] Received new IPv4.Address [%s]", old_ip, value); + DBG("Old IPv4.Address [%s] Received new IPv4.Address [%s]", old_ip, + value); if (g_strcmp0(old_ip, value) != 0) { - if (value == NULL && strlen(old_ip) > 0) - vconf_set_str(VCONFKEY_NETWORK_IP, ""); - else + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + + if (value != NULL) { vconf_set_str(VCONFKEY_NETWORK_IP, value); + g_variant_builder_add(builder, "{sv}", "IPv4Address", + g_variant_new_string(value)); + } else if (old_ip != NULL && strlen(old_ip) > 0) { + vconf_set_str(VCONFKEY_NETWORK_IP, ""); + g_variant_builder_add(builder, "{sv}", "IPv4Address", + g_variant_new_string("")); + } + + params = g_variant_new("(@a{sv})", + g_variant_builder_end(builder)); + + netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH, + NETCONFIG_NETWORK_INTERFACE, "NetworkConfigChanged", + params); } free(old_ip); } } } -static void __netconfig_extract_ipv6_signal_data(GVariant *dictionary, const gchar *profile) +static void __netconfig_extract_ipv6_signal_data(GVariant *dictionary, + const gchar *profile) { gchar *key = NULL; const gchar *value = NULL; GVariant *var = NULL; GVariantIter iter; + GVariantBuilder *builder; + GVariant *params; g_variant_iter_init(&iter, dictionary); while (g_variant_iter_loop(&iter, "{sv}", &key, &var)) { if (g_strcmp0(key, "Address") == 0) { - value = g_variant_get_string(var, NULL); + g_variant_get(var, "&s", &value); char *old_ip6 = vconf_get_str(VCONFKEY_NETWORK_IP6); - DBG("Old IPv6.Address [%s] Received new IPv6.Address [%s]", old_ip6, value); + DBG("Old IPv6.Address [%s] Received new IPv6.Address [%s]", old_ip6, + value); if (g_strcmp0(old_ip6, value) != 0) { - if (value == NULL && strlen(old_ip6) > 0) - vconf_set_str(VCONFKEY_NETWORK_IP6, ""); - else + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + + if (value != NULL) { vconf_set_str(VCONFKEY_NETWORK_IP6, value); + g_variant_builder_add(builder, "{sv}", "IPv6Address", + g_variant_new_string(value)); + } else if (old_ip6 != NULL && strlen(old_ip6) > 0) { + vconf_set_str(VCONFKEY_NETWORK_IP6, ""); + g_variant_builder_add(builder, "{sv}", "IPv6Address", + g_variant_new_string("")); + } + + params = g_variant_new("(@a{sv})", + g_variant_builder_end(builder)); + + netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH, + NETCONFIG_NETWORK_INTERFACE, "NetworkConfigChanged", + params); } free(old_ip6); } } } +#if defined TIZEN_DEBUG_ENABLE +static int __netconfig_handle_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())) { + 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; +} + +static int _start_dump() +{ + int rv = 0; + gchar *path = NETWORK_LOG_DUMP_SCRIPT; + char *const args[] = { NETWORK_LOG_DUMP_SCRIPT, NULL }; + char *const envs[] = { NULL }; + + rv = __netconfig_handle_execute_file(path, args, envs); + if (rv < 0) { + ERR("Fail to execute network log dump shell"); + return -EIO; + } + return 0; +} +#endif + static void _technology_signal_cb(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data) @@ -186,13 +299,16 @@ static void _technology_signal_cb(GDBusConnection *conn, static void _service_signal_cb(GDBusConnection *conn, const gchar *name, const gchar *path, - const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data) + const gchar *interface, const gchar *sig, + GVariant *param, gpointer user_data) { gchar *sigvalue = NULL; gchar *property; GVariant *variant = NULL, *var; GVariantIter *iter; const gchar *value = NULL; + struct sock_data *sd = NULL; + int idx = 0; if (path == NULL || param == NULL) goto done; @@ -208,6 +324,20 @@ static void _service_signal_cb(GDBusConnection *conn, g_variant_get(variant, "s", &property); DBG("[%s] %s", property, path); + if (netconfig_is_wifi_profile(path) || netconfig_is_ethernet_profile(path)) { + if (g_strcmp0(property, "ready") == 0) { + for (idx = 0; idx < MAX_SOCKET_OPEN_RETRY; idx++) { + sd = start_ip_conflict_mon(); + if (sd != NULL) + break; + } + } else if (g_strcmp0(property, "online") == 0) { + // do nothing + } else { + stop_ip_conflict_mon(); + } + } + if (netconfig_is_wifi_profile(path) == TRUE) { int wifi_state = 0; @@ -331,9 +461,13 @@ static void _service_signal_cb(GDBusConnection *conn, g_variant_get(variant, "a{sv}", &iter); while (g_variant_iter_loop(iter, "{sv}", &property, &var)) { + GVariantBuilder *builder; + GVariant *sig_params; if (g_strcmp0(property, "Servers") == 0) { GVariantIter *iter_sub = NULL; + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + g_variant_get(var, "as", &iter_sub); g_variant_iter_loop(iter_sub, "s", &value); g_variant_iter_free(iter_sub); @@ -341,6 +475,16 @@ static void _service_signal_cb(GDBusConnection *conn, DBG("Proxy - [%s]", value); vconf_set_str(VCONFKEY_NETWORK_PROXY, value); + g_variant_builder_add(builder, "{sv}", "ProxyAddress", + g_variant_new_string(value)); + + sig_params = g_variant_new("(@a{sv})", + g_variant_builder_end(builder)); + + netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH, + NETCONFIG_NETWORK_INTERFACE, "NetworkConfigChanged", + sig_params); + g_free(property); g_variant_unref(var); break; @@ -348,8 +492,20 @@ static void _service_signal_cb(GDBusConnection *conn, value = g_variant_get_string(var, NULL); DBG("Method - [%s]", value); - if (g_strcmp0(value, "direct") == 0) + if (g_strcmp0(value, "direct") == 0) { + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + vconf_set_str(VCONFKEY_NETWORK_PROXY, ""); + g_variant_builder_add(builder, "{sv}", "ProxyAddress", + g_variant_new_string("")); + + sig_params = g_variant_new("(@a{sv})", + g_variant_builder_end(builder)); + + netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH, + NETCONFIG_NETWORK_INTERFACE, + "NetworkConfigChanged", sig_params); + } g_free(property); g_variant_unref(var); @@ -365,6 +521,17 @@ static void _service_signal_cb(GDBusConnection *conn, } else if (g_strcmp0(sigvalue, "Error") == 0) { g_variant_get(variant, "s", &property); INFO("[%s] Property : %s", sigvalue, property); +#if defined TIZEN_DEBUG_ENABLE + if (g_strcmp0(property, "dhcp-failed") == 0 + || g_strcmp0(property, "connect-failed") == 0 + || g_strcmp0(property, "login-failed") == 0 + || g_strcmp0(property, "auth-failed") == 0 + || g_strcmp0(property, "invalid-key") == 0) { + + INFO("start dump"); + _start_dump(); + } +#endif g_free(property); } done: @@ -432,7 +599,7 @@ static void _services_changed_cb(GDBusConnection *conn, const gchar *name, is_cell_internet_prof = netconfig_is_cellular_internet_profile( service_path); if (service_path != NULL) { - while (g_variant_iter_loop(next, "{sv}", &property, + while (next && g_variant_iter_loop(next, "{sv}", &property, &variant)) { if (g_strcmp0(property, "State") == 0) { g_variant_get(variant, "s", &value); @@ -486,8 +653,8 @@ static void _supplicant_interface_removed(GDBusConnection *conn, const gchar *sig, GVariant *param, gpointer user_data) { DBG("Interface removed handling!"); - if (netconfig_wifi_is_wps_enabled() == TRUE) - netconfig_wifi_wps_signal_scanaborted(); + if (netconfig_wifi_is_bssid_scan_started() == TRUE) + netconfig_wifi_bssid_signal_scanaborted(); return; } @@ -497,9 +664,10 @@ static void _supplicant_properties_changed(GDBusConnection *conn, const gchar *sig, GVariant *param, gpointer user_data) { DBG("Properties changed handling!"); - gchar *key; - GVariantIter *iter; - GVariant *variant; + gchar *key = NULL; + const gchar *state = NULL; + GVariantIter *iter = NULL; + GVariant *variant = NULL; gboolean scanning = FALSE; if (param == NULL) @@ -509,12 +677,42 @@ static void _supplicant_properties_changed(GDBusConnection *conn, while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) { if (g_strcmp0(key, "Scanning") == 0) { scanning = g_variant_get_boolean(variant); + DBG("setting scanning %s", scanning ? "TRUE" : "FALSE"); if (scanning == TRUE) netconfig_wifi_set_scanning(TRUE); + else + netconfig_wifi_set_scanning(FALSE); g_variant_unref(variant); g_free(key); + variant = NULL; + key = NULL; break; + } else if (g_strcmp0(key, "State") == 0) { + state = g_variant_get_string(variant, NULL); + if (state != NULL) + ERR("Supplicant state : %s", state); + + g_variant_unref(variant); + g_free(key); + variant = NULL; + key = NULL; + break; + } else if (g_strcmp0(key, "DisconnectReason") == 0) { + int reason = g_variant_get_int32(variant); + ERR("Supplicant DisconnReason : %d", reason); + + g_variant_unref(variant); + g_free(key); + variant = NULL; + key = NULL; + break; + } else { + gchar *value; + value = g_variant_print(variant, TRUE); + DBG("Supplicant %s : %s", key, value); + + g_free(value); } } @@ -528,10 +726,7 @@ static void _supplicant_bss_added(GDBusConnection *conn, const gchar *sig, GVariant *param, gpointer user_data) { DBG("BSS added handling!"); - if (wifi_ssid_scan_get_state() == TRUE) - wifi_ssid_scan_add_bss(param); - else - wifi_state_set_bss_found(TRUE); + wifi_state_set_bss_found(TRUE); return; } @@ -543,18 +738,13 @@ static void _supplicant_scan_done(GDBusConnection *conn, DBG("Scan Done handling!"); netconfig_wifi_set_scanning(FALSE); - if (netconfig_wifi_is_wps_enabled() == TRUE) { - netconfig_wifi_wps_signal_scandone(); + if (netconfig_wifi_is_bssid_scan_started() == TRUE) { + netconfig_wifi_bssid_signal_scandone(); if (wifi_state_get_technology_state() < NETCONFIG_WIFI_TECH_POWERED) return; } - if (netconfig_wifi_get_bgscan_state() != TRUE) { - if (wifi_ssid_scan_get_state() == TRUE) - wifi_ssid_scan_emit_scan_completed(); - else - wifi_ssid_scan(NULL); - } else { + if (netconfig_wifi_get_bgscan_state() == TRUE) { if (wifi_state_get_technology_state() >= NETCONFIG_WIFI_TECH_POWERED) netconfig_wifi_bgscan_start(FALSE); @@ -572,9 +762,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, @@ -591,6 +786,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) @@ -691,7 +908,7 @@ static void _supplicant_wifi_wps_event(GVariant *param) g_variant_get(param, "(sa{sv})", &name, &iter); INFO("Event Result: %s", name); - if (g_strcmp0(name, "failed") == 0) { + if (g_strcmp0(name, "fail") == 0) { while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) { if (key == NULL) goto error; @@ -723,8 +940,8 @@ error: static void _supplicant_wifi_wps_credentials(GVariant *param) { gchar *key; - char ssid[32]; - char wps_key[100]; + char ssid[32] = {0, }; + char wps_key[100] = {0, }; GVariantIter *iter; GVariant *variant; int config_error = 0; @@ -928,6 +1145,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. */ @@ -959,4 +1192,8 @@ void deregister_gdbus_signal(void) } } +#if defined TIZEN_DEBUG_ENABLE + g_dbus_connection_signal_unsubscribe(connection, + dumpservice_subscription_id); +#endif }