summaryrefslogtreecommitdiff
path: root/src/notifier.c
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2011-08-11 16:56:18 +0200
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2011-08-11 17:40:53 +0200
commiteadf27c4f3d2e872d390ebddbfc77725fd1d5167 (patch)
tree09fb5439a9328eedc53f5f6f63edc25b02b38d8d /src/notifier.c
parent94b80ba600d314127427b9948459a4c86a05015d (diff)
downloadconnman-eadf27c4f3d2e872d390ebddbfc77725fd1d5167.tar.gz
connman-eadf27c4f3d2e872d390ebddbfc77725fd1d5167.tar.bz2
connman-eadf27c4f3d2e872d390ebddbfc77725fd1d5167.zip
notify: Add state_idle()
Diffstat (limited to 'src/notifier.c')
-rw-r--r--src/notifier.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/notifier.c b/src/notifier.c
index f6d9b00d..aa6611bf 100644
--- a/src/notifier.c
+++ b/src/notifier.c
@@ -30,6 +30,7 @@
static DBusConnection *connection = NULL;
static GSList *notifier_list = NULL;
+static GHashTable *service_hash = NULL;
static gint compare_priority(gconstpointer a, gconstpointer b)
{
@@ -417,6 +418,17 @@ void __connman_notifier_service_remove(struct connman_service *service)
{
GSList *list;
+ if (g_hash_table_lookup(service_hash, service) != NULL) {
+ /*
+ * This is a tempory check for consistency. It can be
+ * removed when there are no reports for the following
+ * error message.
+ */
+ connman_error("Service state machine inconsistency detected.");
+
+ g_hash_table_remove(service_hash, service);
+ }
+
for (list = notifier_list; list; list = list->next) {
struct connman_notifier *notifier = list->data;
@@ -464,10 +476,26 @@ void __connman_notifier_offlinemode(connman_bool_t enabled)
}
}
+static void notify_idle_state(connman_bool_t idle)
+{
+ GSList *list;
+
+ DBG("idle %d", idle);
+
+ for (list = notifier_list; list; list = list->next) {
+ struct connman_notifier *notifier = list->data;
+
+ if (notifier->idle_state)
+ notifier->idle_state(idle);
+ }
+}
+
void __connman_notifier_service_state_changed(struct connman_service *service,
enum connman_service_state state)
{
GSList *list;
+ unsigned int old_size;
+ connman_bool_t found;
for (list = notifier_list; list; list = list->next) {
struct connman_notifier *notifier = list->data;
@@ -475,6 +503,36 @@ void __connman_notifier_service_state_changed(struct connman_service *service,
if (notifier->service_state_changed)
notifier->service_state_changed(service, state);
}
+
+ old_size = g_hash_table_size(service_hash);
+ found = g_hash_table_lookup(service_hash, service) != NULL;
+
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ if (found == FALSE)
+ break;
+
+ g_hash_table_remove(service_hash, service);
+ if (old_size == 1)
+ notify_idle_state(TRUE);
+
+ break;
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ if (found == TRUE)
+ break;
+
+ g_hash_table_insert(service_hash, service, service);
+ if (old_size == 0)
+ notify_idle_state(FALSE);
+
+ break;
+ }
}
void __connman_notifier_ipconfig_changed(struct connman_service *service,
@@ -542,6 +600,10 @@ int __connman_notifier_init(void)
connection = connman_dbus_get_connection();
+ service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, NULL);
+
+
return 0;
}
@@ -549,5 +611,8 @@ void __connman_notifier_cleanup(void)
{
DBG("");
+ g_hash_table_destroy(service_hash);
+ service_hash = NULL;
+
dbus_connection_unref(connection);
}