diff options
-rwxr-xr-x | btif/include/btif_common.h | 18 | ||||
-rw-r--r-- | btif/src/btif_core.c | 143 | ||||
-rw-r--r-- | btif/src/btif_storage.c | 8 | ||||
-rw-r--r-- | main/bte_main.c | 7 | ||||
-rw-r--r-- | vendor/libvendor/include/bt_vendor_brcm.h | 17 | ||||
-rw-r--r-- | vendor/libvendor/include/bt_vendor_lib.h | 2 | ||||
-rw-r--r-- | vendor/libvendor/src/bt_vendor_brcm.c | 6 | ||||
-rw-r--r-- | vendor/libvendor/src/hardware.c | 203 |
8 files changed, 163 insertions, 241 deletions
diff --git a/btif/include/btif_common.h b/btif/include/btif_common.h index 635caeb..3ecea9f 100755 --- a/btif/include/btif_common.h +++ b/btif/include/btif_common.h @@ -140,6 +140,24 @@ enum BTIF_DM_CB_HID_REMOTE_NAME, /* Remote name callback for HID device */ }; +/* Macro definitions for BD ADDR persistence */ +/* PROPERTY_BT_BDADDR_PATH + The property key stores the storage location of Bluetooth Device Address +*/ +#ifndef PROPERTY_BT_BDADDR_PATH +#define PROPERTY_BT_BDADDR_PATH "ro.bt.bdaddr_path" +#endif + +/* PERSIST_BDADDR_PROPERTY + If there is no valid bdaddr available from PROPERTY_BT_BDADDR_PATH, + generating a random BDADDR and keeping it in the PERSIST_BDADDR_DROP. +*/ +#ifndef PERSIST_BDADDR_PROPERTY +#define PERSIST_BDADDR_PROPERTY "persist.service.bdroid.bdaddr" +#endif + +#define FACTORY_BT_BDADDR_STORAGE_LEN 17 + /************************************************************************************ ** Type definitions for callback functions ************************************************************************************/ diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c index ebe2f8b..51328a8 100644 --- a/btif/src/btif_core.c +++ b/btif/src/btif_core.c @@ -54,10 +54,18 @@ * ***********************************************************************************/ +#include <stdlib.h> #include <hardware/bluetooth.h> #include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <dirent.h> +#include <ctype.h> +#include <cutils/properties.h> + #define LOG_TAG "BTIF_CORE" #include "btif_api.h" @@ -113,7 +121,7 @@ typedef union { /************************************************************************************ ** Static variables ************************************************************************************/ - +bt_bdaddr_t btif_local_bd_addr; /************************************************************************************ ** Static functions ************************************************************************************/ @@ -130,7 +138,7 @@ extern void bte_load_did_conf(const char *p_path); /** TODO: Move these to _common.h */ void bte_main_boot_entry(void); -void bte_main_enable(void); +void bte_main_enable(uint8_t *local_addr); void bte_main_disable(void); void bte_main_shutdown(void); #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) @@ -287,18 +295,6 @@ static void btif_task(UINT32 params) btif_disassociate_evt(); - GKI_task_self_cleanup(BTIF_TASK); - - bte_main_shutdown(); - - if (btif_shutdown_pending) - { - btif_shutdown_pending = 0; - - /* shutdown complete, all events notified and we reset HAL callbacks */ - bt_hal_cbacks = NULL; - } - BTIF_TRACE_DEBUG0("btif task exiting"); } @@ -318,6 +314,76 @@ void btif_sendmsg(void *p_msg) GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg); } +static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr) +{ + char val[256]; + uint8_t valid_bda = FALSE; + const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0}; + + BTIF_TRACE_DEBUG1("Look for bdaddr storage path in prop %s", PROPERTY_BT_BDADDR_PATH); + + /* Get local bdaddr storage path from property */ + if (property_get(PROPERTY_BT_BDADDR_PATH, val, NULL)) + { + int addr_fd; + + BTIF_TRACE_DEBUG1("local bdaddr is stored in %s", val); + + if ((addr_fd = open(val, O_RDONLY)) != -1) + { + memset(val, 0, sizeof(val)); + read(addr_fd, val, FACTORY_BT_BDADDR_STORAGE_LEN); + str2bd(val, local_addr); + /* If this is not a reserved/special bda, then use it */ + if (memcmp(local_addr->address, null_bdaddr, BD_ADDR_LEN) != 0) + { + valid_bda = TRUE; + BTIF_TRACE_DEBUG6("Got Factory BDA %02X:%02X:%02X:%02X:%02X:%02X", + local_addr->address[0], local_addr->address[1], local_addr->address[2], + local_addr->address[3], local_addr->address[4], local_addr->address[5]); + } + + close(addr_fd); + } + } + + /* No factory BDADDR found. Look for previously generated random BDA */ + if ((!valid_bda) && \ + (property_get(PERSIST_BDADDR_PROPERTY, val, NULL))) + { + str2bd(val, local_addr); + valid_bda = TRUE; + BTIF_TRACE_DEBUG6("Got prior random BDA %02X:%02X:%02X:%02X:%02X:%02X", + local_addr->address[0], local_addr->address[1], local_addr->address[2], + local_addr->address[3], local_addr->address[4], local_addr->address[5]); + } + + /* Generate new BDA if necessary */ + if (!valid_bda) + { + bdstr_t bdstr; + /* Seed the random number generator */ + srand((unsigned int) (time(0))); + + /* No autogen BDA. Generate one now. */ + local_addr->address[0] = 0x22; + local_addr->address[1] = 0x22; + local_addr->address[2] = (uint8_t) ((rand() >> 8) & 0xFF); + local_addr->address[3] = (uint8_t) ((rand() >> 8) & 0xFF); + local_addr->address[4] = (uint8_t) ((rand() >> 8) & 0xFF); + local_addr->address[5] = (uint8_t) ((rand() >> 8) & 0xFF); + + /* Convert to ascii, and store as a persistent property */ + bd2str(local_addr, &bdstr); + + BTIF_TRACE_DEBUG2("No preset BDA. Generating BDA: %s for prop %s", + (char*)bdstr, PERSIST_BDADDR_PROPERTY); + + if (property_set(PERSIST_BDADDR_PROPERTY, (char*)bdstr) < 0) + BTIF_TRACE_ERROR1("Failed to set random BDA in prop %s",PERSIST_BDADDR_PROPERTY); + } +} + /***************************************************************************** ** ** btif core api functions @@ -336,8 +402,22 @@ void btif_sendmsg(void *p_msg) bt_status_t btif_init_bluetooth(void) { + UINT8 status; + bte_main_boot_entry(); + /* As part of the init, fetch the local BD ADDR */ + memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t)); + btif_fetch_local_bdaddr(&btif_local_bd_addr); + + /* start btif task */ + status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR, + (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE), + sizeof(btif_task_stack)); + + if (status != GKI_SUCCESS) + return BT_STATUS_FAIL; + return BT_STATUS_SUCCESS; } @@ -377,27 +457,19 @@ bt_status_t btif_enable_bluetooth(void) LOGI("btif_enable_bluetooth"); - /* initialize OS */ - GKI_init(); - if (btif_enabled == 1) { LOGD("already enabled\n"); return BT_STATUS_DONE; } - /* Start the BTIF task */ - status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR, - (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE), - sizeof(btif_task_stack)); - - if (status != BTA_SUCCESS) - return BT_STATUS_FAIL; - /* add return status for create tasks functions ? */ /* Create the GKI tasks and run them */ - bte_main_enable(); + bte_main_enable(btif_local_bd_addr.address); + + if (status != BTA_SUCCESS) + return BT_STATUS_FAIL; return BT_STATUS_SUCCESS; } @@ -525,7 +597,10 @@ void btif_disable_bluetooth_evt(void) /* update local state */ btif_enabled = 0; - GKI_send_event(BTIF_TASK, EVENT_MASK(GKI_SHUTDOWN_EVT)); + if (btif_shutdown_pending) + { + btif_shutdown_bluetooth(); + } } @@ -554,10 +629,11 @@ bt_status_t btif_shutdown_bluetooth(void) return BT_STATUS_SUCCESS; } - bte_main_shutdown(); + btif_shutdown_pending = 0; - /* shutdown complete, all events notified and we reset HAL callbacks */ - bt_hal_cbacks = NULL; + GKI_destroy_task(BTIF_TASK); + + bte_main_shutdown(); return BT_STATUS_SUCCESS; } @@ -580,6 +656,9 @@ static bt_status_t btif_disassociate_evt(void) HAL_CBACK(bt_hal_cbacks, thread_evt_cb, DISASSOCIATE_JVM); + /* shutdown complete, all events notified and we reset HAL callbacks */ + bt_hal_cbacks = NULL; + return BT_STATUS_SUCCESS; } @@ -732,7 +811,6 @@ static void execute_storage_request(UINT16 event, char *p_param) prop.type = p_req->read_req.type; prop.val = (void*)buf; prop.len = sizeof(buf); - status = btif_storage_get_adapter_property(&prop); HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, &prop); } break; @@ -875,7 +953,8 @@ bt_status_t btif_get_adapter_property(bt_property_type_t type) BTIF_TRACE_EVENT2("%s %d", __FUNCTION__, type); - if (btif_enabled == 0) + /* Allow get_adapter_property only for BDADDR and BDNAME if BT is disabled */ + if ((btif_enabled == 0) && (type != BT_PROPERTY_BDADDR) && (type != BT_PROPERTY_BDNAME)) return BT_STATUS_FAIL; memset(&(req.read_req.bd_addr), 0, sizeof(bt_bdaddr_t)); diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c index 2c3ed69..e289634 100644 --- a/btif/src/btif_storage.c +++ b/btif/src/btif_storage.c @@ -112,6 +112,7 @@ #include "bta_hh_api.h" #include "btif_hh.h" + /************************************************************************************ ** Constants & Macros ************************************************************************************/ @@ -202,7 +203,7 @@ typedef struct { ** Extern variables ************************************************************************************/ extern UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID]; - +extern bt_bdaddr_t btif_local_bd_addr; /************************************************************************************ ** Static variables ************************************************************************************/ @@ -760,10 +761,9 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t *property) { BD_ADDR addr; bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)property->val; - BTM_GetLocalDeviceAddr(addr); - bdcpy(bd_addr->address, addr); + /* This has been cached in btif. Just fetch it from there */ + memcpy(bd_addr, &btif_local_bd_addr, sizeof(bt_bdaddr_t)); property->len = sizeof(bt_bdaddr_t); - return BT_STATUS_SUCCESS; } else if (property->type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) diff --git a/main/bte_main.c b/main/bte_main.c index 8ac3ff5..49d964e 100644 --- a/main/bte_main.c +++ b/main/bte_main.c @@ -143,6 +143,9 @@ void bte_main_in_hw_init(void) ******************************************************************************/ void bte_main_boot_entry(void) { + /* initialize OS */ + GKI_init(); + bte_main_in_hw_init(); bte_load_conf(BTE_STACK_CONF_FILE); @@ -184,7 +187,7 @@ void bte_main_shutdown() ** Returns None ** ******************************************************************************/ -void bte_main_enable(void) +void bte_main_enable(uint8_t *local_addr) { APPL_TRACE_DEBUG1("%s", __FUNCTION__); @@ -195,7 +198,7 @@ void bte_main_enable(void) if (bt_vendor_if) { - int result = bt_vendor_if->init(&vnd_callbacks); + int result = bt_vendor_if->init(&vnd_callbacks, local_addr); APPL_TRACE_EVENT1("libbt-vendor init returns %d", result); /* toggle chip power to ensure we will reset chip in case diff --git a/vendor/libvendor/include/bt_vendor_brcm.h b/vendor/libvendor/include/bt_vendor_brcm.h index ae72fc7..5d84e8b 100644 --- a/vendor/libvendor/include/bt_vendor_brcm.h +++ b/vendor/libvendor/include/bt_vendor_brcm.h @@ -373,23 +373,6 @@ #define PCM_DATA_FMT_JUSTIFY_MODE 0 #endif -/* PROPERTY_BT_BDADDR_PATH - The property key stores the storage location of Bluetooth Device Address -*/ -#ifndef PROPERTY_BT_BDADDR_PATH -#define PROPERTY_BT_BDADDR_PATH "ro.bt.bdaddr_path" -#endif - -/* PERSIST_BDADDR_PROPERTY - If there is no valid bdaddr available from PROPERTY_BT_BDADDR_PATH, - generating a random BDADDR and keeping it in the PERSIST_BDADDR_DROP. -*/ -#ifndef PERSIST_BDADDR_PROPERTY -#define PERSIST_BDADDR_PROPERTY "persist.service.bdroid.bdaddr" -#endif - -#define FACTORY_BT_BDADDR_STORAGE_LEN 17 - /* Debug mode with bit-wise mask */ typedef uint8_t vnd_debug_t; #define DEBUG_ON 0xFF diff --git a/vendor/libvendor/include/bt_vendor_lib.h b/vendor/libvendor/include/bt_vendor_lib.h index 4b5b5a8..e727840 100644 --- a/vendor/libvendor/include/bt_vendor_lib.h +++ b/vendor/libvendor/include/bt_vendor_lib.h @@ -187,7 +187,7 @@ typedef struct { * Opens the interface and provides the callback routines * to the implemenation of this interface. */ - int (*init)(const bt_vendor_callbacks_t* p_cb); + int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr); /** Chip power control */ void (*set_power)(bt_vendor_chip_power_state_t state); diff --git a/vendor/libvendor/src/bt_vendor_brcm.c b/vendor/libvendor/src/bt_vendor_brcm.c index 9b25692..c7de93e 100644 --- a/vendor/libvendor/src/bt_vendor_brcm.c +++ b/vendor/libvendor/src/bt_vendor_brcm.c @@ -151,8 +151,9 @@ void btvnd_signal_event(uint16_t event) ** BLUETOOTH VENDOR LIBRARY INTERFACE FUNCTIONS ** *****************************************************************************/ +uint8_t vendor_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static int init(const bt_vendor_callbacks_t* p_cb) +static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr) { pthread_attr_t thread_attr; struct sched_param param; @@ -171,6 +172,9 @@ static int init(const bt_vendor_callbacks_t* p_cb) /* store reference to user callbacks */ bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb; + /* This is handed over from the stack */ + memcpy(vendor_local_bd_addr, local_bdaddr, 6); + utils_init(); upio_init(); hci_h4_init(); diff --git a/vendor/libvendor/src/hardware.c b/vendor/libvendor/src/hardware.c index f5865c8..66d2ad1 100644 --- a/vendor/libvendor/src/hardware.c +++ b/vendor/libvendor/src/hardware.c @@ -198,14 +198,12 @@ void hw_config_cback(VND_BT_HDR *p_evt_buf); uint8_t hci_h4_send_int_cmd(uint16_t opcode, VND_BT_HDR *p_buf, \ tINT_CMD_CBACK p_cback); - +extern uint8_t vendor_local_bd_addr[BD_ADDR_LEN]; /****************************************************************************** ** Static variables ******************************************************************************/ static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION; -static uint8_t local_bd_addr[BD_ADDR_LEN]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0}; static bt_hw_cfg_cb_t hw_cfg_cb; static bt_lpm_cb_t hw_lpm_cb; @@ -392,154 +390,6 @@ static uint8_t hw_config_findpatch(char *p_chip_id_str) /******************************************************************************* ** -** Function hw_ascii_2_bdaddr -** -** Description This function converts ASCII string of Bluetooth device -** address (xx:xx:xx:xx:xx:xx) into a BD_ADDR type -** -** Returns None -** -*******************************************************************************/ -void hw_ascii_2_bdaddr (char *p_ascii, uint8_t *p_bd) -{ - int x; - uint8_t c; - - for (x = 0; x < BD_ADDR_LEN; x++) - { - if ((*p_ascii>='0') && (*p_ascii<='9')) - c = (*p_ascii - '0') << 4; - else - c = (toupper(*p_ascii) - 'A' + 10) << 4; - - p_ascii++; - if ((*p_ascii>='0') && (*p_ascii<='9')) - c |= (*p_ascii - '0'); - else - c |= (toupper(*p_ascii) - 'A' + 10); - - p_ascii+=2; // skip ':' and point to next valid digit - *p_bd++ = c; - } -} - -/******************************************************************************* -** -** Function hw_bdaddr_2_ascii -** -** Description This function converts a BD_ADDR type address into ASCII -** string of Bluetooth device address (xx:xx:xx:xx:xx:xx) -** -** Returns None -** -*******************************************************************************/ -void hw_bdaddr_2_ascii (uint8_t *p_bd, char *p_ascii) -{ - int x; - uint8_t c; - - for (x = 0; x < BD_ADDR_LEN; x++) - { - c = (*p_bd >> 4) & 0x0f; - if (c < 10) - *p_ascii++ = c + '0'; - else - *p_ascii++ = c - 10 + 'A'; - - c = *p_bd & 0x0f; - if (c < 10) - *p_ascii++ = c + '0'; - else - *p_ascii++ = c - 10 + 'A'; - - p_bd++; - *p_ascii++ = ':'; - } - *--p_ascii = '\0'; -} - - -/******************************************************************************* -** -** Function hw_config_get_bdaddr -** -** Description Get Bluetooth Device Address -** -** Returns None -** -*******************************************************************************/ -void hw_config_get_bdaddr(uint8_t *local_addr) -{ - char val[LOCAL_BDADDR_PATH_BUFFER_LEN]; - uint8_t bHaveValidBda = FALSE; - - BTHWDBG("Look for bdaddr storage path in prop %s", PROPERTY_BT_BDADDR_PATH); - - /* Get local bdaddr storage path from property */ - if (property_get(PROPERTY_BT_BDADDR_PATH, val, NULL)) - { - int addr_fd; - - BTHWDBG("local bdaddr is stored in %s", val); - - if ((addr_fd = open(val, O_RDONLY)) != -1) - { - memset(val, 0, LOCAL_BDADDR_PATH_BUFFER_LEN); - read(addr_fd, val, FACTORY_BT_BDADDR_STORAGE_LEN); - hw_ascii_2_bdaddr(val, local_addr); - - /* If this is not a reserved/special bda, then use it */ - if (memcmp(local_addr, null_bdaddr, BD_ADDR_LEN) != 0) - { - bHaveValidBda = TRUE; - LOGI("Got Factory BDA %02X:%02X:%02X:%02X:%02X:%02X", - local_addr[0], local_addr[1], local_addr[2], - local_addr[3], local_addr[4], local_addr[5]); - } - - close(addr_fd); - } - } - - /* No factory BDADDR found. Look for previously generated random BDA */ - if ((!bHaveValidBda) && \ - (property_get(PERSIST_BDADDR_PROPERTY, val, NULL))) - { - hw_ascii_2_bdaddr(val, local_addr); - bHaveValidBda = TRUE; - LOGI("Got prior random BDA %02X:%02X:%02X:%02X:%02X:%02X", - local_addr[0], local_addr[1], local_addr[2], - local_addr[3], local_addr[4], local_addr[5]); - } - - /* Generate new BDA if necessary */ - if (!bHaveValidBda) - { - /* Seed the random number generator */ - srand((unsigned int) (time(0))); - - /* No autogen BDA. Generate one now. */ - local_addr[0] = 0x22; - local_addr[1] = 0x22; - local_addr[2] = (uint8_t) ((rand() >> 8) & 0xFF); - local_addr[3] = (uint8_t) ((rand() >> 8) & 0xFF); - local_addr[4] = (uint8_t) ((rand() >> 8) & 0xFF); - local_addr[5] = (uint8_t) ((rand() >> 8) & 0xFF); - - /* Convert to ascii, and store as a persistent property */ - hw_bdaddr_2_ascii(local_addr, val); - - LOGI("No preset BDA. Generating BDA: %s for prop %s", - val, PERSIST_BDADDR_PROPERTY); - - if (property_set(PERSIST_BDADDR_PROPERTY, val) < 0) - LOGE("Failed to set random BDA in prop %s",PERSIST_BDADDR_PROPERTY); - } -} /* btl_cfg_get_bdaddr() */ - - -/******************************************************************************* -** ** Function hw_config_set_bdaddr ** ** Description Program controller's Bluetooth Device Address @@ -553,28 +403,24 @@ static uint8_t hw_config_set_bdaddr(VND_BT_HDR *p_buf) uint8_t retval = FALSE; uint8_t *p = (uint8_t *) (p_buf + 1); - /* See if bdaddr needs to be programmed */ - if (memcmp(local_bd_addr, null_bdaddr, BD_ADDR_LEN) != 0) - { - LOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X", - local_bd_addr[0], local_bd_addr[1], local_bd_addr[2], - local_bd_addr[3], local_bd_addr[4], local_bd_addr[5]); - - UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR); - *p++ = BD_ADDR_LEN; /* parameter length */ - *p++ = local_bd_addr[5]; - *p++ = local_bd_addr[4]; - *p++ = local_bd_addr[3]; - *p++ = local_bd_addr[2]; - *p++ = local_bd_addr[1]; - *p = local_bd_addr[0]; - - p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN; - hw_cfg_cb.state = HW_CFG_SET_BD_ADDR; - - retval = hci_h4_send_int_cmd(HCI_VSC_WRITE_BD_ADDR, p_buf, \ - hw_config_cback); - } + LOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X", + vendor_local_bd_addr[0], vendor_local_bd_addr[1], vendor_local_bd_addr[2], + vendor_local_bd_addr[3], vendor_local_bd_addr[4], vendor_local_bd_addr[5]); + + UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR); + *p++ = BD_ADDR_LEN; /* parameter length */ + *p++ = vendor_local_bd_addr[5]; + *p++ = vendor_local_bd_addr[4]; + *p++ = vendor_local_bd_addr[3]; + *p++ = vendor_local_bd_addr[2]; + *p++ = vendor_local_bd_addr[1]; + *p = vendor_local_bd_addr[0]; + + p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN; + hw_cfg_cb.state = HW_CFG_SET_BD_ADDR; + + retval = hci_h4_send_int_cmd(HCI_VSC_WRITE_BD_ADDR, p_buf, \ + hw_config_cback); return (retval); } @@ -1046,17 +892,6 @@ void hw_config_start(void) hw_cfg_cb.f_set_baud_2 = FALSE; hw_lpm_cb.state = HW_LPM_DISABLED; - /**************************************** - * !!! TODO !!! - * - * === Custom Porting Required === - * - * Unique Bluetooth address should be - * assigned to local_bd_addr[6] in - * production line for each device. - ****************************************/ - hw_config_get_bdaddr(local_bd_addr); - /* Start from sending HCI_RESET */ if (bt_vendor_cbacks) |