* [PATCH v2 2/8] shared/gatt-db: Allow passing 0 as handle to gatt_db_insert_*
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
@ 2019-01-30 13:54 ` Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 3/8] gatt: Implement Handle property Luiz Augusto von Dentz
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Handle 0 should be allocate on the next handle just as any of
gatt_db_add_* functions.
---
src/shared/gatt-db.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index d28301ac4..c62255fee 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -525,9 +525,12 @@ struct gatt_db_attribute *gatt_db_insert_service(struct gatt_db *db,
after = NULL;
- if (!db || handle < 1)
+ if (!db)
return NULL;
+ if (!handle)
+ handle = db->next_handle;
+
if (num_handles < 1 || (handle + num_handles - 1) > UINT16_MAX)
return NULL;
@@ -585,8 +588,7 @@ struct gatt_db_attribute *gatt_db_add_service(struct gatt_db *db,
bool primary,
uint16_t num_handles)
{
- return gatt_db_insert_service(db, db->next_handle, uuid, primary,
- num_handles);
+ return gatt_db_insert_service(db, 0, uuid, primary, num_handles);
}
unsigned int gatt_db_register(struct gatt_db *db,
@@ -768,7 +770,7 @@ gatt_db_service_insert_characteristic(struct gatt_db_attribute *attrib,
gatt_db_write_t write_func,
void *user_data)
{
- if (!attrib || !handle)
+ if (!attrib)
return NULL;
return service_insert_characteristic(attrib->service, handle, uuid,
@@ -856,7 +858,7 @@ gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib,
gatt_db_write_t write_func,
void *user_data)
{
- if (!attrib || !handle)
+ if (!attrib)
return NULL;
return service_insert_descriptor(attrib->service, handle, uuid,
--
2.17.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/8] gatt: Implement Handle property
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 2/8] shared/gatt-db: Allow passing 0 as handle to gatt_db_insert_* Luiz Augusto von Dentz
@ 2019-01-30 13:54 ` Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 4/8] gatt: Write back the handle to " Luiz Augusto von Dentz
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This parses the Handle property and if it exists attempt to insert
attributes in their locations.
---
src/gatt-database.c | 47 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 43 insertions(+), 4 deletions(-)
diff --git a/src/gatt-database.c b/src/gatt-database.c
index 2c2f035b1..025f777eb 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -1839,6 +1839,25 @@ static bool parse_primary(GDBusProxy *proxy, bool *primary)
return true;
}
+static bool parse_handle(GDBusProxy *proxy, uint16_t *handle)
+{
+ DBusMessageIter iter;
+
+ /* Handle property is optional */
+ if (!g_dbus_proxy_get_property(proxy, "Handle", &iter)) {
+ *handle = 0;
+ return true;
+ }
+
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16)
+ return false;
+
+ dbus_message_iter_get_basic(&iter, &handle);
+
+ return true;
+}
+
static uint8_t dbus_error_to_att_ecode(const char *error_name)
{
@@ -2601,14 +2620,21 @@ fail:
static bool database_add_desc(struct external_service *service,
struct external_desc *desc)
{
+ uint16_t handle;
bt_uuid_t uuid;
+ if (!parse_handle(desc->proxy, &handle)) {
+ error("Failed to read \"Handle\" property of descriptor");
+ return false;
+ }
+
if (!parse_uuid(desc->proxy, &uuid)) {
error("Failed to read \"UUID\" property of descriptor");
return false;
}
- desc->attrib = gatt_db_service_add_descriptor(service->attrib, &uuid,
+ desc->attrib = gatt_db_service_insert_descriptor(service->attrib,
+ handle, &uuid,
desc->perm,
desc_read_cb,
desc_write_cb, desc);
@@ -2750,9 +2776,15 @@ static void database_add_includes(struct external_service *service)
static bool database_add_chrc(struct external_service *service,
struct external_chrc *chrc)
{
+ uint16_t handle;
bt_uuid_t uuid;
const struct queue_entry *entry;
+ if (!parse_handle(chrc->proxy, &handle)) {
+ error("Failed to read \"Handle\" property of characteristic");
+ return false;
+ }
+
if (!parse_uuid(chrc->proxy, &uuid)) {
error("Failed to read \"UUID\" property of characteristic");
return false;
@@ -2763,8 +2795,8 @@ static bool database_add_chrc(struct external_service *service,
return false;
}
- chrc->attrib = gatt_db_service_add_characteristic(service->attrib,
- &uuid, chrc->perm,
+ chrc->attrib = gatt_db_service_insert_characteristic(service->attrib,
+ handle, &uuid, chrc->perm,
chrc->props, chrc_read_cb,
chrc_write_cb, chrc);
if (!chrc->attrib) {
@@ -2807,6 +2839,7 @@ static bool database_add_service(struct external_service *service)
{
bt_uuid_t uuid;
bool primary;
+ uint16_t handle;
const struct queue_entry *entry;
if (!parse_uuid(service->proxy, &uuid)) {
@@ -2824,7 +2857,13 @@ static bool database_add_service(struct external_service *service)
return false;
}
- service->attrib = gatt_db_add_service(service->app->database->db, &uuid,
+ if (!parse_handle(service->proxy, &handle)) {
+ error("Failed to read \"Handle\" property of service");
+ return false;
+ }
+
+ service->attrib = gatt_db_insert_service(service->app->database->db,
+ handle, &uuid,
primary, service->attr_cnt);
if (!service->attrib)
return false;
--
2.17.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/8] gatt: Write back the handle to Handle property
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 2/8] shared/gatt-db: Allow passing 0 as handle to gatt_db_insert_* Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 3/8] gatt: Implement Handle property Luiz Augusto von Dentz
@ 2019-01-30 13:54 ` Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 5/8] client: Enable Handle property for GATT attributes Luiz Augusto von Dentz
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
If the application has set an attribute with Handle set to 0 inform the
allocated handle by writting the Handle property.
---
src/gatt-database.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/gatt-database.c b/src/gatt-database.c
index 025f777eb..b159786ea 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -2617,6 +2617,18 @@ fail:
gatt_db_attribute_write_result(attrib, id, BT_ATT_ERROR_UNLIKELY);
}
+static void write_handle(struct GDBusProxy *proxy, uint16_t handle)
+{
+ DBusMessageIter iter;
+
+ /* Check if the attribute has the Handle property */
+ if (!g_dbus_proxy_get_property(proxy, "Handle", &iter))
+ return;
+
+ g_dbus_proxy_set_property_basic(proxy, "Handle", DBUS_TYPE_UINT16,
+ &handle, NULL, NULL, NULL);
+}
+
static bool database_add_desc(struct external_service *service,
struct external_desc *desc)
{
@@ -2645,6 +2657,11 @@ static bool database_add_desc(struct external_service *service,
desc->handled = true;
+ if (!handle) {
+ handle = gatt_db_attribute_get_handle(desc->attrib);
+ write_handle(desc->proxy, handle);
+ }
+
return true;
}
@@ -2810,6 +2827,11 @@ static bool database_add_chrc(struct external_service *service,
if (!database_add_cep(service, chrc))
return false;
+ if (!handle) {
+ handle = gatt_db_attribute_get_handle(chrc->attrib);
+ write_handle(chrc->proxy, handle);
+ }
+
/* Handle the descriptors that belong to this characteristic. */
for (entry = queue_get_entries(service->descs); entry;
entry = entry->next) {
@@ -2868,6 +2890,11 @@ static bool database_add_service(struct external_service *service)
if (!service->attrib)
return false;
+ if (!handle) {
+ handle = gatt_db_attribute_get_handle(service->attrib);
+ write_handle(service->proxy, handle);
+ }
+
database_add_includes(service);
entry = queue_get_entries(service->chrcs);
--
2.17.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 5/8] client: Enable Handle property for GATT attributes
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
` (2 preceding siblings ...)
2019-01-30 13:54 ` [PATCH v2 4/8] gatt: Write back the handle to " Luiz Augusto von Dentz
@ 2019-01-30 13:54 ` Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 6/8] client: Enable setting attribute handles Luiz Augusto von Dentz
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This enable bluetoothd to write back the actual value of attribute
handles.
---
client/gatt.c | 140 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 124 insertions(+), 16 deletions(-)
diff --git a/client/gatt.c b/client/gatt.c
index b6b517bdf..b29e68136 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -62,6 +62,7 @@
struct desc {
struct chrc *chrc;
char *path;
+ uint16_t handle;
char *uuid;
char **flags;
int value_len;
@@ -72,6 +73,7 @@ struct desc {
struct chrc {
struct service *service;
char *path;
+ uint16_t handle;
char *uuid;
char **flags;
bool notifying;
@@ -88,6 +90,7 @@ struct chrc {
struct service {
DBusConnection *conn;
char *path;
+ uint16_t handle;
char *uuid;
bool primary;
GList *chrcs;
@@ -117,21 +120,25 @@ static void print_service(struct service *service, const char *description)
text = bt_uuidstr_to_str(service->uuid);
if (!text)
- bt_shell_printf("%s%s%s%s Service\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%s%s Service (Handle 0x%04x)\n\t%s\n\t"
+ "%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
service->primary ? "Primary" :
"Secondary",
- service->path, service->uuid);
+ service->handle, service->path,
+ service->uuid);
else
- bt_shell_printf("%s%s%s%s Service\n\t%s\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%s%s Service (Handle 0x%04x)\n\t%s\n\t%s"
+ "\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
service->primary ? "Primary" :
"Secondary",
- service->path, service->uuid, text);
+ service->handle, service->path,
+ service->uuid, text);
}
static void print_inc_service(struct service *service, const char *description)
@@ -140,21 +147,25 @@ static void print_inc_service(struct service *service, const char *description)
text = bt_uuidstr_to_str(service->uuid);
if (!text)
- bt_shell_printf("%s%s%s%s Included Service\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%s%s Included Service (Handle 0x%04x)\n\t"
+ "%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
service->primary ? "Primary" :
"Secondary",
- service->path, service->uuid);
+ service->handle, service->path,
+ service->uuid);
else
- bt_shell_printf("%s%s%s%s Included Service\n\t%s\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%s%s Included Service (Handle 0x%04x)\n\t"
+ "%s\n\t%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
service->primary ? "Primary" :
"Secondary",
- service->path, service->uuid, text);
+ service->handle, service->path,
+ service->uuid, text);
}
static void print_service_proxy(GDBusProxy *proxy, const char *description)
@@ -207,17 +218,20 @@ static void print_chrc(struct chrc *chrc, const char *description)
text = bt_uuidstr_to_str(chrc->uuid);
if (!text)
- bt_shell_printf("%s%s%sCharacteristic\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sCharacteristic (Handle 0x%04x)\n\t%s\n\t"
+ "%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
- chrc->path, chrc->uuid);
+ chrc->handle, chrc->path, chrc->uuid);
else
- bt_shell_printf("%s%s%sCharacteristic\n\t%s\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sCharacteristic (Handle 0x%04x)\n\t%s\n\t"
+ "%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
- chrc->path, chrc->uuid, text);
+ chrc->handle, chrc->path, chrc->uuid,
+ text);
}
static void print_characteristic(GDBusProxy *proxy, const char *description)
@@ -297,17 +311,20 @@ static void print_desc(struct desc *desc, const char *description)
text = bt_uuidstr_to_str(desc->uuid);
if (!text)
- bt_shell_printf("%s%s%sDescriptor\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sDescriptor (Handle 0x%04x)\n\t%s\n\t"
+ "%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
- desc->path, desc->uuid);
+ desc->handle, desc->path, desc->uuid);
else
- bt_shell_printf("%s%s%sDescriptor\n\t%s\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sDescriptor (Handle 0x%04x)\n\t%s\n\t"
+ "%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
- desc->path, desc->uuid, text);
+ desc->handle, desc->path, desc->uuid,
+ text);
}
static void print_descriptor(GDBusProxy *proxy, const char *description)
@@ -1259,6 +1276,36 @@ static void service_free(void *data)
g_free(service);
}
+static gboolean service_get_handle(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct service *service = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+ &service->handle);
+
+ return TRUE;
+}
+
+static void service_set_handle(const GDBusPropertyTable *property,
+ DBusMessageIter *value, GDBusPendingPropertySet id,
+ void *data)
+{
+ struct service *service = data;
+
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT16) {
+ g_dbus_pending_property_error(id, "org.bluez.InvalidArguments",
+ "Invalid arguments in method call");
+ return;
+ }
+
+ dbus_message_iter_get_basic(value, &service->handle);
+
+ print_service(service, COLORED_CHG);
+
+ g_dbus_pending_property_success(id);
+}
+
static gboolean service_get_uuid(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
@@ -1326,6 +1373,7 @@ static gboolean service_exist_includes(const GDBusPropertyTable *property,
static const GDBusPropertyTable service_properties[] = {
+ { "Handle", "q", service_get_handle, service_set_handle },
{ "UUID", "s", service_get_uuid },
{ "Primary", "b", service_get_primary },
{ "Includes", "ao", service_get_includes,
@@ -1493,6 +1541,35 @@ void gatt_unregister_include(DBusConnection *conn, GDBusProxy *proxy,
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
+static gboolean chrc_get_handle(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct chrc *chrc = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &chrc->handle);
+
+ return TRUE;
+}
+
+static void chrc_set_handle(const GDBusPropertyTable *property,
+ DBusMessageIter *value, GDBusPendingPropertySet id,
+ void *data)
+{
+ struct chrc *chrc = data;
+
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT16) {
+ g_dbus_pending_property_error(id, "org.bluez.InvalidArguments",
+ "Invalid arguments in method call");
+ return;
+ }
+
+ dbus_message_iter_get_basic(value, &chrc->handle);
+
+ print_chrc(chrc, COLORED_CHG);
+
+ g_dbus_pending_property_success(id);
+}
+
static gboolean chrc_get_uuid(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
@@ -1616,6 +1693,7 @@ static gboolean chrc_notify_acquired_exists(const GDBusPropertyTable *property,
}
static const GDBusPropertyTable chrc_properties[] = {
+ { "Handle", "s", chrc_get_handle, chrc_set_handle, NULL },
{ "UUID", "s", chrc_get_uuid, NULL, NULL },
{ "Service", "o", chrc_get_service, NULL, NULL },
{ "Value", "ay", chrc_get_value, NULL, NULL },
@@ -2342,6 +2420,35 @@ static const GDBusMethodTable desc_methods[] = {
{ }
};
+static gboolean desc_get_handle(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct desc *desc = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &desc->handle);
+
+ return TRUE;
+}
+
+static void desc_set_handle(const GDBusPropertyTable *property,
+ DBusMessageIter *value, GDBusPendingPropertySet id,
+ void *data)
+{
+ struct desc *desc = data;
+
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT16) {
+ g_dbus_pending_property_error(id, "org.bluez.InvalidArguments",
+ "Invalid arguments in method call");
+ return;
+ }
+
+ dbus_message_iter_get_basic(value, &desc->handle);
+
+ print_desc(desc, COLORED_CHG);
+
+ g_dbus_pending_property_success(id);
+}
+
static gboolean desc_get_uuid(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
@@ -2400,6 +2507,7 @@ static gboolean desc_get_flags(const GDBusPropertyTable *property,
}
static const GDBusPropertyTable desc_properties[] = {
+ { "Handle", "q", desc_get_handle, desc_set_handle, NULL },
{ "UUID", "s", desc_get_uuid, NULL, NULL },
{ "Characteristic", "o", desc_get_chrc, NULL, NULL },
{ "Value", "ay", desc_get_value, NULL, NULL },
--
2.17.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 6/8] client: Enable setting attribute handles
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
` (3 preceding siblings ...)
2019-01-30 13:54 ` [PATCH v2 5/8] client: Enable Handle property for GATT attributes Luiz Augusto von Dentz
@ 2019-01-30 13:54 ` Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 7/8] client: Enable list-attributes to print local attributes Luiz Augusto von Dentz
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This emulates application setting their attribute handles.
---
client/gatt.c | 11 ++++++++++-
client/main.c | 13 +++++++------
src/gatt-database.c | 24 +++++++++++++++++++-----
3 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/client/gatt.c b/client/gatt.c
index b29e68136..42fe795d7 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -1410,6 +1410,9 @@ void gatt_register_service(DBusConnection *conn, GDBusProxy *proxy,
service->path = g_strdup_printf("%s/service%p", APP_PATH, service);
service->primary = primary;
+ if (argc > 2)
+ service->handle = atoi(argv[2]);
+
if (g_dbus_register_interface(conn, service->path,
SERVICE_INTERFACE, NULL, NULL,
service_properties, service,
@@ -1693,7 +1696,7 @@ static gboolean chrc_notify_acquired_exists(const GDBusPropertyTable *property,
}
static const GDBusPropertyTable chrc_properties[] = {
- { "Handle", "s", chrc_get_handle, chrc_set_handle, NULL },
+ { "Handle", "q", chrc_get_handle, chrc_set_handle, NULL },
{ "UUID", "s", chrc_get_uuid, NULL, NULL },
{ "Service", "o", chrc_get_service, NULL, NULL },
{ "Value", "ay", chrc_get_value, NULL, NULL },
@@ -2289,6 +2292,9 @@ void gatt_register_chrc(DBusConnection *conn, GDBusProxy *proxy,
chrc->flags = g_strsplit(argv[2], ",", -1);
chrc->authorization_req = attr_authorization_flag_exists(chrc->flags);
+ if (argc > 3)
+ chrc->handle = atoi(argv[3]);
+
if (g_dbus_register_interface(conn, chrc->path, CHRC_INTERFACE,
chrc_methods, NULL, chrc_properties,
chrc, chrc_free) == FALSE) {
@@ -2555,6 +2561,9 @@ void gatt_register_desc(DBusConnection *conn, GDBusProxy *proxy,
desc->path = g_strdup_printf("%s/desc%p", desc->chrc->path, desc);
desc->flags = g_strsplit(argv[2], ",", -1);
+ if (argc > 3)
+ desc->handle = atoi(argv[3]);
+
if (g_dbus_register_interface(conn, desc->path, DESC_INTERFACE,
desc_methods, NULL, desc_properties,
desc, desc_free) == FALSE) {
diff --git a/client/main.c b/client/main.c
index a4647f334..07c8ec008 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2619,22 +2619,23 @@ static const struct bt_shell_menu gatt_menu = {
"Register profile to connect" },
{ "unregister-application", NULL, cmd_unregister_app,
"Unregister profile" },
- { "register-service", "<UUID>", cmd_register_service,
+ { "register-service", "<UUID> [handle]", cmd_register_service,
"Register application service." },
{ "unregister-service", "<UUID/object>", cmd_unregister_service,
"Unregister application service" },
- { "register-includes", "<UUID>", cmd_register_includes,
+ { "register-includes", "<UUID> [handle]", cmd_register_includes,
"Register as Included service in." },
{ "unregister-includes", "<Service-UUID><Inc-UUID>",
cmd_unregister_includes,
"Unregister Included service." },
- { "register-characteristic", "<UUID> <Flags=read,write,notify...> "
- , cmd_register_characteristic,
- "Register application characteristic" },
+ { "register-characteristic",
+ "<UUID> <Flags=read,write,notify...> [handle]",
+ cmd_register_characteristic,
+ "Register application characteristic" },
{ "unregister-characteristic", "<UUID/object>",
cmd_unregister_characteristic,
"Unregister application characteristic" },
- { "register-descriptor", "<UUID> <Flags=read,write...>",
+ { "register-descriptor", "<UUID> <Flags=read,write...> [handle]",
cmd_register_descriptor,
"Register application descriptor" },
{ "unregister-descriptor", "<UUID/object>",
diff --git a/src/gatt-database.c b/src/gatt-database.c
index b159786ea..cca70c947 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -1843,17 +1843,16 @@ static bool parse_handle(GDBusProxy *proxy, uint16_t *handle)
{
DBusMessageIter iter;
+ *handle = 0;
+
/* Handle property is optional */
- if (!g_dbus_proxy_get_property(proxy, "Handle", &iter)) {
- *handle = 0;
+ if (!g_dbus_proxy_get_property(proxy, "Handle", &iter))
return true;
- }
-
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16)
return false;
- dbus_message_iter_get_basic(&iter, &handle);
+ dbus_message_iter_get_basic(&iter, handle);
return true;
}
@@ -2634,6 +2633,7 @@ static bool database_add_desc(struct external_service *service,
{
uint16_t handle;
bt_uuid_t uuid;
+ char str[MAX_LEN_UUID_STR];
if (!parse_handle(desc->proxy, &handle)) {
error("Failed to read \"Handle\" property of descriptor");
@@ -2662,6 +2662,10 @@ static bool database_add_desc(struct external_service *service,
write_handle(desc->proxy, handle);
}
+ bt_uuid_to_string(&uuid, str, sizeof(str));
+
+ DBG("handle 0x%04x UUID %s", handle, str);
+
return true;
}
@@ -2795,6 +2799,7 @@ static bool database_add_chrc(struct external_service *service,
{
uint16_t handle;
bt_uuid_t uuid;
+ char str[MAX_LEN_UUID_STR];
const struct queue_entry *entry;
if (!parse_handle(chrc->proxy, &handle)) {
@@ -2832,6 +2837,10 @@ static bool database_add_chrc(struct external_service *service,
write_handle(chrc->proxy, handle);
}
+ bt_uuid_to_string(&uuid, str, sizeof(str));
+
+ DBG("handle 0x%04x UUID %s", handle, str);
+
/* Handle the descriptors that belong to this characteristic. */
for (entry = queue_get_entries(service->descs); entry;
entry = entry->next) {
@@ -2863,6 +2872,7 @@ static bool database_add_service(struct external_service *service)
bool primary;
uint16_t handle;
const struct queue_entry *entry;
+ char str[MAX_LEN_UUID_STR];
if (!parse_uuid(service->proxy, &uuid)) {
error("Failed to read \"UUID\" property of service");
@@ -2895,6 +2905,10 @@ static bool database_add_service(struct external_service *service)
write_handle(service->proxy, handle);
}
+ bt_uuid_to_string(&uuid, str, sizeof(str));
+
+ DBG("handle 0x%04x UUID %s", handle, str);
+
database_add_includes(service);
entry = queue_get_entries(service->chrcs);
--
2.17.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 7/8] client: Enable list-attributes to print local attributes
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
` (4 preceding siblings ...)
2019-01-30 13:54 ` [PATCH v2 6/8] client: Enable setting attribute handles Luiz Augusto von Dentz
@ 2019-01-30 13:54 ` Luiz Augusto von Dentz
2019-01-30 13:54 ` [PATCH v2 8/8] client: Don't expose pointer value in attribute path Luiz Augusto von Dentz
2019-01-31 12:17 ` [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This enable passing "local" to list-attributes to print the attributes
registered locally:
> list-attributes local
Primary Service (Handle 0x0400)
/org/bluez/app/service0x74ccb0
0x1820
Internet Protocol Support
---
client/gatt.c | 42 ++++++++++++++++++++++++++++++++++++++++++
client/main.c | 15 ++++++++++++---
2 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/client/gatt.c b/client/gatt.c
index 42fe795d7..8e06e793f 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -414,8 +414,50 @@ static void list_attributes(const char *path, GList *source)
}
}
+static void list_descs(GList *descs)
+{
+ GList *l;
+
+ for (l = descs; l; l = g_list_next(l)) {
+ struct desc *desc = l->data;
+
+ print_desc(desc, NULL);
+ }
+}
+
+static void list_chrcs(GList *chrcs)
+{
+ GList *l;
+
+ for (l = chrcs; l; l = g_list_next(l)) {
+ struct chrc *chrc = l->data;
+
+ print_chrc(chrc, NULL);
+
+ list_descs(chrc->descs);
+ }
+}
+
+static void list_services(void)
+{
+ GList *l;
+
+ for (l = local_services; l; l = g_list_next(l)) {
+ struct service *service = l->data;
+
+ print_service(service, NULL);
+
+ list_chrcs(service->chrcs);
+ }
+}
+
void gatt_list_attributes(const char *path)
{
+ if (path && !strcmp(path, "local")) {
+ list_services();
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+ }
+
list_attributes(path, services);
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
diff --git a/client/main.c b/client/main.c
index 07c8ec008..16433f96d 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1905,12 +1905,21 @@ static void cmd_disconn(int argc, char *argv[])
static void cmd_list_attributes(int argc, char *argv[])
{
GDBusProxy *proxy;
+ const char *path;
+
+ if (argc > 1 && !strcmp(argv[1], "local")) {
+ path = argv[1];
+ goto done;
+ }
proxy = find_device(argc, argv);
if (!proxy)
return bt_shell_noninteractive_quit(EXIT_FAILURE);
- gatt_list_attributes(g_dbus_proxy_get_path(proxy));
+ path = g_dbus_proxy_get_path(proxy);
+
+done:
+ gatt_list_attributes(path);
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
@@ -2596,8 +2605,8 @@ static const struct bt_shell_menu gatt_menu = {
.name = "gatt",
.desc = "Generic Attribute Submenu",
.entries = {
- { "list-attributes", "[dev]", cmd_list_attributes, "List attributes",
- dev_generator },
+ { "list-attributes", "[dev/local]", cmd_list_attributes,
+ "List attributes", dev_generator },
{ "select-attribute", "<attribute/UUID>", cmd_select_attribute,
"Select attribute", attribute_generator },
{ "attribute-info", "[attribute/UUID]", cmd_attribute_info,
--
2.17.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 8/8] client: Don't expose pointer value in attribute path
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
` (5 preceding siblings ...)
2019-01-30 13:54 ` [PATCH v2 7/8] client: Enable list-attributes to print local attributes Luiz Augusto von Dentz
@ 2019-01-30 13:54 ` Luiz Augusto von Dentz
2019-01-31 12:17 ` [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Instead use the position in the list to create a unique path:
[bluetooth]# register-service 0x1820
[NEW] Primary Service (Handle 0x0000)
/org/bluez/app/service0
0x1820
Internet Protocol Support
---
client/gatt.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/client/gatt.c b/client/gatt.c
index 8e06e793f..06364a820 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -1449,7 +1449,8 @@ void gatt_register_service(DBusConnection *conn, GDBusProxy *proxy,
service = g_new0(struct service, 1);
service->conn = conn;
service->uuid = g_strdup(argv[1]);
- service->path = g_strdup_printf("%s/service%p", APP_PATH, service);
+ service->path = g_strdup_printf("%s/service%u", APP_PATH,
+ g_list_length(local_services));
service->primary = primary;
if (argc > 2)
@@ -2330,7 +2331,8 @@ void gatt_register_chrc(DBusConnection *conn, GDBusProxy *proxy,
chrc = g_new0(struct chrc, 1);
chrc->service = service;
chrc->uuid = g_strdup(argv[1]);
- chrc->path = g_strdup_printf("%s/chrc%p", service->path, chrc);
+ chrc->path = g_strdup_printf("%s/chrc%u", service->path,
+ g_list_length(service->chrcs));
chrc->flags = g_strsplit(argv[2], ",", -1);
chrc->authorization_req = attr_authorization_flag_exists(chrc->flags);
@@ -2600,7 +2602,8 @@ void gatt_register_desc(DBusConnection *conn, GDBusProxy *proxy,
desc = g_new0(struct desc, 1);
desc->chrc = g_list_last(service->chrcs)->data;
desc->uuid = g_strdup(argv[1]);
- desc->path = g_strdup_printf("%s/desc%p", desc->chrc->path, desc);
+ desc->path = g_strdup_printf("%s/desc%u", desc->chrc->path,
+ g_list_length(desc->chrc->descs));
desc->flags = g_strsplit(argv[2], ",", -1);
if (argc > 3)
--
2.17.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/8] doc/gatt-api: Add Handle property
2019-01-30 13:54 [PATCH v2 1/8] doc/gatt-api: Add Handle property Luiz Augusto von Dentz
` (6 preceding siblings ...)
2019-01-30 13:54 ` [PATCH v2 8/8] client: Don't expose pointer value in attribute path Luiz Augusto von Dentz
@ 2019-01-31 12:17 ` Luiz Augusto von Dentz
7 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2019-01-31 12:17 UTC (permalink / raw)
To: linux-bluetooth
Hi,
On Wed, Jan 30, 2019 at 3:54 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> When acting as server it is useful to select where to allocate the
> handle for an attribute so it can be restored in the same position when
> restarting the daemon or rebooting the system.
>
> In order to do that the application also needs to know in which handle
> the attribute is allocated the very first time it is registered, this
> also allows for a better integration with PTS and tools like auto-pts
> which needs to know the handles where the attributes have been
> allocated.
> ---
> v2: Fixes inserting characteristics and descriptors with handle 0x0000,
> add a patch to enable list-attribute to list with local attributes and
> print changes to attribute Handle property.
>
> doc/gatt-api.txt | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
> index 8dda60b8a..491eb026a 100644
> --- a/doc/gatt-api.txt
> +++ b/doc/gatt-api.txt
> @@ -50,6 +50,14 @@ Properties string UUID [read-only]
> Array of object paths representing the included
> services of this service.
>
> + uint16 Handle [read-write, optional] (Server Only)
> +
> + Service handle. When available in the server it
> + would attempt to use to allocate into the database
> + which may fail, to auto allocate the value 0x0000
> + shall be used which will cause the allocated handle to
> + be set once registered.
> +
>
> Characteristic hierarchy
> ========================
> @@ -257,6 +265,14 @@ Properties string UUID [read-only]
> "secure-write" (Server only)
> "authorize"
>
> + uint16 Handle [read-write, optional] (Server Only)
> +
> + Characteristic handle. When available in the server it
> + would attempt to use to allocate into the database
> + which may fail, to auto allocate the value 0x0000
> + shall be used which will cause the allocated handle to
> + be set once registered.
> +
> Characteristic Descriptors hierarchy
> ====================================
>
> @@ -332,6 +348,14 @@ Properties string UUID [read-only]
> "secure-write" (Server Only)
> "authorize"
>
> + uint16 Handle [read-write, optional] (Server Only)
> +
> + Characteristic handle. When available in the server it
> + would attempt to use to allocate into the database
> + which may fail, to auto allocate the value 0x0000
> + shall be used which will cause the allocated handle to
> + be set once registered.
> +
> GATT Profile hierarchy
> =====================
>
> --
> 2.17.2
Applied.
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 9+ messages in thread