mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
Merge branch 'bugfix/bredr_critical_bugs' into 'master'
bugfix: fix issues raised from AI review See merge request espressif/esp-idf!49755
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
static void btm_read_remote_features (UINT16 handle);
|
||||
static void btm_read_remote_ext_features (UINT16 handle, UINT8 page_number);
|
||||
static void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages);
|
||||
static BOOLEAN btm_get_acl_db(void *p_acl_db_node, void *context);
|
||||
|
||||
#define BTM_DEV_REPLY_TIMEOUT 3 /* 3 second timeout waiting for responses */
|
||||
|
||||
@@ -65,7 +66,7 @@ static void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read
|
||||
static void btm_read_acl_real_rssi_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_acl_real_rssi_cmpl_cb;
|
||||
tBTM_ACL_REAL_RSSI_RESULTS results;
|
||||
tBTM_ACL_REAL_RSSI_RESULTS results = {0};
|
||||
UINT16 handle = 0;
|
||||
tACL_CONN *p_acl_cb = NULL;
|
||||
|
||||
@@ -94,14 +95,16 @@ static void btm_read_acl_real_rssi_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
|
||||
}
|
||||
|
||||
STREAM_TO_UINT16(handle, p);
|
||||
p_acl_cb = btm_handle_to_acl(handle);
|
||||
if (!p_acl_cb) {
|
||||
results.status = BTM_UNKNOWN_ADDR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
|
||||
STREAM_TO_UINT8(results.rssi, p);
|
||||
results.status = BTM_SUCCESS;
|
||||
|
||||
p_acl_cb = btm_handle_to_acl(handle);
|
||||
if (p_acl_cb) {
|
||||
memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
|
||||
}
|
||||
|
||||
out:
|
||||
if (p_cb) {
|
||||
(*p_cb)(&results);
|
||||
@@ -193,38 +196,38 @@ void btm_acl_init (void)
|
||||
** NULL if not found.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN btm_get_acl_db(void *p_acl_db_node, void *context)
|
||||
static BOOLEAN btm_get_acl_db(void *p_acl_db_node, void *context)
|
||||
{
|
||||
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;
|
||||
{
|
||||
UINT8 *p_bda = (UINT8 *)p_param->p_data1;
|
||||
#if BLE_INCLUDED == TRUE
|
||||
tBT_TRANSPORT transport = (tBT_TRANSPORT)(*((UINT8 *)p_param->p_data2));
|
||||
tBT_TRANSPORT transport = (tBT_TRANSPORT)(*((UINT8 *)p_param->p_data2));
|
||||
#endif
|
||||
if (p_acl_db->in_use
|
||||
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;
|
||||
}
|
||||
) {
|
||||
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;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -403,8 +406,12 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
|
||||
|
||||
|
||||
p->p_pm_mode_db = btm_pm_sm_alloc();
|
||||
if (!p->p_pm_mode_db) {
|
||||
list_remove(btm_cb.p_acl_db_list, p);
|
||||
p = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
#if BTM_PM_DEBUG == TRUE
|
||||
BTM_TRACE_DEBUG( "btm_pm_sm_alloc handle:%d st:%d", hci_handle, p->p_pm_mode_db->state);
|
||||
@@ -599,7 +606,10 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport)
|
||||
}
|
||||
#endif
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
list_remove(btm_cb.p_pm_mode_db_list, p->p_pm_mode_db);
|
||||
if (p->p_pm_mode_db) {
|
||||
list_remove(btm_cb.p_pm_mode_db_list, p->p_pm_mode_db);
|
||||
p->p_pm_mode_db = NULL;
|
||||
}
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
#if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE)
|
||||
if (p->transport == BT_TRANSPORT_LE) {
|
||||
@@ -707,14 +717,13 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
|
||||
|| (old_inquiry_state != btm_cb.is_inquiry)
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
) {
|
||||
tBTM_BL_UPDATE_DATA evt = {
|
||||
.event = BTM_BL_UPDATE_EVT,
|
||||
.busy_level = busy_level,
|
||||
.busy_level_flags = busy_level_flags,
|
||||
};
|
||||
tBTM_BL_EVENT_DATA evt = {0};
|
||||
evt.update.event = BTM_BL_UPDATE_EVT;
|
||||
evt.update.busy_level = busy_level;
|
||||
evt.update.busy_level_flags = busy_level_flags;
|
||||
btm_cb.busy_level = busy_level;
|
||||
if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_UPDATE_MASK)) {
|
||||
(*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
|
||||
(*btm_cb.p_bl_changed_cb)(&evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -913,7 +922,7 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
|
||||
{
|
||||
tACL_CONN *p;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec;
|
||||
tBTM_BL_ROLE_CHG_DATA evt;
|
||||
tBTM_BL_ROLE_CHG_DATA evt = {0};
|
||||
|
||||
BTM_TRACE_DEBUG ("btm_acl_encrypt_change handle=%d status=%d encr_enable=%d\n",
|
||||
handle, status, encr_enable);
|
||||
@@ -955,14 +964,20 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
|
||||
else if (p->switch_role_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_ON) {
|
||||
p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
|
||||
p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
|
||||
|
||||
BD_ADDR remote_bd_addr;
|
||||
UINT8 role = btm_cb.devcb.switch_role_ref_data.role;
|
||||
UINT8 hci_status = btm_cb.devcb.switch_role_ref_data.hci_status;
|
||||
bdcpy(remote_bd_addr, btm_cb.devcb.switch_role_ref_data.remote_bd_addr);
|
||||
|
||||
btm_acl_report_role_change(btm_cb.devcb.switch_role_ref_data.hci_status, p->remote_addr);
|
||||
|
||||
/* if role change event is registered, report it now */
|
||||
if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_ROLE_CHG_MASK)) {
|
||||
evt.event = BTM_BL_ROLE_CHG_EVT;
|
||||
evt.new_role = btm_cb.devcb.switch_role_ref_data.role;
|
||||
evt.p_bda = btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
|
||||
evt.hci_status = btm_cb.devcb.switch_role_ref_data.hci_status;
|
||||
evt.new_role = role;
|
||||
evt.p_bda = remote_bd_addr;
|
||||
evt.hci_status = hci_status;
|
||||
(*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
|
||||
|
||||
BTM_TRACE_DEBUG("Role Switch Event: new_role 0x%02x, HCI Status 0x%02x, rs_st:%d\n",
|
||||
@@ -1063,10 +1078,12 @@ void BTM_SetDefaultLinkPolicy (UINT16 settings)
|
||||
}
|
||||
BTM_TRACE_DEBUG("Set DefaultLinkPolicy:0x%04x\n", settings);
|
||||
|
||||
btm_cb.btm_def_link_policy = settings;
|
||||
|
||||
/* Set the default Link Policy of the controller */
|
||||
btsnd_hcic_write_def_policy_set(settings);
|
||||
if (btsnd_hcic_write_def_policy_set(settings) == TRUE) {
|
||||
btm_cb.btm_def_link_policy = settings;
|
||||
} else {
|
||||
BTM_TRACE_WARNING("Failed to issue command of write_default_link_policy\n");
|
||||
}
|
||||
}
|
||||
#endif // (CLASSIC_BT_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
@@ -1079,23 +1096,32 @@ void BTM_SetDefaultLinkPolicy (UINT16 settings)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void btm_read_remote_version_complete (UINT8 *p)
|
||||
void btm_read_remote_version_complete (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tACL_CONN *p_acl_cb = NULL;
|
||||
UINT8 status;
|
||||
UINT16 handle;
|
||||
UINT16 remain_len = evt_len;
|
||||
BTM_TRACE_DEBUG ("btm_read_remote_version_complete\n");
|
||||
|
||||
if (remain_len < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
STREAM_TO_UINT16 (handle, p);
|
||||
remain_len -= 3;
|
||||
|
||||
/* Look up the connection by handle and copy features */
|
||||
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 (remain_len >= 5) {
|
||||
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);
|
||||
remain_len -= 5;
|
||||
}
|
||||
}
|
||||
#if BLE_INCLUDED == TRUE
|
||||
if (p_acl_cb->transport == BT_TRANSPORT_LE) {
|
||||
@@ -1140,6 +1166,9 @@ void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages)
|
||||
if (p_dev_rec == NULL) {
|
||||
/* Get a new device; might be doing dedicated bonding */
|
||||
p_dev_rec = btm_find_or_alloc_dev (p_acl_cb->remote_addr);
|
||||
if (p_dev_rec == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
p_acl_cb->num_read_pages = num_read_pages;
|
||||
@@ -1189,7 +1218,7 @@ void btm_read_remote_features (UINT16 handle)
|
||||
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->num_read_pages = 0;
|
||||
@@ -1247,7 +1276,7 @@ void btm_read_remote_features_complete (UINT8 *p)
|
||||
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;
|
||||
}
|
||||
|
||||
/* Copy the received features page */
|
||||
@@ -1306,6 +1335,11 @@ void btm_read_remote_ext_features_complete (UINT8 *p)
|
||||
BTM_TRACE_ERROR("btm_read_remote_ext_features_complete page=%d unknown", max_page);
|
||||
}
|
||||
|
||||
if (page_num > HCI_EXT_FEATURES_PAGE_MAX) {
|
||||
BTM_TRACE_ERROR("btm_read_remote_ext_features_complete page_num=%u invalid", page_num);
|
||||
page_num = HCI_EXT_FEATURES_PAGE_MAX;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Copy the received features page */
|
||||
STREAM_TO_ARRAY(p_acl_cb->peer_lmp_features[page_num], p, HCI_FEATURE_BYTES_PER_PAGE);
|
||||
@@ -1322,6 +1356,7 @@ void btm_read_remote_ext_features_complete (UINT8 *p)
|
||||
/* Reading of remote feature pages is complete */
|
||||
BTM_TRACE_DEBUG("BTM reached last remote extended features page (%d)\n", page_num);
|
||||
|
||||
exit:
|
||||
/* Process the pages */
|
||||
btm_process_remote_ext_features (p_acl_cb, (UINT8) (page_num + 1));
|
||||
|
||||
@@ -1349,7 +1384,7 @@ void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle)
|
||||
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;
|
||||
}
|
||||
|
||||
/* Process supported features only */
|
||||
@@ -1525,7 +1560,10 @@ UINT16 BTM_GetNumAclLinks (void)
|
||||
{
|
||||
uint16_t num_acl = 0;
|
||||
|
||||
num_acl = list_length(btm_cb.p_acl_db_list);
|
||||
if (btm_cb.p_acl_db_list) {
|
||||
num_acl = list_length(btm_cb.p_acl_db_list);
|
||||
}
|
||||
|
||||
return num_acl;
|
||||
}
|
||||
|
||||
@@ -1536,10 +1574,10 @@ UINT16 BTM_GetNumAclLinks (void)
|
||||
** Description This function is called to get the disconnection reason code
|
||||
** returned by the HCI at disconnection complete event.
|
||||
**
|
||||
** Returns TRUE if connection is up, else FALSE.
|
||||
** Returns UINT the HCI disconnection reason code
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 btm_get_acl_disc_reason_code (void)
|
||||
UINT8 btm_get_acl_disc_reason_code (void)
|
||||
{
|
||||
UINT8 res = btm_cb.acl_disc_reason;
|
||||
BTM_TRACE_DEBUG ("btm_get_acl_disc_reason_code\n");
|
||||
@@ -1732,7 +1770,7 @@ UINT8 BTM_AllocateSCN(void)
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
BOOLEAN BTM_TryAllocateSCN(UINT8 scn)
|
||||
{
|
||||
if (scn >= BTM_MAX_SCN) {
|
||||
if ((scn == 0) || (scn >= BTM_MAX_SCN)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1758,13 +1796,12 @@ BOOLEAN BTM_TryAllocateSCN(UINT8 scn)
|
||||
BOOLEAN BTM_FreeSCN(UINT8 scn)
|
||||
{
|
||||
BTM_TRACE_DEBUG ("BTM_FreeSCN \n");
|
||||
if (scn <= BTM_MAX_SCN) {
|
||||
if ((scn > 0) && (scn <= BTM_MAX_SCN)) {
|
||||
btm_cb.btm_scn[scn - 1] = FALSE;
|
||||
return (TRUE);
|
||||
} else {
|
||||
return (FALSE); /* Illegal SCN passed in */
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
#endif ///CLASSIC_BT_INCLUDED == TRUE
|
||||
|
||||
@@ -1986,13 +2023,12 @@ tBTM_STATUS BTM_RegBusyLevelNotif (tBTM_BL_CHANGE_CB *p_cb, UINT8 *p_level,
|
||||
*p_level = btm_cb.busy_level;
|
||||
}
|
||||
|
||||
btm_cb.bl_evt_mask = evt_mask;
|
||||
|
||||
if (!p_cb) {
|
||||
btm_cb.p_bl_changed_cb = NULL;
|
||||
} else if (btm_cb.p_bl_changed_cb) {
|
||||
return (BTM_BUSY);
|
||||
} else {
|
||||
btm_cb.bl_evt_mask = evt_mask;
|
||||
btm_cb.p_bl_changed_cb = p_cb;
|
||||
}
|
||||
|
||||
@@ -2033,7 +2069,7 @@ tBTM_STATUS BTM_SetQoS (BD_ADDR bd, FLOW_SPEC *p_flow, tBTM_CMPL_CB *p_cb)
|
||||
bd[0], bd[1], bd[2],
|
||||
bd[3], bd[4], bd[5]);
|
||||
|
||||
/* If someone already waiting on the version, do not allow another */
|
||||
/* If someone already waiting on the QoS, do not allow another */
|
||||
if (btm_cb.devcb.p_qossu_cmpl_cb) {
|
||||
return (BTM_BUSY);
|
||||
}
|
||||
@@ -2135,7 +2171,8 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL
|
||||
BTM_TRACE_API ("BTM_ReadRSSI: RemBdAddr: %02x%02x%02x%02x%02x%02x\n",
|
||||
remote_bda[0], remote_bda[1], remote_bda[2],
|
||||
remote_bda[3], remote_bda[4], remote_bda[5]);
|
||||
tBTM_RSSI_RESULTS result;
|
||||
tBTM_RSSI_RESULTS result = {0};
|
||||
memcpy(result.rem_bda, remote_bda, BD_ADDR_LEN);
|
||||
/* If someone already waiting on the version, do not allow another */
|
||||
if (btm_cb.devcb.p_rssi_cmpl_cb) {
|
||||
result.status = BTM_BUSY;
|
||||
@@ -2159,10 +2196,11 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL
|
||||
} else {
|
||||
return (BTM_CMD_STARTED);
|
||||
}
|
||||
} else {
|
||||
result.status = BTM_UNKNOWN_ADDR;
|
||||
(*p_cb)(&result);
|
||||
return (BTM_UNKNOWN_ADDR);
|
||||
}
|
||||
|
||||
/* If here, no BD Addr found */
|
||||
return (BTM_UNKNOWN_ADDR);
|
||||
}
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
@@ -2214,13 +2252,13 @@ tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_C
|
||||
#if CLASSIC_BT_INCLUDED == TRUE
|
||||
tBTM_STATUS ret = BTM_UNKNOWN_ADDR;
|
||||
tACL_CONN *p;
|
||||
tBTM_SET_ACL_PKT_TYPES_RESULTS result;
|
||||
tBTM_SET_ACL_PKT_TYPES_RESULTS result = {0};
|
||||
|
||||
/* If someone already waiting on the version, do not allow another */
|
||||
if (btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb) {
|
||||
result.status = HCI_ERR_REPEATED_ATTEMPTS;
|
||||
result.status = BTM_BUSY;
|
||||
(*p_cb)(&result);
|
||||
return (BTM_BUSY);;
|
||||
return (BTM_BUSY);
|
||||
}
|
||||
|
||||
p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
|
||||
@@ -2233,12 +2271,16 @@ tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_C
|
||||
if (btm_set_packet_types(p, pkt_types) != BTM_CMD_STARTED) {
|
||||
btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = NULL;
|
||||
btu_stop_timer (&btm_cb.devcb.set_acl_pkt_types_timer);
|
||||
result.status = HCI_ERR_MEMORY_FULL;
|
||||
result.status = BTM_NO_RESOURCES;
|
||||
(*p_cb)(&result);
|
||||
ret = BTM_NO_RESOURCES;
|
||||
} else {
|
||||
ret = BTM_CMD_STARTED;
|
||||
}
|
||||
} else {
|
||||
result.status = BTM_UNKNOWN_ADDR;
|
||||
(*p_cb)(&result);
|
||||
return (BTM_UNKNOWN_ADDR);
|
||||
}
|
||||
/* If here, no BD Addr found */
|
||||
return ret;
|
||||
@@ -2251,7 +2293,7 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types)
|
||||
{
|
||||
BTM_TRACE_DEBUG ("btm_acl_pkt_types_changed\n");
|
||||
tACL_CONN *conn = NULL;
|
||||
tBTM_SET_ACL_PKT_TYPES_RESULTS results;
|
||||
tBTM_SET_ACL_PKT_TYPES_RESULTS results = {0};
|
||||
btu_stop_timer (&btm_cb.devcb.set_acl_pkt_types_timer);
|
||||
|
||||
/* If there is a callback registered for packet types changed, call it */
|
||||
@@ -2265,8 +2307,10 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types)
|
||||
/* Search through the list of active channels for the correct BD Addr */
|
||||
if ((conn = btm_handle_to_acl(handle)) != NULL) {
|
||||
memcpy(results.rem_bda, conn->remote_addr, BD_ADDR_LEN);
|
||||
(*btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb)(&results);
|
||||
} else {
|
||||
results.status = BTM_UNKNOWN_ADDR;
|
||||
}
|
||||
(*btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb)(&results);
|
||||
btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = NULL;
|
||||
}
|
||||
}
|
||||
@@ -2296,6 +2340,7 @@ tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda)
|
||||
remote_bda[0], remote_bda[1], remote_bda[2],
|
||||
remote_bda[3], remote_bda[4], remote_bda[5]);
|
||||
|
||||
memcpy(result.rem_bda, remote_bda, BD_ADDR_LEN);
|
||||
memset(result.channel_map, 0, sizeof(result.channel_map)); // Clear channel map data
|
||||
/* If someone already waiting for the channel map, do not allow another */
|
||||
if (btm_cb.devcb.is_ch_map_cb) {
|
||||
@@ -2483,7 +2528,7 @@ err_out:
|
||||
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;
|
||||
tBTM_LINK_QUALITY_RESULTS results = {0};
|
||||
UINT16 handle;
|
||||
tACL_CONN *p_acl_cb = NULL;
|
||||
BTM_TRACE_DEBUG ("btm_read_link_quality_complete\n");
|
||||
@@ -2505,10 +2550,12 @@ 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 */
|
||||
p_acl_cb = btm_handle_to_acl(handle);
|
||||
if (p_acl_cb) {
|
||||
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_UNKNOWN_ADDR;
|
||||
}
|
||||
} else {
|
||||
results.status = BTM_ERR_PROCESSING;
|
||||
}
|
||||
@@ -2531,11 +2578,10 @@ tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport)
|
||||
{
|
||||
UINT16 hci_handle = BTM_GetHCIConnHandle(bd_addr, transport);
|
||||
tBTM_STATUS status = BTM_SUCCESS;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
|
||||
|
||||
BTM_TRACE_DEBUG ("btm_remove_acl\n");
|
||||
#if BTM_DISC_DURING_RS == TRUE
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
|
||||
|
||||
/* Role Switch is pending, postpone until completed */
|
||||
if (p_dev_rec && (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING)) {
|
||||
p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
|
||||
@@ -2591,6 +2637,7 @@ void btm_cont_rswitch (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec,
|
||||
UINT8 hci_status)
|
||||
{
|
||||
BOOLEAN sw_ok = TRUE;
|
||||
UINT8 final_status = hci_status;
|
||||
BTM_TRACE_DEBUG ("btm_cont_rswitch\n");
|
||||
/* Check to see if encryption needs to be turned off if pending
|
||||
change of link key or role switch */
|
||||
@@ -2625,8 +2672,9 @@ void btm_cont_rswitch (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec,
|
||||
}
|
||||
|
||||
if (!sw_ok) {
|
||||
final_status = HCI_ERR_MEMORY_FULL;
|
||||
p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
|
||||
btm_acl_report_role_change(hci_status, p->remote_addr);
|
||||
btm_acl_report_role_change(final_status, p->remote_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2777,23 +2825,23 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type)
|
||||
{
|
||||
/* 3 and 5 slot packets? */
|
||||
if (!HCI_3_SLOT_PACKETS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
|
||||
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3);
|
||||
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH3 | BTM_ACL_PKT_TYPES_MASK_DM3);
|
||||
}
|
||||
|
||||
if (!HCI_5_SLOT_PACKETS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
|
||||
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5);
|
||||
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH5 | BTM_ACL_PKT_TYPES_MASK_DM5);
|
||||
}
|
||||
|
||||
/* 2 and 3 MPS support? */
|
||||
if (!HCI_EDR_ACL_2MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
|
||||
/* Not supported. Add 'not_supported' mask for all 2MPS packet types */
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 | BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_2_DH5);
|
||||
}
|
||||
|
||||
if (!HCI_EDR_ACL_3MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
|
||||
/* Not supported. Add 'not_supported' mask for all 3MPS packet types */
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 +
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 | BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
|
||||
}
|
||||
|
||||
@@ -2803,13 +2851,13 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type)
|
||||
if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
|
||||
/* Not supported. Add 'not_supported' mask for all 3-slot EDR packet types */
|
||||
{
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 | BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
|
||||
}
|
||||
|
||||
if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
|
||||
/* Not supported. Add 'not_supported' mask for all 5-slot EDR packet types */
|
||||
{
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
|
||||
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 | BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2824,8 +2872,10 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type)
|
||||
void btm_acl_free(void)
|
||||
{
|
||||
list_free(btm_cb.p_acl_db_list);
|
||||
btm_cb.p_acl_db_list = NULL;
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
list_free(btm_cb.p_pm_mode_db_list);
|
||||
btm_cb.p_pm_mode_db_list = NULL;
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
static void btm_read_new_conn_tx_pwr_lvl_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb;
|
||||
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
|
||||
|
||||
btu_stop_timer(&btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer);
|
||||
btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
|
||||
@@ -63,11 +63,13 @@ out:
|
||||
tBTM_STATUS BTM_ReadNewConnTxPwrLvl(tBTM_CMPL_CB *p_cb)
|
||||
{
|
||||
tBTM_STATUS status;
|
||||
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
|
||||
|
||||
if (btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb) {
|
||||
result.status = BTM_BUSY;
|
||||
(*p_cb)(&result);
|
||||
if (p_cb) {
|
||||
(*p_cb)(&result);
|
||||
}
|
||||
return BTM_BUSY;
|
||||
}
|
||||
|
||||
@@ -82,7 +84,9 @@ tBTM_STATUS BTM_ReadNewConnTxPwrLvl(tBTM_CMPL_CB *p_cb)
|
||||
btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
|
||||
btu_stop_timer(&btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer);
|
||||
result.status = status;
|
||||
(*p_cb)(&result);
|
||||
if (p_cb) {
|
||||
(*p_cb)(&result);
|
||||
}
|
||||
return BTM_NO_RESOURCES;
|
||||
}
|
||||
|
||||
@@ -92,12 +96,11 @@ tBTM_STATUS BTM_ReadNewConnTxPwrLvl(tBTM_CMPL_CB *p_cb)
|
||||
static void btm_write_new_conn_tx_pwr_lvl_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb;
|
||||
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
|
||||
|
||||
btu_stop_timer(&btm_cb.devcb.write_new_conn_tx_pwr_lvl_timer);
|
||||
btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.status = BTM_ERR_PROCESSING;
|
||||
result.hci_status = HCI_ERR_UNSPECIFIED;
|
||||
|
||||
@@ -122,13 +125,15 @@ out:
|
||||
tBTM_STATUS BTM_WriteNewConnTxPwrLvl(INT8 pwr_lvl_min, INT8 pwr_lvl_max, tBTM_CMPL_CB *p_cb)
|
||||
{
|
||||
tBTM_STATUS status;
|
||||
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
|
||||
UINT8 param[2];
|
||||
UINT8 *p = param;
|
||||
|
||||
if (btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb) {
|
||||
result.status = BTM_BUSY;
|
||||
(*p_cb)(&result);
|
||||
if (p_cb) {
|
||||
(*p_cb)(&result);
|
||||
}
|
||||
return BTM_BUSY;
|
||||
}
|
||||
|
||||
@@ -145,7 +150,9 @@ tBTM_STATUS BTM_WriteNewConnTxPwrLvl(INT8 pwr_lvl_min, INT8 pwr_lvl_max, tBTM_CM
|
||||
btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
|
||||
btu_stop_timer(&btm_cb.devcb.write_new_conn_tx_pwr_lvl_timer);
|
||||
result.status = status;
|
||||
(*p_cb)(&result);
|
||||
if (p_cb) {
|
||||
(*p_cb)(&result);
|
||||
}
|
||||
return BTM_NO_RESOURCES;
|
||||
}
|
||||
|
||||
@@ -156,7 +163,7 @@ static void btm_read_tx_pwr_lvl_vsc_cmpl_cb(tBTM_TX_PWR_LVL_TYPE type, tBTM_VSC_
|
||||
TIMER_LIST_ENT *timer, tBTM_CMPL_CB **pp_cb)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = *pp_cb;
|
||||
tBTM_READ_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_READ_TX_PWR_LVL_RESULTS result = {0};
|
||||
|
||||
btu_stop_timer(timer);
|
||||
*pp_cb = NULL;
|
||||
@@ -220,7 +227,7 @@ tBTM_STATUS BTM_ReadBredrTxPwrLvl(tBTM_TX_PWR_LVL_TYPE type, tBTM_CMPL_CB *p_cb)
|
||||
tBTM_VSC_CMPL_CB *p_vsc_cb;
|
||||
|
||||
tBTM_STATUS status;
|
||||
tBTM_READ_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_READ_TX_PWR_LVL_RESULTS result = {0};
|
||||
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
|
||||
|
||||
switch (type) {
|
||||
@@ -288,7 +295,7 @@ static void btm_write_tx_pwr_lvl_vsc_cmpl_cb(tBTM_TX_PWR_LVL_TYPE type, tBTM_VSC
|
||||
TIMER_LIST_ENT *timer, tBTM_CMPL_CB **pp_cb)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = *pp_cb;
|
||||
tBTM_WRITE_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_WRITE_TX_PWR_LVL_RESULTS result = {0};
|
||||
|
||||
btu_stop_timer(timer);
|
||||
*pp_cb = NULL;
|
||||
@@ -347,7 +354,7 @@ tBTM_STATUS BTM_WriteBredrTxPwrLvl(tBTM_TX_PWR_LVL_TYPE type, INT8 tx_power, tBT
|
||||
tBTM_VSC_CMPL_CB *p_vsc_cb;
|
||||
|
||||
tBTM_STATUS status;
|
||||
tBTM_WRITE_TX_PWR_LVL_RESULTS result;
|
||||
tBTM_WRITE_TX_PWR_LVL_RESULTS result = {0};
|
||||
UINT8 param[1];
|
||||
UINT8 *p = param;
|
||||
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
|
||||
@@ -425,12 +432,12 @@ tBTM_STATUS BTM_WriteBredrTxPwrLvl(tBTM_TX_PWR_LVL_TYPE type, INT8 tx_power, tBT
|
||||
void btm_bredr_pwr_ctrl_timeout(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
if (p_tle == &btm_cb.devcb.write_inq_txpwer_timer) {
|
||||
btm_write_inq_tx_power_complete(NULL);
|
||||
btm_write_inq_tx_power_complete(NULL, 0);
|
||||
} else if (p_tle == &btm_cb.devcb.read_iscan_txpwer_timer) {
|
||||
btm_read_iscan_tx_power_complete(NULL);
|
||||
|
||||
btm_read_iscan_tx_power_complete(NULL, 0);
|
||||
}
|
||||
#if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
|
||||
} else if (p_tle == &btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer) {
|
||||
else if (p_tle == &btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer) {
|
||||
btm_read_new_conn_tx_pwr_lvl_vsc_cmpl_cb(NULL);
|
||||
} else if (p_tle == &btm_cb.devcb.write_new_conn_tx_pwr_lvl_timer) {
|
||||
btm_write_new_conn_tx_pwr_lvl_vsc_cmpl_cb(NULL);
|
||||
@@ -446,9 +453,8 @@ void btm_bredr_pwr_ctrl_timeout(TIMER_LIST_ENT *p_tle)
|
||||
btm_write_page_tx_pwr_lvl_vsc_cmpl_cb(NULL);
|
||||
} else if (p_tle == &btm_cb.devcb.write_pscan_tx_pwr_lvl_timer) {
|
||||
btm_write_pscan_tx_pwr_lvl_vsc_cmpl_cb(NULL);
|
||||
|
||||
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
|
||||
}
|
||||
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
|
||||
}
|
||||
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <stdio.h>
|
||||
@@ -77,7 +78,11 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
|
||||
if(p_dev_rec) {
|
||||
BTM_TRACE_DEBUG("%s alloc a new dev rec %p bd_addr="MACSTR"",
|
||||
__func__, p_dev_rec, MAC2STR(bd_addr));
|
||||
list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec);
|
||||
if (!list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec)) {
|
||||
osi_free(p_dev_rec);
|
||||
p_dev_rec = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
/* 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;
|
||||
@@ -188,17 +193,18 @@ BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) {
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
/* Tell controller to get rid of the link key, if it has one stored */
|
||||
if (transport != BT_TRANSPORT_LE) {
|
||||
BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
|
||||
}
|
||||
#endif // (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
btm_sec_free_dev(p_dev_rec, transport);
|
||||
if ((p_dev_rec = btm_find_dev(bd_addr)) == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
/* Tell controller to get rid of the link key, if it has one stored */
|
||||
if (transport != BT_TRANSPORT_LE) {
|
||||
BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
|
||||
}
|
||||
#endif // (CLASSIC_BT_INCLUDED == TRUE)
|
||||
btm_sec_free_dev(p_dev_rec, transport);
|
||||
|
||||
#if (BLE_SMP_ID_RESET_ENABLE == TRUE)
|
||||
/*
|
||||
* There are tracking risks associated with using a fixed or static IRK.
|
||||
@@ -277,45 +283,45 @@ BOOLEAN btm_find_sec_dev_in_list (void *p_node_data, void *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;
|
||||
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 (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;
|
||||
) {
|
||||
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;
|
||||
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 (!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, bd_addr_null, BD_ADDR_LEN) != 0 &&
|
||||
!memcmp(p_sec_dev->ble.pseudo_addr, p_context->context.p_bd_addr, BD_ADDR_LEN)) {
|
||||
ret = FALSE;
|
||||
}
|
||||
if (memcmp(p_sec_dev->ble.pseudo_addr, bd_addr_null, BD_ADDR_LEN) != 0 &&
|
||||
!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;
|
||||
}
|
||||
if (btm_ble_addr_resolvable(p_context->context.p_bd_addr, p_sec_dev)) {
|
||||
ret = FALSE;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -489,6 +495,13 @@ void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRANSPORT transport)
|
||||
btm_sec_clear_ble_keys (p_dev_rec);
|
||||
#endif
|
||||
}
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
if (p_dev_rec == btm_cb.p_collided_dev_rec) {
|
||||
btm_cb.p_collided_dev_rec = NULL;
|
||||
btm_cb.sec_collision_tle.param = 0;
|
||||
btu_stop_timer(&btm_cb.sec_collision_tle);
|
||||
}
|
||||
#endif
|
||||
/* No BLE keys and BT keys, clear the sec_flags */
|
||||
if(p_dev_rec->sec_flags == BTM_SEC_IN_USE) {
|
||||
p_dev_rec->sec_flags = 0;
|
||||
@@ -585,16 +598,18 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle)
|
||||
*******************************************************************************/
|
||||
tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr)
|
||||
{
|
||||
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));
|
||||
}
|
||||
if (bd_addr) {
|
||||
if (btm_cb.p_sec_dev_rec_list) {
|
||||
list_node_t *p_node = NULL;
|
||||
tSecDevContext context = {0};
|
||||
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);
|
||||
}
|
||||
@@ -791,6 +806,7 @@ BOOLEAN btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type)
|
||||
void btm_sec_dev_init(void)
|
||||
{
|
||||
btm_cb.p_sec_dev_rec_list = list_new(osi_free_func);
|
||||
assert(btm_cb.p_sec_dev_rec_list != NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -802,5 +818,8 @@ void btm_sec_dev_init(void)
|
||||
*******************************************************************************/
|
||||
void btm_sec_dev_free(void)
|
||||
{
|
||||
list_free(btm_cb.p_sec_dev_rec_list);
|
||||
if (btm_cb.p_sec_dev_rec_list) {
|
||||
list_free(btm_cb.p_sec_dev_rec_list);
|
||||
btm_cb.p_sec_dev_rec_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,15 +93,15 @@ void btm_dev_init (void)
|
||||
btm_cb.devcb.rln_timer.param = (TIMER_PARAM_TYPE)TT_DEV_RLN;
|
||||
#endif // (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1 +
|
||||
BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3 +
|
||||
BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5;
|
||||
btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 | BTM_ACL_PKT_TYPES_MASK_DM1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DH3 | BTM_ACL_PKT_TYPES_MASK_DM3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DH5 | BTM_ACL_PKT_TYPES_MASK_DM5;
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1 +
|
||||
BTM_SCO_PKT_TYPES_MASK_HV2 +
|
||||
BTM_SCO_PKT_TYPES_MASK_HV3 +
|
||||
BTM_SCO_PKT_TYPES_MASK_EV3 +
|
||||
BTM_SCO_PKT_TYPES_MASK_EV4 +
|
||||
btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1 |
|
||||
BTM_SCO_PKT_TYPES_MASK_HV2 |
|
||||
BTM_SCO_PKT_TYPES_MASK_HV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_EV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_EV4 |
|
||||
BTM_SCO_PKT_TYPES_MASK_EV5;
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
}
|
||||
@@ -132,6 +132,17 @@ static void btm_db_reset (void)
|
||||
(*p_cb)((void *) NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (btm_cb.devcb.p_page_to_set_cmpl_cb) {
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_page_to_set_cmpl_cb;
|
||||
tBTM_SET_PAGE_TIMEOUT_RESULTS results = {0};
|
||||
|
||||
results.status = BTM_DEV_RESET;
|
||||
btm_cb.devcb.p_page_to_set_cmpl_cb = NULL;
|
||||
btu_free_timer(&btm_cb.devcb.page_timeout_set_timer);
|
||||
|
||||
(*p_cb)(&results);
|
||||
}
|
||||
#endif // (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
if (btm_cb.devcb.p_rssi_cmpl_cb) {
|
||||
@@ -188,7 +199,7 @@ static void reset_complete(void)
|
||||
btm_pm_reset();
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
l2c_link_processs_num_bufs(controller->get_acl_buffer_count_classic());
|
||||
l2c_link_process_num_bufs(controller->get_acl_buffer_count_classic());
|
||||
#if BTM_SCO_HCI_INCLUDED == TRUE
|
||||
btm_sco_process_num_bufs(controller->get_sco_buffer_count());
|
||||
#endif
|
||||
@@ -297,29 +308,29 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
case HCI_EXT_FEATURES_PAGE_0:
|
||||
|
||||
/* Create ACL supported packet types mask */
|
||||
btm_cb.btm_acl_pkt_types_supported = (BTM_ACL_PKT_TYPES_MASK_DH1 +
|
||||
btm_cb.btm_acl_pkt_types_supported = (BTM_ACL_PKT_TYPES_MASK_DH1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DM1);
|
||||
|
||||
if (HCI_3_SLOT_PACKETS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DM3);
|
||||
}
|
||||
|
||||
if (HCI_5_SLOT_PACKETS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH5 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH5 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DM5);
|
||||
}
|
||||
|
||||
/* Add in EDR related ACL types */
|
||||
if (!HCI_EDR_ACL_2MPS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 +
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_2_DH5);
|
||||
}
|
||||
|
||||
if (!HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 +
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
|
||||
}
|
||||
|
||||
@@ -327,12 +338,12 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
if (HCI_EDR_ACL_2MPS_SUPPORTED(p_features) ||
|
||||
HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) {
|
||||
if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
|
||||
}
|
||||
|
||||
if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
|
||||
}
|
||||
}
|
||||
@@ -378,7 +389,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_2_EV5;
|
||||
}
|
||||
} else {
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 +
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5);
|
||||
}
|
||||
|
||||
@@ -387,7 +398,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_3_EV5;
|
||||
}
|
||||
} else {
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 +
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5);
|
||||
}
|
||||
}
|
||||
@@ -635,8 +646,6 @@ tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class)
|
||||
return (BTM_SUCCESS);
|
||||
}
|
||||
|
||||
memcpy (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN);
|
||||
|
||||
if (!controller_get_interface()->get_is_ready()) {
|
||||
return (BTM_DEV_RESET);
|
||||
}
|
||||
@@ -645,6 +654,8 @@ tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class)
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
|
||||
memcpy (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN);
|
||||
|
||||
return (BTM_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -691,7 +702,7 @@ UINT8 *BTM_ReadLocalFeatures (void)
|
||||
** save the pointer to the function that is return and
|
||||
** call it when processing of the event is complete
|
||||
**
|
||||
** Returns status of the operation
|
||||
** Returns original device status callback
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTM_DEV_STATUS_CB *BTM_RegisterForDeviceStatusNotif (tBTM_DEV_STATUS_CB *p_cb)
|
||||
@@ -725,6 +736,10 @@ tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 param_len,
|
||||
BTM_TRACE_EVENT ("BTM: BTM_VendorSpecificCommand: Opcode: 0x%04X, ParamLen: %i.",
|
||||
opcode, param_len);
|
||||
|
||||
if ((param_len > 0) && (p_param_buf == NULL)) {
|
||||
return BTM_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
/* Allocate a buffer to hold HCI command plus the callback function */
|
||||
if ((p_buf = HCI_GET_CMD_BUF(param_len)) != NULL) {
|
||||
/* Send the HCI command (opcode will be OR'd with HCI_GRP_VENDOR_SPECIFIC) */
|
||||
@@ -769,51 +784,68 @@ tBTM_STATUS BTM_ConfigCoexStatus(tBTM_COEX_OPERATION op, tBTM_COEX_TYPE type, UI
|
||||
void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
|
||||
tBTM_CMPL_CB *p_vsc_cplt_cback)
|
||||
{
|
||||
UINT8 *p_orig = p;
|
||||
UINT16 remain_len = evt_len;
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
switch(opcode) {
|
||||
case HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST: {
|
||||
#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
|
||||
uint8_t subcode, status; uint32_t length;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
STREAM_TO_UINT8(subcode, p);
|
||||
STREAM_TO_UINT32(length, p);
|
||||
if (remain_len >= 6) {
|
||||
uint8_t subcode, status; uint32_t length;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
STREAM_TO_UINT8(subcode, p);
|
||||
STREAM_TO_UINT32(length, p);
|
||||
remain_len -= 6;
|
||||
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.exception_list_up.status = status;
|
||||
cb_params.exception_list_up.subcode = subcode;
|
||||
cb_params.exception_list_up.length = length;
|
||||
cb_params.exception_list_up.device_info = p;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_EXCEPTION_LIST_UPDATE_EVT, &cb_params);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.exception_list_up.status = status;
|
||||
cb_params.exception_list_up.subcode = subcode;
|
||||
cb_params.exception_list_up.length = length;
|
||||
cb_params.exception_list_up.device_info = p;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_EXCEPTION_LIST_UPDATE_EVT, &cb_params);
|
||||
}
|
||||
#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
|
||||
break;
|
||||
}
|
||||
case HCI_VENDOR_BLE_CLEAR_ADV: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_CLEAR_ADV_COMPLETE_EVT, &cb_params);
|
||||
if (remain_len >= 1) {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
remain_len -= 1;
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_CLEAR_ADV_COMPLETE_EVT, &cb_params);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_VENDOR_BLE_SET_CSA_SUPPORT: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_CSA_SUPPORT_COMPLETE_EVT, &cb_params);
|
||||
if (remain_len >= 1) {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
remain_len -= 1;
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_CSA_SUPPORT_COMPLETE_EVT, &cb_params);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_VENDOR_BLE_SET_EVT_MASK: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_VENDOR_EVT_MASK_COMPLETE_EVT, &cb_params);
|
||||
if (remain_len >= 1) {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
remain_len -= 1;
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_VENDOR_EVT_MASK_COMPLETE_EVT, &cb_params);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
UNUSED(remain_len);
|
||||
#endif // (BLE_INCLUDED == TRUE)
|
||||
tBTM_VSC_CMPL vcs_cplt_params;
|
||||
|
||||
@@ -822,7 +854,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
|
||||
/* Pass parameters to the callback function */
|
||||
vcs_cplt_params.opcode = opcode; /* Number of bytes in return info */
|
||||
vcs_cplt_params.param_len = evt_len; /* Number of bytes in return info */
|
||||
vcs_cplt_params.p_param_buf = p;
|
||||
vcs_cplt_params.p_param_buf = p_orig;
|
||||
(*p_vsc_cplt_cback)(&vcs_cplt_params); /* Call the VSC complete callback function */
|
||||
}
|
||||
|
||||
@@ -897,16 +929,29 @@ void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len)
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
UINT8 sub_event;
|
||||
UINT8 remain_len = evt_len;
|
||||
UINT8 *p_evt = p;
|
||||
|
||||
if (remain_len < 1) {
|
||||
goto exit;
|
||||
}
|
||||
STREAM_TO_UINT8(sub_event, p_evt);
|
||||
remain_len -= 1;
|
||||
|
||||
/* Check in subevent if authentication is through Legacy Authentication. */
|
||||
if (sub_event == HCI_VENDOR_LEGACY_REM_AUTH_EVT_SUBCODE) {
|
||||
if (remain_len < 2) {
|
||||
goto exit;
|
||||
}
|
||||
UINT16 hci_handle;
|
||||
STREAM_TO_UINT16(hci_handle, p_evt);
|
||||
remain_len -= 2;
|
||||
btm_sec_handle_remote_legacy_auth_cmp(hci_handle);
|
||||
}
|
||||
|
||||
exit:
|
||||
#endif /// (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
for (i = 0; i < BTM_MAX_VSE_CALLBACKS; i++) {
|
||||
if (btm_cb.devcb.p_vend_spec_cb[i]) {
|
||||
(*btm_cb.devcb.p_vend_spec_cb[i])(evt_len, p);
|
||||
@@ -932,16 +977,22 @@ tBTM_STATUS BTM_WritePageTimeout(UINT16 timeout, tBTM_CMPL_CB *p_cb)
|
||||
{
|
||||
BTM_TRACE_EVENT ("BTM: BTM_WritePageTimeout: Timeout: %d.", timeout);
|
||||
|
||||
if (timeout >= HCI_MIN_PAGE_TOUT) {
|
||||
btm_cb.btm_inq_vars.page_timeout = timeout;
|
||||
if (btm_cb.devcb.p_page_to_set_cmpl_cb) {
|
||||
return BTM_BUSY;
|
||||
}
|
||||
|
||||
btm_cb.devcb.p_page_to_set_cmpl_cb = p_cb;
|
||||
|
||||
/* Send the HCI command */
|
||||
if (!btsnd_hcic_write_page_tout (timeout)) {
|
||||
btm_cb.devcb.p_page_to_set_cmpl_cb = NULL;
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
|
||||
if (timeout >= HCI_MIN_PAGE_TOUT) {
|
||||
btm_cb.btm_inq_vars.page_timeout = timeout;
|
||||
}
|
||||
|
||||
if (p_cb) {
|
||||
btu_start_timer(&btm_cb.devcb.page_timeout_set_timer, BTU_TTYPE_BTM_SET_PAGE_TO, BTM_DEV_REPLY_TIMEOUT);
|
||||
}
|
||||
@@ -981,6 +1032,14 @@ tBTM_STATUS BTM_SetMinEncKeySize(UINT8 key_size, tBTM_CMPL_CB *p_cb)
|
||||
status = BTM_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
if (status != BTM_SUCCESS) {
|
||||
if (p_cb) {
|
||||
btm_cb.devcb.p_set_min_enc_key_size_cmpl_cb = NULL;
|
||||
tBTM_SET_MIN_ENC_KEY_SIZE_RESULTS results = {0};
|
||||
results.hci_status = HCI_ERR_MEMORY_FULL;
|
||||
(*p_cb)(&results);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
@@ -1065,7 +1124,7 @@ tBTM_STATUS BTM_ReadPageTimeout(tBTM_CMPL_CB *p_cb)
|
||||
BTM_TRACE_EVENT ("BTM: BTM_ReadPageTimeout");
|
||||
|
||||
/* Get the page timeout */
|
||||
tBTM_GET_PAGE_TIMEOUT_RESULTS results;
|
||||
tBTM_GET_PAGE_TIMEOUT_RESULTS results = {0};
|
||||
|
||||
if (p_cb) {
|
||||
results.hci_status = HCI_SUCCESS;
|
||||
@@ -1142,6 +1201,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb)
|
||||
/* Send the HCI command */
|
||||
btm_cb.devcb.p_stored_link_key_cmpl_cb = p_cb;
|
||||
if (!btsnd_hcic_delete_stored_key (bd_addr, delete_all_flag)) {
|
||||
btm_cb.devcb.p_stored_link_key_cmpl_cb = NULL;
|
||||
return (BTM_NO_RESOURCES);
|
||||
} else {
|
||||
return (BTM_SUCCESS);
|
||||
@@ -1161,7 +1221,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb)
|
||||
void btm_delete_stored_link_key_complete (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_stored_link_key_cmpl_cb;
|
||||
tBTM_DELETE_STORED_LINK_KEY_COMPLETE result;
|
||||
tBTM_DELETE_STORED_LINK_KEY_COMPLETE result = {0};
|
||||
|
||||
/* If there was a callback registered for read stored link key, call it */
|
||||
btm_cb.devcb.p_stored_link_key_cmpl_cb = NULL;
|
||||
@@ -1232,6 +1292,7 @@ tBTM_STATUS BTM_SetAfhChannels (AFH_CHANNELS channels, tBTM_CMPL_CB *p_afh_chann
|
||||
btm_cb.devcb.p_afh_channels_cmpl_cb = p_afh_channels_cmpl_cback;
|
||||
|
||||
if (!btsnd_hcic_set_afh_channels (channels)) {
|
||||
btm_cb.devcb.p_afh_channels_cmpl_cb = NULL;
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,11 +213,11 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter
|
||||
memcpy (temp_lap[0], limited_inq_lap, LAP_LEN);
|
||||
memcpy (temp_lap[1], general_inq_lap, LAP_LEN);
|
||||
|
||||
if (!btsnd_hcic_write_cur_iac_lap (2, (LAP * const) temp_lap)) {
|
||||
if (!btsnd_hcic_write_cur_iac_lap (2, temp_lap)) {
|
||||
return (BTM_NO_RESOURCES); /* Cannot continue */
|
||||
}
|
||||
} else {
|
||||
if (!btsnd_hcic_write_cur_iac_lap (1, (LAP * const) &general_inq_lap)) {
|
||||
if (!btsnd_hcic_write_cur_iac_lap (1, &general_inq_lap)) {
|
||||
return (BTM_NO_RESOURCES); /* Cannot continue */
|
||||
}
|
||||
}
|
||||
@@ -290,7 +290,8 @@ tBTM_STATUS BTM_SetInquiryScanType (UINT16 scan_type)
|
||||
}
|
||||
|
||||
/* whatever app wants if device is not 1.2 scan type should be STANDARD */
|
||||
if (!controller_get_interface()->supports_interlaced_inquiry_scan()) {
|
||||
if ((scan_type == BTM_SCAN_TYPE_INTERLACED) &&
|
||||
!controller_get_interface()->supports_interlaced_inquiry_scan()) {
|
||||
return (BTM_MODE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@@ -329,7 +330,8 @@ tBTM_STATUS BTM_SetPageScanType (UINT16 scan_type)
|
||||
}
|
||||
|
||||
/* whatever app wants if device is not 1.2 scan type should be STANDARD */
|
||||
if (!controller_get_interface()->supports_interlaced_inquiry_scan()) {
|
||||
if ((scan_type == BTM_SCAN_TYPE_INTERLACED) &&
|
||||
!controller_get_interface()->supports_interlaced_page_scan()) {
|
||||
return (BTM_MODE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@@ -368,6 +370,10 @@ tBTM_STATUS BTM_SetInquiryMode (UINT8 mode)
|
||||
{
|
||||
const controller_t *controller = controller_get_interface();
|
||||
BTM_TRACE_API ("BTM_SetInquiryMode\n");
|
||||
if (!BTM_IsDeviceUp()) {
|
||||
return (BTM_WRONG_MODE);
|
||||
}
|
||||
|
||||
if (mode == BTM_INQ_RESULT_STANDARD) {
|
||||
/* mandatory mode */
|
||||
} else if (mode == BTM_INQ_RESULT_WITH_RSSI) {
|
||||
@@ -382,10 +388,6 @@ tBTM_STATUS BTM_SetInquiryMode (UINT8 mode)
|
||||
return (BTM_ILLEGAL_VALUE);
|
||||
}
|
||||
|
||||
if (!BTM_IsDeviceUp()) {
|
||||
return (BTM_WRONG_MODE);
|
||||
}
|
||||
|
||||
if (!btsnd_hcic_write_inquiry_mode (mode)) {
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
@@ -519,7 +521,7 @@ tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, UINT16 max_d
|
||||
/* If set filter command is not successful reset the state */
|
||||
p_inq->p_inq_results_cb = NULL;
|
||||
p_inq->state = BTM_INQ_INACTIVE_STATE;
|
||||
|
||||
p_inq->inq_active = BTM_INQUIRY_INACTIVE;
|
||||
}
|
||||
|
||||
return (status);
|
||||
@@ -631,11 +633,11 @@ tBTM_STATUS BTM_SetConnectability (UINT16 page_mode, UINT16 window, UINT16 inter
|
||||
|
||||
if ((window != p_inq->page_scan_window) ||
|
||||
(interval != p_inq->page_scan_period)) {
|
||||
p_inq->page_scan_window = window;
|
||||
p_inq->page_scan_period = interval;
|
||||
if (!btsnd_hcic_write_pagescan_cfg (interval, window)) {
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
p_inq->page_scan_window = window;
|
||||
p_inq->page_scan_period = interval;
|
||||
}
|
||||
|
||||
/* Keep the inquiry scan as previouosly set */
|
||||
@@ -804,10 +806,8 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p
|
||||
/* Only one active inquiry is allowed in this implementation.
|
||||
Also do not allow an inquiry if the inquiry filter is being updated */
|
||||
if (p_inq->inq_active || p_inq->inqfilt_active) {
|
||||
{
|
||||
return (BTM_BUSY);
|
||||
BTM_TRACE_API("BTM_StartInquiry: return BUSY\n");
|
||||
}
|
||||
BTM_TRACE_API("BTM_StartInquiry: return BUSY\n");
|
||||
return (BTM_BUSY);
|
||||
} else {
|
||||
p_inq->scan_type = INQ_GENERAL;
|
||||
}
|
||||
@@ -911,8 +911,9 @@ tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb
|
||||
/* Use the remote device's clock offset if it is in the local inquiry database */
|
||||
if ((p_i = btm_inq_db_find (remote_bda)) != NULL) {
|
||||
p_cur = &p_i->inq_info;
|
||||
} else {
|
||||
BTM_TRACE_API ("no device found in inquiry db\n");
|
||||
}
|
||||
BTM_TRACE_API ("no device found in inquiry db\n");
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
if (transport == BT_TRANSPORT_LE) {
|
||||
@@ -1049,7 +1050,7 @@ tBTM_INQ_INFO *BTM_InqDbNext (tBTM_INQ_INFO *p_cur)
|
||||
}
|
||||
}
|
||||
|
||||
/* If here, more entries found */
|
||||
/* If here, no entries found */
|
||||
return ((tBTM_INQ_INFO *)NULL);
|
||||
} else {
|
||||
return (BTM_InqDbFirst());
|
||||
@@ -1194,9 +1195,9 @@ tBTM_STATUS BTM_WriteInquiryTxPower(INT8 tx_power, tBTM_CMPL_CB *p_cb)
|
||||
*******************************************************************************/
|
||||
void btm_inq_db_reset (void)
|
||||
{
|
||||
tBTM_REMOTE_DEV_NAME rem_name;
|
||||
tBTM_REMOTE_DEV_NAME rem_name = {0};
|
||||
tBTM_INQUIRY_CMPL cmpl_param = {0};
|
||||
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
|
||||
UINT8 num_responses;
|
||||
UINT8 temp_inq_active;
|
||||
tBTM_STATUS status;
|
||||
|
||||
@@ -1212,16 +1213,18 @@ void btm_inq_db_reset (void)
|
||||
if (temp_inq_active == BTM_LIMITED_INQUIRY_ACTIVE ||
|
||||
temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE) {
|
||||
if (p_inq->p_inq_cmpl_cb) {
|
||||
num_responses = 0;
|
||||
(*p_inq->p_inq_cmpl_cb)(&num_responses);
|
||||
cmpl_param.status = BTM_SUCCESS;
|
||||
cmpl_param.num_resp = 0;
|
||||
(*p_inq->p_inq_cmpl_cb)(&cmpl_param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Cancel a remote name request if active, and notify the caller (if waiting) */
|
||||
if (p_inq->remname_active ) {
|
||||
if (p_inq->remname_active) {
|
||||
btu_stop_timer (&p_inq->rmt_name_timer_ent);
|
||||
p_inq->remname_active = FALSE;
|
||||
memcpy(rem_name.bd_addr, p_inq->remname_bda, BD_ADDR_LEN);
|
||||
memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
|
||||
|
||||
if (p_inq->p_remname_cmpl_cb) {
|
||||
@@ -1560,13 +1563,12 @@ static tBTM_STATUS btm_set_inq_event_filter (UINT8 filter_cond_type,
|
||||
return (BTM_ILLEGAL_VALUE); /* Bad parameter was passed in */
|
||||
}
|
||||
|
||||
btm_cb.btm_inq_vars.inqfilt_active = TRUE;
|
||||
|
||||
/* Filter the inquiry results for the specified condition type and value */
|
||||
if (btsnd_hcic_set_event_filter(HCI_FILTER_INQUIRY_RESULT, filter_cond_type,
|
||||
p_cond, condition_length))
|
||||
|
||||
{
|
||||
btm_cb.btm_inq_vars.inqfilt_active = TRUE;
|
||||
return (BTM_CMD_STARTED);
|
||||
} else {
|
||||
return (BTM_NO_RESOURCES);
|
||||
@@ -1734,7 +1736,7 @@ static void btm_initiate_inquiry (tBTM_INQUIRY_VAR_ST *p_inq)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
|
||||
void btm_process_inq_results (UINT8 *p, UINT16 evt_len, UINT8 inq_res_mode)
|
||||
{
|
||||
UINT8 num_resp, xx;
|
||||
BD_ADDR bda;
|
||||
@@ -1752,6 +1754,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
|
||||
DEV_CLASS dc;
|
||||
UINT16 clock_offset;
|
||||
UINT8 *p_eir_data = NULL;
|
||||
UINT16 remain_len = evt_len;
|
||||
|
||||
#if (BTM_INQ_DEBUG == TRUE)
|
||||
BTM_TRACE_DEBUG ("btm_process_inq_results inq_active:0x%x state:%d inqfilt_active:%d inq_res_mode=%d\n",
|
||||
@@ -1762,23 +1765,45 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
|
||||
return;
|
||||
}
|
||||
|
||||
if (remain_len < 1) {
|
||||
return;
|
||||
}
|
||||
STREAM_TO_UINT8 (num_resp, p);
|
||||
remain_len -= 1;
|
||||
|
||||
for (xx = 0; xx < num_resp; xx++) {
|
||||
update = FALSE;
|
||||
is_new = TRUE;
|
||||
|
||||
if (remain_len < 8) {
|
||||
return;
|
||||
}
|
||||
/* Extract inquiry results */
|
||||
STREAM_TO_BDADDR (bda, p);
|
||||
STREAM_TO_UINT8 (page_scan_rep_mode, p);
|
||||
STREAM_TO_UINT8 (page_scan_per_mode, p);
|
||||
remain_len -= 8;
|
||||
|
||||
if (inq_res_mode == BTM_INQ_RESULT_STANDARD) {
|
||||
if (remain_len < 1) {
|
||||
return;
|
||||
}
|
||||
STREAM_TO_UINT8(page_scan_mode, p);
|
||||
remain_len -= 1;
|
||||
}
|
||||
|
||||
if (remain_len < 5) {
|
||||
return;
|
||||
}
|
||||
STREAM_TO_DEVCLASS (dc, p);
|
||||
STREAM_TO_UINT16 (clock_offset, p);
|
||||
remain_len -= 5;
|
||||
if (inq_res_mode != BTM_INQ_RESULT_STANDARD) {
|
||||
if (remain_len < 1) {
|
||||
return;
|
||||
}
|
||||
STREAM_TO_UINT8(rssi, p);
|
||||
remain_len -= 1;
|
||||
}
|
||||
|
||||
p_i = btm_inq_db_find (bda);
|
||||
@@ -2101,13 +2126,6 @@ tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
|
||||
if (p_inq->remname_active) {
|
||||
return (BTM_BUSY);
|
||||
} else {
|
||||
/* If there is no remote name request running,call the callback function and start timer */
|
||||
p_inq->p_remname_cmpl_cb = p_cb;
|
||||
memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
|
||||
btu_start_timer (&p_inq->rmt_name_timer_ent,
|
||||
BTU_TTYPE_BTM_RMT_NAME,
|
||||
timeout);
|
||||
|
||||
/* If the database entry exists for the device, use its clock offset */
|
||||
if (p_cur) {
|
||||
cmd_ok = btsnd_hcic_rmt_name_req (remote_bda,
|
||||
@@ -2120,6 +2138,10 @@ tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
|
||||
HCI_MANDATARY_PAGE_SCAN_MODE, 0);
|
||||
}
|
||||
if (cmd_ok) {
|
||||
/* If there is no remote name request running,call the callback function and start timer */
|
||||
p_inq->p_remname_cmpl_cb = p_cb;
|
||||
memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
|
||||
btu_start_timer (&p_inq->rmt_name_timer_ent, BTU_TTYPE_BTM_RMT_NAME, timeout);
|
||||
p_inq->remname_active = TRUE;
|
||||
return BTM_CMD_STARTED;
|
||||
} else {
|
||||
@@ -2144,7 +2166,7 @@ tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
|
||||
*******************************************************************************/
|
||||
void btm_process_remote_name (BD_ADDR bda, BD_NAME bdn, UINT16 evt_len, UINT8 hci_status)
|
||||
{
|
||||
tBTM_REMOTE_DEV_NAME rem_name;
|
||||
tBTM_REMOTE_DEV_NAME rem_name = {0};
|
||||
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
|
||||
tBTM_CMPL_CB *p_cb = p_inq->p_remname_cmpl_cb;
|
||||
UINT8 *p_n1;
|
||||
@@ -2250,36 +2272,36 @@ void btm_inq_rmt_name_failed (void)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void btm_read_iscan_tx_power_complete(UINT8 *p)
|
||||
void btm_read_iscan_tx_power_complete(UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_read_iscan_txpwer_cmpl_cb;
|
||||
tBTM_READ_TX_PWR_LVL_RESULTS results;
|
||||
|
||||
memset(&results, 0, sizeof(results));
|
||||
results.type = BTM_TX_PWR_LVL_ISCAN;
|
||||
results.status = BTM_ERR_PROCESSING;
|
||||
|
||||
btu_stop_timer (&btm_cb.devcb.read_iscan_txpwer_timer);
|
||||
/* If there was a callback registered for read inq tx power, call it */
|
||||
btm_cb.devcb.p_read_iscan_txpwer_cmpl_cb = NULL;
|
||||
|
||||
if (p_cb) {
|
||||
if (p) {
|
||||
STREAM_TO_UINT8 (results.hci_status, p);
|
||||
if (!p_cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
if (evt_len >= 2) {
|
||||
STREAM_TO_UINT8 (results.hci_status, p);
|
||||
if (results.hci_status == HCI_SUCCESS) {
|
||||
results.status = BTM_SUCCESS;
|
||||
|
||||
STREAM_TO_UINT8 (results.tx_power, p);
|
||||
BTM_TRACE_EVENT ("BTM INQ TX POWER Complete: tx_power %d, hci status 0x%02x\n",
|
||||
results.tx_power, results.hci_status);
|
||||
} else {
|
||||
results.status = BTM_ERR_PROCESSING;
|
||||
}
|
||||
} else {
|
||||
results.status = BTM_ERR_PROCESSING;
|
||||
}
|
||||
(*p_cb)(&results);
|
||||
}
|
||||
|
||||
(*p_cb)(&results);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -2291,26 +2313,31 @@ void btm_read_iscan_tx_power_complete(UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void btm_write_inq_tx_power_complete(UINT8 *p)
|
||||
void btm_write_inq_tx_power_complete(UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_write_inq_txpwer_cmpl_cb;
|
||||
tBTM_WRITE_TX_PWR_LVL_RESULTS results;
|
||||
tBTM_WRITE_TX_PWR_LVL_RESULTS results = {0};
|
||||
|
||||
memset(&results, 0, sizeof(results));
|
||||
results.type = BTM_TX_PWR_LVL_INQ;
|
||||
results.status = BTM_ERR_PROCESSING;
|
||||
|
||||
btu_stop_timer(&btm_cb.devcb.write_inq_txpwer_timer);
|
||||
btm_cb.devcb.p_write_inq_txpwer_cmpl_cb = NULL;
|
||||
|
||||
if (p_cb) {
|
||||
if (p) {
|
||||
STREAM_TO_UINT8(results.hci_status, p);
|
||||
results.status = (results.hci_status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING;
|
||||
} else {
|
||||
results.status = BTM_ERR_PROCESSING;
|
||||
}
|
||||
(*p_cb)(&results);
|
||||
if (!p_cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
if (evt_len >= 1) {
|
||||
STREAM_TO_UINT8(results.hci_status, p);
|
||||
if (results.hci_status == HCI_SUCCESS) {
|
||||
results.status = BTM_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*p_cb)(&results);
|
||||
}
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
@@ -2326,19 +2353,25 @@ void btm_write_inq_tx_power_complete(UINT8 *p)
|
||||
**
|
||||
** Returns BTM_SUCCESS - if successful
|
||||
** BTM_MODE_UNSUPPORTED - if local device cannot support it
|
||||
** BTM_NO_RESOURCES - if command failed to issue
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff, BOOLEAN fec_required)
|
||||
{
|
||||
tBTM_STATUS status = BTM_SUCCESS;
|
||||
if (controller_get_interface()->supports_extended_inquiry_response()) {
|
||||
BTM_TRACE_API("Write Extended Inquiry Response to controller\n");
|
||||
btsnd_hcic_write_ext_inquiry_response (p_buff, fec_required);
|
||||
osi_free(p_buff);
|
||||
return BTM_SUCCESS;
|
||||
if (!btsnd_hcic_write_ext_inquiry_response (p_buff, fec_required)) {
|
||||
status = BTM_NO_RESOURCES;
|
||||
}
|
||||
} else {
|
||||
osi_free(p_buff);
|
||||
return BTM_MODE_UNSUPPORTED;
|
||||
status = BTM_MODE_UNSUPPORTED;
|
||||
}
|
||||
if (p_buff) {
|
||||
osi_free(p_buff);
|
||||
p_buff = NULL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -2357,18 +2390,12 @@ tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff, BOOLEAN fec_required)
|
||||
UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
|
||||
{
|
||||
UINT8 *p = p_eir;
|
||||
UINT8 *p_data_length = p_length;
|
||||
UINT8 temp_length = 0;
|
||||
UINT8 *p_data_length = (p_length ? p_length : &temp_length);
|
||||
UINT8 length;
|
||||
UINT8 eir_type;
|
||||
BTM_TRACE_API("BTM_CheckEirData type=0x%02X\n", type);
|
||||
|
||||
if (!p_length) {
|
||||
if ((p_data_length = (UINT8 *)osi_malloc(sizeof(UINT8))) == NULL) {
|
||||
BTM_TRACE_ERROR("%s: Memory allocation failed.", __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
STREAM_TO_UINT8(length, p);
|
||||
while ( length ) {
|
||||
STREAM_TO_UINT8(eir_type, p);
|
||||
@@ -2398,9 +2425,6 @@ UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
|
||||
p = NULL;
|
||||
|
||||
exit:
|
||||
if (!p_length) {
|
||||
osi_free(p_data_length);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "stack/bt_types.h"
|
||||
#include "common/bt_target.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "btm_int.h"
|
||||
#include "osi/allocator.h"
|
||||
@@ -61,14 +62,17 @@ void btm_init (void)
|
||||
{
|
||||
#if BTM_DYNAMIC_MEMORY
|
||||
btm_cb_ptr = (tBTM_CB *)osi_malloc(sizeof(tBTM_CB));
|
||||
assert(btm_cb_ptr != NULL);
|
||||
#endif /* #if BTM_DYNAMIC_MEMORY */
|
||||
/* All fields are cleared; nonzero fields are reinitialized in appropriate function */
|
||||
memset(&btm_cb, 0, sizeof(tBTM_CB));
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
btm_cb.page_queue = fixed_queue_new(QUEUE_SIZE_MAX);
|
||||
assert(btm_cb.page_queue != NULL);
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
btm_cb.sec_pending_q = fixed_queue_new(QUEUE_SIZE_MAX);
|
||||
assert(btm_cb.sec_pending_q != NULL);
|
||||
#endif // (SMP_INCLUDED == TRUE)
|
||||
#if defined(BTM_INITIAL_TRACE_LEVEL)
|
||||
btm_cb.trace_level = BTM_INITIAL_TRACE_LEVEL;
|
||||
@@ -114,6 +118,11 @@ void btm_init (void)
|
||||
*******************************************************************************/
|
||||
void btm_free(void)
|
||||
{
|
||||
#if BTM_DYNAMIC_MEMORY
|
||||
if (!btm_cb_ptr) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
fixed_queue_free(btm_cb.page_queue, osi_free_func);
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
@@ -125,6 +134,7 @@ void btm_free(void)
|
||||
#if BTM_SCO_INCLUDED == TRUE
|
||||
btm_sco_free();
|
||||
#endif
|
||||
FREE_AND_RESET(btm_cb.btm_inq_vars.p_bd_db);
|
||||
#if BTM_DYNAMIC_MEMORY
|
||||
FREE_AND_RESET(btm_cb_ptr);
|
||||
#endif
|
||||
|
||||
@@ -195,6 +195,19 @@ 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;
|
||||
|
||||
switch (mode) {
|
||||
case BTM_PM_MD_ACTIVE:
|
||||
case BTM_PM_MD_HOLD:
|
||||
case BTM_PM_MD_SNIFF:
|
||||
case BTM_PM_MD_PARK: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return BTM_ILLEGAL_VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p_acl_cb = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
|
||||
if (p_acl_cb == NULL){
|
||||
return BTM_UNKNOWN_ADDR;
|
||||
@@ -321,6 +334,9 @@ tBTM_STATUS BTM_SetSsrParams (BD_ADDR remote_bda, UINT16 max_lat,
|
||||
return (BTM_UNKNOWN_ADDR);
|
||||
}
|
||||
p_cb = p_acl_cb->p_pm_mode_db;
|
||||
if (!p_cb) {
|
||||
return BTM_NO_RESOURCES;
|
||||
}
|
||||
|
||||
if (BTM_PM_STS_ACTIVE == p_cb->state ||
|
||||
BTM_PM_STS_SNIFF == p_cb->state) {
|
||||
@@ -352,6 +368,7 @@ tBTM_STATUS BTM_SetSsrParams (BD_ADDR remote_bda, UINT16 max_lat,
|
||||
void btm_pm_reset(void)
|
||||
{
|
||||
int xx;
|
||||
tACL_CONN *p_acl_cb = NULL;
|
||||
tBTM_PM_STATUS_CBACK *cb = NULL;
|
||||
|
||||
/* clear the pending request for application */
|
||||
@@ -367,7 +384,11 @@ void btm_pm_reset(void)
|
||||
}
|
||||
|
||||
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);
|
||||
p_acl_cb = btm_handle_to_acl(btm_cb.pm_pend_link_hdl);
|
||||
if (p_acl_cb != NULL) {
|
||||
/* safe to use remote_addr */
|
||||
(*cb)(p_acl_cb->remote_addr, BTM_PM_STS_ERROR, BTM_DEV_RESET, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* no command pending */
|
||||
@@ -674,15 +695,22 @@ static void btm_pm_check_stored(void)
|
||||
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);
|
||||
p_acl_cb = list_node(p_node);
|
||||
if (!p_acl_cb || !p_acl_cb->p_pm_mode_db) {
|
||||
continue;
|
||||
}
|
||||
if (p_acl_cb->p_pm_mode_db->state & BTM_PM_STORED_MASK) {
|
||||
tBTM_PM_STATE old_state = p_acl_cb->p_pm_mode_db->state;
|
||||
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;
|
||||
tBTM_STATUS status = btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, p_acl_cb->hci_handle, NULL);
|
||||
if (status == BTM_CMD_STARTED) {
|
||||
break;
|
||||
} else if (status == BTM_NO_RESOURCES) {
|
||||
p_acl_cb->p_pm_mode_db->state = old_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -757,9 +785,9 @@ void btm_pm_proc_cmd_status(UINT8 status)
|
||||
*******************************************************************************/
|
||||
void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, UINT16 interval)
|
||||
{
|
||||
int i;
|
||||
tACL_CONN *p;
|
||||
tBTM_PM_MCB *p_cb = NULL;
|
||||
int yy;
|
||||
tBTM_PM_STATE old_state;
|
||||
tL2C_LCB *p_lcb;
|
||||
|
||||
@@ -768,9 +796,12 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* update control block */
|
||||
p_cb = p->p_pm_mode_db;
|
||||
if (!p_cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
old_state = p_cb->state;
|
||||
p_cb->state = mode;
|
||||
p_cb->interval = interval;
|
||||
@@ -787,39 +818,32 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U
|
||||
}
|
||||
|
||||
/* notify registered parties */
|
||||
for (yy = 0; yy <= BTM_MAX_PM_RECORDS; yy++) {
|
||||
for (i = 0; i <= BTM_MAX_PM_RECORDS; i++) {
|
||||
/* set req_mode HOLD mode->ACTIVE */
|
||||
if ( (mode == BTM_PM_MD_ACTIVE) && (p_cb->req_mode[yy].mode == BTM_PM_MD_HOLD) ) {
|
||||
p_cb->req_mode[yy].mode = BTM_PM_MD_ACTIVE;
|
||||
if ( (mode == BTM_PM_MD_ACTIVE) && (p_cb->req_mode[i].mode == BTM_PM_MD_HOLD) ) {
|
||||
p_cb->req_mode[i].mode = BTM_PM_MD_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/* new request has been made. - post a message to BTU task */
|
||||
if (old_state & BTM_PM_STORED_MASK) {
|
||||
#if BTM_PM_DEBUG == TRUE
|
||||
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending stored req:%d", xx);
|
||||
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending stored req");
|
||||
#endif // BTM_PM_DEBUG
|
||||
btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL);
|
||||
} else {
|
||||
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 (p_cb->chg_ind == TRUE) {
|
||||
#if BTM_PM_DEBUG == TRUE
|
||||
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending PM req :%d", zz);
|
||||
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending PM req");
|
||||
#endif // BTM_PM_DEBUG
|
||||
btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL);
|
||||
break;
|
||||
}
|
||||
btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* notify registered parties */
|
||||
for (yy = 0; yy < BTM_MAX_PM_RECORDS; yy++) {
|
||||
if (btm_cb.pm_reg_db[yy].mask & BTM_PM_REG_NOTIF) {
|
||||
(*btm_cb.pm_reg_db[yy].cback)( p->remote_addr, mode, interval, hci_status);
|
||||
for (i = 0; i < BTM_MAX_PM_RECORDS; i++) {
|
||||
if (btm_cb.pm_reg_db[i].mask & BTM_PM_REG_NOTIF) {
|
||||
(*btm_cb.pm_reg_db[i].cback)( p->remote_addr, mode, interval, hci_status);
|
||||
}
|
||||
}
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
@@ -861,6 +885,9 @@ void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len)
|
||||
return;
|
||||
}
|
||||
p_cb = p_acl->p_pm_mode_db;
|
||||
if (!p_cb) {
|
||||
return;
|
||||
}
|
||||
if (p_cb->interval == max_rx_lat) {
|
||||
/* using legacy sniff */
|
||||
use_ssr = FALSE;
|
||||
|
||||
@@ -135,7 +135,7 @@ static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] = {
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
static BOOLEAN btm_dev_authenticated (tBTM_SEC_DEV_REC *p_dev_rec)
|
||||
{
|
||||
if (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) {
|
||||
if (p_dev_rec && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)) {
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
@@ -291,6 +291,12 @@ BOOLEAN BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
|
||||
if (btm_cb.p_rmt_name_callback[i] == p_callback) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
|
||||
if (btm_cb.p_rmt_name_callback[i] == NULL) {
|
||||
btm_cb.p_rmt_name_callback[i] = p_callback;
|
||||
@@ -316,6 +322,10 @@ BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (p_callback == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
|
||||
if (btm_cb.p_rmt_name_callback[i] == p_callback) {
|
||||
btm_cb.p_rmt_name_callback[i] = NULL;
|
||||
@@ -339,6 +349,10 @@ BOOLEAN BTM_GetSecurityFlags (BD_ADDR bd_addr, UINT8 *p_sec_flags)
|
||||
{
|
||||
tBTM_SEC_DEV_REC *p_dev_rec;
|
||||
|
||||
if (!bd_addr || !p_sec_flags) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL) {
|
||||
*p_sec_flags = (UINT8) p_dev_rec->sec_flags;
|
||||
return (TRUE);
|
||||
@@ -366,6 +380,10 @@ BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 *p_sec_flags,
|
||||
{
|
||||
tBTM_SEC_DEV_REC *p_dev_rec;
|
||||
|
||||
if (!bd_addr || !p_sec_flags) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL) {
|
||||
if (transport == BT_TRANSPORT_BR_EDR) {
|
||||
*p_sec_flags = (UINT8) p_dev_rec->sec_flags;
|
||||
@@ -396,8 +414,8 @@ BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 *p_sec_flags,
|
||||
*******************************************************************************/
|
||||
void BTM_SetPinType (UINT8 pin_type, PIN_CODE pin_code, UINT8 pin_code_len)
|
||||
{
|
||||
BTM_TRACE_API ("BTM_SetPinType: pin type %d [variable-0, fixed-1], code %s, length %d\n",
|
||||
pin_type, (char *) pin_code, pin_code_len);
|
||||
BTM_TRACE_API ("BTM_SetPinType: pin type %d [variable-0, fixed-1], code %.*s, length %d\n",
|
||||
pin_type, pin_code_len, (char *) pin_code, pin_code_len);
|
||||
|
||||
/* If device is not up security mode will be set as a part of startup */
|
||||
if ( (btm_cb.cfg.pin_type != pin_type)
|
||||
@@ -757,6 +775,9 @@ UINT8 BTM_SecClrService (UINT8 service_id)
|
||||
#if (L2CAP_UCD_INCLUDED == TRUE)
|
||||
p_srec->ucd_security_flags = 0;
|
||||
#endif
|
||||
if (btm_cb.p_out_serv == p_srec) {
|
||||
btm_cb.p_out_serv = NULL;
|
||||
}
|
||||
num_freed++;
|
||||
}
|
||||
}
|
||||
@@ -793,6 +814,9 @@ UINT8 btm_sec_clr_service_by_psm (UINT16 psm)
|
||||
if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm == psm) ) {
|
||||
BTM_TRACE_API("BTM_SEC_CLR[%d]: id %d\n", i, p_srec->service_id);
|
||||
p_srec->security_flags = 0;
|
||||
#if (L2CAP_UCD_INCLUDED == TRUE)
|
||||
p_srec->ucd_security_flags = 0;
|
||||
#endif
|
||||
num_freed++;
|
||||
}
|
||||
}
|
||||
@@ -883,12 +907,11 @@ void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin,
|
||||
/* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
|
||||
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
|
||||
btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
|
||||
|
||||
btsnd_hcic_pin_code_neg_reply (bd_addr);
|
||||
} else {
|
||||
p_dev_rec->security_required = BTM_SEC_NONE;
|
||||
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
|
||||
}
|
||||
btsnd_hcic_pin_code_neg_reply (bd_addr);
|
||||
return;
|
||||
}
|
||||
if (trusted_mask) {
|
||||
@@ -1025,7 +1048,8 @@ tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
|
||||
if (p_pin && (pin_len <= PIN_CODE_LEN) && (pin_len != 0)) {
|
||||
btm_cb.pin_code_len = pin_len;
|
||||
p_dev_rec->pin_code_length = pin_len;
|
||||
memcpy (btm_cb.pin_code, p_pin, PIN_CODE_LEN);
|
||||
memset (btm_cb.pin_code, 0, PIN_CODE_LEN);
|
||||
memcpy (btm_cb.pin_code, p_pin, pin_len);
|
||||
}
|
||||
#endif ///CLASSIC_BT_INCLUDED == TRUE
|
||||
|
||||
@@ -1324,8 +1348,8 @@ tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key)
|
||||
** BTM_UNKNOWN_ADDR if Security Manager does not know about
|
||||
** the device or device record does not contain link key info
|
||||
**
|
||||
** Returns BTM_LKEY_TYPE_IGNORE if link key is unknown, link type
|
||||
** otherwise.
|
||||
** Returns Link key type for the specified device, or BTM_LKEY_TYPE_IGNORE
|
||||
** if no valid link key is available.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType (BD_ADDR bd_addr)
|
||||
@@ -1403,7 +1427,6 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SE
|
||||
|
||||
return (BTM_SUCCESS);
|
||||
}
|
||||
p_dev_rec->enc_init_by_we = TRUE;
|
||||
/* enqueue security request if security is active */
|
||||
if (p_dev_rec->p_callback || (p_dev_rec->sec_state != BTM_SEC_STATE_IDLE)) {
|
||||
BTM_TRACE_WARNING ("Security Manager: BTM_SetEncryption busy, enqueue request\n");
|
||||
@@ -1418,6 +1441,11 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SE
|
||||
}
|
||||
}
|
||||
|
||||
UINT16 old_security_required = p_dev_rec->security_required;
|
||||
BOOLEAN old_is_originator = p_dev_rec->is_originator;
|
||||
BOOLEAN old_enc_init_by_we = p_dev_rec->enc_init_by_we;
|
||||
|
||||
p_dev_rec->enc_init_by_we = TRUE;
|
||||
p_dev_rec->p_callback = p_callback;
|
||||
p_dev_rec->p_ref_data = p_ref_data;
|
||||
p_dev_rec->security_required |= (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT);
|
||||
@@ -1443,9 +1471,17 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SE
|
||||
}
|
||||
|
||||
if (rc != BTM_CMD_STARTED && rc != BTM_BUSY) {
|
||||
if (p_callback) {
|
||||
if (rc != BTM_SUCCESS) {
|
||||
p_dev_rec->p_callback = NULL;
|
||||
p_dev_rec->p_ref_data = NULL;
|
||||
p_dev_rec->security_required = old_security_required;
|
||||
p_dev_rec->is_originator = old_is_originator;
|
||||
p_dev_rec->enc_init_by_we = old_enc_init_by_we;
|
||||
} else {
|
||||
p_dev_rec->p_callback = NULL;
|
||||
(*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, rc);
|
||||
}
|
||||
if (p_callback) {
|
||||
(*p_callback) (bd_addr, transport, p_ref_data, rc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1493,14 +1529,16 @@ static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UIN
|
||||
break;
|
||||
}
|
||||
|
||||
#if BTM_DISC_DURING_RS == TRUE
|
||||
/* If a role switch is in progress, delay the HCI Disconnect to avoid controller problem */
|
||||
if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING && p_dev_rec->hci_handle == conn_handle) {
|
||||
BTM_TRACE_DEBUG("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect\n");
|
||||
p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
|
||||
status = BTM_SUCCESS;
|
||||
}
|
||||
} else
|
||||
/* Tear down the HCI link */
|
||||
else if (!btsnd_hcic_disconnect (conn_handle, reason)) {
|
||||
#endif
|
||||
if (!btsnd_hcic_disconnect (conn_handle, reason)) {
|
||||
/* could not send disconnect. restore old state */
|
||||
p_dev_rec->sec_state = old_state;
|
||||
status = BTM_NO_RESOURCES;
|
||||
@@ -1637,7 +1675,9 @@ void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
|
||||
{
|
||||
/* This API only make sense between PASSKEY_REQ and SP complete */
|
||||
if (btm_cb.pairing_state == BTM_PAIR_STATE_KEY_ENTRY) {
|
||||
btsnd_hcic_send_keypress_notif (bd_addr, type);
|
||||
if (bd_addr) {
|
||||
btsnd_hcic_send_keypress_notif (bd_addr, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
|
||||
@@ -1959,7 +1999,7 @@ void BTM_SetOutService(BD_ADDR bd_addr, UINT8 service_id, UINT32 mx_chan_id)
|
||||
tBTM_SEC_DEV_REC *p_dev_rec;
|
||||
tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
|
||||
|
||||
btm_cb.p_out_serv = p_serv_rec;
|
||||
btm_cb.p_out_serv = NULL;
|
||||
p_dev_rec = btm_find_dev (bd_addr);
|
||||
|
||||
for (int i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++) {
|
||||
@@ -2017,6 +2057,7 @@ static BOOLEAN btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC *p_dev_rec, BOOLEAN
|
||||
/* has unauthenticated
|
||||
link key */
|
||||
&& (p_dev_rec->rmt_io_caps < BTM_IO_CAP_MAX) /* a valid peer IO cap */
|
||||
&& (btm_cb.devcb.loc_io_caps < BTM_IO_CAP_MAX) /* a valid local IO cap */
|
||||
&& (btm_sec_io_map[p_dev_rec->rmt_io_caps][btm_cb.devcb.loc_io_caps]))
|
||||
/* authenticated
|
||||
link key is possible */
|
||||
@@ -2129,6 +2170,12 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
|
||||
|
||||
/* Find or get oldest record */
|
||||
p_dev_rec = btm_find_or_alloc_dev (bd_addr);
|
||||
if (!p_dev_rec) {
|
||||
if (p_callback) {
|
||||
(*p_callback) (bd_addr, transport, p_ref_data, BTM_NO_RESOURCES);
|
||||
}
|
||||
return BTM_NO_RESOURCES;
|
||||
}
|
||||
|
||||
p_dev_rec->hci_handle = handle;
|
||||
|
||||
@@ -2464,6 +2511,12 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
|
||||
BTM_TRACE_DEBUG ("%s() is_originator: %d\n", __func__, is_originator);
|
||||
/* Find or get oldest record */
|
||||
p_dev_rec = btm_find_or_alloc_dev (bd_addr);
|
||||
if (!p_dev_rec) {
|
||||
if (p_callback) {
|
||||
(*p_callback)(bd_addr, transport, p_ref_data, BTM_NO_RESOURCES);
|
||||
}
|
||||
return BTM_NO_RESOURCES;
|
||||
}
|
||||
|
||||
/* Find the service record for the PSM */
|
||||
p_serv_rec = btm_sec_find_mx_serv (is_originator, psm, mx_proto_id, mx_chan_id);
|
||||
@@ -2550,8 +2603,14 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
|
||||
}
|
||||
if (rc == BTM_CMD_STARTED) {
|
||||
BTM_TRACE_EVENT("%s: call btm_sec_queue_mx_request\n", __FUNCTION__);
|
||||
btm_sec_queue_mx_request (bd_addr, psm, is_originator, mx_proto_id,
|
||||
mx_chan_id, p_callback, p_ref_data);
|
||||
BOOLEAN ret = btm_sec_queue_mx_request (bd_addr, psm, is_originator, mx_proto_id,
|
||||
mx_chan_id, p_callback, p_ref_data);
|
||||
if (!ret) {
|
||||
rc = BTM_NO_RESOURCES;
|
||||
if (p_callback) {
|
||||
(*p_callback) (bd_addr, transport, p_ref_data, (UINT8)rc);
|
||||
}
|
||||
}
|
||||
} else { /* rc == BTM_SUCCESS */
|
||||
/* access granted */
|
||||
if (p_callback) {
|
||||
@@ -2903,7 +2962,7 @@ void btm_sec_dev_reset (void)
|
||||
/* set the default IO capabilities */
|
||||
btm_cb.devcb.loc_io_caps = BTM_LOCAL_IO_CAPS;
|
||||
/* add mx service to use no security */
|
||||
BTM_SetSecurityLevel(FALSE, "RFC_MUX\n", BTM_SEC_SERVICE_RFC_MUX,
|
||||
BTM_SetSecurityLevel(FALSE, "RFC_MUX", BTM_SEC_SERVICE_RFC_MUX,
|
||||
BTM_SEC_NONE, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, 0);
|
||||
} else {
|
||||
btm_cb.security_mode = BTM_SEC_MODE_SERVICE;
|
||||
@@ -3024,7 +3083,7 @@ 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 {
|
||||
list_node_t *p_node = 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)
|
||||
@@ -3032,20 +3091,18 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
|
||||
p_bd_addr = p_dev_rec->bd_addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!p_bd_addr) {
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Commenting out trace due to obf/compilation problems.
|
||||
*/
|
||||
#if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE)
|
||||
if (!p_bd_name) {
|
||||
p_bd_name = (UINT8 *)"";
|
||||
}
|
||||
|
||||
/* Commenting out trace due to obf/compilation problems.
|
||||
*/
|
||||
#if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE)
|
||||
if (p_dev_rec) {
|
||||
BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s RemName: %s status: %d State:%d p_dev_rec: %p \n",
|
||||
btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
|
||||
@@ -3264,6 +3321,10 @@ void btm_sec_rmt_host_support_feat_evt (UINT8 *p)
|
||||
|
||||
STREAM_TO_BDADDR (bd_addr, p);
|
||||
p_dev_rec = btm_find_or_alloc_dev (bd_addr);
|
||||
if (!p_dev_rec) {
|
||||
BTM_TRACE_ERROR("Unable to allocate or find device record for remote features event");
|
||||
return;
|
||||
}
|
||||
|
||||
BTM_TRACE_EVENT ("btm_sec_rmt_host_support_feat_evt sm4: 0x%x p[0]: 0x%x\n", p_dev_rec->sm4, p[0]);
|
||||
|
||||
@@ -3309,6 +3370,11 @@ void btm_io_capabilities_req (UINT8 *p)
|
||||
BTM_TRACE_EVENT("%s: State: %s\n", __FUNCTION__, btm_pair_state_descr(btm_cb.pairing_state));
|
||||
#endif ///BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE
|
||||
p_dev_rec = btm_find_or_alloc_dev (evt_data.bd_addr);
|
||||
if (!p_dev_rec) {
|
||||
BTM_TRACE_ERROR("%s: unable to allocate device record", __func__);
|
||||
btsnd_hcic_io_cap_req_neg_reply(evt_data.bd_addr, HCI_ERR_HOST_REJECT_RESOURCES);
|
||||
return;
|
||||
}
|
||||
|
||||
BTM_TRACE_DEBUG("%s:Security mode: %d, Num Read Remote Feat pages: %d\n", __FUNCTION__,
|
||||
btm_cb.security_mode, p_dev_rec->num_read_pages);
|
||||
@@ -3667,11 +3733,15 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void btm_keypress_notif_evt (UINT8 *p)
|
||||
void btm_keypress_notif_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_SP_KEYPRESS evt_data;
|
||||
UINT8 *p_bda;
|
||||
|
||||
if (evt_len < 7) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse & report BTM_SP_KEYPRESS_EVT */
|
||||
if (btm_cb.api.p_sp_callback) {
|
||||
p_bda = evt_data.bd_addr;
|
||||
@@ -3693,13 +3763,17 @@ void btm_keypress_notif_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void btm_simple_pair_complete (UINT8 *p)
|
||||
void btm_simple_pair_complete (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_SP_COMPLT evt_data;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec;
|
||||
UINT8 status;
|
||||
BOOLEAN disc = FALSE;
|
||||
|
||||
if (evt_len < 7) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = *p++;
|
||||
STREAM_TO_BDADDR (evt_data.bd_addr, p);
|
||||
|
||||
@@ -4287,6 +4361,10 @@ static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle)
|
||||
btm_cb.sec_collision_tle.param = 0;
|
||||
btm_cb.p_collided_dev_rec = 0;
|
||||
|
||||
if (!p_dev_rec) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED) {
|
||||
BTM_TRACE_WARNING ("Security Manager: btm_sec_connect_after_reject_timeout: failed to start connection\n");
|
||||
|
||||
@@ -4413,8 +4491,6 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
|
||||
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
|
||||
#endif
|
||||
|
||||
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
|
||||
|
||||
if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
|
||||
&& (memcmp (btm_cb.pairing_bda, bda, BD_ADDR_LEN) == 0) ) {
|
||||
/* if we rejected incoming connection from bonding device */
|
||||
@@ -4550,7 +4626,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
|
||||
|
||||
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
|
||||
|
||||
if ( res ) {
|
||||
if (res && (p_dev_rec != NULL)) {
|
||||
/* Let l2cap start bond timer */
|
||||
l2cu_update_lcb_4_bonding (p_dev_rec->bd_addr, TRUE);
|
||||
}
|
||||
@@ -4629,8 +4705,8 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason)
|
||||
|
||||
/* In some weird race condition we may not have a record */
|
||||
if (!p_dev_rec) {
|
||||
btsnd_hcic_disconnect (handle, reason);
|
||||
return (BTM_SUCCESS);
|
||||
BOOLEAN ret = btsnd_hcic_disconnect (handle, reason);
|
||||
return (ret ? BTM_SUCCESS : BTM_NO_RESOURCES);
|
||||
}
|
||||
|
||||
/* If we are in the process of bonding we need to tell client that auth failed */
|
||||
@@ -4677,8 +4753,6 @@ BOOLEAN btm_sec_disconnected (UINT16 handle, UINT8 reason)
|
||||
p_dev_rec->enc_init_by_we = FALSE;
|
||||
transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE;
|
||||
|
||||
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
|
||||
|
||||
#if BTM_DISC_DURING_RS == TRUE
|
||||
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
|
||||
#endif
|
||||
@@ -4781,6 +4855,10 @@ void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_t
|
||||
/* If connection was made to do bonding restore link security if changed */
|
||||
btm_restore_mode();
|
||||
|
||||
if (p_dev_rec == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store the previous state of secure connection as current state. Since
|
||||
* this is the first encounter with the remote device, whatever the remote
|
||||
* device's SC state is, it cannot lower the SC level from this. */
|
||||
@@ -4927,6 +5005,7 @@ void btm_sec_link_key_request (UINT8 *p_bda)
|
||||
|
||||
if ( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ) &&
|
||||
(btm_cb.collision_start_time != 0) &&
|
||||
(btm_cb.p_collided_dev_rec != NULL) &&
|
||||
(memcmp (btm_cb.p_collided_dev_rec->bd_addr, p_bda, BD_ADDR_LEN) == 0) ) {
|
||||
BTM_TRACE_EVENT ("btm_sec_link_key_request() rejecting link key req "
|
||||
"State: %d START_TIMEOUT : %d\n",
|
||||
@@ -4969,7 +5048,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
|
||||
tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_YES;
|
||||
#endif
|
||||
#endif
|
||||
UINT8 name[2];
|
||||
tBTM_BD_NAME name = {0};
|
||||
UNUSED(p_tle);
|
||||
|
||||
p_cb->pairing_tle.param = 0;
|
||||
@@ -5141,6 +5220,12 @@ void btm_sec_pin_code_request (UINT8 *p_bda)
|
||||
}
|
||||
|
||||
p_dev_rec = btm_find_or_alloc_dev (p_bda);
|
||||
if (!p_dev_rec) {
|
||||
BTM_TRACE_ERROR ("btm_sec_pin_code_request no device record available\n");
|
||||
btsnd_hcic_pin_code_neg_reply (p_bda);
|
||||
return;
|
||||
}
|
||||
|
||||
/* received PIN code request. must be non-sm4 */
|
||||
p_dev_rec->sm4 = BTM_SM4_KNOWN;
|
||||
|
||||
@@ -5491,7 +5576,7 @@ static BOOLEAN btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec)
|
||||
*******************************************************************************/
|
||||
static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec)
|
||||
{
|
||||
UINT8 result;
|
||||
UINT8 result = BTM_SUCCESS;
|
||||
UINT8 *p_service_name = NULL;
|
||||
UINT8 service_id;
|
||||
|
||||
@@ -5543,7 +5628,9 @@ static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec)
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
btm_sec_start_get_name (p_dev_rec);
|
||||
if (!btm_sec_start_get_name (p_dev_rec)) {
|
||||
return BTM_NO_RESOURCES;
|
||||
}
|
||||
return (BTM_CMD_STARTED);
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
@@ -5697,6 +5784,10 @@ static void btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle)
|
||||
BTM_TRACE_EVENT ("%s()\n", __func__);
|
||||
btm_cb.sec_collision_tle.param = 0;
|
||||
|
||||
if (!btm_cb.p_collided_dev_rec) {
|
||||
return;
|
||||
}
|
||||
|
||||
tBTM_STATUS status = btm_sec_execute_procedure (btm_cb.p_collided_dev_rec);
|
||||
|
||||
/* If result is pending reply from the user or from the device is pending */
|
||||
@@ -5763,15 +5854,17 @@ UINT32 *BTM_ReadTrustedMask (BD_ADDR bd_addr)
|
||||
static void btm_restore_mode(void)
|
||||
{
|
||||
if (btm_cb.security_mode_changed) {
|
||||
btm_cb.security_mode_changed = FALSE;
|
||||
BTM_TRACE_DEBUG("%s() Auth enable -> %d\n", __func__, (btm_cb.security_mode == BTM_SEC_MODE_LINK));
|
||||
btsnd_hcic_write_auth_enable ((UINT8)(btm_cb.security_mode == BTM_SEC_MODE_LINK));
|
||||
if (btsnd_hcic_write_auth_enable ((UINT8)(btm_cb.security_mode == BTM_SEC_MODE_LINK))) {
|
||||
btm_cb.security_mode_changed = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
if (btm_cb.pin_type_changed) {
|
||||
btm_cb.pin_type_changed = FALSE;
|
||||
btsnd_hcic_write_pin_type (btm_cb.cfg.pin_type);
|
||||
if (btsnd_hcic_write_pin_type (btm_cb.cfg.pin_type)) {
|
||||
btm_cb.pin_type_changed = FALSE;
|
||||
}
|
||||
}
|
||||
#endif ///CLASSIC_BT_INCLUDED == TRUE
|
||||
}
|
||||
@@ -5794,7 +5887,7 @@ tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state)
|
||||
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)
|
||||
if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
|
||||
&& (p_dev_rec->sec_state == state)) {
|
||||
return (p_dev_rec);
|
||||
}
|
||||
@@ -5945,9 +6038,14 @@ static BOOLEAN btm_sec_queue_mx_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN
|
||||
BTM_TRACE_EVENT ("%s() PSM: 0x%04x Is_Orig: %u mx_proto_id: %u mx_chan_id: %u\n",
|
||||
__func__, psm, is_orig, mx_proto_id, mx_chan_id);
|
||||
|
||||
fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT);
|
||||
if (fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT)) {
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
if (p_e) {
|
||||
osi_free(p_e);
|
||||
p_e = NULL;
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
@@ -5958,7 +6056,6 @@ static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec)
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
UINT8 major = (UINT8)(p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK);
|
||||
UINT8 minor = (UINT8)(p_dev_rec->dev_class[2] & BTM_COD_MINOR_CLASS_MASK);
|
||||
rv = TRUE;
|
||||
|
||||
if ((major == BTM_COD_MAJOR_AUDIO)
|
||||
&& ((minor == BTM_COD_MINOR_CONFM_HANDSFREE) || (minor == BTM_COD_MINOR_CAR_AUDIO)) ) {
|
||||
@@ -5974,30 +6071,30 @@ static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec)
|
||||
btsnd_hcic_write_auth_enable (TRUE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
|
||||
|
||||
/* If we got a PIN, use that, else try to get one */
|
||||
if (btm_cb.pin_code_len) {
|
||||
BTM_PINCodeReply (p_dev_rec->bd_addr, BTM_SUCCESS, btm_cb.pin_code_len, btm_cb.pin_code, p_dev_rec->trusted_mask);
|
||||
} else {
|
||||
/* pin was not supplied - pre-fetch pin code now */
|
||||
if (btm_cb.api.p_pin_callback && ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0)) {
|
||||
BTM_TRACE_DEBUG("%s() PIN code callback called\n", __func__);
|
||||
if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL) {
|
||||
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
|
||||
}
|
||||
(btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, (p_dev_rec->p_cur_service == NULL) ? FALSE
|
||||
: (p_dev_rec->p_cur_service->security_flags
|
||||
& BTM_SEC_IN_MIN_16_DIGIT_PIN));
|
||||
}
|
||||
}
|
||||
|
||||
rv = TRUE;
|
||||
} else if (btm_cb.pin_code_len) {
|
||||
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
|
||||
BTM_PINCodeReply (p_dev_rec->bd_addr, BTM_SUCCESS, btm_cb.pin_code_len, btm_cb.pin_code, p_dev_rec->trusted_mask);
|
||||
rv = TRUE;
|
||||
} else if (btm_cb.api.p_pin_callback) {
|
||||
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
|
||||
/* pin was not supplied - pre-fetch pin code now */
|
||||
if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0) {
|
||||
BTM_TRACE_DEBUG("%s() PIN code callback called\n", __func__);
|
||||
if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL) {
|
||||
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
|
||||
}
|
||||
(btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, (p_dev_rec->p_cur_service == NULL) ? FALSE
|
||||
: (p_dev_rec->p_cur_service->security_flags
|
||||
& BTM_SEC_IN_MIN_16_DIGIT_PIN));
|
||||
}
|
||||
rv = TRUE;
|
||||
} else {
|
||||
BTM_TRACE_WARNING ("%s() cannot prefetch PIN: no PIN supplied and no callback registered\n", __func__);
|
||||
}
|
||||
#endif ///CLASSIC_BT_INCLUDED == TRUE
|
||||
#
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -6016,6 +6113,10 @@ void btm_sec_auth_payload_tout (UINT8 *p, UINT16 hci_evt_len)
|
||||
{
|
||||
UINT16 handle;
|
||||
|
||||
if (hci_evt_len < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT16 (handle, p);
|
||||
handle = HCID_GET_HANDLE (handle);
|
||||
|
||||
@@ -6053,10 +6154,15 @@ static BOOLEAN btm_sec_queue_encrypt_request (BD_ADDR bd_addr, tBT_TRANSPORT tra
|
||||
}
|
||||
p_e->transport = transport;
|
||||
memcpy(p_e->bd_addr, bd_addr, BD_ADDR_LEN);
|
||||
fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT);
|
||||
return TRUE;
|
||||
if (fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_e) {
|
||||
osi_free(p_e);
|
||||
p_e = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -6187,7 +6293,7 @@ static void btm_sec_check_pending_enc_req (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRA
|
||||
(*p_e->p_callback) (p_dev_rec->bd_addr, transport, p_e->p_ref_data, res);
|
||||
}
|
||||
|
||||
fixed_queue_try_remove_from_queue(btm_cb.sec_pending_q, (void *)p_e);
|
||||
osi_free(fixed_queue_try_remove_from_queue(btm_cb.sec_pending_q, (void *)p_e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,7 +1103,7 @@ void btm_inq_rmt_name_failed(void);
|
||||
/* Inquiry related functions */
|
||||
void btm_clr_inq_db (BD_ADDR p_bda);
|
||||
void btm_inq_db_init (void);
|
||||
void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode);
|
||||
void btm_process_inq_results (UINT8 *p, UINT16 evt_len, UINT8 inq_res_mode);
|
||||
void btm_process_inq_complete (UINT8 status, UINT8 mode);
|
||||
void btm_process_cancel_complete(UINT8 status, UINT8 mode);
|
||||
void btm_event_filter_complete (UINT8 *p);
|
||||
@@ -1115,8 +1115,8 @@ BOOLEAN btm_inq_find_bdaddr (BD_ADDR p_bda);
|
||||
BOOLEAN btm_lookup_eir(BD_ADDR_PTR p_rem_addr);
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
void btm_read_iscan_tx_power_complete (UINT8 *p);
|
||||
void btm_write_inq_tx_power_complete (UINT8 *p);
|
||||
void btm_read_iscan_tx_power_complete (UINT8 *p, UINT16 evt_len);
|
||||
void btm_write_inq_tx_power_complete (UINT8 *p, UINT16 evt_len);
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
/* Internal functions provided by btm_bredr_pwr_ctrl.c
|
||||
@@ -1153,12 +1153,12 @@ tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types);
|
||||
void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset);
|
||||
void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role);
|
||||
void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable);
|
||||
UINT16 btm_get_acl_disc_reason_code (void);
|
||||
UINT8 btm_get_acl_disc_reason_code (void);
|
||||
tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport);
|
||||
void btm_read_remote_features_complete (UINT8 *p);
|
||||
void btm_read_remote_ext_features_complete (UINT8 *p);
|
||||
void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle);
|
||||
void btm_read_remote_version_complete (UINT8 *p);
|
||||
void btm_read_remote_version_complete (UINT8 *p, UINT16 evt_len);
|
||||
void btm_establish_continue (tACL_CONN *p_acl_cb);
|
||||
|
||||
// btla-specific ++
|
||||
@@ -1326,8 +1326,8 @@ void btm_io_capabilities_req (UINT8 *p);
|
||||
void btm_io_capabilities_rsp (UINT8 *p);
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p);
|
||||
void btm_keypress_notif_evt (UINT8 *p);
|
||||
void btm_simple_pair_complete (UINT8 *p);
|
||||
void btm_keypress_notif_evt (UINT8 *p, UINT16 evt_len);
|
||||
void btm_simple_pair_complete (UINT8 *p, UINT16 evt_len);
|
||||
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
|
||||
void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_type);
|
||||
void btm_sec_link_key_request (UINT8 *p_bda);
|
||||
|
||||
@@ -67,10 +67,10 @@ extern void btm_ble_test_command_complete(UINT8 *p, UINT16 len);
|
||||
/* L O C A L F U N C T I O N P R O T O T Y P E S */
|
||||
/********************************************************************************/
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
static void btu_hcif_inquiry_comp_evt (UINT8 *p);
|
||||
static void btu_hcif_inquiry_result_evt (UINT8 *p);
|
||||
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p);
|
||||
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p);
|
||||
static void btu_hcif_inquiry_comp_evt (UINT8 *p, UINT16 evt_len);
|
||||
static void btu_hcif_inquiry_result_evt (UINT8 *p, UINT16 evt_len);
|
||||
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p, UINT16 evt_len);
|
||||
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p, UINT16 evt_len);
|
||||
|
||||
static void btu_hcif_connection_comp_evt (UINT8 *p);
|
||||
static void btu_hcif_connection_request_evt (UINT8 *p);
|
||||
@@ -89,7 +89,7 @@ static void btu_hcif_encryption_change_evt (UINT8 *p);
|
||||
static void btu_hcif_read_rmt_features_comp_evt (UINT8 *p);
|
||||
static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p);
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p);
|
||||
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p, UINT16 evt_len);
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
static void btu_hcif_qos_setup_comp_evt (UINT8 *p);
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
@@ -134,9 +134,9 @@ static void btu_hcif_io_cap_request_evt (UINT8 *p);
|
||||
static void btu_hcif_io_cap_response_evt (UINT8 *p);
|
||||
static void btu_hcif_user_conf_request_evt (UINT8 *p);
|
||||
static void btu_hcif_user_passkey_request_evt (UINT8 *p);
|
||||
static void btu_hcif_simple_pair_complete_evt (UINT8 *p);
|
||||
static void btu_hcif_simple_pair_complete_evt (UINT8 *p, UINT16 evt_len);
|
||||
static void btu_hcif_user_passkey_notif_evt (UINT8 *p);
|
||||
static void btu_hcif_keypress_notif_evt (UINT8 *p);
|
||||
static void btu_hcif_keypress_notif_evt (UINT8 *p, UINT16 evt_len);
|
||||
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
|
||||
#if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
|
||||
static void btu_hcif_rem_oob_request_evt (UINT8 *p);
|
||||
@@ -305,16 +305,16 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
switch (hci_evt_code) {
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_INQUIRY_COMP_EVT:
|
||||
btu_hcif_inquiry_comp_evt (p);
|
||||
btu_hcif_inquiry_comp_evt (p, hci_evt_len);
|
||||
break;
|
||||
case HCI_INQUIRY_RESULT_EVT:
|
||||
btu_hcif_inquiry_result_evt (p);
|
||||
btu_hcif_inquiry_result_evt (p, hci_evt_len);
|
||||
break;
|
||||
case HCI_INQUIRY_RSSI_RESULT_EVT:
|
||||
btu_hcif_inquiry_rssi_result_evt (p);
|
||||
btu_hcif_inquiry_rssi_result_evt (p, hci_evt_len);
|
||||
break;
|
||||
case HCI_EXTENDED_INQUIRY_RESULT_EVT:
|
||||
btu_hcif_extended_inquiry_result_evt (p);
|
||||
btu_hcif_extended_inquiry_result_evt (p, hci_evt_len);
|
||||
break;
|
||||
case HCI_CONNECTION_COMP_EVT:
|
||||
btu_hcif_connection_comp_evt (p);
|
||||
@@ -357,7 +357,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
break;
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_READ_RMT_VERSION_COMP_EVT:
|
||||
btu_hcif_read_rmt_version_comp_evt (p);
|
||||
btu_hcif_read_rmt_version_comp_evt (p, hci_evt_len);
|
||||
break;
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_QOS_SETUP_COMP_EVT:
|
||||
@@ -461,13 +461,13 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
#endif
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_SIMPLE_PAIRING_COMPLETE_EVT:
|
||||
btu_hcif_simple_pair_complete_evt (p);
|
||||
btu_hcif_simple_pair_complete_evt (p, hci_evt_len);
|
||||
break;
|
||||
case HCI_USER_PASSKEY_NOTIFY_EVT:
|
||||
btu_hcif_user_passkey_notif_evt (p);
|
||||
break;
|
||||
case HCI_KEYPRESS_NOTIFY_EVT:
|
||||
btu_hcif_keypress_notif_evt (p);
|
||||
btu_hcif_keypress_notif_evt (p, hci_evt_len);
|
||||
break;
|
||||
case HCI_LINK_SUPER_TOUT_CHANGED_EVT:
|
||||
btu_hcif_link_supv_to_changed_evt (p);
|
||||
@@ -842,11 +842,13 @@ void btu_hcif_send_host_rdy_for_data(void)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_inquiry_comp_evt (UINT8 *p)
|
||||
static void btu_hcif_inquiry_comp_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
UINT8 status;
|
||||
UINT8 status = HCI_ERR_HW_FAILURE;
|
||||
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
if (evt_len >= 1) {
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
}
|
||||
|
||||
/* Tell inquiry processing that we are done */
|
||||
btm_process_inq_complete(status, BTM_BR_INQUIRY_MASK);
|
||||
@@ -862,10 +864,10 @@ static void btu_hcif_inquiry_comp_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_inquiry_result_evt (UINT8 *p)
|
||||
static void btu_hcif_inquiry_result_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
/* Store results in the cache */
|
||||
btm_process_inq_results (p, BTM_INQ_RESULT_STANDARD);
|
||||
btm_process_inq_results (p, evt_len, BTM_INQ_RESULT_STANDARD);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -877,10 +879,10 @@ static void btu_hcif_inquiry_result_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p)
|
||||
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
/* Store results in the cache */
|
||||
btm_process_inq_results (p, BTM_INQ_RESULT_WITH_RSSI);
|
||||
btm_process_inq_results (p, evt_len, BTM_INQ_RESULT_WITH_RSSI);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -892,10 +894,10 @@ static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p)
|
||||
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
/* Store results in the cache */
|
||||
btm_process_inq_results (p, BTM_INQ_RESULT_EXTENDED);
|
||||
btm_process_inq_results (p, evt_len, BTM_INQ_RESULT_EXTENDED);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -1097,7 +1099,6 @@ static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len)
|
||||
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
STREAM_TO_BDADDR (bd_addr, p);
|
||||
|
||||
evt_len -= (1 + BD_ADDR_LEN);
|
||||
|
||||
btm_process_remote_name (bd_addr, p, evt_len, status);
|
||||
@@ -1182,9 +1183,9 @@ static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p)
|
||||
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
btm_read_remote_version_complete (p);
|
||||
btm_read_remote_version_complete (p, evt_len);
|
||||
}
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
@@ -1346,10 +1347,10 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_READ_INQ_TX_POWER_LEVEL:
|
||||
btm_read_iscan_tx_power_complete (p);
|
||||
btm_read_iscan_tx_power_complete (p, evt_len);
|
||||
break;
|
||||
case HCI_WRITE_INQ_TX_POWER_LEVEL:
|
||||
btm_write_inq_tx_power_complete(p);
|
||||
btm_write_inq_tx_power_complete(p, evt_len);
|
||||
break;
|
||||
case HCI_SET_AFH_CHANNELS:
|
||||
btm_set_afh_channels_complete(p);
|
||||
@@ -2439,9 +2440,9 @@ static void btu_hcif_user_passkey_request_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_simple_pair_complete_evt (UINT8 *p)
|
||||
static void btu_hcif_simple_pair_complete_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
btm_simple_pair_complete(p);
|
||||
btm_simple_pair_complete(p, evt_len);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -2467,9 +2468,9 @@ static void btu_hcif_user_passkey_notif_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_keypress_notif_evt (UINT8 *p)
|
||||
static void btu_hcif_keypress_notif_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
btm_keypress_notif_evt(p);
|
||||
btm_keypress_notif_evt(p, evt_len);
|
||||
}
|
||||
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
|
||||
|
||||
|
||||
@@ -41,6 +41,12 @@ tGAP_CB *gap_cb_ptr;
|
||||
*******************************************************************************/
|
||||
UINT8 GAP_SetTraceLevel (UINT8 new_level)
|
||||
{
|
||||
#if GAP_DYNAMIC_MEMORY == TRUE
|
||||
if (!gap_cb_ptr) {
|
||||
return GAP_INITIAL_TRACE_LEVEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (new_level != 0xFF) {
|
||||
gap_cb.trace_level = new_level;
|
||||
}
|
||||
|
||||
@@ -298,12 +298,9 @@ UINT16 GAP_ConnClose (UINT16 gap_handle)
|
||||
*******************************************************************************/
|
||||
UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
|
||||
{
|
||||
tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
|
||||
tGAP_CCB *p_ccb = NULL;
|
||||
UINT16 copy_len;
|
||||
|
||||
if (!p_ccb) {
|
||||
return (GAP_ERR_BAD_HANDLE);
|
||||
}
|
||||
if (!p_len) {
|
||||
return (GAP_ERR_ILL_PARM);
|
||||
}
|
||||
@@ -312,6 +309,12 @@ UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT1
|
||||
|
||||
osi_mutex_global_lock();
|
||||
|
||||
p_ccb = gap_find_ccb_by_handle (gap_handle);
|
||||
if (!p_ccb) {
|
||||
osi_mutex_global_unlock();
|
||||
return (GAP_ERR_BAD_HANDLE);
|
||||
}
|
||||
|
||||
if (fixed_queue_is_empty(p_ccb->rx_queue)) {
|
||||
osi_mutex_global_unlock();
|
||||
return (GAP_NO_DATA_AVAIL);
|
||||
@@ -363,18 +366,22 @@ UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT1
|
||||
int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
|
||||
{
|
||||
tGAP_CCB *p_ccb;
|
||||
int rc = GAP_INVALID_HANDLE;
|
||||
int rc = GAP_ERR_BAD_HANDLE;
|
||||
|
||||
if (!p_rx_queue_count) {
|
||||
return GAP_ERR_ILL_PARM;
|
||||
}
|
||||
|
||||
*p_rx_queue_count = 0;
|
||||
|
||||
/* Check that handle is valid */
|
||||
p_ccb = gap_find_ccb_by_handle (handle);
|
||||
if (p_ccb) {
|
||||
if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
|
||||
*p_rx_queue_count = p_ccb->rx_queue_size;
|
||||
rc = BT_PASS;
|
||||
} else {
|
||||
rc = GAP_ERR_BAD_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,24 +408,32 @@ int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
|
||||
*******************************************************************************/
|
||||
UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf)
|
||||
{
|
||||
tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
|
||||
tGAP_CCB *p_ccb;
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if (!pp_buf) {
|
||||
return (GAP_ERR_ILL_PARM);
|
||||
}
|
||||
|
||||
osi_mutex_global_lock();
|
||||
|
||||
p_ccb = gap_find_ccb_by_handle (gap_handle);
|
||||
if (!p_ccb) {
|
||||
osi_mutex_global_unlock();
|
||||
return (GAP_ERR_BAD_HANDLE);
|
||||
}
|
||||
|
||||
p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->rx_queue, 0);
|
||||
|
||||
if (p_buf) {
|
||||
*pp_buf = p_buf;
|
||||
|
||||
p_ccb->rx_queue_size -= p_buf->len;
|
||||
osi_mutex_global_unlock();
|
||||
*pp_buf = p_buf;
|
||||
return (BT_PASS);
|
||||
} else {
|
||||
*pp_buf = NULL;
|
||||
return (GAP_NO_DATA_AVAIL);
|
||||
}
|
||||
|
||||
osi_mutex_global_unlock();
|
||||
*pp_buf = NULL;
|
||||
return (GAP_NO_DATA_AVAIL);
|
||||
}
|
||||
|
||||
|
||||
@@ -462,9 +477,6 @@ UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
|
||||
}
|
||||
|
||||
/* Send the buffer through L2CAP */
|
||||
#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
|
||||
gap_send_event (gap_handle);
|
||||
#else
|
||||
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL) {
|
||||
UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
|
||||
|
||||
@@ -475,7 +487,6 @@ UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
|
||||
return (GAP_ERR_BAD_STATE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (BT_PASS);
|
||||
}
|
||||
|
||||
@@ -545,9 +556,6 @@ UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT
|
||||
}
|
||||
|
||||
/* Send the buffer through L2CAP */
|
||||
#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
|
||||
gap_send_event (gap_handle);
|
||||
#else
|
||||
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL)
|
||||
{
|
||||
UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
|
||||
@@ -559,7 +567,6 @@ UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT
|
||||
return (GAP_ERR_BAD_STATE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (BT_PASS);
|
||||
}
|
||||
|
||||
@@ -580,14 +587,21 @@ UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg)
|
||||
{
|
||||
tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
|
||||
|
||||
if (!p_cfg) {
|
||||
return GAP_ERR_ILL_PARM;
|
||||
}
|
||||
if (!p_ccb) {
|
||||
return (GAP_ERR_BAD_HANDLE);
|
||||
}
|
||||
|
||||
tL2CAP_CFG_INFO old_cfg = p_ccb->cfg;
|
||||
p_ccb->cfg = *p_cfg;
|
||||
|
||||
if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
|
||||
L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg);
|
||||
if (!L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg)) {
|
||||
p_ccb->cfg = old_cfg;
|
||||
return GAP_ERR_BAD_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
return (BT_PASS);
|
||||
@@ -642,8 +656,8 @@ UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout)
|
||||
**
|
||||
** Parameters: handle - Handle of the connection returned by GAP_ConnOpen
|
||||
**
|
||||
** Returns BT_PASS - closed OK
|
||||
** GAP_ERR_BAD_HANDLE - invalid handle
|
||||
** Returns Pointer to remote BD_ADDR (UINT8 *) if connection exists,
|
||||
** otherwise NULL.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle)
|
||||
@@ -777,10 +791,12 @@ static void gap_checks_con_flags (tGAP_CCB *p_ccb)
|
||||
GAP_TRACE_EVENT ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags);
|
||||
/* if all the required con_flags are set, report the OPEN event now */
|
||||
if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE) {
|
||||
p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
|
||||
if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) {
|
||||
p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
|
||||
|
||||
if (p_ccb->p_callback) {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
|
||||
if (p_ccb->p_callback) {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -882,8 +898,11 @@ static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
|
||||
/* Remember the remote MTU size */
|
||||
|
||||
if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
|
||||
local_mtu_size = p_ccb->ertm_info.user_tx_buf_size
|
||||
- sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
|
||||
if (p_ccb->ertm_info.user_tx_buf_size > sizeof(BT_HDR) + L2CAP_MIN_OFFSET) {
|
||||
local_mtu_size = p_ccb->ertm_info.user_tx_buf_size - sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
|
||||
} else {
|
||||
local_mtu_size = L2CAP_MTU_SIZE;
|
||||
}
|
||||
} else {
|
||||
local_mtu_size = L2CAP_MTU_SIZE;
|
||||
}
|
||||
@@ -999,9 +1018,15 @@ static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
|
||||
}
|
||||
|
||||
if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
|
||||
fixed_queue_enqueue(p_ccb->rx_queue, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
|
||||
|
||||
p_ccb->rx_queue_size += p_msg->len;
|
||||
UINT16 msg_len = p_msg->len;
|
||||
bool ok = fixed_queue_enqueue(p_ccb->rx_queue, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
|
||||
if (!ok) {
|
||||
osi_free(p_msg);
|
||||
return;
|
||||
}
|
||||
osi_mutex_global_lock();
|
||||
p_ccb->rx_queue_size += msg_len;
|
||||
osi_mutex_global_unlock();
|
||||
/*
|
||||
GAP_TRACE_EVENT ("gap_data_ind - rx_queue_size=%d, msg len=%d",
|
||||
p_ccb->rx_queue_size, p_msg->len);
|
||||
@@ -1135,7 +1160,13 @@ static tGAP_CCB *gap_allocate_ccb (void)
|
||||
if (p_ccb->con_state == GAP_CCB_STATE_IDLE) {
|
||||
memset (p_ccb, 0, sizeof (tGAP_CCB));
|
||||
p_ccb->tx_queue = fixed_queue_new(QUEUE_SIZE_MAX);
|
||||
if (!p_ccb->tx_queue) {
|
||||
goto error;
|
||||
}
|
||||
p_ccb->rx_queue = fixed_queue_new(QUEUE_SIZE_MAX);
|
||||
if (!p_ccb->rx_queue) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
p_ccb->gap_handle = xx;
|
||||
p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
|
||||
@@ -1144,6 +1175,17 @@ static tGAP_CCB *gap_allocate_ccb (void)
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
error:
|
||||
if (p_ccb && p_ccb->tx_queue) {
|
||||
fixed_queue_free(p_ccb->tx_queue, NULL);
|
||||
p_ccb->tx_queue = NULL;
|
||||
}
|
||||
if (p_ccb && p_ccb->rx_queue) {
|
||||
fixed_queue_free(p_ccb->rx_queue, NULL);
|
||||
p_ccb->rx_queue = NULL;
|
||||
}
|
||||
/* If here, no free CCB found */
|
||||
return (NULL);
|
||||
}
|
||||
@@ -1165,6 +1207,7 @@ static void gap_release_ccb (tGAP_CCB *p_ccb)
|
||||
UINT8 service_id = p_ccb->service_id;
|
||||
|
||||
/* Drop any buffers we may be holding */
|
||||
osi_mutex_global_lock();
|
||||
p_ccb->rx_queue_size = 0;
|
||||
|
||||
while (!fixed_queue_is_empty(p_ccb->rx_queue)) {
|
||||
@@ -1172,6 +1215,7 @@ static void gap_release_ccb (tGAP_CCB *p_ccb)
|
||||
}
|
||||
fixed_queue_free(p_ccb->rx_queue, NULL);
|
||||
p_ccb->rx_queue = NULL;
|
||||
osi_mutex_global_unlock();
|
||||
|
||||
while (!fixed_queue_is_empty(p_ccb->tx_queue)) {
|
||||
osi_free(fixed_queue_dequeue(p_ccb->tx_queue, 0));
|
||||
@@ -1189,37 +1233,11 @@ static void gap_release_ccb (tGAP_CCB *p_ccb)
|
||||
}
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* Free the security record for this PSM */
|
||||
BTM_SecClrService(service_id);
|
||||
if (service_id != 0) {
|
||||
BTM_SecClrService(service_id);
|
||||
}
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
L2CA_DEREGISTER (psm);
|
||||
}
|
||||
|
||||
#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gap_send_event
|
||||
**
|
||||
** Description Send BT_EVT_TO_GAP_MSG event to BTU task
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void gap_send_event (UINT16 gap_handle)
|
||||
{
|
||||
BT_HDR *p_msg;
|
||||
|
||||
if ((p_msg = (BT_HDR *)osi_malloc(BT_HDR_SIZE)) != NULL) {
|
||||
p_msg->event = BT_EVT_TO_GAP_MSG;
|
||||
p_msg->len = 0;
|
||||
p_msg->offset = 0;
|
||||
p_msg->layer_specific = gap_handle;
|
||||
|
||||
GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
|
||||
} else {
|
||||
GAP_TRACE_ERROR("Unable to allocate message buffer for event.");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */
|
||||
#endif /* GAP_CONN_INCLUDED */
|
||||
|
||||
@@ -165,7 +165,10 @@ BOOLEAN btsnd_hcic_create_conn(BD_ADDR dest, UINT16 packet_types,
|
||||
#endif
|
||||
#if (SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE)
|
||||
btm_acl_paging (p, dest);
|
||||
#endif ///SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE
|
||||
#else
|
||||
HCI_FREE_CMD_BUF (p);
|
||||
return (FALSE);
|
||||
#endif
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
@@ -493,7 +496,10 @@ BOOLEAN btsnd_hcic_rmt_name_req (BD_ADDR bd_addr, UINT8 page_scan_rep_mode,
|
||||
UINT16_TO_STREAM (pp, clock_offset);
|
||||
#if (SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE)
|
||||
btm_acl_paging (p, bd_addr);
|
||||
#endif ///SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE
|
||||
#else
|
||||
HCI_FREE_CMD_BUF (p);
|
||||
return (FALSE);
|
||||
#endif
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
@@ -1370,7 +1376,7 @@ BOOLEAN btsnd_hcic_write_link_super_tout (UINT8 local_controller_id, UINT16 hand
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, LAP *const iac_lap)
|
||||
BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, const LAP *iac_lap)
|
||||
{
|
||||
BT_HDR *p;
|
||||
UINT8 *pp;
|
||||
@@ -1432,11 +1438,11 @@ BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat,
|
||||
#endif /* BTM_SSR_INCLUDED */
|
||||
|
||||
/**** Extended Inquiry Response Commands ****/
|
||||
void btsnd_hcic_write_ext_inquiry_response (BT_HDR *buffer, UINT8 fec_req)
|
||||
BOOLEAN btsnd_hcic_write_ext_inquiry_response (BT_HDR *buffer, UINT8 fec_req)
|
||||
{
|
||||
BT_HDR *p;
|
||||
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_EXT_INQ_RESP)) == NULL) {
|
||||
return;
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
UINT8 *pp = (UINT8 *)(p + 1);
|
||||
@@ -1451,6 +1457,7 @@ void btsnd_hcic_write_ext_inquiry_response (BT_HDR *buffer, UINT8 fec_req)
|
||||
memcpy(pp, buffer->data + 4, p->len - 4);
|
||||
|
||||
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN btsnd_hcic_io_cap_req_reply (BD_ADDR bd_addr, UINT8 capability,
|
||||
|
||||
@@ -103,6 +103,12 @@ void HID_DevDeinit(void)
|
||||
******************************************************************************/
|
||||
uint8_t HID_DevSetTraceLevel(uint8_t new_level)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (!hidd_cb_ptr) {
|
||||
return BT_TRACE_LEVEL_NONE;
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
|
||||
if (new_level != 0xFF) {
|
||||
hd_cb.trace_level = new_level;
|
||||
}
|
||||
@@ -159,15 +165,20 @@ tHID_STATUS HID_DevDeregister(void)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
if (!hd_cb.reg_flag)
|
||||
if (!hd_cb.reg_flag) {
|
||||
return (HID_ERR_NOT_REGISTERED);
|
||||
}
|
||||
if (hd_cb.pending_data) {
|
||||
osi_free(hd_cb.pending_data);
|
||||
hd_cb.pending_data = NULL;
|
||||
}
|
||||
hidd_conn_dereg();
|
||||
hd_cb.reg_flag = FALSE;
|
||||
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl)
|
||||
tHID_STATUS HID_DevSetSecurityLevel(uint16_t sec_lvl)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
if (!BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_HIDD_SEC_CTRL, sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID,
|
||||
@@ -203,6 +214,53 @@ tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl)
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
#define HIDD_MAX_DESCRIPTOR_LEN 2048
|
||||
|
||||
static size_t hidd_descriptor_list_buf_size(uint16_t desc_len)
|
||||
{
|
||||
size_t text_elem_len = (desc_len <= 255) ? (2 + desc_len) : (3 + desc_len);
|
||||
size_t inner_len = 2 + text_elem_len;
|
||||
|
||||
return inner_len + ((inner_len <= 255) ? 2 : 3);
|
||||
}
|
||||
|
||||
static uint8_t *hidd_build_descriptor_list(uint16_t desc_len, uint8_t *p_desc_data, uint16_t *p_list_len)
|
||||
{
|
||||
static uint8_t cdt = 0x22;
|
||||
size_t text_elem_len = (desc_len <= 255) ? (2 + desc_len) : (3 + desc_len);
|
||||
size_t inner_len = 2 + text_elem_len;
|
||||
uint8_t *p_buf = (uint8_t *)osi_malloc(hidd_descriptor_list_buf_size(desc_len));
|
||||
uint8_t *p;
|
||||
|
||||
if (p_buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = p_buf;
|
||||
if (inner_len <= 255) {
|
||||
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, (uint8_t)inner_len);
|
||||
} else {
|
||||
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
|
||||
UINT16_TO_BE_STREAM(p, (uint16_t)inner_len);
|
||||
}
|
||||
|
||||
UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, cdt);
|
||||
|
||||
if (desc_len <= 255) {
|
||||
UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, (uint8_t)desc_len);
|
||||
} else {
|
||||
UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
|
||||
UINT16_TO_BE_STREAM(p, desc_len);
|
||||
}
|
||||
ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
|
||||
|
||||
*p_list_len = (uint16_t)(p - p_buf);
|
||||
return p_buf;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevAddRecord
|
||||
@@ -219,6 +277,13 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char *p_name, char *p_description,
|
||||
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
if (desc_len > HIDD_MAX_DESCRIPTOR_LEN) {
|
||||
return HID_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (desc_len > 0 && p_desc_data == NULL) {
|
||||
return HID_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Service Class ID List
|
||||
if (result) {
|
||||
uint16_t uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
|
||||
@@ -292,23 +357,16 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char *p_name, char *p_description,
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_VIRTUAL_CABLE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_RECONNECT_INITIATE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
|
||||
{
|
||||
static uint8_t cdt = 0x22;
|
||||
uint8_t *p_buf;
|
||||
uint8_t seq_len = 4 + desc_len;
|
||||
p_buf = (uint8_t *)osi_malloc(2048);
|
||||
uint16_t list_len;
|
||||
|
||||
p_buf = hidd_build_descriptor_list(desc_len, p_desc_data, &list_len);
|
||||
if (p_buf == NULL) {
|
||||
HIDD_TRACE_ERROR("%s: Buffer allocation failure for size = 2048 ", __func__);
|
||||
return HID_ERR_NOT_REGISTERED;
|
||||
HIDD_TRACE_ERROR("%s: Buffer allocation failure for descriptor list size = %u", __func__,
|
||||
(unsigned)hidd_descriptor_list_buf_size(desc_len));
|
||||
return HID_ERR_NO_RESOURCES;
|
||||
}
|
||||
p = p_buf;
|
||||
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, seq_len);
|
||||
UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, cdt);
|
||||
UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, desc_len);
|
||||
ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_DESCRIPTOR_LIST, DATA_ELE_SEQ_DESC_TYPE, p - p_buf, p_buf);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_DESCRIPTOR_LIST, DATA_ELE_SEQ_DESC_TYPE, list_len, p_buf);
|
||||
osi_free(p_buf);
|
||||
}
|
||||
{
|
||||
@@ -416,6 +474,7 @@ tHID_STATUS HID_DevUnplugDevice(BD_ADDR addr)
|
||||
{
|
||||
if (!memcmp(hd_cb.device.addr, addr, sizeof(BD_ADDR))) {
|
||||
hd_cb.device.in_use = FALSE;
|
||||
hd_cb.device.state = HIDD_DEV_NO_CONN;
|
||||
hd_cb.device.conn.conn_state = HID_CONN_STATE_UNUSED;
|
||||
hd_cb.device.conn.ctrl_cid = 0;
|
||||
hd_cb.device.conn.intr_cid = 0;
|
||||
@@ -480,6 +539,12 @@ tHID_STATUS HID_DevDisconnect(void)
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevSetIncomingPolicy(bool allow)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (!hidd_cb_ptr) {
|
||||
return HID_ERR_NO_RESOURCES;
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
|
||||
hd_cb.allow_incoming = allow;
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
@@ -551,7 +616,14 @@ tHID_STATUS HID_DevGetDevice(BD_ADDR *addr)
|
||||
tHID_STATUS HID_DevSetIncomingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
|
||||
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (!hidd_cb_ptr) {
|
||||
return HID_ERR_NO_RESOURCES;
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
hd_cb.use_in_qos = TRUE;
|
||||
hd_cb.in_qos.service_type = service_type;
|
||||
hd_cb.in_qos.token_rate = token_rate;
|
||||
@@ -573,7 +645,14 @@ tHID_STATUS HID_DevSetIncomingQos(uint8_t service_type, uint32_t token_rate, uin
|
||||
tHID_STATUS HID_DevSetOutgoingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
|
||||
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (!hidd_cb_ptr) {
|
||||
return HID_ERR_NO_RESOURCES;
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
hd_cb.l2cap_intr_cfg.qos_present = TRUE;
|
||||
hd_cb.l2cap_intr_cfg.qos.service_type = service_type;
|
||||
hd_cb.l2cap_intr_cfg.qos.token_rate = token_rate;
|
||||
|
||||
@@ -451,6 +451,10 @@ static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result)
|
||||
}
|
||||
if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) {
|
||||
HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__);
|
||||
if (hd_cb.pending_data) {
|
||||
osi_free(hd_cb.pending_data);
|
||||
hd_cb.pending_data = NULL;
|
||||
}
|
||||
hd_cb.device.state = HIDD_DEV_NO_CONN;
|
||||
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
|
||||
if (hd_cb.pending_vc_unplug) {
|
||||
@@ -667,6 +671,7 @@ tHID_STATUS hidd_conn_initiate(void)
|
||||
if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) == 0) {
|
||||
HIDD_TRACE_WARNING("%s: could not start L2CAP connection", __func__);
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL);
|
||||
return HID_ERR_L2CAP_FAILED;
|
||||
} else {
|
||||
p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,9 @@ tHID_STATUS HID_HostGetSDPRecord ( BD_ADDR addr, tSDP_DISCOVERY_DB *p_db, UINT32
|
||||
uuid_list.uu.uuid16 = UUID_SERVCLASS_HUMAN_INTERFACE;
|
||||
|
||||
hh_cb.p_sdp_db = p_db;
|
||||
SDP_InitDiscoveryDb (p_db, db_len, 1, &uuid_list, 0, NULL);
|
||||
if (!SDP_InitDiscoveryDb (p_db, db_len, 1, &uuid_list, 0, NULL)) {
|
||||
return HID_ERR_NO_RESOURCES;
|
||||
}
|
||||
|
||||
if (SDP_ServiceSearchRequest (addr, p_db, hidh_search_callback)) {
|
||||
hh_cb.sdp_cback = sdp_cback ;
|
||||
@@ -558,11 +560,10 @@ tHID_STATUS HID_HostCloseDev( UINT8 dev_handle )
|
||||
return HID_ERR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY + 1;
|
||||
return hidh_conn_disconnect( dev_handle );
|
||||
}
|
||||
|
||||
tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl )
|
||||
tHID_STATUS HID_HostSetSecurityLevel( const char *serv_name, UINT8 sec_lvl )
|
||||
{
|
||||
if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HIDH_SEC_CTRL,
|
||||
sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN)) {
|
||||
@@ -656,6 +657,11 @@ BOOLEAN HID_HostConnectOrig(UINT8 dev_handle)
|
||||
BOOLEAN ret = FALSE;
|
||||
|
||||
do {
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (!hidh_cb_ptr) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (!hh_cb.reg_flag) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ tHID_STATUS hidh_conn_reg (void)
|
||||
}
|
||||
|
||||
for (xx = 0; xx < HID_HOST_MAX_DEVICES; xx++) {
|
||||
memset(&hh_cb.devices[xx], 0, sizeof(tHID_HOST_DEV_CTB));
|
||||
hh_cb.devices[xx].in_use = FALSE ;
|
||||
hh_cb.devices[xx].delay_remove = FALSE;
|
||||
hh_cb.devices[xx].conn.conn_state = HID_CONN_STATE_UNUSED;
|
||||
@@ -515,7 +516,7 @@ static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
|
||||
}
|
||||
|
||||
if (p_hcon == NULL) {
|
||||
HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid);
|
||||
HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg cfm, unknown CID: 0x%x", l2cap_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -833,6 +834,7 @@ static void hidh_l2cif_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
|
||||
tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
UINT16 data, UINT8 report_id, BT_HDR *buf)
|
||||
{
|
||||
tHID_STATUS rc = HID_SUCCESS;
|
||||
tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn;
|
||||
BT_HDR *p_buf;
|
||||
UINT8 *p_out;
|
||||
@@ -845,17 +847,13 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
BOOLEAN blank_datc = FALSE;
|
||||
|
||||
if (!BTM_IsAclConnectionUp(hh_cb.devices[dhandle].addr, BT_TRANSPORT_BR_EDR)) {
|
||||
if (buf) {
|
||||
osi_free ((void *)buf);
|
||||
}
|
||||
return ( HID_ERR_NO_CONNECTION );
|
||||
rc = HID_ERR_NO_CONNECTION;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) {
|
||||
if (buf) {
|
||||
osi_free ((void *)buf);
|
||||
}
|
||||
return ( HID_ERR_CONGESTED );
|
||||
rc = HID_ERR_CONGESTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch ( trans_type ) {
|
||||
@@ -874,7 +872,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
buf_size = HID_INTERRUPT_BUF_SIZE;
|
||||
break;
|
||||
default:
|
||||
return (HID_ERR_INVALID_PARAM) ;
|
||||
rc = HID_ERR_INVALID_PARAM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ( trans_type == HID_TRANS_SET_IDLE ) {
|
||||
@@ -886,7 +885,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
do {
|
||||
if ( buf == NULL || blank_datc ) {
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(buf_size)) == NULL) {
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
rc = HID_ERR_NO_RESOURCES;
|
||||
goto error;
|
||||
}
|
||||
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
@@ -896,7 +896,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
blank_datc = FALSE;
|
||||
} else if ( (buf->len > (p_hcon->rem_mtu_size - 1))) {
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(buf_size)) == NULL) {
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
rc = HID_ERR_NO_RESOURCES;
|
||||
goto error;
|
||||
}
|
||||
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
@@ -904,11 +905,13 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
data_size = buf->len;
|
||||
bytes_copied = p_hcon->rem_mtu_size - 1;
|
||||
} else {
|
||||
p_buf = buf ;
|
||||
p_buf = buf;
|
||||
p_buf->offset -= 1;
|
||||
seg_req = FALSE;
|
||||
data_size = buf->len;
|
||||
bytes_copied = buf->len;
|
||||
// The ownership of buf has been handed over to p_buf
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
p_out = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
@@ -937,7 +940,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
|
||||
/* Send the buffer through L2CAP */
|
||||
if (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED) {
|
||||
return (HID_ERR_CONGESTED);
|
||||
rc = HID_ERR_CONGESTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (data_size) {
|
||||
@@ -950,6 +954,12 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
|
||||
} while ((data_size != 0) || blank_datc ) ;
|
||||
|
||||
return (HID_SUCCESS);
|
||||
|
||||
error:
|
||||
if (buf) {
|
||||
osi_free ((void *)buf);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -1018,7 +1028,7 @@ BOOLEAN hidh_conn_is_orig(UINT8 dhandle)
|
||||
**
|
||||
** Description This function finds a connection control block based on CID
|
||||
**
|
||||
** Returns address of control block, or NULL if not found
|
||||
** Returns index of connection, or HID_HOST_MAX_DEVICES if not found
|
||||
**
|
||||
*******************************************************************************/
|
||||
static UINT8 find_conn_by_cid (UINT16 cid)
|
||||
|
||||
@@ -194,11 +194,15 @@ extern UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data,
|
||||
**
|
||||
** Function GAP_GetRxQueueCnt
|
||||
**
|
||||
** Description This function return number of bytes on the rx queue.
|
||||
** Description Return the number of bytes waiting on the connection rx queue.
|
||||
**
|
||||
** Parameters: handle - Handle returned in the GAP_ConnOpen
|
||||
** p_rx_queue_count - Pointer to return queue count in.
|
||||
** Parameters: handle - Handle returned from GAP_ConnOpen
|
||||
** p_rx_queue_count - Pointer to receive queue byte count
|
||||
**
|
||||
** Returns BT_PASS - success, count stored in *p_rx_queue_count
|
||||
** GAP_ERR_ILL_PARM - p_rx_queue_count is NULL
|
||||
** GAP_ERR_BAD_HANDLE - handle is invalid
|
||||
** GAP_ERR_BAD_STATE - connection is not established
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count);
|
||||
|
||||
@@ -411,7 +411,7 @@
|
||||
#define HCI_BLE_SET_PAST_PARAMS (0x005C | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_SET_DEFAULT_PAST_PARAMS (0x005D | HCI_GRP_BLE_CMDS)
|
||||
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
|
||||
#define HCI_BLE_READ_BUFFER_SZIE_V2 (0x0060 | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_READ_BUFFER_SIZE_V2 (0x0060 | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_ISO_READ_TX_SYNC (0x0061 | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_ISO_SET_CIG_PARAMS (0x0062 | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_ISO_SET_CIG_PARAMS_TEST (0x0063 | HCI_GRP_BLE_CMDS)
|
||||
|
||||
@@ -435,7 +435,7 @@ BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat,
|
||||
#endif /* BTM_SSR_INCLUDED */
|
||||
|
||||
/* Extended Inquiry Response */
|
||||
void btsnd_hcic_write_ext_inquiry_response(BT_HDR *buffer, UINT8 fec_req);
|
||||
BOOLEAN btsnd_hcic_write_ext_inquiry_response(BT_HDR *buffer, UINT8 fec_req);
|
||||
|
||||
#define HCIC_PARAM_SIZE_EXT_INQ_RESP 241
|
||||
|
||||
@@ -670,7 +670,7 @@ BOOLEAN btsnd_hcic_write_link_super_tout(UINT8 local_controller_id, UINT16 handl
|
||||
/* Write Link Supervision Timeout */
|
||||
|
||||
BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac,
|
||||
LAP *const iac_lap); /* Write Current IAC LAP */
|
||||
const LAP *iac_lap); /* Write Current IAC LAP */
|
||||
|
||||
#define MAX_IAC_LAPS 0x40
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ extern tHID_STATUS HID_DevDeregister(void);
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl);
|
||||
extern tHID_STATUS HID_DevSetSecurityLevel(uint16_t sec_lvl);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
||||
@@ -223,7 +223,7 @@ extern void HID_HostDeinit(void);
|
||||
**
|
||||
** Returns tHID_STATUS
|
||||
*******************************************************************************/
|
||||
extern tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl );
|
||||
extern tHID_STATUS HID_HostSetSecurityLevel( const char *serv_name, UINT8 sec_lvl );
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
||||
@@ -783,7 +783,7 @@ extern void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_H
|
||||
extern void l2c_link_adjust_allocation (void);
|
||||
extern void l2c_link_process_num_completed_pkts (UINT8 *p, UINT8 evt_len);
|
||||
extern void l2c_link_process_num_completed_blocks (UINT8 controller_id, UINT8 *p, UINT16 evt_len);
|
||||
extern void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs);
|
||||
extern void l2c_link_process_num_bufs (UINT16 num_lm_acl_bufs);
|
||||
extern UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles);
|
||||
extern void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status);
|
||||
extern void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data, UINT8 status);
|
||||
|
||||
@@ -286,8 +286,14 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
|
||||
p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
|
||||
}
|
||||
|
||||
p_ccb->max_rx_mtu = p_ertm_info->user_rx_buf_size -
|
||||
(L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
|
||||
UINT16 overhead = L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN;
|
||||
if (p_ccb->ertm_info.user_rx_buf_size > overhead) {
|
||||
p_ccb->max_rx_mtu = p_ccb->ertm_info.user_rx_buf_size - overhead;
|
||||
} else {
|
||||
L2CAP_TRACE_ERROR ("L2CAP - Req rx mtu (0) invalid");
|
||||
l2cu_release_ccb(p_ccb);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -435,8 +441,13 @@ BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 re
|
||||
p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
|
||||
}
|
||||
|
||||
p_ccb->max_rx_mtu = p_ertm_info->user_rx_buf_size -
|
||||
(L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
|
||||
UINT16 overhead = L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN;
|
||||
if (p_ccb->ertm_info.user_rx_buf_size > overhead) {
|
||||
p_ccb->max_rx_mtu = p_ccb->ertm_info.user_rx_buf_size - overhead;
|
||||
} else {
|
||||
L2CAP_TRACE_ERROR ("L2CAP - Rsp rx mtu invalid");
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (result == L2CAP_CONN_OK) {
|
||||
@@ -685,7 +696,8 @@ BOOLEAN L2CA_Ping (BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB *p_callback)
|
||||
BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_callback)
|
||||
{
|
||||
tL2C_LCB *p_lcb;
|
||||
UINT8 *pp;
|
||||
UINT8 *pp = NULL;
|
||||
UINT16 len = 0;
|
||||
|
||||
L2CAP_TRACE_API ("L2CA_Echo() BDA: %08X%04X",
|
||||
((p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) + (p_bd_addr[3])),
|
||||
@@ -717,9 +729,12 @@ BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_cal
|
||||
l2cb.p_echo_data_cb = p_callback;
|
||||
|
||||
/* Set the pointer to the beginning of the data */
|
||||
pp = (UINT8 *)(p_data + 1) + p_data->offset;
|
||||
if (p_data) {
|
||||
pp = (UINT8 *)(p_data + 1) + p_data->offset;
|
||||
len = p_data->len;
|
||||
}
|
||||
l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */
|
||||
l2cu_send_peer_echo_req (p_lcb, pp, p_data->len);
|
||||
l2cu_send_peer_echo_req (p_lcb, pp, len);
|
||||
|
||||
return (TRUE);
|
||||
|
||||
@@ -731,7 +746,7 @@ BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_cal
|
||||
bool L2CA_GetIdentifiers(uint16_t lcid, uint16_t *rcid, uint16_t *handle)
|
||||
{
|
||||
tL2C_CCB *control_block = l2cu_find_ccb_by_cid(NULL, lcid);
|
||||
if (!control_block) {
|
||||
if (!control_block || !control_block->p_lcb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -830,7 +845,7 @@ BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout, tBT_TRANSPO
|
||||
} else {
|
||||
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->in_use) && (p_lcb->link_state == LST_CONNECTED) && p_lcb->transport == transport) {
|
||||
p_lcb->idle_timeout = timeout;
|
||||
|
||||
if (!p_lcb->ccb_queue.p_first_ccb) {
|
||||
@@ -946,6 +961,8 @@ UINT16 L2CA_LocalLoopbackReq (UINT16 psm, UINT16 handle, BD_ADDR p_bd_addr)
|
||||
/* Allocate a channel control block */
|
||||
if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_conn_req");
|
||||
p_lcb->link_state = LST_DISCONNECTED;
|
||||
l2cu_release_lcb(p_lcb);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1047,7 +1064,7 @@ BOOLEAN L2CA_SendTestSFrame (UINT16 cid, UINT8 sup_type, UINT8 back_track)
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
p_ccb->fcrb.next_seq_expected -= back_track;
|
||||
p_ccb->fcrb.next_seq_expected = (p_ccb->fcrb.next_seq_expected - back_track) & L2CAP_FCR_SEQ_MODULO;
|
||||
|
||||
l2c_fcr_send_S_frame (p_ccb, (UINT16)(sup_type & 3), (UINT16)(sup_type & (L2CAP_FCR_P_BIT | L2CAP_FCR_F_BIT)));
|
||||
|
||||
@@ -1172,14 +1189,13 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
|
||||
|
||||
if ((p_lcb) && (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;
|
||||
|
||||
L2CAP_TRACE_API ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
|
||||
flush_tout, bd_addr[3], bd_addr[4], bd_addr[5]);
|
||||
|
||||
if (!btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to)) {
|
||||
return (FALSE);
|
||||
}
|
||||
p_lcb->link_flush_tout = flush_tout;
|
||||
}
|
||||
} else {
|
||||
L2CAP_TRACE_WARNING ("WARNING L2CA_SetFlushTimeout No lcb for bd_addr [...;%02x%02x%02x]",
|
||||
@@ -1192,8 +1208,6 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
|
||||
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;
|
||||
|
||||
L2CAP_TRACE_API ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
|
||||
flush_tout, p_lcb->remote_bd_addr[3],
|
||||
p_lcb->remote_bd_addr[4], p_lcb->remote_bd_addr[5]);
|
||||
@@ -1201,6 +1215,7 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
|
||||
if (!btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to)) {
|
||||
return (FALSE);
|
||||
}
|
||||
p_lcb->link_flush_tout = flush_tout;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2123,7 +2138,7 @@ BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle
|
||||
transport = BT_TRANSPORT_LE;
|
||||
}
|
||||
#endif
|
||||
if (fixed_cid<L2CAP_FIRST_FIXED_CHNL) {
|
||||
if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
@@ -2169,6 +2184,11 @@ BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid,
|
||||
|
||||
L2CAP_TRACE_API ("L2CA_GetCurrentConfig() CID: 0x%04x", lcid);
|
||||
|
||||
if (!pp_our_cfg || !p_our_cfg_bits || !pp_peer_cfg || !p_peer_cfg_bits) {
|
||||
L2CAP_TRACE_ERROR ("L2CA_GetCurrentConfig() - NULL output pointer");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
|
||||
|
||||
if (p_ccb) {
|
||||
@@ -2269,7 +2289,7 @@ void l2cap_bqb_write_data(UINT16 cid)
|
||||
BT_HDR *p_buf;
|
||||
uint8_t *p;
|
||||
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE)) != NULL) {
|
||||
if ((p_buf = (BT_HDR *)osi_calloc(SDP_DATA_BUF_SIZE)) != NULL) {
|
||||
p_buf->len = 30;
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
|
||||
@@ -50,7 +50,7 @@ static void l2c_csm_w4_l2cap_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void
|
||||
static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data);
|
||||
|
||||
#if (BT_TRACE_VERBOSE == TRUE)
|
||||
static char *l2c_csm_get_event_name (UINT16 event);
|
||||
static const char *l2c_csm_get_event_name (UINT16 event);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -221,7 +221,7 @@ static void l2c_csm_closed (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
|
||||
/* Need to have at least one compatible channel to continue */
|
||||
if (!l2c_fcr_chk_chan_modes(p_ccb)) {
|
||||
l2cu_release_ccb (p_ccb);
|
||||
(*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(local_cid, L2CAP_CONN_NO_LINK);
|
||||
(*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
|
||||
} else {
|
||||
l2cu_send_peer_connect_req (p_ccb);
|
||||
btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT);
|
||||
@@ -757,13 +757,17 @@ static void l2c_csm_config (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
|
||||
break;
|
||||
|
||||
case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer config error rsp */
|
||||
/* Disable the Timer */
|
||||
btu_stop_timer (&p_ccb->timer_entry);
|
||||
|
||||
/* If failure was channel mode try to renegotiate */
|
||||
if (l2c_fcr_renegotiate_chan(p_ccb, p_cfg) == FALSE) {
|
||||
L2CAP_TRACE_API ("L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d", p_ccb->local_cid, p_cfg->result);
|
||||
(*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(p_ccb->local_cid, p_cfg);
|
||||
if (p_ccb && p_ccb->in_use) {
|
||||
/* Disable the Timer */
|
||||
btu_stop_timer (&p_ccb->timer_entry);
|
||||
tL2CA_CONFIG_CFM_CB *config_cfm = p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb;
|
||||
/* If failure was channel mode try to renegotiate */
|
||||
if (l2c_fcr_renegotiate_chan(p_ccb, p_cfg) == FALSE) {
|
||||
L2CAP_TRACE_API ("L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d", p_ccb->local_cid, p_cfg->result);
|
||||
if (p_ccb->in_use) {
|
||||
(*config_cfm)(p_ccb->local_cid, p_cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -897,6 +901,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
|
||||
tL2C_CHNL_STATE tempstate;
|
||||
UINT8 tempcfgdone;
|
||||
UINT8 cfg_result = L2CAP_PEER_CFG_DISCONNECT;
|
||||
tL2CA_DISCONNECT_IND_CB *disconnect_ind = NULL;
|
||||
|
||||
#if (BT_TRACE_VERBOSE == TRUE)
|
||||
L2CAP_TRACE_EVENT ("L2CAP - LCID: 0x%04x st: OPEN evt: %s",
|
||||
@@ -919,9 +924,12 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
|
||||
case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
|
||||
L2CAP_TRACE_API ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
|
||||
p_ccb->local_cid);
|
||||
l2cu_release_ccb (p_ccb);
|
||||
if (p_ccb->p_rcb) {
|
||||
(*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(local_cid, FALSE);
|
||||
disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
|
||||
}
|
||||
l2cu_release_ccb (p_ccb);
|
||||
if (disconnect_ind) {
|
||||
(*disconnect_ind)(local_cid, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -985,6 +993,8 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
|
||||
case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
|
||||
if (p_data && (p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_DataInd_Cb)) {
|
||||
(*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR *)p_data);
|
||||
} else if (p_data) {
|
||||
osi_free(p_data);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1136,7 +1146,6 @@ static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /// (L2CAP_COC_INCLUDED == TRUE)
|
||||
|
||||
#if (BT_TRACE_VERBOSE == TRUE)
|
||||
/*******************************************************************************
|
||||
@@ -1150,7 +1159,7 @@ static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void
|
||||
** Returns pointer to the name
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *l2c_csm_get_event_name (UINT16 event)
|
||||
static const char *l2c_csm_get_event_name (UINT16 event)
|
||||
{
|
||||
switch (event) {
|
||||
case L2CEVT_LP_CONNECT_CFM: /* Lower layer connect confirm */
|
||||
@@ -1228,6 +1237,7 @@ static char *l2c_csm_get_event_name (UINT16 event)
|
||||
}
|
||||
}
|
||||
#endif /* (BT_TRACE_VERBOSE == TRUE) */
|
||||
#endif /// (L2CAP_COC_INCLUDED == TRUE)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -256,7 +256,8 @@ void l2c_fcr_cleanup (tL2C_CCB *p_ccb)
|
||||
#if (L2CAP_ERTM_STATS == TRUE)
|
||||
if ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID) && (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) ) {
|
||||
UINT32 dur = osi_time_get_os_boottime_ms() - p_ccb->fcrb.connect_tick_count;
|
||||
char *p_str = (char *)osi_malloc(120);
|
||||
UINT32 str_len = 120;
|
||||
char *p_str = (char *)osi_malloc(str_len);
|
||||
UINT16 i;
|
||||
UINT32 throughput_avg, ack_delay_avg, ack_q_count_avg;
|
||||
|
||||
@@ -270,14 +271,14 @@ void l2c_fcr_cleanup (tL2C_CCB *p_ccb)
|
||||
BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC,
|
||||
"max_held_acks:%08u, in_cfg.fcr.tx_win_sz:%08u", p_ccb->fcrb.max_held_acks, p_ccb->peer_cfg.fcr.tx_win_sz );
|
||||
if (p_str) {
|
||||
sprintf(p_str, "Sent Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
|
||||
snprintf(p_str, str_len, "Sent Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
|
||||
p_ccb->fcrb.ertm_pkt_counts[0], p_ccb->fcrb.ertm_byte_counts[0],
|
||||
(dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[0] * 100) / (dur / 10) : 0),
|
||||
p_ccb->fcrb.s_frames_sent[0], p_ccb->fcrb.s_frames_sent[1], p_ccb->fcrb.s_frames_sent[2], p_ccb->fcrb.s_frames_sent[3]);
|
||||
|
||||
BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, "%s", p_str);
|
||||
|
||||
sprintf(p_str, "Rcvd Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
|
||||
snprintf(p_str, str_len, "Rcvd Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
|
||||
p_ccb->fcrb.ertm_pkt_counts[1], p_ccb->fcrb.ertm_byte_counts[1],
|
||||
(dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[1] * 100) / (dur / 10) : 0),
|
||||
p_ccb->fcrb.s_frames_rcvd[0], p_ccb->fcrb.s_frames_rcvd[1], p_ccb->fcrb.s_frames_rcvd[2], p_ccb->fcrb.s_frames_rcvd[3]);
|
||||
@@ -295,7 +296,7 @@ void l2c_fcr_cleanup (tL2C_CCB *p_ccb)
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf(p_str, "[%02u] throughput: %5u, ack_delay avg:%3u, min:%3u, max:%3u, ack_q_count avg:%3u, min:%3u, max:%3u",
|
||||
snprintf(p_str, str_len, "[%02u] throughput: %5u, ack_delay avg:%3u, min:%3u, max:%3u, ack_q_count avg:%3u, min:%3u, max:%3u",
|
||||
i, p_ccb->fcrb.throughput[i],
|
||||
p_ccb->fcrb.ack_delay_avg[i], p_ccb->fcrb.ack_delay_min[i], p_ccb->fcrb.ack_delay_max[i],
|
||||
p_ccb->fcrb.ack_q_count_avg[i], p_ccb->fcrb.ack_q_count_min[i], p_ccb->fcrb.ack_q_count_max[i] );
|
||||
@@ -343,7 +344,7 @@ BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes)
|
||||
* NOTE: We allocate extra L2CAP_FCS_LEN octets, in case we need to put
|
||||
* the FCS (Frame Check Sequence) at the end of the buffer.
|
||||
*/
|
||||
uint16_t buf_size = no_of_bytes + sizeof(BT_HDR) + new_offset + L2CAP_FCS_LEN;
|
||||
UINT32 buf_size = no_of_bytes + sizeof(BT_HDR) + new_offset + L2CAP_FCS_LEN;
|
||||
#if (L2CAP_ERTM_STATS == TRUE)
|
||||
/*
|
||||
* NOTE: If L2CAP_ERTM_STATS is enabled, we need 4 extra octets at the
|
||||
@@ -351,6 +352,11 @@ BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes)
|
||||
*/
|
||||
buf_size += sizeof(uint32_t);
|
||||
#endif
|
||||
if (buf_size > L2CAP_MAX_BUF_SIZE) {
|
||||
L2CAP_TRACE_ERROR ("l2c_fcr_clone_buf() buf_size invalid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BT_HDR *p_buf2 = (BT_HDR *)osi_malloc(buf_size);
|
||||
if (!p_buf2) {
|
||||
L2CAP_TRACE_ERROR ("l2c_fcr_clone_buf() malloc failed");
|
||||
@@ -372,7 +378,7 @@ BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes)
|
||||
**
|
||||
** Description This function checks if the CCB is flow controlled by peer.
|
||||
**
|
||||
** Returns The control word
|
||||
** Returns TRUE if the CCB is flow controlled by peer, FALSE otherwise
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN l2c_fcr_is_flow_controlled (tL2C_CCB *p_ccb)
|
||||
@@ -1452,6 +1458,8 @@ static BOOLEAN retransmit_i_frames (tL2C_CCB *p_ccb, UINT8 tx_seq)
|
||||
if (tx_seq == buf_seq) {
|
||||
break;
|
||||
}
|
||||
|
||||
p_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -224,8 +224,10 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda)
|
||||
p_lcb->br_edr_create_con_retries = 0;
|
||||
btu_stop_timer(&p_lcb->retry_timer_entry);
|
||||
/* For all channels, send the event through their FSMs */
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
|
||||
tL2C_CCB *pn = p_ccb->p_next_ccb;
|
||||
l2c_csm_execute (p_ccb, L2CEVT_LP_CONNECT_CFM, &ci);
|
||||
p_ccb = pn;
|
||||
}
|
||||
#endif ///CLASSIC_BT_INCLUDED == TRUE
|
||||
if (p_lcb->p_echo_rsp_cb) {
|
||||
@@ -607,10 +609,12 @@ BOOLEAN l2c_link_hci_qos_violation (UINT16 handle)
|
||||
}
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
/* For all channels, tell the upper layer about it */
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
|
||||
if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) {
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
|
||||
tL2C_CCB *pn = p_ccb->p_next_ccb;
|
||||
if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) {
|
||||
l2c_csm_execute (p_ccb, L2CEVT_LP_QOS_VIOLATION_IND, NULL);
|
||||
}
|
||||
p_ccb = pn;
|
||||
}
|
||||
#endif ///CLASSIC_BT_INCLUDED == TRUE
|
||||
return (TRUE);
|
||||
@@ -781,6 +785,7 @@ void l2c_info_timeout (tL2C_LCB *p_lcb)
|
||||
{
|
||||
tL2C_CCB *p_ccb;
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
tL2C_CCB *p_next_ccb;
|
||||
tL2C_CONN_INFO ci;
|
||||
#endif ///CLASSIC_BT_INCLUDED == TRUE
|
||||
/* If we timed out waiting for info response, just continue using basic if allowed */
|
||||
@@ -803,8 +808,10 @@ void l2c_info_timeout (tL2C_LCB *p_lcb)
|
||||
ci.status = HCI_SUCCESS;
|
||||
memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
|
||||
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
|
||||
p_next_ccb = p_ccb->p_next_ccb;
|
||||
l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
|
||||
p_ccb = p_next_ccb;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -838,6 +845,10 @@ void l2c_link_adjust_allocation (void)
|
||||
UINT16 high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
|
||||
list_node_t *p_node = NULL;
|
||||
|
||||
if (controller_xmit_quota == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no links active, reset buffer quotas and controller buffers */
|
||||
if (l2cb.num_links_active == 0) {
|
||||
l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
|
||||
@@ -976,7 +987,7 @@ void l2c_link_adjust_chnl_allocation (void)
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function l2c_link_processs_num_bufs
|
||||
** Function l2c_link_process_num_bufs
|
||||
**
|
||||
** Description This function is called when a "controller buffer size"
|
||||
** event is first received from the controller. It updates
|
||||
@@ -985,7 +996,7 @@ void l2c_link_adjust_chnl_allocation (void)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs)
|
||||
void l2c_link_process_num_bufs (UINT16 num_lm_acl_bufs)
|
||||
{
|
||||
l2cb.num_lm_acl_bufs = l2cb.controller_xmit_window = num_lm_acl_bufs;
|
||||
|
||||
@@ -1033,10 +1044,9 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status)
|
||||
/* If here came form hci role change event */
|
||||
p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
|
||||
if (p_lcb) {
|
||||
p_lcb->link_role = new_role;
|
||||
|
||||
/* Reset high priority link if needed */
|
||||
if (hci_status == HCI_SUCCESS) {
|
||||
p_lcb->link_role = new_role;
|
||||
l2cu_set_acl_priority(bd_addr, p_lcb->acl_priority, TRUE);
|
||||
}
|
||||
}
|
||||
@@ -1396,7 +1406,16 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (acl_data_size == 0) {
|
||||
osi_free(p_buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
num_segs = (p_buf->len - HCI_DATA_PREAMBLE_SIZE + acl_data_size - 1) / acl_data_size;
|
||||
if (num_segs == 0) {
|
||||
osi_free(p_buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* If doing round-robin, then only 1 segment each time */
|
||||
@@ -1642,7 +1661,9 @@ void l2c_link_segments_xmitted (BT_HDR *p_msg)
|
||||
if (p_lcb->link_state == LST_CONNECTED) {
|
||||
/* Enqueue the buffer to the head of the transmit queue, and see */
|
||||
/* if we can transmit anything more. */
|
||||
list_prepend(p_lcb->link_xmit_data_q, p_msg);
|
||||
if (!list_prepend(p_lcb->link_xmit_data_q, p_msg)) {
|
||||
osi_free(p_msg);
|
||||
}
|
||||
|
||||
p_lcb->partial_segment_being_sent = FALSE;
|
||||
|
||||
|
||||
@@ -365,8 +365,9 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
tL2CAP_CFG_INFO cfg_info;
|
||||
UINT16 rej_reason, rej_mtu, lcid, rcid, info_type;
|
||||
tL2C_CCB *p_ccb;
|
||||
tL2C_CCB *p_next_ccb;
|
||||
tL2C_RCB *p_rcb;
|
||||
BOOLEAN cfg_rej, cfg_bad, info_bad, pkt_size_rej = FALSE;
|
||||
BOOLEAN cfg_rej, cfg_bad, pkt_size_rej = FALSE;
|
||||
UINT16 cfg_rej_len, cmd_len;
|
||||
UINT16 result;
|
||||
tL2C_CONN_INFO ci;
|
||||
@@ -467,8 +468,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
|
||||
|
||||
/* For all channels, send the event through their FSMs */
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
|
||||
p_next_ccb = p_ccb->p_next_ccb;
|
||||
l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
|
||||
p_ccb = p_next_ccb;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -541,14 +544,14 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
break;
|
||||
|
||||
case L2CAP_CMD_CONFIG_REQ:
|
||||
if (cmd_len < L2CAP_CONFIG_REQ_LEN) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - cfg req too short, cmd_len: %d", cmd_len);
|
||||
break;
|
||||
}
|
||||
p_cfg_end = p + cmd_len;
|
||||
cfg_rej = FALSE;
|
||||
cfg_rej_len = 0;
|
||||
|
||||
if ((p_cfg_end - p) < L2CAP_CONFIG_REQ_LEN) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - cfg req too short, cmd_len: %d", cmd_len);
|
||||
break;
|
||||
}
|
||||
STREAM_TO_UINT16 (lcid, p);
|
||||
STREAM_TO_UINT16 (cfg_info.flags, p);
|
||||
|
||||
@@ -673,13 +676,12 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
break;
|
||||
|
||||
case L2CAP_CMD_CONFIG_RSP:
|
||||
p_cfg_end = p + cmd_len;
|
||||
cfg_bad = FALSE;
|
||||
|
||||
if ((p_cfg_end - p) < L2CAP_CONFIG_RSP_LEN) {
|
||||
if (cmd_len < L2CAP_CONFIG_RSP_LEN) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - cfg rsp too short, cmd_len: %d", cmd_len);
|
||||
break;
|
||||
}
|
||||
p_cfg_end = p + cmd_len;
|
||||
cfg_bad = FALSE;
|
||||
STREAM_TO_UINT16 (lcid, p);
|
||||
STREAM_TO_UINT16 (cfg_info.flags, p);
|
||||
STREAM_TO_UINT16 (cfg_info.result, p);
|
||||
@@ -876,10 +878,11 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
break;
|
||||
|
||||
case L2CAP_CMD_INFO_RSP:
|
||||
info_bad = FALSE;
|
||||
p_info_end = p + cmd_len;
|
||||
{
|
||||
BOOLEAN info_bad = FALSE;
|
||||
|
||||
if ((p_info_end - p) < L2CAP_INFO_RSP_LEN) {
|
||||
p_info_end = p + cmd_len;
|
||||
if ((p + L2CAP_INFO_RSP_LEN) > p_info_end) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - cmd info rsp too short, cmd_len: %d", cmd_len);
|
||||
break;
|
||||
}
|
||||
@@ -944,15 +947,14 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (info_bad) {
|
||||
break;
|
||||
}
|
||||
|
||||
ci.status = HCI_SUCCESS;
|
||||
memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
|
||||
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
|
||||
p_next_ccb = p_ccb->p_next_ccb;
|
||||
l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
|
||||
p_ccb = p_next_ccb;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -408,6 +408,11 @@ UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 fla
|
||||
}
|
||||
}
|
||||
|
||||
if (p_buf->offset < L2CAP_UCD_OVERHEAD) {
|
||||
osi_free(p_buf);
|
||||
return L2CAP_DW_FAILED;
|
||||
}
|
||||
|
||||
/* write PSM */
|
||||
p_buf->offset -= L2CAP_UCD_OVERHEAD;
|
||||
p_buf->len += L2CAP_UCD_OVERHEAD;
|
||||
@@ -774,9 +779,15 @@ void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB *p_ccb)
|
||||
*******************************************************************************/
|
||||
BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb)
|
||||
{
|
||||
BT_HDR *p_buf = (BT_HDR*)fixed_queue_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q, 0);
|
||||
BT_HDR *p_buf = NULL;
|
||||
|
||||
while ((p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_ccb->p_lcb->ucd_in_sec_pending_q)) != NULL) {
|
||||
if (p_buf->len < L2CAP_UCD_OVERHEAD) {
|
||||
fixed_queue_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q, 0);
|
||||
osi_free(p_buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p_buf != NULL) {
|
||||
UINT16 psm;
|
||||
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
STREAM_TO_UINT16(psm, p)
|
||||
@@ -787,6 +798,7 @@ BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb)
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,10 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
|
||||
if (p_lcb) {
|
||||
memset (p_lcb, 0, sizeof(tL2C_LCB));
|
||||
list_ret = list_append(l2cb.p_lcb_pool, p_lcb);
|
||||
if (!list_ret) {
|
||||
osi_free(p_lcb);
|
||||
return NULL;
|
||||
}
|
||||
}else {
|
||||
L2CAP_TRACE_ERROR("Error in allocating L2CAP Link Control Block");
|
||||
}
|
||||
@@ -457,10 +461,14 @@ BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb)
|
||||
*******************************************************************************/
|
||||
BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id)
|
||||
{
|
||||
BT_HDR *p_buf = (BT_HDR *)osi_malloc(L2CAP_CMD_BUF_SIZE);
|
||||
BT_HDR *p_buf;
|
||||
UINT8 *p;
|
||||
|
||||
if (!p_buf) {
|
||||
if (len + BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD > L2CAP_CMD_BUF_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(L2CAP_CMD_BUF_SIZE)) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -667,7 +675,7 @@ void l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, U
|
||||
UINT8 *p;
|
||||
|
||||
if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL ) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
|
||||
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_rsp");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -724,7 +732,7 @@ void l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
|
||||
|
||||
if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16) (L2CAP_CONFIG_REQ_LEN + cfg_len),
|
||||
L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL ) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
|
||||
L2CAP_TRACE_WARNING ("L2CAP - no buffer for cfg_req");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -822,7 +830,7 @@ void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
|
||||
|
||||
if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16)(L2CAP_CONFIG_RSP_LEN + cfg_len),
|
||||
L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL ) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
|
||||
L2CAP_TRACE_WARNING ("L2CAP - no buffer for cfg_rsp");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1015,6 +1023,10 @@ void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
|
||||
BT_HDR *p_buf, *p_buf2;
|
||||
UINT8 *p;
|
||||
|
||||
if (!p_ccb || !p_ccb->p_lcb) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create an identifier for this packet */
|
||||
p_ccb->p_lcb->id++;
|
||||
l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
|
||||
@@ -1034,7 +1046,7 @@ void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
|
||||
/* Move all queued data packets to the LCB. In FCR mode, assume the higher
|
||||
layer checks that all buffers are sent before disconnecting.
|
||||
*/
|
||||
if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) {
|
||||
if (p_ccb->xmit_hold_q && (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)) {
|
||||
while ((p_buf2 = (BT_HDR *)fixed_queue_dequeue(p_ccb->xmit_hold_q, 0)) != NULL) {
|
||||
l2cu_set_acl_hci_header (p_buf2, p_ccb);
|
||||
l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2);
|
||||
@@ -1224,14 +1236,11 @@ void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type
|
||||
|
||||
#if (L2CAP_CONFORMANCE_TESTING == TRUE)
|
||||
if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
|
||||
&& (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
|
||||
L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
|
||||
L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
|
||||
&& (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
|
||||
L2CAP_EXTFEA_UCD_RECEPTION )) )
|
||||
#else
|
||||
if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
|
||||
&& (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
|
||||
L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_FIXED_CHNLS |
|
||||
L2CAP_EXTFEA_UCD_RECEPTION )) )
|
||||
#endif
|
||||
{
|
||||
@@ -1481,6 +1490,10 @@ void l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
|
||||
*******************************************************************************/
|
||||
void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
|
||||
{
|
||||
if ((priority >= L2CAP_NUM_CHNL_PRIORITY) || (p_ccb->ccb_priority >= L2CAP_NUM_CHNL_PRIORITY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_ccb->ccb_priority != priority) {
|
||||
/* If CCB is not the only guy on the queue */
|
||||
if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) ) {
|
||||
@@ -1536,7 +1549,10 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
|
||||
|
||||
if (p_ccb) {
|
||||
memset (p_ccb, 0, sizeof(tL2C_CCB));
|
||||
list_append(l2cb.p_ccb_pool, p_ccb);
|
||||
if (!list_append(l2cb.p_ccb_pool, p_ccb)) {
|
||||
osi_free(p_ccb);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1857,6 +1873,7 @@ tL2C_RCB *l2cu_allocate_rcb (UINT16 psm)
|
||||
|
||||
for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
|
||||
if (!p_rcb->in_use) {
|
||||
memset(p_rcb, 0, sizeof(tL2C_RCB));
|
||||
p_rcb->in_use = TRUE;
|
||||
p_rcb->psm = psm;
|
||||
#if (L2CAP_UCD_INCLUDED == TRUE)
|
||||
@@ -2679,7 +2696,10 @@ BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_af
|
||||
UINT16_TO_STREAM (pp, p_lcb->handle);
|
||||
UINT8_TO_STREAM (pp, vs_param);
|
||||
|
||||
BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
|
||||
tBTM_STATUS status = BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
|
||||
if (status != BTM_SUCCESS) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Adjust lmp buffer allocation for this channel if priority changed */
|
||||
if (p_lcb->acl_priority != priority) {
|
||||
@@ -2767,7 +2787,7 @@ void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
|
||||
** Description This function allows the script wrapper to change the
|
||||
** info resp mask for conformance testing.
|
||||
**
|
||||
** Returns pointer to CCB, or NULL if none
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void l2cu_set_info_rsp_mask (UINT32 mask)
|
||||
@@ -2846,9 +2866,9 @@ BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR
|
||||
/* Set CID for the connection */
|
||||
p_ccb->local_cid = fixed_cid;
|
||||
p_ccb->remote_cid = fixed_cid;
|
||||
|
||||
#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
|
||||
p_ccb->is_flushable = FALSE;
|
||||
|
||||
#endif
|
||||
p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
|
||||
|
||||
|
||||
@@ -2925,11 +2945,6 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
|
||||
/* BTM SEC will make sure that link is release (probably after pairing is done) */
|
||||
p_lcb->link_state = LST_DISCONNECTING;
|
||||
timeout = 0xFFFF;
|
||||
} else if ( (p_lcb->is_bonding)
|
||||
&& (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) ) {
|
||||
l2cu_process_fixed_disc_cback(p_lcb);
|
||||
p_lcb->link_state = LST_DISCONNECTING;
|
||||
timeout = L2CAP_LINK_DISCONNECT_TOUT;
|
||||
} else {
|
||||
/* probably no buffer to send disconnect */
|
||||
timeout = BT_1SEC_TIMEOUT;
|
||||
@@ -3036,7 +3051,8 @@ void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
|
||||
#if (L2CAP_NUM_FIXED_CHNLS > 0)
|
||||
|
||||
/* Select peer channels mask to use depending on transport */
|
||||
UINT8 peer_channel_mask = p_lcb->peer_chnl_mask[0];
|
||||
UINT8 peer_chnl_mask[L2CAP_FIXED_CHNL_ARRAY_SIZE] = {0};
|
||||
memcpy(peer_chnl_mask, p_lcb->peer_chnl_mask, sizeof(peer_chnl_mask));
|
||||
|
||||
// For LE, reset the stored peer channel mask
|
||||
if (p_lcb->transport == BT_TRANSPORT_LE) {
|
||||
@@ -3058,7 +3074,7 @@ void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
|
||||
p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
|
||||
#endif
|
||||
}
|
||||
} else if ( (peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
|
||||
} else if ( (peer_chnl_mask[(xx + L2CAP_FIRST_FIXED_CHNL) / 8] & (1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8)))
|
||||
&& (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) {
|
||||
#if BLE_INCLUDED == TRUE
|
||||
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
|
||||
@@ -3246,6 +3262,11 @@ void l2cu_send_peer_ble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result)
|
||||
UINT8 *p;
|
||||
|
||||
L2CAP_TRACE_DEBUG ("l2cu_send_peer_ble_credit_based_conn_res");
|
||||
|
||||
if (!p_ccb || !p_ccb->p_lcb) {
|
||||
L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_res - no link");
|
||||
return;
|
||||
}
|
||||
if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
|
||||
L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id)) == NULL )
|
||||
{
|
||||
@@ -3493,6 +3514,11 @@ tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle)
|
||||
{
|
||||
list_node_t *p_node = NULL;
|
||||
tL2C_LCB *p_lcb = NULL;
|
||||
|
||||
if (!l2cb.p_lcb_pool) {
|
||||
return 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)) {
|
||||
@@ -3693,11 +3719,11 @@ static tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
|
||||
if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
|
||||
return p_ccb;
|
||||
}
|
||||
|
||||
if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
|
||||
if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,11 @@ l2cap_client_t *l2cap_client_new(const l2cap_client_callbacks_t *callbacks, void
|
||||
goto error;
|
||||
}
|
||||
|
||||
list_append(l2cap_clients, ret);
|
||||
if (!list_append(l2cap_clients, ret)) {
|
||||
list_free(ret->outbound_fragments);
|
||||
osi_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -131,6 +135,11 @@ void l2cap_client_free(l2cap_client_t *client)
|
||||
l2cap_client_disconnect(client);
|
||||
list_free(client->outbound_fragments);
|
||||
osi_free(client);
|
||||
|
||||
if (l2cap_clients && list_is_empty(l2cap_clients)) {
|
||||
list_free(l2cap_clients);
|
||||
l2cap_clients = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdaddr, uint16_t psm)
|
||||
@@ -150,7 +159,12 @@ bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdad
|
||||
return false;
|
||||
}
|
||||
|
||||
L2CA_SetConnectionCallbacks(client->local_channel_id, &l2cap_callbacks);
|
||||
if (!L2CA_SetConnectionCallbacks(client->local_channel_id, &l2cap_callbacks)) {
|
||||
L2CA_DisconnectReq(client->local_channel_id);
|
||||
client->local_channel_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -192,8 +206,16 @@ bool l2cap_client_write(l2cap_client_t *client, buffer_t *packet)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t cid = client->local_channel_id;
|
||||
|
||||
fragment_packet(client, packet);
|
||||
dispatch_fragments(client);
|
||||
|
||||
client = find(cid);
|
||||
if (!client || !l2cap_client_is_connected(client)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -261,7 +283,9 @@ static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *reques
|
||||
}
|
||||
|
||||
// If we've configured both endpoints, let the listener know we've connected.
|
||||
client->configured_peer = true;
|
||||
if (response.result == L2CAP_CFG_OK) {
|
||||
client->configured_peer = true;
|
||||
}
|
||||
if (l2cap_client_is_connected(client)) {
|
||||
client->callbacks.connected(client, client->context);
|
||||
}
|
||||
@@ -355,7 +379,8 @@ static void congestion_cb(uint16_t local_channel_id, bool is_congested)
|
||||
// Once that's done, if we're still decongested, notify the listener so it
|
||||
// can start writing again.
|
||||
dispatch_fragments(client);
|
||||
if (!client->is_congested) {
|
||||
client = find(local_channel_id);
|
||||
if (client && !client->is_congested && l2cap_client_is_connected(client)) {
|
||||
client->callbacks.write_ready(client, client->context);
|
||||
}
|
||||
}
|
||||
@@ -372,6 +397,12 @@ static void read_ready_cb(uint16_t local_channel_id, BT_HDR *packet)
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet->len == 0) {
|
||||
L2CAP_TRACE_ERROR("%s zero packet length\n", __func__);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(sharvil): eliminate copy from BT_HDR.
|
||||
buffer_t *buffer = buffer_new(packet->len);
|
||||
if (!buffer) {
|
||||
@@ -399,8 +430,10 @@ static void fragment_packet(l2cap_client_t *client, buffer_t *packet)
|
||||
assert(client != NULL);
|
||||
assert(packet != NULL);
|
||||
|
||||
bool ret = false;
|
||||
// TODO(sharvil): eliminate copy into BT_HDR.
|
||||
BT_HDR *bt_packet = osi_malloc(sizeof(BT_HDR) + buffer_length(packet) + L2CAP_MIN_OFFSET);
|
||||
assert(bt_packet != NULL);
|
||||
bt_packet->offset = L2CAP_MIN_OFFSET;
|
||||
bt_packet->len = buffer_length(packet);
|
||||
memcpy(bt_packet->data + bt_packet->offset, buffer_ptr(packet), buffer_length(packet));
|
||||
@@ -408,7 +441,8 @@ static void fragment_packet(l2cap_client_t *client, buffer_t *packet)
|
||||
for (;;) {
|
||||
if (bt_packet->len <= client->remote_mtu) {
|
||||
if (bt_packet->len > 0) {
|
||||
list_append(client->outbound_fragments, bt_packet);
|
||||
ret = list_append(client->outbound_fragments, bt_packet);
|
||||
assert(ret);
|
||||
} else {
|
||||
osi_free(bt_packet);
|
||||
}
|
||||
@@ -416,11 +450,13 @@ static void fragment_packet(l2cap_client_t *client, buffer_t *packet)
|
||||
}
|
||||
|
||||
BT_HDR *fragment = osi_malloc(sizeof(BT_HDR) + client->remote_mtu + L2CAP_MIN_OFFSET);
|
||||
assert(fragment != NULL);
|
||||
fragment->offset = L2CAP_MIN_OFFSET;
|
||||
fragment->len = client->remote_mtu;
|
||||
memcpy(fragment->data + fragment->offset, bt_packet->data + bt_packet->offset, client->remote_mtu);
|
||||
|
||||
list_append(client->outbound_fragments, fragment);
|
||||
ret = list_append(client->outbound_fragments, fragment);
|
||||
assert(ret);
|
||||
|
||||
bt_packet->offset += client->remote_mtu;
|
||||
bt_packet->len -= client->remote_mtu;
|
||||
@@ -444,6 +480,7 @@ static void dispatch_fragments(l2cap_client_t *client)
|
||||
case L2CAP_DW_FAILED:
|
||||
L2CAP_TRACE_ERROR("%s error writing data to L2CAP connection LCID 0x%04x; disconnecting.", __func__, client->local_channel_id);
|
||||
l2cap_client_disconnect(client);
|
||||
client->callbacks.disconnected(client, client->context);
|
||||
return;
|
||||
|
||||
case L2CAP_DW_SUCCESS:
|
||||
@@ -456,6 +493,10 @@ static l2cap_client_t *find(uint16_t local_channel_id)
|
||||
{
|
||||
assert(local_channel_id != 0);
|
||||
|
||||
if (!l2cap_clients) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (const list_node_t *node = list_begin(l2cap_clients); node != list_end(l2cap_clients); node = list_next(node)) {
|
||||
l2cap_client_t *client = (l2cap_client_t *)list_node(node);
|
||||
if (client->local_channel_id == local_channel_id) {
|
||||
|
||||
Reference in New Issue
Block a user