OSDN Git Service

Rejig hci upwards dispatch
authorZach Johnson <zachoverflow@google.com>
Wed, 4 Mar 2015 22:47:00 +0000 (14:47 -0800)
committerAndre Eisenbach <eisenbach@google.com>
Mon, 16 Mar 2015 23:51:48 +0000 (16:51 -0700)
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
hci/src/hci_layer.c
main/bte_main.c

index 810e0b8..bdc4681 100644 (file)
@@ -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)(
index fcf77d8..30e69a9 100644 (file)
@@ -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;
index f6d1bdf..be8b2bf 100755 (executable)
@@ -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;