+static void notify_idle_state(bool idle)
+{
+ GSList *list;
+
+ DBG("idle %d", idle);
+
+ for (list = notifier_list; list; list = list->next) {
+ const 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;
+ bool found;
+
+ for (list = notifier_list; list; list = list->next) {
+ const struct connman_notifier *notifier = list->data;
+
+ 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);
+
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ if (!found)
+ 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:
+ if (found)
+ 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,
+ struct connman_ipconfig *ipconfig)
+{
+ GSList *list;
+
+ for (list = notifier_list; list; list = list->next) {
+ const struct connman_notifier *notifier = list->data;
+
+ if (notifier->ipconfig_changed)
+ notifier->ipconfig_changed(service, ipconfig);
+ }
+}
+