mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-28 19:20:54 +00:00
att: support for delayed att read response
This commit is contained in:
parent
75130320d7
commit
e404a68886
@ -494,6 +494,10 @@ static uint16_t handle_read_by_type_request2(att_connection_t * att_connection,
|
||||
uint8_t error_code = 0;
|
||||
uint16_t first_matching_but_unreadable_handle = 0;
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
int read_request_pending = 0;
|
||||
#endif
|
||||
|
||||
while (att_iterator_has_next(&it)){
|
||||
att_iterator_fetch_next(&it);
|
||||
|
||||
@ -520,6 +524,13 @@ static uint16_t handle_read_by_type_request2(att_connection_t * att_connection,
|
||||
|
||||
att_update_value_len(&it, att_connection->con_handle);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
if (it.value_len == ATT_READ_RESPONSE_PENDING){
|
||||
read_request_pending = 1;
|
||||
}
|
||||
if (read_request_pending) continue;
|
||||
#endif
|
||||
|
||||
// check if value has same len as last one
|
||||
uint16_t this_pair_len = 2 + it.value_len;
|
||||
if (offset > 1){
|
||||
@ -549,6 +560,10 @@ static uint16_t handle_read_by_type_request2(att_connection_t * att_connection,
|
||||
offset += bytes_copied;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
if (read_request_pending) return ATT_READ_RESPONSE_PENDING;
|
||||
#endif
|
||||
|
||||
// at least one attribute could be read
|
||||
if (offset > 1){
|
||||
response_buffer[0] = ATT_READ_BY_TYPE_RESPONSE;
|
||||
@ -609,6 +624,10 @@ static uint16_t handle_read_request2(att_connection_t * att_connection, uint8_t
|
||||
|
||||
att_update_value_len(&it, att_connection->con_handle);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
if (it.value_len == ATT_READ_RESPONSE_PENDING) return ATT_READ_RESPONSE_PENDING;
|
||||
#endif
|
||||
|
||||
uint16_t offset = 1;
|
||||
// limit data
|
||||
if (offset + it.value_len > response_buffer_size) {
|
||||
@ -657,6 +676,10 @@ static uint16_t handle_read_blob_request2(att_connection_t * att_connection, uin
|
||||
|
||||
att_update_value_len(&it, att_connection->con_handle);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
if (it.value_len == ATT_READ_RESPONSE_PENDING) return ATT_READ_RESPONSE_PENDING;
|
||||
#endif
|
||||
|
||||
if (value_offset > it.value_len){
|
||||
return setup_error_invalid_offset(response_buffer, request_type, handle);
|
||||
}
|
||||
@ -698,6 +721,11 @@ static uint16_t handle_read_multiple_request2(att_connection_t * att_connection,
|
||||
int i;
|
||||
uint8_t error_code = 0;
|
||||
uint16_t handle = 0;
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
int read_request_pending = 0;
|
||||
#endif
|
||||
|
||||
for (i=0;i<num_handles;i++){
|
||||
handle = little_endian_read_16(handles, i << 1);
|
||||
|
||||
@ -725,6 +753,13 @@ static uint16_t handle_read_multiple_request2(att_connection_t * att_connection,
|
||||
}
|
||||
att_update_value_len(&it, att_connection->con_handle);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
if (it.value_len == ATT_READ_RESPONSE_PENDING) {
|
||||
read_request_pending = 1;
|
||||
}
|
||||
if (read_request_pending) continue;
|
||||
#endif
|
||||
|
||||
// limit data
|
||||
if (offset + it.value_len > response_buffer_size) {
|
||||
it.value_len = response_buffer_size - 1;
|
||||
|
@ -48,12 +48,15 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// custom BTstack error codes
|
||||
#define ATT_ERROR_HCI_DISCONNECT_RECEIVED 0x1f
|
||||
#define ATT_ERROR_HCI_DISCONNECT_RECEIVED 0x1f
|
||||
|
||||
// custom BTstack ATT error codes
|
||||
#define ATT_ERROR_DATA_MISMATCH 0x7e
|
||||
#define ATT_ERROR_TIMEOUT 0x7F
|
||||
|
||||
#define ATT_ERROR_DATA_MISMATCH 0x7e
|
||||
#define ATT_ERROR_TIMEOUT 0x7F
|
||||
|
||||
// custom BTstack ATT Response Pending
|
||||
#define ATT_READ_RESPONSE_PENDING 0xffff
|
||||
|
||||
typedef struct att_connection {
|
||||
hci_con_handle_t con_handle;
|
||||
uint16_t mtu; // initialized to ATT_DEFAULT_MTU (23), negotiated during MTU exchange
|
||||
@ -66,6 +69,7 @@ typedef struct att_connection {
|
||||
// ATT Client Read Callback for Dynamic Data
|
||||
// - if buffer == NULL, don't copy data, just return size of value
|
||||
// - if buffer != NULL, copy data and return number bytes copied
|
||||
// If ENABLE_ATT_DELAYED_READ_RESPONSE is defined, you may return ATT_READ_RESPONSE_PENDING if data isn't available yet
|
||||
// @param con_handle of hci le connection
|
||||
// @param attribute_handle to be read
|
||||
// @param offset defines start of attribute value
|
||||
@ -130,7 +134,8 @@ void att_dump_attributes(void);
|
||||
* @param att_connection used for mtu and security properties
|
||||
* @param request_buffer, request_len: ATT request from clinet
|
||||
* @param response_buffer for result
|
||||
* @returns len of data in response buffer. 0 = no response
|
||||
* @returns len of data in response buffer. 0 = no response,
|
||||
* ATT_READ_RESPONSE_PENDING if it was returned at least once for dynamic data (requires ENABLE_ATT_DELAYED_READ_RESPONSE)
|
||||
*/
|
||||
uint16_t att_handle_request(att_connection_t * att_connection,
|
||||
uint8_t * request_buffer,
|
||||
|
@ -340,6 +340,16 @@ static int att_server_process_validated_request(att_server_t * att_server){
|
||||
uint8_t * att_response_buffer = l2cap_get_outgoing_buffer();
|
||||
uint16_t att_response_size = att_handle_request(&att_server->connection, att_server->request_buffer, att_server->request_size, att_response_buffer);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
if (att_response_size == ATT_READ_RESPONSE_PENDING){
|
||||
// update state
|
||||
att_server->state = ATT_SERVER_READ_RESPONSE_PENDING;
|
||||
|
||||
// callback with handle ATT_READ_RESPONSE_PENDING
|
||||
att_server_client_read_callback(att_server->connection.con_handle, ATT_READ_RESPONSE_PENDING, 0, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// intercept "insufficient authorization" for authenticated connections to allow for user authorization
|
||||
if ((att_response_size >= 4)
|
||||
&& (att_response_buffer[0] == ATT_ERROR_RESPONSE)
|
||||
@ -374,6 +384,18 @@ static int att_server_process_validated_request(att_server_t * att_server){
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
int att_server_read_response_ready(hci_con_handle_t con_handle){
|
||||
att_server_t * att_server = att_server_for_handle(con_handle);
|
||||
if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
if (att_server->state != ATT_SERVER_READ_RESPONSE_PENDING) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
|
||||
att_server->state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
|
||||
att_dispatch_server_request_can_send_now_event(con_handle);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void att_run_for_context(att_server_t * att_server){
|
||||
switch (att_server->state){
|
||||
case ATT_SERVER_REQUEST_RECEIVED:
|
||||
@ -829,7 +851,6 @@ void att_server_register_can_send_now_callback(btstack_context_callback_registra
|
||||
att_dispatch_server_request_can_send_now_event(con_handle);
|
||||
}
|
||||
|
||||
|
||||
int att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len){
|
||||
att_server_t * att_server = att_server_for_handle(con_handle);
|
||||
if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
|
@ -112,6 +112,16 @@ int att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, ui
|
||||
*/
|
||||
int att_server_indicate(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
/*
|
||||
* @brief read response ready - called after returning ATT_READ_RESPONSE_PENDING in an att_read_callback before
|
||||
* @nore The ATT Server will retry handling the current ATT request
|
||||
* @param con_handle
|
||||
* @return 0 if ok, error otherwise
|
||||
*/
|
||||
int att_server_read_response_ready(hci_con_handle_t con_handle);
|
||||
#endif
|
||||
|
||||
/* API_END */
|
||||
|
||||
#if defined __cplusplus
|
||||
|
Loading…
x
Reference in New Issue
Block a user