mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/bluedroid_link_based_dynamic_allocation' into 'master'
Bluedroid stack dynamic allocation changes to optimise DRAM usage See merge request espressif/esp-idf!9461
This commit is contained in:
commit
84aebc6a78
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
@ -1142,7 +1154,6 @@ void btm_read_remote_ext_features_complete (UINT8 *p)
|
||||
BTM_TRACE_ERROR("btm_read_remote_ext_features_complete page=%d unknown", max_page);
|
||||
}
|
||||
|
||||
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);
|
||||
@ -1179,18 +1190,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);
|
||||
|
||||
@ -1362,12 +1371,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;
|
||||
}
|
||||
|
||||
@ -1426,12 +1430,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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -1848,7 +1854,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],
|
||||
@ -2118,8 +2124,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);
|
||||
|
||||
@ -2137,12 +2142,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 {
|
||||
@ -2175,8 +2178,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);
|
||||
|
||||
@ -2196,12 +2198,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;
|
||||
}
|
||||
@ -2225,8 +2225,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);
|
||||
|
||||
@ -2246,12 +2245,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;
|
||||
}
|
||||
@ -2552,3 +2549,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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
#endif /// BLE_INCLUDED == TRUE
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -25,7 +25,6 @@
|
||||
#define L2C_INT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#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 */
|
||||
|
@ -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;
|
||||
}
|
||||
@ -2378,4 +2375,4 @@ void l2ble_update_att_acl_pkt_num(UINT8 type, tl2c_buff_param_t *param)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user