Linux-Bluetooth Archive on lore.kernel.org
 help / color / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ 09/15] gatt: Add caching support for server
Date: Tue, 29 Jan 2019 15:26:28 +0200
Message-ID: <20190129132634.28786-9-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20190129132634.28786-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This registers both Client Features and Database Hash Characteristics
which are mandatory for the server.
---
 src/gatt-database.c | 103 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 1 deletion(-)

diff --git a/src/gatt-database.c b/src/gatt-database.c
index 2c2f035b1..d72f2c781 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -86,6 +86,8 @@ struct btd_gatt_database {
 	struct queue *ccc_callbacks;
 	struct gatt_db_attribute *svc_chngd;
 	struct gatt_db_attribute *svc_chngd_ccc;
+	struct gatt_db_attribute *cli_feat;
+	struct gatt_db_attribute *db_hash;
 	struct queue *apps;
 	struct queue *profiles;
 };
@@ -177,6 +179,7 @@ struct device_state {
 	bdaddr_t bdaddr;
 	uint8_t bdaddr_type;
 	unsigned int disc_id;
+	uint8_t cli_feat[1];
 	struct queue *ccc_states;
 	struct notify *pending;
 };
@@ -1055,6 +1058,90 @@ service_add_ccc(struct gatt_db_attribute *service,
 	return ccc;
 }
 
+static void cli_feat_read_cb(struct gatt_db_attribute *attrib,
+					unsigned int id, uint16_t offset,
+					uint8_t opcode, struct bt_att *att,
+					void *user_data)
+{
+	struct btd_gatt_database *database = user_data;
+	struct device_state *state;
+	uint8_t ecode = 0;
+	const uint8_t *value = NULL;
+	size_t len = 0;
+
+	DBG("Client Features read");
+
+	state = get_device_state(database, att);
+	if (!state) {
+		ecode = BT_ATT_ERROR_UNLIKELY;
+		goto done;
+	}
+
+	len = sizeof(state->cli_feat) - offset;
+	value = len ? &state->cli_feat[offset] : NULL;
+
+done:
+	gatt_db_attribute_read_result(attrib, id, ecode, value, len);
+}
+
+static void cli_feat_write_cb(struct gatt_db_attribute *attrib,
+					unsigned int id, uint16_t offset,
+					const uint8_t *value, size_t len,
+					uint8_t opcode, struct bt_att *att,
+					void *user_data)
+{
+	struct btd_gatt_database *database = user_data;
+	struct device_state *state;
+	uint8_t ecode = 0;
+
+	DBG("Client Features write");
+
+	state = get_device_state(database, att);
+	if (!state) {
+		ecode = BT_ATT_ERROR_UNLIKELY;
+		goto done;
+	}
+
+	if (!value || !len) {
+		ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
+		goto done;
+	}
+
+	/* A client shall never clear a bit it has set.
+	 * TODO: make it generic to any bits.
+	 */
+	if (state->cli_feat[0] & BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING &&
+			!(value[0] & BT_GATT_CHRC_CLI_FEAT_ROBUST_CACHING)) {
+		ecode = BT_ATT_ERROR_VALUE_NOT_ALLOWED;
+		goto done;
+	}
+
+	/* Shall we reallocate the feat array if bigger? */
+	len = MIN(sizeof(state->cli_feat), len);
+	while (len) {
+		state->cli_feat[len - 1] |= value[len -1];
+		len--;
+	}
+
+done:
+	gatt_db_attribute_write_result(attrib, id, ecode);
+}
+
+static void db_hash_read_cb(struct gatt_db_attribute *attrib,
+					unsigned int id, uint16_t offset,
+					uint8_t opcode, struct bt_att *att,
+					void *user_data)
+{
+	struct btd_gatt_database *database = user_data;
+	const uint8_t *hash;
+
+	DBG("Database Hash read");
+
+	hash = gatt_db_get_hash(database->db);
+
+	gatt_db_attribute_read_result(attrib, id, 0, hash, 16);
+}
+
 static void populate_gatt_service(struct btd_gatt_database *database)
 {
 	bt_uuid_t uuid;
@@ -1062,7 +1149,7 @@ static void populate_gatt_service(struct btd_gatt_database *database)
 
 	/* Add the GATT service */
 	bt_uuid16_create(&uuid, UUID_GATT);
-	service = gatt_db_add_service(database->db, &uuid, true, 4);
+	service = gatt_db_add_service(database->db, &uuid, true, 8);
 
 	bt_uuid16_create(&uuid, GATT_CHARAC_SERVICE_CHANGED);
 	database->svc_chngd = gatt_db_service_add_characteristic(service, &uuid,
@@ -1072,11 +1159,25 @@ static void populate_gatt_service(struct btd_gatt_database *database)
 	database->svc_chngd_ccc = service_add_ccc(service, database, NULL, NULL,
 									NULL);
 
+	bt_uuid16_create(&uuid, GATT_CHARAC_CLI_FEAT);
+	database->cli_feat = gatt_db_service_add_characteristic(service,
+				&uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+				BT_GATT_CHRC_PROP_READ |
+				BT_GATT_CHRC_PROP_WRITE,
+				cli_feat_read_cb, cli_feat_write_cb,
+				database);
+
+	bt_uuid16_create(&uuid, GATT_CHARAC_DB_HASH);
+	database->db_hash = gatt_db_service_add_characteristic(service,
+				&uuid, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
+				db_hash_read_cb, NULL, database);
+
 	gatt_db_service_set_active(service, true);
 
 	database_add_record(database, service);
 }
 
+
 static void register_core_services(struct btd_gatt_database *database)
 {
 	populate_gap_service(database);
-- 
2.17.2


  parent reply index

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-29 13:26 [PATCH BlueZ 01/15] shared/crypto: Add bt_crypto_gatt_hash Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 02/15] unit/test-crypto: Add test for bt_crypto_gatt_hash Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 03/15] lib/uuid: Introduce definition for GATT caching attributes Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 04/15] shared/util: Add decoding support " Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 05/15] shared/att-types: Add errors introduced by GATT caching Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 06/15] monitor: Decode GATT Caching errors Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 07/15] shared/gatt-db: Introduce Database Hash Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 08/15] shared/gatt-db: Generate database hash Luiz Augusto von Dentz
2019-01-29 13:26 ` Luiz Augusto von Dentz [this message]
2019-01-29 13:26 ` [PATCH BlueZ 10/15] shared/gatt-db: Add gatt_db_set_authorize Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 11/15] shared/gatt-server: Add bt_gatt_server_set_authorize Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 12/15] gatt: Implement Robust Caching handling for server Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 13/15] shared/gatt-client: Read database hash if available Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 14/15] shared/gatt-client: Write Client Features Luiz Augusto von Dentz
2019-01-29 13:26 ` [PATCH BlueZ 15/15] device: Store Database Hash on storage Luiz Augusto von Dentz
2019-02-06 11:49 ` [PATCH BlueZ 01/15] shared/crypto: Add bt_crypto_gatt_hash Luiz Augusto von Dentz

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190129132634.28786-9-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Bluetooth Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-bluetooth/0 linux-bluetooth/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-bluetooth linux-bluetooth/ https://lore.kernel.org/linux-bluetooth \
		linux-bluetooth@vger.kernel.org linux-bluetooth@archiver.kernel.org
	public-inbox-index linux-bluetooth


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-bluetooth


AGPL code for this site: git clone https://public-inbox.org/ public-inbox