Commit 00bfac00 authored by Krzysztof Kopyściński's avatar Krzysztof Kopyściński Committed by Christopher Friedt
Browse files

Bluetooth: gatt: Add option to read multiple without variable length



Currently, with EATT enabled, when bt_gatt_read is called with multiple
handles first it'll try to use gatt_read_mult_vl, and if it fails
gatt_read_mult will be used to try again. Add option to skip
the gatt_read_mult_vl and use gatt_read_mult right away. This is needed
by tests that expect BT_ATT_OP_READ_MULT_REQ but support variable
lenght, thus don't return BT_ATT_ERR_NOT_SUPPORTED.

Removed fallback from read multiple vl to read multiple on
BT_ATT_ERR_NOT_SUPPORTED error.

This was affecting:
GATT/CL/GAR/BV-05-C, GATT/CL/GAR/BI-18-C, GATT/CL/GAR/BI-19-C,
GATT/CL/GAR/BI-20-C, GATT/CL/GAR/BI-21-C, GATT/CL/GAR/BI-22-C

Signed-off-by: default avatarKrzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>
parent e4dc8ed2
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -52,6 +52,12 @@ Removed APIs in this release
Stable API changes in this release
==================================

* Bluetooth

  * Added :c:struct:`multiple` to the :c:struct:`bt_gatt_read_params` - this
    structure contains two members: ``handles``, which was moved from
    :c:struct:`bt_gatt_read_params`, and ``variable``.

Kernel
******

+18 −4
Original line number Diff line number Diff line
@@ -1366,8 +1366,7 @@ struct bt_gatt_read_params {
	/** Read attribute callback. */
	bt_gatt_read_func_t func;
	/** If equals to 1 single.handle and single.offset are used.
	 *  If >1 Read Multiple Characteristic Values is performed and handles
	 *  are used.
	 *  If greater than 1 multiple.handles are used.
	 *  If equals to 0 by_uuid is used for Read Using Characteristic UUID.
	 */
	size_t handle_count;
@@ -1378,8 +1377,23 @@ struct bt_gatt_read_params {
			/** Attribute data offset. */
			uint16_t offset;
		} single;
		/** Handles to read in Read Multiple Characteristic Values. */
		struct {
			/** Attribute handles to read with Read Multiple
			 *  Characteristic Values.
			 */
			uint16_t *handles;
			/** If true use Read Multiple Variable Length
			 *  Characteristic Values procedure.
			 *  The values of the set of attributes may be of
			 *  variable or unknown length.
			 *  If false use Read Multiple Characteristic Values
			 *  procedure.
			 *  The values of the set of attributes must be of a
			 *  known fixed length, with the exception of the last
			 *  value that can have a variable length.
			 */
			bool variable;
		} multiple;
		struct {
			/** First requested handle number. */
			uint16_t start_handle;
+10 −11
Original line number Diff line number Diff line
@@ -3951,7 +3951,7 @@ static int gatt_read_mult_encode(struct net_buf *buf, size_t len,
	uint8_t i;

	for (i = 0U; i < params->handle_count; i++) {
		net_buf_add_le16(buf, params->handles[i]);
		net_buf_add_le16(buf, params->multiple.handles[i]);
	}

	return 0;
@@ -3979,9 +3979,6 @@ static void gatt_read_mult_vl_rsp(struct bt_conn *conn, uint8_t err,
	BT_DBG("err 0x%02x", err);

	if (err || !length) {
		if (err == BT_ATT_ERR_NOT_SUPPORTED) {
			gatt_read_mult(conn, params);
		}
		params->func(conn, err, params, NULL, 0);
		return;
	}
@@ -4018,7 +4015,7 @@ static int gatt_read_mult_vl_encode(struct net_buf *buf, size_t len,
	uint8_t i;

	for (i = 0U; i < params->handle_count; i++) {
		net_buf_add_le16(buf, params->handles[i]);
		net_buf_add_le16(buf, params->multiple.handles[i]);
	}

	return 0;
@@ -4042,13 +4039,15 @@ static int gatt_read_mult(struct bt_conn *conn,
{
	return -ENOTSUP;
}
#endif /* CONFIG_BT_GATT_READ_MULTIPLE */

#if !defined(CONFIG_BT_GATT_READ_MULTIPLE) || !defined(CONFIG_BT_EATT)
static int gatt_read_mult_vl(struct bt_conn *conn,
			     struct bt_gatt_read_params *params)
{
	return -ENOTSUP;
}
#endif /* CONFIG_BT_GATT_READ_MULTIPLE */
#endif

static int gatt_read_encode(struct net_buf *buf, size_t len, void *user_data)
{
@@ -4075,11 +4074,11 @@ int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params)
	}

	if (params->handle_count > 1) {
#if defined(CONFIG_BT_EATT)
		if (params->multiple.variable) {
			return gatt_read_mult_vl(conn, params);
#else
		} else {
			return gatt_read_mult(conn, params);
#endif /* CONFIG_BT_EATT */
		}
	}

	if (params->single.offset) {
+2 −1
Original line number Diff line number Diff line
@@ -340,7 +340,8 @@ static int cmd_mread(const struct shell *shell, size_t argc, char *argv[])

	read_params.func = read_func;
	read_params.handle_count = i;
	read_params.handles = h; /* not used in read func */
	read_params.multiple.handles = h;
	read_params.multiple.variable = true;

	err = bt_gatt_read(default_conn, &read_params);
	if (err) {
+2 −1
Original line number Diff line number Diff line
@@ -1528,7 +1528,8 @@ static void read_multiple(uint8_t *data, uint16_t len)

	read_params.func = read_cb;
	read_params.handle_count = i;
	read_params.handles = handles; /* not used in read func */
	read_params.multiple.handles = handles; /* not used in read func */
	read_params.multiple.variable = false;

	/* TODO should be handled as user_data via CONTAINER_OF macro */
	btp_opcode = GATT_READ_MULTIPLE;