summaryrefslogtreecommitdiff
path: root/src/notifier.c
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2012-04-17 15:29:54 +0200
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-04-17 15:34:18 +0200
commite5a4da9e8587b32ce314c457ca0c5b28c8f43e29 (patch)
treeb9bdb14c945efc989cf9dab7b7a550ccf055ffba /src/notifier.c
parente093e07dbf7ba956e2d7ac8cbc8e966ceb6a5068 (diff)
downloadconnman-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.c66
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, &notifier_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;
}