summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2012-04-17 13:29:54 (GMT)
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-04-17 13:34:18 (GMT)
commite5a4da9e8587b32ce314c457ca0c5b28c8f43e29 (patch)
treeb9bdb14c945efc989cf9dab7b7a550ccf055ffba
parente093e07dbf7ba956e2d7ac8cbc8e966ceb6a5068 (diff)
downloadconnman-e5a4da9e8587b32ce314c457ca0c5b28c8f43e29.zip
connman-e5a4da9e8587b32ce314c457ca0c5b28c8f43e29.tar.gz
connman-e5a4da9e8587b32ce314c457ca0c5b28c8f43e29.tar.bz2
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.
-rw-r--r--src/notifier.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/src/notifier.c b/src/notifier.c
index fa32d3a..7d4b1e8 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;
}