diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
index f1940ba..232ffa0 100644
--- a/doc/gatt-api.txt
+++ b/doc/gatt-api.txt
belongs to. Only present on services from remote
devices.
- array{object} Characteristics [read-only]
-
- Array of object paths representing the characteristics
- of this service. This property is set only when the
- characteristic discovery has been completed, however the
- characteristic objects will become available via
- ObjectManager as soon as they get discovered.
-
array{object} Includes [read-only]: Not implemented
Array of object paths representing the included
"encrypt-authenticated-read"
"encrypt-authenticated-write"
- array{object} Descriptors [read-only]
-
- Array of object paths representing the descriptors
- of this service. This property is set only when the
- descriptor discovery has been completed, however the
- descriptor objects will become available via
- ObjectManager as soon as they get discovered.
-
-
Characteristic Descriptors hierarchy
====================================
diff --git a/src/gatt-client.c b/src/gatt-client.c
index dd76a36..0f6e274 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
bt_uuid_t uuid;
char *path;
struct queue *chrcs;
- bool chrcs_ready;
struct queue *pending_ext_props;
- guint idle_id;
};
struct characteristic {
return dbus_message_new_method_return(msg);
}
-static void append_desc_path(void *data, void *user_data)
-{
- struct descriptor *desc = data;
- DBusMessageIter *array = user_data;
-
- dbus_message_iter_append_basic(array, DBUS_TYPE_OBJECT_PATH,
- &desc->path);
-}
-
-static gboolean characteristic_get_descriptors(
- const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *data)
-{
- struct characteristic *chrc = data;
- DBusMessageIter array;
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "o", &array);
-
- queue_foreach(chrc->descs, append_desc_path, &array);
-
- dbus_message_iter_close_container(iter, &array);
-
- return TRUE;
-}
-
static const GDBusPropertyTable characteristic_properties[] = {
{ "UUID", "s", characteristic_get_uuid, NULL, NULL,
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
{ "Flags", "as", characteristic_get_flags, NULL, NULL,
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
- { "Descriptors", "ao", characteristic_get_descriptors, NULL, NULL,
- G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
{ }
};
return TRUE;
}
-static void append_chrc_path(void *data, void *user_data)
-{
- struct characteristic *chrc = data;
- DBusMessageIter *array = user_data;
-
- dbus_message_iter_append_basic(array, DBUS_TYPE_OBJECT_PATH,
- &chrc->path);
-}
-
-static gboolean service_get_characteristics(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *data)
-{
- struct service *service = data;
- DBusMessageIter array;
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "o", &array);
-
- if (service->chrcs_ready)
- queue_foreach(service->chrcs, append_chrc_path, &array);
-
- dbus_message_iter_close_container(iter, &array);
-
- return TRUE;
-}
-
static const GDBusPropertyTable service_properties[] = {
{ "UUID", "s", service_get_uuid, NULL, NULL,
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
{ "Primary", "b", service_get_primary, NULL, NULL,
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
- { "Characteristics", "ao", service_get_characteristics, NULL, NULL,
- G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
{ }
};
DBG("Removing GATT service: %s", service->path);
- if (service->idle_id)
- g_source_remove(service->idle_id);
-
queue_remove_all(service->chrcs, NULL, NULL, unregister_characteristic);
g_dbus_unregister_interface(btd_get_dbus_connection(), service->path,
GATT_SERVICE_IFACE);
}
-static void notify_chrcs(struct service *service)
-{
-
- if (service->chrcs_ready ||
- !queue_isempty(service->pending_ext_props))
- return;
-
- service->chrcs_ready = true;
-
- g_dbus_emit_property_changed(btd_get_dbus_connection(), service->path,
- GATT_SERVICE_IFACE,
- "Characteristics");
-}
-
struct export_data {
void *root;
bool failed;
"Flags");
queue_remove(service->pending_ext_props, chrc);
-
- notify_chrcs(service);
}
static void read_ext_props(void *data, void *user_data)
return true;
}
-static gboolean set_chrcs_ready(gpointer user_data)
-{
- struct service *service = user_data;
-
- service->idle_id = 0;
- notify_chrcs(service);
-
- return FALSE;
-}
-
static void export_service(struct gatt_db_attribute *attr, void *user_data)
{
struct btd_gatt_client *client = user_data;
}
queue_push_tail(client->services, service);
-
- /*
- * Asynchronously update the "Characteristics" property of the service.
- * If there are any pending reads to obtain the value of the "Extended
- * Properties" descriptor then wait until they are complete.
- */
- if (!service->chrcs_ready && queue_isempty(service->pending_ext_props))
- service->idle_id = g_idle_add(set_chrcs_ready, service);
}
static void create_services(struct btd_gatt_client *client)