X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fsignal-handler.c;h=4fe67ad328540f444c8264af1b3f931651233b52;hb=refs%2Fchanges%2F51%2F179351%2F1;hp=822a7ba788643fe561a88e0e4466c7e5b49dbb23;hpb=5cc540a651f7ca00edcfc0df492ac12cd8585f28;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git diff --git a/src/signal-handler.c b/src/signal-handler.c old mode 100644 new mode 100755 index 822a7ba..4fe67ad --- a/src/signal-handler.c +++ b/src/signal-handler.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. @@ -18,352 +18,1103 @@ */ #include +#include #include -#include - #include #include #include "log.h" #include "util.h" #include "netdbus.h" -#include "netsupplicant.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" -#include "wifi-indicator.h" -#include "wifi-ssid-scan.h" -#include "wifi-background-scan.h" +#include "netsupplicant.h" #include "network-state.h" -#include "neterror.h" -#include "wifi.h" - -#define SIGNAL_SCAN_DONE "ScanDone" -#define SIGNAL_BSS_ADDED "BSSAdded" -#define SIGNAL_PROPERTIES_CHANGED "PropertiesChanged" +#include "cellular-state.h" +#include "signal-handler.h" +#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" +#define SIGNAL_INTERFACE_REMOVED "InterfaceRemoved" +#define SIGNAL_SCAN_DONE "ScanDone" +#define SIGNAL_BSS_ADDED "BSSAdded" +#define SIGNAL_PROPERTIES_CHANGED "PropertiesChanged" +#define SIGNAL_PROPERTIES_DRIVER_HANGED "DriverHanged" +#define SIGNAL_PROPERTIES_SESSION_OVERLAPPED "SessionOverlapped" +#define SIGNAL_TDLS_CONNECTED "TDLSConnected" +#define SIGNAL_TDLS_DISCONNECTED "TDLSDisconnected" +#define SIGNAL_TDLS_PEER_FOUND "TDLSPeerFound" + +#define SIGNAL_WPS_CONNECTED "WPSConnected" +#define SIGNAL_WPS_EVENT "Event" +#define SIGNAL_WPS_CREDENTIALS "Credentials" #define CONNMAN_SIGNAL_SERVICES_CHANGED "ServicesChanged" #define CONNMAN_SIGNAL_PROPERTY_CHANGED "PropertyChanged" +#define CONNMAN_SIGNAL_NAME_CHANGED "NameOwnerChanged" + +#define MAX_SIG_LEN 64 +#define TOTAL_CONN_SIGNALS 5 +#define MAX_SOCKET_OPEN_RETRY 5 + +typedef enum { + SIG_INTERFACE_REMOVED = 0, + SIG_PROPERTIES_CHANGED, + SIG_BSS_ADDED, + SIG_SCAN_DONE, + SIG_DRIVER_HANGED, + SIG_SESSION_OVERLAPPED, + SIG_TDLS_CONNECTED, + SIG_TDLS_DISCONNECTED, + SIG_TDLS_PEER_FOUND, + SIG_MAX +} SuppSigArrayIndex; + +static int conn_subscription_ids[TOTAL_CONN_SIGNALS] = {0}; +static const char supplicant_signals[SIG_MAX][MAX_SIG_LEN] = { + SIGNAL_INTERFACE_REMOVED, + SIGNAL_PROPERTIES_CHANGED, + SIGNAL_BSS_ADDED, + SIGNAL_SCAN_DONE, + SIGNAL_PROPERTIES_DRIVER_HANGED, + SIGNAL_PROPERTIES_SESSION_OVERLAPPED, + SIGNAL_TDLS_CONNECTED, + SIGNAL_TDLS_DISCONNECTED, + SIGNAL_TDLS_PEER_FOUND, +}; + +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, + const gchar *sig, GVariant *param, gpointer user_data); +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) +{ + 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) { + 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); + if (g_strcmp0(old_ip, value) != 0) { + 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("")); + } -#define CONNMAN_MANAGER_SIGNAL_FILTER "type='signal',interface='net.connman.Manager'" -#define CONNMAN_TECHNOLOGY_SIGNAL_FILTER "type='signal',interface='net.connman.Technology'" -#define CONNMAN_SERVICE_SIGNAL_FILTER "type='signal',interface='net.connman.Service'" -#define SUPPLICANT_INTERFACE_SIGNAL_FILTER "type='signal',interface='fi.w1.wpa_supplicant1.Interface'" - + params = g_variant_new("(@a{sv})", + g_variant_builder_end(builder)); -static DBusConnection *signal_connection = NULL; + netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH, + NETCONFIG_NETWORK_INTERFACE, "NetworkConfigChanged", + params); + } + free(old_ip); + } + } +} -static char *__netconfig_get_property(DBusMessage *msg, int *prop_value) +static void __netconfig_extract_ipv6_signal_data(GVariant *dictionary, + const gchar *profile) { - DBusMessageIter args, variant; - char *property = NULL; - dbus_bool_t data; - - /** read these parameters */ - if (!dbus_message_iter_init(msg, &args)) { - ERR("Message does not have parameters"); - } else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { - ERR("Argument is not string"); - } else { - dbus_message_iter_get_basic(&args, &property); - dbus_message_iter_next(&args); - dbus_message_iter_recurse(&args, &variant); - /* Right now, checking for only 'Powered' property which has - * Boolean type values - */ - if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_BOOLEAN) { - dbus_message_iter_get_basic(&variant, &data); - if (data) - *prop_value = TRUE; - else - *prop_value = FALSE; - } else { - *prop_value = FALSE; + 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) { + 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); + if (g_strcmp0(old_ip6, value) != 0) { + 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); } } - - return property; } -static void __netconfig_technology_signal_handler(DBusMessage *msg) +static void _technology_signal_cb(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) { - char *key = NULL; - const char *tech = NULL; - dbus_bool_t value = FALSE; + gchar *key = NULL; + gboolean value = FALSE; + GVariant *var = NULL; - if (netconfig_dbus_get_basic_params_string(msg, - &key, DBUS_TYPE_BOOLEAN, &value) != TRUE) + if (param == NULL) return; - tech = dbus_message_get_path(msg); - if (key == NULL || tech == NULL) - return; - - if (g_str_has_prefix(tech, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == TRUE) { - INFO("Wi-Fi Technology %s, property %d", key, value); - + if (g_str_has_prefix(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == TRUE) { + g_variant_get(param, "(sv)", &key, &var); if (g_strcmp0(key, "Powered") == 0) { /* Power state */ + value = g_variant_get_boolean(var); if (value == TRUE) - netconfig_wifi_update_power_state(TRUE); + wifi_state_update_power_state(TRUE); else - netconfig_wifi_update_power_state(FALSE); + wifi_state_update_power_state(FALSE); } else if (g_strcmp0(key, "Connected") == 0) { /* Connection state */ + value = g_variant_get_boolean(var); + if (value == TRUE) + wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_CONNECTED); + else + wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_POWERED); } else if (g_strcmp0(key, "Tethering") == 0) { /* Tethering state */ + wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_TETHERED); } - } else if (g_str_has_prefix(tech, - CONNMAN_CELLULAR_TECHNOLOGY_PREFIX) == TRUE) { - /* Cellular technology state */ + if (key) + g_free(key); + if (var) + g_variant_unref(var); } } -static void __netconfig_wifi_service_state_signal_handler(DBusMessage *msg) +static void _service_signal_cb(GDBusConnection *conn, + const gchar *name, const gchar *path, + const gchar *interface, const gchar *sig, + GVariant *param, gpointer user_data) { - char *sigvalue = NULL; - char *property = NULL; - char *service_profile = NULL; - DBusMessageIter args, variant; + 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; + + g_variant_get(param, "(sv)", &sigvalue, &variant); + if (sigvalue == NULL) + goto done; - service_profile = (char *)dbus_message_get_path(msg); - if (service_profile == NULL) - return; + if (g_strcmp0(sig, CONNMAN_SIGNAL_PROPERTY_CHANGED) != 0) + goto done; - dbus_message_iter_init(msg, &args); - dbus_message_iter_get_basic(&args, &sigvalue); - if (sigvalue == NULL) - return; + if (g_strcmp0(sigvalue, "State") == 0) { + g_variant_get(variant, "s", &property); - if (g_str_equal(sigvalue, "State") == TRUE) { - dbus_message_iter_next(&args); - dbus_message_iter_recurse(&args, &variant); - dbus_message_iter_get_basic(&variant, &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(); + } + } - DBG("[%s] %s", property, service_profile); - if (netconfig_is_wifi_profile(service_profile) == TRUE) { + if (netconfig_is_wifi_profile(path) == TRUE) { int wifi_state = 0; - vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); - if (wifi_state == VCONFKEY_WIFI_OFF) - return; + netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); + if (wifi_state == VCONFKEY_WIFI_OFF) { + g_free(property); + goto done; + } - if (g_str_equal(property, "ready") == TRUE || - g_str_equal(property, "online") == TRUE) { - if (wifi_state >= VCONFKEY_WIFI_CONNECTED) - return; + if (g_strcmp0(property, "ready") == 0 || g_strcmp0(property, "online") == 0) { + if (wifi_state >= VCONFKEY_WIFI_CONNECTED) { + g_free(property); + goto done; + } - netconfig_set_default_profile(service_profile); + netconfig_update_default_profile(path); - netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTED); + wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTED); - } else if (g_str_equal(property, "failure") == TRUE || - g_str_equal(property, "disconnect") == TRUE || - g_str_equal(property, "idle") == TRUE) { + } else if (g_strcmp0(property, "failure") == 0 || g_strcmp0(property, "disconnect") == 0 || g_strcmp0(property, "idle") == 0) { if (netconfig_get_default_profile() == NULL || netconfig_is_wifi_profile(netconfig_get_default_profile()) != TRUE) { - netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_IDLE); - return; + if (g_strcmp0(property, "failure") == 0) + wifi_state_set_service_state(NETCONFIG_WIFI_FAILURE); + else + wifi_state_set_service_state(NETCONFIG_WIFI_IDLE); + g_free(property); + goto done; } - if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) - return; + if (g_strcmp0(path, netconfig_get_default_profile()) != 0) { + g_free(property); + goto done; + } - netconfig_set_default_profile(NULL); + netconfig_update_default_profile(NULL); - netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_IDLE); + if (g_strcmp0(property, "failure") == 0) + wifi_state_set_service_state(NETCONFIG_WIFI_FAILURE); + else + wifi_state_set_service_state(NETCONFIG_WIFI_IDLE); - } else if (g_str_equal(property, "association") == TRUE || - g_str_equal(property, "configuration") == TRUE) { + } else if (g_strcmp0(property, "association") == 0 || g_strcmp0(property, "configuration") == 0) { if (netconfig_get_default_profile() == NULL || - netconfig_is_wifi_profile(netconfig_get_default_profile()) - != TRUE) { - netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTING); - return; + netconfig_is_wifi_profile(netconfig_get_default_profile()) != TRUE) { + if (g_strcmp0(property, "association") == 0) + wifi_state_set_service_state(NETCONFIG_WIFI_ASSOCIATION); + else + wifi_state_set_service_state(NETCONFIG_WIFI_CONFIGURATION); + g_free(property); + goto done; + } + + if (g_strcmp0(path, netconfig_get_default_profile()) != 0) { + g_free(property); + goto done; } - if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) - return; + netconfig_update_default_profile(NULL); - netconfig_set_default_profile(NULL); + if (g_strcmp0(property, "association") == 0) + wifi_state_set_service_state(NETCONFIG_WIFI_ASSOCIATION); + else + wifi_state_set_service_state(NETCONFIG_WIFI_CONFIGURATION); - netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTING); } } else { - if (g_str_equal(property, "ready") == TRUE || - g_str_equal(property, "online") == TRUE) { - if (netconfig_get_default_profile() == NULL) - netconfig_set_default_profile(service_profile); + if (g_strcmp0(property, "ready") == 0 || g_strcmp0(property, "online") == 0) { + if (netconfig_get_default_profile() == NULL) { + if (!netconfig_is_cellular_profile(path)) + netconfig_update_default_profile(path); + else { + if (netconfig_is_cellular_internet_profile(path)) + netconfig_update_default_profile(path); + } + } + + if (netconfig_is_cellular_profile(path) && netconfig_is_cellular_internet_profile(path)) + cellular_state_set_service_state(NETCONFIG_CELLULAR_ONLINE); - } else if (g_str_equal(property, "failure") == TRUE || - g_str_equal(property, "disconnect") == TRUE || - g_str_equal(property, "idle") == TRUE) { - if (netconfig_get_default_profile() == NULL) - return; + } else if (g_strcmp0(property, "failure") == 0 || g_strcmp0(property, "disconnect") == 0 || g_strcmp0(property, "idle") == 0) { + if (netconfig_get_default_profile() == NULL) { + g_free(property); + goto done; + } + + if (netconfig_is_cellular_profile(path) && netconfig_is_cellular_internet_profile(path)) + cellular_state_set_service_state(NETCONFIG_CELLULAR_IDLE); - if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) - return; + if (g_strcmp0(path, netconfig_get_default_profile()) != 0) { + g_free(property); + goto done; + } - netconfig_set_default_profile(NULL); + netconfig_update_default_profile(NULL); + } else if (g_strcmp0(property, "association") == 0 || g_strcmp0(property, "configuration") == 0) { + if (netconfig_get_default_profile() == NULL) { + g_free(property); + goto done; + } - } else if (g_str_equal(property, "association") == TRUE || - g_str_equal(property, "configuration") == TRUE) { - if (netconfig_get_default_profile() == NULL) - return; + if (netconfig_is_cellular_profile(path) && netconfig_is_cellular_internet_profile(path)) + cellular_state_set_service_state(NETCONFIG_CELLULAR_CONNECTING); - if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) - return; + if (g_strcmp0(path, netconfig_get_default_profile()) != 0) { + g_free(property); + goto done; + } - netconfig_set_default_profile(NULL); + netconfig_update_default_profile(NULL); } } + g_free(property); + } else if (g_strcmp0(sigvalue, "Proxy") == 0) { + if (netconfig_is_wifi_profile(path) != TRUE || g_strcmp0(path, netconfig_get_default_profile()) != 0) + goto done; + + if (!g_variant_type_equal(variant, G_VARIANT_TYPE_ARRAY)) + goto done; + + 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); + + 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; + } else if (g_strcmp0(property, "Method") == 0) { + value = g_variant_get_string(var, NULL); + DBG("Method - [%s]", value); + + 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); + break; + } + } + + g_variant_iter_free(iter); + } else if (g_strcmp0(sigvalue, "IPv4") == 0) { + __netconfig_extract_ipv4_signal_data(variant, path); + } else if (g_strcmp0(sigvalue, "IPv6") == 0) { + __netconfig_extract_ipv6_signal_data(variant, path); + } else if (g_strcmp0(sigvalue, "Error") == 0) { + g_variant_get(variant, "s", &property); + INFO("[%s] Property : %s", sigvalue, property); + g_free(property); } +done: + if (sigvalue) + g_free(sigvalue); + + if (variant) + g_variant_unref(variant); + + return; +} + +static void _dbus_name_changed_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; + + if (param == NULL) + return; + + g_variant_get(param, "(sss)", &name, &old, &new); + + if (g_strcmp0(name, CONNMAN_SERVICE) == 0 && *new == '\0') { + DBG("ConnMan destroyed: name %s, old %s, new %s", name, old, new); + + connman_register_agent(); + } + if (name) + g_free(name); + if (old) + g_free(old); + if (new) + g_free(new); + + return; } -static DBusHandlerResult __netconfig_signal_filter_handler( - DBusConnection *conn, DBusMessage *msg, void *user_data) +static void _services_changed_cb(GDBusConnection *conn, const gchar *name, + const gchar *path, const gchar *interface, const gchar *sig, + GVariant *param, gpointer user_data) { - char *sigvalue = NULL; + gchar *property, *value; + gchar *service_path; + GVariant *variant = NULL; + GVariantIter *added = NULL, *removed = NULL, *next = NULL; - if (msg == NULL) { - DBG("Invalid Message. Ignore"); - return DBUS_HANDLER_RESULT_HANDLED; + if (path == NULL || param == NULL) + return; + + if (g_strcmp0(sig, CONNMAN_SIGNAL_SERVICES_CHANGED) != 0) + return; + + if (netconfig_get_default_profile() != NULL) + return; + + g_variant_get(param, "(a(oa{sv})ao)", &added, &removed); + + while (g_variant_iter_loop(added, "(oa{sv})", &service_path, &next)) { + gboolean is_wifi_prof, is_cell_prof, is_cell_internet_prof; + is_wifi_prof = netconfig_is_wifi_profile(service_path); + is_cell_prof = netconfig_is_cellular_profile(service_path); + is_cell_internet_prof = netconfig_is_cellular_internet_profile( + service_path); + if (service_path != NULL) { + while (next && g_variant_iter_loop(next, "{sv}", &property, + &variant)) { + if (g_strcmp0(property, "State") == 0) { + g_variant_get(variant, "s", &value); + DBG("Profile %s State %s", service_path, + value); + if (g_strcmp0(value, "ready") != 0 && + g_strcmp0(value, + "online") != 0) { + g_free(property); + g_free(value); + g_variant_unref(variant); + break; + } + + if (!is_cell_prof) + netconfig_update_default_profile( + service_path); + else if (is_cell_internet_prof) { + netconfig_update_default_profile( + service_path); + } + if (is_wifi_prof) + wifi_state_set_service_state( + NETCONFIG_WIFI_CONNECTED); + else if (is_cell_prof && + is_cell_internet_prof) + cellular_state_set_service_state( + NETCONFIG_CELLULAR_ONLINE); + g_free(property); + g_free(value); + g_variant_unref(variant); + break; + } + } + } } - if (dbus_message_is_signal(msg, CONNMAN_MANAGER_INTERFACE, - CONNMAN_SIGNAL_PROPERTY_CHANGED)) { - /* We have handled this message, don't pass it on */ - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, CONNMAN_TECHNOLOGY_INTERFACE, - CONNMAN_SIGNAL_PROPERTY_CHANGED)) { - __netconfig_technology_signal_handler(msg); - - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, CONNMAN_SERVICE_INTERFACE, - CONNMAN_SIGNAL_PROPERTY_CHANGED)) { - __netconfig_wifi_service_state_signal_handler(msg); - - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, CONNMAN_MANAGER_INTERFACE, - CONNMAN_SIGNAL_SERVICES_CHANGED)) { - DBG("Received CONNMAN_SIGNAL_SERVICES_CHANGED message"); - netconfig_wifi_check_network_notification(msg); - - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface", - SIGNAL_PROPERTIES_CHANGED)) { - dbus_bool_t scanning = FALSE; - void *property = &scanning; - - if (netconfig_dbus_get_basic_params_array(msg, - &sigvalue, &property) != TRUE) - return DBUS_HANDLER_RESULT_HANDLED; - - if (sigvalue == NULL) - return DBUS_HANDLER_RESULT_HANDLED; - - if (scanning == TRUE) - netconfig_wifi_set_scanning(TRUE); - - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface", - SIGNAL_BSS_ADDED)) { - if (netconfig_wifi_get_ssid_scan_state() == TRUE) - netconfig_wifi_bss_added(msg); - - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface", - SIGNAL_SCAN_DONE)) { - netconfig_wifi_set_scanning(FALSE); - - if (netconfig_wifi_get_bgscan_state() != TRUE) { - if (netconfig_wifi_get_ssid_scan_state() == TRUE) - netconfig_wifi_notify_ssid_scan_done(); + g_variant_iter_free(added); + + if (next) + g_variant_iter_free(next); + + if (removed) + g_variant_iter_free(removed); + + return; +} + +static void _supplicant_interface_removed(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + DBG("Interface removed handling!"); + if (netconfig_wifi_is_bssid_scan_started() == TRUE) + netconfig_wifi_bssid_signal_scanaborted(); + + return; +} + +static void _supplicant_properties_changed(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + DBG("Properties changed handling!"); + gchar *key = NULL; + const gchar *state = NULL; + GVariantIter *iter = NULL; + GVariant *variant = NULL; + gboolean scanning = FALSE; + + if (param == NULL) + return; + + g_variant_get(param, "(a{sv})", &iter); + 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_ssid_scan(NULL); + 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); } + } + + g_variant_iter_free(iter); + + return; +} + +static void _supplicant_bss_added(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + DBG("BSS added handling!"); + wifi_state_set_bss_found(TRUE); - return DBUS_HANDLER_RESULT_HANDLED; + return; +} + +static void _supplicant_scan_done(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + DBG("Scan Done handling!"); + netconfig_wifi_set_scanning(FALSE); + + if (netconfig_wifi_is_bssid_scan_started() == TRUE) { + netconfig_wifi_bssid_signal_scandone(); + if (wifi_state_get_technology_state() < NETCONFIG_WIFI_TECH_POWERED) + return; } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + if (netconfig_wifi_get_bgscan_state() == TRUE) { + if (wifi_state_get_technology_state() >= + NETCONFIG_WIFI_TECH_POWERED) + netconfig_wifi_bgscan_start(FALSE); + + wifi_start_timer_network_notification(); + } + + return; } -void netconfig_register_signal(void) +static void _supplicant_driver_hanged(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) { - DBusConnection *conn = NULL; - DBusError err; + 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(); - DBG("Register DBus signal filters"); + return; - dbus_error_init(&err); - conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); - if (conn == NULL) { - ERR("Error! Failed to connect to the D-BUS daemon: [%s]", - err.message); - dbus_error_free(&err); +} + +static void _supplicant_session_overlapped(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + DBG("Driver session overlapped handling!"); + ERR("WPS PBC SESSION OVERLAPPED"); +#if defined TIZEN_WEARABLE + return; +#else + netconfig_send_message_to_net_popup("WPS Error", + "wps session overlapped", "popup", NULL); +#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; - } - signal_connection = conn; + g_variant_get(param, "(is)", &mode, &signal_path); + DBG("Path: %s and mode: %d", signal_path, mode); - dbus_connection_setup_with_g_main(conn, NULL); + netconfig_dump_log(signal_path); + if (signal_path) + g_free(signal_path); - /* listening to messages from all objects as no path is specified */ - /* see signals from the given interface */ - dbus_bus_add_match(conn, CONNMAN_MANAGER_SIGNAL_FILTER, &err); - dbus_connection_flush(conn); - if (dbus_error_is_set(&err)) { - ERR("Error! Match Error (%s)", err.message); - dbus_error_free(&err); + 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) +{ + DBG("Received TDLS Connected Signal"); + netconfig_wifi_tdls_connected_event(param); + + return; +} + +static void _supplicant_tdls_disconnected(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + DBG("Received TDLS Disconnected Signal"); + netconfig_wifi_tdls_disconnected_event(param); + + return; +} + +static void _supplicant_tdls_peer_found(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + DBG("Received TDLS Peer Found Signal"); + netconfig_wifi_tdls_peer_found_event(param); + return; +} + +static void _supplicant_wifi_wps_connected(GVariant *param) +{ + gchar *key; + char ssid[32] = {0, }; + gchar *name; + GVariantIter *iter; + GVariant *variant; + int config_error = 0; + int error_indication = 0; + gsize ssid_len = 0; + + if (param == NULL) { + ERR("Param is NULL"); return; } - dbus_bus_add_match(conn, CONNMAN_TECHNOLOGY_SIGNAL_FILTER, &err); - dbus_connection_flush(conn); - if (dbus_error_is_set(&err)) { - ERR("Error! Match Error (%s)", err.message); - dbus_error_free(&err); - return; + g_variant_get(param, "(sa{sv})", &name, &iter); + INFO("wps Result: %s", name); + while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) { + INFO("wps Key is %s", key); + if (g_strcmp0(key, "SSID") == 0) { + const char *t_key = NULL; + t_key = g_variant_get_fixed_array(variant, &ssid_len, sizeof(guchar)); + INFO("wps ssid_len is %d ", ssid_len); + if (t_key == NULL) { + g_free(key); + g_variant_unref(variant); + ERR("WPS PBC Connection Failed"); + goto error; + } + if (ssid_len > 0 && ssid_len <= 32) { + memcpy(ssid, t_key, ssid_len); + } else { + memset(ssid, 0, sizeof(ssid)); + ssid_len = 0; + } + INFO("WPS PBC Connection completed with AP %s", ssid); + netconfig_wifi_notify_wps_completed(ssid, ssid_len); + } } - dbus_bus_add_match(conn, CONNMAN_SERVICE_SIGNAL_FILTER, &err); - dbus_connection_flush(conn); - if (dbus_error_is_set(&err)) { - ERR("Error! Match Error (%s)", err.message); - dbus_error_free(&err); + g_variant_iter_free(iter); + g_free(name); + return; + +error: + g_variant_iter_free(iter); + g_free(name); + error_indication = WPS_EI_OPERATION_FAILED; + config_error = WPS_CFG_NO_ERROR; + ERR("Error Occured! Notifying Fail Event"); + netconfig_wifi_notify_wps_fail_event(config_error, error_indication); + +} + +static void _supplicant_wifi_wps_event(GVariant *param) +{ + gchar *key; + gchar *name; + GVariantIter *iter; + GVariant *variant; + gint32 config_error = 0; + gint32 error_indication = 0; + + if (param == NULL) { + ERR("Param is NULL"); return; } - dbus_bus_add_match(conn, SUPPLICANT_INTERFACE_SIGNAL_FILTER, &err); - dbus_connection_flush(conn); - if (dbus_error_is_set(&err)) { - ERR("Error! Match Error (%s)", err.message); - dbus_error_free(&err); + g_variant_get(param, "(sa{sv})", &name, &iter); + INFO("Event Result: %s", name); + if (g_strcmp0(name, "fail") == 0) { + while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) { + if (key == NULL) + goto error; + INFO("Key is %s", key); + if (g_strcmp0(key, "config_error") == 0) { + config_error = g_variant_get_int32(variant); + ERR("Config Error %d", config_error); + } else if (g_strcmp0(key, "error_indication") == 0) { + error_indication = g_variant_get_int32(variant); + ERR("Error Indication %d", error_indication); + } + } + netconfig_wifi_notify_wps_fail_event(config_error, error_indication); + } + + g_variant_iter_free(iter); + g_free(name); + return; + +error: + g_variant_iter_free(iter); + g_free(name); + error_indication = WPS_EI_OPERATION_FAILED; + config_error = WPS_CFG_NO_ERROR; + ERR("Error Occured! Notifying Fail Event"); + netconfig_wifi_notify_wps_fail_event(config_error, error_indication); +} + +static void _supplicant_wifi_wps_credentials(GVariant *param) +{ + gchar *key; + char ssid[32] = {0, }; + char wps_key[100] = {0, }; + GVariantIter *iter; + GVariant *variant; + int config_error = 0; + int error_indication = 0; + gsize ssid_len = 0; + + if (param == NULL) { + ERR("Param is NULL"); return; } - if (dbus_connection_add_filter(conn, - __netconfig_signal_filter_handler, NULL, NULL) == FALSE) { - ERR("Error! dbus_connection_add_filter() failed"); + g_variant_get(param, "(a{sv})", &iter); + while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) { + if (key == NULL) + goto error; + INFO("wps Key is %s", key); + if (g_strcmp0(key, "Key") == 0) { + gsize key_len = 0; + const char *t_key = NULL; + key_len = g_variant_get_size(variant); + + INFO("wps password len %d ", key_len); + if (key_len > 0) { + t_key = g_variant_get_fixed_array(variant, &key_len, sizeof(guchar)); + if (!t_key) { + g_free(key); + g_variant_unref(variant); + goto error; + } + strncpy(wps_key, t_key, key_len); + wps_key[key_len] = '\0'; + INFO("WPS Key in process credentials %s", wps_key); + } else + SLOGI("WPS AP Security ->Open"); + } else if (g_strcmp0(key, "SSID") == 0) { + const char *t_key = NULL; + t_key = g_variant_get_fixed_array(variant, &ssid_len, sizeof(guchar)); + INFO("wps ssid_len is %d ", ssid_len); + if (!t_key) { + g_free(key); + g_variant_unref(variant); + goto error; + } + if (ssid_len > 0 && ssid_len <= 32) { + memcpy(ssid, t_key, ssid_len); + } else { + memset(ssid, 0, sizeof(ssid)); + ssid_len = 0; + } + INFO("SSID in process credentials %s", ssid); + } + } + + g_variant_iter_free(iter); + +#if 0 + /* + * Notify WPS Credentials only when requested through WPS PBC + * In case of WPS PIN connman will take care of notification + */ + if (netconfig_get_wps_field() == TRUE) +#endif + netconfig_wifi_notify_wps_credentials(ssid, ssid_len, wps_key); + return; + +error: + g_variant_iter_free(iter); + error_indication = WPS_EI_OPERATION_FAILED; + config_error = WPS_CFG_NO_ERROR; + ERR("Error Occured! Notifying Fail Event"); + netconfig_wifi_notify_wps_fail_event(config_error, error_indication); +} + +static void __netconfig_wps_signal_filter_handler(GDBusConnection *conn, + const gchar *name, const gchar *path, const gchar *interface, + const gchar *sig, GVariant *param, gpointer user_data) +{ + if (g_strcmp0(sig, SIGNAL_WPS_CREDENTIALS) == 0) { + INFO("Received wps CREDENTIALS Signal from Supplicant"); + _supplicant_wifi_wps_credentials(param); + } else if (g_strcmp0(sig, SIGNAL_WPS_EVENT) == 0) { + INFO("Received wps EVENT Signal from Supplicant"); + _supplicant_wifi_wps_event(param); + } else if (g_strcmp0(sig, SIGNAL_WPS_CONNECTED) == 0) { + INFO("Received WPSConnected Signal from Supplicant"); + _supplicant_wifi_wps_connected(param); + } + + return; +} + +static supplicant_signal_cb supplicant_cbs[SIG_MAX] = { + _supplicant_interface_removed, + _supplicant_properties_changed, + _supplicant_bss_added, + _supplicant_scan_done, + _supplicant_driver_hanged, + _supplicant_session_overlapped, + _supplicant_tdls_connected, + _supplicant_tdls_disconnected, + _supplicant_tdls_peer_found +}; + +void register_gdbus_signal(void) +{ + GDBusConnection *connection = NULL; + const char *interface = NULL; + SuppSigArrayIndex sig; + connection = netdbus_get_connection(); + + if (connection == NULL) { + ERR("Failed to get GDbus Connection"); return; } - INFO("Successfully register signal filters"); + /* listening to messages from all objects as no path is specified */ + /* see signals from the given interface */ + conn_subscription_ids[0] = g_dbus_connection_signal_subscribe( + connection, + CONNMAN_SERVICE, + CONNMAN_TECHNOLOGY_INTERFACE, + NULL, + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _technology_signal_cb, + NULL, + NULL); + + conn_subscription_ids[1] = g_dbus_connection_signal_subscribe( + connection, + CONNMAN_SERVICE, + CONNMAN_SERVICE_INTERFACE, + CONNMAN_SIGNAL_PROPERTY_CHANGED, + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _service_signal_cb, + NULL, + NULL); + + conn_subscription_ids[2] = g_dbus_connection_signal_subscribe( + connection, + DBUS_SERVICE_DBUS, + DBUS_INTERFACE_DBUS, + CONNMAN_SIGNAL_NAME_CHANGED, + NULL, + CONNMAN_SERVICE, + G_DBUS_SIGNAL_FLAGS_NONE, + _dbus_name_changed_cb, + NULL, + NULL); + + conn_subscription_ids[3] = g_dbus_connection_signal_subscribe( + connection, + CONNMAN_SERVICE, + CONNMAN_MANAGER_INTERFACE, + CONNMAN_SIGNAL_SERVICES_CHANGED, + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _services_changed_cb, + NULL, + NULL); + + INFO("Successfully register connman DBus signal filters"); + + conn_subscription_ids[4] = g_dbus_connection_signal_subscribe( + connection, + SUPPLICANT_SERVICE, + SUPPLICANT_INTERFACE ".Interface.WPS", + NULL, + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + __netconfig_wps_signal_filter_handler, + NULL, + NULL); + + INFO("Successfully register Supplicant WPS DBus signal filters"); + + for (sig = SIG_INTERFACE_REMOVED; sig < SIG_MAX; sig++) { + /* + * For SIG_INTERFACE_REMOVED INTERFACE_ADDED + */ + interface = (sig == SIG_INTERFACE_REMOVED) ? + SUPPLICANT_INTERFACE : SUPPLICANT_IFACE_INTERFACE; + + supp_subscription_ids[sig] = g_dbus_connection_signal_subscribe( + connection, + SUPPLICANT_SERVICE, + interface, + supplicant_signals[sig], + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + supplicant_cbs[sig], + NULL, + NULL); + } + + 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. + */ + netconfig_update_default(); } -void netconfig_deregister_signal(void) +void deregister_gdbus_signal(void) { - if (signal_connection == NULL) { - ERR("Error! Already de-registered. Nothing to be done"); + GDBusConnection *connection = NULL; + int signal; + SuppSigArrayIndex sig; + connection = netdbus_get_connection(); + if (!connection) { + ERR("Already de-registered. Nothing to be done"); return; } - dbus_connection_remove_filter(signal_connection, - __netconfig_signal_filter_handler, NULL); - INFO("Successfully remove DBus signal filters"); + for (signal = 0; signal < TOTAL_CONN_SIGNALS; signal++) { + if (conn_subscription_ids[signal]) { + g_dbus_connection_signal_unsubscribe(connection, + conn_subscription_ids[signal]); + } + } - dbus_connection_unref(signal_connection); - signal_connection = NULL; + for (sig = SIG_INTERFACE_REMOVED; sig < SIG_MAX; sig++) { + if (supp_subscription_ids[sig]) { + g_dbus_connection_signal_unsubscribe(connection, + supp_subscription_ids[sig]); + } + } - netconfig_wifi_deinit_bgscan(); +#if defined TIZEN_DEBUG_ENABLE + g_dbus_connection_signal_unsubscribe(connection, + dumpservice_subscription_id); +#endif }