diff options
author | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2012-04-17 15:29:54 +0200 |
---|---|---|
committer | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2012-04-17 15:34:18 +0200 |
commit | e5a4da9e8587b32ce314c457ca0c5b28c8f43e29 (patch) | |
tree | b9bdb14c945efc989cf9dab7b7a550ccf055ffba /src/notifier.c | |
parent | e093e07dbf7ba956e2d7ac8cbc8e966ceb6a5068 (diff) | |
download | connman-e5a4da9e8587b32ce314c457ca0c5b28c8f43e29.tar.gz connman-e5a4da9e8587b32ce314c457ca0c5b28c8f43e29.tar.bz2 connman-e5a4da9e8587b32ce314c457ca0c5b28c8f43e29.zip |
notifier: Distinguish between different states
Instead of only having "offline" and "online" states, we support
now having "offline", "idle", "ready" and "online" as on the
Manager.State documenation update required.
Diffstat (limited to 'src/notifier.c')
-rw-r--r-- | src/notifier.c | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/src/notifier.c b/src/notifier.c index fa32d3ab..7d4b1e89 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -32,6 +32,8 @@ static DBusConnection *connection = NULL; static GSList *notifier_list = NULL; static GHashTable *service_hash = NULL; +static const char *notifier_state; + static gint compare_priority(gconstpointer a, gconstpointer b) { const struct connman_notifier *notifier1 = a; @@ -73,7 +75,21 @@ void connman_notifier_unregister(struct connman_notifier *notifier) #define MAX_TECHNOLOGIES 10 -static volatile int connected[MAX_TECHNOLOGIES]; +static int connected[MAX_TECHNOLOGIES]; +static int online[MAX_TECHNOLOGIES]; + +static unsigned int notifier_count_online(void) +{ + unsigned int i, count = 0; + + __sync_synchronize(); + for (i = 0; i < MAX_TECHNOLOGIES; i++) { + if (online[i] > 0) + count++; + } + + return count; +} unsigned int __connman_notifier_count_connected(void) { @@ -88,34 +104,43 @@ unsigned int __connman_notifier_count_connected(void) return count; } -const char *__connman_notifier_get_state(void) +static const char *evaluate_notifier_state(void) { - unsigned int count = __connman_notifier_count_connected(); + unsigned int count; + count = notifier_count_online(); if (count > 0) return "online"; - return "offline"; + count = __connman_notifier_count_connected(); + if (count > 0) + return "ready"; + + if ( __connman_technology_get_offlinemode() == TRUE) + return "offline"; + + return "idle"; } -static void state_changed(connman_bool_t connected) +const char *__connman_notifier_get_state(void) { - unsigned int count = __connman_notifier_count_connected(); - char *state = "offline"; + return notifier_state; +} - if (count > 1) - return; +static void state_changed(void) +{ + const char *state; - if (count == 1) { - if (connected == FALSE) - return; + state = evaluate_notifier_state(); - state = "online"; - } + if (g_strcmp0(state, notifier_state) == 0) + return; + + notifier_state = state; connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "State", - DBUS_TYPE_STRING, &state); + DBUS_TYPE_STRING, ¬ifier_state); } static void technology_connected(enum connman_service_type type, @@ -124,7 +149,7 @@ static void technology_connected(enum connman_service_type type, DBG("type %d connected %d", type, connected); __connman_technology_set_connected(type, connected); - state_changed(connected); + state_changed(); } void __connman_notifier_connect(enum connman_service_type type) @@ -153,6 +178,9 @@ void __connman_notifier_connect(enum connman_service_type type) void __connman_notifier_online(enum connman_service_type type) { DBG("type %d", type); + + if (__sync_fetch_and_add(&online[type], 1) == 0) + state_changed(); } void __connman_notifier_disconnect(enum connman_service_type type, @@ -181,6 +209,9 @@ void __connman_notifier_disconnect(enum connman_service_type type, break; } + if (old_state == CONNMAN_SERVICE_STATE_ONLINE) + __sync_fetch_and_sub(&online[type], 1); + if (__sync_fetch_and_sub(&connected[type], 1) != 1) return; @@ -279,6 +310,7 @@ void __connman_notifier_offlinemode(connman_bool_t enabled) DBG("enabled %d", enabled); offlinemode_changed(enabled); + state_changed(); for (list = notifier_list; list; list = list->next) { struct connman_notifier *notifier = list->data; @@ -369,6 +401,8 @@ int __connman_notifier_init(void) service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); + notifier_state = evaluate_notifier_state(); + return 0; } |