att_server: add att_server_request_to_send_notification and att_server_request_to_send_indication

This commit is contained in:
Matthias Ringwald 2018-05-17 15:53:39 +02:00
parent 969a5bba93
commit cbbb12d994
4 changed files with 75 additions and 14 deletions

View File

@ -10,8 +10,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- GAP: re-encrypt outgoing connection if bonded
- ATT Server: wait until re-encryption is complete
- GATT Client: wait until re-encryption is complete
- ATT Server: added att_server_request_to_send_notification and att_server_request_to_send_indication
### Changed
- ATT Server: att_server_register_can_send_now_callback is deprecated, use att_server_request_to_send_notification/indication instead
### Fixed
- SM: Fix LE Secure Connection pairing in Central role

View File

@ -504,14 +504,33 @@ static void att_server_handle_can_send_now(void){
hci_connection_t * connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it);
att_server_t * att_server = &connection->att_server;
if (!btstack_linked_list_empty(&att_server->can_send_now_clients)){
// handle indications first
if (!btstack_linked_list_empty(&att_server->indication_requests) && att_server->value_indication_handle == 0){
if (can_send_now){
btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) att_server->can_send_now_clients;
btstack_linked_list_remove(&att_server->can_send_now_clients, (btstack_linked_item_t *) client);
btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) att_server->indication_requests;
btstack_linked_list_remove(&att_server->indication_requests, (btstack_linked_item_t *) client);
client->callback(client->context);
can_send_now = att_dispatch_server_can_send_now(att_server->connection.con_handle);
// track if there's more to send, but keep iterating - only true if callee didn't send indication
if (request_con_handle == HCI_CON_HANDLE_INVALID && att_server->value_indication_handle == 0 && !btstack_linked_list_empty(&att_server->indication_requests)){
request_con_handle = att_server->connection.con_handle;
}
} else {
// can_send_now == 0
att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
return;
}
}
// then notifications
if (!btstack_linked_list_empty(&att_server->notification_requests)){
if (can_send_now){
btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) att_server->notification_requests;
btstack_linked_list_remove(&att_server->notification_requests, (btstack_linked_item_t *) client);
client->callback(client->context);
can_send_now = att_dispatch_server_can_send_now(att_server->connection.con_handle);
// track if there's more to send, but keep iterating
if (request_con_handle == HCI_CON_HANDLE_INVALID && !btstack_linked_list_empty(&att_server->can_send_now_clients)){
if (request_con_handle == HCI_CON_HANDLE_INVALID && !btstack_linked_list_empty(&att_server->notification_requests)){
request_con_handle = att_server->connection.con_handle;
}
} else {
@ -570,6 +589,7 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa
uint16_t att_handle = att_server->value_indication_handle;
att_server->value_indication_handle = 0;
att_handle_value_indication_notify_client(0, att_server->connection.con_handle, att_handle);
att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
return;
}
@ -873,20 +893,34 @@ void att_server_register_packet_handler(btstack_packet_handler_t handler){
att_client_packet_handler = handler;
}
int att_server_can_send_packet_now(hci_con_handle_t con_handle){
return att_dispatch_server_can_send_now(con_handle);
}
void att_server_request_can_send_now_event(hci_con_handle_t con_handle){
log_debug("att_server_request_can_send_now_event 0x%04x", con_handle);
att_client_waiting_for_can_send_registration.callback = &att_emit_can_send_now_event;
att_server_register_can_send_now_callback(&att_client_waiting_for_can_send_registration, con_handle);
// to be deprecated
int att_server_can_send_packet_now(hci_con_handle_t con_handle){
return att_dispatch_server_can_send_now(con_handle);
}
int att_server_register_can_send_now_callback(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
return att_server_request_to_send_notification(callback_registration, con_handle);
}
void att_server_request_can_send_now_event(hci_con_handle_t con_handle){
att_client_waiting_for_can_send_registration.callback = &att_emit_can_send_now_event;
att_server_request_to_send_notification(&att_client_waiting_for_can_send_registration, con_handle);
}
// end of deprecated
int att_server_request_to_send_notification(btstack_context_callback_registration_t * callback_registration, 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;
btstack_linked_list_add_tail(&att_server->can_send_now_clients, (btstack_linked_item_t*) callback_registration);
btstack_linked_list_add_tail(&att_server->notification_requests, (btstack_linked_item_t*) callback_registration);
att_dispatch_server_request_can_send_now_event(con_handle);
return ERROR_CODE_SUCCESS;
}
int att_server_request_to_send_indication(btstack_context_callback_registration_t * callback_registration, 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;
btstack_linked_list_add_tail(&att_server->indication_requests, (btstack_linked_item_t*) callback_registration);
att_dispatch_server_request_can_send_now_event(con_handle);
return ERROR_CODE_SUCCESS;
}

View File

@ -69,6 +69,8 @@ void att_server_register_packet_handler(btstack_packet_handler_t handler);
*/
void att_server_register_service_handler(att_service_handler_t * handler);
// the following functions will be removed soon
/*
* @brief tests if a notification or indication can be send right now
* @param con_handle
@ -76,7 +78,7 @@ void att_server_register_service_handler(att_service_handler_t * handler);
*/
int att_server_can_send_packet_now(hci_con_handle_t con_handle);
/**
/**
* @brief Request emission of ATT_EVENT_CAN_SEND_NOW as soon as possible
* @note ATT_EVENT_CAN_SEND_NOW might be emitted during call to this function
* so packet handler should be ready to handle it
@ -84,7 +86,7 @@ int att_server_can_send_packet_now(hci_con_handle_t con_handle);
*/
void att_server_request_can_send_now_event(hci_con_handle_t con_handle);
/**
/**
* @brief Request callback when sending is possible
* @note callback might happend during call to this function
* @param callback_registration to point to callback function and context information
@ -93,6 +95,26 @@ void att_server_request_can_send_now_event(hci_con_handle_t con_handle);
*/
int att_server_register_can_send_now_callback(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle);
// end of deprecated functions
/**
* @brief Request callback when sending notifcation is possible
* @note callback might happend during call to this function
* @param callback_registration to point to callback function and context information
* @param con_handle
* @return 0 if ok, error otherwise
*/
int att_server_request_to_send_notification(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle);
/**
* @brief Request callback when sending indication is possible
* @note callback might happend during call to this function
* @param callback_registration to point to callback function and context information
* @param con_handle
* @return 0 if ok, error otherwise
*/
int att_server_request_to_send_indication(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle);
/*
* @brief notify client about attribute value change
* @param con_handle

View File

@ -413,6 +413,9 @@ typedef struct {
att_connection_t connection;
btstack_linked_list_t notification_requests;
btstack_linked_list_t indication_requests;
uint16_t request_size;
uint8_t request_buffer[ATT_REQUEST_BUFFER_SIZE];