diff --git a/src/service.c b/src/service.c
index 6228de1..eb765f2 100644
--- a/src/service.c
+++ b/src/service.c
int err;
};
+struct service_state_callback {
+ btd_service_state_cb cb;
+ void *user_data;
+ unsigned int id;
+};
+
+static GSList *state_callbacks = NULL;
+
static const char *state2str(btd_service_state_t state)
{
switch (state) {
{
btd_service_state_t old = service->state;
char addr[18];
+ GSList *l;
if (state == old)
return;
DBG("%p: device %s profile %s state changed: %s -> %s (%d)", service,
addr, service->profile->name,
state2str(old), state2str(state), err);
+
+ for (l = state_callbacks; l != NULL; l = g_slist_next(l)) {
+ struct service_state_callback *cb = l->data;
+
+ cb->cb(service, old, state, cb->user_data);
+ }
}
struct btd_service *btd_service_ref(struct btd_service *service)
return service->err;
}
+unsigned int btd_service_add_state_cb(btd_service_state_cb cb, void *user_data)
+{
+ struct service_state_callback *state_cb;
+ static unsigned int id = 0;
+
+ state_cb = g_new0(struct service_state_callback, 1);
+ state_cb->cb = cb;
+ state_cb->user_data = user_data;
+ state_cb->id = ++id;
+
+ state_callbacks = g_slist_append(state_callbacks, state_cb);
+
+ return state_cb->id;
+}
+
+bool btd_service_remove_state_cb(unsigned int id)
+{
+ GSList *l;
+
+ for (l = state_callbacks; l != NULL; l = g_slist_next(l)) {
+ struct service_state_callback *cb = l->data;
+
+ if (cb && cb->id == id) {
+ state_callbacks = g_slist_remove(state_callbacks, cb);
+ g_free(cb);
+ return true;
+ }
+ }
+
+ return false;
+}
+
void btd_service_connecting_complete(struct btd_service *service, int err)
{
if (service->state != BTD_SERVICE_STATE_DISCONNECTED &&
diff --git a/src/service.h b/src/service.h
index e3bc6e5..6ee8f17 100644
--- a/src/service.h
+++ b/src/service.h
struct btd_device;
struct btd_profile;
+typedef void (*btd_service_state_cb) (struct btd_service *service,
+ btd_service_state_t old_state,
+ btd_service_state_t new_state,
+ void *user_data);
+
struct btd_service *btd_service_ref(struct btd_service *service);
void btd_service_unref(struct btd_service *service);
btd_service_state_t btd_service_get_state(const struct btd_service *service);
int btd_service_get_error(const struct btd_service *service);
+unsigned int btd_service_add_state_cb(btd_service_state_cb cb,
+ void *user_data);
+bool btd_service_remove_state_cb(unsigned int id);
+
/* Functions used by profile implementation */
void btd_service_connecting_complete(struct btd_service *service, int err);
void btd_service_disconnecting_complete(struct btd_service *service, int err);