diff --git a/components/bt/common/osi/include/osi/list.h b/components/bt/common/osi/include/osi/list.h index c0abd106e5..d3373fcc8c 100644 --- a/components/bt/common/osi/include/osi/list.h +++ b/components/bt/common/osi/include/osi/list.h @@ -34,6 +34,10 @@ bool list_is_empty(const list_t *list); // |list| may not be NULL. bool list_contains(const list_t *list, const void *data); +// Returns list_node which contains |data|, NULL otherwise. +// |list| may not be NULL. +list_node_t *list_get_node(const list_t *list, const void *data); + // Returns the length of the |list|. |list| may not be NULL. size_t list_length(const list_t *list); diff --git a/components/bt/common/osi/list.c b/components/bt/common/osi/list.c index 93db17fb38..6d8406d32b 100644 --- a/components/bt/common/osi/list.c +++ b/components/bt/common/osi/list.c @@ -68,6 +68,21 @@ bool list_contains(const list_t *list, const void *data) return false; } +list_node_t *list_get_node(const list_t *list, const void *data) +{ + assert(list != NULL); + assert(data != NULL); + list_node_t *p_node_ret = NULL; + for (list_node_t *node = list_begin(list); node != list_end(list); node = list_next(node)) { + if (list_node(node) == data) { + p_node_ret = node; + break; + } + } + + return p_node_ret; +} + size_t list_length(const list_t *list) { assert(list != NULL); diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 0a99840f56..5f105add92 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -46,6 +46,7 @@ #include "l2c_int.h" #include "stack/hcidefs.h" //#include "bt_utils.h" +#include "osi/list.h" static void btm_read_remote_features (UINT16 handle); static void btm_read_remote_ext_features (UINT16 handle, UINT8 page_number); @@ -71,6 +72,8 @@ void btm_acl_init (void) btm_cb.btm_def_link_policy = 0; btm_cb.p_bl_changed_cb = NULL; #endif + btm_cb.p_acl_db_list = list_new(osi_free_func); + btm_cb.p_pm_mode_db_list = list_new(osi_free_func); /* Initialize nonzero defaults */ btm_cb.btm_def_link_super_tout = HCI_DEFAULT_INACT_TOUT; @@ -90,49 +93,56 @@ void btm_acl_init (void) ** NULL if not found. ** *******************************************************************************/ -tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport) +BOOLEAN btm_get_acl_db(void *p_acl_db_node, void *context) { - tACL_CONN *p = &btm_cb.acl_db[0]; - UINT16 xx; - if (bda) { - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN)) + tACL_CONN *p_acl_db =(tACL_CONN *)p_acl_db_node; + BOOLEAN ret = TRUE; + tACL_DB_PARAM *p_param = (tACL_DB_PARAM *)context; + switch(p_param->type) { + case ACL_DB_BDA: + { + UINT8 *p_bda = (UINT8 *)p_param->p_data1; #if BLE_INCLUDED == TRUE - && p->transport == transport + tBT_TRANSPORT transport = (tBT_TRANSPORT)(*((UINT8 *)p_param->p_data2)); #endif - ) { - BTM_TRACE_DEBUG ("btm_bda_to_acl found\n"); - return (p); - } - } + if (p_acl_db->in_use + && !memcmp(p_bda, p_acl_db->remote_addr, BD_ADDR_LEN) +#if BLE_INCLUDED == TRUE + && transport == p_acl_db->transport +#endif + ) { + ret = FALSE; + } + break; + } + case ACL_DB_HANDLE: + { + UINT16 handle = (UINT16) *((UINT16 *)p_param->p_data1); + if (p_acl_db->in_use && handle == p_acl_db->hci_handle) { + ret = FALSE; + } + break; + } + default: + break; } - - /* If here, no BD Addr found */ - return ((tACL_CONN *)NULL); + return ret; } -/******************************************************************************* -** -** Function btm_handle_to_acl_index -** -** Description This function returns the FIRST acl_db entry for the passed hci_handle. -** -** Returns index to the acl_db or MAX_L2CAP_LINKS. -** -*******************************************************************************/ -UINT8 btm_handle_to_acl_index (UINT16 hci_handle) +tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport) { - tACL_CONN *p = &btm_cb.acl_db[0]; - UINT8 xx; - BTM_TRACE_DEBUG ("btm_handle_to_acl_index\n"); - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if ((p->in_use) && (p->hci_handle == hci_handle)) { - break; - } + tACL_CONN *p_acl_db = NULL; + list_node_t *p_node = NULL; + tACL_DB_PARAM acl_params; + acl_params.type = ACL_DB_BDA; + acl_params.p_data1 = (void *)bda; + acl_params.p_data2 = (void *)&transport; + p_node = list_foreach(btm_cb.p_acl_db_list, btm_get_acl_db, (void *)&acl_params); + if (p_node) { + p_acl_db = list_node(p_node); } - /* If here, no BD Addr found */ - return (xx); + return (p_acl_db); } /******************************************************************************* @@ -147,17 +157,21 @@ UINT8 btm_handle_to_acl_index (UINT16 hci_handle) *******************************************************************************/ tACL_CONN *btm_handle_to_acl (UINT16 hci_handle) { - tACL_CONN *p = &btm_cb.acl_db[0]; - UINT8 xx; - BTM_TRACE_DEBUG ("btm_handle_to_acl_index\n"); - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if ((p->in_use) && (p->hci_handle == hci_handle)) { - return(p); - } + tACL_CONN *p_acl_db = NULL; + tACL_DB_PARAM acl_params; + list_node_t *p_node = NULL; + + BTM_TRACE_DEBUG ("btm_handle_to_acl_index: %d\n", hci_handle); + + acl_params.type = ACL_DB_HANDLE; + acl_params.p_data1 = (void *)&hci_handle; + acl_params.p_data2 = NULL; + p_node = list_foreach(btm_cb.p_acl_db_list, btm_get_acl_db, (void *)&acl_params); + if (p_node) { + p_acl_db = list_node(p_node); } - /* If here, no BD Addr found */ - return ((tACL_CONN *)NULL); + return (p_acl_db); } #if BLE_PRIVACY_SPT == TRUE @@ -228,7 +242,6 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, { tBTM_SEC_DEV_REC *p_dev_rec = NULL; tACL_CONN *p; - UINT8 xx; BTM_TRACE_DEBUG ("btm_acl_created hci_handle=%d link_role=%d transport=%d\n", hci_handle, link_role, transport); @@ -247,8 +260,13 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, } /* Allocate acl_db entry */ - for (xx = 0, p = &btm_cb.acl_db[0]; xx < MAX_L2CAP_LINKS; xx++, p++) { - if (!p->in_use) { + if (list_length(btm_cb.p_acl_db_list) >= MAX_L2CAP_LINKS) { + return; + } + else { + p = (tACL_CONN *)osi_malloc(sizeof(tACL_CONN)); + if (p && list_append(btm_cb.p_acl_db_list, p)) { + memset(p, 0, sizeof(tACL_CONN)); p->in_use = TRUE; p->hci_handle = hci_handle; p->link_role = link_role; @@ -274,7 +292,10 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, #endif p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE; - btm_pm_sm_alloc(xx); + p->p_pm_mode_db = btm_pm_sm_alloc(); +#if BTM_PM_DEBUG == TRUE + BTM_TRACE_DEBUG( "btm_pm_sm_alloc handle:%d st:%d", hci_handle, p->p_pm_mode_db->state); +#endif // BTM_PM_DEBUG #if (CLASSIC_BT_INCLUDED == TRUE) btm_sec_update_legacy_auth_state(p, BTM_ACL_LEGACY_AUTH_NONE); @@ -462,8 +483,12 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport) } #endif + list_remove(btm_cb.p_pm_mode_db_list, p->p_pm_mode_db); /* Clear the ACL connection data */ memset(p, 0, sizeof(tACL_CONN)); + if (list_remove(btm_cb.p_acl_db_list, p)) { + p = NULL; + } } } @@ -480,17 +505,16 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport) *******************************************************************************/ void btm_acl_device_down (void) { - tACL_CONN *p = &btm_cb.acl_db[0]; - UINT16 xx; + tACL_CONN *p = NULL; BTM_TRACE_DEBUG ("btm_acl_device_down\n"); - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if (p->in_use) { - BTM_TRACE_DEBUG ("hci_handle=%d HCI_ERR_HW_FAILURE \n", p->hci_handle ); - l2c_link_hci_disc_comp (p->hci_handle, HCI_ERR_HW_FAILURE); - } - } + for (list_node_t *p_node = list_begin(btm_cb.p_acl_db_list); p_node; p_node = list_next(p_node)) { + p = list_node(p_node); + if (!p && p->in_use) { + BTM_TRACE_DEBUG ("hci_handle=%d HCI_ERR_HW_FAILURE \n", p->hci_handle ); + l2c_link_hci_disc_comp (p->hci_handle, HCI_ERR_HW_FAILURE); + } + } } - /******************************************************************************* ** ** Function btm_acl_update_busy_level @@ -730,20 +754,15 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr, UINT8 new_role, tBTM_CMPL_CB void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) { tACL_CONN *p; - UINT8 xx; tBTM_SEC_DEV_REC *p_dev_rec; tBTM_BL_ROLE_CHG_DATA evt; BTM_TRACE_DEBUG ("btm_acl_encrypt_change handle=%d status=%d encr_enabl=%d\n", handle, status, encr_enable); - xx = btm_handle_to_acl_index(handle); - /* don't assume that we can never get a bad hci_handle */ - if (xx < MAX_L2CAP_LINKS) { - p = &btm_cb.acl_db[xx]; - } else { + p = btm_handle_to_acl(handle); + if (p == NULL) { return; } - /* Process Role Switch if active */ if (p->switch_role_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF) { /* if encryption turn off failed we still will try to switch role */ @@ -913,44 +932,40 @@ void BTM_SetDefaultLinkPolicy (UINT16 settings) *******************************************************************************/ void btm_read_remote_version_complete (UINT8 *p) { - tACL_CONN *p_acl_cb = &btm_cb.acl_db[0]; + tACL_CONN *p_acl_cb = NULL; UINT8 status; UINT16 handle; - int xx; BTM_TRACE_DEBUG ("btm_read_remote_version_complete\n"); STREAM_TO_UINT8 (status, p); STREAM_TO_UINT16 (handle, p); /* Look up the connection by handle and copy features */ - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++) { - if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle)) { - if (status == HCI_SUCCESS) { - STREAM_TO_UINT8 (p_acl_cb->lmp_version, p); - STREAM_TO_UINT16 (p_acl_cb->manufacturer, p); - STREAM_TO_UINT16 (p_acl_cb->lmp_subversion, p); - } -#if BLE_INCLUDED == TRUE - if (p_acl_cb->transport == BT_TRANSPORT_LE) { - if(p_acl_cb->link_role == HCI_ROLE_MASTER) { - if (HCI_LE_DATA_LEN_EXT_SUPPORTED(p_acl_cb->peer_le_features)) { - uint16_t data_length = controller_get_interface()->get_ble_default_data_packet_length(); - uint16_t data_txtime = controller_get_interface()->get_ble_default_data_packet_txtime(); - btsnd_hcic_ble_set_data_length(p_acl_cb->hci_handle, data_length, data_txtime); - } - l2cble_notify_le_connection (p_acl_cb->remote_addr); - } else { - //slave role, read remote feature - btsnd_hcic_ble_read_remote_feat(p_acl_cb->hci_handle); - } - } -#endif - break; + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb) { + if (status == HCI_SUCCESS) { + STREAM_TO_UINT8 (p_acl_cb->lmp_version, p); + STREAM_TO_UINT16 (p_acl_cb->manufacturer, p); + STREAM_TO_UINT16 (p_acl_cb->lmp_subversion, p); } +#if BLE_INCLUDED == TRUE + if (p_acl_cb->transport == BT_TRANSPORT_LE) { + if(p_acl_cb->link_role == HCI_ROLE_MASTER) { + if (HCI_LE_DATA_LEN_EXT_SUPPORTED(p_acl_cb->peer_le_features)) { + uint16_t data_length = controller_get_interface()->get_ble_default_data_packet_length(); + uint16_t data_txtime = controller_get_interface()->get_ble_default_data_packet_txtime(); + btsnd_hcic_ble_set_data_length(p_acl_cb->hci_handle, data_length, data_txtime); + } + l2cble_notify_le_connection (p_acl_cb->remote_addr); + } else { + //slave role, read remote feature + btsnd_hcic_ble_read_remote_feat(p_acl_cb->hci_handle); + } + } +#endif } } - /******************************************************************************* ** ** Function btm_process_remote_ext_features @@ -1015,17 +1030,16 @@ void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages) *******************************************************************************/ void btm_read_remote_features (UINT16 handle) { - UINT8 acl_idx; tACL_CONN *p_acl_cb; BTM_TRACE_DEBUG("btm_read_remote_features() handle: %d\n", handle); - if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS) { + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb == NULL) { BTM_TRACE_ERROR("btm_read_remote_features handle=%d invalid\n", handle); - return; + return; } - p_acl_cb = &btm_cb.acl_db[acl_idx]; p_acl_cb->num_read_pages = 0; memset (p_acl_cb->peer_lmp_features, 0, sizeof(p_acl_cb->peer_lmp_features)); @@ -1067,7 +1081,6 @@ void btm_read_remote_features_complete (UINT8 *p) tACL_CONN *p_acl_cb; UINT8 status; UINT16 handle; - UINT8 acl_idx; BTM_TRACE_DEBUG ("btm_read_remote_features_complete\n"); STREAM_TO_UINT8 (status, p); @@ -1079,13 +1092,12 @@ void btm_read_remote_features_complete (UINT8 *p) STREAM_TO_UINT16 (handle, p); - if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS) { + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb == NULL) { BTM_TRACE_ERROR("btm_read_remote_features_complete handle=%d invalid\n", handle); - return; + return; } - p_acl_cb = &btm_cb.acl_db[acl_idx]; - /* Copy the received features page */ STREAM_TO_ARRAY(p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0], p, HCI_FEATURE_BYTES_PER_PAGE); @@ -1123,7 +1135,6 @@ void btm_read_remote_ext_features_complete (UINT8 *p) tACL_CONN *p_acl_cb; UINT8 page_num, max_page; UINT16 handle; - UINT8 acl_idx; BTM_TRACE_DEBUG ("btm_read_remote_ext_features_complete\n"); @@ -1133,7 +1144,8 @@ void btm_read_remote_ext_features_complete (UINT8 *p) STREAM_TO_UINT8 (max_page, p); /* Validate parameters */ - if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS) { + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb == NULL) { BTM_TRACE_ERROR("btm_read_remote_ext_features_complete handle=%d invalid\n", handle); return; } @@ -1143,7 +1155,6 @@ void btm_read_remote_ext_features_complete (UINT8 *p) return; } - p_acl_cb = &btm_cb.acl_db[acl_idx]; /* Copy the received features page */ STREAM_TO_ARRAY(p_acl_cb->peer_lmp_features[page_num], p, HCI_FEATURE_BYTES_PER_PAGE); @@ -1180,18 +1191,16 @@ void btm_read_remote_ext_features_complete (UINT8 *p) void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle) { tACL_CONN *p_acl_cb; - UINT8 acl_idx; BTM_TRACE_WARNING ("btm_read_remote_ext_features_failed (status 0x%02x) for handle %d\n", status, handle); - if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS) { + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb == NULL) { BTM_TRACE_ERROR("btm_read_remote_ext_features_failed handle=%d invalid\n", handle); - return; + return; } - p_acl_cb = &btm_cb.acl_db[acl_idx]; - /* Process supported features only */ btm_process_remote_ext_features (p_acl_cb, 1); @@ -1363,12 +1372,7 @@ UINT16 BTM_GetNumAclLinks (void) { uint16_t num_acl = 0; - for (uint16_t i = 0; i < MAX_L2CAP_LINKS; ++i) { - if (btm_cb.acl_db[i].in_use) { - ++num_acl; - } - } - + num_acl = list_length(btm_cb.p_acl_db_list); return num_acl; } @@ -1427,12 +1431,14 @@ UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport) *******************************************************************************/ void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset) { - UINT8 xx; + tACL_CONN *p_acl_cb = NULL; BTM_TRACE_DEBUG ("btm_process_clk_off_comp_evt\n"); /* Look up the connection by handle and set the current mode */ - if ((xx = btm_handle_to_acl_index(hci_handle)) < MAX_L2CAP_LINKS) { - btm_cb.acl_db[xx].clock_offset = clock_offset; + p_acl_cb = btm_handle_to_acl(hci_handle); + if (p_acl_cb) { + p_acl_cb->clock_offset = clock_offset; } + } /******************************************************************************* @@ -1849,7 +1855,7 @@ tBTM_STATUS BTM_RegBusyLevelNotif (tBTM_BL_CHANGE_CB *p_cb, UINT8 *p_level, *******************************************************************************/ tBTM_STATUS BTM_SetQoS (BD_ADDR bd, FLOW_SPEC *p_flow, tBTM_CMPL_CB *p_cb) { - tACL_CONN *p = &btm_cb.acl_db[0]; + tACL_CONN *p = NULL; BTM_TRACE_API ("BTM_SetQoS: BdAddr: %02x%02x%02x%02x%02x%02x\n", bd[0], bd[1], bd[2], @@ -2119,8 +2125,7 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_tx_power_cmpl_cb; tBTM_TX_POWER_RESULTS results; UINT16 handle; - tACL_CONN *p_acl_cb = &btm_cb.acl_db[0]; - UINT16 index; + tACL_CONN *p_acl_cb = NULL; BTM_TRACE_DEBUG ("btm_read_tx_power_complete\n"); btu_stop_timer (&btm_cb.devcb.tx_power_timer); @@ -2138,12 +2143,10 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) STREAM_TO_UINT8 (results.tx_power, p); /* Search through the list of active channels for the correct BD Addr */ - for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) { - if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) { - memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); - break; - } - } + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb) { + memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); + } } #if BLE_INCLUDED == TRUE else { @@ -2176,8 +2179,7 @@ void btm_read_rssi_complete (UINT8 *p) tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_rssi_cmpl_cb; tBTM_RSSI_RESULTS results; UINT16 handle; - tACL_CONN *p_acl_cb = &btm_cb.acl_db[0]; - UINT16 index; + tACL_CONN *p_acl_cb = NULL; BTM_TRACE_DEBUG ("btm_read_rssi_complete\n"); btu_stop_timer (&btm_cb.devcb.rssi_timer); @@ -2197,12 +2199,10 @@ void btm_read_rssi_complete (UINT8 *p) results.rssi, results.hci_status); /* Search through the list of active channels for the correct BD Addr */ - for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) { - if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) { - memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); - break; - } - } + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb) { + memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); + } } else { results.status = BTM_ERR_PROCESSING; } @@ -2226,8 +2226,7 @@ void btm_read_link_quality_complete (UINT8 *p) tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_lnk_qual_cmpl_cb; tBTM_LINK_QUALITY_RESULTS results; UINT16 handle; - tACL_CONN *p_acl_cb = &btm_cb.acl_db[0]; - UINT16 index; + tACL_CONN *p_acl_cb = NULL; BTM_TRACE_DEBUG ("btm_read_link_quality_complete\n"); btu_stop_timer (&btm_cb.devcb.lnk_quality_timer); @@ -2247,12 +2246,10 @@ void btm_read_link_quality_complete (UINT8 *p) results.link_quality, results.hci_status); /* Search through the list of active channels for the correct BD Addr */ - for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) { - if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) { - memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); - break; - } - } + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb) { + memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); + } } else { results.status = BTM_ERR_PROCESSING; } @@ -2553,3 +2550,16 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type) } } } + +/******************************************************************************* +** +** Function btm_acl_free +** +** Description Free acl specific lists from btm control block +** +*******************************************************************************/ +void btm_acl_free(void) +{ + list_free(btm_cb.p_acl_db_list); + list_free(btm_cb.p_pm_mode_db_list); +} diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index a0ab1d30dc..60bb6fb0bd 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -74,7 +74,6 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d tBLE_ADDR_TYPE addr_type, UINT32 auth_mode) { tBTM_SEC_DEV_REC *p_dev_rec; - UINT8 i = 0; tBTM_INQ_INFO *p_info = NULL; BTM_TRACE_DEBUG ("BTM_SecAddBleDevice dev_type=0x%x", dev_type); @@ -85,10 +84,11 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d /* There is no device record, allocate one. * If we can not find an empty spot for this one, let it fail. */ - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) { - if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE)) { - BTM_TRACE_DEBUG ("allocate a new dev rec idx=0x%x ", i ); - p_dev_rec = &btm_cb.sec_dev_rec[i]; + if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) { + p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); + if(p_dev_rec) { + list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); + BTM_TRACE_DEBUG ("allocate a new dev rec idx=0x%x\n", list_length(btm_cb.p_sec_dev_rec_list)); /* Mark this record as in use and initialize */ memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); @@ -104,7 +104,6 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d p_dev_rec->conn_params.slave_latency = BTM_BLE_CONN_PARAM_UNDEF; BTM_TRACE_DEBUG ("hci_handl=0x%x ", p_dev_rec->ble_hci_handle ); - break; } } @@ -312,18 +311,14 @@ void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_A BOOLEAN BTM_IsBleConnection (UINT16 conn_handle) { #if (BLE_INCLUDED == TRUE) - UINT8 xx; tACL_CONN *p; BTM_TRACE_API ("BTM_IsBleConnection: conn_handle: %d", conn_handle); - xx = btm_handle_to_acl_index (conn_handle); - if (xx >= MAX_L2CAP_LINKS) { + p = btm_handle_to_acl(conn_handle); + if (!p) { return FALSE; } - - p = &btm_cb.acl_db[xx]; - return (p->transport == BT_TRANSPORT_LE); #else return FALSE; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c b/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c index 730d7895bc..0f134de8b9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c @@ -236,17 +236,12 @@ void btm_gen_non_resolvable_private_addr (tBTM_BLE_ADDR_CBACK *p_cback, void *p) static void btm_ble_resolve_address_cmpl(void) { tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; - tBTM_SEC_DEV_REC *p_dev_rec = NULL; - BTM_TRACE_EVENT ("btm_ble_resolve_address_cmpl p_mgnt_cb->index = %d", p_mgnt_cb->index); - - if (p_mgnt_cb->index < BTM_SEC_MAX_DEVICE_RECORDS) { - p_dev_rec = &btm_cb.sec_dev_rec[p_mgnt_cb->index]; - } + BTM_TRACE_EVENT ("btm_ble_resolve_address_cmpl p_mgnt_cb->p_dev_rec = 0x%08x", (uint32_t)p_mgnt_cb->p_dev_rec); p_mgnt_cb->busy = FALSE; - (* p_mgnt_cb->p_resolve_cback)(p_dev_rec, p_mgnt_cb->p); + (* p_mgnt_cb->p_resolve_cback)(p_mgnt_cb->p_dev_rec, p_mgnt_cb->p); } /******************************************************************************* ** @@ -360,7 +355,7 @@ BOOLEAN btm_ble_addr_resolvable (BD_ADDR rpa, tBTM_SEC_DEV_REC *p_dev_rec) ** Returns None. ** *******************************************************************************/ -static BOOLEAN btm_ble_match_random_bda(UINT16 rec_index) +static BOOLEAN btm_ble_match_random_bda(tBTM_SEC_DEV_REC *p_dev_rec) { /* use the 3 MSB of bd address as prand */ @@ -370,12 +365,10 @@ static BOOLEAN btm_ble_match_random_bda(UINT16 rec_index) rand[1] = p_mgnt_cb->random_bda[1]; rand[2] = p_mgnt_cb->random_bda[0]; - BTM_TRACE_EVENT("%s rec_index = %d", __func__, rec_index); + BTM_TRACE_EVENT("%s p_dev_rec = 0x%08x", __func__, (uint32_t)p_dev_rec); - if (rec_index < BTM_SEC_MAX_DEVICE_RECORDS) { + { tSMP_ENC output; - tBTM_SEC_DEV_REC *p_dev_rec; - p_dev_rec = &btm_cb.sec_dev_rec[rec_index]; BTM_TRACE_DEBUG("sec_flags = %02x device_type = %d", p_dev_rec->sec_flags, p_dev_rec->device_type); @@ -390,9 +383,6 @@ static BOOLEAN btm_ble_match_random_bda(UINT16 rec_index) // not completed return FALSE; } - } else { /* no match found */ - btm_ble_resolve_address_cmpl(); - return TRUE; } } #endif ///BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE @@ -411,23 +401,26 @@ void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK *p_c { #if (SMP_INCLUDED == TRUE) tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; + list_node_t *p_node = NULL; + tBTM_SEC_DEV_REC *p_dev_rec = NULL; BTM_TRACE_EVENT ("btm_ble_resolve_random_addr"); if ( !p_mgnt_cb->busy) { p_mgnt_cb->p = p; p_mgnt_cb->busy = TRUE; - p_mgnt_cb->index = 0; + p_mgnt_cb->p_dev_rec = NULL; p_mgnt_cb->p_resolve_cback = p_cback; memcpy(p_mgnt_cb->random_bda, random_bda, BD_ADDR_LEN); /* start to resolve random address */ /* check for next security record */ - while (TRUE) { - if (btm_ble_match_random_bda(p_mgnt_cb->index)) { - /* atch found or went through the list */ - break; - } - p_mgnt_cb->index ++; - } + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); + p_mgnt_cb->p_dev_rec = p_dev_rec; + if (btm_ble_match_random_bda(p_dev_rec)) { + break; + } + } + btm_ble_resolve_address_cmpl(); } else { (*p_cback)(NULL, p); } @@ -449,24 +442,23 @@ void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK *p_c tBTM_SEC_DEV_REC *btm_find_dev_by_identity_addr(BD_ADDR bd_addr, UINT8 addr_type) { #if BLE_PRIVACY_SPT == TRUE - UINT8 i; - tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; - - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec ++) { - if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) && - memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) == 0) { - if ((p_dev_rec->ble.static_addr_type & (~BLE_ADDR_TYPE_ID_BIT)) != - (addr_type & (~BLE_ADDR_TYPE_ID_BIT))) { - BTM_TRACE_WARNING("%s find pseudo->random match with diff addr type: %d vs %d", - __func__, p_dev_rec->ble.static_addr_type, addr_type); - } - - /* found the match */ - return p_dev_rec; - } + tBTM_SEC_DEV_REC *p_dev_rec = NULL; + list_node_t *p_node = NULL; + tSecDevContext context; + context.type = SEC_DEV_ID_ADDR; + context.context.p_bd_addr = bd_addr; + context.free_check = FALSE; + p_node = list_foreach(btm_cb.p_sec_dev_rec_list, btm_find_sec_dev_in_list, &context); + if (p_node) { + p_dev_rec = list_node(p_node); + if ((p_dev_rec->ble.static_addr_type & (~BLE_ADDR_TYPE_ID_BIT)) != + (addr_type & (~BLE_ADDR_TYPE_ID_BIT))) { + BTM_TRACE_WARNING("%s find pseudo->random match with diff addr type: %d vs %d", + __func__, p_dev_rec->ble.static_addr_type, addr_type); + } } + return p_dev_rec; #endif - return NULL; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 6644a8cd0e..3b63b48e97 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -1174,6 +1174,7 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, #if BLE_PRIVACY_SPT == TRUE UINT8 i = BTM_SEC_MAX_DEVICE_RECORDS; tBTM_SEC_DEV_REC *p_dev_rec; + list_node_t *p_node = NULL; #endif ///BLE_PRIVACY_SPT == TRUE evt_type = (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) ? \ ((p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT )\ @@ -1217,14 +1218,15 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, if ((btm_cb.ble_ctr_cb.privacy_mode == BTM_PRIVACY_1_2 && p_cb->afp != AP_SCAN_CONN_ALL) || btm_cb.ble_ctr_cb.privacy_mode == BTM_PRIVACY_MIXED) { /* if enhanced privacy is required, set Identity address and matching IRK peer */ - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++) { - if ((btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE) != 0 && - (btm_cb.sec_dev_rec[i].ble.in_controller_list & BTM_RESOLVING_LIST_BIT) != 0) { - memcpy(p_peer_addr_ptr, btm_cb.sec_dev_rec[i].ble.static_addr, BD_ADDR_LEN); - *p_peer_addr_type = btm_cb.sec_dev_rec[i].ble.static_addr_type; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); + if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) != 0 && + (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) != 0) { + memcpy(p_peer_addr_ptr, p_dev_rec->ble.static_addr, BD_ADDR_LEN); + *p_peer_addr_type = p_dev_rec->ble.static_addr_type; break; - } - } + } + } if (i != BTM_SEC_MAX_DEVICE_RECORDS) { *p_own_addr_type = BLE_ADDR_RANDOM_ID; @@ -4130,10 +4132,9 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) *******************************************************************************/ void btm_ble_read_remote_features_complete(UINT8 *p) { - tACL_CONN *p_acl_cb = &btm_cb.acl_db[0]; + tACL_CONN *p_acl_cb = NULL; UINT16 handle; UINT8 status; - int xx; BTM_TRACE_EVENT ("btm_ble_read_remote_features_complete "); @@ -4145,8 +4146,9 @@ void btm_ble_read_remote_features_complete(UINT8 *p) STREAM_TO_UINT16 (handle, p); /* Look up the connection by handle and copy features */ - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++) { - if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle)) { + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb) { + { STREAM_TO_ARRAY(p_acl_cb->peer_le_features, p, BD_FEATURES_LEN); #if BLE_INCLUDED == TRUE /* In the original Bluedroid version, slave need to send LL_VERSION_IND(call btsnd_hcic_rmt_ver_req) @@ -4167,7 +4169,6 @@ void btm_ble_read_remote_features_complete(UINT8 *p) } } #endif - break; } } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c b/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c index b18d68e39a..e70cc51b82 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c @@ -720,9 +720,9 @@ tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id) void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p) { UINT8 sub_event; - UINT8 adv_inst, idx; + UINT8 adv_inst; UINT16 conn_handle; - + tACL_CONN *p_acl_cb = NULL; /* Check if this is a BLE RSSI vendor specific event */ STREAM_TO_UINT8(sub_event, p); len--; @@ -733,11 +733,11 @@ void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p) ++p; STREAM_TO_UINT16(conn_handle, p); - if ((idx = btm_handle_to_acl_index(conn_handle)) != MAX_L2CAP_LINKS) { + if ((p_acl_cb = btm_handle_to_acl(conn_handle)) != NULL) { #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE && adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) { - memcpy(btm_cb.acl_db[idx].conn_addr, btm_multi_adv_cb.p_adv_inst[adv_inst - 1].rpa, + memcpy(p_acl_cb->conn_addr, btm_multi_adv_cb.p_adv_inst[adv_inst - 1].rpa, BD_ADDR_LEN); } #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index 884fa35bd8..d745435206 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -252,9 +252,12 @@ void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len) BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d", __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size); - for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; ++i) { - btm_cb.sec_dev_rec[i].ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT; - } + list_node_t *p_node = NULL; + tBTM_SEC_DEV_REC *p_dev_rec = NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); + p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT; + } } } @@ -932,9 +935,11 @@ void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask) return; } - tBTM_SEC_DEV_REC *p_dev = &btm_cb.sec_dev_rec[0]; - for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev ++) { - if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && + tBTM_SEC_DEV_REC *p_dev = NULL; + list_node_t *p_node = NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev = list_node(p_node); + if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) { btm_ble_enable_resolving_list(rl_mask); return; diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index 9f18f85fc7..5772639821 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -72,10 +72,10 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, if (!p_dev_rec) { /* There is no device record, allocate one. * If we can not find an empty spot for this one, let it fail. */ - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) { - if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE)) { - p_dev_rec = &btm_cb.sec_dev_rec[i]; - + if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) { + p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); + if(p_dev_rec) { + list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); /* Mark this record as in use and initialize */ memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); p_dev_rec->sec_flags = BTM_SEC_IN_USE; @@ -88,7 +88,6 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, /* update conn params, use default value for background connection params */ memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); #endif - break; } } @@ -96,7 +95,6 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, return (FALSE); } } - p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; /* Default value */ p_dev_rec->timestamp = btm_cb.dev_rec_count++; p_dev_rec->remote_secure_connection_previous_state = sc_support; @@ -240,6 +238,69 @@ char *BTM_SecReadDevName (BD_ADDR bd_addr) return (p_name); } + +/******************************************************************************* +** +** Function btm_find_sec_dev_in_list +** +** Description Look for the record in the device database for the record +** with specified address +** +** Returns Pointer to the record or NULL +** +*******************************************************************************/ +BOOLEAN btm_find_sec_dev_in_list (void *p_node_data, void *context) +{ + tBTM_SEC_DEV_REC *p_sec_dev = (tBTM_SEC_DEV_REC *)p_node_data; + BOOLEAN ret = TRUE; + BOOLEAN dev_free = !(p_sec_dev->sec_flags & BTM_SEC_IN_USE); + tSecDevContext *p_context = (tSecDevContext *)context; + + if (dev_free == p_context->free_check) { + switch (p_context->type) { + case SEC_DEV_BDA: + if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->bd_addr, BD_ADDR_LEN)) { + ret = FALSE; + } + break; + case SEC_DEV_HDL: + if (p_context->context.handle == p_sec_dev->hci_handle +#if BLE_INCLUDED == TRUE + || (p_context->context.handle == p_sec_dev->ble_hci_handle) +#endif + ) { + ret = FALSE; + } + break; +#if BLE_PRIVACY_SPT == TRUE + case SEC_DEV_ID_ADDR: + if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->ble.static_addr, BD_ADDR_LEN)) { + ret = FALSE; + } + break; +#endif //BLE_PRIVACY_SPT == TRUE + case SEC_DEV_BTDM_BDA: + if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->bd_addr, BD_ADDR_LEN)) { + ret = FALSE; + } +#if BLE_INCLUDED == TRUE + // If a LE random address is looking for device record + if (!memcmp(p_sec_dev->ble.pseudo_addr, p_context->context.p_bd_addr, BD_ADDR_LEN)) { + ret = FALSE; + } + + if (btm_ble_addr_resolvable(p_context->context.p_bd_addr, p_sec_dev)) { + ret = FALSE; + } +#endif + break; + default: + break; + } + } + return ret; +} + /******************************************************************************* ** ** Function btm_sec_alloc_dev @@ -254,50 +315,26 @@ tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) { tBTM_SEC_DEV_REC *p_dev_rec = NULL; tBTM_INQ_INFO *p_inq_info; - int i; - DEV_CLASS old_cod; - int i_new_entry = BTM_SEC_MAX_DEVICE_RECORDS; - int i_old_entry = BTM_SEC_MAX_DEVICE_RECORDS; BTM_TRACE_EVENT ("btm_sec_alloc_dev\n"); - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) { - /* look for old entry where device details are present */ - if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE) && - (!memcmp (btm_cb.sec_dev_rec[i].bd_addr, bd_addr, BD_ADDR_LEN))) { - i_old_entry = i; - BTM_TRACE_EVENT ("btm_sec_alloc_dev old device found\n"); - break; - } - } - - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) { - if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE)) { - i_new_entry = i; - break; - } - } - - if (i_new_entry == BTM_SEC_MAX_DEVICE_RECORDS) { - p_dev_rec = btm_find_oldest_dev(); - } else { - /* if the old device entry not present go with - new entry */ - if (i_old_entry == BTM_SEC_MAX_DEVICE_RECORDS) { - p_dev_rec = &btm_cb.sec_dev_rec[i_new_entry]; + /* Old devices which are not in use are deleted already */ + /* Allocate new device or reuse the oldest device */ + if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) { + //Max number of devices is not exceeded, allocate new device + p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); + if (p_dev_rec) { + list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); } else { - p_dev_rec = &btm_cb.sec_dev_rec[i_old_entry]; - memcpy (old_cod, p_dev_rec->dev_class, DEV_CLASS_LEN); + return NULL; } } - memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); - - /* Retain the old COD for device */ - if (i_old_entry != BTM_SEC_MAX_DEVICE_RECORDS) { - BTM_TRACE_EVENT ("btm_sec_alloc_dev restoring cod \n"); - memcpy (p_dev_rec->dev_class, old_cod, DEV_CLASS_LEN); - + else { + //Find and reuse the oldest device + p_dev_rec = btm_find_oldest_dev(); } + memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); + p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; /* Default value */ p_dev_rec->sec_flags = BTM_SEC_IN_USE; @@ -374,6 +411,7 @@ void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRANSPORT transport) if(p_dev_rec->sec_flags == BTM_SEC_IN_USE) { p_dev_rec->sec_flags = 0; } + list_remove(btm_cb.p_sec_dev_rec_list, p_dev_rec); } /******************************************************************************* @@ -438,22 +476,19 @@ BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr) *******************************************************************************/ tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle) { - tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; - int i; + tBTM_SEC_DEV_REC *p_dev_rec = NULL; + list_node_t *p_node = NULL; + tSecDevContext context; + context.type = SEC_DEV_HDL; + context.context.handle = handle; + context.free_check = FALSE; - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { - if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) - && ((p_dev_rec->hci_handle == handle) -#if BLE_INCLUDED == TRUE - || (p_dev_rec->ble_hci_handle == handle) -#endif - )) { - return (p_dev_rec); - } + p_node = list_foreach(btm_cb.p_sec_dev_rec_list, btm_find_sec_dev_in_list, &context); + if (p_node) { + p_dev_rec = list_node(p_node); } - return (NULL); + return (p_dev_rec); } - /******************************************************************************* ** ** Function btm_find_dev @@ -466,31 +501,19 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle) *******************************************************************************/ tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr) { - tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; - - if (bd_addr) { - for (uint8_t i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { - if (p_dev_rec->sec_flags & BTM_SEC_IN_USE) { - if (!memcmp (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN)) { - return (p_dev_rec); - } - -#if BLE_INCLUDED == TRUE - // If a LE random address is looking for device record - if (!memcmp(p_dev_rec->ble.pseudo_addr, bd_addr, BD_ADDR_LEN)) { - return (p_dev_rec); - } - - if (btm_ble_addr_resolvable(bd_addr, p_dev_rec)) { - return (p_dev_rec); - } -#endif - } - } + if(bd_addr) { + list_node_t *p_node = NULL; + tSecDevContext context; + context.type = SEC_DEV_BTDM_BDA; + context.context.p_bd_addr = bd_addr; + context.free_check = FALSE; + p_node = list_foreach(btm_cb.p_sec_dev_rec_list, btm_find_sec_dev_in_list, &context); + if (p_node) { + return(list_node(p_node)); + } } return (NULL); } - /******************************************************************************* ** ** Function btm_consolidate_dev @@ -503,12 +526,13 @@ tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr) void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec) { #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; + tBTM_SEC_DEV_REC *p_dev_rec = NULL; tBTM_SEC_DEV_REC temp_rec = *p_target_rec; - + list_node_t *p_node = NULL; BTM_TRACE_DEBUG("%s\n", __func__); - for (uint8_t i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); if (p_target_rec != p_dev_rec && p_dev_rec->sec_flags & BTM_SEC_IN_USE) { if (!memcmp (p_dev_rec->bd_addr, p_target_rec->bd_addr, BD_ADDR_LEN)) { memcpy(p_target_rec, p_dev_rec, sizeof(tBTM_SEC_DEV_REC)); @@ -522,9 +546,8 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec) p_target_rec->new_encryption_key_is_p256 = temp_rec.new_encryption_key_is_p256; p_target_rec->no_smp_on_br = temp_rec.no_smp_on_br; p_target_rec->bond_type = temp_rec.bond_type; - /* mark the combined record as unused */ - p_dev_rec->sec_flags &= ~BTM_SEC_IN_USE; - p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; + /* Remove the unused device from the list */ + list_remove(btm_cb.p_sec_dev_rec_list, p_dev_rec); break; } @@ -533,9 +556,9 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec) if (memcmp(p_target_rec->ble.pseudo_addr, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0) { p_target_rec->ble.ble_addr_type = p_dev_rec->ble.ble_addr_type; p_target_rec->device_type |= p_dev_rec->device_type; - p_dev_rec->sec_flags &= ~BTM_SEC_IN_USE; - p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; - } + /* Remove the unused device from the list */ + list_remove(btm_cb.p_sec_dev_rec_list, p_dev_rec); + } break; } } @@ -578,13 +601,14 @@ tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr) *******************************************************************************/ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) { - tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; - tBTM_SEC_DEV_REC *p_oldest = p_dev_rec; - UINT32 ot = 0xFFFFFFFF; - int i; - + tBTM_SEC_DEV_REC *p_dev_rec = NULL; + tBTM_SEC_DEV_REC *p_oldest = NULL; + list_node_t *p_node = NULL; + UINT32 ot = 0xFFFFFFFF; + /* First look for the non-paired devices for the oldest entry */ - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); if (((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0) || ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LE_LINK_KEY_KNOWN)) != 0)) { continue; /* Device is paired so skip it */ @@ -601,8 +625,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) } /* All devices are paired; find the oldest */ - p_dev_rec = &btm_cb.sec_dev_rec[0]; - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0) { continue; } @@ -614,7 +637,6 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) } return (p_oldest); } - /******************************************************************************* ** ** Function btm_get_bond_type_dev @@ -657,3 +679,27 @@ BOOLEAN btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type) p_dev_rec->bond_type = bond_type; return TRUE; } + +/******************************************************************************* +** +** Function btm_sec_dev_init +** +** Description Create new linked list for dynamic allocation on sec_dev_rec +** +*******************************************************************************/ +void btm_sec_dev_init(void) +{ + btm_cb.p_sec_dev_rec_list = list_new(osi_free_func); +} + +/******************************************************************************* +** +** Function btm_sec_dev_free +** +** Description Delete sec_dev_rec list when btm_cb is being released +** +*******************************************************************************/ +void btm_sec_dev_free(void) +{ + list_free(btm_cb.p_sec_dev_rec_list); +} diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 163a248898..f578e9a458 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -145,8 +145,12 @@ static void reset_complete(void) l2cu_device_reset (); #if (SMP_INCLUDED == TRUE) /* Clear current security state */ - for (int devinx = 0; devinx < BTM_SEC_MAX_DEVICE_RECORDS; devinx++) { - btm_cb.sec_dev_rec[devinx].sec_state = BTM_SEC_STATE_IDLE; + { + list_node_t *p_node = NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + tBTM_SEC_DEV_REC *p_dev_rec = (tBTM_SEC_DEV_REC *) list_node(p_node); + p_dev_rec->sec_state = BTM_SEC_STATE_IDLE; + } } #endif ///SMP_INCLUDED == TRUE /* After the reset controller should restore all parameters to defaults. */ @@ -1158,4 +1162,4 @@ void btm_ble_set_channels_complete (UINT8 *p) (*p_cb)(&results); } } -#endif /// BLE_INCLUDED == TRUE \ No newline at end of file +#endif /// BLE_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/stack/btm/btm_main.c b/components/bt/host/bluedroid/stack/btm/btm_main.c index cf950f21a9..9c13240739 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_main.c +++ b/components/bt/host/bluedroid/stack/btm/btm_main.c @@ -79,6 +79,7 @@ void btm_init (void) btm_ble_lock_init(); btm_ble_sem_init(); #endif + btm_sec_dev_init(); } @@ -95,6 +96,8 @@ void btm_free(void) { fixed_queue_free(btm_cb.page_queue, osi_free_func); fixed_queue_free(btm_cb.sec_pending_q, osi_free_func); + btm_acl_free(); + btm_sec_dev_free(); #if BTM_DYNAMIC_MEMORY FREE_AND_RESET(btm_cb_ptr); #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_pm.c b/components/bt/host/bluedroid/stack/btm/btm_pm.c index 3ea3dfbddd..f7bf6f0cfb 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/components/bt/host/bluedroid/stack/btm/btm_pm.c @@ -44,7 +44,7 @@ #include "stack/hcidefs.h" //#include "bt_utils.h" //#include "osi/include/log.h" - +#include "osi/allocator.h" /*****************************************************************************/ /* to handle different modes */ /*****************************************************************************/ @@ -76,8 +76,7 @@ const UINT8 btm_pm_md_comp_matrix[BTM_PM_NUM_SET_MODES * BTM_PM_NUM_SET_MODES] = }; /* function prototype */ -static int btm_pm_find_acl_ind(BD_ADDR remote_bda); -static tBTM_STATUS btm_pm_snd_md_req( UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD *p_mode ); +static tBTM_STATUS btm_pm_snd_md_req( UINT8 pm_id, UINT16 link_hdl, tBTM_PM_PWR_MD *p_mode ); #if (!CONFIG_BT_STACK_NO_LOG) static const char *mode_to_string(tBTM_PM_MODE mode); #endif @@ -174,11 +173,11 @@ tBTM_STATUS BTM_PmRegister (UINT8 mask, UINT8 *p_pm_id, tBTM_PM_STATUS_CBACK *p_ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p_mode) { UINT8 *p_features; - int ind, acl_ind; + int ind; tBTM_PM_MCB *p_cb = NULL; /* per ACL link */ tBTM_PM_MODE mode; int temp_pm_id; - + tACL_CONN *p_acl_cb; if (pm_id >= BTM_MAX_PM_RECORDS) { pm_id = BTM_PM_SET_ONLY_ID; @@ -194,13 +193,8 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p /* take out the force bit */ mode = p_mode->mode & ~BTM_PM_MD_FORCE; - acl_ind = btm_pm_find_acl_ind(remote_bda); - if (acl_ind == MAX_L2CAP_LINKS) { - return (BTM_UNKNOWN_ADDR); - } - - p_cb = &(btm_cb.pm_mode_db[acl_ind]); - + p_acl_cb = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); + p_cb = p_acl_cb->p_pm_mode_db; if (mode != BTM_PM_MD_ACTIVE) { /* check if the requested mode is supported */ ind = mode - BTM_PM_MD_HOLD; /* make it base 0 */ @@ -228,9 +222,10 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p /* update mode database */ if ( ((pm_id != BTM_PM_SET_ONLY_ID) && (btm_cb.pm_reg_db[pm_id].mask & BTM_PM_REG_SET)) - || ((pm_id == BTM_PM_SET_ONLY_ID) && (btm_cb.pm_pend_link != MAX_L2CAP_LINKS)) ) { + || ((pm_id == BTM_PM_SET_ONLY_ID) + && (btm_cb.pm_pend_link_hdl != BTM_INVALID_HANDLE)) ) { #if BTM_PM_DEBUG == TRUE - BTM_TRACE_DEBUG( "BTM_SetPowerMode: Saving cmd acl_ind %d temp_pm_id %d", acl_ind, temp_pm_id); + BTM_TRACE_DEBUG( "BTM_SetPowerMode: Saving cmd acl handle %d temp_pm_id %d", p_acl_cb->hci_handle, temp_pm_id); #endif // BTM_PM_DEBUG /* Make sure mask is set to BTM_PM_REG_SET */ btm_cb.pm_reg_db[temp_pm_id].mask |= BTM_PM_REG_SET; @@ -239,23 +234,23 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p } #if BTM_PM_DEBUG == TRUE - BTM_TRACE_DEBUG( "btm_pm state:0x%x, pm_pend_link: %d", p_cb->state, btm_cb.pm_pend_link); + BTM_TRACE_DEBUG( "btm_pm state:0x%x, pm_pend_link_hdl: %d", p_cb->state, btm_cb.pm_pend_link_hdl); #endif // BTM_PM_DEBUG /* if mode == hold or pending, return */ if ( (p_cb->state == BTM_PM_STS_HOLD) || (p_cb->state == BTM_PM_STS_PENDING) || - (btm_cb.pm_pend_link != MAX_L2CAP_LINKS) ) { /* command pending */ - if (acl_ind != btm_cb.pm_pend_link) { + (btm_cb.pm_pend_link_hdl != BTM_INVALID_HANDLE) ) { /* command pending */ + if (p_acl_cb->hci_handle != btm_cb.pm_pend_link_hdl) { /* set the stored mask */ p_cb->state |= BTM_PM_STORED_MASK; - BTM_TRACE_DEBUG( "btm_pm state stored:%d", acl_ind); + BTM_TRACE_DEBUG( "btm_pm state stored:%d", p_acl_cb->hci_handle); } return BTM_CMD_STORED; } - return btm_pm_snd_md_req(pm_id, acl_ind, p_mode); + return btm_pm_snd_md_req(pm_id, p_acl_cb->hci_handle, p_mode); } /******************************************************************************* @@ -280,13 +275,12 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p *******************************************************************************/ tBTM_STATUS BTM_ReadPowerMode (BD_ADDR remote_bda, tBTM_PM_MODE *p_mode) { - int acl_ind; - - if ( (acl_ind = btm_pm_find_acl_ind(remote_bda)) == MAX_L2CAP_LINKS) { + tACL_CONN *p_acl_cb = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); + if (!p_acl_cb) { return (BTM_UNKNOWN_ADDR); } - *p_mode = btm_cb.pm_mode_db[acl_ind].state; + *p_mode = p_acl_cb->p_pm_mode_db->state; return BTM_SUCCESS; } @@ -314,21 +308,26 @@ tBTM_STATUS BTM_SetSsrParams (BD_ADDR remote_bda, UINT16 max_lat, #if (BTM_SSR_INCLUDED == TRUE) int acl_ind; tBTM_PM_MCB *p_cb; + tACL_CONN *p_acl_cb = NULL; if ( (acl_ind = btm_pm_find_acl_ind(remote_bda)) == MAX_L2CAP_LINKS) { return (BTM_UNKNOWN_ADDR); } + p_acl_cb = btm_bda_to_acl(remote_bda); + if (!p_acl_cb) { + return (BTM_UNKNOWN_ADDR); + } + p_cb = p_acl_cb->p_pm_mode_db; - if (BTM_PM_STS_ACTIVE == btm_cb.pm_mode_db[acl_ind].state || - BTM_PM_STS_SNIFF == btm_cb.pm_mode_db[acl_ind].state) { - if (btsnd_hcic_sniff_sub_rate(btm_cb.acl_db[acl_ind].hci_handle, max_lat, + if (BTM_PM_STS_ACTIVE == p_cb->state || + BTM_PM_STS_SNIFF == p_cb->state) { + if (btsnd_hcic_sniff_sub_rate(p_acl_cb->hci_handle, max_lat, min_rmt_to, min_loc_to)) { return BTM_SUCCESS; } else { return BTM_NO_RESOURCES; } } - p_cb = &btm_cb.pm_mode_db[acl_ind]; p_cb->max_lat = max_lat; p_cb->min_rmt_to = min_rmt_to; p_cb->min_loc_to = min_loc_to; @@ -364,12 +363,12 @@ void btm_pm_reset(void) btm_cb.pm_reg_db[xx].mask = BTM_PM_REC_NOT_USED; } - if (cb != NULL && btm_cb.pm_pend_link < MAX_L2CAP_LINKS) { - (*cb)(btm_cb.acl_db[btm_cb.pm_pend_link].remote_addr, BTM_PM_STS_ERROR, BTM_DEV_RESET, 0); + if (cb != NULL && btm_cb.pm_pend_link_hdl != BTM_INVALID_HANDLE) { + (*cb)((btm_handle_to_acl(btm_cb.pm_pend_link_hdl))->remote_addr, BTM_PM_STS_ERROR, BTM_DEV_RESET, 0); } /* no command pending */ - btm_cb.pm_pend_link = MAX_L2CAP_LINKS; + btm_cb.pm_pend_link_hdl = BTM_INVALID_HANDLE; } /******************************************************************************* @@ -382,16 +381,23 @@ void btm_pm_reset(void) ** Returns void ** *******************************************************************************/ -void btm_pm_sm_alloc(UINT8 ind) +tBTM_PM_MCB *btm_pm_sm_alloc(void) { - tBTM_PM_MCB *p_db = &btm_cb.pm_mode_db[ind]; /* per ACL link */ - memset (p_db, 0, sizeof(tBTM_PM_MCB)); - p_db->state = BTM_PM_ST_ACTIVE; -#if BTM_PM_DEBUG == TRUE - BTM_TRACE_DEBUG( "btm_pm_sm_alloc ind:%d st:%d", ind, p_db->state); -#endif // BTM_PM_DEBUG + tBTM_PM_MCB *p_db = (tBTM_PM_MCB *) osi_malloc(sizeof(tBTM_PM_MCB)); /* per ACL link */ + if (p_db) { + memset (p_db, 0, sizeof(tBTM_PM_MCB)); + p_db->state = BTM_PM_ST_ACTIVE; + if (list_length(btm_cb.p_pm_mode_db_list) >= MAX_L2CAP_LINKS) { + osi_free(p_db); + p_db = NULL; + } + if (!list_append(btm_cb.p_pm_mode_db_list, p_db)) { + osi_free(p_db); + p_db = NULL; + } + } + return p_db; } - /******************************************************************************* ** ** Function btm_pm_find_acl_ind @@ -402,25 +408,6 @@ void btm_pm_sm_alloc(UINT8 ind) ** Returns void ** *******************************************************************************/ -static int btm_pm_find_acl_ind(BD_ADDR remote_bda) -{ - tACL_CONN *p = &btm_cb.acl_db[0]; - UINT8 xx; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if ((p->in_use) && (!memcmp (p->remote_addr, remote_bda, BD_ADDR_LEN)) -#if (BLE_INCLUDED == TRUE) - && p->transport == BT_TRANSPORT_BR_EDR -#endif // BLE_INCLUDED - ) { -#if BTM_PM_DEBUG == TRUE - BTM_TRACE_DEBUG( "btm_pm_find_acl_ind ind:%d, st:%d", xx, btm_cb.pm_mode_db[xx].state); -#endif // BTM_PM_DEBUG - break; - } - } - return xx; -} /******************************************************************************* ** @@ -557,19 +544,20 @@ static tBTM_PM_MODE btm_pm_get_set_mode(UINT8 pm_id, tBTM_PM_MCB *p_cb, tBTM_PM_ ** Returns tBTM_STATUS **, BOOLEAN *p_chg_ind *******************************************************************************/ -static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD *p_mode) +static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, UINT16 link_hdl, tBTM_PM_PWR_MD *p_mode) { tBTM_PM_PWR_MD md_res; tBTM_PM_MODE mode; - tBTM_PM_MCB *p_cb = &btm_cb.pm_mode_db[link_ind]; + tACL_CONN *p_acl_cb = btm_handle_to_acl(link_hdl); + tBTM_PM_MCB *p_cb = p_acl_cb->p_pm_mode_db; BOOLEAN chg_ind = FALSE; mode = btm_pm_get_set_mode(pm_id, p_cb, p_mode, &md_res); md_res.mode = mode; #if BTM_PM_DEBUG == TRUE - BTM_TRACE_DEBUG( "btm_pm_snd_md_req link_ind:%d, mode: %d", - link_ind, mode); + BTM_TRACE_DEBUG( "btm_pm_snd_md_req link_hdl:%d, mode: %d", + link_hdl, mode); #endif // BTM_PM_DEBUG if ( p_cb->state == mode) { @@ -593,19 +581,19 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD * } #if (BTM_SSR_INCLUDED == TRUE) else if (BTM_PM_MD_SNIFF == md_res.mode && p_cb->max_lat) { - btsnd_hcic_sniff_sub_rate(btm_cb.acl_db[link_ind].hci_handle, p_cb->max_lat, + btsnd_hcic_sniff_sub_rate(link_hdl, p_cb->max_lat, p_cb->min_rmt_to, p_cb->min_loc_to); p_cb->max_lat = 0; } #endif // BTM_SSR_INCLUDED /* Default is failure */ - btm_cb.pm_pend_link = MAX_L2CAP_LINKS; + btm_cb.pm_pend_link_hdl = BTM_INVALID_HANDLE; /* send the appropriate HCI command */ btm_cb.pm_pend_id = pm_id; #if BTM_PM_DEBUG == TRUE - BTM_TRACE_DEBUG("btm_pm_snd_md_req state:0x%x, link_ind: %d", p_cb->state, link_ind); + BTM_TRACE_DEBUG("btm_pm_snd_md_req state:0x%x, link_hdl: %d", p_cb->state, link_hdl); #endif // BTM_PM_DEBUG BTM_TRACE_DEBUG("%s switching from %s to %s.", __func__, mode_to_string(p_cb->state), mode_to_string(md_res.mode)); @@ -613,13 +601,13 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD * case BTM_PM_MD_ACTIVE: switch (p_cb->state) { case BTM_PM_MD_SNIFF: - if (btsnd_hcic_exit_sniff_mode(btm_cb.acl_db[link_ind].hci_handle)) { - btm_cb.pm_pend_link = link_ind; + if (btsnd_hcic_exit_sniff_mode(link_hdl)) { + btm_cb.pm_pend_link_hdl = link_hdl; } break; case BTM_PM_MD_PARK: - if (btsnd_hcic_exit_park_mode(btm_cb.acl_db[link_ind].hci_handle)) { - btm_cb.pm_pend_link = link_ind; + if (btsnd_hcic_exit_park_mode(link_hdl)) { + btm_cb.pm_pend_link_hdl = link_hdl; } break; default: @@ -629,24 +617,24 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD * break; case BTM_PM_MD_HOLD: - if (btsnd_hcic_hold_mode (btm_cb.acl_db[link_ind].hci_handle, + if (btsnd_hcic_hold_mode (link_hdl, md_res.max, md_res.min)) { - btm_cb.pm_pend_link = link_ind; + btm_cb.pm_pend_link_hdl = link_hdl; } break; case BTM_PM_MD_SNIFF: - if (btsnd_hcic_sniff_mode (btm_cb.acl_db[link_ind].hci_handle, + if (btsnd_hcic_sniff_mode (link_hdl, md_res.max, md_res.min, md_res.attempt, md_res.timeout)) { - btm_cb.pm_pend_link = link_ind; + btm_cb.pm_pend_link_hdl = link_hdl; } break; case BTM_PM_MD_PARK: - if (btsnd_hcic_park_mode (btm_cb.acl_db[link_ind].hci_handle, + if (btsnd_hcic_park_mode (link_hdl, md_res.max, md_res.min)) { - btm_cb.pm_pend_link = link_ind; + btm_cb.pm_pend_link_hdl = link_hdl; } break; default: @@ -654,10 +642,10 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD * break; } - if (btm_cb.pm_pend_link == MAX_L2CAP_LINKS) { + if (btm_cb.pm_pend_link_hdl == BTM_INVALID_HANDLE) { /* the command was not sent */ #if BTM_PM_DEBUG == TRUE - BTM_TRACE_DEBUG( "pm_pend_link: %d", btm_cb.pm_pend_link); + BTM_TRACE_DEBUG( "pm_pend_link_hdl: %d", btm_cb.pm_pend_link_hdl); #endif // BTM_PM_DEBUG return (BTM_NO_RESOURCES); } @@ -678,15 +666,18 @@ static tBTM_STATUS btm_pm_snd_md_req(UINT8 pm_id, int link_ind, tBTM_PM_PWR_MD * *******************************************************************************/ static void btm_pm_check_stored(void) { - int xx; - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++) { - if (btm_cb.pm_mode_db[xx].state & BTM_PM_STORED_MASK) { - btm_cb.pm_mode_db[xx].state &= ~BTM_PM_STORED_MASK; - BTM_TRACE_DEBUG( "btm_pm_check_stored :%d", xx); - btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, xx, NULL); + tACL_CONN *p_acl_cb = NULL; + list_node_t *p_node = NULL; + for (p_node = list_begin(btm_cb.p_acl_db_list); p_node; p_node = list_next(p_node)) { + p_acl_cb = list_node(p_node); + if (p_acl_cb->p_pm_mode_db->state & BTM_PM_STORED_MASK) { + p_acl_cb->p_pm_mode_db->state &= ~BTM_PM_STORED_MASK; + BTM_TRACE_DEBUG( "btm_pm_check_stored :%d", p_acl_cb->hci_handle); + btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, p_acl_cb->hci_handle, NULL); break; } } + } @@ -706,12 +697,15 @@ void btm_pm_proc_cmd_status(UINT8 status) { tBTM_PM_MCB *p_cb; tBTM_PM_STATUS pm_status; + tACL_CONN *p_acl_cb; - if (btm_cb.pm_pend_link >= MAX_L2CAP_LINKS) { + if (btm_cb.pm_pend_link_hdl == BTM_INVALID_HANDLE) { return; } - p_cb = &btm_cb.pm_mode_db[btm_cb.pm_pend_link]; + + p_acl_cb = btm_handle_to_acl(btm_cb.pm_pend_link_hdl); + p_cb = p_acl_cb->p_pm_mode_db; if (status == HCI_SUCCESS) { p_cb->state = BTM_PM_ST_PENDING; @@ -726,15 +720,15 @@ void btm_pm_proc_cmd_status(UINT8 status) /* notify the caller is appropriate */ if ( (btm_cb.pm_pend_id != BTM_PM_SET_ONLY_ID) && (btm_cb.pm_reg_db[btm_cb.pm_pend_id].mask & BTM_PM_REG_NOTIF) ) { - (*btm_cb.pm_reg_db[btm_cb.pm_pend_id].cback)(btm_cb.acl_db[btm_cb.pm_pend_link].remote_addr, pm_status, 0, status); + (*btm_cb.pm_reg_db[btm_cb.pm_pend_id].cback)(p_acl_cb->remote_addr, pm_status, 0, status); } /* no pending cmd now */ #if BTM_PM_DEBUG == TRUE BTM_TRACE_DEBUG( "btm_pm_proc_cmd_status state:0x%x, pm_pend_link: %d(new: %d)", - p_cb->state, btm_cb.pm_pend_link, MAX_L2CAP_LINKS); + p_cb->state, btm_cb.pm_pend_link_hdl, MAX_L2CAP_LINKS); #endif // BTM_PM_DEBUG - btm_cb.pm_pend_link = MAX_L2CAP_LINKS; + btm_cb.pm_pend_link_hdl = BTM_INVALID_HANDLE; btm_pm_check_stored(); } @@ -757,19 +751,18 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U { tACL_CONN *p; tBTM_PM_MCB *p_cb = NULL; - int xx, yy, zz; + int yy; tBTM_PM_STATE old_state; tL2C_LCB *p_lcb; /* get the index to acl_db */ - if ((xx = btm_handle_to_acl_index(hci_handle)) >= MAX_L2CAP_LINKS) { + p = btm_handle_to_acl(hci_handle); + if (!p) { return; } - p = &btm_cb.acl_db[xx]; - /* update control block */ - p_cb = &(btm_cb.pm_mode_db[xx]); + p_cb = p->p_pm_mode_db; old_state = p_cb->state; p_cb->state = mode; p_cb->interval = interval; @@ -798,14 +791,17 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U #if BTM_PM_DEBUG == TRUE BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending stored req:%d", xx); #endif // BTM_PM_DEBUG - btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, xx, NULL); + btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL); } else { - for (zz = 0; zz < MAX_L2CAP_LINKS; zz++) { - if (btm_cb.pm_mode_db[zz].chg_ind == TRUE) { + list_node_t *p_node = NULL; + + for (p_node =(list_begin(btm_cb.p_pm_mode_db_list)); p_node; p_node = (list_next(p_node))) { + p_cb = (tBTM_PM_MCB *)list_node(p_node); + if (p_cb->chg_ind == TRUE) { #if BTM_PM_DEBUG == TRUE BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending PM req :%d", zz); #endif // BTM_PM_DEBUG - btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, zz, NULL); + btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL); break; } } @@ -848,15 +844,14 @@ void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len) STREAM_TO_UINT16 (handle, p); /* get the index to acl_db */ - if ((xx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS) { - return; - } p += 2; STREAM_TO_UINT16 (max_rx_lat, p); - p_cb = &(btm_cb.pm_mode_db[xx]); - - p_acl = &btm_cb.acl_db[xx]; + p_acl = btm_handle_to_acl(handle); + if (!p_acl) { + return; + } + p_cb = p_acl->p_pm_mode_db; if (p_cb->interval == max_rx_lat) { /* using legacy sniff */ use_ssr = FALSE; diff --git a/components/bt/host/bluedroid/stack/btm/btm_sco.c b/components/bt/host/bluedroid/stack/btm/btm_sco.c index 0b05b18ba3..4db42024b6 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sco.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sco.c @@ -481,7 +481,6 @@ static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle, tBTM_ESCO_PARAMS *p_setup) { UINT16 temp_pkt_types; - UINT8 xx; tACL_CONN *p_acl; /* Send connect request depending on version of spec */ @@ -499,9 +498,8 @@ static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle, /* Finally, remove EDR eSCO if the remote device doesn't support it */ /* UPF25: Only SCO was brought up in this case */ - btm_handle_to_acl_index(acl_handle); - if ((xx = btm_handle_to_acl_index(acl_handle)) < MAX_L2CAP_LINKS) { - p_acl = &btm_cb.acl_db[xx]; + p_acl = btm_handle_to_acl(acl_handle); + if (p_acl) { if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) { BTM_TRACE_WARNING("BTM Remote does not support 2-EDR eSCO"); diff --git a/components/bt/host/bluedroid/stack/btm/btm_sec.c b/components/bt/host/bluedroid/stack/btm/btm_sec.c index 2e2ed582b9..cf13e5d7e7 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sec.c @@ -2971,7 +2971,7 @@ static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec) #if (SMP_INCLUDED == TRUE) void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT8 status) { - tBTM_SEC_DEV_REC *p_dev_rec; + tBTM_SEC_DEV_REC *p_dev_rec = NULL; int i; DEV_CLASS dev_class; UINT8 old_sec_state; @@ -2987,19 +2987,18 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT if (p_bd_addr) { p_dev_rec = btm_find_dev (p_bd_addr); } else { - p_dev_rec = &btm_cb.sec_dev_rec[0]; - - for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { + list_node_t *p_node = NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) && (p_dev_rec->sec_state == BTM_SEC_STATE_GETTING_NAME)) { p_bd_addr = p_dev_rec->bd_addr; break; } - } - - if (i == BTM_SEC_MAX_DEVICE_RECORDS) { - p_dev_rec = NULL; - } + } + if (!p_bd_addr) { + p_dev_rec = NULL; + } } @@ -4051,7 +4050,6 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle); #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE tACL_CONN *p_acl = NULL; - UINT8 acl_idx = btm_handle_to_acl_index(handle); #endif BTM_TRACE_EVENT ("Security Manager: encrypt_change status:%d State:%d, encr_enable = %d\n", status, (p_dev_rec) ? p_dev_rec->sec_state : 0, encr_enable); @@ -4096,9 +4094,7 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) BTM_TRACE_DEBUG ("after update p_dev_rec->sec_flags=0x%x\n", p_dev_rec->sec_flags ); #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - if (acl_idx != MAX_L2CAP_LINKS) { - p_acl = &btm_cb.acl_db[acl_idx]; - } + p_acl = btm_handle_to_acl(handle); if (p_acl != NULL) { btm_sec_check_pending_enc_req(p_dev_rec, p_acl->transport, encr_enable); @@ -5649,10 +5645,11 @@ static void btm_restore_mode(void) tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state) { #if (SMP_INCLUDED == TRUE) - tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; - - for (int i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { - if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) + tBTM_SEC_DEV_REC *p_dev_rec = NULL; + list_node_t *p_node = NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); + if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) && (p_dev_rec->sec_state == state)) { return (p_dev_rec); } @@ -5660,7 +5657,6 @@ tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state) #endif ///SMP_INCLUDED == TRUE return (NULL); } - /******************************************************************************* ** ** Function btm_sec_change_pairing_state @@ -6148,22 +6144,17 @@ BOOLEAN btm_sec_is_le_capable_dev (BD_ADDR bda) ** *******************************************************************************/ #if (BLE_INCLUDED == TRUE) -BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT8 *p_found_idx, tBTM_SEC_DEV_REC **p_rec) +BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT16 *p_found_handle, tBTM_SEC_DEV_REC **p_rec) { BOOLEAN found = FALSE; #if (SMP_INCLUDED== TRUE) tBTM_SEC_DEV_REC *p_dev_rec; - int i; - if (start_idx >= BTM_SEC_MAX_DEVICE_RECORDS) { - BTM_TRACE_DEBUG ("LE bonded device not found\n"); - return found; - } - - p_dev_rec = &btm_cb.sec_dev_rec[start_idx]; - for (i = start_idx; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { + list_node_t *p_node = NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); if (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)) { - *p_found_idx = i; + *p_found_handle = p_dev_rec->hci_handle; *p_rec = p_dev_rec; break; } diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 4fc915e471..a7c97735c2 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -192,7 +192,7 @@ typedef struct { BD_ADDR private_addr; BD_ADDR random_bda; BOOLEAN busy; - UINT16 index; + tBTM_SEC_DEV_REC *p_dev_rec; tBTM_BLE_RESOLVE_CBACK *p_resolve_cback; tBTM_BLE_ADDR_CBACK *p_generate_cback; void *p; diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index abfcb82842..184cd16d1b 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -25,6 +25,8 @@ #ifndef BTM_INT_H #define BTM_INT_H +typedef struct tBTM_SEC_DEV_REC tBTM_SEC_DEV_REC; + #include "common/bt_defs.h" #include "common/bt_target.h" #include "stack/hcidefs.h" @@ -75,6 +77,36 @@ typedef char tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1]; #define BTM_IS_BRCM_CONTROLLER() (controller_get_interface()->get_bt_version()->manufacturer == LMP_COMPID_BROADCOM) +typedef struct t_acl_db_param{ +#define ACL_DB_HANDLE 0x00 +#define ACL_DB_BDA 0x01 + UINT8 type; + void *p_data1; + void *p_data2; +}tACL_DB_PARAM; + +enum { + BTM_PM_ST_ACTIVE = BTM_PM_STS_ACTIVE, + BTM_PM_ST_HOLD = BTM_PM_STS_HOLD, + BTM_PM_ST_SNIFF = BTM_PM_STS_SNIFF, + BTM_PM_ST_PARK = BTM_PM_STS_PARK, + BTM_PM_ST_PENDING = BTM_PM_STS_PENDING +}; +typedef UINT8 tBTM_PM_STATE; + +typedef struct { + tBTM_PM_PWR_MD req_mode[BTM_MAX_PM_RECORDS + 1]; /* the desired mode and parameters of the connection*/ + tBTM_PM_PWR_MD set_mode; /* the mode and parameters sent down to the host controller. */ + UINT16 interval; /* the interval from last mode change event. */ +#if (BTM_SSR_INCLUDED == TRUE) + UINT16 max_lat; /* stored SSR maximum latency */ + UINT16 min_rmt_to;/* stored SSR minimum remote timeout */ + UINT16 min_loc_to;/* stored SSR minimum local timeout */ +#endif + tBTM_PM_STATE state; /* contains the current mode of the connection */ + BOOLEAN chg_ind; /* a request change indication */ +} tBTM_PM_MCB; + /* Define the ACL Management control structure */ typedef struct { @@ -127,6 +159,7 @@ BD_FEATURES peer_le_features; /* Peer LE Used features mask for the de tBTM_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback; tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS data_length_params; #endif +tBTM_PM_MCB *p_pm_mode_db; /* Pointer to PM mode control block per ACL link */ } tACL_CONN; @@ -538,7 +571,7 @@ typedef UINT8 tBTM_BOND_TYPE; ** Define structure for Security Device Record. ** A record exists for each device authenticated with this device */ -typedef struct { +struct tBTM_SEC_DEV_REC{ tBTM_SEC_SERV_REC *p_cur_service; tBTM_SEC_CALLBACK *p_callback; void *p_ref_data; @@ -647,7 +680,7 @@ typedef struct { #define BTM_SEC_NO_LAST_SERVICE_ID 0 UINT8 last_author_service_id; /* ID of last serviced authorized: Reset after each l2cap connection */ BOOLEAN enc_init_by_we; -} tBTM_SEC_DEV_REC; +}; #define BTM_SEC_IS_SM4(sm) ((BOOLEAN)(BTM_SM4_TRUE == ((sm)&BTM_SM4_TRUE))) #define BTM_SEC_IS_SM4_LEGACY(sm) ((BOOLEAN)(BTM_SM4_KNOWN == ((sm)&BTM_SM4_TRUE))) @@ -669,15 +702,6 @@ typedef struct { UINT8 def_inq_scan_mode; /* ??? limited/general/none */ } tBTM_CFG; -enum { - BTM_PM_ST_ACTIVE = BTM_PM_STS_ACTIVE, - BTM_PM_ST_HOLD = BTM_PM_STS_HOLD, - BTM_PM_ST_SNIFF = BTM_PM_STS_SNIFF, - BTM_PM_ST_PARK = BTM_PM_STS_PARK, - BTM_PM_ST_PENDING = BTM_PM_STS_PENDING -}; -typedef UINT8 tBTM_PM_STATE; - enum { BTM_PM_SET_MODE_EVT, /* Set power mode API is called. */ BTM_PM_UPDATE_EVT, @@ -707,19 +731,6 @@ typedef struct { UINT8 link_ind; } tBTM_PM_SM_DATA; -typedef struct { - tBTM_PM_PWR_MD req_mode[BTM_MAX_PM_RECORDS + 1]; /* the desired mode and parameters of the connection*/ - tBTM_PM_PWR_MD set_mode; /* the mode and parameters sent down to the host controller. */ - UINT16 interval; /* the interval from last mode change event. */ -#if (BTM_SSR_INCLUDED == TRUE) - UINT16 max_lat; /* stored SSR maximum latency */ - UINT16 min_rmt_to;/* stored SSR minimum remote timeout */ - UINT16 min_loc_to;/* stored SSR minimum local timeout */ -#endif - tBTM_PM_STATE state; /* contains the current mode of the connection */ - BOOLEAN chg_ind; /* a request change indication */ -} tBTM_PM_MCB; - #define BTM_PM_REC_NOT_USED 0 typedef struct { tBTM_PM_STATUS_CBACK *cback;/* to notify the registered party of mode change event */ @@ -798,13 +809,15 @@ typedef BOOLEAN CONNECTION_TYPE; #define BTM_STATE_BUFFER_SIZE 5 /* size of state buffer */ +#define BTM_INVALID_HANDLE 0xFFFF + typedef struct { tBTM_CFG cfg; /* Device configuration */ /**************************************************** ** ACL Management ****************************************************/ - tACL_CONN acl_db[MAX_L2CAP_LINKS]; + list_t *p_acl_db_list; #if (CLASSIC_BT_INCLUDED == TRUE) UINT8 btm_scn[BTM_MAX_SCN]; /* current SCNs: TRUE if SCN is in use */ #endif ///CLASSIC_BT_INCLUDED == TRUE @@ -817,10 +830,10 @@ typedef struct { /**************************************************** ** Power Management ****************************************************/ - tBTM_PM_MCB pm_mode_db[MAX_L2CAP_LINKS]; /* per ACL link */ + list_t *p_pm_mode_db_list; tBTM_PM_RCB pm_reg_db[BTM_MAX_PM_RECORDS + 1]; /* per application/module */ - UINT8 pm_pend_link; /* the index of acl_db, which has a pending PM cmd */ - UINT8 pm_pend_id; /* the id pf the module, which has a pending PM cmd */ + UINT16 pm_pend_link_hdl; /* the index of acl_db, which has a pending PM cmd */ + UINT8 pm_pend_id; /* the id pf the module, which has a pending PM cmd */ /***************************************************** ** Device control @@ -902,7 +915,7 @@ typedef struct { #if SMP_INCLUDED == TRUE || CLASSIC_BT_INCLUDED == TRUE tBTM_SEC_SERV_REC sec_serv_rec[BTM_SEC_MAX_SERVICE_RECORDS]; #endif // SMP_INCLUDED == TRUE || BT_CLASSIC_ENABLED == TRUE - tBTM_SEC_DEV_REC sec_dev_rec[BTM_SEC_MAX_DEVICE_RECORDS]; + list_t *p_sec_dev_rec_list; tBTM_SEC_SERV_REC *p_out_serv; tBTM_MKEY_CALLBACK *mkey_cback; @@ -952,6 +965,19 @@ extern tBTM_CB *btm_cb_ptr; #define btm_cb (*btm_cb_ptr) #endif +typedef struct tSecDevContext { +#define SEC_DEV_BTDM_BDA 0x01 +#define SEC_DEV_BDA 0x02 +#define SEC_DEV_HDL 0x03 +#define SEC_DEV_ID_ADDR 0x04 + UINT8 type; + BOOLEAN free_check; + union { + BD_ADDR_PTR p_bd_addr; + UINT16 handle; + }context; +}tSecDevContext; + /* Internal functions provided by btm_main.c ******************************************** */ @@ -987,6 +1013,7 @@ BOOLEAN btm_lookup_eir(BD_ADDR_PTR p_rem_addr); /* Internal functions provided by btm_acl.c ******************************************** */ +void btm_acl_free(void); void btm_acl_init (void); void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, UINT16 hci_handle, UINT8 link_role, tBT_TRANSPORT transport); @@ -998,7 +1025,6 @@ void btm_cont_rswitch (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec, UINT8 hci_status); -UINT8 btm_handle_to_acl_index (UINT16 hci_handle); tACL_CONN *btm_handle_to_acl (UINT16 hci_handle); void btm_read_link_policy_complete (UINT8 *p); void btm_read_rssi_complete (UINT8 *p); @@ -1025,7 +1051,7 @@ tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport); BOOLEAN btm_acl_notif_conn_collision (BD_ADDR bda); void btm_pm_reset(void); -void btm_pm_sm_alloc(UINT8 ind); +tBTM_PM_MCB *btm_pm_sm_alloc(void); void btm_pm_proc_cmd_status(UINT8 status); void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, UINT16 interval); @@ -1103,6 +1129,8 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle); tBTM_BOND_TYPE btm_get_bond_type_dev(BD_ADDR bd_addr); BOOLEAN btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type); +void btm_sec_dev_init(void); +void btm_sec_dev_free(void); /* Internal functions provided by btm_sec.c ********************************************** @@ -1142,7 +1170,7 @@ void btm_sec_set_peer_sec_caps (tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec #if BLE_INCLUDED == TRUE void btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC *p_dev_rec); -BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT8 *p_found_idx, tBTM_SEC_DEV_REC **p_rec); +BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT16 *p_found_handle, tBTM_SEC_DEV_REC **p_rec); BOOLEAN btm_sec_is_a_bonded_dev (BD_ADDR bda); void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec); BOOLEAN btm_sec_is_le_capable_dev (BD_ADDR bda); @@ -1180,6 +1208,7 @@ void btm_ble_lock_free(void); void btm_sec_handle_remote_legacy_auth_cmp(UINT16 handle); void btm_sec_update_legacy_auth_state(tACL_CONN *p_acl_cb, UINT8 legacy_auth_state); BOOLEAN btm_sec_legacy_authentication_mutual (tBTM_SEC_DEV_REC *p_dev_rec); +BOOLEAN btm_find_sec_dev_in_list (void *p_node_data, void *context); /* #ifdef __cplusplus diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 473250a59c..f686f8f4e4 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -1242,7 +1242,6 @@ void GATT_Deregister (tGATT_IF gatt_if) tGATT_REG *p_reg = gatt_get_regcb(gatt_if); tGATT_TCB *p_tcb; tGATT_CLCB *p_clcb; - UINT8 i, j; #if (GATTS_INCLUDED == TRUE) UINT8 ii; tGATT_SR_REG *p_sreg; @@ -1269,7 +1268,9 @@ void GATT_Deregister (tGATT_IF gatt_if) #endif ///GATTS_INCLUDED == TRUE /* When an application deregisters, check remove the link associated with the app */ - for (i = 0, p_tcb = gatt_cb.tcb; i < GATT_MAX_PHY_CHANNEL; i++, p_tcb++) { + list_node_t *p_node = NULL; + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); if (p_tcb->in_use) { if (gatt_get_ch_state(p_tcb) != GATT_CH_CLOSE) { gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); @@ -1279,7 +1280,9 @@ void GATT_Deregister (tGATT_IF gatt_if) } } - for (j = 0, p_clcb = &gatt_cb.clcb[j]; j < GATT_CL_MAX_LCB; j++, p_clcb++) { + list_node_t *p_node = NULL; + for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) { + p_clcb = list_node(p_node); if (p_clcb->in_use && (p_clcb->p_reg->gatt_if == gatt_if) && (p_clcb->p_tcb->tcb_idx == p_tcb->tcb_idx)) { @@ -1508,7 +1511,7 @@ tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr) start_idx = 0; BD_ADDR addr; while (gatt_find_the_connected_bda(start_idx, addr, &found_idx, &transport)) { - p_tcb = &gatt_cb.tcb[found_idx]; + p_tcb = gatt_get_tcb_by_idx(found_idx); srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb); if (!srv_chg_ind_pending) { diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index fd300b3814..34715bc44e 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -96,12 +96,15 @@ tGATT_DEFAULT gatt_default; void gatt_init (void) { tL2CAP_FIXED_CHNL_REG fixed_reg; + #if GATT_DYNAMIC_MEMORY gatt_cb_ptr = (tGATT_CB *)osi_malloc(sizeof(tGATT_CB)); #endif /* #if GATT_DYNAMIC_MEMORY */ memset (&gatt_cb, 0, sizeof(tGATT_CB)); memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG)); + gatt_cb.p_clcb_list = list_new(osi_free_func); + gatt_cb.p_tcb_list = list_new(osi_free_func); #if defined(GATT_INITIAL_TRACE_LEVEL) gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL; #else @@ -167,25 +170,31 @@ void gatt_free(void) fixed_queue_free(gatt_cb.pending_new_srv_start_q, NULL); gatt_cb.pending_new_srv_start_q = NULL; - for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) - { - fixed_queue_free(gatt_cb.tcb[i].pending_enc_clcb, NULL); - gatt_cb.tcb[i].pending_enc_clcb = NULL; + list_node_t *p_node = NULL; + tGATT_TCB *p_tcb = NULL; + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); + fixed_queue_free(p_tcb->pending_enc_clcb, NULL); + p_tcb->pending_enc_clcb = NULL; - fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL); - gatt_cb.tcb[i].pending_ind_q = NULL; + fixed_queue_free(p_tcb->pending_ind_q, NULL); + p_tcb->pending_ind_q = NULL; - btu_free_timer(&gatt_cb.tcb[i].conf_timer_ent); - memset(&gatt_cb.tcb[i].conf_timer_ent, 0, sizeof(TIMER_LIST_ENT)); + btu_free_timer(&p_tcb->conf_timer_ent); + memset(&p_tcb->conf_timer_ent, 0, sizeof(TIMER_LIST_ENT)); - btu_free_timer(&gatt_cb.tcb[i].ind_ack_timer_ent); - memset(&gatt_cb.tcb[i].ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT)); + btu_free_timer(&p_tcb->ind_ack_timer_ent); + memset(&p_tcb->ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT)); #if (GATTS_INCLUDED == TRUE) - fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL); - gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL; + fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL); + p_tcb->sr_cmd.multi_rsp_q = NULL; #endif /* #if (GATTS_INCLUDED == TRUE) */ } + list_free(gatt_cb.p_tcb_list); +#if (GATTC_INCLUDED == TRUE) + list_free(gatt_cb.p_clcb_list); +#endif //(GATTC_INCLUDED == TRUE) #if (GATTS_INCLUDED == TRUE) for (i = 0; i < GATT_MAX_SR_PROFILES; i++) { @@ -392,7 +401,7 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_a GATT_TRACE_ERROR("gatt_connect failed"); fixed_queue_free(p_tcb->pending_enc_clcb, NULL); fixed_queue_free(p_tcb->pending_ind_q, NULL); - memset(p_tcb, 0, sizeof(tGATT_TCB)); + gatt_tcb_free(p_tcb); } else { ret = TRUE; } @@ -1146,8 +1155,8 @@ void gatt_proc_srv_chg (void) gatt_set_srv_chg(); start_idx = 0; while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) { - p_tcb = &gatt_cb.tcb[found_idx]; - srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb); + p_tcb = gatt_get_tcb_by_idx(found_idx); + srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb); if (!srv_chg_ind_pending) { gatt_send_srv_chg_ind(bda); diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index d6f339cf3d..07daab0dae 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -78,6 +78,7 @@ static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x0 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static UINT32 gatt_tcb_id; /******************************************************************************* ** @@ -779,27 +780,27 @@ BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIS BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, tBT_TRANSPORT *p_transport) { - UINT8 i; BOOLEAN found = FALSE; GATT_TRACE_DEBUG("gatt_find_the_connected_bda start_idx=%d", start_idx); - - for (i = start_idx ; i < GATT_MAX_PHY_CHANNEL; i ++) { - if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) { - memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN); - *p_found_idx = i; - *p_transport = gatt_cb.tcb[i].transport; + tGATT_TCB *p_tcb = NULL; + list_node_t *p_node = NULL; + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); + if (p_tcb->in_use && p_tcb->ch_state == GATT_CH_OPEN) { + memcpy( bda, p_tcb->peer_bda, BD_ADDR_LEN); + *p_found_idx = p_tcb->tcb_idx; + *p_transport = p_tcb->transport; found = TRUE; GATT_TRACE_DEBUG("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x", bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); break; } } - GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found, i); + GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found, p_tcb->tcb_idx); return found; } - /******************************************************************************* ** ** Function gatt_is_srv_chg_ind_pending @@ -883,19 +884,19 @@ tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda) *******************************************************************************/ BOOLEAN gatt_is_bda_connected(BD_ADDR bda) { - UINT8 i = 0; BOOLEAN connected = FALSE; - - for ( i = 0; i < GATT_MAX_PHY_CHANNEL; i ++) { - if (gatt_cb.tcb[i].in_use && - !memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN)) { + tGATT_TCB *p_tcb = NULL; + list_node_t *p_node = NULL; + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); + if (p_tcb->in_use && + !memcmp(p_tcb->peer_bda, bda, BD_ADDR_LEN)) { connected = TRUE; break; } } return connected; } - /******************************************************************************* ** ** Function gatt_find_i_tcb_by_addr @@ -908,17 +909,19 @@ BOOLEAN gatt_is_bda_connected(BD_ADDR bda) UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) { UINT8 i = 0; - - for ( ; i < GATT_MAX_PHY_CHANNEL; i ++) { - if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) && - gatt_cb.tcb[i].transport == transport) { + list_node_t *p_node = NULL; + tGATT_TCB *p_tcb = NULL; + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); + if (!memcmp(p_tcb->peer_bda, bda, BD_ADDR_LEN) && + p_tcb->transport == transport) { + i = p_tcb->tcb_idx; return i; } } return GATT_INDEX_INVALID; } - /******************************************************************************* ** ** Function gatt_get_tcb_by_idx @@ -930,10 +933,13 @@ UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) *******************************************************************************/ tGATT_TCB *gatt_get_tcb_by_idx(UINT8 tcb_idx) { - tGATT_TCB *p_tcb = NULL; - - if ( (tcb_idx < GATT_MAX_PHY_CHANNEL) && gatt_cb.tcb[tcb_idx].in_use) { - p_tcb = &gatt_cb.tcb[tcb_idx]; + tGATT_TCB *p_tcb = NULL; + list_node_t *p_node = NULL; + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); + if ( (tcb_idx < GATT_MAX_PHY_CHANNEL) && p_tcb->in_use && p_tcb->tcb_idx == tcb_idx ) { + break; + } } return p_tcb; @@ -954,7 +960,7 @@ tGATT_TCB *gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) UINT8 i = 0; if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID) { - p_tcb = &gatt_cb.tcb[i]; + p_tcb = gatt_get_tcb_by_idx(i); } return p_tcb; @@ -973,7 +979,7 @@ UINT8 gatt_find_i_tcb_free(void) UINT8 i = 0, j = GATT_INDEX_INVALID; for (i = 0; i < GATT_MAX_PHY_CHANNEL; i ++) { - if (!gatt_cb.tcb[i].in_use) { + if (!((1 << i) & gatt_tcb_id)) { j = i; break; } @@ -982,6 +988,48 @@ UINT8 gatt_find_i_tcb_free(void) } /******************************************************************************* ** +** Function gatt_tcb_alloc +** +** Description The function allocates tcb for given tcb_idx and update tcb_id +** +** Returns Allocated tcb block +** +*******************************************************************************/ +tGATT_TCB *gatt_tcb_alloc(UINT8 tcb_idx) +{ + /* Allocate tcb block */ + tGATT_TCB *p_tcb = (tGATT_TCB *)osi_malloc(sizeof(tGATT_TCB)); + if (p_tcb && list_length(gatt_cb.p_tcb_list) < GATT_MAX_PHY_CHANNEL) { + memset(p_tcb, 0, sizeof(tGATT_TCB)); + /* Add tcb block to list in gatt_cb */ + list_append(gatt_cb.p_tcb_list, p_tcb); + /* Update tcb id */ + gatt_tcb_id |= 1 << tcb_idx; + } else if(p_tcb) { + osi_free(p_tcb); + p_tcb = NULL; + } + return p_tcb; +} + +/******************************************************************************* +** +** Function gatt_tcb_free +** +** Description The function free the given tcb block and update tcb id +** +** Returns void +** +*******************************************************************************/ +void gatt_tcb_free( tGATT_TCB *p_tcb) +{ + UINT8 tcb_idx = p_tcb->tcb_idx; + if (list_remove(gatt_cb.p_tcb_list, p_tcb)) { + gatt_tcb_id &= ~(1 << tcb_idx); + } +} +/******************************************************************************* +** ** Function gatt_allocate_tcb_by_bdaddr ** ** Description The function locate or allocate new tcb entry for matching bda. @@ -1003,8 +1051,10 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) allocated = TRUE; } if (i != GATT_INDEX_INVALID) { - p_tcb = &gatt_cb.tcb[i]; - + p_tcb = gatt_tcb_alloc(i); + if (!p_tcb) { + return NULL; + } if (allocated) { memset(p_tcb, 0, sizeof(tGATT_TCB)); p_tcb->pending_enc_clcb = fixed_queue_new(QUEUE_SIZE_MAX); @@ -1216,7 +1266,7 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 * *******************************************************************************/ void gatt_start_rsp_timer(UINT16 clcb_idx) { - tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx]; + tGATT_CLCB *p_clcb = gatt_clcb_find_by_idx(clcb_idx); UINT32 timeout = GATT_WAIT_FOR_RSP_TOUT; p_clcb->rsp_timer_ent.param = (TIMER_PARAM_TYPE)p_clcb; if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && @@ -1625,19 +1675,65 @@ tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if) BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id) { - UINT8 i = 0; BOOLEAN is_allocated = FALSE; - for (i = 0; i < GATT_CL_MAX_LCB; i++) { - if (gatt_cb.clcb[i].in_use && (gatt_cb.clcb[i].conn_id == conn_id)) { - is_allocated = TRUE; - break; - } + tGATT_CLCB *p_clcb = gatt_clcb_find_by_conn_id(conn_id); + if (p_clcb) { + is_allocated = TRUE; } - return is_allocated; } +/******************************************************************************* +** +** Function gatt_clcb_find_by_conn_id +** +** Description Find clcb block using clcb_idx stored at the time of alloc +** +** Returns pointer to clcb corresponding to conn_id +** +*******************************************************************************/ + +tGATT_CLCB *gatt_clcb_find_by_conn_id(UINT16 conn_id) +{ + list_node_t *p_node = NULL; + tGATT_CLCB *p_clcb = NULL; + tGATT_CLCB *p_clcb_ret = NULL; + for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) { + p_clcb = list_node(p_node); + if (p_clcb->conn_id == conn_id) { + p_clcb_ret = p_clcb; + break; + } + } + return p_clcb_ret; +} + +/******************************************************************************* +** +** Function gatt_clcb_find_by_idx +** +** Description Find clcb block using clcb_idx stored at the time of alloc +** +** Returns pointer to clcb corresponding to clcb_idx +** +*******************************************************************************/ + +tGATT_CLCB *gatt_clcb_find_by_idx(UINT16 clcb_idx) +{ + list_node_t *p_node = NULL; + tGATT_CLCB *p_clcb = NULL; + tGATT_CLCB *p_clcb_ret = NULL; + for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) { + p_clcb = list_node(p_node); + if (p_clcb->clcb_idx == clcb_idx) { + p_clcb_ret = p_clcb; + break; + } + } + return p_clcb_ret; +} + /******************************************************************************* ** ** Function gatt_clcb_alloc @@ -1649,24 +1745,23 @@ BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id) *******************************************************************************/ tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id) { - UINT8 i = 0; tGATT_CLCB *p_clcb = NULL; tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx); tGATT_REG *p_reg = gatt_get_regcb(gatt_if); - for (i = 0; i < GATT_CL_MAX_LCB; i++) { - if (!gatt_cb.clcb[i].in_use) { - p_clcb = &gatt_cb.clcb[i]; - - p_clcb->in_use = TRUE; - p_clcb->conn_id = conn_id; - p_clcb->clcb_idx = i; - p_clcb->p_reg = p_reg; - p_clcb->p_tcb = p_tcb; - break; - } + if (list_length(gatt_cb.p_clcb_list) < GATT_CL_MAX_LCB) { + p_clcb = (tGATT_CLCB *)osi_malloc(sizeof(tGATT_CLCB)); + if (p_clcb) { + memset(p_clcb, 0, sizeof(tGATT_CLCB)); + p_clcb->in_use = TRUE; + p_clcb->conn_id = conn_id; + //Add index of the clcb same as conn_id + p_clcb->clcb_idx = conn_id; + p_clcb->p_reg = p_reg; + p_clcb->p_tcb = p_tcb; + } } return p_clcb; } @@ -1685,6 +1780,7 @@ void gatt_clcb_dealloc (tGATT_CLCB *p_clcb) if (p_clcb && p_clcb->in_use) { btu_free_timer(&p_clcb->rsp_timer_ent); memset(p_clcb, 0, sizeof(tGATT_CLCB)); + list_remove(gatt_cb.p_clcb_list, p_clcb); } } @@ -1702,19 +1798,17 @@ void gatt_clcb_dealloc (tGATT_CLCB *p_clcb) *******************************************************************************/ tGATT_TCB *gatt_find_tcb_by_cid (UINT16 lcid) { - UINT16 xx = 0; - tGATT_TCB *p_tcb = NULL; - - for (xx = 0; xx < GATT_MAX_PHY_CHANNEL; xx++) { - if (gatt_cb.tcb[xx].in_use && gatt_cb.tcb[xx].att_lcid == lcid) { - p_tcb = &gatt_cb.tcb[xx]; + tGATT_TCB *p_tcb = NULL; + list_node_t *p_node = NULL; + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); + if (p_tcb->in_use && p_tcb->att_lcid == lcid) { break; } } return p_tcb; } - /******************************************************************************* ** ** Function gatt_num_apps_hold_link @@ -1750,12 +1844,15 @@ UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb) *******************************************************************************/ UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda) { - UINT8 i, num = 0; + UINT8 num = 0; - for (i = 0; i < GATT_CL_MAX_LCB; i ++) { - if (gatt_cb.clcb[i].in_use && memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0) { - num ++; - } + list_node_t *p_node = NULL; + tGATT_CLCB *p_clcb = NULL; + for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) { + p_clcb = list_node(p_node); + if (memcmp(p_clcb->p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0) { + num++; + } } return num; } @@ -1989,7 +2086,7 @@ BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 *p_foun for (i = start_idx; i < GATT_MAX_APPS; i ++) { if (p_tcb->app_hold_link[i]) { - *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if; + *p_gatt_if = p_tcb->app_hold_link[i]; *p_found_idx = i; found = TRUE; break; @@ -2064,7 +2161,7 @@ tGATT_CLCB *gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code) tGATT_CLCB *p_clcb = NULL; if (p_tcb->pending_cl_req != p_tcb->next_slot_inq) { - p_clcb = &gatt_cb.clcb[p_cmd->clcb_idx]; + p_clcb = gatt_clcb_find_by_idx(p_cmd->clcb_idx); *p_op_code = p_cmd->op_code; @@ -2227,8 +2324,9 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL) { GATT_TRACE_DEBUG ("found p_tcb "); gatt_set_ch_state(p_tcb, GATT_CH_CLOSE); - for (i = 0; i < GATT_CL_MAX_LCB; i ++) { - p_clcb = &gatt_cb.clcb[i]; + list_node_t *p_node = NULL; + for(p_node = list_begin(gatt_cb.p_clcb_list); p_node; p_node = list_next(p_node)) { + p_clcb = list_node(p_node); if (p_clcb->in_use && p_clcb->p_tcb == p_tcb) { btu_stop_timer(&p_clcb->rsp_timer_ent); GATT_TRACE_DEBUG ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx); @@ -2258,8 +2356,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason, transport); } } - memset(p_tcb, 0, sizeof(tGATT_TCB)); - + gatt_tcb_free(p_tcb); } else { GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc "); BTM_Recovery_Pre_State(); diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 0762b519f1..80badd32fd 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -500,7 +500,7 @@ typedef struct { } tGATT_PROFILE_CLCB; typedef struct { - tGATT_TCB tcb[GATT_MAX_PHY_CHANNEL]; + list_t *p_tcb_list; fixed_queue_t *sign_op_queue; tGATT_SR_REG sr_reg[GATT_MAX_SR_PROFILES]; @@ -516,7 +516,7 @@ typedef struct { fixed_queue_t *srv_chg_clt_q; /* service change clients queue */ fixed_queue_t *pending_new_srv_start_q; /* pending new service start queue */ tGATT_REG cl_rcb[GATT_MAX_APPS]; - tGATT_CLCB clcb[GATT_CL_MAX_LCB]; /* connection link control block*/ + list_t *p_clcb_list; /* connection link control block*/ tGATT_SCCB sccb[GATT_MAX_SCCB]; /* sign complete callback function GATT_MAX_SCCB <= GATT_CL_MAX_LCB */ UINT8 trace_level; UINT16 def_mtu_size; @@ -675,6 +675,8 @@ extern tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if); extern BOOLEAN gatt_is_clcb_allocated (UINT16 conn_id); extern tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id); extern void gatt_clcb_dealloc (tGATT_CLCB *p_clcb); +extern tGATT_CLCB *gatt_clcb_find_by_conn_id(UINT16 conn_id); +extern tGATT_CLCB *gatt_clcb_find_by_idx(UINT16 cclcb_idx); extern void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB *p_tcb ); extern BOOLEAN gatt_sr_is_cback_cnt_zero(tGATT_TCB *p_tcb ); @@ -693,6 +695,7 @@ extern tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transpo extern tGATT_TCB *gatt_get_tcb_by_idx(UINT8 tcb_idx); extern tGATT_TCB *gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport); extern BOOLEAN gatt_send_ble_burst_data (BD_ADDR remote_bda, BT_HDR *p_buf); +extern void gatt_tcb_free( tGATT_TCB *p_tcb); /* GATT client functions */ extern void gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb); diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index 26075679be..c520fa0719 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -25,7 +25,6 @@ #define L2C_INT_H #include - #include "stack/btm_api.h" #include "stack/l2c_api.h" #include "stack/l2cdefs.h" @@ -372,6 +371,7 @@ typedef struct { #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */ + /* Define a link control block. There is one link control block between ** this device and any other device (i.e. BD ADDR). */ @@ -466,6 +466,7 @@ typedef struct t_l2c_linkcb { } tL2C_LCB; + /* Define the L2CAP control structure */ typedef struct { @@ -478,12 +479,10 @@ typedef struct { BOOLEAN is_cong_cback_context; - tL2C_LCB lcb_pool[MAX_L2CAP_LINKS]; /* Link Control Block pool */ - tL2C_CCB ccb_pool[MAX_L2CAP_CHANNELS]; /* Channel Control Block pool */ + list_t *p_lcb_pool; /* Link Control Block pool */ + list_t *p_ccb_pool; /* Channel Control Block pool */ tL2C_RCB rcb_pool[MAX_L2CAP_CLIENTS]; /* Registration info pool */ - tL2C_CCB *p_free_ccb_first; /* Pointer to first free CCB */ - tL2C_CCB *p_free_ccb_last; /* Pointer to last free CCB */ UINT8 desire_role; /* desire to be master/slave when accepting a connection */ BOOLEAN disallow_switch; /* FALSE, to allow switch at create conn */ diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index 859389c073..c2e6846013 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -120,12 +120,11 @@ void L2CA_Deregister (UINT16 psm) tL2C_RCB *p_rcb; tL2C_CCB *p_ccb; tL2C_LCB *p_lcb; - int ii; - + list_node_t *p_node = NULL; if ((p_rcb = l2cu_find_rcb_by_psm (psm)) != NULL) { - p_lcb = &l2cb.lcb_pool[0]; - for (ii = 0; ii < MAX_L2CAP_LINKS; ii++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (p_lcb->in_use) { if (((p_ccb = p_lcb->ccb_queue.p_first_ccb) == NULL) || (p_lcb->link_state == LST_DISCONNECTING)) { @@ -403,7 +402,6 @@ BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 re L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_conn_rsp"); return (FALSE); } - /* Now, find the channel control block */ if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) == NULL) { L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_conn_rsp"); @@ -815,6 +813,7 @@ BOOLEAN L2CA_SetIdleTimeout (UINT16 cid, UINT16 timeout, BOOLEAN is_global) BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout, tBT_TRANSPORT transport) { tL2C_LCB *p_lcb; + list_node_t *p_node = NULL; if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN)) { p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr, transport); @@ -828,10 +827,8 @@ BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout, tBT_TRANSPO return FALSE; } } else { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) { p_lcb->idle_timeout = timeout; @@ -1188,10 +1185,9 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout) return (FALSE); } } else { - int xx; - p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + list_node_t *p_node = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) { if (p_lcb->link_flush_tout != flush_tout) { p_lcb->link_flush_tout = flush_tout; @@ -1397,9 +1393,10 @@ void L2CA_DeregisterLECoc(UINT16 psm) return; } - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - for (int i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) - { + tL2C_LCB *p_lcb = NULL; + list_node_t *p_node = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (!p_lcb->in_use || p_lcb->transport != BT_TRANSPORT_LE) { continue; } @@ -2359,4 +2356,4 @@ void l2ble_update_att_acl_pkt_num(UINT8 type, tl2c_buff_param_t *param) } xSemaphoreGive(buff_semaphore); } -#endif \ No newline at end of file +#endif diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index efc3785767..d860f81d50 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -136,6 +136,7 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in p_lcb->waiting_update_conn_max_interval = max_int; p_lcb->waiting_update_conn_latency = latency; p_lcb->waiting_update_conn_timeout = timeout; + p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; if(l2cble_start_conn_update(p_lcb) == TRUE) { @@ -586,7 +587,6 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL; - btu_stop_timer(&p_lcb->upda_con_timer); if (conn_param_update_cb.update_conn_param_cb != NULL) { @@ -922,13 +922,14 @@ void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs) *******************************************************************************/ void l2c_ble_link_adjust_allocation (void) { - UINT16 qq, yy, qq_remainder; + UINT16 qq, yy = 0, qq_remainder; tL2C_LCB *p_lcb; UINT16 hi_quota, low_quota; UINT16 num_lowpri_links = 0; UINT16 num_hipri_links = 0; UINT16 controller_xmit_quota = l2cb.num_lm_ble_bufs; UINT16 high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A; + list_node_t *p_node = NULL; /* If no links active, reset buffer quotas and controller buffers */ if (l2cb.num_ble_links_active == 0) { @@ -938,7 +939,8 @@ void l2c_ble_link_adjust_allocation (void) } /* First, count the links */ - for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) { if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) { num_hipri_links++; @@ -984,7 +986,9 @@ void l2c_ble_link_adjust_allocation (void) l2cb.ble_round_robin_quota, qq); /* Now, assign the quotas to each link */ - for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) { + p_node = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) { if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) { p_lcb->link_xmit_quota = high_pri_link_quota; @@ -1490,4 +1494,4 @@ UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport) L2CAP_TRACE_DEBUG ("L2CA_GetDisconnectReason=%d ", reason); return reason; -} \ No newline at end of file +} diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 960c455d87..77d05c2718 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -56,7 +56,6 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr) { tL2C_LCB *p_lcb; tL2C_LCB *p_lcb_cur; - int xx; BOOLEAN no_links; /* See if we have a link control block for the remote device */ @@ -74,7 +73,9 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr) no_links = TRUE; /* If we already have connection, accept as a master */ - for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++) { + list_node_t *p_node = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb_cur = list_node(p_node); if (p_lcb_cur == p_lcb) { continue; } @@ -682,13 +683,14 @@ void l2c_info_timeout (tL2C_LCB *p_lcb) *******************************************************************************/ void l2c_link_adjust_allocation (void) { - UINT16 qq, yy, qq_remainder; + UINT16 qq, yy = 0, qq_remainder; tL2C_LCB *p_lcb; UINT16 hi_quota, low_quota; UINT16 num_lowpri_links = 0; UINT16 num_hipri_links = 0; UINT16 controller_xmit_quota = l2cb.num_lm_acl_bufs; UINT16 high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A; + list_node_t *p_node = NULL; /* If no links active, reset buffer quotas and controller buffers */ if (l2cb.num_links_active == 0) { @@ -698,7 +700,8 @@ void l2c_link_adjust_allocation (void) } /* First, count the links */ - for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (p_lcb->in_use) { if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) { num_hipri_links++; @@ -744,7 +747,9 @@ void l2c_link_adjust_allocation (void) l2cb.round_robin_quota, qq); /* Now, assign the quotas to each link */ - for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) { + p_node = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (p_lcb->in_use) { if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) { p_lcb->link_xmit_quota = high_pri_link_quota; @@ -796,32 +801,31 @@ void l2c_link_adjust_allocation (void) ** Returns void ** *******************************************************************************/ -void l2c_link_adjust_chnl_allocation (void) + +bool l2c_chnl_allocation_in_ccb_list (void *p_ccb_node, void *context) { - UINT8 xx; - - - L2CAP_TRACE_DEBUG ("l2c_link_adjust_chnl_allocation"); - - /* assign buffer quota to each channel based on its data rate requirement */ - for (xx = 0; xx < MAX_L2CAP_CHANNELS; xx++) - { - tL2C_CCB *p_ccb = l2cb.ccb_pool + xx; - - if (!p_ccb->in_use) { - continue; - } - + UNUSED(context); + tL2C_CCB *p_ccb = (tL2C_CCB *)p_ccb_node; + if (p_ccb->in_use) { tL2CAP_CHNL_DATA_RATE data_rate = p_ccb->tx_data_rate + p_ccb->rx_data_rate; p_ccb->buff_quota = L2CAP_CBB_DEFAULT_DATA_RATE_BUFF_QUOTA * data_rate; L2CAP_TRACE_EVENT("CID:0x%04x FCR Mode:%u Priority:%u TxDataRate:%u RxDataRate:%u Quota:%u", - p_ccb->local_cid, p_ccb->peer_cfg.fcr.mode, - p_ccb->ccb_priority, p_ccb->tx_data_rate, - p_ccb->rx_data_rate, p_ccb->buff_quota); + p_ccb->local_cid, p_ccb->peer_cfg.fcr.mode, + p_ccb->ccb_priority, p_ccb->tx_data_rate, + p_ccb->rx_data_rate, p_ccb->buff_quota); /* quota may be change so check congestion */ l2cu_check_channel_congestion (p_ccb); } + return false; +} +void l2c_link_adjust_chnl_allocation (void) +{ + + L2CAP_TRACE_DEBUG ("l2c_link_adjust_chnl_allocation"); + + /* assign buffer quota to each channel based on its data rate requirement */ + list_foreach(l2cb.p_ccb_pool, l2c_chnl_allocation_in_ccb_list, NULL); } /******************************************************************************* @@ -876,7 +880,6 @@ UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles) void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) { tL2C_LCB *p_lcb; - int xx; /* Make sure not called from HCI Command Status (bd_addr and new_role are invalid) */ if (bd_addr) { @@ -893,7 +896,9 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) } /* Check if any LCB was waiting for switch to be completed */ - for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + list_node_t *p_node = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH)) { l2cu_create_conn_after_switch (p_lcb); } @@ -981,7 +986,6 @@ BOOLEAN l2c_link_check_power_mode (tL2C_LCB *p_lcb) *******************************************************************************/ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) { - int xx; BOOLEAN single_write = FALSE; L2CAP_TRACE_DEBUG("%s",__func__); /* Save the channel ID for faster counting */ @@ -1020,14 +1024,25 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) ** have at least 1, then do a round-robin for all the LCBs */ if ( (p_lcb == NULL) || (p_lcb->link_xmit_quota == 0) ) { + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb_cur = NULL; if (p_lcb == NULL) { - p_lcb = l2cb.lcb_pool; + p_node = list_begin(l2cb.p_lcb_pool); + p_lcb = list_node(p_node); } else if (!single_write) { - p_lcb++; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb_cur = list_node(p_node); + if (p_lcb_cur == p_lcb) { + p_node = list_next(p_node); + p_lcb = list_node(p_node); + break; + } + } } /* Loop through, starting at the next */ - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + for ( ; p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); #if (BLE_INCLUDED == TRUE) L2CAP_TRACE_DEBUG("window = %d,robin_unacked = %d,robin_quota=%d",l2cb.controller_le_xmit_window,l2cb.ble_round_robin_unacked,l2cb.ble_round_robin_quota); #endif ///BLE_INCLUDED == TRUE @@ -1047,9 +1062,10 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) /* Check for wraparound */ - if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) { - p_lcb = &l2cb.lcb_pool[0]; - } + if (p_node == list_end(l2cb.p_lcb_pool)) { + p_node = list_begin(l2cb.p_lcb_pool); + p_lcb = list_node(p_node); + } L2CAP_TRACE_DEBUG("in_use=%d,segment_being_sent=%d,link_state=%d,link_xmit_quota=%d",p_lcb->in_use,p_lcb->partial_segment_being_sent,p_lcb->link_state,p_lcb->link_xmit_quota); if ( (!p_lcb->in_use) || (p_lcb->partial_segment_being_sent) diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index c6baaca3c7..71736205ea 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -827,7 +827,6 @@ void l2c_process_held_packets(BOOLEAN timed_out) *******************************************************************************/ void l2c_init (void) { - INT16 xx; #if L2C_DYNAMIC_MEMORY l2c_cb_ptr = (tL2C_CB *)osi_malloc(sizeof(tL2C_CB)); #endif /* #if L2C_DYNAMIC_MEMORY */ @@ -835,9 +834,13 @@ void l2c_init (void) /* the psm is increased by 2 before being used */ l2cb.dyn_psm = 0xFFF; - /* Put all the channel control blocks on the free queue */ - for (xx = 0; xx < MAX_L2CAP_CHANNELS - 1; xx++) { - l2cb.ccb_pool[xx].p_next_ccb = &l2cb.ccb_pool[xx + 1]; + l2cb.p_ccb_pool = list_new(osi_free_func); + if (l2cb.p_ccb_pool == NULL) { + L2CAP_TRACE_ERROR("%s unable to allocate memory for L2CAP channel control block", __func__); + } + l2cb.p_lcb_pool = list_new(osi_free_func); + if (l2cb.p_lcb_pool == NULL) { + L2CAP_TRACE_ERROR("%s unable to allocate memory for L2CAP Link control block", __func__); } #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) @@ -846,8 +849,6 @@ void l2c_init (void) #endif - l2cb.p_free_ccb_first = &l2cb.ccb_pool[0]; - l2cb.p_free_ccb_last = &l2cb.ccb_pool[MAX_L2CAP_CHANNELS - 1]; #ifdef L2CAP_DESIRED_LINK_ROLE l2cb.desire_role = L2CAP_DESIRED_LINK_ROLE; @@ -892,6 +893,8 @@ void l2c_free(void) { list_free(l2cb.rcv_pending_q); l2cb.rcv_pending_q = NULL; + list_free(l2cb.p_lcb_pool); + list_free(l2cb.p_ccb_pool); #if L2C_DYNAMIC_MEMORY FREE_AND_RESET(l2c_cb_ptr); #endif diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c index 2b130c3490..d2de138b22 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c @@ -245,6 +245,16 @@ BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info ) ** Return value: TRUE if successs ** *******************************************************************************/ +BOOLEAN L2CA_UcdDeregister_In_CCB_List (void *p_ccb_node, void * context) +{ + p_ccb = (tL2C_CCB *)p_ccb_node; + if (( p_ccb->in_use ) + && ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )) { + l2cu_release_ccb (p_ccb); + } + return false; +} + BOOLEAN L2CA_UcdDeregister ( UINT16 psm ) { tL2C_CCB *p_ccb; @@ -275,15 +285,7 @@ BOOLEAN L2CA_UcdDeregister ( UINT16 psm ) } /* delete CCB for UCD */ - p_ccb = l2cb.ccb_pool; - for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ ) { - if (( p_ccb->in_use ) - && ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )) { - l2cu_release_ccb (p_ccb); - } - p_ccb++; - } - + list_foreach(l2cb.p_ccb_pool, L2CA_UcdDeregister_In_CCB_List, NULL); return (TRUE); } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 01761346af..3899090e44 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -37,6 +37,7 @@ #include "btm_int.h" #include "stack/hcidefs.h" #include "osi/allocator.h" +#include "osi/list.h" /******************************************************************************* ** @@ -49,11 +50,19 @@ *******************************************************************************/ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport) { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { - if (!p_lcb->in_use) { + tL2C_LCB *p_lcb = NULL; + bool list_ret = false; + if (list_length(l2cb.p_lcb_pool) < MAX_L2CAP_LINKS) { + p_lcb = (tL2C_LCB *)osi_malloc(sizeof(tL2C_LCB)); + if (p_lcb) { + memset (p_lcb, 0, sizeof(tL2C_LCB)); + list_ret = list_append(l2cb.p_lcb_pool, p_lcb); + }else { + L2CAP_TRACE_ERROR("Error in allocating L2CAP Link Control Block"); + } + } + if (list_ret) { + if (p_lcb) { btu_free_timer(&p_lcb->timer_entry); btu_free_timer(&p_lcb->info_timer_entry); btu_free_timer(&p_lcb->upda_con_timer); @@ -263,7 +272,14 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) #if (C2H_FLOW_CONTROL_INCLUDED == TRUE) p_lcb->completed_packets = 0; #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE - + { + if (list_remove(l2cb.p_lcb_pool, p_lcb)) { + p_lcb = NULL; + } + else { + L2CAP_TRACE_ERROR("Error in removing L2CAP Link Control Block"); + } + } } @@ -279,10 +295,10 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) *******************************************************************************/ tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport) { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && #if BLE_INCLUDED == TRUE p_lcb->transport == transport && @@ -1419,52 +1435,27 @@ void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority) *******************************************************************************/ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid) { - tL2C_CCB *p_ccb; - tL2C_CCB *p_prev; - + tL2C_CCB *p_ccb = NULL; L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x", cid); - if (!l2cb.p_free_ccb_first) { - return (NULL); + + if (list_length(l2cb.p_ccb_pool) < MAX_L2CAP_CHANNELS) { + p_ccb = (tL2C_CCB *)osi_malloc(sizeof(tL2C_CCB)); + if (p_ccb) { + memset (p_ccb, 0, sizeof(tL2C_CCB)); + list_append(l2cb.p_ccb_pool, p_ccb); + } } - - /* If a CID was passed in, use that, else take the first free one */ - if (cid == 0) { - p_ccb = l2cb.p_free_ccb_first; - l2cb.p_free_ccb_first = p_ccb->p_next_ccb; - } else { - p_prev = NULL; - - p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID]; - - if (p_ccb == l2cb.p_free_ccb_first) { - l2cb.p_free_ccb_first = p_ccb->p_next_ccb; - } else { - for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL; p_prev = p_prev->p_next_ccb) { - if (p_prev->p_next_ccb == p_ccb) { - p_prev->p_next_ccb = p_ccb->p_next_ccb; - - if (p_ccb == l2cb.p_free_ccb_last) { - l2cb.p_free_ccb_last = p_prev; - } - - break; - } - } - if (p_prev == NULL) { - L2CAP_TRACE_ERROR ("l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free list", cid); - return NULL; - } - } + if (p_ccb == NULL) { + return (NULL); } p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL; p_ccb->in_use = TRUE; - + /* Get a CID for the connection */ - p_ccb->local_cid = L2CAP_BASE_APPL_CID + (UINT16)(p_ccb - l2cb.ccb_pool); - + p_ccb->local_cid = L2CAP_BASE_APPL_CID + (list_length(l2cb.p_ccb_pool) - 1); p_ccb->p_lcb = p_lcb; p_ccb->p_rcb = NULL; p_ccb->should_free_rcb = false; @@ -1628,7 +1619,6 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb) { tL2C_LCB *p_lcb = p_ccb->p_lcb; tL2C_RCB *p_rcb = p_ccb->p_rcb; - L2CAP_TRACE_DEBUG ("l2cu_release_ccb: cid 0x%04x in_use: %u", p_ccb->local_cid, p_ccb->in_use); /* If already released, could be race condition */ @@ -1645,7 +1635,6 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb) p_ccb->p_rcb = NULL; p_ccb->should_free_rcb = false; } - if (p_lcb) { btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr); } @@ -1682,22 +1671,17 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb) p_ccb->p_lcb = NULL; } - /* Put the CCB back on the free pool */ - if (!l2cb.p_free_ccb_first) { - l2cb.p_free_ccb_first = p_ccb; - l2cb.p_free_ccb_last = p_ccb; - p_ccb->p_next_ccb = NULL; - p_ccb->p_prev_ccb = NULL; - } else { - p_ccb->p_next_ccb = NULL; - p_ccb->p_prev_ccb = l2cb.p_free_ccb_last; - l2cb.p_free_ccb_last->p_next_ccb = p_ccb; - l2cb.p_free_ccb_last = p_ccb; - } /* Flag as not in use */ p_ccb->in_use = FALSE; - + { + if (list_remove(l2cb.p_ccb_pool, p_ccb)) { + p_ccb = NULL; + } + else { + L2CAP_TRACE_ERROR("Error in removing L2CAP Channel Control Block"); + } + } /* If no channels on the connection, start idle timeout */ if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED)) { if (!p_lcb->ccb_queue.p_first_ccb) { @@ -2188,10 +2172,10 @@ void l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) *******************************************************************************/ void l2cu_device_reset (void) { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE)) { l2c_link_hci_disc_comp (p_lcb->handle, (UINT8) - 1); } @@ -2212,11 +2196,11 @@ void l2cu_device_reset (void) *******************************************************************************/ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) { - int xx; - tL2C_LCB *p_lcb_cur = &l2cb.lcb_pool[0]; #if BTM_SCO_INCLUDED == TRUE BOOLEAN is_sco_active; #endif + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb_cur = NULL; #if (BLE_INCLUDED == TRUE) tBT_DEVICE_TYPE dev_type; @@ -2241,7 +2225,8 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) /* If there is a connection where we perform as a slave, try to switch roles for this connection */ - for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb_cur = list_node(p_node); if (p_lcb_cur == p_lcb) { continue; } @@ -2295,10 +2280,11 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) UINT8 l2cu_get_num_hi_priority (void) { UINT8 no_hi = 0; - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) { no_hi++; } @@ -2395,10 +2381,11 @@ BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb) *******************************************************************************/ tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state) { - UINT16 i; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; - for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->link_state == state)) { return (p_lcb); } @@ -2425,12 +2412,11 @@ BOOLEAN l2cu_lcb_disconnecting (void) { tL2C_LCB *p_lcb; tL2C_CCB *p_ccb; - UINT16 i; BOOLEAN status = FALSE; + list_node_t *p_node = NULL; - p_lcb = &l2cb.lcb_pool[0]; - - for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (p_lcb->in_use) { /* no ccbs on lcb, or lcb is in disconnecting state */ if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING)) { @@ -2541,8 +2527,8 @@ void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda) tL2C_LCB *p_lcb; tL2C_CCB *p_ccb; tL2C_CCB *p_next_ccb; - int xx; L2CAP_TRACE_DEBUG ("l2cu_resubmit_pending_sec_req p_bda: %p", p_bda); + list_node_t *p_node = NULL; /* If we are called with a BDA, only resubmit for that BDA */ if (p_bda) { @@ -2559,7 +2545,8 @@ void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda) } } else { /* No BDA pasesed in, so check all links */ - for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if (p_lcb->in_use) { /* For all channels, send the event through their FSMs */ for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) { @@ -3179,11 +3166,11 @@ void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb) *******************************************************************************/ UINT8 l2cu_find_completed_packets(UINT16 *handles, UINT16 *num_packets) { - int xx; UINT8 num = 0; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->completed_packets > 0)) { *(handles++) = p_lcb->handle; *(num_packets++) = p_lcb->completed_packets; @@ -3212,10 +3199,10 @@ UINT8 l2cu_find_completed_packets(UINT16 *handles, UINT16 *num_packets) *******************************************************************************/ tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle) { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { + list_node_t *p_node = NULL; + tL2C_LCB *p_lcb = NULL; + for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { + p_lcb = list_node(p_node); if ((p_lcb->in_use) && (p_lcb->handle == handle)) { return (p_lcb); } @@ -3236,50 +3223,35 @@ tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle) ** Returns pointer to matched CCB, or NULL if no match ** *******************************************************************************/ +bool l2cu_find_ccb_in_list(void *p_ccb_node, void *p_local_cid) +{ + tL2C_CCB *p_ccb = (tL2C_CCB *)p_ccb_node; + uint8_t local_cid = *((uint8_t *)p_local_cid); + + if (p_ccb->local_cid == local_cid && p_ccb->in_use) { + return FALSE; + } + return TRUE; +} + tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid) { tL2C_CCB *p_ccb = NULL; -#if (L2CAP_UCD_INCLUDED == TRUE) - UINT8 xx; -#endif - - if (local_cid >= L2CAP_BASE_APPL_CID) { - /* find the associated CCB by "index" */ - local_cid -= L2CAP_BASE_APPL_CID; - - if (local_cid >= MAX_L2CAP_CHANNELS) { - return NULL; - } - - p_ccb = l2cb.ccb_pool + local_cid; - - /* make sure the CCB is in use */ - if (!p_ccb->in_use) { - p_ccb = NULL; - } - /* make sure it's for the same LCB */ - else if (p_lcb && p_lcb != p_ccb->p_lcb) { - p_ccb = NULL; - } +#if (L2CAP_UCD_INCLUDED == FALSE) + if (local_cid < L2CAP_BASE_APPL_CID) { + return NULL; } -#if (L2CAP_UCD_INCLUDED == TRUE) - else { - /* searching fixed channel */ - p_ccb = l2cb.ccb_pool; - for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ ) { - if ((p_ccb->local_cid == local_cid) - && (p_ccb->in_use) - && (p_lcb == p_ccb->p_lcb)) { - break; - } else { - p_ccb++; - } - } - if ( xx >= MAX_L2CAP_CHANNELS ) { - return NULL; - } +#endif //(L2CAP_UCD_INCLUDED == FALSE) + list_node_t *p_node = NULL; + + p_node = (list_foreach(l2cb.p_ccb_pool, l2cu_find_ccb_in_list, &local_cid)); + if (p_node) { + p_ccb = (tL2C_CCB *)list_node(p_node); + + if (p_lcb && p_lcb != p_ccb->p_lcb) { + p_ccb = NULL; + } } -#endif return (p_ccb); } diff --git a/components/bt/host/bluedroid/stack/sdp/include/sdpint.h b/components/bt/host/bluedroid/stack/sdp/include/sdpint.h index c459edea0b..9c0e6047d0 100644 --- a/components/bt/host/bluedroid/stack/sdp/include/sdpint.h +++ b/components/bt/host/bluedroid/stack/sdp/include/sdpint.h @@ -29,6 +29,7 @@ #include "common/bt_defs.h" #include "stack/sdp_api.h" #include "stack/l2c_api.h" +#include "osi/list.h" #if (SDP_INCLUDED == TRUE) /* Continuation length - we use a 2-byte offset */ @@ -136,7 +137,7 @@ typedef struct { typedef struct { UINT32 di_primary_handle; /* Device ID Primary record or NULL if nonexistent */ UINT16 num_records; - tSDP_RECORD record[SDP_MAX_RECORDS]; + list_t *p_record_list; } tSDP_DB; enum { diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_db.c b/components/bt/host/bluedroid/stack/sdp/sdp_db.c index 5f049e4eb7..d5a5b64471 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_db.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_db.c @@ -37,6 +37,8 @@ #include "stack/sdp_api.h" #include "sdpint.h" +#include "osi/list.h" + #if (SDP_INCLUDED == TRUE) #if SDP_SERVER_ENABLED == TRUE @@ -62,18 +64,25 @@ tSDP_RECORD *sdp_db_service_search (tSDP_RECORD *p_rec, tSDP_UUID_SEQ *p_seq) { UINT16 xx, yy; tSDP_ATTRIBUTE *p_attr; - tSDP_RECORD *p_end = &sdp_cb.server_db.record[sdp_cb.server_db.num_records]; - + list_node_t *p_node = NULL; + /* If NULL, start at the beginning, else start at the first specified record */ if (!p_rec) { - p_rec = &sdp_cb.server_db.record[0]; + p_node = list_begin(sdp_cb.server_db.p_record_list); } else { - p_rec++; + /* get node in the record list with given p_rec */ + p_node = list_get_node(sdp_cb.server_db.p_record_list, p_rec); + if (p_node == NULL) { + return NULL; + } + /* get next node */ + p_node = list_next(p_node); } /* Look through the records. The spec says that a match occurs if */ /* the record contains all the passed UUIDs in it. */ - for ( ; p_rec < p_end; p_rec++) { + for( ; p_node; p_node = list_next(p_node)) { + p_rec = list_node(p_node); for (yy = 0; yy < p_seq->num_uids; yy++) { p_attr = &p_rec->attribute[0]; for (xx = 0; xx < p_rec->num_attributes; xx++, p_attr++) { @@ -161,11 +170,12 @@ static BOOLEAN find_uuid_in_seq (UINT8 *p , UINT32 seq_len, UINT8 *p_uuid, tSDP_RECORD *sdp_db_find_record (UINT32 handle) { tSDP_RECORD *p_rec; - tSDP_RECORD *p_end = &sdp_cb.server_db.record[sdp_cb.server_db.num_records]; + list_node_t *p_node = NULL; /* Look through the records for the caller's handle */ - for (p_rec = &sdp_cb.server_db.record[0]; p_rec < p_end; p_rec++) { - if (p_rec->record_handle == handle) { + for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + p_rec = list_node(p_node); + if (p_rec->record_handle == handle) { return (p_rec); } } @@ -278,30 +288,42 @@ UINT32 SDP_CreateRecord (void) UINT32 handle; UINT8 buf[4]; tSDP_DB *p_db = &sdp_cb.server_db; + tSDP_RECORD *p_rec = NULL; + tSDP_RECORD *p_rec_prev = NULL; /* First, check if there is a free record */ if (p_db->num_records < SDP_MAX_RECORDS) { - memset (&p_db->record[p_db->num_records], 0, - sizeof (tSDP_RECORD)); - - /* We will use a handle of the first unreserved handle plus last record - ** number + 1 */ - if (p_db->num_records) { - handle = p_db->record[p_db->num_records - 1].record_handle + 1; - } else { - handle = 0x10000; - } - - p_db->record[p_db->num_records].record_handle = handle; - - p_db->num_records++; - SDP_TRACE_DEBUG("SDP_CreateRecord ok, num_records:%d\n", p_db->num_records); - /* Add the first attribute (the handle) automatically */ - UINT32_TO_BE_FIELD (buf, handle); - SDP_AddAttribute (handle, ATTR_ID_SERVICE_RECORD_HDL, UINT_DESC_TYPE, - 4, buf); - - return (p_db->record[p_db->num_records - 1].record_handle); + p_rec =(tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD)); + if (p_rec) { + memset(p_rec, 0, sizeof(tSDP_RECORD)); + /* Save previous rec */ + if (p_db->num_records) { + p_rec_prev = list_back(p_db->p_record_list); + } + /* Append new record */ + list_append(p_db->p_record_list, p_rec); + + /* We will use a handle of the first unreserved handle plus last record + ** number + 1 */ + if (p_db->num_records) { + handle = p_rec_prev->record_handle + 1; + } else { + handle = 0x10000; + } + + p_rec->record_handle = handle; + + p_db->num_records++; + SDP_TRACE_DEBUG("SDP_CreateRecord ok, num_records:%d\n", p_db->num_records); + /* Add the first attribute (the handle) automatically */ + UINT32_TO_BE_FIELD (buf, handle); + SDP_AddAttribute (handle, ATTR_ID_SERVICE_RECORD_HDL, UINT_DESC_TYPE, + 4, buf); + + return (p_rec->record_handle); + } else { + SDP_TRACE_ERROR("SDP_CreateRecord fail, memory allocation failed\n"); + } } else { SDP_TRACE_ERROR("SDP_CreateRecord fail, exceed maximum records:%d\n", SDP_MAX_RECORDS); } @@ -326,30 +348,26 @@ UINT32 SDP_CreateRecord (void) BOOLEAN SDP_DeleteRecord (UINT32 handle) { #if SDP_SERVER_ENABLED == TRUE - UINT16 xx, yy, zz; - tSDP_RECORD *p_rec = &sdp_cb.server_db.record[0]; + tSDP_RECORD *p_rec = NULL; + list_node_t *p_node = NULL; if (handle == 0 || sdp_cb.server_db.num_records == 0) { /* Delete all records in the database */ sdp_cb.server_db.num_records = 0; - + for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + list_remove(sdp_cb.server_db.p_record_list, p_node); + } /* require new DI record to be created in SDP_SetLocalDiRecord */ sdp_cb.server_db.di_primary_handle = 0; return (TRUE); } else { /* Find the record in the database */ - for (xx = 0; xx < sdp_cb.server_db.num_records; xx++, p_rec++) { + for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + p_rec = list_node(p_node); if (p_rec->record_handle == handle) { /* Found it. Shift everything up one */ - for (yy = xx; yy < sdp_cb.server_db.num_records; yy++, p_rec++) { - *p_rec = *(p_rec + 1); - - /* Adjust the attribute value pointer for each attribute */ - for (zz = 0; zz < p_rec->num_attributes; zz++) { - p_rec->attribute[zz].value_ptr -= sizeof(tSDP_RECORD); - } - } + list_remove(sdp_cb.server_db.p_record_list, p_rec); sdp_cb.server_db.num_records--; @@ -387,8 +405,9 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 attr_type, UINT32 attr_len, UINT8 *p_val) { #if SDP_SERVER_ENABLED == TRUE - UINT16 xx, yy, zz; - tSDP_RECORD *p_rec = &sdp_cb.server_db.record[0]; + UINT16 xx, yy; + tSDP_RECORD *p_rec = NULL; + list_node_t *p_node= NULL; #if (BT_TRACE_VERBOSE == TRUE) if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) { @@ -418,7 +437,8 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 attr_type, #endif /* Find the record in the database */ - for (zz = 0; zz < sdp_cb.server_db.num_records; zz++, p_rec++) { + for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + p_rec= list_node(p_node); if (p_rec->record_handle == handle) { tSDP_ATTRIBUTE *p_attr = &p_rec->attribute[0]; @@ -850,12 +870,14 @@ BOOLEAN SDP_DeleteAttribute (UINT32 handle, UINT16 attr_id) { #if SDP_SERVER_ENABLED == TRUE UINT16 xx, yy; - tSDP_RECORD *p_rec = &sdp_cb.server_db.record[0]; + tSDP_RECORD *p_rec = NULL; + list_node_t *p_node= NULL; UINT8 *pad_ptr; UINT32 len; /* Number of bytes in the entry */ /* Find the record in the database */ - for (xx = 0; xx < sdp_cb.server_db.num_records; xx++, p_rec++) { + for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + p_rec= list_node(p_node); if (p_rec->record_handle == handle) { tSDP_ATTRIBUTE *p_attr = &p_rec->attribute[0]; diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_main.c b/components/bt/host/bluedroid/stack/sdp/sdp_main.c index 8e1ae5822c..885e131367 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_main.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_main.c @@ -41,6 +41,8 @@ #include "stack/sdp_api.h" #include "sdpint.h" +#include "osi/list.h" + #if (SDP_INCLUDED == TRUE) /********************************************************************************/ /* G L O B A L S D P D A T A */ @@ -87,6 +89,7 @@ void sdp_init (void) /* Clears all structures and local SDP database (if Server is enabled) */ memset (&sdp_cb, 0, sizeof (tSDP_CB)); + sdp_cb.server_db.p_record_list = list_new(osi_free_func); /* Initialize the L2CAP configuration. We only care about MTU and flush */ sdp_cb.l2cap_my_cfg.mtu_present = TRUE; sdp_cb.l2cap_my_cfg.mtu = SDP_MTU_SIZE; @@ -140,6 +143,7 @@ void sdp_init (void) void sdp_deinit (void) { + list_free(sdp_cb.server_db.p_record_list); #if SDP_DYNAMIC_MEMORY osi_free(sdp_cb_ptr); sdp_cb_ptr = NULL;