From b55a8a62b23be97fcb3f2ba9f3c4cb03cfb59914 Mon Sep 17 00:00:00 2001 From: Zach Johnson Date: Wed, 4 Mar 2015 14:47:00 -0800 Subject: [PATCH] Rejig hci upwards dispatch Split events and acl data in hci dispatch, and dispatch events by event code Future code will now be able to dynamically tie into hci events, instead of relying on a hard coded routing. --- hci/include/hci_layer.h | 8 ++++++-- hci/src/hci_layer.c | 50 ++++++++++++++++++++++++++++++++++++++----------- main/bte_main.c | 6 ++++-- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/hci/include/hci_layer.h b/hci/include/hci_layer.h index 810e0b8a7..bdc468146 100644 --- a/hci/include/hci_layer.h +++ b/hci/include/hci_layer.h @@ -23,6 +23,7 @@ #include "allocator.h" #include "bt_types.h" #include "data_dispatcher.h" +#include "fixed_queue.h" #include "future.h" #include "osi.h" @@ -79,8 +80,11 @@ typedef struct hci_t { // Do the postload sequence (call after the rest of the BT stack initializes). void (*do_postload)(void); - // Register with this data dispatcher to receive data flowing upward out of the HCI layer - data_dispatcher_t *upward_dispatcher; + // Register with this data dispatcher to receive events flowing upward out of the HCI layer + data_dispatcher_t *event_dispatcher; + + // Set the queue to receive ACL data in + void (*set_data_queue)(fixed_queue_t *queue); // Send a command through the HCI layer void (*transmit_command)( diff --git a/hci/src/hci_layer.c b/hci/src/hci_layer.c index fcf77d849..30e69a9d9 100644 --- a/hci/src/hci_layer.c +++ b/hci/src/hci_layer.c @@ -132,6 +132,9 @@ static list_t *commands_pending_response; static pthread_mutex_t commands_pending_response_lock; static packet_receive_data_t incoming_packets[INBOUND_PACKET_TYPE_COUNT]; +// The hand-off point for data going to a higher layer, set by the higher layer +static fixed_queue_t *upwards_data_queue; + static future_t *shut_down(); static void event_finish_startup(void *context); @@ -329,6 +332,10 @@ static void do_postload() { thread_post(thread, event_postload, NULL); } +static void set_data_queue(fixed_queue_t *queue) { + upwards_data_queue = queue; +} + static void transmit_command( BT_HDR *command, command_complete_cb complete_callback, @@ -481,10 +488,14 @@ static void transmit_fragment(BT_HDR *packet, bool send_transmit_finished) { } static void fragmenter_transmit_finished(BT_HDR *packet, bool all_fragments_sent) { - if (all_fragments_sent) + if (all_fragments_sent) { buffer_allocator->free(packet); - else - data_dispatcher_dispatch(interface.upward_dispatcher, packet->event & MSG_EVT_MASK, packet); + } else { + // This is kind of a weird case, since we're dispatching a partially sent packet + // up to a higher layer. + // TODO(zachoverflow): rework upper layer so this isn't necessary. + data_dispatcher_dispatch(interface.event_dispatcher, packet->event & MSG_EVT_MASK, packet); + } } static void command_timed_out(UNUSED_ATTR void *context) { @@ -584,8 +595,19 @@ static void hal_says_data_ready(serial_data_type_t type) { incoming->buffer->len = incoming->index; btsnoop->capture(incoming->buffer, true); - if (type != DATA_TYPE_EVENT || !filter_incoming_event(incoming->buffer)) { + if (type != DATA_TYPE_EVENT) { packet_fragmenter->reassemble_and_dispatch(incoming->buffer); + } else if (!filter_incoming_event(incoming->buffer)) { + // Dispatch the event by event code + uint8_t *stream = incoming->buffer->data; + uint8_t event_code; + STREAM_TO_UINT8(event_code, stream); + + data_dispatcher_dispatch( + interface.event_dispatcher, + event_code, + incoming->buffer + ); } // We don't control the buffer anymore @@ -666,11 +688,16 @@ intercepted:; // Callback for the fragmenter to dispatch up a completely reassembled packet static void dispatch_reassembled(BT_HDR *packet) { - data_dispatcher_dispatch( - interface.upward_dispatcher, - packet->event & MSG_EVT_MASK, - packet - ); + // Events should already have been dispatched before this point + assert((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT); + assert(upwards_data_queue != NULL); + + if (upwards_data_queue) { + fixed_queue_enqueue(upwards_data_queue, packet); + } else { + LOG_ERROR("%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__); + buffer_allocator->free(packet); + } } // Misc internal functions @@ -717,12 +744,13 @@ static void init_layer_interface() { // It's probably ok for this to live forever. It's small and // there's only one instance of the hci interface. - interface.upward_dispatcher = data_dispatcher_new("hci_layer"); - if (!interface.upward_dispatcher) { + interface.event_dispatcher = data_dispatcher_new("hci_layer"); + if (!interface.event_dispatcher) { LOG_ERROR("%s could not create upward dispatcher.", __func__); return; } + interface.set_data_queue = set_data_queue; interface.transmit_command = transmit_command; interface.transmit_command_futured = transmit_command_futured; interface.transmit_downward = transmit_downward; diff --git a/main/bte_main.c b/main/bte_main.c index f6d1bdfd8..be8b2bfde 100755 --- a/main/bte_main.c +++ b/main/bte_main.c @@ -108,7 +108,8 @@ void bte_main_boot_entry(void) return; } - data_dispatcher_register_default(hci->upward_dispatcher, btu_hci_msg_queue); + data_dispatcher_register_default(hci->event_dispatcher, btu_hci_msg_queue); + hci->set_data_queue(btu_hci_msg_queue); #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE); @@ -127,7 +128,8 @@ void bte_main_boot_entry(void) ******************************************************************************/ void bte_main_shutdown() { - data_dispatcher_register_default(hci_layer_get_interface()->upward_dispatcher, NULL); + data_dispatcher_register_default(hci_layer_get_interface()->event_dispatcher, NULL); + hci->set_data_queue(NULL); fixed_queue_free(btu_hci_msg_queue, NULL); btu_hci_msg_queue = NULL; -- 2.11.0