Commit 1b7b6af7 authored by Sean Madigan's avatar Sean Madigan Committed by Johan Hedberg
Browse files

bluetooth: host: add frame space update support



This commit adds support for the frame space update feature
to the bluetooth host.

This is mainly just a wrapper around the frame space update
HCI command and event.

Signed-off-by: default avatarSean Madigan <sean.madigan@nordicsemi.no>
parent 9bbc906b
Loading
Loading
Loading
Loading
+117 −0
Original line number Diff line number Diff line
@@ -273,6 +273,86 @@ struct bt_conn_le_read_all_remote_feat_complete {
	const uint8_t *features;
};

#define BT_CONN_LE_FRAME_SPACE_TYPES_MASK_ACL_IFS                    \
	(BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_ACL_CP_MASK | \
	 BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_ACL_PC_MASK)

#define BT_CONN_LE_FRAME_SPACE_TYPES_MASK_ACL                        \
	(BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_ACL_CP_MASK | \
	 BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_ACL_PC_MASK | \
	 BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_MCES_MASK)

#define BT_CONN_LE_FRAME_SPACE_TYPES_MASK_CIS                     \
	(BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_CIS_MASK | \
	 BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_MSS_CIS_MASK)

/** Maximum frame space in microseconds.
 *  As defined in Bluetooth Core Specification, Vol 4, Part E, Section 7.8.151.
 */
#define BT_CONN_LE_FRAME_SPACE_MAX (10000U)

/** Frame space update initiator. */
enum bt_conn_le_frame_space_update_initiator {
	/** Initiated by local host */
	BT_CONN_LE_FRAME_SPACE_UPDATE_INITIATOR_LOCAL_HOST =
		BT_HCI_LE_FRAME_SPACE_UPDATE_INITIATOR_LOCAL_HOST,
	/** Initiated by local controller */
	BT_CONN_LE_FRAME_SPACE_UPDATE_INITIATOR_LOCAL_CONTROLLER =
		BT_HCI_LE_FRAME_SPACE_UPDATE_INITIATOR_LOCAL_CONTROLLER,
	/** Initiated by peer */
	BT_CONN_LE_FRAME_SPACE_UPDATE_INITIATOR_PEER =
		BT_HCI_LE_FRAME_SPACE_UPDATE_INITIATOR_PEER
};

/** Frame space update params */
struct bt_conn_le_frame_space_update_param {
	/** Phy mask of the PHYs to be updated.
	 *  Refer to BT_HCI_LE_FRAME_SPACE_UPDATE_PHY_* for values.
	 */
	uint8_t phys;
	/** Spacing types mask of the spacing types to be updated.
	 *  Refer to BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_* and
	 *  BT_CONN_LE_FRAME_SPACE_TYPES_MASK_* for values.
	 */
	uint16_t spacing_types;
	/** Minimum frame space in microseconds.
	 *  Bluetooth Core Specification, Vol 4, Part E, Section 7.8.151
	 *  allows for a range of frame space from 0 to 10000 microseconds.
	 *  The actual supported frame space values will be dependent on
	 *  the controller's capabilities.
	 */
	uint16_t frame_space_min;
	/** Maximum frame space in microseconds.
	 *  Bluetooth Core Specification, Vol 4, Part E, Section 7.8.151
	 *  allows for a range of frame space from 0 to 10000 microseconds.
	 *  The actual supported frame space values will be dependent on
	 *  the controller's capabilities.
	 */
	uint16_t frame_space_max;
};

/** Frame space updated callback params */
struct bt_conn_le_frame_space_updated {
	/** HCI Status from LE Frame Space Update Complete event.
	 *  The remaining parameters will be invalid if status is not
	 *  @ref BT_HCI_ERR_SUCCESS.
	 */
	uint8_t status;
	/** Initiator of the frame space update. */
	enum bt_conn_le_frame_space_update_initiator initiator;
	/** Updated frame space in microseconds. */
	uint16_t frame_space;
	/** Phy mask of the PHYs updated.
	 *  Refer to BT_HCI_LE_FRAME_SPACE_UPDATE_PHY_* for values.
	 */
	uint8_t phys;
	/** Spacing types mask of the spacing types updated.
	 *  Refer to BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_* and
	 *  BT_CONN_LE_FRAME_SPACE_TYPES_MASK_* for values.
	 */
	uint16_t spacing_types;
};

