summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-01-05 05:14:29 -0800
committerMarcel Holtmann <marcel@holtmann.org>2010-01-05 05:14:29 -0800
commitcec31fbcdf1be94f060ba4e02db074b6a654afbd (patch)
treec06cd7ab95a03c9f75f5b0a817945a13028f42fb
parentf5d476e9d5ecaa45e22823b2a21a1e2fad775aff (diff)
downloadconnman-cec31fbcdf1be94f060ba4e02db074b6a654afbd.tar.gz
connman-cec31fbcdf1be94f060ba4e02db074b6a654afbd.tar.bz2
connman-cec31fbcdf1be94f060ba4e02db074b6a654afbd.zip
Move online/offline state handling into notifier framework
-rw-r--r--include/element.h2
-rw-r--r--src/connman.h4
-rw-r--r--src/element.c118
-rw-r--r--src/manager.c13
-rw-r--r--src/notifier.c56
5 files changed, 80 insertions, 113 deletions
diff --git a/include/element.h b/include/element.h
index 1d9aa69d..f97e2e42 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 6f6b6215..109ed8e5 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 <connman/rtnl.h>
diff --git a/src/element.c b/src/element.c
index 6dc0a714..01ae10eb 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 cc5d163d..7b2f9963 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 d2d33428..d001cfc7 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)