-
Notifications
You must be signed in to change notification settings - Fork 8.1k
att: Support deferred Read and Write Response handling. #97594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -156,6 +156,11 @@ struct bt_gatt_attr; | |||
* @note The GATT server propagates the return value from this | ||||
* method back to the remote client. | ||||
* | ||||
* @note If this function returns ``-EINPROGRESS``, the read operation | ||||
* is deferred and the application must later send the response | ||||
* using @ref bt_gatt_send_read_response(). Deferred responses | ||||
* are only supported when Enhanced ATT (EATT) is not active. | ||||
* | ||||
Comment on lines
+159
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This API allows any attribute type to defer reads. The Host uses the read function locally in places and is not compatible with deferred reads, e.g. here: zephyr/subsys/bluetooth/host/gatt.c Line 3549 in 3973aaa
Either the API has to prevent this, or better yet: The local reads in Host are updated respecting the API change. Now in prototype stage, we can fix it in the API. But I would like local reads to work eventually, so we need to give it some though now to be forwards compatible. I'll give my thoughts below: I think we should have a new API to do local reads. The requests can appear to originate from a pseudo-connection. A local reader might need to allocate a pseudo connection themselves. The ATT database should not give out pointers to Any thoughts?
Comment on lines
+159
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's worth explicitly saying that the lifetime of
Comment on lines
+159
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to discuses how this API can be extended (it the future?) to support EATT and local reads. If we decide to handle ATT requests over multiple bearers (EATT) on a single connection serially (one at a time), then there is no problem, since the connection is enough to identify the associated request. On the other hand, if we can pipeline requests to the application, then we have to allow the application to reply in any order. In this case, we need something to identify the request in
Comment on lines
+159
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should have a note informing the developer that the application needs to be able to accept one concurrent request for every connection (or risk blocking Bluetooth after all). If we add local reads through pseudo-connections, then those count as well. If we pipeline EATT, then it grows to one request per ATT Bearer in the system. |
||||
* @param conn The connection that is requesting to read. | ||||
* NULL if local. | ||||
* @param attr The attribute that's being read | ||||
|
@@ -199,6 +204,11 @@ typedef ssize_t (*bt_gatt_attr_read_func_t)(struct bt_conn *conn, | |||
* @note The GATT server propagates the return value from this | ||||
* method back to the remote client. | ||||
* | ||||
* @note If this function returns ``-EINPROGRESS``, the write operation | ||||
* is deferred and the application must later send the response | ||||
* using @ref bt_gatt_send_write_response(). Deferred responses | ||||
* are only supported when Enhanced ATT (EATT) is not active. | ||||
* | ||||
* @param conn The connection that is requesting to write | ||||
* @param attr The attribute that's being written | ||||
* @param buf Buffer with the data to write | ||||
|
@@ -2024,6 +2034,25 @@ struct bt_gatt_read_params { | |||
*/ | ||||
int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params); | ||||
|
||||
/** @brief Send a deferred Read Response | ||||
* | ||||
* Used when an attribute read was deferred (attr->read returned | ||||
* -EINPROGRESS). The application later provides the | ||||
* response value via this API. | ||||
* | ||||
* @param conn Connection object. | ||||
* @param data Pointer to the attribute value buffer. | ||||
* @param length Length of the attribute value. | ||||
* | ||||
* @retval 0 Successfully queued response. | ||||
* | ||||
* @retval -ENOTCONN The connection is not established. | ||||
* @retval -EINVAL Invalid parameters. | ||||
* @retval -ENOMEM Out of memory. | ||||
* @retval -ENOTSUP EATT active and deferred responses not supported. | ||||
*/ | ||||
int bt_gatt_send_read_response(struct bt_conn *conn, const void *data, uint16_t length); | ||||
|
||||
struct bt_gatt_write_params; | ||||
|
||||
/** @typedef bt_gatt_write_func_t | ||||
|
@@ -2073,6 +2102,24 @@ struct bt_gatt_write_params { | |||
*/ | ||||
int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params); | ||||
|
||||
/** | ||||
* @brief Send a deferred Write Response | ||||
* | ||||
* Used when an attribute write was deferred (attr->write returned | ||||
* -EINPROGRESS). The application later | ||||
* responds using this API once the write has been processed. | ||||
* | ||||
* @param conn Connection object. | ||||
* | ||||
* @retval 0 Successfully queued response. | ||||
* | ||||
* @retval -ENOTCONN The connection is not established. | ||||
* @retval -EINVAL Invalid parameters. | ||||
* @retval -ENOMEM Out of memory. | ||||
* @retval -ENOTSUP EATT active and deferred responses not supported. | ||||
*/ | ||||
int bt_gatt_send_write_response(struct bt_conn *conn); | ||||
|
||||
/** @brief Write Attribute Value by handle without response with callback. | ||||
* | ||||
* This function works in the same way as @ref bt_gatt_write_without_response. | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should clarify how the user should determine whether EATT is active. I think the user has to check
IS_ENABLED(CONFIG_BT_EATT)
. Any other suggestions?