att_server: allow individual service implementations to register for can send now callbacks

This commit is contained in:
Matthias Ringwald 2016-11-01 15:42:03 +01:00
parent 8ac574d6fa
commit bb38f05734
3 changed files with 45 additions and 2 deletions

View File

@ -95,6 +95,8 @@ static btstack_packet_callback_registration_t hci_event_callback_registration;
static btstack_packet_callback_registration_t sm_event_callback_registration;
static btstack_packet_handler_t att_client_packet_handler = NULL;
static btstack_linked_list_t can_send_now_clients;
static void att_handle_value_indication_notify_client(uint8_t status, uint16_t client_handle, uint16_t attribute_handle){
if (!att_client_packet_handler) return;
@ -345,12 +347,27 @@ static void att_server_handle_can_send_now(void){
if (att_server_state == ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED){
int sent = att_server_process_validated_request(att_connection.con_handle);
if (sent && att_client_waiting_for_can_send){
if (sent && (att_client_waiting_for_can_send || !btstack_linked_list_empty(&can_send_now_clients))){
att_dispatch_server_request_can_send_now_event(att_connection.con_handle);
return;
}
}
while (!btstack_linked_list_empty(&can_send_now_clients)){
// handle first client
btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) can_send_now_clients;
btstack_linked_list_remove(&can_send_now_clients, (btstack_linked_item_t *) client);
client->callback(client->context);
// request again if needed
if (!att_dispatch_server_can_send_now(att_connection.con_handle)){
if (!btstack_linked_list_empty(&can_send_now_clients) || att_client_waiting_for_can_send){
att_dispatch_server_request_can_send_now_event(att_connection.con_handle);
}
return;
}
}
if (att_client_waiting_for_can_send){
att_client_waiting_for_can_send = 0;
att_emit_can_send_now_event();
@ -441,6 +458,16 @@ void att_server_request_can_send_now_event(hci_con_handle_t con_handle){
att_dispatch_server_request_can_send_now_event(att_connection.con_handle);
}
void att_server_register_can_send_now_callback(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
// check if can send already
if (att_dispatch_server_can_send_now(con_handle)){
callback_registration->callback(callback_registration->context);
return;
}
btstack_linked_list_add_tail(&can_send_now_clients, (btstack_linked_item_t*) callback_registration);
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){
if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL;

View File

@ -56,8 +56,9 @@ void att_server_init(uint8_t const * db, att_read_callback_t read_callback, att_
/*
* @brief register packet handler for ATT server events:
* - ATT_EVENT_MTU_EXCHANGE_COMPLETE
* - ATT_EVENT_CAN_SEND_NOW
* - ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE
* - ATT_EVENT_MTU_EXCHANGE_COMPLETE
* @param handler
*/
void att_server_register_packet_handler(btstack_packet_handler_t handler);
@ -77,6 +78,14 @@ 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
* @param con_handle
*/
void att_server_register_can_send_now_callback(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

@ -61,6 +61,13 @@ typedef struct {
btstack_packet_handler_t callback;
} btstack_packet_callback_registration_t;
// context callback supporting multiple registrations
typedef struct {
btstack_linked_item_t * item;
void (*callback)(void * context);
void * context;
} btstack_context_callback_registration_t;
/**
* @brief 128 bit key used with AES128 in Security Manager
*/