diff options
author | Zach Johnson <zachoverflow@google.com> | 2014-09-23 18:30:45 -0700 |
---|---|---|
committer | Andre Eisenbach <eisenbach@google.com> | 2015-03-16 16:51:35 -0700 |
commit | 093948aaec3d88f3e52cae28b286d694f2645f82 (patch) | |
tree | 91c382274688fd0450757123069fffab6e146c6d /hci | |
parent | b1f991590b530715bb6fb4c44695af1e87e167f6 (diff) | |
download | android_system_bt-093948aaec3d88f3e52cae28b286d694f2645f82.tar.gz android_system_bt-093948aaec3d88f3e52cae28b286d694f2645f82.tar.bz2 android_system_bt-093948aaec3d88f3e52cae28b286d694f2645f82.zip |
Modulizification of the HCI layer
Shutdown is managed by the stack manager now, so we don't need to lock
around it. The fetching of the device address is a bit hacky right now,
until it becomes part of its own module.
Diffstat (limited to 'hci')
-rw-r--r-- | hci/Android.mk | 2 | ||||
-rw-r--r-- | hci/include/hci_layer.h | 22 | ||||
-rw-r--r-- | hci/include/packet_fragmenter.h | 1 | ||||
-rw-r--r-- | hci/src/hci_layer.c | 72 | ||||
-rw-r--r-- | hci/test/hci_layer_test.cpp | 41 | ||||
-rw-r--r-- | hci/test/packet_fragmenter_test.cpp | 2 |
6 files changed, 56 insertions, 84 deletions
diff --git a/hci/Android.mk b/hci/Android.mk index 048652c46..b1d04b68f 100644 --- a/hci/Android.mk +++ b/hci/Android.mk @@ -74,6 +74,6 @@ LOCAL_CFLAGS := -Wall -Werror $(bdroid_CFLAGS) LOCAL_MODULE := libbt-hcitests LOCAL_MODULE_TAGS := tests LOCAL_SHARED_LIBRARIES := liblog libdl -LOCAL_STATIC_LIBRARIES := libbt-hci libosi libcutils +LOCAL_STATIC_LIBRARIES := libbt-hci libosi libcutils libbtcore include $(BUILD_NATIVE_TEST) diff --git a/hci/include/hci_layer.h b/hci/include/hci_layer.h index ba674ba6c..957e5003f 100644 --- a/hci/include/hci_layer.h +++ b/hci/include/hci_layer.h @@ -66,31 +66,10 @@ typedef enum { LPM_WAKE_DEASSERT } low_power_command_t; -typedef void (*startup_finished_cb)(bool success); -typedef void (*transmit_finished_cb)(void *buffer, bool all_fragments_sent); typedef void (*command_complete_cb)(BT_HDR *response, void *context); typedef void (*command_status_cb)(uint8_t status, BT_HDR *command, void *context); -typedef struct { - // Called when the HCI layer finishes the preload sequence. - startup_finished_cb startup_finished; - - // Called when the HCI layer finishes sending a packet. - transmit_finished_cb transmit_finished; -} hci_callbacks_t; - typedef struct hci_t { - // Start up the HCI layer, with the specified |local_bdaddr|. - // |upper_callbacks->startup_finished| will be called when the full - // start up sequence is complete. - bool (*start_up_async)( - bdaddr_t local_bdaddr, - const hci_callbacks_t *upper_callbacks - ); - - // Tear down and relese all resources - void (*shut_down)(void); - // Send a low power command, if supported and the low power manager is enabled. void (*send_low_power_command)(low_power_command_t command); @@ -112,6 +91,7 @@ typedef struct hci_t { void (*transmit_downward)(data_dispatcher_type_t type, void *data); } hci_t; +#define HCI_MODULE "hci_module" const hci_t *hci_layer_get_interface(); const hci_t *hci_layer_get_test_interface( diff --git a/hci/include/packet_fragmenter.h b/hci/include/packet_fragmenter.h index 93dc97ef9..c7f643e21 100644 --- a/hci/include/packet_fragmenter.h +++ b/hci/include/packet_fragmenter.h @@ -22,6 +22,7 @@ #include "bt_types.h" #include "hci_layer.h" +typedef void (*transmit_finished_cb)(BT_HDR *packet, bool all_fragments_sent); typedef void (*packet_reassembled_cb)(BT_HDR *packet); typedef void (*packet_fragmented_cb)(BT_HDR *packet, bool send_transmit_finished); diff --git a/hci/src/hci_layer.c b/hci/src/hci_layer.c index 07c6484a3..6b4c2b7d7 100644 --- a/hci/src/hci_layer.c +++ b/hci/src/hci_layer.c @@ -33,12 +33,17 @@ #include "hci_layer.h" #include "list.h" #include "low_power_manager.h" +#include "module.h" #include "non_repeating_timer.h" #include "osi.h" #include "packet_fragmenter.h" #include "reactor.h" #include "vendor.h" +// TODO(zachoverflow): remove this hack extern +#include <hardware/bluetooth.h> +bt_bdaddr_t btif_local_bd_addr; + #define HCI_COMMAND_COMPLETE_EVT 0x0E #define HCI_COMMAND_STATUS_EVT 0x0F @@ -103,7 +108,6 @@ static hci_t interface; static const allocator_t *buffer_allocator; static const btsnoop_t *btsnoop; static const controller_t *controller; -static const hci_callbacks_t *callbacks; static const hci_hal_t *hal; static const hci_hal_callbacks_t hal_callbacks; static const hci_inject_t *hci_inject; @@ -112,10 +116,10 @@ static const packet_fragmenter_t *packet_fragmenter; static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks; static const vendor_t *vendor; +static future_t *startup_future; static thread_t *thread; // We own this static volatile bool firmware_is_configured = false; -static volatile bool has_shut_down = false; static non_repeating_timer_t *epilog_timer; static non_repeating_timer_t *startup_timer; @@ -130,6 +134,8 @@ 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]; +static future_t *shut_down(); + static void event_finish_startup(void *context); static void firmware_config_callback(bool success); static void startup_timer_expired(void *context); @@ -151,12 +157,9 @@ static bool filter_incoming_event(BT_HDR *packet); static serial_data_type_t event_to_data_type(uint16_t event); static waiting_command_t *get_waiting_command(command_opcode_t opcode); -// Interface functions - -static bool start_up_async(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_callbacks) { - assert(local_bdaddr != NULL); - assert(upper_callbacks != NULL); +// Module lifecycle functions +static future_t *start_up(void) { ALOGI("%s", __func__); // The host is only allowed to send at most one command initially, @@ -164,7 +167,6 @@ static bool start_up_async(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_c // This value can change when you get a command complete or command status event. command_credits = 1; firmware_is_configured = false; - has_shut_down = false; pthread_mutex_init(&commands_pending_response_lock, NULL); @@ -220,7 +222,6 @@ static bool start_up_async(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_c goto error; } - callbacks = upper_callbacks; memset(incoming_packets, 0, sizeof(incoming_packets)); controller->init(&interface); @@ -229,7 +230,7 @@ static bool start_up_async(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_c fixed_queue_register_dequeue(command_queue, thread_get_reactor(thread), event_command_ready, NULL); fixed_queue_register_dequeue(packet_queue, thread_get_reactor(thread), event_packet_ready, NULL); - vendor->open(local_bdaddr, &interface); + vendor->open(btif_local_bd_addr.address, &interface); hal->init(&hal_callbacks, thread); low_power_manager->init(thread); @@ -257,21 +258,16 @@ static bool start_up_async(bdaddr_t local_bdaddr, const hci_callbacks_t *upper_c power_state = BT_VND_PWR_ON; vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state); + startup_future = future_new(); ALOGD("%s starting async portion", __func__); thread_post(thread, event_finish_startup, NULL); - - return true; + return startup_future; error:; - interface.shut_down(); - return false; + shut_down(); // returns NULL so no need to wait for it + return future_new_immediate(FUTURE_FAIL); } -static void shut_down() { - if (has_shut_down) { - ALOGW("%s already happened for this session", __func__); - return; - } - +static future_t *shut_down() { ALOGI("%s", __func__); hci_inject->close(); @@ -313,9 +309,24 @@ static void shut_down() { thread_free(thread); thread = NULL; firmware_is_configured = false; - has_shut_down = true; + + return NULL; } +const module_t hci_module = { + .name = HCI_MODULE, + .init = NULL, + .start_up = start_up, + .shut_down = shut_down, + .clean_up = NULL, + .dependencies = { + BTSNOOP_MODULE, + NULL + } +}; + +// Interface functions + static void do_postload() { ALOGD("%s posting postload work item", __func__); thread_post(thread, event_postload, NULL); @@ -367,11 +378,14 @@ static void event_finish_startup(UNUSED_ATTR void *context) { static void firmware_config_callback(UNUSED_ATTR bool success) { firmware_is_configured = true; non_repeating_timer_cancel(startup_timer); - callbacks->startup_finished(true); + + future_ready(startup_future, FUTURE_SUCCESS); + startup_future = NULL; } static void startup_timer_expired(UNUSED_ATTR void *context) { - callbacks->startup_finished(false); + future_ready(startup_future, FUTURE_FAIL); + startup_future = NULL; } // Postload functions @@ -448,11 +462,14 @@ static void transmit_fragment(BT_HDR *packet, bool send_transmit_finished) { hal->transmit_data(type, packet->data + packet->offset, packet->len); if (event != MSG_STACK_TO_HC_HCI_CMD && send_transmit_finished) - callbacks->transmit_finished(packet, true); + buffer_allocator->free(packet); } -static void fragmenter_transmit_finished(void *buffer, bool all_fragments_sent) { - callbacks->transmit_finished(buffer, all_fragments_sent); +static void fragmenter_transmit_finished(BT_HDR *packet, bool all_fragments_sent) { + if (all_fragments_sent) + buffer_allocator->free(packet); + else + data_dispatcher_dispatch(interface.upward_dispatcher, packet->event & MSG_EVT_MASK, packet); } static void command_timed_out(UNUSED_ATTR void *context) { @@ -670,9 +687,6 @@ static waiting_command_t *get_waiting_command(command_opcode_t opcode) { static void init_layer_interface() { if (!interface_created) { - interface.start_up_async = start_up_async; - interface.shut_down = shut_down; - interface.send_low_power_command = low_power_manager->post_command; interface.do_postload = do_postload; diff --git a/hci/test/hci_layer_test.cpp b/hci/test/hci_layer_test.cpp index d040138d2..40d3587b0 100644 --- a/hci/test/hci_layer_test.cpp +++ b/hci/test/hci_layer_test.cpp @@ -33,11 +33,14 @@ extern "C" { #include "hci_inject.h" #include "hci_layer.h" #include "low_power_manager.h" +#include "module.h" #include "osi.h" #include "packet_fragmenter.h" #include "semaphore.h" #include "test_stubs.h" #include "vendor.h" + +extern const module_t hci_module; } DECLARE_TEST_MODES( @@ -343,9 +346,9 @@ STUB_FUNCTION(void, low_power_transmit_done, ()) UNEXPECTED_CALL; } -STUB_FUNCTION(bool, vendor_open, (const uint8_t *addr, const hci_t *hci_interface)) +STUB_FUNCTION(bool, vendor_open, (UNUSED_ATTR const uint8_t *addr, const hci_t *hci_interface)) DURING(start_up_async) AT_CALL(0) { - EXPECT_EQ(test_addr, addr); + //EXPECT_EQ(test_addr, addr); // TODO(zachoverflow): reinstate when address put into module EXPECT_EQ(hci, hci_interface); return true; } @@ -428,26 +431,6 @@ STUB_FUNCTION(int, vendor_send_async_command, (UNUSED_ATTR vendor_async_opcode_t return 0; } -STUB_FUNCTION(void, callback_startup_finished, (bool success)) - DURING(start_up_async) AT_CALL(0) { - EXPECT_EQ(true, success); - semaphore_post(done); - return; - } - - UNEXPECTED_CALL; -} - -STUB_FUNCTION(void, callback_transmit_finished, (UNUSED_ATTR void *buffer, bool all_fragments_sent)) - DURING(transmit_simple) AT_CALL(0) { - EXPECT_TRUE(all_fragments_sent); - osi_free(buffer); - return; - } - - UNEXPECTED_CALL; -} - STUB_FUNCTION(void, command_complete_callback, (BT_HDR *response, UNUSED_ATTR void *context)) DURING(transmit_command_command_complete) AT_CALL(0) { osi_free(response); @@ -511,8 +494,6 @@ static void reset_for(TEST_MODES_T next) { RESET_CALL_COUNT(low_power_cleanup); RESET_CALL_COUNT(low_power_wake_assert); RESET_CALL_COUNT(low_power_transmit_done); - RESET_CALL_COUNT(callback_startup_finished); - RESET_CALL_COUNT(callback_transmit_finished); RESET_CALL_COUNT(command_complete_callback); RESET_CALL_COUNT(command_status_callback); RESET_CALL_COUNT(controller_init); @@ -540,6 +521,7 @@ class HciLayerTest : public AlarmTestHarness { // Make sure the data dispatcher allocation isn't tracked allocation_tracker_reset(); + module_management_start(); packet_index = 0; data_size_sum = 0; @@ -562,8 +544,6 @@ class HciLayerTest : public AlarmTestHarness { low_power_manager.cleanup = low_power_cleanup; low_power_manager.wake_assert = low_power_wake_assert; low_power_manager.transmit_done = low_power_transmit_done; - callbacks.startup_finished = callback_startup_finished; - callbacks.transmit_finished = callback_transmit_finished; controller.init = controller_init; controller.begin_acl_size_fetch = controller_begin_acl_size_fetch; controller.get_acl_size_classic = controller_get_acl_size_classic; @@ -572,8 +552,7 @@ class HciLayerTest : public AlarmTestHarness { done = semaphore_new(0); reset_for(start_up_async); - hci->start_up_async(test_addr, &callbacks); - semaphore_wait(done); + EXPECT_TRUE(module_start_up(&hci_module)); EXPECT_CALL_COUNT(vendor_open, 1); EXPECT_CALL_COUNT(hal_init, 1); @@ -582,12 +561,11 @@ class HciLayerTest : public AlarmTestHarness { EXPECT_CALL_COUNT(controller_init, 1); EXPECT_CALL_COUNT(hal_open, 1); EXPECT_CALL_COUNT(vendor_send_async_command, 1); - EXPECT_CALL_COUNT(callback_startup_finished, 1); } virtual void TearDown() { reset_for(shut_down); - hci->shut_down(); + module_shut_down(&hci_module); EXPECT_CALL_COUNT(low_power_cleanup, 1); EXPECT_CALL_COUNT(hal_close, 1); @@ -595,6 +573,7 @@ class HciLayerTest : public AlarmTestHarness { EXPECT_CALL_COUNT(vendor_close, 1); semaphore_free(done); + module_management_stop(); AlarmTestHarness::TearDown(); } @@ -604,7 +583,6 @@ class HciLayerTest : public AlarmTestHarness { hci_inject_t hci_inject; vendor_t vendor; low_power_manager_t low_power_manager; - hci_callbacks_t callbacks; }; TEST_F(HciLayerTest, test_postload) { @@ -626,7 +604,6 @@ TEST_F(HciLayerTest, test_transmit_simple) { EXPECT_CALL_COUNT(btsnoop_capture, 1); EXPECT_CALL_COUNT(low_power_transmit_done, 1); EXPECT_CALL_COUNT(low_power_wake_assert, 1); - EXPECT_CALL_COUNT(callback_transmit_finished, 1); } TEST_F(HciLayerTest, test_receive_simple) { diff --git a/hci/test/packet_fragmenter_test.cpp b/hci/test/packet_fragmenter_test.cpp index 2221fc18a..929973cc1 100644 --- a/hci/test/packet_fragmenter_test.cpp +++ b/hci/test/packet_fragmenter_test.cpp @@ -247,7 +247,7 @@ STUB_FUNCTION(void, reassembled_callback, (BT_HDR *packet)) UNEXPECTED_CALL; } -STUB_FUNCTION(void, transmit_finished_callback, (UNUSED_ATTR void *packet, UNUSED_ATTR bool sent_all_fragments)) +STUB_FUNCTION(void, transmit_finished_callback, (UNUSED_ATTR BT_HDR *packet, UNUSED_ATTR bool sent_all_fragments)) UNEXPECTED_CALL; } |