diff options
author | Andre Eisenbach <eisenbach@google.com> | 2016-01-14 02:00:24 -0800 |
---|---|---|
committer | The Android Automerger <android-build@google.com> | 2016-02-24 13:21:23 -0800 |
commit | a3478935fe3fe3a1958813e531249f93628b9aa1 (patch) | |
tree | 289386f52dd6860cfdc0c8575fe16eb8dcd06125 | |
parent | ed1563bbd6c634841aa1e27d13aaf0e0f3580ec9 (diff) | |
download | android_system_bt-a3478935fe3fe3a1958813e531249f93628b9aa1.tar.gz android_system_bt-a3478935fe3fe3a1958813e531249f93628b9aa1.tar.bz2 android_system_bt-a3478935fe3fe3a1958813e531249f93628b9aa1.zip |
DO NOT MERGE Add ability to add interop entries dynamically (2/2)
Add ability and interface for adding dynamic entries to the interop
workaround database.
Bug: 26548845
Change-Id: Id886e4233fc1548727e79f1581cdc0c6f0738d59
-rw-r--r-- | btif/src/bluetooth.c | 7 | ||||
-rw-r--r-- | device/include/interop.h | 14 | ||||
-rw-r--r-- | device/include/interop_database.h | 2 | ||||
-rw-r--r-- | device/src/interop.c | 102 | ||||
-rw-r--r-- | device/test/interop_test.cpp | 20 | ||||
-rw-r--r-- | main/bte_main.c | 5 |
6 files changed, 139 insertions, 11 deletions
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c index 32132214f..8863f7553 100644 --- a/btif/src/bluetooth.c +++ b/btif/src/bluetooth.c @@ -50,9 +50,10 @@ #include "btsnoop.h" #include "btsnoop_mem.h" #include "bt_utils.h" -#include "osi/include/osi.h" +#include "device/include/interop.h" #include "osi/include/allocation_tracker.h" #include "osi/include/log.h" +#include "osi/include/osi.h" #include "stack_manager.h" #include "btif_config.h" @@ -456,7 +457,9 @@ static const bt_interface_t bluetoothInterface = { set_os_callouts, read_energy_info, dump, - config_clear + config_clear, + interop_database_clear, + interop_database_add, }; const bt_interface_t* bluetooth__get_bluetooth_interface () diff --git a/device/include/interop.h b/device/include/interop.h index e2ca682a3..b2b01bb4e 100644 --- a/device/include/interop.h +++ b/device/include/interop.h @@ -22,11 +22,13 @@ #include "btcore/include/bdaddr.h" +static const char INTEROP_MODULE[] = "interop_module"; + typedef enum { // Disable secure connections // This is for pre BT 4.1/2 devices that do not handle secure mode // very well. - INTEROP_DISABLE_LE_SECURE_CONNECTIONS, + INTEROP_DISABLE_LE_SECURE_CONNECTIONS = 0, // Some devices have proven problematic during the pairing process, often // requiring multiple retries to complete pairing. To avoid degrading the user @@ -38,5 +40,13 @@ typedef enum { // Check if a given |addr| matches a known interoperability workaround as identified // by the |interop_feature_t| enum. This API is used for simple address based lookups // where more information is not available. No look-ups or random address resolution -// is performed on |addr|. +// are performed on |addr|. bool interop_match(const interop_feature_t feature, const bt_bdaddr_t *addr); + +// Add a dynamic interop database entry for a device matching the first |length| bytes +// of |addr|, implementing the workaround identified by |feature|. |addr| may not be +// null and |length| must be greater than 0 and less than sizeof(bt_bdaddr_t). +void interop_database_add(const interop_feature_t feature, const bt_bdaddr_t *addr, size_t length); + +// Clear the dynamic portion of the interoperability workaround database. +void interop_database_clear(void); diff --git a/device/include/interop_database.h b/device/include/interop_database.h index 4f95be916..9148f6845 100644 --- a/device/include/interop_database.h +++ b/device/include/interop_database.h @@ -22,7 +22,7 @@ typedef struct { bt_bdaddr_t addr; - uint8_t len; + size_t length; interop_feature_t feature; } interop_entry_t; diff --git a/device/src/interop.c b/device/src/interop.c index 84decd765..605d7be05 100644 --- a/device/src/interop.c +++ b/device/src/interop.c @@ -21,13 +21,78 @@ #include <assert.h> #include <string.h> // For memcmp +#include "btcore/include/module.h" #include "device/include/interop.h" #include "device/include/interop_database.h" +#include "osi/include/allocator.h" +#include "osi/include/list.h" #include "osi/include/log.h" #define CASE_RETURN_STR(const) case const: return #const; -static const char* interop_feature_string(const interop_feature_t feature) { +static list_t *interop_list = NULL; + +static const char* interop_feature_string_(const interop_feature_t feature); +static void interop_free_entry_(void *data); +static void interop_lazy_init_(void); +static bool interop_match_fixed_(const interop_feature_t feature, const bt_bdaddr_t *addr); +static bool interop_match_dynamic_(const interop_feature_t feature, const bt_bdaddr_t *addr); + +// Interface functions + +bool interop_match(const interop_feature_t feature, const bt_bdaddr_t *addr) { + assert(addr); + + if (interop_match_fixed_(feature, addr) || interop_match_dynamic_(feature, addr)) { + char bdstr[20] = {0}; + LOG_WARN("%s() Device %s is a match for interop workaround %s.", + __func__, bdaddr_to_string(addr, bdstr, sizeof(bdstr)), + interop_feature_string_(feature)); + return true; + } + + return false; +} + +void interop_database_add(const interop_feature_t feature, const bt_bdaddr_t *addr, size_t length) { + assert(addr); + assert(length > 0); + assert(length < sizeof(bt_bdaddr_t)); + + interop_entry_t *entry = osi_calloc(sizeof(interop_entry_t)); + memcpy(&entry->addr, addr, length); + entry->feature = feature; + entry->length = length; + + interop_lazy_init_(); + list_append(interop_list, entry); +} + +void interop_database_clear() { + if (interop_list) + list_clear(interop_list); +} + +// Module life-cycle functions + +static future_t *interop_clean_up(void) { + list_free(interop_list); + interop_list = NULL; + return future_new_immediate(FUTURE_SUCCESS); +} + +const module_t interop_module = { + .name = INTEROP_MODULE, + .init = NULL, + .start_up = NULL, + .shut_down = NULL, + .clean_up = interop_clean_up, + .dependencies = {NULL}, +}; + +// Local functions + +static const char* interop_feature_string_(const interop_feature_t feature) { switch (feature) { CASE_RETURN_STR(INTEROP_DISABLE_LE_SECURE_CONNECTIONS) CASE_RETURN_STR(INTEROP_AUTO_RETRY_PAIRING) @@ -36,19 +101,44 @@ static const char* interop_feature_string(const interop_feature_t feature) { return "UNKNOWN"; } -// Interface functions +static void interop_free_entry_(void *data) { + interop_entry_t *entry = (interop_entry_t *)data; + osi_free(entry); +} -bool interop_match(const interop_feature_t feature, const bt_bdaddr_t *addr) { +static void interop_lazy_init_(void) { + if (interop_list == NULL) { + interop_list = list_new(interop_free_entry_); + } +} + +static bool interop_match_dynamic_(const interop_feature_t feature, const bt_bdaddr_t *addr) { + if (interop_list == NULL || list_length(interop_list) == 0) + return false; + + const list_node_t *node = list_begin(interop_list); + while (node != list_end(interop_list)) { + interop_entry_t *entry = list_node(node); + assert(entry); + + if (feature == entry->feature && memcmp(addr, &entry->addr, entry->length) == 0) + return true; + + node = list_next(node); + } + return false; +} + +static bool interop_match_fixed_(const interop_feature_t feature, const bt_bdaddr_t *addr) { assert(addr); const size_t db_size = sizeof(interop_database) / sizeof(interop_entry_t); - for (size_t i = 0; i != db_size; ++i) { if (feature == interop_database[i].feature && - memcmp(addr, &interop_database[i].addr, interop_database[i].len) == 0) { + memcmp(addr, &interop_database[i].addr, interop_database[i].length) == 0) { char bdstr[20] = {0}; LOG_WARN("%s() Device %s is a match for interop workaround %s", __func__, - bdaddr_to_string(addr, bdstr, sizeof(bdstr)), interop_feature_string(feature)); + bdaddr_to_string(addr, bdstr, sizeof(bdstr)), interop_feature_string_(feature)); return true; } } diff --git a/device/test/interop_test.cpp b/device/test/interop_test.cpp index eae23ffab..a3ccecbcb 100644 --- a/device/test/interop_test.cpp +++ b/device/test/interop_test.cpp @@ -42,3 +42,23 @@ TEST(InteropTest, test_lookup_miss) { EXPECT_FALSE(interop_match(INTEROP_AUTO_RETRY_PAIRING, &test_address)); } +TEST(InteropTest, test_dynamic) { + bt_bdaddr_t test_address; + + string_to_bdaddr("11:22:33:44:55:66", &test_address); + EXPECT_FALSE(interop_match(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address)); + + interop_database_add(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address, 3); + EXPECT_TRUE(interop_match(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address)); + EXPECT_FALSE(interop_match(INTEROP_AUTO_RETRY_PAIRING, &test_address)); + + string_to_bdaddr("66:55:44:33:22:11", &test_address); + EXPECT_FALSE(interop_match(INTEROP_AUTO_RETRY_PAIRING, &test_address)); + + interop_database_add(INTEROP_AUTO_RETRY_PAIRING, &test_address, 3); + EXPECT_TRUE(interop_match(INTEROP_AUTO_RETRY_PAIRING, &test_address)); + EXPECT_FALSE(interop_match(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address)); + + interop_database_clear(); + EXPECT_FALSE(interop_match(INTEROP_AUTO_RETRY_PAIRING, &test_address)); +} diff --git a/main/bte_main.c b/main/bte_main.c index d08d6f615..a88839162 100644 --- a/main/bte_main.c +++ b/main/bte_main.c @@ -45,6 +45,9 @@ #include "bt_utils.h" #include "btcore/include/counter.h" #include "btcore/include/module.h" +#include "device/include/interop.h" +#include "hci_layer.h" +#include "osi/include/alarm.h" #include "osi/include/fixed_queue.h" #include "osi/include/future.h" #include "gki.h" @@ -97,6 +100,7 @@ void bte_main_boot_entry(void) { module_init(get_module(GKI_MODULE)); module_init(get_module(COUNTER_MODULE)); + module_init(get_module(INTEROP_MODULE)); hci = hci_layer_get_interface(); if (!hci) @@ -136,6 +140,7 @@ void bte_main_shutdown() module_clean_up(get_module(STACK_CONFIG_MODULE)); + module_clean_up(get_module(INTEROP_MODULE)); module_clean_up(get_module(COUNTER_MODULE)); module_clean_up(get_module(GKI_MODULE)); } |