/** Connection Type */
enum __packed bt_conn_type {
	/** LE Connection Type */
@@ -1225,6 +1305,23 @@ int bt_conn_le_subrate_request(struct bt_conn *conn,
 */
int bt_conn_le_read_all_remote_features(struct bt_conn *conn, uint8_t pages_requested);

/** @brief Update frame space.
 *
 *  Request a change to the frame space parameters of a connection.
 *  This function will trigger the frame_space_updated callback when the
 *  procedure is completed.
 *
 *  @kconfig_dep{CONFIG_BT_FRAME_SPACE_UPDATE}.
 *
 *  @param conn   @ref BT_CONN_TYPE_LE connection object.
 *  @param params Frame Space Update parameters.
 *
 *  @return Zero on success or (negative) error code on failure.
 *  @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection.
 */
int bt_conn_le_frame_space_update(struct bt_conn *conn,
				  const struct bt_conn_le_frame_space_update_param *params);

/** @brief Update the connection parameters.
 *
 *  If the local device is in the peripheral role then updating the connection
@@ -1949,6 +2046,26 @@ struct bt_conn_cb {
		const struct bt_conn_le_read_all_remote_feat_complete *params);
#endif /* CONFIG_BT_LE_EXTENDED_FEAT_SET */

#if defined(CONFIG_BT_FRAME_SPACE_UPDATE)
	/** @brief Frame Space Update Complete event.
	 *
	 *  This callback notifies the application that the frame space of
	 *  the connection may have changed.
	 *  The frame space update parameters will be invalid
	 *  if status is not @ref BT_HCI_ERR_SUCCESS.
	 *
	 *  This callback can be triggered by calling @ref
	 *  bt_conn_le_frame_space_update, by the procedure running
	 *  autonomously in the controller or by the peer.
	 *
	 *  @param conn   Connection object.
	 *  @param params New frame space update parameters.
	 */
	void (*frame_space_updated)(
		struct bt_conn *conn,
		const struct bt_conn_le_frame_space_updated *params);
#endif /* CONFIG_BT_FRAME_SPACE_UPDATE */

#if defined(CONFIG_BT_CHANNEL_SOUNDING)
	/** @brief LE CS Read Remote Supported Capabilities Complete event.
	 *
+39 −0
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ struct bt_hci_cmd_hdr {
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING_HOST    47
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING_TONE_QUAL_IND    48
#define BT_LE_FEAT_BIT_EXTENDED_FEAT_SET        63
#define BT_LE_FEAT_BIT_FRAME_SPACE_UPDATE       65

#define BT_LE_FEAT_TEST(feat, n)                (feat[(n) >> 3] & \
						 BIT((n) & 7))
@@ -286,6 +287,8 @@ struct bt_hci_cmd_hdr {
						  BT_LE_FEAT_BIT_CHANNEL_SOUNDING_HOST)
#define BT_FEAT_LE_EXTENDED_FEAT_SET(feat)        BT_LE_FEAT_TEST(feat, \
						  BT_LE_FEAT_BIT_EXTENDED_FEAT_SET)
#define BT_FEAT_LE_FRAME_SPACE_UPDATE_SET(feat)   BT_LE_FEAT_TEST(feat, \
						  BT_LE_FEAT_BIT_FRAME_SPACE_UPDATE)

#define BT_FEAT_LE_CIS(feat)            (BT_FEAT_LE_CIS_CENTRAL(feat) | \
					BT_FEAT_LE_CIS_PERIPHERAL(feat))
@@ -2815,6 +2818,30 @@ struct bt_hci_cp_le_cs_remove_config {

#define BT_HCI_OP_LE_CS_TEST_END BT_OP(BT_OGF_LE, 0x0096) /* 0x2096 */

#define BT_HCI_LE_FRAME_SPACE_UPDATE_PHY_1M_MASK    BIT(0)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_PHY_2M_MASK    BIT(1)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_PHY_CODED_MASK BIT(2)

#define BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_ACL_CP_MASK BIT(0)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_ACL_PC_MASK BIT(1)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_MCES_MASK       BIT(2)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_IFS_CIS_MASK    BIT(3)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_SPACING_TYPE_MSS_CIS_MASK    BIT(4)

#define BT_HCI_LE_FRAME_SPACE_UPDATE_INITIATOR_LOCAL_HOST       (0)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_INITIATOR_LOCAL_CONTROLLER (1)
#define BT_HCI_LE_FRAME_SPACE_UPDATE_INITIATOR_PEER             (2)

struct bt_hci_cp_le_frame_space_update {
	uint16_t handle;
	uint16_t frame_space_min;
	uint16_t frame_space_max;
	uint8_t  phys;
	uint16_t spacing_types;
} __packed;

#define BT_HCI_OP_LE_FRAME_SPACE_UPDATE BT_OP(BT_OGF_LE, 0x009D) /* 0x209D */

/* Event definitions */

#define BT_HCI_EVT_UNKNOWN                      0x00
@@ -4004,6 +4031,16 @@ struct bt_hci_evt_le_cs_procedure_enable_complete {
	uint16_t max_procedure_len;
} __packed;

#define BT_HCI_EVT_LE_FRAME_SPACE_UPDATE_COMPLETE 0x35
struct bt_hci_evt_le_frame_space_update_complete {
	uint8_t  status;
	uint16_t handle;
	uint8_t  initiator;
	uint16_t frame_space;
	uint8_t  phys;
	uint16_t spacing_types;
} __packed;

/* Event mask bits */

#define BT_EVT_BIT(n) (1ULL << (n))
@@ -4105,6 +4142,8 @@ struct bt_hci_evt_le_cs_procedure_enable_complete {
#define BT_EVT_MASK_LE_CS_SUBEVENT_RESULT_CONTINUE                    BT_EVT_BIT(49)
#define BT_EVT_MASK_LE_CS_TEST_END_COMPLETE                           BT_EVT_BIT(50)

#define BT_EVT_MASK_LE_FRAME_SPACE_UPDATE_COMPLETE BT_EVT_BIT(52)

/** HCI Error Codes, BT Core Spec v5.4 [Vol 1, Part F]. */
#define BT_HCI_ERR_SUCCESS                      0x00
#define BT_HCI_ERR_UNKNOWN_CMD                  0x01
+16 −2
Original line number Diff line number Diff line
@@ -115,10 +115,18 @@ config BT_CONN_TX
	help
	  Hidden configuration that is true if ACL or broadcast ISO is enabled

config BT_LE_LOCAL_MINIMUM_REQUIRED_FEATURE_PAGE
	int
	default 1 if BT_FRAME_SPACE_UPDATE
	default 0
	depends on BT_LE_EXTENDED_FEAT_SET
	help
	  Minimum required feature page that must be supported.

config BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE
	int "Maximum supported feature page"
	default 0
	range 0 10
	default BT_LE_LOCAL_MINIMUM_REQUIRED_FEATURE_PAGE
	range BT_LE_LOCAL_MINIMUM_REQUIRED_FEATURE_PAGE 10
	depends on BT_LE_EXTENDED_FEAT_SET
	help
	  Maximum feature page that can be stored for local supported features.
@@ -212,6 +220,12 @@ config BT_SUBRATING
	  Enable support for LE Connection Subrating feature that is defined in the
	  Bluetooth Core specification, Version 5.4 | Vol 6, Part B, Section 4.6.35.

config BT_FRAME_SPACE_UPDATE
	bool "Frame Space Update"
	depends on (!HAS_BT_CTLR || BT_CTLR_FRAME_SPACE_UPDATE_SUPPORT) && BT_CONN && BT_LE_EXTENDED_FEAT_SET
	help
	  Enable support for Bluetooth 6.0 Frame Space Update feature.

config BT_CHANNEL_SOUNDING
	bool "Channel Sounding [EXPERIMENTAL]"
	select EXPERIMENTAL
+11 −0
Original line number Diff line number Diff line
@@ -125,6 +125,9 @@ config BT_CTLR_LE_PATH_LOSS_MONITORING_SUPPORT
config BT_CTLR_SUBRATING_SUPPORT
	bool

config BT_CTLR_FRAME_SPACE_UPDATE_SUPPORT
	bool

config BT_CTLR_CHANNEL_SOUNDING_SUPPORT
	bool

@@ -1168,6 +1171,14 @@ config BT_CTLR_SUBRATING
	  Enable support for Bluetooth v5.3 LE Connection Subrating
	  in the Controller.

config BT_CTLR_FRAME_SPACE_UPDATE
	bool "Frame Space Update"
	depends on BT_CTLR_FRAME_SPACE_UPDATE_SUPPORT
	default y if BT_FRAME_SPACE_UPDATE
	help
	  Enable support for Bluetooth 6.0 Frame Space Update
	  in the Controller.

config BT_CTLR_CHANNEL_SOUNDING
	bool "Channel Sounding support"
	depends on BT_CTLR_CHANNEL_SOUNDING_SUPPORT
+72 −0
Original line number Diff line number Diff line
@@ -3390,6 +3390,78 @@ int bt_conn_le_read_all_remote_features(struct bt_conn *conn, uint8_t pages_requ
}
#endif /* CONFIG_BT_LE_EXTENDED_FEAT_SET */

#if defined(CONFIG_BT_FRAME_SPACE_UPDATE)
void notify_frame_space_update_complete(struct bt_conn *conn,
					struct bt_conn_le_frame_space_updated *params)
{
	if (IS_ENABLED(CONFIG_BT_CONN_DYNAMIC_CALLBACKS)) {
		struct bt_conn_cb *callback;

		SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) {
			if (callback->frame_space_updated != NULL) {
				callback->frame_space_updated(conn, params);
			}
		}
	}

	STRUCT_SECTION_FOREACH(bt_conn_cb, cb)
	{
		if (cb->frame_space_updated != NULL) {
			cb->frame_space_updated(conn, params);
		}
	}
}

static bool frame_space_update_param_valid(const struct bt_conn_le_frame_space_update_param *param)
{
	if (param->frame_space_min > BT_CONN_LE_FRAME_SPACE_MAX ||
	    param->frame_space_max > BT_CONN_LE_FRAME_SPACE_MAX ||
	    param->frame_space_min > param->frame_space_max) {
		return false;
	}

	if (param->spacing_types == 0) {
		return false;
	}

	if (param->phys == 0) {
		return false;
	}

	return true;
}

int bt_conn_le_frame_space_update(struct bt_conn *conn,
				  const struct bt_conn_le_frame_space_update_param *param)
{
	struct bt_hci_cp_le_frame_space_update *cp;
	struct net_buf *buf;

	if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) {
		LOG_DBG("Invalid connection type: %u for %p", conn->type, conn);
		return -EINVAL;
	}

	if (!frame_space_update_param_valid(param)) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_alloc(K_FOREVER);
	if (buf == NULL) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(conn->handle);
	cp->frame_space_min = sys_cpu_to_le16(param->frame_space_min);
	cp->frame_space_max = sys_cpu_to_le16(param->frame_space_max);
	cp->spacing_types = sys_cpu_to_le16(param->spacing_types);
	cp->phys = param->phys;

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_FRAME_SPACE_UPDATE, buf, NULL);
}
#endif /* CONFIG_BT_FRAME_SPACE_UPDATE */

#if defined(CONFIG_BT_CHANNEL_SOUNDING)
void notify_remote_cs_capabilities(struct bt_conn *conn, uint8_t status,
				   struct bt_conn_le_cs_capabilities *params)
Loading