Merge branch 'bugfix/sync_security_fix_from_flouride_v5.1' into 'release/v5.1'

fix: synchronized several security-related fixes from Google Fluoride (v5.1)

See merge request espressif/esp-idf!44410
This commit is contained in:
Jiang Jiang Jian
2025-12-31 09:17:50 +08:00
44 changed files with 450 additions and 161 deletions
@@ -1937,13 +1937,17 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
void bta_av_setconfig_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
{
tBTA_AV_REJECT reject;
UINT8 avdt_handle = p_data->ci_setconfig.avdt_handle;
UINT8 err_code = p_data->ci_setconfig.err_code;
bta_av_adjust_seps_idx(p_scb, avdt_handle);
if (err_code == AVDT_SUCCESS) {
err_code = AVDT_ERR_UNSUP_CFG;
}
bta_av_adjust_seps_idx(p_scb, p_scb->avdt_handle);
APPL_TRACE_DEBUG("bta_av_setconfig_rej: sep_idx: %d", p_scb->sep_idx);
AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, p_data->ci_setconfig.err_code, 0);
AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, err_code, 0);
bdcpy(reject.bd_addr, p_data->str_msg.bd_addr);
bdcpy(reject.bd_addr, p_scb->peer_addr);
reject.hndl = p_scb->hndl;
(*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, (tBTA_AV *) &reject);
}
@@ -1184,16 +1184,16 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
}
}
} else {
if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) {
bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
/* this channel is still marked as open. decrease the count */
bta_av_cb.audio_open_cnt--;
}
/* clear the conned mask for this channel */
p_cb->conn_audio &= ~mask;
p_cb->conn_video &= ~mask;
if (p_scb) {
if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) {
bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
/* this channel is still marked as open. decrease the count */
bta_av_cb.audio_open_cnt--;
}
/* clear the conned mask for this channel */
p_cb->conn_audio &= ~mask;
p_cb->conn_video &= ~mask;
/* the stream is closed.
* clear the peer address, so it would not mess up the AVRCP for the next round of operation */
bdcpy(p_scb->peer_addr, bd_addr_null);
@@ -1629,9 +1629,20 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
p_lcb = bta_av_find_lcb(p_scb->peer_addr, BTA_AV_LCB_FIND);
if (p_lcb) {
rc_handle = bta_av_rc_create(p_cb, AVCT_INT, (UINT8)(p_scb->hdi + 1), p_lcb->lidx);
p_cb->rcb[rc_handle].peer_features = peer_features;
p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features;
p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features;
if (rc_handle < BTA_AV_NUM_RCB) {
p_cb->rcb[rc_handle].peer_features = peer_features;
p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features;
p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features;
} else {
/* cannot create valid rc_handle for current device. report failure */
APPL_TRACE_ERROR("%s: no link resources available", __func__);
p_scb->use_rc = FALSE;
bdcpy(rc_open.peer_addr, p_scb->peer_addr);
rc_open.peer_features = 0;
rc_open.sdp_disc_done = FALSE;
rc_open.status = BTA_AV_FAIL_SDP;
(*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open);
}
}
#if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
else {
@@ -2248,7 +2248,7 @@ void bta_dm_search_result (tBTA_DM_MSG *p_data)
/* call back if application wants name discovery or found services that application is searching */
if (( !bta_dm_search_cb.services )
|| (( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services ))) {
|| ( p_data->disc_result.result.disc_res.services )) {
bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
}
@@ -2028,7 +2028,7 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) {
/* not an opened connection; or connection busy */
/* search for first available clcb and start discovery */
if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
if ((p_clcb == NULL) || (p_clcb->p_q_cmd != NULL)) {
for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) {
if (bta_gattc_cb.clcb[i].in_use &&
bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
@@ -1370,14 +1370,8 @@ BOOLEAN bta_ag_sco_is_open(tBTA_AG_SCB *p_scb)
*******************************************************************************/
BOOLEAN bta_ag_sco_is_opening(tBTA_AG_SCB *p_scb)
{
#if (BTM_WBS_INCLUDED == TRUE )
return (((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) ||
(bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST)) &&
(bta_ag_cb.sco.p_curr_scb == p_scb));
#else
return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) &&
(bta_ag_cb.sco.p_curr_scb == p_scb));
#endif
}
/*******************************************************************************
@@ -1665,7 +1659,7 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data
bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST)
{
/* If script overrided sco parameter by BTA_CMD_SET_ESCO_PARAM */
/* If script overrode sco parameter by BTA_CMD_SET_ESCO_PARAM */
if (bta_ag_cb.sco.param_updated)
{
resp = bta_ag_cb.sco.params;
@@ -1736,7 +1730,7 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data
**
** Function bta_ag_ci_sco_data
**
** Description Process the SCO data ready callin event
** Description Process the SCO data ready call in event
**
**
** Returns void
@@ -404,6 +404,11 @@ void bta_ag_do_disc(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service)
return;
}
if (p_scb->p_disc_db) {
APPL_TRACE_ERROR("Discovery already in progress... returning.");
return;
}
/* allocate buffer for sdp database */
p_scb->p_disc_db = (tSDP_DISCOVERY_DB *) osi_malloc(BTA_AG_DISC_BUF_SIZE);
if(p_scb->p_disc_db) {
@@ -362,6 +362,10 @@ static void bta_hf_client_handle_cind_list_item(char *name, UINT32 min, UINT32 m
APPL_TRACE_DEBUG("%s %u.%s <%u:%u>", __FUNCTION__, index, name, min, max);
if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
return;
}
/* look for a matching indicator on list of supported ones */
for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) {
if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) {
@@ -591,7 +595,7 @@ while (*buf == ' ') buf++;
buf += sizeof("\r\n") - 1;
/* skip rest of AT string up to <cr> */
#define AT_SKIP_REST(buf) while(*buf != '\r') buf++;
#define AT_SKIP_REST(buf) while((*buf != '\r') && (*buf != '\0')) buf++;
static char *bta_hf_client_parse_ok(char *buffer)
{
@@ -1018,7 +1022,7 @@ static char *bta_hf_client_parse_clcc(char *buffer)
}
}
/* Skip any remaing param,as they are not defined by BT HFP spec */
/* Skip any remaining param,as they are not defined by BT HFP spec */
AT_SKIP_REST(buffer);
AT_CHECK_RN(buffer);
@@ -1374,6 +1378,11 @@ void bta_hf_client_at_parse(char *buf, unsigned int len)
osi_free(tmp_buff);
}
/* prevent buffer overflow in cases where LEN exceeds available buffer space */
if (len > BTA_HF_CLIENT_AT_PARSER_MAX_LEN - bta_hf_client_cb.scb.at_cb.offset) {
return;
}
memcpy(bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, buf, len);
bta_hf_client_cb.scb.at_cb.offset += len;
@@ -1571,7 +1580,7 @@ void bta_hf_client_send_at_xapl(char *information, UINT32 features)
*vendorID: A string representation of the hex value of the vendor ID from the manufacturer, without the 0x prefix.
*productID: A string representation of the hex value of the product ID from the manufacturer, without the 0x prefix.
*version: The revision of the software.
*Fatures: A base-10 representation of a bit field. Available features are:
*Features: A base-10 representation of a bit field. Available features are:
*Bit 0 = reserved
*Bit 1 = The accessory supports battery reporting (reserved only for battery operated accessories).
*Bit 2 = The accessory is docked or powered (reserved only for battery operated accessories).
@@ -1827,7 +1836,7 @@ void bta_hf_client_send_at_bia(void)
for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
int sup = bta_hf_client_cb.scb.at_cb.indicator_lookup[i] == -1 ? 0 : 1;
at_len += snprintf(buf + at_len, BTA_HF_CLIENT_AT_MAX_LEN - at_len, "%u,", sup);
at_len += snprintf(buf + at_len, BTA_HF_CLIENT_AT_MAX_LEN - at_len, "%d,", sup);
}
buf[at_len - 1] = '\r';
@@ -2941,7 +2941,9 @@ void bta_jv_l2cap_connect_le(tBTA_JV_MSG *p_data)
if (call_init_f) {
cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &evt, cc->user_data);
}
t->init_called = TRUE;
if (t) {
t->init_called = TRUE;
}
}
@@ -696,7 +696,7 @@ on
*******************************************************************************/
int BTA_JvL2capRead(UINT32 handle, UINT32 req_id, UINT8 *p_data, UINT16 len)
{
tBTA_JV_L2CAP_READ evt_data;
tBTA_JV_L2CAP_READ evt_data = {0};
APPL_TRACE_API( "%s", __func__);
+1 -1
View File
@@ -43,7 +43,7 @@ INT16 utl_str2int(const char *p_s)
{
INT32 val = 0;
for (; *p_s == ' ' && *p_s != 0; p_s++);
for (; *p_s == ' '; p_s++);
if (*p_s == 0) {
return -1;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -115,7 +115,7 @@ static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
//uuid = {LEN_UUID_16, {ATT_CHAR_BUTTON_WIT}};
//start the button service after created
esp_ble_gatts_start_srvc(p_data->create.service_id);
//add the frist button characteristic --> write characteristic
//add the first button characteristic --> write characteristic
esp_ble_gatts_add_char(button_cb_env.clcb.cur_srvc_id, &uuid,
(GATT_PERM_WRITE | GATT_PERM_READ),
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE));
@@ -128,15 +128,15 @@ static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
tBTA_GATT_CHAR_PROP prop = (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
//save the att handle to the env
button_cb_env.button_inst.but_wirt_hdl = p_data->add_result.attr_id;
//add the frist button characteristic --> Notify characteristic
//add the first button characteristic --> Notify characteristic
esp_ble_gatts_add_char(button_cb_env.clcb.cur_srvc_id, &uuid,
GATT_PERM_READ, (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY));
} else if (p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_BUTTON_NTF) { // add the gattc config descriptor to the notify charateristic
} else if (p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_BUTTON_NTF) { // add the gattc config descriptor to the notify characteristic
//tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE);
uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
button_cb_env.button_inst.but_ntf_hdl = p_data->add_result.attr_id;
esp_ble_gatts_add_char_descr (button_cb_env.clcb.cur_srvc_id,
(GATT_PERM_WRITE | GATT_PERM_WRITE),
GATT_PERM_WRITE,
&uuid);
}
@@ -151,7 +151,7 @@ static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
//BTA_GATTS_Listen(button_cb_env.gatt_if, true, NULL);
break;
case ESP_GATTS_CONNECT_EVT:
BTC_TRACE_ERROR("############BUTTON CONNCET EVT################\n");
BTC_TRACE_ERROR("############BUTTON CONNECT EVT################\n");
//esp_ble_stop_advertising();
//set the connection flag to true
button_env_clcb_alloc(p_data->conn.conn_id, p_data->conn.remote_bda);
@@ -232,7 +232,7 @@ but_clcb_t *button_env_clcb_alloc (uint16_t conn_id, BD_ADDR remote_bda)
**
** Function button_env_find_conn_id_by_bd_adddr
**
** Description The function searches all LCB with macthing bd address
** Description The function searches all LCB with matching bd address
**
** Returns total number of clcb found.
**
@@ -280,7 +280,7 @@ BOOLEAN button_env_clcb_dealloc(uint16_t conn_id)
**
** Function button_init
**
** Description Initializa the GATT Service for button profiles.
** Description Initialize the GATT Service for button profiles.
**
*******************************************************************************/
esp_gatt_status_t button_init (but_prf_cb_t call_back)
@@ -323,7 +323,7 @@ void button_msg_notify(uint16_t len, uint8_t *button_msg)
//notify rsp==false; indicate rsp==true.
BOOLEAN rsp = false;
if (!conn_status && button_cb_env.clcb.congest) {
BTC_TRACE_ERROR("the conneciton for button profile has been loss\n");
BTC_TRACE_ERROR("the connection for button profile has been loss\n");
return;
}
@@ -1,6 +1,6 @@
#include "wx_airsync_prf.h"
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -91,7 +91,7 @@ static void airsync_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
airsync_cb_env.is_primery = p_data->create.is_primary;
//start the airsync service after created
esp_ble_gatts_start_srvc(p_data->create.service_id);
//add the frist airsync characteristic --> write characteristic
//add the first airsync characteristic --> write characteristic
esp_ble_gatts_add_char(airsync_cb_env.clcb.cur_srvc_id, &uuid,
(GATT_PERM_WRITE | GATT_PERM_READ),
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE));
@@ -112,7 +112,7 @@ static void airsync_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
airsync_cb_env.airsync_inst.airsync_ntf_hdl = p_data->add_result.attr_id;
esp_ble_gatts_add_char_descr (airsync_cb_env.clcb.cur_srvc_id,
(GATT_PERM_WRITE | GATT_PERM_WRITE),
GATT_PERM_WRITE,
&uuid);
uuid.uu.uuid16 = ATT_CHAR_AIRSYNC_READ;
@@ -207,7 +207,7 @@ tAirSync_CLCB *airsync_env_clcb_alloc (UINT16 conn_id, BD_ADDR remote_bda)
**
** Function airsync_env_find_conn_id_by_bd_adddr
**
** Description The function searches all LCB with macthing bd address
** Description The function searches all LCB with matching bd address
**
** Returns total number of clcb found.
**
@@ -231,7 +231,7 @@ UINT16 airsync_env_find_conn_id_by_bd_adddr(BD_ADDR remote_bda)
**
** Function airsync_init
**
** Description Initializa the GATT Service for airsync profiles.
** Description Initialize the GATT Service for airsync profiles.
**
*******************************************************************************/
tGATT_STATUS AirSync_Init(tAIRSYNC_CBACK *call_back)
@@ -290,14 +290,14 @@ static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_d
/* Allocate buffer to hold the pointers (deep copy). The pointers will point to the end of the tBTA_DM_SEARCH */
switch (event) {
case BTA_DM_INQ_RES_EVT: {
if (p_data->inq_res.p_eir) {
if (p_data && p_data->inq_res.p_eir) {
param_len += HCI_EXT_INQ_RESPONSE_LEN;
}
}
break;
case BTA_DM_DISC_RES_EVT: {
if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) {
if (p_data && p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) {
param_len += p_data->disc_res.raw_data_size;
}
}
@@ -305,7 +305,7 @@ static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_d
}
/* if remote name is available in EIR, set the flag so that stack doesn't trigger RNR */
if (event == BTA_DM_INQ_RES_EVT) {
if (p_data && (event == BTA_DM_INQ_RES_EVT)) {
p_data->inq_res.remt_name_not_required = check_eir_remote_name(p_data, NULL, NULL);
}
@@ -457,7 +457,7 @@ static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_S
}
/* Allocate buffer to hold the pointers (deep copy). The pointers will point to the end of the tBTA_DM_SEARCH */
if (event == BTA_DM_DISC_RES_EVT) {
if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) {
if (p_data && p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) {
param_len += p_data->disc_res.raw_data_size;
}
}
@@ -549,7 +549,7 @@ static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH
switch (event) {
case BTA_DM_DISC_RES_EVT: {
if ((p_data->disc_res.result == BTA_SUCCESS) && (p_data->disc_res.num_uuids > 0)) {
if (p_data && (p_data->disc_res.result == BTA_SUCCESS) && (p_data->disc_res.num_uuids > 0)) {
param_len += (p_data->disc_res.num_uuids * MAX_UUID_SIZE);
}
} break;
@@ -719,7 +719,7 @@ static void btc_l2cap_write(uint32_t handle)
}
l2cap_slot_t *slot = NULL;
slot = l2cap_find_slot_by_handle(handle);
if (!slot || (slot && !slot->connected)) {
if (!slot || !slot->connected) {
if (!slot) {
BTC_TRACE_ERROR("%s unable to find l2cap slot!", __func__);
} else {
@@ -749,7 +749,7 @@ static void btc_l2cap_disconnect(uint32_t handle)
}
l2cap_slot_t *slot = NULL;
slot = l2cap_find_slot_by_handle(handle);
if (!slot || (slot && !slot->connected)) {
if (!slot || !slot->connected) {
if (!slot) {
BTC_TRACE_ERROR("%s unable to find L2CAP slot! disconnect fail!", __func__);
} else {
@@ -713,7 +713,7 @@ static void btc_spp_disconnect(btc_spp_args_t *arg)
spp_slot_t *slot = NULL;
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
slot = spp_find_slot_by_handle(arg->disconnect.handle);
if (!slot || (slot && !slot->connected)) {
if (!slot || !slot->connected) {
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot! disconnect fail!", __func__);
@@ -894,7 +894,7 @@ static void btc_spp_write(btc_spp_args_t *arg)
spp_slot_t *slot = NULL;
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
slot = spp_find_slot_by_handle(arg->write.handle);
if (!slot || (slot && !slot->connected)) {
if (!slot || !slot->connected) {
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
@@ -305,7 +305,6 @@ OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
return OI_CODEC_SBC_CHECKSUM_MISMATCH;
}
#ifdef OI_DEBUG
/*
* Make sure the bitpool values are sane.
*/
@@ -317,7 +316,6 @@ OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool, OI_SBC_MaxBitpool(&context->common.frameInfo)));
return OI_STATUS_INVALID_PARAMETERS;
}
#endif
/*
* Now decode the SBC data. Partial decode is not yet implemented for an SBC
@@ -325,7 +325,7 @@ int hci_adv_credits_prep_to_release(uint16_t num)
hci_hal_env.adv_credits_to_release = credits_to_release;
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
if (credits_to_release == num && num != 0) {
if (credits_to_release == num) {
osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
osi_alarm_set(hci_hal_env.adv_flow_monitor, HCI_ADV_FLOW_MONITOR_PERIOD_MS);
}
@@ -86,6 +86,11 @@ static BT_HDR *avct_lcb_msg_asmbl(tAVCT_LCB *p_lcb, BT_HDR *p_buf)
AVCT_TRACE_WARNING("Got start during reassembly");
}
osi_free(p_lcb->p_rx_msg);
p_lcb->p_rx_msg = NULL;
if (sizeof(BT_HDR) + p_buf->offset + p_buf->len > BT_DEFAULT_BUFFER_SIZE) {
osi_free(p_buf);
return NULL;
}
/* Allocate bigger buffer for reassembly. As lower layers are
* not aware of possible packet size after reassembly they
* would have allocated smaller buffer.
@@ -1279,7 +1279,7 @@ BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf)
UINT8 *p;
UINT8 pkt_type;
BT_HDR *p_ret;
UINT16 buf_len;
size_t buf_len;
/* parse the message header */
p = (UINT8 *)(p_buf + 1) + p_buf->offset;
@@ -1314,6 +1314,10 @@ BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf)
* not aware of possible packet size after reassembly, they
* would have allocated smaller buffer.
*/
if (sizeof(BT_HDR) + p_buf->offset + p_buf->len > BT_DEFAULT_BUFFER_SIZE) {
osi_free(p_buf);
return NULL;
}
p_ccb->p_rx_msg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
memcpy(p_ccb->p_rx_msg, p_buf,
sizeof(BT_HDR) + p_buf->offset + p_buf->len);
@@ -1351,7 +1355,7 @@ BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf)
p_buf->len -= AVDT_LEN_TYPE_CONT;
/* verify length */
if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len) {
if (((size_t)p_ccb->p_rx_msg->offset + (size_t)p_buf->len) > buf_len) {
/* won't fit; free everything */
AVDT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
osi_free(p_ccb->p_rx_msg);
@@ -749,14 +749,14 @@ UINT8 avdt_scb_verify(tAVDT_CCB *p_ccb, UINT8 state, UINT8 *p_seid, UINT16 num_s
switch (state) {
case AVDT_VERIFY_OPEN:
case AVDT_VERIFY_START:
if (p_scb->state != AVDT_SCB_OPEN_ST && p_scb->state != AVDT_SCB_STREAM_ST) {
if (p_scb && p_scb->state != AVDT_SCB_OPEN_ST && p_scb->state != AVDT_SCB_STREAM_ST) {
*p_err_code = AVDT_ERR_BAD_STATE;
}
break;
case AVDT_VERIFY_SUSPEND:
case AVDT_VERIFY_STREAMING:
if (p_scb->state != AVDT_SCB_STREAM_ST) {
if (p_scb && p_scb->state != AVDT_SCB_STREAM_ST) {
*p_err_code = AVDT_ERR_BAD_STATE;
}
break;
@@ -252,10 +252,16 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
UINT16 offset;
UINT16 ex_len;
UINT8 pad_len = 0;
uint16_t len = p_data->p_pkt->len;
p = p_start = (UINT8 *)(p_data->p_pkt + 1) + p_data->p_pkt->offset;
/* parse media packet header */
offset = 12; // AVDT_MSG_PRS_OCTET1(1) + AVDT_MSG_PRS_M_PT(1) + UINT16(2) + UINT32(4) + 4
if (len < offset) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, offset);
goto length_error;
}
AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc);
AVDT_MSG_PRS_M_PT(p, m_pt, marker);
BE_STREAM_TO_UINT16(seq, p);
@@ -265,10 +271,16 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
UNUSED(o_v);
/* skip over any csrc's in packet */
offset += o_cc * 4;
p += o_cc * 4;
/* check for and skip over extension header */
if (o_x) {
offset += 4;
if (len < offset) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, offset);
goto length_error;
}
p += 2;
BE_STREAM_TO_UINT16(ex_len, p);
p += ex_len * 4;
@@ -276,18 +288,20 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
/* save our new offset */
offset = (UINT16) (p - p_start);
if (len <= offset) {
goto length_error;
}
/* adjust length for any padding at end of packet */
if (o_p) {
/* padding length in last byte of packet */
pad_len = *(p_start + p_data->p_pkt->len);
pad_len = *(p_start + len - 1);
}
/* do sanity check */
if ((offset > p_data->p_pkt->len) || ((pad_len + offset) > p_data->p_pkt->len)) {
if (pad_len >= len - offset) {
AVDT_TRACE_WARNING("Got bad media packet");
osi_free(p_data->p_pkt);
p_data->p_pkt = NULL;
goto length_error;
}
/* adjust offset and length and send it up */
else {
@@ -303,18 +317,22 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
#if AVDT_MULTIPLEXING == TRUE
if ((p_scb->cs.p_media_cback != NULL)
&& (p_scb->p_media_buf != NULL)
&& (p_scb->media_buf_len > p_data->p_pkt->len)) {
&& (p_scb->media_buf_len > len)) {
/* media buffer enough length is assigned by application. Lets use it*/
memcpy(p_scb->p_media_buf, (UINT8 *)(p_data->p_pkt + 1) + p_data->p_pkt->offset,
p_data->p_pkt->len);
len);
(*p_scb->cs.p_media_cback)(avdt_scb_to_hdl(p_scb), p_scb->p_media_buf,
p_scb->media_buf_len, time_stamp, seq, m_pt, marker);
}
#endif
osi_free(p_data->p_pkt);
p_data->p_pkt = NULL;
goto length_error;
}
}
return;
length_error:
osi_free(p_data->p_pkt);
p_data->p_pkt = NULL;
}
#if AVDT_REPORTING == TRUE
@@ -333,13 +351,18 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
UINT8 *p_start = p;
UINT32 ssrc;
UINT8 o_v, o_p, o_cc;
UINT32 min_len = 0;
AVDT_REPORT_TYPE pt;
tAVDT_REPORT_DATA report, *p_rpt;
tAVDT_REPORT_DATA report;
AVDT_TRACE_DEBUG( "avdt_scb_hdl_report");
if (p_scb->cs.p_report_cback) {
p_rpt = &report;
/* parse report packet header */
min_len += 8;
if (len < min_len) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
goto avdt_scb_hdl_report_exit;
}
AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc);
pt = *p++;
p += 2;
@@ -352,6 +375,11 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
switch (pt) {
case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */
min_len += 20;
if (len < min_len) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
goto avdt_scb_hdl_report_exit;
}
BE_STREAM_TO_UINT32(report.sr.ntp_sec, p);
BE_STREAM_TO_UINT32(report.sr.ntp_frac, p);
BE_STREAM_TO_UINT32(report.sr.rtp_time, p);
@@ -360,6 +388,11 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
break;
case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */
min_len += 20;
if (len < min_len) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
goto avdt_scb_hdl_report_exit;
}
report.rr.frag_lost = *p;
BE_STREAM_TO_UINT32(report.rr.packet_lost, p);
report.rr.packet_lost &= 0xFFFFFF;
@@ -370,11 +403,32 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
break;
case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */
if (*p == AVDT_RTCP_SDES_CNAME) {
p_rpt = (tAVDT_REPORT_DATA *)(p + 2);
min_len += 1;
if (len < min_len) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
goto avdt_scb_hdl_report_exit;
}
uint8_t sdes_type;
BE_STREAM_TO_UINT8(sdes_type, p);
if (sdes_type == AVDT_RTCP_SDES_CNAME) {
min_len += 1;
if (len < min_len) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
goto avdt_scb_hdl_report_exit;
}
uint8_t name_length;
BE_STREAM_TO_UINT8(name_length, p);\
if ((name_length > len - min_len) || (name_length > AVDT_MAX_CNAME_SIZE)) {
result = AVDT_BAD_PARAMS;
} else {
BE_STREAM_TO_ARRAY(p, &(report.cname[0]), name_length);
}
} else {
AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d %s\n",
ssrc, o_cc, *p, *(p + 1), p + 2);
if (len < min_len + 1) {
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
goto avdt_scb_hdl_report_exit;
}
AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d\n", ssrc, o_cc, sdes_type, *p);
result = AVDT_BUSY;
}
break;
@@ -385,10 +439,12 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
}
if (result == AVDT_SUCCESS) {
(*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, p_rpt);
(*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, &report);
}
}
avdt_scb_hdl_report_exit:
p_start += len;
return p_start;
}
@@ -624,7 +680,7 @@ void avdt_scb_hdl_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
#endif
#if AVDT_MULTIPLEXING == TRUE
/* select right function in dependance of is fragmentation supported or not */
/* select right function in dependence of is fragmentation supported or not */
if ( 0 != (p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX)) {
avdt_scb_hdl_pkt_frag(p_scb, p_data);
} else
@@ -200,7 +200,7 @@ static void avrc_send_continue_frag(UINT8 handle, UINT8 label)
if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
p_pkt_old = p_fcb->p_fmsg;
p_pkt = (BT_HDR *)osi_malloc((UINT16)(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE));
p_pkt = (BT_HDR *)osi_calloc((UINT16)(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE));
if (p_pkt) {
p_pkt->len = AVRC_MAX_CTRL_DATA_LEN;
p_pkt->offset = AVCT_MSG_OFFSET;
@@ -526,7 +526,7 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
tAVRC_MSG_VENDOR *p_msg = &msg.vendor;
if (cr == AVCT_CMD &&
(p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < sizeof(p_pkt->len))) {
(p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < p_pkt->len)) {
/* Ignore the invalid AV/C command frame */
#if (BT_USE_TRACES == TRUE)
p_drop_msg = "dropped - too long AV/C cmd frame size";
@@ -55,13 +55,27 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
if (p_msg->p_vendor_data == NULL) {
return AVRC_STS_INTERNAL_ERR;
}
if (p_msg->vendor_len < 4) {
AVRC_TRACE_WARNING("message length %u too short: must be at least 4", p_msg->vendor_len);
return AVRC_STS_INTERNAL_ERR;
}
p = p_msg->p_vendor_data;
BE_STREAM_TO_UINT8 (p_result->pdu, p);
p++; /* skip the reserved/packe_type byte */
BE_STREAM_TO_UINT16 (len, p);
AVRC_TRACE_DEBUG("avrc_pars_vendor_rsp() ctype:0x%x pdu:0x%x, len:%d/0x%x", p_msg->hdr.ctype, p_result->pdu, len, len);
if (p_msg->vendor_len < len + 4) {
AVRC_TRACE_WARNING("message length %u too short: must be at least %u", p_msg->vendor_len, len + 4);
return AVRC_STS_INTERNAL_ERR;
}
if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
if (len < 1) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least 1", len);
return AVRC_STS_INTERNAL_ERR;
}
p_result->rsp.status = *p;
return p_result->rsp.status;
}
@@ -82,10 +96,18 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
if (len < 1) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least 1", len);
return AVRC_STS_INTERNAL_ERR;
}
BE_STREAM_TO_UINT8 (eventid, p);
if (AVRC_EVT_VOLUME_CHANGE == eventid
&& (AVRC_RSP_CHANGED == p_msg->hdr.ctype || AVRC_RSP_INTERIM == p_msg->hdr.ctype
|| AVRC_RSP_REJ == p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) {
if (len < 2) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least 2", len);
return AVRC_STS_INTERNAL_ERR;
}
p_result->reg_notif.status = p_msg->hdr.ctype;
p_result->reg_notif.event_id = eventid;
BE_STREAM_TO_UINT8 (p_result->reg_notif.param.volume, p);
@@ -95,18 +117,30 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
break;
#endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
case AVRC_PDU_GET_CAPABILITIES: /* 0x10 */
if (len < 2) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least 2", len);
return AVRC_STS_INTERNAL_ERR;
}
BE_STREAM_TO_UINT8 (p_result->get_caps.capability_id, p);
BE_STREAM_TO_UINT8 (p_result->get_caps.count, p);
if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED) {
if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_EVT_ID) {
status = AVRC_STS_INTERNAL_ERR;
} else {
if (len < 2 + p_result->get_caps.count) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least %d", len, 2 + p_result->get_caps.count);
return AVRC_STS_INTERNAL_ERR;
}
BE_STREAM_TO_ARRAY(p, p_result->get_caps.param.event_id, p_result->get_caps.count);
}
} else if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) {
if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_COMP_ID) {
status = AVRC_STS_INTERNAL_ERR;
} else {
if (len < 2 + p_result->get_caps.count * 6) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least %d", len, 2 + p_result->get_caps.count * 6);
return AVRC_STS_INTERNAL_ERR;
}
for (int i = 0; i < p_result->get_caps.count; ++i) {
BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[i], p);
}
@@ -242,7 +242,11 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
status = AVRC_STS_INTERNAL_ERR;
} else {
BE_STREAM_TO_UINT8 (p_result->reg_notif.event_id, p);
BE_STREAM_TO_UINT32 (p_result->reg_notif.param, p);
if (AVRC_IS_VALID_EVENT_ID(p_result->reg_notif.event_id)) {
BE_STREAM_TO_UINT32 (p_result->reg_notif.param, p);
} else {
status = AVRC_STS_BAD_PARAM;
}
}
break;
@@ -792,6 +792,11 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
if (p == NULL) {
return;
}
/* if we are trying to drop encryption on an encrypted connection, drop the connection */
if (!encr_enable && (p->encrypt_state == BTM_ACL_ENCRYPT_STATE_ENCRYPT_ON)) {
btm_sec_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
return;
}
/* Process Role Switch if active */
if (p->switch_role_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF) {
/* if encryption turn off failed we still will try to switch role */
@@ -2247,7 +2252,7 @@ void BTM_BleGetPeriodicAdvListSize(uint8_t *size)
** Returns void
**
*******************************************************************************/
void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble)
void btm_read_tx_power_complete (UINT8 *p, UINT16 evt_len, BOOLEAN is_ble)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_tx_power_cmpl_cb;
tBTM_TX_POWER_RESULTS results;
@@ -2260,12 +2265,23 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble)
btm_cb.devcb.p_tx_power_cmpl_cb = NULL;
if (p_cb) {
if (evt_len < 1) {
BTM_TRACE_ERROR("Bogus event packet, too short\n");
results.status = BTM_ERR_PROCESSING;
goto err_out;
}
STREAM_TO_UINT8 (results.hci_status, p);
if (results.hci_status == HCI_SUCCESS) {
results.status = BTM_SUCCESS;
if (!is_ble) {
if (evt_len < 1 + 3) {
BTM_TRACE_ERROR("Bogus event packet, too short\n");
results.status = BTM_ERR_PROCESSING;
goto err_out;
}
STREAM_TO_UINT16 (handle, p);
STREAM_TO_UINT8 (results.tx_power, p);
@@ -2277,6 +2293,11 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble)
}
#if BLE_INCLUDED == TRUE
else {
if (evt_len < 1 + 1) {
BTM_TRACE_ERROR("Bogus event packet, too short\n");
results.status = BTM_ERR_PROCESSING;
goto err_out;
}
STREAM_TO_UINT8 (results.tx_power, p);
memcpy(results.rem_bda, btm_cb.devcb.read_tx_pwr_addr, BD_ADDR_LEN);
}
@@ -2287,6 +2308,7 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble)
results.status = BTM_ERR_PROCESSING;
}
err_out:
(*p_cb)(&results);
}
}
@@ -2301,7 +2323,7 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble)
** Returns void
**
*******************************************************************************/
void btm_read_rssi_complete (UINT8 *p)
void btm_read_rssi_complete (UINT8 *p, UINT16 evt_len)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_rssi_cmpl_cb;
tBTM_RSSI_RESULTS results;
@@ -2314,11 +2336,21 @@ void btm_read_rssi_complete (UINT8 *p)
btm_cb.devcb.p_rssi_cmpl_cb = NULL;
if (p_cb) {
if (evt_len < 1) {
BTM_TRACE_ERROR("Bogus event packet, too short");
results.status = BTM_ERR_PROCESSING;
goto err_out;
}
STREAM_TO_UINT8 (results.hci_status, p);
if (results.hci_status == HCI_SUCCESS) {
results.status = BTM_SUCCESS;
if (evt_len < 1 + 3) {
BTM_TRACE_ERROR("Bogus event packet, too short");
results.status = BTM_ERR_PROCESSING;
goto err_out;
}
STREAM_TO_UINT16 (handle, p);
STREAM_TO_UINT8 (results.rssi, p);
@@ -2334,6 +2366,7 @@ void btm_read_rssi_complete (UINT8 *p)
results.status = BTM_ERR_PROCESSING;
}
err_out:
(*p_cb)(&results);
}
}
@@ -2384,7 +2384,7 @@ BOOLEAN BTM_BleVerifySignature (BD_ADDR bd_addr, UINT8 *p_orig, UINT16 len, UINT
tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bd_addr);
UINT8 p_mac[BTM_CMAC_TLEN_SIZE];
if (p_rec == NULL || (p_rec && !(p_rec->ble.key_type & BTM_LE_KEY_PCSRK))) {
if (p_rec == NULL || !(p_rec->ble.key_type & BTM_LE_KEY_PCSRK)) {
BTM_TRACE_ERROR("can not verify signature for unknown device");
} else if (counter < p_rec->ble.keys.counter) {
BTM_TRACE_ERROR("signature received with out dated sign counter");
@@ -428,8 +428,7 @@ BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filte
for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) {
if ((p_addr_filter->in_use) && (NULL == p_bd_addr ||
(NULL != p_bd_addr &&
memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) {
(memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) {
found = TRUE;
memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT));
@@ -914,7 +913,7 @@ tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action,
if (NULL == p_bda_filter ||
/* not a generic filter */
(p_target != NULL && p_bda_filter)) {
(p_target != NULL)) {
BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!");
return st;
}
@@ -3757,7 +3757,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
3. For same address and scan response, do nothing
*/
int same_addr = memcmp(bda, p_le_inq_cb->adv_addr, BD_ADDR_LEN);
if (same_addr != 0 || (same_addr == 0 && evt_type != BTM_BLE_SCAN_RSP_EVT)) {
if (same_addr != 0 || (evt_type != BTM_BLE_SCAN_RSP_EVT)) {
btm_ble_process_last_adv_pkt();
}
@@ -3808,8 +3808,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
/* new device */
if (p_i == NULL ||
/* assume a DUMO device, BR/EDR inquiry is always active */
(p_i &&
(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE &&
((p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE &&
p_i->scan_rsp)) {
BTM_TRACE_WARNING("INQ RES: Extra Response Received...cancelling inquiry..");
@@ -227,6 +227,7 @@ void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
{
UINT8 status = 0;
STREAM_TO_UINT8(status, p);
BTM_TRACE_DEBUG("%s status=%d", __func__, status);
@@ -1006,7 +1006,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb)
** Returns void
**
*******************************************************************************/
void btm_delete_stored_link_key_complete (UINT8 *p)
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;
@@ -1018,10 +1018,16 @@ void btm_delete_stored_link_key_complete (UINT8 *p)
/* Set the call back event to indicate command complete */
result.event = BTM_CB_EVT_DELETE_STORED_LINK_KEYS;
if (evt_len < 3) {
BTM_TRACE_ERROR("Malformatted event packet, too short");
result.status = BTM_ERR_PROCESSING;
goto err_out;
}
/* Extract the result fields from the HCI event */
STREAM_TO_UINT8 (result.status, p);
STREAM_TO_UINT16 (result.num_keys, p);
err_out:
/* Call the call back and pass the result */
(*p_cb)(&result);
}
@@ -1860,7 +1860,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
/* new device response */
&& ( p_i == NULL ||
/* existing device with BR/EDR info */
(p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)
((p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)
)
#endif
@@ -866,9 +866,7 @@ void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len)
/* notify registered parties */
for (xx = 0; xx < BTM_MAX_PM_RECORDS; xx++) {
if (btm_cb.pm_reg_db[xx].mask & BTM_PM_REG_NOTIF) {
if ( p_acl) {
(*btm_cb.pm_reg_db[xx].cback)( p_acl->remote_addr, BTM_PM_STS_SSR, use_ssr, status);
}
(*btm_cb.pm_reg_db[xx].cback)( p_acl->remote_addr, BTM_PM_STS_SSR, use_ssr, status);
}
}
}
@@ -2748,11 +2748,16 @@ static void btm_sec_bond_cancel_complete (void)
** Returns void
**
*******************************************************************************/
void btm_create_conn_cancel_complete (UINT8 *p)
void btm_create_conn_cancel_complete (UINT8 *p, UINT16 evt_len)
{
UINT8 status;
STREAM_TO_UINT8 (status, p);
if (evt_len >= 1) {
STREAM_TO_UINT8 (status, p);
} else {
BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__);
status = BTM_ERR_PROCESSING;
}
//BTM_TRACE_EVENT ("btm_create_conn_cancel_complete(): in State: %s status:%d\n",
// btm_pair_state_descr(btm_cb.pairing_state), status);
@@ -3795,13 +3800,27 @@ void btm_rem_oob_req (UINT8 *p)
** Returns void
**
*******************************************************************************/
void btm_read_local_oob_complete (UINT8 *p)
void btm_read_local_oob_complete (UINT8 *p, UINT16 evt_len)
{
tBTM_SP_LOC_OOB evt_data;
UINT8 status = *p++;
UINT8 status;
if (evt_len < 1) {
BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__);
evt_data.status = BTM_ERR_PROCESSING;
goto err_out;
}
STREAM_TO_UINT8(status, p);
BTM_TRACE_EVENT ("btm_read_local_oob_complete:%d\n", status);
if (status == HCI_SUCCESS) {
if (evt_len < 1 + 32) {
BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__);
evt_data.status = BTM_ERR_PROCESSING;
goto err_out;
}
evt_data.status = BTM_SUCCESS;
STREAM_TO_ARRAY16(evt_data.c, p);
STREAM_TO_ARRAY16(evt_data.r, p);
@@ -3809,6 +3828,7 @@ void btm_read_local_oob_complete (UINT8 *p)
evt_data.status = BTM_ERR_PROCESSING;
}
err_out:
if (btm_cb.api.p_sp_callback) {
(*btm_cb.api.p_sp_callback) (BTM_SP_LOC_OOB_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
}
@@ -4267,7 +4287,6 @@ static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle)
#if (SMP_INCLUDED == TRUE)
void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
{
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
UINT8 res;
UINT8 sec_dev_rec_status;
BOOLEAN is_pairing_device = FALSE;
@@ -4276,6 +4295,8 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
btm_acl_resubmit_page();
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
/* Commenting out trace due to obf/compilation problems.
*/
#if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE)
@@ -4598,7 +4619,6 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason)
*******************************************************************************/
void btm_sec_disconnected (UINT16 handle, UINT8 reason)
{
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
UINT8 old_pairing_flags = btm_cb.pairing_flags;
int result = HCI_ERR_AUTH_FAILURE;
tBTM_SEC_CALLBACK *p_callback = NULL;
@@ -4611,6 +4631,8 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
btm_acl_resubmit_page();
#endif
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
if (!p_dev_rec) {
return;
}
@@ -5032,6 +5054,12 @@ void btm_sec_pin_code_request (UINT8 *p_bda)
btm_pair_state_descr(btm_cb.pairing_state),
(p_bda[0] << 8) + p_bda[1], (p_bda[2] << 24) + (p_bda[3] << 16) + (p_bda[4] << 8) + p_bda[5] );
#endif ///BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE
const bt_bdaddr_t *local_bd_addr = controller_get_interface()->get_address();
if (!memcmp(p_bda, local_bd_addr, BD_ADDR_LEN)) {
BTM_TRACE_WARNING("btm_sec_pin_code_request() rejected device with same address\n");
btsnd_hcic_pin_code_neg_reply(p_bda);
return;
}
if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) {
if ( (memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) == 0) &&
(btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_AUTH_COMPLETE) ) {
@@ -1051,8 +1051,8 @@ void btm_cont_rswitch (tACL_CONN *p,
tACL_CONN *btm_handle_to_acl (UINT16 hci_handle);
void btm_read_link_policy_complete (UINT8 *p);
void btm_read_rssi_complete (UINT8 *p);
void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble);
void btm_read_rssi_complete (UINT8 *p, UINT16 evt_len);
void btm_read_tx_power_complete (UINT8 *p, UINT16 evt_len, BOOLEAN is_ble);
void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types);
void btm_read_link_quality_complete (UINT8 *p);
tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types);
@@ -1147,7 +1147,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 cc_opcode, UINT16 evt_len,
void btm_inq_db_reset (void);
void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len);
#if (CLASSIC_BT_INCLUDED == TRUE)
void btm_delete_stored_link_key_complete (UINT8 *p);
void btm_delete_stored_link_key_complete (UINT8 *p, UINT16 evt_len);
#endif // (CLASSIC_BT_INCLUDED == TRUE)
void btm_report_device_status (tBTM_DEV_STATUS status);
void btm_set_afh_channels_complete (UINT8 *p);
@@ -1180,7 +1180,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_
UINT32 mx_proto_id, UINT32 mx_chan_id,
tBTM_SEC_CALLBACK *p_callback, void *p_ref_data);
void btm_sec_conn_req (UINT8 *bda, UINT8 *dc);
void btm_create_conn_cancel_complete (UINT8 *p);
void btm_create_conn_cancel_complete (UINT8 *p, UINT16 evt_len);
void btm_read_linq_tx_power_complete (UINT8 *p);
void btm_sec_init (UINT8 sec_mode);
@@ -1222,10 +1222,10 @@ tINQ_DB_ENT *btm_inq_db_new (BD_ADDR p_bda);
#if BTM_OOB_INCLUDED == TRUE
void btm_rem_oob_req (UINT8 *p);
void btm_read_local_oob_complete (UINT8 *p);
void btm_read_local_oob_complete (UINT8 *p, UINT16 evt_len);
#else
#define btm_rem_oob_req(p)
#define btm_read_local_oob_complete(p)
#define btm_read_local_oob_complete(p, evt_len)
#endif
void btm_acl_resubmit_page (void);
@@ -964,7 +964,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
break;
#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_DELETE_STORED_LINK_KEY:
btm_delete_stored_link_key_complete (p);
btm_delete_stored_link_key_complete (p, evt_len);
break;
#endif // (CLASSIC_BT_INCLUDED == TRUE)
@@ -977,20 +977,20 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
break;
case HCI_READ_RSSI:
btm_read_rssi_complete (p);
btm_read_rssi_complete (p, evt_len);
break;
case HCI_READ_TRANSMIT_POWER_LEVEL:
btm_read_tx_power_complete(p, FALSE);
btm_read_tx_power_complete(p, evt_len, FALSE);
break;
case HCI_CREATE_CONNECTION_CANCEL:
btm_create_conn_cancel_complete(p);
btm_create_conn_cancel_complete(p, evt_len);
break;
case HCI_READ_LOCAL_OOB_DATA:
#if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
btm_read_local_oob_complete(p);
btm_read_local_oob_complete(p, evt_len);
#endif
break;
@@ -1049,7 +1049,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
break;
case HCI_BLE_READ_ADV_CHNL_TX_POWER:
btm_read_tx_power_complete(p, TRUE);
btm_read_tx_power_complete(p, evt_len, TRUE);
break;
case HCI_BLE_WRITE_ADV_ENABLE:
@@ -200,7 +200,8 @@ BT_HDR *attp_build_read_by_type_value_cmd (UINT16 payload_size, tGATT_FIND_TYPE_
BT_HDR *attp_build_read_multi_cmd(UINT8 op_code, UINT16 payload_size, UINT16 num_handle, UINT16 *p_handle)
{
BT_HDR *p_buf = NULL;
UINT8 *p, i = 0;
UINT8 *p;
UINT16 i = 0;
if ((p_buf = (BT_HDR *)osi_malloc((UINT16)(sizeof(BT_HDR) + num_handle * 2 + 1 + L2CAP_MIN_OFFSET))) != NULL) {
p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -695,7 +695,7 @@ static void l2c_csm_config (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
l2cu_process_peer_cfg_rsp (p_ccb, p_cfg);
if (p_cfg->result != L2CAP_CFG_PENDING) {
/* TBD: When config options grow beyong minimum MTU (48 bytes)
/* TBD: When config options grow beyond minimum MTU (48 bytes)
* logic needs to be added to handle responses with
* continuation bit set in flags field.
* 1. Send additional config request out until C-bit is cleared in response
@@ -885,7 +885,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
tL2CAP_CFG_INFO *p_cfg;
tL2C_CHNL_STATE tempstate;
UINT8 tempcfgdone;
UINT8 cfg_result;
UINT8 cfg_result = L2CAP_PEER_CFG_DISCONNECT;
#if (BT_TRACE_VERBOSE == TRUE)
L2CAP_TRACE_EVENT ("L2CAP - LCID: 0x%04x st: OPEN evt: %s",
@@ -916,7 +916,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
case L2CEVT_LP_QOS_VIOLATION_IND: /* QOS violation */
/* Tell upper layer. If service guaranteed, then clear the channel */
if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) {
if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) {
(*p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb)(p_ccb->p_lcb->remote_bd_addr);
}
break;
@@ -931,7 +931,11 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT);
if ((cfg_result = l2cu_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_OK) {
if (p_cfg) {
cfg_result = l2cu_process_peer_cfg_req (p_ccb, p_cfg);
}
if (cfg_result == L2CAP_PEER_CFG_OK) {
(*p_ccb->p_rcb->api.pL2CA_ConfigInd_Cb)(p_ccb->local_cid, p_cfg);
}
@@ -968,7 +972,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
break;
case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
if ((p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_DataInd_Cb)) {
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);
}
break;
@@ -988,16 +992,20 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
break;
case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_data);
l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL);
if (p_data) {
l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_data);
l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL);
}
break;
case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req */
p_ccb->chnl_state = CST_CONFIG;
p_ccb->config_done &= ~CFG_DONE_MASK;
l2cu_process_our_cfg_req (p_ccb, (tL2CAP_CFG_INFO *)p_data);
l2cu_send_peer_config_req (p_ccb, (tL2CAP_CFG_INFO *)p_data);
btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT);
if (p_data) {
p_ccb->chnl_state = CST_CONFIG;
p_ccb->config_done &= ~CFG_DONE_MASK;
l2cu_process_our_cfg_req (p_ccb, (tL2CAP_CFG_INFO *)p_data);
l2cu_send_peer_config_req (p_ccb, (tL2CAP_CFG_INFO *)p_data);
btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT);
}
break;
case L2CEVT_TIMEOUT:
@@ -181,7 +181,7 @@ int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
/* If the MTU is not specified (0), keep MTU decision until the
* PN frame has to be send
* at that time connection should be established and we
* will know for sure our prefered MTU
* will know for sure our preferred MTU
*/
rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
@@ -298,12 +298,12 @@ int RFCOMM_RemoveServer (UINT16 handle)
**
** Description This function is called to provide an address of the
** function which will be called when one of the events
** specified in the mask occures.
** specified in the mask occurs.
**
** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
** p_callback - address of the callback function which should
** be called from the RFCOMM when an event
** specified in the mask occures.
** specified in the mask occurs.
**
**
*******************************************************************************/
@@ -537,8 +537,7 @@ BOOLEAN PORT_IsOpening (BD_ADDR bd_addr)
}
}
if ((!found_port) ||
(found_port && (p_port->rfc.state < RFC_STATE_OPENED))) {
if ((!found_port) || (p_port->rfc.state < RFC_STATE_OPENED)) {
/* Port is not established yet. */
memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
return TRUE;
@@ -641,7 +640,7 @@ int PORT_GetRxQueueCnt (UINT16 handle, UINT16 *p_rx_queue_count)
** Function PORT_GetState
**
** Description This function is called to fill tPORT_STATE structure
** with the curremt control settings for the port
** with the current control settings for the port
**
** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
** p_settings - Pointer to a tPORT_STATE structure in which
@@ -1009,15 +1008,15 @@ int PORT_GetModemStatus (UINT16 handle, UINT8 *p_signal)
**
** Function PORT_ClearError
**
** Description This function retreives information about a communications
** Description This function retrieves information about a communications
** error and reports current status of a connection. The
** function should be called when an error occures to clear
** function should be called when an error occurs to clear
** the connection error flag and to enable additional read
** and write operations.
**
** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
** p_errors - pointer of the variable to receive error codes
** p_status - pointer to the tPORT_STATUS structur to receive
** p_status - pointer to the tPORT_STATUS structure to receive
** connection status
**
*******************************************************************************/
@@ -1090,7 +1089,7 @@ int PORT_SendError (UINT16 handle, UINT8 errors)
** Description This function reports current status of a connection.
**
** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
** p_status - pointer to the tPORT_STATUS structur to receive
** p_status - pointer to the tPORT_STATUS structure to receive
** connection status
**
*******************************************************************************/
@@ -1700,7 +1699,7 @@ int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
rc = port_write (p_port, p_buf);
/* If queue went below the threashold need to send flow control */
/* If queue went below the threshold need to send flow control */
event |= port_flow_control_user (p_port);
if (rc == PORT_SUCCESS) {
@@ -415,6 +415,10 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 attr_type,
tSDP_RECORD *p_rec = NULL;
list_node_t *p_node= NULL;
if (!p_val) {
return FALSE;
}
#if (BT_TRACE_VERBOSE == TRUE)
if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) {
if ((attr_type == UINT_DESC_TYPE) ||
@@ -448,6 +452,12 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 attr_type,
if (p_rec->record_handle == handle) {
tSDP_ATTRIBUTE *p_attr = &p_rec->attribute[0];
// error out early, no need to look up
if (p_rec->free_pad_ptr >= SDP_MAX_PAD_LEN) {
SDP_TRACE_ERROR("the free pad for SDP record with handle %d is full, skip adding the attribute", handle);
return (FALSE);
}
/* Found the record. Now, see if the attribute already exists */
for (xx = 0; xx < p_rec->num_attributes; xx++, p_attr++) {
/* The attribute exists. replace it */
@@ -45,9 +45,9 @@
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
#if SDP_CLIENT_ENABLED == TRUE
static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply);
static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply);
static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply);
static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end);
static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end);
static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end);
static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end);
static tSDP_DISC_REC *add_record (tSDP_DISCOVERY_DB *p_db, BD_ADDR p_bda);
static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, tSDP_DISC_REC *p_rec,
@@ -189,7 +189,7 @@ void sdp_disc_connected (tCONN_CB *p_ccb)
if (p_ccb->is_attr_search) {
p_ccb->disc_state = SDP_DISC_WAIT_SEARCH_ATTR;
process_service_search_attr_rsp (p_ccb, NULL);
process_service_search_attr_rsp (p_ccb, NULL, NULL);
} else {
/* First step is to get a list of the handles from the server. */
/* We are not searching for a specific attribute, so we will */
@@ -213,7 +213,7 @@ void sdp_disc_connected (tCONN_CB *p_ccb)
*******************************************************************************/
void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg)
{
UINT8 *p, rsp_pdu;
UINT8 *p, *p_end, rsp_pdu;
BOOLEAN invalid_pdu = TRUE;
#if (SDP_DEBUG_RAW == TRUE)
@@ -225,7 +225,12 @@ void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg)
/* Got a reply!! Check what we got back */
p = (UINT8 *)(p_msg + 1) + p_msg->offset;
p_end = p + p_msg->len;
if (p_msg->len < 1) {
sdp_disconnect(p_ccb, SDP_GENERIC_ERROR);
return;
}
BE_STREAM_TO_UINT8 (rsp_pdu, p);
p_msg->len--;
@@ -233,21 +238,21 @@ void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg)
switch (rsp_pdu) {
case SDP_PDU_SERVICE_SEARCH_RSP:
if (p_ccb->disc_state == SDP_DISC_WAIT_HANDLES) {
process_service_search_rsp (p_ccb, p);
process_service_search_rsp (p_ccb, p, p_end);
invalid_pdu = FALSE;
}
break;
case SDP_PDU_SERVICE_ATTR_RSP:
if (p_ccb->disc_state == SDP_DISC_WAIT_ATTR) {
process_service_attr_rsp (p_ccb, p);
process_service_attr_rsp (p_ccb, p, p_end);
invalid_pdu = FALSE;
}
break;
case SDP_PDU_SERVICE_SEARCH_ATTR_RSP:
if (p_ccb->disc_state == SDP_DISC_WAIT_SEARCH_ATTR) {
process_service_search_attr_rsp (p_ccb, p);
process_service_search_attr_rsp (p_ccb, p, p_end);
invalid_pdu = FALSE;
}
break;
@@ -269,12 +274,17 @@ void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg)
** Returns void
**
*******************************************************************************/
static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end)
{
UINT16 xx;
UINT16 total, cur_handles, orig;
UINT8 cont_len;
if (p_reply + 8 > p_reply_end) {
sdp_disconnect (p_ccb, SDP_GENERIC_ERROR);
return;
}
/* Skip transaction, and param len */
p_reply += 4;
BE_STREAM_TO_UINT16 (total, p_reply);
@@ -282,7 +292,7 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
orig = p_ccb->num_handles;
p_ccb->num_handles += cur_handles;
if (p_ccb->num_handles == 0) {
if ((p_ccb->num_handles == 0) || (p_ccb->num_handles < orig)) {
SDP_TRACE_WARNING ("SDP - Rcvd ServiceSearchRsp, no matches\n");
sdp_disconnect (p_ccb, SDP_NO_RECS_MATCH);
return;
@@ -296,6 +306,11 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
p_ccb->num_handles = sdp_cb.max_recs_per_search;
}
if (p_reply + ((p_ccb->num_handles - orig) * 4) + 1 > p_reply_end) {
sdp_disconnect(p_ccb, SDP_GENERIC_ERROR);
return;
}
for (xx = orig; xx < p_ccb->num_handles; xx++) {
BE_STREAM_TO_UINT32 (p_ccb->handles[xx], p_reply);
}
@@ -306,6 +321,10 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
sdp_disconnect (p_ccb, SDP_INVALID_CONT_STATE);
return;
}
if (p_reply + cont_len > p_reply_end) {
sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
return;
}
/* stay in the same state */
sdp_snd_service_search_req(p_ccb, cont_len, p_reply);
} else {
@@ -313,7 +332,7 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
p_ccb->disc_state = SDP_DISC_WAIT_ATTR;
/* Kick off the first attribute request */
process_service_attr_rsp (p_ccb, NULL);
process_service_attr_rsp (p_ccb, NULL, NULL);
}
}
@@ -392,7 +411,7 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset)
** Returns void
**
*******************************************************************************/
static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end)
{
UINT8 *p_start, *p_param_len;
UINT16 param_len, list_byte_count;
@@ -411,6 +430,11 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
/* Skip transaction ID and length */
p_reply += 4;
if (p_reply + 2 > p_reply_end) {
sdp_disconnect (p_ccb, SDP_INVALID_PDU_SIZE);
return;
}
BE_STREAM_TO_UINT16 (list_byte_count, p_reply);
#if (SDP_DEBUG_RAW == TRUE)
SDP_TRACE_WARNING("list_byte_count:%d\n", list_byte_count);
@@ -426,6 +450,12 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d\n",
p_ccb->list_len, list_byte_count);
#endif
if (p_reply + list_byte_count + 1 /* continuation */ > p_reply_end) {
sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
return;
}
if (p_ccb->rsp_list == NULL) {
p_ccb->rsp_list = (UINT8 *)osi_malloc (SDP_MAX_LIST_BYTE_COUNT);
if (p_ccb->rsp_list == NULL) {
@@ -502,8 +532,10 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
/* Was this a continuation request ? */
if (cont_request_needed) {
memcpy (p, p_reply, *p_reply + 1);
p += *p_reply + 1;
if (p_reply + *p_reply + 1 <= p_reply_end) {
memcpy (p, p_reply, *p_reply + 1);
p += *p_reply + 1;
}
} else {
UINT8_TO_BE_STREAM (p, 0);
}
@@ -537,7 +569,7 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
** Returns void
**
*******************************************************************************/
static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end)
{
UINT8 *p, *p_start, *p_end, *p_param_len;
UINT8 type;
@@ -557,6 +589,11 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
/* Skip transaction ID and length */
p_reply += 4;
if (p_reply + 2 > p_reply_end) {
sdp_disconnect (p_ccb, SDP_INVALID_PDU_SIZE);
return;
}
BE_STREAM_TO_UINT16 (lists_byte_count, p_reply);
#if (SDP_DEBUG_RAW == TRUE)
SDP_TRACE_WARNING("lists_byte_count:%d\n", lists_byte_count);
@@ -572,6 +609,12 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d\n",
p_ccb->list_len, lists_byte_count);
#endif
if (p_reply + lists_byte_count + 1 /* continuation */ > p_reply_end) {
sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
return;
}
if (p_ccb->rsp_list == NULL) {
p_ccb->rsp_list = (UINT8 *)osi_malloc (SDP_MAX_LIST_BYTE_COUNT);
if (p_ccb->rsp_list == NULL) {
@@ -643,8 +686,10 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply)
/* No continuation for first request */
if (p_reply) {
memcpy (p, p_reply, *p_reply + 1);
p += *p_reply + 1;
if (p_reply + *p_reply + 1 <= p_reply_end) {
memcpy (p, p_reply, *p_reply + 1);
p += *p_reply + 1;
}
} else {
UINT8_TO_BE_STREAM (p, 0);
}
@@ -179,7 +179,6 @@ static void process_service_search (tCONN_CB *p_ccb, UINT16 trans_num,
tSDP_RECORD *p_rec = NULL;
BT_HDR *p_buf;
BOOLEAN is_cont = FALSE;
UNUSED(p_req_end);
p_req = sdpu_extract_uid_seq (p_req, param_len, &uid_seq);
@@ -214,6 +213,10 @@ static void process_service_search (tCONN_CB *p_ccb, UINT16 trans_num,
}
/* Check if this is a continuation request */
if (p_req + 1 > p_req_end) {
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
return;
}
if (*p_req) {
if (*p_req++ != SDP_CONTINUATION_LEN || (p_req >= p_req_end)) {
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE,
@@ -351,6 +354,10 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
}
/* Check if this is a continuation request */
if (p_req + 1 > p_req_end) {
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
return;
}
if (*p_req) {
/* Free and reallocate buffer */
if (p_ccb->rsp_list) {
@@ -565,7 +572,7 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
/* Extract the UUID sequence to search for */
p_req = sdpu_extract_uid_seq (p_req, param_len, &uid_seq);
if ((!p_req) || (!uid_seq.num_uids)) {
if ((!p_req) || (!uid_seq.num_uids) || (p_req + 2 > p_req_end)) {
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX, SDP_TEXT_BAD_UUID_LIST);
return;
}
@@ -586,7 +593,16 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ)) ;
if (max_list_len < 4) {
sdpu_build_n_send_error (p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
return;
}
/* Check if this is a continuation request */
if (p_req + 1 > p_req_end) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
return;
}
if (*p_req) {
/* Free and reallocate buffer */
if (p_ccb->rsp_list) {
@@ -600,7 +616,7 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
return;
}
if (*p_req++ != SDP_CONTINUATION_LEN) {
if ((*p_req++ != SDP_CONTINUATION_LEN) || (p_req + 2 > p_req_end)) {
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
return;
}
@@ -865,7 +865,7 @@ void smp_br_process_pairing_command(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
SMP_TRACE_DEBUG("%s", __func__);
/* rejecting BR pairing request over non-SC BR link */
if (!p_dev_rec->new_encryption_key_is_p256 && p_cb->role == HCI_ROLE_SLAVE) {
if (p_dev_rec && !p_dev_rec->new_encryption_key_is_p256 && p_cb->role == HCI_ROLE_SLAVE) {
reason = SMP_XTRANS_DERIVE_NOT_ALLOW;
smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &reason);
return;
@@ -1343,7 +1343,14 @@ void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
/* state check to prevent re-entrant */
if (smp_get_state() == SMP_STATE_BOND_PENDING) {
if (p_cb->derive_lk) {
smp_derive_link_key_from_long_term_key(p_cb, NULL);
tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
if (!(p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED) &&
(p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)) {
SMP_TRACE_DEBUG("%s BREDR key is higher security than existing LE keys, "
"don't derive LK from LTK", __func__);
} else {
smp_derive_link_key_from_long_term_key(p_cb, NULL);
}
p_cb->derive_lk = FALSE;
}
@@ -2231,7 +2231,7 @@ void smp_process_new_nonce(tSMP_CB *p_cb)
static void smp_rand_back(tBTM_RAND_ENC *p)
{
tSMP_CB *p_cb = &smp_cb;
UINT8 *pp = p->param_buf;
UINT8 *pp = NULL;
UINT8 failure = SMP_PAIR_FAIL_UNKNOWN;
UINT8 state = p_cb->rand_enc_proc_state & ~0x80;
@@ -2249,11 +2249,13 @@ static void smp_rand_back(tBTM_RAND_ENC *p)
break;
case SMP_GEN_DIV_LTK:
pp = p->param_buf;
STREAM_TO_UINT16(p_cb->div, pp);
smp_generate_ltk_cont(p_cb, NULL);
break;
case SMP_GEN_DIV_CSRK:
pp = p->param_buf;
STREAM_TO_UINT16(p_cb->div, pp);
smp_compute_csrk(p_cb, NULL);
break;
@@ -320,6 +320,12 @@ static void smp_br_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
UINT8 cmd ;
SMP_TRACE_EVENT ("SMDBG l2c %s\n", __func__);
if (p_buf->len < 1) {
SMP_TRACE_WARNING( "Bogus l2cap packet, too short");
osi_free(p_buf);
return;
}
STREAM_TO_UINT8(cmd, p);
/* sanity check */
@@ -331,6 +337,11 @@ static void smp_br_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
/* reject the pairing request if there is an on-going SMP pairing */
if (SMP_OPCODE_PAIRING_REQ == cmd) {
if (p_buf->len != smp_cmd_size_per_spec[cmd]) {
SMP_TRACE_WARNING( "Ignore received command 0x%02x with invalid length %d", cmd, p_buf->len);
osi_free(p_buf);
return;
}
if ((p_cb->state == SMP_STATE_IDLE) && (p_cb->br_state == SMP_BR_STATE_IDLE)) {
p_cb->role = HCI_ROLE_SLAVE;
p_cb->smp_over_br = TRUE;