From cec31fbcdf1be94f060ba4e02db074b6a654afbd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jan 2010 05:14:29 -0800 Subject: [PATCH] Move online/offline state handling into notifier framework --- include/element.h | 2 +- src/connman.h | 4 +- src/element.c | 118 ++++++++++-------------------------------------------- src/manager.c | 13 ++---- src/notifier.c | 56 ++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 113 deletions(-) diff --git a/include/element.h b/include/element.h index 1d9aa69..f97e2e4 100644 --- a/include/element.h +++ b/include/element.h @@ -80,9 +80,9 @@ struct connman_element { enum connman_element_state state; enum connman_element_error error; gboolean enabled; - gboolean configuring; gchar *devname; + GHashTable *children; struct connman_element *parent; struct connman_driver *driver; diff --git a/src/connman.h b/src/connman.h index 6f6b621..109ed8e 100644 --- a/src/connman.h +++ b/src/connman.h @@ -219,8 +219,6 @@ void __connman_element_foreach(struct connman_element *element, void __connman_element_list(struct connman_element *element, enum connman_element_type type, DBusMessageIter *iter); -int __connman_element_count(struct connman_element *element, - enum connman_element_type type); struct connman_service *__connman_element_get_service(struct connman_element *element); struct connman_device *__connman_element_get_device(struct connman_element *element); @@ -420,6 +418,8 @@ void __connman_notifier_offlinemode(connman_bool_t enabled); void __connman_notifier_default_changed(struct connman_service *service); connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type); +unsigned int __connman_notifier_count_connected(void); +const char *__connman_notifier_get_state(void); #include diff --git a/src/element.c b/src/element.c index 6dc0a71..01ae10e 100644 --- a/src/element.c +++ b/src/element.c @@ -176,52 +176,6 @@ void __connman_element_list(struct connman_element *element, append_path, &filter); } -struct count_data { - enum connman_element_type type; - int count; -}; - -static gboolean count_element(GNode *node, gpointer user_data) -{ - struct connman_element *element = node->data; - struct count_data *data = user_data; - - DBG("element %p name %s", element, element->name); - - if (element->type == CONNMAN_ELEMENT_TYPE_ROOT) - return FALSE; - - if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN && - data->type != element->type) - return FALSE; - - data->count++; - - return FALSE; -} - -int __connman_element_count(struct connman_element *element, - enum connman_element_type type) -{ - struct count_data data = { type, 0 }; - GNode *node; - - DBG(""); - - if (element != NULL) { - node = g_node_find(element_root, G_PRE_ORDER, - G_TRAVERSE_ALL, element); - if (node == NULL) - return 0; - } else - node = element_root; - - g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - count_element, &data); - - return data.count; -} - static struct connman_network *__connman_element_get_network(struct connman_element *element) { if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK && @@ -601,6 +555,15 @@ static void unregister_property(gpointer data) g_free(property); } +static void unregister_child(gpointer data) +{ + struct connman_element *element = data; + + DBG("element %p", element); + + connman_element_unref(element); +} + void __connman_element_initialize(struct connman_element *element) { DBG("element %p", element); @@ -614,7 +577,8 @@ void __connman_element_initialize(struct connman_element *element) element->index = -1; element->enabled = FALSE; - element->configuring = FALSE; + element->children = g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, unregister_child); element->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, unregister_property); @@ -662,6 +626,14 @@ static void free_properties(struct connman_element *element) element->properties = NULL; } +static void free_children(struct connman_element *element) +{ + DBG("element %p name %s", element, element->name); + + g_hash_table_destroy(element->children); + element->children = NULL; +} + void connman_element_unref(struct connman_element *element) { DBG("element %p name %s refcount %d", element, element->name, @@ -670,6 +642,7 @@ void connman_element_unref(struct connman_element *element) if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) { if (element->destruct) element->destruct(element); + free_children(element); free_properties(element); g_free(element->ipv4.address); g_free(element->ipv4.netmask); @@ -998,26 +971,6 @@ const void *connman_element_get_blob(struct connman_element *element, return value; } -static void emit_state_change(DBusConnection *conn, const char *state) -{ - DBusMessage *signal; - DBusMessageIter iter; - - connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH, - CONNMAN_MANAGER_INTERFACE, "State", - DBUS_TYPE_STRING, &state); - - signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH, - CONNMAN_MANAGER_INTERFACE, "StateChanged"); - if (signal == NULL) - return; - - dbus_message_iter_init_append(signal, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &state); - - g_dbus_send_message(conn, signal); -} - static void probe_element(struct connman_element *element) { GSList *list; @@ -1068,29 +1021,6 @@ static void register_element(gpointer data, gpointer user_data) g_node_append_data(node, element); - if (element->type == CONNMAN_ELEMENT_TYPE_DHCP) { - element->parent->configuring = TRUE; - -#if 0 - if (__connman_element_count(NULL, - CONNMAN_ELEMENT_TYPE_CONNECTION) == 0) - emit_state_change(connection, "connecting"); -#endif - } - - if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) { - struct connman_element *parent = element->parent; - - while (parent) { - parent->configuring = FALSE; - parent = parent->parent; - } - - if (__connman_element_count(NULL, - CONNMAN_ELEMENT_TYPE_CONNECTION) == 1) - emit_state_change(connection, "online"); - } - if (started == FALSE) return; @@ -1137,7 +1067,7 @@ int connman_element_register(struct connman_element *element, if (element->devname == NULL) element->devname = g_strdup(element->name); - if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE) + if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE) goto setup; if (__connman_element_device_isfiltered(element->devname) == TRUE) @@ -1187,12 +1117,6 @@ static gboolean remove_element(GNode *node, gpointer user_data) if (node != NULL) g_node_destroy(node); - if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) { - if (__connman_element_count(NULL, - CONNMAN_ELEMENT_TYPE_CONNECTION) == 0) - emit_state_change(connection, "offline"); - } - connman_element_unref(element); return FALSE; diff --git a/src/manager.c b/src/manager.c index cc5d163..7b2f996 100644 --- a/src/manager.c +++ b/src/manager.c @@ -64,11 +64,7 @@ static DBusMessage *get_properties(DBusConnection *conn, connman_dbus_dict_append_array(&dict, "Devices", DBUS_TYPE_OBJECT_PATH, __connman_device_list, NULL); - if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0) - str = "online"; - else - str = "offline"; - + str = __connman_notifier_get_state(); connman_dbus_dict_append_basic(&dict, "State", DBUS_TYPE_STRING, &str); @@ -154,10 +150,7 @@ static DBusMessage *get_state(DBusConnection *conn, CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0) return __connman_error_permission_denied(msg); - if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0) - str = "online"; - else - str = "offline"; + str = __connman_notifier_get_state(); return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); @@ -627,7 +620,7 @@ static DBusMessage *nm_state(DBusConnection *conn, if (reply == NULL) return NULL; - if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0) + if (__connman_notifier_count_connected() > 0) state = NM_STATE_CONNECTED; else state = NM_STATE_DISCONNECTED; diff --git a/src/notifier.c b/src/notifier.c index d2d3342..d001cfc 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -80,7 +80,7 @@ void __connman_notifier_list_registered(DBusMessageIter *iter, void *user_data) { int i; - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_TECHNOLOGIES; i++) { const char *type = __connman_service_type2string(i); if (type == NULL) @@ -96,7 +96,7 @@ void __connman_notifier_list_enabled(DBusMessageIter *iter, void *user_data) { int i; - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_TECHNOLOGIES; i++) { const char *type = __connman_service_type2string(i); if (type == NULL) @@ -112,7 +112,7 @@ void __connman_notifier_list_connected(DBusMessageIter *iter, void *user_data) { int i; - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_TECHNOLOGIES; i++) { const char *type = __connman_service_type2string(i); if (type == NULL) @@ -153,6 +153,54 @@ static void technology_enabled(enum connman_service_type type, } } +unsigned int __connman_notifier_count_connected(void) +{ + unsigned int i, count = 0; + + for (i = 0; i < MAX_TECHNOLOGIES; i++) { + if (g_atomic_int_get(&connected[i]) > 0) + count++; + } + + return count; +} + +const char *__connman_notifier_get_state(void) +{ + unsigned int count = __connman_notifier_count_connected(); + + if (count > 0) + return "online"; + + return "offline"; +} + +static void state_changed(void) +{ + unsigned int count = __connman_notifier_count_connected(); + char *state = "offline"; + DBusMessage *signal; + + if (count > 1) + return; + + if (count > 0) + state = "online"; + + connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH, + CONNMAN_MANAGER_INTERFACE, "State", + DBUS_TYPE_STRING, &state); + + signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH, + CONNMAN_MANAGER_INTERFACE, "StateChanged"); + if (signal == NULL) + return; + + dbus_message_append_args(signal, DBUS_TYPE_STRING, &state, NULL); + + g_dbus_send_message(connection, signal); +} + static void technology_connected(enum connman_service_type type, connman_bool_t connected) { @@ -161,6 +209,8 @@ static void technology_connected(enum connman_service_type type, connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "ConnectedTechnologies", DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL); + + state_changed(); } void __connman_notifier_register(enum connman_service_type type) -- 2.7.4