diff options
author | alk3pInjection <webmaster@raspii.tech> | 2023-04-20 00:08:54 +0800 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2023-04-20 00:08:54 +0800 |
commit | ccb26dc8332fd8ca40e27ba99602883bee1d21e3 (patch) | |
tree | 9485c4fef031d7a6744ba8a518fd1af1ee3d6d3a | |
parent | 614ff61260cfc4f0b6ec3dcebf8811269a643bf6 (diff) | |
parent | 9ba16b56e2cdcdf76bdf1f269a5bf189bd091835 (diff) |
Merge tag 'LA.QSSI.13.0.r1-09800-qssi.0' into tachibana
"LA.QSSI.13.0.r1-09800-qssi.0"
Change-Id: I950597ebb936f5cdd667a2c5ce99393047d200de
62 files changed, 1031 insertions, 320 deletions
diff --git a/audio_hal_interface/aidl/le_audio_software.cc b/audio_hal_interface/aidl/le_audio_software.cc index ecfb2119f..32ed8d242 100644 --- a/audio_hal_interface/aidl/le_audio_software.cc +++ b/audio_hal_interface/aidl/le_audio_software.cc @@ -150,11 +150,11 @@ bool LeAudioTransport::GetPresentationPosition(uint64_t* remote_delay_report_ns, << data_position_.tv_nsec << "s, delay report=" << remote_delay_report_ms_ << " msec."; if (remote_delay_report_ns != nullptr) { - *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u; + *remote_delay_report_ns = (uint64_t)(remote_delay_report_ms_ * 1000000u); } if (total_bytes_processed != nullptr) - *total_bytes_processed = total_bytes_processed_; - if (data_position != nullptr) *data_position = data_position_; + *total_bytes_processed = (uint64_t)total_bytes_processed_; + if (data_position != nullptr) *data_position = (timespec)data_position_; return true; } @@ -235,6 +235,11 @@ void LeAudioTransport::SetRemoteDelay(uint16_t delay_report_ms) { remote_delay_report_ms_ = delay_report_ms; } +uint16_t LeAudioTransport::GetRemoteDelay() { + LOG(INFO) << __func__ << ": delay_report=" << remote_delay_report_ms_ << " msec"; + return remote_delay_report_ms_; +} + const PcmConfiguration& LeAudioTransport::LeAudioGetSelectedHalPcmConfig() { return pcm_config_; } @@ -342,6 +347,10 @@ void LeAudioSinkTransport::SetRemoteDelay(uint16_t delay_report_ms) { transport_->SetRemoteDelay(delay_report_ms); } +uint16_t LeAudioSinkTransport::GetRemoteDelay() { + return transport_->GetRemoteDelay(); +} + const PcmConfiguration& LeAudioSinkTransport::LeAudioGetSelectedHalPcmConfig() { return transport_->LeAudioGetSelectedHalPcmConfig(); } @@ -435,6 +444,10 @@ void LeAudioSourceTransport::SetRemoteDelay(uint16_t delay_report_ms) { transport_->SetRemoteDelay(delay_report_ms); } +uint16_t LeAudioSourceTransport::GetRemoteDelay() { + return transport_->GetRemoteDelay(); +} + const PcmConfiguration& LeAudioSourceTransport::LeAudioGetSelectedHalPcmConfig() { return transport_->LeAudioGetSelectedHalPcmConfig(); @@ -543,6 +556,10 @@ void LeAudioClientInterface::Sink::SetRemoteDelay(uint16_t delay_report_ms) { delay_report_ms); } +uint16_t LeAudioClientInterface::Sink::GetRemoteDelay() { + return get_aidl_transport_instance(is_broadcaster_)->GetRemoteDelay(); +} + void LeAudioClientInterface::Sink::StartSession() { LOG(ERROR) << __func__; AudioConfigurationAIDL audio_config; @@ -681,6 +698,10 @@ void LeAudioClientInterface::Source::SetRemoteDelay(uint16_t delay_report_ms) { delay_report_ms); } +uint16_t LeAudioClientInterface::Source::GetRemoteDelay() { + return aidl::le_audio::LeAudioSourceTransport::instance->GetRemoteDelay(); +} + void LeAudioClientInterface::Source::StartSession() { LOG(INFO) << __func__; AudioConfigurationAIDL audio_config; diff --git a/audio_hal_interface/aidl/le_audio_software.h b/audio_hal_interface/aidl/le_audio_software.h index ab2beb692..faa3a61fb 100644 --- a/audio_hal_interface/aidl/le_audio_software.h +++ b/audio_hal_interface/aidl/le_audio_software.h @@ -127,6 +127,8 @@ class LeAudioTransport { void SetRemoteDelay(uint16_t delay_report_ms); + uint16_t GetRemoteDelay(); + const PcmConfiguration& LeAudioGetSelectedHalPcmConfig(); void LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz, uint8_t bit_rate, @@ -181,6 +183,8 @@ class LeAudioSinkTransport void SetRemoteDelay(uint16_t delay_report_ms); + uint16_t GetRemoteDelay(); + const PcmConfiguration& LeAudioGetSelectedHalPcmConfig(); void LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz, uint8_t bit_rate, @@ -230,6 +234,8 @@ class LeAudioSourceTransport void SetRemoteDelay(uint16_t delay_report_ms); + uint16_t GetRemoteDelay(); + const PcmConfiguration& LeAudioGetSelectedHalPcmConfig(); void LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz, uint8_t bit_rate, @@ -262,6 +268,7 @@ class LeAudioClientInterface { virtual void Cleanup() = 0; virtual void SetPcmParameters(const PcmParameters& params) = 0; virtual void SetRemoteDelay(uint16_t delay_report_ms) = 0; + virtual uint16_t GetRemoteDelay() = 0; virtual void StartSession() = 0; virtual void StopSession() = 0; virtual tA2DP_CTRL_CMD GetPendingCmd() = 0; @@ -284,6 +291,7 @@ class LeAudioClientInterface { void Cleanup() override; void SetPcmParameters(const PcmParameters& params) override; void SetRemoteDelay(uint16_t delay_report_ms) override; + uint16_t GetRemoteDelay() override; void StartSession() override; void StopSession() override; tA2DP_CTRL_CMD GetPendingCmd() override; @@ -311,6 +319,7 @@ class LeAudioClientInterface { void Cleanup() override; void SetPcmParameters(const PcmParameters& params) override; void SetRemoteDelay(uint16_t delay_report_ms) override; + uint16_t GetRemoteDelay() override; void StartSession() override; void StopSession() override; tA2DP_CTRL_CMD GetPendingCmd() override; diff --git a/bta/ag/bta_ag_act.cc b/bta/ag/bta_ag_act.cc index c2f05facf..2b4d5c627 100644 --- a/bta/ag/bta_ag_act.cc +++ b/bta/ag/bta_ag_act.cc @@ -898,6 +898,9 @@ void bta_ag_post_sco_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { * ******************************************************************************/ void bta_ag_post_sco_close(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { + APPL_TRACE_IMP("%s: post_sco is %x, device %s", + __func__, p_scb->post_sco, + p_scb->peer_addr.ToString().c_str()); switch (p_scb->post_sco) { case BTA_AG_POST_SCO_CLOSE_RFC: bta_ag_rfc_do_close(p_scb, p_data); @@ -917,13 +920,33 @@ void bta_ag_post_sco_close(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { case BTA_AG_POST_SCO_CALL_END: for (size_t i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++) { if (bta_ag_cb.scb[i].in_use && - bta_ag_cb.scb[i].svc_conn && - bta_ag_cb.scb[i].post_sco == BTA_AG_POST_SCO_CALL_END) { - bta_ag_send_call_inds(&bta_ag_cb.scb[i], BTA_AG_END_CALL_RES); - bta_ag_cb.scb[i].post_sco = BTA_AG_POST_SCO_NONE; - APPL_TRACE_IMP("%s: sending call end indicators after SCO close for scb" \ + bta_ag_cb.scb[i].svc_conn) { + + if(bta_ag_cb.scb[i].post_sco == BTA_AG_POST_SCO_CALL_END) { + bta_ag_send_call_inds(&bta_ag_cb.scb[i], BTA_AG_END_CALL_RES); + bta_ag_cb.scb[i].post_sco = BTA_AG_POST_SCO_NONE; + APPL_TRACE_IMP("%s: sending call end indicators after SCO close for scb" \ " on index %x, device %s", __func__, i, bta_ag_cb.scb[i].peer_addr.ToString().c_str()); + } else if(bta_ag_cb.scb[i].post_sco == BTA_AG_POST_SCO_CALL_END_INCALL) { + bta_ag_send_call_inds(&bta_ag_cb.scb[i], BTA_AG_END_CALL_RES); + + /* Sending callsetup IND and Ring were defered to after SCO close. */ + bta_ag_send_call_inds(&bta_ag_cb.scb[i], BTA_AG_IN_CALL_RES); + APPL_TRACE_IMP("%s: sending call end and incoming indicators after SCO close for scb" \ + " on index %x, device %s", + __func__, i, bta_ag_cb.scb[i].peer_addr.ToString().c_str()); + + if (bta_ag_inband_enabled(&bta_ag_cb.scb[i]) && + !(bta_ag_cb.scb[i].features & BTA_AG_FEAT_NOSCO) && + bta_ag_sco_is_active_device(bta_ag_cb.scb[i].peer_addr)) { + bta_ag_cb.scb[i].post_sco = BTA_AG_POST_SCO_RING; + bta_ag_sco_open(&bta_ag_cb.scb[i], p_data); + } else { + bta_ag_cb.scb[i].post_sco = BTA_AG_POST_SCO_NONE; + bta_ag_send_ring(&bta_ag_cb.scb[i], p_data); + } + } } } break; diff --git a/bta/ag/bta_ag_sco.cc b/bta/ag/bta_ag_sco.cc index fc2b298a3..834277a9a 100644 --- a/bta/ag/bta_ag_sco.cc +++ b/bta/ag/bta_ag_sco.cc @@ -337,6 +337,7 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) { status != HCI_ERR_PEER_USER && status !=HCI_ERR_HOST_REJECT_SECURITY && bta_ag_cb.sco.p_curr_scb != NULL && + bta_ag_cb.sco.p_curr_scb->post_sco != BTA_AG_POST_SCO_CALL_END && bta_ag_cb.sco.p_curr_scb->no_of_xsco_retry == 0 ) { char value[PROPERTY_VALUE_MAX] = {0}; osi_property_get("vendor.bt.pts.certification", value, "false"); diff --git a/bta/av/bta_av_aact.cc b/bta/av/bta_av_aact.cc index 25ff311f5..e03c9b968 100644 --- a/bta/av/bta_av_aact.cc +++ b/bta/av/bta_av_aact.cc @@ -1054,6 +1054,22 @@ void bta_av_delay_rpt(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { + //To Pass pTS TC A2DP/SRC/AVP/BI-10-C + /* After adding PTS dongle to the AAC whitelist, + * when PTS pops up a dialog to ask IUT to response a error code, + * (Please prepare the IUT to reject an AVDTP SET CONFIGURATION + * command with error code INVALID_OBJECT_TYPE, then press 'OK' to continue.) + * user needs to click the OK very quickly other wise the case will fail + * due to IUT will start discover and set config to PTS.*/ + + char is_pts_enable[PROPERTY_VALUE_MAX] = "false"; + property_get("persist.vendor.bt.a2dp.pts_enable", is_pts_enable, "false"); + APPL_TRACE_DEBUG("%s: is_pts_enable: %s", __func__, is_pts_enable); + if (!strncmp("true", is_pts_enable, 4)) { + APPL_TRACE_DEBUG("%s: Don't do a2dp discovery for PTS, return", __func__); + return; + } + bool ok_continue = false; uint16_t avdtp_version = 0; tA2DP_SDP_DB_PARAMS db_params; @@ -2446,8 +2462,10 @@ void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { void bta_av_discover_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { /* send avdtp discover request */ APPL_TRACE_DEBUG("%s: hdi is: %d , pscb is %x\n", __func__, p_scb->hdi, p_scb); - if (AVDT_DiscoverReq(p_scb->peer_addr, p_scb->sep_info, - BTA_AV_NUM_SEPS, bta_av_dt_cback[p_scb->hdi]) != AVDT_SUCCESS) { + uint16_t status; + status = AVDT_DiscoverReq(p_scb->peer_addr, p_scb->sep_info, + BTA_AV_NUM_SEPS, bta_av_dt_cback[p_scb->hdi]); + if ((status != AVDT_SUCCESS) && (status != AVDT_BUSY)) { APPL_TRACE_ERROR("bta_av_discover_req command couldn't be sent because of resource constraint"); bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data); } @@ -4227,7 +4245,7 @@ void bta_av_vendor_offload_start(tBTA_AV_SCB* p_scb) bta_av_update_enc_mode(&av_data); break; case APTX_ULL: - av_data.encoder_mode.enc_mode = APTX_LL; + av_data.encoder_mode.enc_mode = APTX_HQ; bta_av_update_enc_mode(&av_data); BTA_AvUpdateAptxData(APTX_ULL); break; diff --git a/bta/av/bta_av_act.cc b/bta/av/bta_av_act.cc index 5743532b4..33d331765 100644 --- a/bta/av/bta_av_act.cc +++ b/bta/av/bta_av_act.cc @@ -2384,16 +2384,20 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { p_cb->rcb[rc_handle].peer_features = peer_features; p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm; } else { - /* cannot create valid rc_handle for current device */ - APPL_TRACE_ERROR(" No link resources available"); - p_scb->use_rc = FALSE; + /* Cannot create valid rc_handle for current device. Report failure*/ + APPL_TRACE_ERROR("%s: No link resources available", __func__); + p_scb->use_rc = false; + tBTA_AV_RC_OPEN rc_open; rc_open.peer_addr = p_scb->peer_addr; rc_open.peer_features = 0; + rc_open.cover_art_psm = 0; rc_open.status = BTA_AV_FAIL_RESOURCES; - (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); + tBTA_AV bta_av_data; + bta_av_data.rc_open = rc_open; + (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data); } } else { - APPL_TRACE_ERROR("can not find LCB!!"); + APPL_TRACE_ERROR("%s: can not find LCB!!", __func__); } } else if (p_scb->use_rc) { /* can not find AVRC on peer device. report failure */ diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc index 916067053..6d7b04614 100644 --- a/bta/dm/bta_dm_act.cc +++ b/bta/dm/bta_dm_act.cc @@ -15,40 +15,6 @@ * limitations under the License. * * Changes from Qualcomm Innovation Center are provided under the following license: - * - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the - * disclaimer below) provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE - * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT - * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE - * - * Changes from Qualcomm Innovation Center are provided under the following license: * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * SPDX-License-Identifier: BSD-3-Clause-Clear ******************************************************************************/ @@ -171,7 +137,6 @@ static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result); static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, tBT_TRANSPORT transport); static void bta_dm_discover_device(const RawAddress& remote_bd_addr); - static void bta_dm_sys_hw_cback(tBTA_SYS_HW_EVT status); static void bta_dm_disable_search_and_disc(void); @@ -183,6 +148,8 @@ static void bta_dm_gattc_register(void); static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr); static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr); static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data); +static void bta_dm_le_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data); + extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); @@ -351,6 +318,8 @@ extern DEV_CLASS local_device_default_class; // Stores the local Input/Output Capabilities of the Bluetooth device. static uint8_t btm_local_io_caps; +tBTA_DM_LE_GATT_INFO bta_dm_le_gatt_cb; + /** Initialises the BT device manager */ void bta_dm_enable(tBTA_DM_MSG* p_data) { tBTA_DM_ENABLE enable_event; @@ -1498,7 +1467,9 @@ void bta_dm_search_start(tBTA_DM_MSG* p_data) { APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, p_bta_dm_cfg->avoid_scatter); - +#ifdef ADV_AUDIO_FEATURE + bta_dm_reset_adv_audio_device_db(); +#endif if (p_bta_dm_cfg->avoid_scatter && (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT)) { @@ -1586,6 +1557,7 @@ void bta_dm_search_cancel(UNUSED_ATTR tBTA_DM_MSG* p_data) { * ******************************************************************************/ void bta_dm_discover(tBTA_DM_MSG* p_data) { + APPL_TRACE_EVENT("%s ", __func__); size_t len = sizeof(Uuid) * p_data->discover.num_uuid; APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__, p_data->discover.services, p_data->discover.sdp_search); @@ -2641,9 +2613,9 @@ static void bta_dm_discover_next_device(void) { ******************************************************************************/ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; + tBLE_ADDR_TYPE addr_type = BLE_ADDR_PUBLIC; if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) { tBT_DEVICE_TYPE dev_type; - tBLE_ADDR_TYPE addr_type; BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type); if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) @@ -2667,8 +2639,10 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name); } if ((bta_dm_search_cb.p_btm_inq_info) && - (bta_dm_search_cb.p_btm_inq_info->results.device_type == - BT_DEVICE_TYPE_BLE) && + ((bta_dm_search_cb.p_btm_inq_info->results.device_type == + BT_DEVICE_TYPE_BLE) || ((bta_dm_search_cb.p_btm_inq_info->results.device_type == + BT_DEVICE_TYPE_DUMO) && (addr_type == BLE_ADDR_RANDOM))) + && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) { /* Do not perform RNR for LE devices at inquiry complete*/ bta_dm_search_cb.name_discover_done = true; @@ -2915,7 +2889,7 @@ static void bta_dm_rem_name_cback (const RawAddress& bd_addr, DEV_CLASS dc, BD_N static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, UNUSED_ATTR DEV_CLASS dc, BD_NAME bd_name) { - tBTM_REMOTE_DEV_NAME rem_name; + tBTM_REMOTE_DEV_NAME rem_name = {}; tBTM_STATUS btm_status; APPL_TRACE_DEBUG("%s name=<%s>", __func__, bd_name); @@ -2929,7 +2903,7 @@ static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, } strlcpy((char*)rem_name.remote_bd_name, (char*)bd_name, BD_NAME_LEN + 1); rem_name.status = BTM_SUCCESS; - + rem_name.hci_status = HCI_SUCCESS; bta_dm_remname_cback(&rem_name); } else { /* get name of device */ @@ -2947,6 +2921,7 @@ static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, rem_name.length = 0; rem_name.remote_bd_name[0] = 0; rem_name.status = btm_status; + rem_name.hci_status = HCI_SUCCESS; bta_dm_remname_cback(&rem_name); } } @@ -2967,19 +2942,32 @@ static void bta_dm_remname_cback(void* p) { p_remote_name->length, p_remote_name->remote_bd_name); if ((p_remote_name->bd_addr != RawAddress::kEmpty) && - (p_remote_name->bd_addr != bta_dm_search_cb.peer_bdaddr)) { - VLOG(1) << "bta_dm_remname_cback ,rnr complete for diff device,return" - << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr - << " p_remote_name_bda=" << p_remote_name->bd_addr; - return; + (p_remote_name->bd_addr == bta_dm_search_cb.peer_bdaddr)) { + BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); + } else { + VLOG(1) << "bta_dm_remname_cback ,rnr complete for diff device,return"; + // if we got a different response, maybe ignore it + // we will have made a request directly from BTM_ReadRemoteDeviceName so we + // expect a dedicated response for us + if (p_remote_name->hci_status == HCI_ERR_CONNECTION_EXISTS) { + BTM_SecDeleteRmtNameNotifyCallback( + &bta_dm_service_search_remname_cback); + VLOG(1) << "Assume command failed due to disconnection hci_status:" + << p_remote_name->hci_status + << " p_remote_name_bda=" << p_remote_name->bd_addr; + } else { + VLOG(1) << "Ignored remote name response for the wrong address exp:" + << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr + << " act: p_remote_name_bda=" << p_remote_name->bd_addr; + return; + } } + /* remote name discovery is done but it could be failed */ bta_dm_search_cb.name_discover_done = true; strlcpy((char*)bta_dm_search_cb.peer_name, (char*)p_remote_name->remote_bd_name, BD_NAME_LEN + 1); - BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); - if (bta_dm_search_cb.transport == BT_TRANSPORT_LE) { GAP_BleReadPeerPrefConnParams(bta_dm_search_cb.peer_bdaddr); } @@ -5383,6 +5371,9 @@ void bta_dm_ble_config_local_privacy(tBTA_DM_MSG* p_data) { void bta_dm_ble_observe(tBTA_DM_MSG* p_data) { tBTM_STATUS status; if (p_data->ble_observe.start) { +#ifdef ADV_AUDIO_FEATURE + bta_dm_reset_adv_audio_device_db(); +#endif /*Save the callback to be called when a scan results are available */ bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback; status = BTM_BleObserve(true, p_data->ble_observe.duration, @@ -5705,8 +5696,20 @@ void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) { btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id); } else { if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { +#ifdef ADV_AUDIO_FEATURE + if (is_remote_support_adv_audio(bd_addr)) { + APPL_TRACE_DEBUG("%s ADV_AUDIO_DEVICE ", __func__); + BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true, + GATT_TRANSPORT_LE, true); + } else { + APPL_TRACE_DEBUG("%s LEGACY LE DEVICE ", __func__); + BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true, + GATT_TRANSPORT_LE, false); + } +#else BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true, - GATT_TRANSPORT_LE, true); + GATT_TRANSPORT_LE, false); +#endif } else { //TODO review. Kept qcom Specific change only. APPL_TRACE_DEBUG("btm_dm_start_gatt_discovery: ACL is disconnected"); @@ -5927,4 +5930,114 @@ void bta_dm_ble_subrate_request(tBTA_DM_MSG* p_data) { } } +void bta_dm_le_gatt_open_evt(tBTA_GATTC_OPEN* p_data) { + VLOG(1) << "bta_dm_le_gatt_open_evt peer_dbaddr:" + << bta_dm_le_gatt_cb.peer_address + << " connected_bda=" << p_data->remote_bda; + if (p_data->status == GATT_SUCCESS) { + btm_dm_start_disc_gatt_services(p_data->conn_id); + } else { + bta_dm_gatt_disc_complete(GATT_INVALID_CONN_ID, p_data->status); + } +} + +static void bta_dm_le_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { + APPL_TRACE_DEBUG(" bta_dm_le_gattc_callback event = %d", event); + + switch (event) { + case BTA_GATTC_OPEN_EVT: + APPL_TRACE_DEBUG(" bta_dm_le_gattc_callback BTA_GATTC_OPEN_EVT"); + bta_dm_le_gatt_cb.disc_progress = false; + bta_dm_le_gatt_open_evt(&p_data->open); + break; + + case BTA_GATTC_SEARCH_RES_EVT: +#ifdef ADV_AUDIO_FEATURE + if (!bta_dm_le_gatt_cb.is_lea_device) { + if (is_le_audio_service(p_data->srvc_res.service_uuid.uuid)) { + APPL_TRACE_DEBUG(" bta_dm_le_gattc_callback LE AUDIO UUID"); + bta_dm_le_gatt_cb.is_lea_device = true; + //This remote supports LE AUDIO. So reuse LE AUDIO API's to derive role + btif_store_adv_audio_pair_info(bta_dm_le_gatt_cb.peer_address); + bta_dm_update_adv_audio_db(bta_dm_le_gatt_cb.peer_address); + } + } +#endif + break; + + case BTA_GATTC_SEARCH_CMPL_EVT: + APPL_TRACE_DEBUG(" bta_dm_le_gattc_callback BTA_GATTC_SEARCH_CMPL_EVT"); +#ifdef ADV_AUDIO_FEATURE + if (bta_dm_le_gatt_cb.is_lea_device && !bta_dm_le_gatt_cb.disc_progress) { + APPL_TRACE_DEBUG(" bta_dm_le_gattc_callback LE AUDIO ROLE DISC"); + //This remote supports LE AUDIO. So reuse LE AUDIO API's to derive role + tBTA_GATTC_OPEN p_tmp_data; + p_tmp_data.remote_bda = bta_dm_le_gatt_cb.peer_address; + p_tmp_data.conn_id = p_data->search_cmpl.conn_id; + p_tmp_data.transport = BT_TRANSPORT_LE; + bta_dm_le_gatt_cb.disc_progress = true; + bta_dm_set_adv_audio_dev_info(&p_tmp_data); + bta_adv_audio_update_bond_db(bta_dm_le_gatt_cb.peer_address, GATT_TRANSPORT_LE); + + if (p_data->search_cmpl.status == 0) { + bta_get_adv_audio_role(bta_dm_le_gatt_cb.peer_address, + p_data->search_cmpl.conn_id, + p_data->search_cmpl.status); + if (is_adv_audio_group_supported(bta_dm_le_gatt_cb.peer_address, + p_data->search_cmpl.conn_id)) { + bta_find_adv_audio_group_instance(p_data->search_cmpl.conn_id, + p_data->search_cmpl.status, bta_dm_le_gatt_cb.peer_address); + } + } else { + APPL_TRACE_DEBUG("%s Discovery Failure ", __func__); + bta_le_audio_service_search_failed(&bta_dm_le_gatt_cb.peer_address); + } + } +#endif + break; + + case BTA_GATTC_CLOSE_EVT: + APPL_TRACE_ERROR(" BTA_GATTC_CLOSE_EVT reason = %d," + "p_data conn_id %d, search conn_id %d", p_data->close.reason, + p_data->close.conn_id,bta_dm_search_cb.conn_id); + BTA_GATTC_AppDeregister(bta_dm_le_gatt_cb.gatt_if); + bta_dm_le_gatt_cb.gatt_if = GATT_INVALID_CONN_ID; + bta_dm_le_gatt_cb.is_lea_device = false; + bta_dm_le_gatt_cb.disc_progress = false; + bta_dm_le_gatt_cb.peer_address = RawAddress::kEmpty; + +#ifdef ADV_AUDIO_FEATURE + if (is_remote_support_adv_audio(p_data->close.remote_bda)) { + bta_dm_reset_adv_audio_dev_info(p_data->close.remote_bda); + } +#endif + break; + default: + break; + } +} + +void bta_dm_gatt_le_services(RawAddress bd_addr) { + APPL_TRACE_WARNING(" bta_dm_gatt_le_services"); + + if (bta_dm_le_gatt_cb.disc_progress) { + APPL_TRACE_ERROR("Already dm le discovery in progress. Ignore it"); + return; + } + bta_dm_le_gatt_cb.peer_address = bd_addr; + + BTA_GATTC_AppRegister(bta_dm_le_gattc_callback, + base::Bind([](uint8_t client_id, uint8_t status) { + if (status == GATT_SUCCESS) { + + APPL_TRACE_DEBUG("bta_dm_gatt_le_services Client Id: %d", + client_id); + bta_dm_le_gatt_cb.gatt_if = client_id; + bta_dm_le_gatt_cb.disc_progress = true; + BTA_GATTC_Open(client_id, bta_dm_le_gatt_cb.peer_address, + true, GATT_TRANSPORT_LE, false); + } + }), false); + +} diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h index 72fab36d3..779dc2eb1 100644 --- a/bta/dm/bta_dm_int.h +++ b/bta/dm/bta_dm_int.h @@ -905,6 +905,12 @@ typedef struct { uint8_t lmp_version; } tBTA_DM_LMP_VER_INFO; +typedef struct { + RawAddress peer_address; + int gatt_if; + bool disc_progress = false; + bool is_lea_device = false; +} tBTA_DM_LE_GATT_INFO; extern const uint16_t bta_service_id_to_uuid_lkup_tbl[]; diff --git a/bta/dm/bta_dm_main.cc b/bta/dm/bta_dm_main.cc index 3b105adb7..9ba343ff9 100644 --- a/bta/dm/bta_dm_main.cc +++ b/bta/dm/bta_dm_main.cc @@ -274,7 +274,7 @@ const uint8_t bta_dm_search_disc_active_st_table[][BTA_DM_SEARCH_NUM_COLS] = { /* Event Action 1 Action 2 Next State */ - /* API_SEARCH */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, + /* API_SEARCH */ {BTA_DM_QUEUE_SEARCH, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE}, /* API_SEARCH_CANCEL */ {BTA_DM_SEARCH_CANCEL_NOTIFY, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING}, diff --git a/bta/gatt/bta_gattc_act.cc b/bta/gatt/bta_gattc_act.cc index 42f9eef44..4ba66e165 100644 --- a/bta/gatt/bta_gattc_act.cc +++ b/bta/gatt/bta_gattc_act.cc @@ -345,18 +345,20 @@ void bta_gattc_process_api_open(tBTA_GATTC_DATA* p_msg) { p_msg->api_conn.remote_bda = map_addr; } } else { - tBT_DEVICE_TYPE dev_type; - tBLE_ADDR_TYPE addr_type; - - BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type); - bool addr_is_rpa = (addr_type == BLE_ADDR_RANDOM && BTM_BLE_IS_RESOLVE_BDA(bd_addr)); - LOG(INFO) << __func__ << " -- addr_is_rpa " << addr_is_rpa; - if (addr_is_rpa) { - dev_addr_map[p_msg->api_conn.client_if] = bd_addr; - p_msg->api_conn.remote_bda = map_addr; - } else if (!is_remote_support_adv_audio(map_addr)) { - dev_addr_map[p_msg->api_conn.client_if] = bd_addr; - p_msg->api_conn.remote_bda = map_addr; + if (!p_msg->api_conn.opportunistic) { + tBT_DEVICE_TYPE dev_type; + tBLE_ADDR_TYPE addr_type; + + BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type); + bool addr_is_rpa = (addr_type == BLE_ADDR_RANDOM && BTM_BLE_IS_RESOLVE_BDA(bd_addr)); + LOG(INFO) << __func__ << " -- addr_is_rpa " << addr_is_rpa; + if (addr_is_rpa) { + dev_addr_map[p_msg->api_conn.client_if] = bd_addr; + p_msg->api_conn.remote_bda = map_addr; + } else if (!is_remote_support_adv_audio(map_addr)) { + dev_addr_map[p_msg->api_conn.client_if] = bd_addr; + p_msg->api_conn.remote_bda = map_addr; + } } } } @@ -805,7 +807,7 @@ void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb, /** Configure MTU size on the GATT connection */ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { - if (!bta_gattc_enqueue(p_clcb, p_data)) return; + if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATTC_ConfigureMTU(p_clcb->bta_conn_id, p_data->api_mtu.mtu); @@ -821,6 +823,7 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { } bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL); + bta_gattc_continue(p_clcb); } } @@ -962,6 +965,8 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, * referenced by p_clcb->p_q_cmd */ if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd); + } else { + bta_gattc_continue(p_clcb); } if (p_clcb->p_rcb->p_cback && p_clcb->p_srcb) { @@ -973,7 +978,7 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, /** Read an attribute */ void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { - if (!bta_gattc_enqueue(p_clcb, p_data)) return; + if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status; if (p_data->api_read.handle != 0) { @@ -1000,12 +1005,13 @@ void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); + bta_gattc_continue(p_clcb); } } /** read multiple */ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { - if (!bta_gattc_enqueue(p_clcb, p_data)) return; + if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_READ_PARAM read_param; memset(&read_param, 0, sizeof(tGATT_READ_PARAM)); @@ -1032,12 +1038,13 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); + bta_gattc_continue(p_clcb); } } /** Write an attribute */ void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { - if (!bta_gattc_enqueue(p_clcb, p_data)) return; + if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATT_SUCCESS; tGATT_VALUE attr; @@ -1061,12 +1068,13 @@ void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL); + bta_gattc_continue(p_clcb); } } /** send execute write */ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { - if (!bta_gattc_enqueue(p_clcb, p_data)) return; + if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute); @@ -1076,6 +1084,7 @@ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL); + bta_gattc_continue(p_clcb); } } diff --git a/bta/gatt/bta_gattc_cache.cc b/bta/gatt/bta_gattc_cache.cc index 7902a5990..23ba4e21e 100644 --- a/bta/gatt/bta_gattc_cache.cc +++ b/bta/gatt/bta_gattc_cache.cc @@ -186,7 +186,7 @@ static void bta_gattc_explore_next_service(uint16_t conn_id, p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_READ_EXT_PROP_DESC; - if (p_srvc_cb->read_multiple_not_supported) { + if (p_srvc_cb->read_multiple_not_supported || descriptors.size() == 1) { tGATT_READ_PARAM read_param{ .by_handle = {.handle = descriptors.front(), .auth_req = GATT_AUTH_REQ_NONE}}; diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h index bace691f4..d17b58c2b 100644 --- a/bta/gatt/bta_gattc_int.h +++ b/bta/gatt/bta_gattc_int.h @@ -24,8 +24,9 @@ #ifndef BTA_GATTC_INT_H #define BTA_GATTC_INT_H -#include "bt_target.h" +#include <deque> +#include "bt_target.h" #include "bta_gatt_api.h" #include "bta_sys.h" #include "database_builder.h" @@ -264,6 +265,7 @@ typedef struct { tBTA_GATTC_RCB* p_rcb; /* pointer to the registration CB */ tBTA_GATTC_SERV* p_srcb; /* server cache CB */ tBTA_GATTC_DATA* p_q_cmd; /* command in queue waiting for execution */ + std::deque<tBTA_GATTC_DATA*> p_q_cmd_queue; // request during discover state #define BTA_GATTC_DISCOVER_REQ_NONE 0 @@ -432,7 +434,16 @@ extern tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id); extern tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg); extern tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg); -extern bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data); +enum BtaEnqueuedResult_t { + ENQUEUED_READY_TO_SEND, + ENQUEUED_FOR_LATER, +}; + +extern BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, + tBTA_GATTC_DATA* p_data); +extern bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb, + tBTA_GATTC_DATA* p_data); +extern void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb); extern bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg, tBTA_GATTC_SERV* p_srcb, diff --git a/bta/gatt/bta_gattc_main.cc b/bta/gatt/bta_gattc_main.cc index db36b8b80..4cd3724ab 100644 --- a/bta/gatt/bta_gattc_main.cc +++ b/bta/gatt/bta_gattc_main.cc @@ -363,7 +363,7 @@ bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event, action = state_table[event][i]; if (action != BTA_GATTC_IGNORE) { (*bta_gattc_action[action])(p_clcb, p_data); - if (p_clcb->p_q_cmd == p_data) { + if (bta_gattc_is_data_queued(p_clcb, p_data)) { /* buffer is queued, don't free in the bta dispatcher. * we free it ourselves when a completion event is received. */ diff --git a/bta/gatt/bta_gattc_utils.cc b/bta/gatt/bta_gattc_utils.cc index 35c6c3799..46e5bec48 100644 --- a/bta/gatt/bta_gattc_utils.cc +++ b/bta/gatt/bta_gattc_utils.cc @@ -58,6 +58,8 @@ #define LOG_TAG "bt_bta_gattc" #include <base/logging.h> +#include "osi/include/log.h" + #include <string.h> #include "bt_common.h" @@ -240,8 +242,27 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { p_srcb->gatt_database.Clear(); } + while (!p_clcb->p_q_cmd_queue.empty()) { + auto p_q_cmd = p_clcb->p_q_cmd_queue.front(); + p_clcb->p_q_cmd_queue.pop_front(); + osi_free_and_reset((void**)&p_q_cmd); + } + osi_free_and_reset((void**)&p_clcb->p_q_cmd); - memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB)); + + /* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and + * p_q_cmd. */ + p_clcb->bta_conn_id = 0; + p_clcb->bda = {}; + p_clcb->transport = 0; + p_clcb->p_rcb = NULL; + p_clcb->p_srcb = NULL; + p_clcb->request_during_discovery = 0; + p_clcb->auto_update = 0; + p_clcb->disc_active = 0; + p_clcb->in_use = 0; + p_clcb->state = BTA_GATTC_IDLE_ST; + p_clcb->status = GATT_SUCCESS; } /******************************************************************************* @@ -338,24 +359,56 @@ tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) { } return p_tcb; } + +void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb) { + if (p_clcb->p_q_cmd != NULL) { + VLOG(1) << __func__ << "Already scheduled another request for conn_id = 0x" + << +p_clcb->bta_conn_id; + return; + } + + if (p_clcb->p_q_cmd_queue.empty()) { + VLOG(1) << __func__ << "Nothing to do for conn_id = 0x" << +p_clcb->bta_conn_id; + return; + } + + tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd_queue.front(); + p_clcb->p_q_cmd_queue.pop_front(); + bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd); +} + +bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb, + tBTA_GATTC_DATA* p_data) { + if (p_clcb->p_q_cmd == p_data) { + return true; + } + + auto it = std::find(p_clcb->p_q_cmd_queue.begin(), + p_clcb->p_q_cmd_queue.end(), p_data); + return it != p_clcb->p_q_cmd_queue.end(); +} /******************************************************************************* * * Function bta_gattc_enqueue * * Description enqueue a client request in clcb. * - * Returns success or failure. + * Returns BtaEnqueuedResult_t * ******************************************************************************/ -bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { +BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) { if (p_clcb->p_q_cmd == NULL) { p_clcb->p_q_cmd = p_data; - return true; + return ENQUEUED_READY_TO_SEND; } - LOG(ERROR) << __func__ << ": already has a pending command"; - /* skip the callback now. ----- need to send callback ? */ - return false; + VLOG(1) << __func__ << + "Already has a pending command to executer. Queuing for later " + << +p_clcb->bda.ToString().c_str() + << "conn id=0x" << p_clcb->bta_conn_id; + p_clcb->p_q_cmd_queue.push_back(p_data); + + return ENQUEUED_FOR_LATER; } /******************************************************************************* diff --git a/bta/gatt/bta_gatts_api.cc b/bta/gatt/bta_gatts_api.cc index 81e8704eb..9c54a360a 100644 --- a/bta/gatt/bta_gatts_api.cc +++ b/bta/gatt/bta_gatts_api.cc @@ -235,6 +235,12 @@ void BTA_GATTS_StopService(uint16_t service_id) { void BTA_GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_id, std::vector<uint8_t> value, bool need_confirm) { + + if (value.size() > sizeof(tBTA_GATTS_API_INDICATION::value)) { + LOG(ERROR) << __func__ << "data to indicate is too long"; + return; + } + tBTA_GATTS_API_INDICATION* p_buf = (tBTA_GATTS_API_INDICATION*)osi_calloc(sizeof(tBTA_GATTS_API_INDICATION)); diff --git a/bta/hh/bta_hh_le.cc b/bta/hh/bta_hh_le.cc index b6c2272dc..00e8d3549 100644 --- a/bta/hh/bta_hh_le.cc +++ b/bta/hh/bta_hh_le.cc @@ -1752,7 +1752,7 @@ void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) { : BTA_HH_ERR; else conn_dat.status = p_cb->status; - + p_cb->hid_handle = BTA_HH_INVALID_HANDLE; /* Report OPEN fail event */ (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH*)&conn_dat); } diff --git a/bta/include/bta_dm_api.h b/bta/include/bta_dm_api.h index de92947bf..35d97dc27 100644 --- a/bta/include/bta_dm_api.h +++ b/bta/include/bta_dm_api.h @@ -29,5 +29,6 @@ // Brings connection to active mode void bta_dm_pm_active(const RawAddress& peer_addr); +void bta_dm_gatt_le_services(RawAddress bd_addr); #endif /* BTA_DM_API_H */ diff --git a/btif/co/bta_av_co.cc b/btif/co/bta_av_co.cc index 5ec759c37..cd978784a 100644 --- a/btif/co/bta_av_co.cc +++ b/btif/co/bta_av_co.cc @@ -991,6 +991,11 @@ void* bta_av_co_audio_src_data_path(const uint8_t* p_codec_info, return NULL; } + if (p_buf->offset < 4) { + APPL_TRACE_ERROR("%s: No space for timestamp in packet, dropped", __func__); + return NULL; + } + /* * Retrieve the timestamp information from the media packet, * and set up the packet header. @@ -1004,6 +1009,7 @@ void* bta_av_co_audio_src_data_path(const uint8_t* p_codec_info, !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) { APPL_TRACE_ERROR("%s: unsupported codec type (%d)", __func__, A2DP_GetCodecType(p_codec_info)); + return NULL; } #if (BTA_AV_CO_CP_SCMS_T == TRUE) diff --git a/btif/include/btif_ahim.h b/btif/include/btif_ahim.h index 239893e46..6fee2b349 100644 --- a/btif/include/btif_ahim.h +++ b/btif/include/btif_ahim.h @@ -144,6 +144,7 @@ typedef void (* ahim_update_src_metadata)(const source_metadata_t& source_metada typedef void (* ahim_update_snk_metadata)(const sink_metadata_t& sink_metadata); typedef uint32_t (* ahim_get_mode_callback)(); typedef uint16_t (* ahim_get_frame_duration)(uint8_t direction); +typedef void (* ahim_update_params)(uint16_t delay, uint8_t mode); typedef struct { uint8_t mode; @@ -168,6 +169,7 @@ typedef struct { ahim_update_snk_metadata snk_meta_update; ahim_get_mode_callback get_mode_cb; ahim_get_frame_duration get_frame_duration; + ahim_update_params params_update; }btif_ahim_client_callbacks_t; extern btif_ahim_client_callbacks_t* pclient_cbs[MAX_CLIENT]; @@ -198,6 +200,10 @@ bool btif_ahim_is_restart_session_needed(uint8_t profile); void btif_ahim_update_session_params(SessionParamType param_type); +void btif_ahim_update_audio_config(); + +uint16_t btif_ahim_get_remote_delay(); + bool btif_ahim_setup_codec(uint8_t profile); void btif_ahim_start_session(uint8_t profile); @@ -211,6 +217,8 @@ tA2DP_CTRL_CMD btif_ahim_get_pending_command(uint8_t profile, void btif_ahim_reset_pending_command(uint8_t profile); +void btif_ahim_update_params (uint16_t delay, uint8_t mode); + void btif_ahim_reset_pending_command(uint8_t profile, uint8_t direction); void btif_ahim_update_pending_command(tA2DP_CTRL_CMD cmd, uint8_t profile); diff --git a/btif/include/btif_api.h b/btif/include/btif_api.h index f549519bf..1e733720a 100644 --- a/btif/include/btif_api.h +++ b/btif/include/btif_api.h @@ -527,6 +527,7 @@ bt_status_t btif_set_dynamic_audio_buffer_size(int codec, int size); * Returns void * ******************************************************************************/ +void btif_update_params(uint16_t delay, uint8_t mode); #ifdef ADV_AUDIO_FEATURE void btif_register_uuid_srvc_disc(bluetooth::Uuid uuid); #endif diff --git a/btif/include/btif_dm.h b/btif/include/btif_dm.h index 8ce3fb41c..eb1250c66 100644 --- a/btif/include/btif_dm.h +++ b/btif/include/btif_dm.h @@ -117,11 +117,15 @@ void btif_vendor_update_whitelisted_media_players(); bool fetch_whitelisted_media_players(list_t** bl_devices); void btif_get_pairing_cb_info(bt_bond_state_t* state, uint8_t* sdp_attempts, - RawAddress* bd_addr, RawAddress* static_bdaddr); + RawAddress* bd_addr, RawAddress* static_bdaddr, + RawAddress* lea_bd_addr); void btif_inc_sdp_attempts(); void btif_reset_pairing_cb() ; void btif_reset_sdp_attempts(); int btif_dm_is_adv_audio(); - +void btif_dm_get_le_services(RawAddress *bd_addr, int transport); +#ifdef ADV_AUDIO_FEATURE +void btif_store_adv_audio_pair_info(RawAddress bd_addr); +#endif #endif diff --git a/btif/include/btif_sock_sdp.h b/btif/include/btif_sock_sdp.h index 03571c9e4..d4bf8f57c 100644 --- a/btif/include/btif_sock_sdp.h +++ b/btif/include/btif_sock_sdp.h @@ -14,6 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. * + * Changes from Qualcomm Innovation Center are provided under the following license: + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause-Clear + * ******************************************************************************/ #ifndef BTIF_SOCK_SDP_H @@ -26,7 +30,7 @@ static const bluetooth::Uuid UUID_OBEX_OBJECT_PUSH = bluetooth::Uuid::From16Bit(0x1105); -static const bluetooth::Uuid UUID_PBAP_PCE = bluetooth::Uuid::From16Bit(0x112F); +static const bluetooth::Uuid UUID_PBAP_PCE = bluetooth::Uuid::From16Bit(0x112E); static const bluetooth::Uuid UUID_PBAP_PSE = bluetooth::Uuid::From16Bit(0x112F); static const bluetooth::Uuid UUID_MAP_MAS = bluetooth::Uuid::From16Bit(0x1132); static const bluetooth::Uuid UUID_SAP = bluetooth::Uuid::From16Bit(0x112D); diff --git a/btif/src/bluetooth.cc b/btif/src/bluetooth.cc index 28472217c..9ad80e043 100644 --- a/btif/src/bluetooth.cc +++ b/btif/src/bluetooth.cc @@ -366,10 +366,12 @@ static int get_connection_state(const RawAddress* bd_addr) { static int pin_reply(const RawAddress* bd_addr, uint8_t accept, uint8_t pin_len, bt_pin_code_t* pin_code) { + bt_pin_code_t tmp_pin_code; /* sanity check */ if (interface_ready() == false) return BT_STATUS_NOT_READY; - return btif_dm_pin_reply(bd_addr, accept, pin_len, pin_code); + memcpy(&tmp_pin_code, pin_code, pin_len); + return btif_dm_pin_reply(bd_addr, accept, pin_len, &tmp_pin_code); } static int ssp_reply(const RawAddress* bd_addr, bt_ssp_variant_t variant, @@ -555,6 +557,10 @@ static bool allow_low_latency_audio(bool allowed, const RawAddress& address) { return false; } +static void metadata_changed(const RawAddress& remote_bd_addr, int key, + std::vector<uint8_t> value) { +} + EXPORT_SYMBOL bt_interface_t bluetoothInterface = { sizeof(bluetoothInterface), init, @@ -596,6 +602,7 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = { generate_local_oob_data, allow_low_latency_audio, clear_event_filter, + metadata_changed, }; void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c, diff --git a/btif/src/btif_a2dp_source.cc b/btif/src/btif_a2dp_source.cc index 7f90a8f58..d1b5ec373 100644 --- a/btif/src/btif_a2dp_source.cc +++ b/btif/src/btif_a2dp_source.cc @@ -66,6 +66,7 @@ using ::bluetooth::audio::a2dp::SessionType; #include "btif_hf.h" #include "btif_av.h" #include "bta_sys.h" +#include "btif_acm.h" using system_bt_osi::BluetoothMetricsLogger; using system_bt_osi::A2dpSessionMetrics; @@ -174,6 +175,9 @@ extern int btif_av_get_tws_pair_idx(int index); extern void btif_av_clear_pending_start_flag(); extern bool btif_av_is_tws_suspend_triggered(int index); +extern bool btif_acm_check_in_call_tracker_timer_exist(); +extern void stop_stream_acm_initiator_now(); + static char a2dp_hal_imp[PROPERTY_VALUE_MAX] = "false"; UNUSED_ATTR static const char* dump_media_event(uint16_t event) { switch (event) { @@ -398,25 +402,30 @@ static void btif_a2dp_source_remote_start_timeout(UNUSED_ATTR void* context) { btif_a2dp_source_cb.remote_start_alarm = NULL; btif_a2dp_source_cb.last_remote_started_index = -1; btif_a2dp_source_cb.last_started_index_pointer = NULL; + if(arg) { + osi_free(arg); + } } btif_dispatch_sm_event(BTIF_AV_REMOTE_SUSPEND_STREAM_REQ_EVT, &index, sizeof(index)); - if(arg) { - osi_free(arg); - } return; } void btif_a2dp_source_on_remote_start(struct alarm_t **remote_start_alarm, int index) { // initiate remote start timer for index basis int *arg = NULL; - arg = (int *) osi_malloc(sizeof(int)); if (remote_start_alarm == NULL) { LOG_ERROR(LOG_TAG,"%s:remote start alarm is NULL",__func__); return; } + arg = (int *) osi_malloc(sizeof(int)); + if (!arg) { + LOG_ERROR(LOG_TAG,"%s: alloc fail.", __func__); + return; + } *remote_start_alarm = alarm_new("btif.remote_start_task"); - if (!(*remote_start_alarm) || !arg) { + if (!(*remote_start_alarm)) { LOG_ERROR(LOG_TAG,"%s:unable to allocate media alarm",__func__); + osi_free(arg); btif_av_clear_remote_start_timer(index); btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, &index, sizeof(index)); return; @@ -1823,6 +1832,12 @@ void btif_a2dp_source_process_request(tA2DP_CTRL_CMD cmd) { status = A2DP_CTRL_ACK_INCALL_FAILURE; break; } + if (btif_ahim_is_aosp_aidl_hal_enabled() && + btif_acm_check_in_call_tracker_timer_exist()) { + stop_stream_acm_initiator_now(); + status = A2DP_CTRL_ACK_INCALL_FAILURE; + break; + } if (btif_ba_is_active()) { ba_send_message(BTIF_BA_AUDIO_START_REQ_EVT, 0, NULL, false); diff --git a/btif/src/btif_ahim.cc b/btif/src/btif_ahim.cc index f061a09ae..96fc27dc8 100644 --- a/btif/src/btif_ahim.cc +++ b/btif/src/btif_ahim.cc @@ -74,7 +74,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE #endif #include <aidl/vendor/qti/hardware/bluetooth/audio/LeAudioVendorConfiguration.h> #include <aidl/vendor/qti/hardware/bluetooth/audio/VendorCodecType.h> -#include "osi/include/properties.h" using bluetooth::audio::aidl::le_audio::LeAudioClientInterface; @@ -246,13 +245,24 @@ void btif_ahim_update_src_metadata (const source_metadata_t& source_metadata) { std::unique_lock<std::mutex> guard(src_metadata_wait_mutex_); src_metadata_wait = false; pclient_cbs[AUDIO_GROUP_MGR - 1]->src_meta_update(source_metadata); - src_metadata_wait_cv.wait_for(guard, std::chrono::milliseconds(100), + src_metadata_wait_cv.wait_for(guard, std::chrono::milliseconds(3200), []{return src_metadata_wait;}); BTIF_TRACE_IMP("%s: src waiting completed", __func__); } } } +void btif_ahim_update_params (uint16_t delay, uint8_t mode) { + // pass on the callbacks to ACM only for new vendor + if(btif_ahim_is_aosp_aidl_hal_enabled()) { + if (pclient_cbs[AUDIO_GROUP_MGR - 1] && + pclient_cbs[AUDIO_GROUP_MGR - 1]->params_update) { + BTIF_TRACE_IMP("%s: calling updateParams for Audio Group Manager", __func__); + pclient_cbs[AUDIO_GROUP_MGR - 1]->params_update(delay, mode); + } + } +} + void btif_ahim_update_sink_metadata (const sink_metadata_t& sink_metadata) { auto track_count = sink_metadata.track_count; auto source = sink_metadata.tracks->source; @@ -269,7 +279,7 @@ void btif_ahim_update_sink_metadata (const sink_metadata_t& sink_metadata) { std::unique_lock<std::mutex> guard(snk_metadata_wait_mutex_); snk_metadata_wait = false; pclient_cbs[AUDIO_GROUP_MGR - 1]->snk_meta_update(sink_metadata); - snk_metadata_wait_cv.wait_for(guard, std::chrono::milliseconds(100), + snk_metadata_wait_cv.wait_for(guard, std::chrono::milliseconds(3200), []{return snk_metadata_wait;}); BTIF_TRACE_IMP("%s: snk waiting completed", __func__); } @@ -516,15 +526,10 @@ LeAudioConfiguration fetch_offload_audio_config(int profile, int direction) { #ifdef ADV_AUDIO_FEATURE bool is_lc3q_supported = false; CodecIndex codec_type = (CodecIndex) pclient_cbs[profile - 1]->get_codec_type(direction); - /* >> XPAN Testing Purpose Only */ - char r4_aidl_value[PROPERTY_VALUE_MAX] = "true"; - property_get("persist.vendor.service.bt.test_aidl_r4", r4_aidl_value, "false"); - if (std::string{r4_aidl_value, 4} == "true") { - codec_type = CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_R4; - } - /* << XPAN Testing Purpose Only */ - if (codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_LE) { - frame_duration = pclient_cbs[profile - 1]->get_frame_duration(direction); + if (codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_LE || + codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_R4) { + frame_duration = + ((pclient_cbs[profile - 1]->get_min_sup_frame_dur(direction)) / 4) * 1000; LOG(ERROR) << __func__ << ": fetch frame duration: " << frame_duration << ", from leaudio_configs.xml"; } @@ -543,66 +548,44 @@ LeAudioConfiguration fetch_offload_audio_config(int profile, int direction) { le_vendor_config.octetsPerFrame = (int) pclient_cbs[profile - 1]->get_mtu_cb(0, direction); le_vendor_config.blocksPerSdu = 1; - + le_vendor_config.codecSpecificData = + { 0x0F, //Vendor Metadata Length + 0xFF, //Vendor META data type + 0x0A, //Qtil ID + 0x00, + 0x0B, //Vendor Metadata length + 0x10, //LC3Q Type + pclient_cbs[profile - 1]->get_codec_encoder_version(direction), + pclient_cbs[profile - 1]->get_codec_decoder_version(direction), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // RFU + }; encoder_version = pclient_cbs[profile - 1]->get_codec_encoder_version(direction); LOG(ERROR) << __func__ << ": codec negotiated encoder version: " << loghex(encoder_version); - if (codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_LE) { - le_vendor_config.vendorCodecType = VendorCodecType::APTX_ADAPTIVE_R3; - LOG(ERROR) << __func__ << ": AptX LE metadata params are updated"; - le_vendor_config.codecSpecificData = - { 0x0F, //Vendor Metadata Length - 0xFF, //Vendor META data type - 0x0A, //Qtil ID - 0x00, - 0x0B, //Vendor Metadata length - 0x11, //AptX Adaptive LE Type - pclient_cbs[profile - 1]->get_codec_encoder_version(direction), - pclient_cbs[profile - 1]->get_codec_decoder_version(direction), - pclient_cbs[profile - 1]->get_min_sup_frame_dur(direction), - pclient_cbs[profile - 1]->get_feature_map(direction), - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // RFU - }; - } else if (codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_R4) { + if (codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_LE || + codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_R4) { + le_vendor_config.codecSpecificData[5] = 0x11; // Aptx Adaptive Type + le_vendor_config.codecSpecificData[8] = pclient_cbs[profile - 1]->get_min_sup_frame_dur(direction); + le_vendor_config.codecSpecificData[9] = pclient_cbs[profile - 1]->get_feature_map(direction); + if (codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_R4) { le_vendor_config.vendorCodecType = VendorCodecType::APTX_ADAPTIVE_R4; + LOG(ERROR) << __func__ << ": AptX R4 metadata params are updated"; for (int i = 0; i < 4; i++) { - /* le_vendor_config.codecSpecificData.push_back((pclient_cbs[profile - 1]->get_mode_cb(direction) & - (0xff <<((3 - i)*8))) >> ((3 - i)*8)); */ - /* >> XPAN Testing Purpose Only */ - le_vendor_config.codecSpecificData.push_back((0x02 & (0xff <<((3 - i)*8))) >> ((3 - i)*8)); - /* << XPAN Testing Purpose Only */ + le_vendor_config.codecSpecificData.push_back((pclient_cbs[profile - 1]->get_mode_cb() & + (0xff <<((3 - i)*8))) >> ((3 - i)*8)); + } + for (int i = 4; i < 6; i++) { + le_vendor_config.codecSpecificData.push_back((unicastSinkClientInterface->GetRemoteDelay() & + (0xff <<((5 - i)*8))) >> ((5 - i)*8)); } - le_vendor_config.codecSpecificData.push_back(0x0F); //Vendor Metadata Length - le_vendor_config.codecSpecificData.push_back(0xFF); //Vendor META data type - le_vendor_config.codecSpecificData.push_back(0x0A); //Qtil ID - le_vendor_config.codecSpecificData.push_back(0x00); - le_vendor_config.codecSpecificData.push_back(0x0B); //Vendor Metadata length - le_vendor_config.codecSpecificData.push_back(0x11);//Vendor META data type - Supported features for AptX - le_vendor_config.codecSpecificData.push_back(pclient_cbs[profile - 1]->get_codec_encoder_version(direction)); - le_vendor_config.codecSpecificData.push_back(pclient_cbs[profile - 1]->get_codec_decoder_version(direction)); - le_vendor_config.codecSpecificData.push_back(pclient_cbs[profile - 1]->get_min_sup_frame_dur(direction)); - le_vendor_config.codecSpecificData.push_back(pclient_cbs[profile - 1]->get_feature_map(direction)); - le_vendor_config.codecSpecificData.push_back(0x00); - le_vendor_config.codecSpecificData.push_back(0x00); - le_vendor_config.codecSpecificData.push_back(0x00); - le_vendor_config.codecSpecificData.push_back(0x00); - le_vendor_config.codecSpecificData.push_back(0x00); - le_vendor_config.codecSpecificData.push_back(0x00); + } else { + le_vendor_config.vendorCodecType = VendorCodecType::APTX_ADAPTIVE_R3; + LOG(ERROR) << __func__ << ": AptX LE metadata params are updated"; + } } else { is_lc3q_supported = true; le_vendor_config.vendorCodecType = VendorCodecType::LC3Q; LOG(ERROR) << __func__ << ": Lc3q params are updated"; - le_vendor_config.codecSpecificData = - { 0x0F, //Vendor Metadata Length - 0xFF, //Vendor META data type - 0x0A, //Qtil ID - 0x00, - 0x0B, //Vendor Metadata length - 0x10, //LC3Q Type - pclient_cbs[profile - 1]->get_codec_encoder_version(direction), - pclient_cbs[profile - 1]->get_codec_decoder_version(direction), - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // RFU - }; } for (int i = 0; i < 16; i++) { @@ -1212,6 +1195,28 @@ size_t btif_ahim_read(uint8_t* p_buf, uint32_t len) { return bluetooth::audio::aidl::a2dp::read(p_buf, len); } +void btif_ahim_update_audio_config() { + AudioConfigurationAIDL lea_tx_config, lea_rx_config; + CodecIndex codec_type = + (CodecIndex) pclient_cbs[AUDIO_GROUP_MGR - 1]->get_codec_type(TX_ONLY_CONFIG); + if (codec_type == CodecIndex::CODEC_INDEX_SOURCE_APTX_ADAPTIVE_R4) { + if (!leAudio_get_selected_hal_codec_config(&lea_tx_config, AUDIO_GROUP_MGR, + TX_ONLY_CONFIG)) { + LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration"; + return; + } + if(unicastSinkClientInterface) + unicastSinkClientInterface->UpdateAudioConfigToHal(lea_tx_config); + } +} + +uint16_t btif_ahim_get_remote_delay() { +if(unicastSinkClientInterface) + return unicastSinkClientInterface->GetRemoteDelay(); +else + return 0xFFFF; +} + void btif_ahim_set_remote_delay(uint16_t delay_report, uint8_t profile) { BTIF_TRACE_IMP("%s: AIDL, profile: %d, delay_report: %d", __func__, profile, delay_report); @@ -1236,7 +1241,6 @@ void btif_ahim_set_remote_delay(uint16_t delay_report, uint8_t profile) { if(unicastSourceClientInterface) unicastSourceClientInterface->SetRemoteDelay(delay_report); } - } else if (profile == BROADCAST) { if (broadcastSinkClientInterface) { broadcastSinkClientInterface->SetRemoteDelay(delay_report); diff --git a/btif/src/btif_ble_scanner.cc b/btif/src/btif_ble_scanner.cc index 883c98077..1754a822a 100644 --- a/btif/src/btif_ble_scanner.cc +++ b/btif/src/btif_ble_scanner.cc @@ -349,7 +349,7 @@ class BleScannerInterfaceImpl : public BleScannerInterface { void StartSync(uint8_t sid, RawAddress address, uint16_t skip, uint16_t timeout, StartSyncCb start_cb, SyncReportCb report_cb, - SyncLostCb lost_cb) override { + SyncLostCb lost_cb, BigInfoReportCb biginfo_report_cb) override { const controller_t* controller = controller_get_interface(); if (!controller->supports_ble_periodic_sync_transfer()) { uint8_t status_no_resource = 2; @@ -359,7 +359,8 @@ class BleScannerInterfaceImpl : public BleScannerInterface { base::Bind(&BTM_BleStartPeriodicSync, sid, address, skip, timeout, jni_thread_wrapper(FROM_HERE, std::move(start_cb)), jni_thread_wrapper(FROM_HERE, std::move(report_cb)), - jni_thread_wrapper(FROM_HERE, std::move(lost_cb)))); + jni_thread_wrapper(FROM_HERE, std::move(lost_cb)), + jni_thread_wrapper(FROM_HERE, std::move(biginfo_report_cb)))); } void StartSync(uint8_t sid, RawAddress address, uint16_t skip, diff --git a/btif/src/btif_config.cc b/btif/src/btif_config.cc index b056a4fac..eaeb8e77a 100644 --- a/btif/src/btif_config.cc +++ b/btif/src/btif_config.cc @@ -16,6 +16,14 @@ * ******************************************************************************/ +/****************************************************************************** + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause-Clear + * + *****************************************************************************/ + #define LOG_TAG "bt_btif_config" #include "btif_config.h" @@ -81,6 +89,7 @@ static void timer_config_save_cb(void* data); static void btif_config_write(uint16_t event, char* p_param); static bool is_factory_reset(void); static void delete_config_files(void); +static void btif_config_file_update(config_t* config); static void btif_config_remove_unpaired(config_t* config); static void btif_config_remove_restricted(config_t* config); @@ -674,19 +683,77 @@ static void btif_config_write(UNUSED_ATTR uint16_t event, std::unique_lock<std::recursive_mutex> lock(config_lock); rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH); - config_t* config_paired = config_new_clone(config); - if (config_paired != NULL) { - btif_config_remove_unpaired(config_paired); - config_save(config_paired, CONFIG_FILE_PATH); - config_free(config_paired); - } + btif_config_file_update(config); + if (is_common_criteria_mode()) { get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key( CONFIG_FILE_PREFIX, CONFIG_FILE_HASH); } } +static void btif_config_file_update(config_t* conf) { + CHECK(conf != NULL); + int paired_devices = 0; + int entries=0; + int new_config_entries=0; + config_t* config_new_conf = config_new_empty(); + + CHECK(config_new_conf != NULL); + // The paired config used to carry information about + // discovered devices during regular inquiry scans. + // We remove these now and cache them in memory instead. + const config_section_node_t* snode = config_section_begin(conf); + + BTIF_TRACE_WARNING("%s", __func__); + + while (snode != config_section_end(conf)) { + section_t* section = config_section(snode); + entries++; + if (RawAddress::IsValidAddress(section->name)) { + if (!section_has_key(section, "LinkKey") && + !section_has_key(section, "LE_KEY_PENC") && + !section_has_key(section, "LE_KEY_PID") && + !section_has_key(section, "LE_KEY_PCSRK") && + !section_has_key(section, "LE_KEY_LENC") && + !section_has_key(section, "LE_KEY_LCSRK") && + !section_has_key(section, "AvrcpCtVersion") && + !section_has_key(section, "AvrcpFeatures") && + !section_has_key(section, "TwsPlusPeerAddr") && + !section_has_key(section, "Codecs")) { + snode = config_section_next(snode); + continue; + } + paired_devices++; + } + + if (section) { + for (const list_node_t* node_entry = list_begin(section->entries); + node_entry != list_end(section->entries); + node_entry = list_next(node_entry)) { + entry_t* entry = static_cast<entry_t*>(list_node(node_entry)); + config_set_string(config_new_conf, section->name, entry->key, entry->value); + } + } + + new_config_entries++; + snode = config_section_next(snode); + } + + BTIF_TRACE_WARNING("%s: entries: %d paired_devices: %d, new_config_entries: %d", + __func__, entries, paired_devices, new_config_entries); + + if (new_config_entries > 0) { + config_save(config_new_conf, CONFIG_FILE_PATH); + } + + config_free(config_new_conf); + + // should only happen once, at initial load time + if (btif_config_devices_loaded == -1) + btif_config_devices_loaded = paired_devices; +} + static void btif_config_remove_unpaired(config_t* conf) { CHECK(conf != NULL); int paired_devices = 0; diff --git a/btif/src/btif_core.cc b/btif/src/btif_core.cc index 44d6acb94..843b1eb66 100644 --- a/btif/src/btif_core.cc +++ b/btif/src/btif_core.cc @@ -67,6 +67,7 @@ #include "stack_manager.h" #include "device/include/device_iot_config.h" +#include "btif_ahim.h" using bluetooth::Uuid; /******************************************************************************* * Constants & Macros @@ -1449,3 +1450,8 @@ bt_status_t btif_set_dynamic_audio_buffer_size(int codec, int size) { return BT_STATUS_SUCCESS; } + +void btif_update_params(uint16_t delay, uint8_t mode) { + BTIF_TRACE_DEBUG("%s", __func__); + btif_ahim_update_params(delay, mode); +} diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc index aff83d5ca..095baba19 100644 --- a/btif/src/btif_dm.cc +++ b/btif/src/btif_dm.cc @@ -122,7 +122,7 @@ #include "device/include/device_iot_config.h" #include "stack_interface.h" #ifdef ADV_AUDIO_FEATURE -#include "btif_dm_adv_audio.h" +#include "btif/include/btif_dm_adv_audio.h" #include "bta_dm_adv_audio.h" #endif @@ -180,6 +180,7 @@ typedef struct { bt_bond_state_t state; RawAddress static_bdaddr; RawAddress bd_addr; + RawAddress lea_bd_addr; tBTM_BOND_TYPE bond_type; uint8_t pin_code_len; uint8_t is_ssp; @@ -912,7 +913,7 @@ static void btif_dm_cb_create_bond(const RawAddress& bd_addr, bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING); int device_type; - int addr_type; + int addr_type = BLE_ADDR_PUBLIC; std::string addrstr = bd_addr.ToString(); const char* bdstr = addrstr.c_str(); if (transport == BT_TRANSPORT_LE) { @@ -953,6 +954,7 @@ static void btif_dm_cb_create_bond(const RawAddress& bd_addr, __func__); btif_dm_cancel_discovery(); pairing_cb.is_adv_audio = 1; + pairing_cb.lea_bd_addr = bd_addr; } else { if ((addr_type == BLE_ADDR_RANDOM) && ((device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE)) { @@ -1440,11 +1442,23 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { if (is_crosskey) { + bt_property_t prop; + + BTIF_STORAGE_FILL_PROPERTY(&prop, + (bt_property_type_t)BT_PROPERTY_REM_DEV_IDENT_BD_ADDR, sizeof(RawAddress), &bd_addr); + + int ret = btif_storage_set_remote_device_property(&pairing_cb.bd_addr, &prop); + ASSERTC(ret == BT_STATUS_SUCCESS, "failed to save BT_PROPERTY_REM_DEV_IDENT_BD_ADDR", ret); + + HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, BT_STATUS_SUCCESS, + &pairing_cb.bd_addr, 1, &prop); + // If bonding occurred due to cross-key pairing, send bonding callback // for static address now - LOG_INFO(LOG_TAG, - "%s: send bonding state update for static address %s", - __func__, bd_addr.ToString().c_str()); + LOG_INFO(LOG_TAG, + "%s: send bonding state update for static bd_addr %s private (pairing_cb) %s ", + __func__, bd_addr.ToString().c_str(), pairing_cb.bd_addr.ToString().c_str()); + bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING); } bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDED); @@ -2806,7 +2820,7 @@ bt_status_t btif_dm_start_discovery(void) { BTIF_TRACE_EVENT("%s : pairing_cb.state: 0x%x", __FUNCTION__, pairing_cb.state); /* We should not go for inquiry in BONDING STATE. */ - if (pairing_cb.state == BT_BOND_STATE_BONDING) + if (is_bonding_or_sdp()) return BT_STATUS_BUSY; #ifdef ADV_AUDIO_FEATURE if (bta_lea_is_le_pairing()){ @@ -4417,11 +4431,13 @@ uint16_t btif_dm_get_le_links() { * ******************************************************************************/ void btif_get_pairing_cb_info(bt_bond_state_t* state, uint8_t* sdp_attempts, - RawAddress* bd_addr, RawAddress* static_bdaddr) { + RawAddress* bd_addr, RawAddress* static_bdaddr, + RawAddress* lea_bd_addr) { *state = pairing_cb.state; *bd_addr = pairing_cb.bd_addr; *sdp_attempts = pairing_cb.sdp_attempts; *static_bdaddr= pairing_cb.static_bdaddr; + *lea_bd_addr = pairing_cb.lea_bd_addr; } /******************************************************************************* @@ -4486,3 +4502,8 @@ void btif_store_adv_audio_pair_info(RawAddress bd_addr) { ret); } #endif + +void btif_dm_get_le_services(RawAddress *bd_addr, int transport) { + BTIF_TRACE_WARNING("%s %s", __func__, bd_addr->ToString().c_str()); + bta_dm_gatt_le_services(*bd_addr); +} diff --git a/btif/src/btif_hf.cc b/btif/src/btif_hf.cc index 4718a8235..eb5a92281 100644 --- a/btif/src/btif_hf.cc +++ b/btif/src/btif_hf.cc @@ -1117,7 +1117,10 @@ static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) { if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) || (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED))) i++; - else + else if(!((btif_hf_cb[i].handle > 0) && (btif_hf_cb[i].handle <= btif_max_hf_clients))){ + BTIF_TRACE_WARNING("%s: index %d, handle %d, not correct", __func__, i, btif_hf_cb[i].handle); + i++; + }else break; } diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc index a15b63c87..650f69b54 100644 --- a/btif/src/btif_rc.cc +++ b/btif/src/btif_rc.cc @@ -5145,6 +5145,12 @@ static void handle_app_attr_val_txt_response( } p_app_settings->ext_val_index++; + if (p_app_settings->ext_val_index >= AVRC_MAX_APP_ATTR_SIZE) { + BTIF_TRACE_ERROR("%s: ext_val_index is 0x%02x, overflow!", + __func__, p_app_settings->ext_val_index); + return; + } + if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs) { attr_index = p_app_settings->ext_val_index; for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) { diff --git a/btif/src/btif_sock_rfc.cc b/btif/src/btif_sock_rfc.cc index a4ad07349..748c1723c 100644 --- a/btif/src/btif_sock_rfc.cc +++ b/btif/src/btif_sock_rfc.cc @@ -215,7 +215,11 @@ static rfc_slot_t* alloc_rfc_slot(const RawAddress* addr, const char* name, } // Increment slot id and make sure we don't use id=0. - if (++rfc_slot_id == 0) rfc_slot_id = 1; + if (UINT32_MAX == rfc_slot_id) { + rfc_slot_id = 1; + } else { + ++rfc_slot_id; + } slot->fd = fds[0]; slot->app_fd = fds[1]; diff --git a/btif/src/btif_sock_sdp.cc b/btif/src/btif_sock_sdp.cc index ef8ca4fe2..ff577fb76 100644 --- a/btif/src/btif_sock_sdp.cc +++ b/btif/src/btif_sock_sdp.cc @@ -492,7 +492,7 @@ bool is_reserved_rfc_channel(const int channel) { return true; } /* Code to check number of email instances in use */ - char no_of_email_instance[2] = {0}; + char no_of_email_instance[PROPERTY_VALUE_MAX] = {0}; osi_property_get(NO_OF_EMAIL_ACCOUNTS_PROPERTY, no_of_email_instance, DEFAULT_ACTIVE_ACCOUNTS); if (channel > RESERVED_SCN_MAP && channel <= (RESERVED_SCN_MAP + atoi(no_of_email_instance))) { diff --git a/btif/src/btif_storage.cc b/btif/src/btif_storage.cc index 26e9395ae..825e05626 100644 --- a/btif/src/btif_storage.cc +++ b/btif/src/btif_storage.cc @@ -1369,15 +1369,13 @@ bt_status_t btif_storage_load_bonded_devices(void) { remote_properties[num_props]); num_props++; - char addr_map[1024] = ""; - int addr_len = RawAddress::kLength; - BTIF_STORAGE_GET_REMOTE_PROP(p_remote_addr, (bt_property_type_t)BT_PROPERTY_REM_DEV_IDENT_BD_ADDR, - addr_map, addr_len, - remote_properties[num_props]); - RawAddress::FromString(addr_map, mapping_addr); - remote_properties[num_props].val = &mapping_addr; - remote_properties[num_props].len = RawAddress::kLength; - num_props++; + RawAddress map_addr = btif_get_map_address(*p_remote_addr); + if (map_addr != RawAddress::kEmpty) { + remote_properties[num_props].type = (bt_property_type_t)BT_PROPERTY_REM_DEV_IDENT_BD_ADDR; + remote_properties[num_props].val = &map_addr; + remote_properties[num_props].len = sizeof(RawAddress); + num_props++; + } btif_storage_get_remote_services(p_remote_addr, remote_uuids, sizeof(remote_uuids)); diff --git a/device/include/interop.h b/device/include/interop.h index f3d0d36f7..f188cec0b 100644 --- a/device/include/interop.h +++ b/device/include/interop.h @@ -298,6 +298,17 @@ typedef enum { // local device to be only master as role switch would be restricted during connection. INTEROP_DISABLE_ROLE_SWITCH_DURING_CONNECTION, + //Add remote device into L2CAP_DISCONNECT_ACL_DIRECTLY blacklist + INTEROP_L2CAP_DISCONNECT_ACL_DIRECTLY, + + // Skip Robust Caching Read of client supported featuresc characteristic for specific devices + // Some remote devices do not respond to ATT_READ_BY_TYPE_REQ(for Client Supported Features + // characteristic) sent by local device for Robust caching support and this results in + // GATT response timeout and LE link disconnection. This interop arrangement will make local + // device to skip reading of Client supported features characteristic with devices in the + // interop list. + INTEROP_SKIP_ROBUST_CACHING_READ, + END_OF_INTEROP_LIST } interop_feature_t; diff --git a/device/src/controller.cc b/device/src/controller.cc index 06d8a3210..6a16ca915 100644 --- a/device/src/controller.cc +++ b/device/src/controller.cc @@ -274,7 +274,7 @@ bool is_soc_lpa_enh_pwr_enabled() { static future_t* start_up(void) { BT_HDR* response; uint8_t adv_audio_support_mask = 0; - char adv_audio_property[2] = {}; + char adv_audio_property[PROPERTY_VALUE_MAX] = {0}; osi_property_get("persist.vendor.service.bt.adv_audio_mask", adv_audio_property, "0"); adv_audio_support_mask = (uint8_t)atoi(adv_audio_property); diff --git a/include/hardware/ble_scanner.h b/include/hardware/ble_scanner.h index 393963328..b8b672810 100644 --- a/include/hardware/ble_scanner.h +++ b/include/hardware/ble_scanner.h @@ -125,9 +125,13 @@ class BleScannerInterface { base::Callback<void(uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data)>; using SyncLostCb = base::Callback<void(uint16_t sync_handle)>; + + using BigInfoReportCb = base::Callback<void(uint16_t sync_handle, bool encrypted)>; + virtual void StartSync(uint8_t sid, RawAddress address, uint16_t skip, uint16_t timeout, StartSyncCb start_cb, - SyncReportCb report_cb, SyncLostCb lost_cb) = 0; + SyncReportCb report_cb, SyncLostCb lost_cb, + BigInfoReportCb biginfo_report_cb) = 0; virtual void StopSync(uint16_t handle) = 0; #if (BLE_PS_PAST_IF_SUPPORTED == TRUE) virtual void CancelCreateSync(uint8_t sid, RawAddress address) = 0; diff --git a/osi/include/config.h b/osi/include/config.h index 6c41f87d5..55d81f68e 100644 --- a/osi/include/config.h +++ b/osi/include/config.h @@ -33,6 +33,11 @@ typedef struct { list_t* entries; } section_t; +typedef struct { + char* key; + char* value; +} entry_t; + #if (BT_IOT_LOGGING_ENABLED == TRUE) typedef int (*compare_func)(const char* first, const char* second); #endif diff --git a/osi/src/config.cc b/osi/src/config.cc index 65eb0dfeb..9fe6bfb94 100644 --- a/osi/src/config.cc +++ b/osi/src/config.cc @@ -16,6 +16,14 @@ * ******************************************************************************/ +/****************************************************************************** + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause-Clear + * +*****************************************************************************/ + #define LOG_TAG "bt_osi_config" #include "osi/include/config.h" @@ -40,11 +48,6 @@ #include "bt_target.h" #include <inttypes.h> -typedef struct { - char* key; - char* value; -} entry_t; - struct config_t { list_t* sections; }; @@ -382,7 +385,7 @@ bool section_has_key(const section_t* section, if (!strcmp(entry->key, key)) return true; } - return false;; + return false; } #if (BT_IOT_LOGGING_ENABLED == TRUE) diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc index 0b0af3555..8b61db886 100644 --- a/stack/a2dp/a2dp_sbc.cc +++ b/stack/a2dp/a2dp_sbc.cc @@ -918,6 +918,11 @@ bool A2DP_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t* p_codec_info, return false; } + // there is a timestamp right following p_buf + if (p_buf->offset < 4 + A2DP_SBC_MPL_HDR_LEN) { + return false; + } + p_buf->offset -= A2DP_SBC_MPL_HDR_LEN; uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset; p_buf->len += A2DP_SBC_MPL_HDR_LEN; diff --git a/stack/avdt/avdt_scb_act.cc b/stack/avdt/avdt_scb_act.cc index ca713ce91..fc354068a 100644 --- a/stack/avdt/avdt_scb_act.cc +++ b/stack/avdt/avdt_scb_act.cc @@ -1239,6 +1239,10 @@ void avdt_scb_hdl_write_req(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) { /* Build a media packet, and add an RTP header if required. */ if (add_rtp_header) { AVDT_TRACE_DEBUG("%s:add rtp header",__func__); + if (p_data->apiwrite.p_buf->offset < AVDT_MEDIA_HDR_SIZE) { + android_errorWriteWithInfoLog(0x534e4554, "242535997", -1, NULL, 0); + return; + } ssrc = avdt_scb_gen_ssrc(p_scb); p_data->apiwrite.p_buf->len += AVDT_MEDIA_HDR_SIZE; diff --git a/stack/avrc/avrc_pars_ct.cc b/stack/avrc/avrc_pars_ct.cc index 2cae55b21..91c22108e 100644 --- a/stack/avrc/avrc_pars_ct.cc +++ b/stack/avrc/avrc_pars_ct.cc @@ -378,8 +378,14 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, /* Parse the name now */ BE_STREAM_TO_UINT16(attr_entry->name.charset_id, p); BE_STREAM_TO_UINT16(attr_entry->name.str_len, p); + if (static_cast<uint16_t>(min_len + attr_entry->name.str_len) < + min_len) { + // Check for overflow + android_errorWriteLog(0x534e4554, "205570663"); + } + if (pkt_len - min_len < attr_entry->name.str_len) + goto browse_length_error; min_len += attr_entry->name.str_len; - if (pkt_len < min_len) goto browse_length_error; attr_entry->name.p_str = (uint8_t*)osi_malloc( attr_entry->name.str_len * sizeof(uint8_t)); BE_STREAM_TO_ARRAY(p, attr_entry->name.p_str, @@ -782,8 +788,12 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p); BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p); BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p); - min_len += p_attrs[i].name.str_len; - if (len < min_len) { + if (static_cast<uint16_t>(min_len + p_attrs[i].name.str_len) < + min_len) { + // Check for overflow + android_errorWriteLog(0x534e4554, "205570663"); + } + if (len - min_len < p_attrs[i].name.str_len) { for (int j = 0; j < i; j++) { osi_free(p_attrs[j].name.p_str); } @@ -791,6 +801,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, p_result->get_attrs.num_attrs = 0; goto length_error; } + min_len += p_attrs[i].name.str_len; if (p_attrs[i].name.str_len > 0) { p_attrs[i].name.p_str = (uint8_t*)osi_calloc(p_attrs[i].name.str_len); diff --git a/stack/btm/btm_acl.cc b/stack/btm/btm_acl.cc index 240096f0f..eb8b530ce 100644 --- a/stack/btm/btm_acl.cc +++ b/stack/btm/btm_acl.cc @@ -2520,7 +2520,7 @@ void btm_read_tx_power_timeout(UNUSED_ATTR void* data) { * Returns void * ******************************************************************************/ -void btm_read_tx_power_complete(uint8_t* p, bool is_ble) { +void btm_read_tx_power_complete(uint8_t* p, uint16_t evt_len, bool is_ble) { tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_tx_power_cmpl_cb; tBTM_TX_POWER_RESULT result; tACL_CONN* p_acl_cb = &btm_cb.acl_db[0]; @@ -2531,6 +2531,10 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) { /* If there was a registered callback, call it */ if (p_cb) { + if (evt_len < 1) { + goto err_out; + } + STREAM_TO_UINT8(result.hci_status, p); if (result.hci_status == HCI_SUCCESS) { @@ -2538,6 +2542,11 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) { if (!is_ble) { uint16_t handle; + + if (evt_len < 4) { + goto err_out; + } + STREAM_TO_UINT16(handle, p); STREAM_TO_UINT8(result.tx_power, p); @@ -2549,6 +2558,10 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) { } } } else { + if (evt_len < 2) { + goto err_out; + } + STREAM_TO_UINT8(result.tx_power, p); result.rem_bda = btm_cb.devcb.read_tx_pwr_addr; } @@ -2560,6 +2573,11 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) { (*p_cb)(&result); } + + return; + + err_out: + BTM_TRACE_ERROR(" %s Bogus event packet, too short", __func__); } /******************************************************************************* @@ -2589,7 +2607,7 @@ void btm_read_rssi_timeout(UNUSED_ATTR void* data) { * Returns void * ******************************************************************************/ -void btm_read_rssi_complete(uint8_t* p) { +void btm_read_rssi_complete(uint8_t* p, uint16_t evt_len) { tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_rssi_cmpl_cb; tBTM_RSSI_RESULT result; tACL_CONN* p_acl_cb = &btm_cb.acl_db[0]; @@ -2600,10 +2618,19 @@ void btm_read_rssi_complete(uint8_t* p) { /* If there was a registered callback, call it */ if (p_cb) { + if (evt_len < 1) { + goto err_out; + } + STREAM_TO_UINT8(result.hci_status, p); if (result.hci_status == HCI_SUCCESS) { uint16_t handle; + + if (evt_len < 4) { + goto err_out; + } + result.status = BTM_SUCCESS; STREAM_TO_UINT16(handle, p); @@ -2625,6 +2652,11 @@ void btm_read_rssi_complete(uint8_t* p) { (*p_cb)(&result); } + + return; + +err_out: + BTM_TRACE_ERROR("Bogus event packet, too short"); } /******************************************************************************* @@ -2786,7 +2818,7 @@ void btm_read_link_quality_timeout(UNUSED_ATTR void* data) { * Returns void * ******************************************************************************/ -void btm_read_link_quality_complete(uint8_t* p) { +void btm_read_link_quality_complete(uint8_t* p, uint16_t evt_len) { tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_link_qual_cmpl_cb; tBTM_LINK_QUALITY_RESULT result; tACL_CONN* p_acl_cb = &btm_cb.acl_db[0]; @@ -2797,12 +2829,20 @@ void btm_read_link_quality_complete(uint8_t* p) { /* If there was a registered callback, call it */ if (p_cb) { + if (evt_len < 1) { + goto err_out; + } + STREAM_TO_UINT8(result.hci_status, p); if (result.hci_status == HCI_SUCCESS) { uint16_t handle; result.status = BTM_SUCCESS; + if (evt_len < 4) { + goto err_out; + } + STREAM_TO_UINT16(handle, p); STREAM_TO_UINT8(result.link_quality, p); @@ -2823,6 +2863,11 @@ void btm_read_link_quality_complete(uint8_t* p) { (*p_cb)(&result); } + + return; + +err_out: + BTM_TRACE_ERROR("Bogus Link Quality event packet, size: %d", evt_len); } /******************************************************************************* diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc index d1e6f496f..f2dc1adef 100644 --- a/stack/btm/btm_ble.cc +++ b/stack/btm/btm_ble.cc @@ -1286,7 +1286,7 @@ tL2CAP_LE_RESULT_CODE btm_ble_start_sec_check(const RawAddress& bd_addr, * Returns void * ******************************************************************************/ -void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code, +void btm_ble_rand_enc_complete(uint8_t* p, uint16_t evt_len, uint16_t op_code, tBTM_RAND_ENC_CB* p_enc_cplt_cback) { tBTM_RAND_ENC params; uint8_t* p_dest = params.param_buf; @@ -1297,6 +1297,11 @@ void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code, /* If there was a callback address for vcs complete, call it */ if (p_enc_cplt_cback && p) { + + if (evt_len < 1) { + goto err_out; + } + /* Pass paramters to the callback function */ STREAM_TO_UINT8(params.status, p); /* command status */ @@ -1307,6 +1312,9 @@ void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code, params.param_len = BT_OCTET8_LEN; else params.param_len = OCTET16_LEN; + if (evt_len < 1 + params.param_len) { + goto err_out; + } /* Fetch return info from HCI event message */ memcpy(p_dest, p, params.param_len); @@ -1314,6 +1322,11 @@ void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code, if (p_enc_cplt_cback) /* Call the Encryption complete callback function */ (*p_enc_cplt_cback)(¶ms); } + + return; + +err_out: + BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__); } /******************************************************************************* diff --git a/stack/btm/btm_ble_gap.cc b/stack/btm/btm_ble_gap.cc index 7dd2d74dd..345e10ed1 100644 --- a/stack/btm/btm_ble_gap.cc +++ b/stack/btm/btm_ble_gap.cc @@ -164,6 +164,8 @@ using SyncReportCb = uint8_t /*status*/, std::vector<uint8_t> /*data*/)>; using SyncLostCb = base::Callback<void(uint16_t /*sync_handle*/)>; using SyncTransferCb = base::Callback<void(uint8_t /*status*/, RawAddress)>; +using BigInfoReportCb = base::Callback<void(uint16_t /*sync_handle*/, bool /*encrypted*/)>; + #define MAX_SYNC_TRANSACTION 16 #define SYNC_TIMEOUT (30 * 1000) #define ADV_SYNC_ESTB_EVT_LEN 16 @@ -185,6 +187,7 @@ typedef struct { StartSyncCb sync_start_cb; SyncReportCb sync_report_cb; SyncLostCb sync_lost_cb; + BigInfoReportCb biginfo_report_cb; } tBTM_BLE_PERIODIC_SYNC; typedef struct { @@ -1272,7 +1275,8 @@ void btm_ble_periodic_adv_sync_lost(uint8_t *param, uint16_t param_len) { ******************************************************************************/ void BTM_BleStartPeriodicSync(uint8_t adv_sid, RawAddress address, uint16_t skip, - uint16_t timeout, StartSyncCb syncCb, SyncReportCb reportCb, SyncLostCb lostCb) { + uint16_t timeout, StartSyncCb syncCb, SyncReportCb reportCb, SyncLostCb lostCb, + BigInfoReportCb biginfo_reportCb) { BTM_TRACE_DEBUG("[PSync]%s",__func__); int index = btm_ble_get_free_psync_index(); tBTM_BLE_PERIODIC_SYNC *p = &btm_ble_pa_sync_cb.p_sync[index]; @@ -1286,6 +1290,7 @@ void BTM_BleStartPeriodicSync(uint8_t adv_sid, RawAddress address, uint16_t skip p->sync_start_cb = syncCb; p->sync_report_cb = reportCb; p->sync_lost_cb = lostCb; + p->biginfo_report_cb = biginfo_reportCb; btm_queue_start_sync_req(adv_sid, address, skip, timeout); } @@ -1484,6 +1489,14 @@ void btm_ble_biginfo_adv_report_rcvd(uint8_t *p, uint16_t param_len) { "sdu_interval = %d, max_sdu = %d, phy = %d, framing = %d, encryption = %d", __func__, sync_handle, num_bises, nse, iso_interval, bn, pto, irc, max_pdu, sdu_interval, max_sdu, phy, framing, encryption); + int index = btm_ble_get_psync_index_from_handle(sync_handle); + if (index == MAX_SYNC_TRANSACTION) { + BTM_TRACE_ERROR("[PSync]%s: index not found", __func__); + return; + } + tBTM_BLE_PERIODIC_SYNC *ps = &btm_ble_pa_sync_cb.p_sync[index]; + BTM_TRACE_DEBUG("[PSync]%s: invoking callback", __func__); + ps->biginfo_report_cb.Run(sync_handle, encryption ? true: false); } /******************************************************************************* @@ -2669,12 +2682,7 @@ void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type, BTM_TRACE_DEBUG("BR/EDR NOT support bit not set, treat as DUMO"); p_cur->device_type |= BT_DEVICE_TYPE_DUMO; } else { - if ((p_cur->flag & BTM_BLE_DMT_HOST_SPT) != 0) { - p_cur->device_type |= BT_DEVICE_TYPE_DUMO; - BTM_TRACE_DEBUG("Random address, -- treating device as DUMO only"); - } else { BTM_TRACE_DEBUG("Random address, treating device as LE only"); - } } } else { BTM_TRACE_DEBUG("BR/EDR NOT SUPPORT bit set, LE only device"); @@ -3332,11 +3340,16 @@ void btm_ble_refresh_raddr_timer_timeout(UNUSED_ATTR void* data) { * Returns void * ******************************************************************************/ -void btm_ble_read_remote_features_complete(uint8_t* p) { +void btm_ble_read_remote_features_complete(uint8_t* p, uint8_t length) { BTM_TRACE_EVENT("%s", __func__); - uint16_t handle; uint8_t status; + int idx; + + if (length < 3) { + goto err_out; + } + STREAM_TO_UINT8(status, p); STREAM_TO_UINT16(handle, p); handle = handle & 0x0FFF; // only 12 bits meaningful @@ -3347,13 +3360,19 @@ void btm_ble_read_remote_features_complete(uint8_t* p) { if (status != HCI_ERR_UNSUPPORTED_REM_FEATURE) return; } - int idx = btm_handle_to_acl_index(handle); + idx = btm_handle_to_acl_index(handle); if (idx == MAX_L2CAP_LINKS) { BTM_TRACE_ERROR("%s: can't find acl for handle: 0x%04x", __func__, handle); return; } if (status == HCI_SUCCESS) { + // BD_FEATURES_LEN additional bytes are read + // in acl_set_peer_le_features_from_handle + if (length < 3 + BD_FEATURES_LEN) { + goto err_out; + } + STREAM_TO_ARRAY(btm_cb.acl_db[idx].peer_le_features, p, BD_FEATURES_LEN); #if (BT_IOT_LOGGING_ENABLED == TRUE) /* save LE remote supported features to iot conf file */ @@ -3367,6 +3386,10 @@ void btm_ble_read_remote_features_complete(uint8_t* p) { } btsnd_hcic_rmt_ver_req(handle); + return; + +err_out: + BTM_TRACE_ERROR("%s: bogus event packet, too short", __func__); } /******************************************************************************* @@ -3378,11 +3401,11 @@ void btm_ble_read_remote_features_complete(uint8_t* p) { * Returns void * ******************************************************************************/ -void btm_ble_write_adv_enable_complete(uint8_t* p) { +void btm_ble_write_adv_enable_complete(uint8_t* p, uint16_t evt_len) { tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; /* if write adv enable/disbale not succeed */ - if (*p != HCI_SUCCESS) { + if (evt_len < 1 || *p != HCI_SUCCESS) { /* toggle back the adv mode */ p_cb->adv_mode = !p_cb->adv_mode; } diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h index b201fe63e..09d407f75 100644 --- a/stack/btm/btm_ble_int.h +++ b/stack/btm/btm_ble_int.h @@ -67,8 +67,8 @@ extern void btm_ble_init(void); extern void btm_ble_connected(const RawAddress& bda, uint16_t handle, uint8_t enc_mode, uint8_t role, tBLE_ADDR_TYPE addr_type, bool addr_matched); -extern void btm_ble_read_remote_features_complete(uint8_t* p); -extern void btm_ble_write_adv_enable_complete(uint8_t* p); +extern void btm_ble_read_remote_features_complete(uint8_t* p, uint8_t length); +extern void btm_ble_write_adv_enable_complete(uint8_t* p, uint16_t evt_len); extern void btm_ble_conn_complete(uint8_t* p, uint16_t evt_len, bool enhanced); extern void btm_read_ble_local_supported_states_complete(uint8_t* p, uint16_t evt_len); @@ -116,7 +116,7 @@ extern bool btm_ble_get_enc_key_type(const RawAddress& bd_addr, uint8_t* p_key_types); extern void btm_ble_test_command_complete(uint8_t* p); -extern void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code, +extern void btm_ble_rand_enc_complete(uint8_t* p, uint16_t evt_len, uint16_t op_code, tBTM_RAND_ENC_CB* p_enc_cplt_cback); extern void btm_sec_save_le_key(const RawAddress& bd_addr, diff --git a/stack/btm/btm_ble_privacy.cc b/stack/btm/btm_ble_privacy.cc index 7a43f7245..177697584 100644 --- a/stack/btm/btm_ble_privacy.cc +++ b/stack/btm/btm_ble_privacy.cc @@ -221,6 +221,12 @@ bool clear_resolving_list_bit(void* data, void* context) { ******************************************************************************/ void btm_ble_clear_resolving_list_complete(uint8_t* p, uint16_t evt_len) { uint8_t status = 0; + + if (evt_len < 1) { + BTM_TRACE_ERROR("malformatted event packet: containing zero bytes"); + return; + } + STREAM_TO_UINT8(status, p); BTM_TRACE_DEBUG("%s status=%d", __func__, status); @@ -265,6 +271,12 @@ void btm_ble_clear_resolving_list_complete(uint8_t* p, uint16_t evt_len) { ******************************************************************************/ void btm_ble_add_resolving_list_entry_complete(uint8_t* p, uint16_t evt_len) { uint8_t status; + + if (evt_len < 1) { + BTM_TRACE_ERROR("malformatted event packet: containing zero bytes"); + return; + } + STREAM_TO_UINT8(status, p); BTM_TRACE_DEBUG("%s status = %d", __func__, status); diff --git a/stack/btm/btm_devctl.cc b/stack/btm/btm_devctl.cc index 302e66a76..0e0ef828a 100644 --- a/stack/btm/btm_devctl.cc +++ b/stack/btm/btm_devctl.cc @@ -44,6 +44,7 @@ #include "gatt_int.h" #include "hci/include/vendor.h" +#include "btif/include/btif_api.h" extern thread_t* bt_workqueue_thread; @@ -61,6 +62,7 @@ extern thread_t* bt_workqueue_thread; */ #define BTM_INFO_TIMEOUT 5 /* 5 seconds for info response */ +#define HCI_VSE_SUBCODE_PARAMS_REPORT 0x12 /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ @@ -882,49 +884,59 @@ void btm_vendor_specific_evt(uint8_t* p, uint8_t evt_len) { uint8_t *pp = p; uint8_t vse_subcode; - STREAM_TO_UINT8 (vse_subcode, pp); + if (evt_len >= 2) { + STREAM_TO_UINT8 (vse_subcode, pp); - if(HCI_VSE_INFO_REPORT == vse_subcode) { - BTM_TRACE_DEBUG ("BTM Event: Vendor Specific iot info report event"); - if (btm_cb.devcb.p_vnd_iot_info_cb) { - BTM_TRACE_DEBUG ("Calling bta_dm_vnd_info_report_cback"); - (*btm_cb.devcb.p_vnd_iot_info_cb)(evt_len, pp); - return; - } - } else if (HCI_BT_SOC_CRASHED_OGF == vse_subcode) { - STREAM_TO_UINT8 (vse_subcode, pp); - if (HCI_BT_SOC_CRASHED_OCF == vse_subcode) { - decode_crash_reason(pp, (evt_len - 2)); + if(HCI_VSE_INFO_REPORT == vse_subcode) { + BTM_TRACE_DEBUG ("BTM Event: Vendor Specific iot info report event"); + if (btm_cb.devcb.p_vnd_iot_info_cb) { + BTM_TRACE_DEBUG ("Calling bta_dm_vnd_info_report_cback"); + (*btm_cb.devcb.p_vnd_iot_info_cb)(evt_len, pp); return; } - } else if (HCI_VSE_SUBCODE_QBCE == vse_subcode) { - uint8_t vse_msg_type; - - STREAM_TO_UINT8(vse_msg_type, pp); - BTM_TRACE_DEBUG("%s: QBCE VSE event received, msg = %x", __func__, - vse_msg_type); - switch(vse_msg_type) { - case MSG_QBCE_QLL_CONNECTION_COMPLETE: - btm_ble_qll_connection_complete(pp); - break; - case MSG_QBCE_REMOTE_SUPPORTED_QLL_FEATURES_COMPLETE: - btm_ble_read_remote_supported_qll_features_complete(pp); - break; - case MSG_QBCE_QCM_PHY_CHANGE: - btm_acl_update_qcm_phy_state(pp); - break; - case MSG_QBCE_QLE_CIG_LATENCY_CHANGED: - if (btm_cb.devcb.p_vnd_qle_cig_latency_changed_cb) { - BTM_TRACE_DEBUG ("Calling qle_cig_latency_changed_cb"); - (*btm_cb.devcb.p_vnd_qle_cig_latency_changed_cb)((evt_len - 2), pp); + } else if (HCI_BT_SOC_CRASHED_OGF == vse_subcode) { + STREAM_TO_UINT8 (vse_subcode, pp); + if (HCI_BT_SOC_CRASHED_OCF == vse_subcode) { + decode_crash_reason(pp, (evt_len - 2)); return; } - break; - default: - BTM_TRACE_ERROR("%s: unknown msg type: %d", __func__, vse_msg_type); - break; + } else if (HCI_VSE_SUBCODE_QBCE == vse_subcode) { + uint8_t vse_msg_type; + + STREAM_TO_UINT8(vse_msg_type, pp); + BTM_TRACE_DEBUG("%s: QBCE VSE event received, msg = %x", __func__, + vse_msg_type); + switch(vse_msg_type) { + case MSG_QBCE_QLL_CONNECTION_COMPLETE: + btm_ble_qll_connection_complete(pp); + break; + case MSG_QBCE_REMOTE_SUPPORTED_QLL_FEATURES_COMPLETE: + btm_ble_read_remote_supported_qll_features_complete(pp); + break; + case MSG_QBCE_QCM_PHY_CHANGE: + btm_acl_update_qcm_phy_state(pp); + break; + case MSG_QBCE_QLE_CIG_LATENCY_CHANGED: + if (btm_cb.devcb.p_vnd_qle_cig_latency_changed_cb) { + BTM_TRACE_DEBUG ("Calling qle_cig_latency_changed_cb"); + (*btm_cb.devcb.p_vnd_qle_cig_latency_changed_cb)((evt_len - 2), pp); + return; + } + break; + default: + BTM_TRACE_ERROR("%s: unknown msg type: %d", __func__, vse_msg_type); + break; + } + return; + } else if (HCI_VSE_SUBCODE_PARAMS_REPORT == vse_subcode){ + BTM_TRACE_DEBUG ("BTM Event: Vendor Specific params report evt"); + uint16_t delay; + uint8_t mode; + STREAM_TO_UINT16(delay, pp); + STREAM_TO_UINT8(mode, pp); + BTM_TRACE_DEBUG ("%s: Delay value = %x, Mode value = %x", __func__, delay, mode); + btif_update_params(delay, mode); } - return; } BTM_TRACE_DEBUG("BTM Event: Vendor Specific event from controller"); diff --git a/stack/btm/btm_inq.cc b/stack/btm/btm_inq.cc index 22a2182dc..d9f879626 100644 --- a/stack/btm/btm_inq.cc +++ b/stack/btm/btm_inq.cc @@ -1161,7 +1161,7 @@ tBTM_STATUS BTM_ReadInquiryRspTxPower(tBTM_CMPL_CB* p_cb) { * ******************************************************************************/ void btm_inq_db_reset(void) { - tBTM_REMOTE_DEV_NAME rem_name; + tBTM_REMOTE_DEV_NAME rem_name = {}; tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; uint8_t num_responses; uint8_t temp_inq_active; @@ -1193,6 +1193,7 @@ void btm_inq_db_reset(void) { if (p_inq->p_remname_cmpl_cb) { rem_name.status = BTM_DEV_RESET; + rem_name.hci_status = HCI_SUCCESS; (*p_inq->p_remname_cmpl_cb)(&rem_name); p_inq->p_remname_cmpl_cb = NULL; @@ -1668,12 +1669,11 @@ static void btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST* p_inq) { const LAP* lap; tBTM_INQ_PARMS* p_inqparms = &p_inq->inqparms; -#if (BTM_INQ_DEBUG == TRUE) BTM_TRACE_DEBUG( - "btm_initiate_inquiry: inq_active:0x%x state:%d inqfilt_active:%d", + "btm_initiate_inquiry: inq_active:0x%x state:%d inqfilt_active:%d inqparms.mode:0x%x", btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, - btm_cb.btm_inq_vars.inqfilt_active); -#endif + btm_cb.btm_inq_vars.inqfilt_active, p_inqparms->mode); + btm_acl_update_busy_level(BTM_BLI_INQ_EVT); if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE) { @@ -1695,6 +1695,14 @@ static void btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST* p_inq) { btsnd_hcic_per_inq_mode(p_inq->per_max_delay, p_inq->per_min_delay, *lap, p_inqparms->duration, p_inqparms->max_resps); } else { +#if (BTA_HOST_INTERLEAVE_SEARCH == FALSE) + if ((p_inq->inq_active & BTM_GENERAL_INQUIRY_ACTIVE) != 0 && + (p_inqparms->mode & BTM_GENERAL_INQUIRY) == 0) { + BTM_TRACE_DEBUG("%s: inq_active is not inconsistent with p_inqparms->mode", __func__); + p_inqparms->mode |= BTM_GENERAL_INQUIRY; + } +#endif + btm_clr_inq_result_flt(); /* Allocate memory to hold bd_addrs responding */ @@ -2226,6 +2234,7 @@ void btm_process_remote_name(const RawAddress* bda, BD_NAME bdn, rem_name.length = (evt_len < BD_NAME_LEN) ? evt_len : BD_NAME_LEN; rem_name.remote_bd_name[rem_name.length] = 0; rem_name.status = BTM_SUCCESS; + rem_name.hci_status = hci_status; temp_evt_len = rem_name.length; while (temp_evt_len > 0) { @@ -2233,12 +2242,11 @@ void btm_process_remote_name(const RawAddress* bda, BD_NAME bdn, temp_evt_len--; } rem_name.remote_bd_name[rem_name.length] = 0; - } - - /* If processing a stand alone remote name then report the error in the - callback */ - else { + } else { + /* If processing a stand alone remote name then report the error in the + callback */ rem_name.status = BTM_BAD_VALUE_RET; + rem_name.hci_status = hci_status; rem_name.length = 0; rem_name.remote_bd_name[0] = 0; } diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h index a2e8ac6a5..481a2f083 100644 --- a/stack/btm/btm_int.h +++ b/stack/btm/btm_int.h @@ -94,7 +94,7 @@ extern uint8_t btm_handle_to_acl_index(uint16_t hci_handle); extern void btm_read_link_policy_complete(uint8_t* p); extern void btm_read_rssi_timeout(void* data); -extern void btm_read_rssi_complete(uint8_t* p); +extern void btm_read_rssi_complete(uint8_t* p, uint16_t evt_len); extern void btm_read_failed_contact_counter_timeout(void* data); extern void btm_read_failed_contact_counter_complete(uint8_t* p); @@ -103,10 +103,10 @@ extern void btm_read_automatic_flush_timeout_timeout(void* data); extern void btm_read_automatic_flush_timeout_complete(uint8_t* p); extern void btm_read_tx_power_timeout(void* data); -extern void btm_read_tx_power_complete(uint8_t* p, bool is_ble); +extern void btm_read_tx_power_complete(uint8_t* p, uint16_t evt_len, bool is_ble); extern void btm_read_link_quality_timeout(void* data); -extern void btm_read_link_quality_complete(uint8_t* p); +extern void btm_read_link_quality_complete(uint8_t* p, uint16_t evt_len); extern tBTM_STATUS btm_set_packet_types(tACL_CONN* p, uint16_t pkt_types); extern void btm_process_clk_off_comp_evt(uint16_t hci_handle, @@ -244,7 +244,7 @@ extern tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, void* p_ref_data); extern void btm_sec_conn_req(const RawAddress& bda, uint8_t* dc); extern tBTM_STATUS btm_sec_execute_procedure (tBTM_SEC_DEV_REC *p_dev_rec); -extern void btm_create_conn_cancel_complete(uint8_t* p); +extern void btm_create_conn_cancel_complete(uint8_t* p, uint16_t evt_len); extern void btm_read_inq_tx_power_timeout(void* data); extern void btm_read_inq_tx_power_complete(uint8_t* p); @@ -296,7 +296,7 @@ extern tL2CAP_LE_RESULT_CODE btm_ble_start_sec_check( extern tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda, bool keep); extern void btm_rem_oob_req(uint8_t* p); -extern void btm_read_local_oob_complete(uint8_t* p); +extern void btm_read_local_oob_complete(uint8_t* p, uint16_t evt_len); extern void btm_acl_resubmit_page(const RawAddress& target_bda, bool skip_connect_page); extern void btm_acl_resubmit_page(void); diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc index ecdc6689f..28e8e777f 100644 --- a/stack/btm/btm_sec.cc +++ b/stack/btm/btm_sec.cc @@ -14,6 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. * + * Changes from Qualcomm Innovation Center are provided under the following license: + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause-Clear ******************************************************************************/ /****************************************************************************** @@ -2827,9 +2830,14 @@ static void btm_sec_bond_cancel_complete(void) { * Returns void * ******************************************************************************/ -void btm_create_conn_cancel_complete(uint8_t* p) { +void btm_create_conn_cancel_complete(uint8_t* p, uint16_t evt_len) { uint8_t status; + if (evt_len < 1 + BD_ADDR_LEN) { + BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__); + return; + } + STREAM_TO_UINT8(status, p); BTM_TRACE_EVENT("btm_create_conn_cancel_complete(): in State: %s status:%d", btm_pair_state_descr(btm_cb.pairing_state), status); @@ -3903,13 +3911,22 @@ void btm_rem_oob_req(uint8_t* p) { * Returns void * ******************************************************************************/ -void btm_read_local_oob_complete(uint8_t* p) { +void btm_read_local_oob_complete(uint8_t* p, uint16_t evt_len) { tBTM_SP_LOC_OOB evt_data; - uint8_t status = *p++; + uint8_t status; + if (evt_len < 1) { + goto err_out; + } + STREAM_TO_UINT8(status, p); BTM_TRACE_EVENT("btm_read_local_oob_complete:%d", status); if (status == HCI_SUCCESS) { evt_data.status = BTM_SUCCESS; + + if (evt_len < 1 + 32) { + goto err_out; + } + STREAM_TO_ARRAY16(evt_data.c.data(), p); STREAM_TO_ARRAY16(evt_data.r.data(), p); } else @@ -3920,6 +3937,11 @@ void btm_read_local_oob_complete(uint8_t* p) { btm_sp_evt_data.loc_oob = evt_data; (*btm_cb.api.p_sp_callback)(BTM_SP_LOC_OOB_EVT, &btm_sp_evt_data); } + + return; + +err_out: + BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__); } /******************************************************************************* @@ -5398,7 +5420,12 @@ extern tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; /* There is a chance that we are getting name. Wait until done. */ - if (p_dev_rec->sec_state != 0) return (BTM_CMD_STARTED); + if ((p_dev_rec->sec_state != BTM_SEC_STATE_IDLE) && + (p_dev_rec->sec_state != BTM_SEC_STATE_DISCONNECTING_BLE)) { + LOG_DEBUG(LOG_TAG, + "Security state is not idle indicating RNR or security is in progress"); + return (BTM_CMD_STARTED); + } /* If any security is required, get the name first */ if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN) && diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc index 822d809a8..94d704954 100644 --- a/stack/btu/btu_hcif.cc +++ b/stack/btu/btu_hcif.cc @@ -165,13 +165,13 @@ static void btu_hcif_ssr_evt(uint8_t* p, uint16_t evt_len); #endif /* BTM_SSR_INCLUDED == TRUE */ static void btu_ble_ll_conn_complete_evt(uint8_t* p, uint16_t evt_len); -static void btu_ble_read_remote_feat_evt(uint8_t* p); +static void btu_ble_read_remote_feat_evt(uint8_t* p, uint8_t length); static void btu_ble_ll_conn_param_upd_evt(uint8_t* p, uint16_t evt_len); static void btu_ble_proc_ltk_req(uint8_t* p); static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p); static void btu_ble_data_length_change_evt(uint8_t* p, uint16_t evt_len); #if (BLE_LLT_INCLUDED == TRUE) -static void btu_ble_rc_param_req_evt(uint8_t* p); +static void btu_ble_rc_param_req_evt(uint8_t* p, uint8_t len); #endif #if (BLE_PRIVACY_SPT == TRUE) static void btu_ble_proc_enhanced_conn_cmpl(uint8_t* p, uint16_t evt_len); @@ -388,10 +388,10 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_msg) { btu_ble_ll_conn_complete_evt(p, hci_evt_len); break; case HCI_BLE_LL_CONN_PARAM_UPD_EVT: - btu_ble_ll_conn_param_upd_evt(p, hci_evt_len); + btu_ble_ll_conn_param_upd_evt(p, ble_evt_len); break; case HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT: - btu_ble_read_remote_feat_evt(p); + btu_ble_read_remote_feat_evt(p, ble_evt_len); break; case HCI_BLE_LTK_REQ_EVT: /* received only at slave device */ btu_ble_proc_ltk_req(p); @@ -403,7 +403,7 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_msg) { #endif #if (BLE_LLT_INCLUDED == TRUE) case HCI_BLE_RC_PARAM_REQ_EVT: - btu_ble_rc_param_req_evt(p); + btu_ble_rc_param_req_evt(p, ble_evt_len); break; #endif case HCI_BLE_DATA_LENGTH_CHANGE_EVT: @@ -1159,11 +1159,11 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, break; case HCI_GET_LINK_QUALITY: - btm_read_link_quality_complete(p); + btm_read_link_quality_complete(p, evt_len); break; case HCI_READ_RSSI: - btm_read_rssi_complete(p); + btm_read_rssi_complete(p, evt_len); break; case HCI_READ_FAILED_CONTACT_COUNTER: @@ -1175,15 +1175,15 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, 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: - btm_read_local_oob_complete(p); + btm_read_local_oob_complete(p, evt_len); break; case HCI_READ_INQ_TX_POWER_LEVEL: @@ -1193,15 +1193,15 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, /* BLE Commands sComplete*/ case HCI_BLE_RAND: case HCI_BLE_ENCRYPT: - btm_ble_rand_enc_complete(p, opcode, (tBTM_RAND_ENC_CB*)p_cplt_cback); + btm_ble_rand_enc_complete(p, evt_len, opcode, (tBTM_RAND_ENC_CB*)p_cplt_cback); 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: - btm_ble_write_adv_enable_complete(p); + btm_ble_write_adv_enable_complete(p, evt_len); break; case HCI_BLE_CREATE_LL_CONN: @@ -2064,6 +2064,11 @@ static void btu_ble_ll_conn_param_upd_evt(uint8_t* p, uint16_t evt_len) { uint16_t latency; uint16_t timeout; + if (evt_len < 9) { + LOG_ERROR(LOG_TAG, "Bogus event packet, too short"); + return; + } + STREAM_TO_UINT8(status, p); STREAM_TO_UINT16(handle, p); STREAM_TO_UINT16(interval, p); @@ -2075,8 +2080,8 @@ static void btu_ble_ll_conn_param_upd_evt(uint8_t* p, uint16_t evt_len) { gatt_notify_conn_update(handle & 0x0FFF, interval, latency, timeout, status); } -static void btu_ble_read_remote_feat_evt(uint8_t* p) { - btm_ble_read_remote_features_complete(p); +static void btu_ble_read_remote_feat_evt(uint8_t* p, uint8_t length) { + btm_ble_read_remote_features_complete(p, length); } static void btu_ble_proc_ltk_req(uint8_t* p) { @@ -2112,10 +2117,15 @@ static void btu_ble_data_length_change_evt(uint8_t* p, uint16_t evt_len) { * End of BLE Events Handler **********************************************/ #if (BLE_LLT_INCLUDED == TRUE) -static void btu_ble_rc_param_req_evt(uint8_t* p) { +static void btu_ble_rc_param_req_evt(uint8_t* p, uint8_t len) { uint16_t handle; uint16_t int_min, int_max, latency, timeout; + if (len < 10) { + LOG(ERROR) << __func__ << "bogus event packet, too short"; + return; + } + STREAM_TO_UINT16(handle, p); STREAM_TO_UINT16(int_min, p); STREAM_TO_UINT16(int_max, p); diff --git a/stack/gatt/eatt_utils.cc b/stack/gatt/eatt_utils.cc index de336c0c9..4a89c0b2f 100644 --- a/stack/gatt/eatt_utils.cc +++ b/stack/gatt/eatt_utils.cc @@ -882,8 +882,13 @@ void gatt_send_pending_notif(tGATT_TCB& tcb, uint16_t cid) { return; } - p_buf = (tGATT_VALUE*)&(notif_q->front()); - if (p_buf != NULL) { + while (!notif_q->empty()) { + p_buf = (tGATT_VALUE*)&(notif_q->front()); + if (!p_buf) { + VLOG(1) << __func__ << " notification op value is NULL"; + return; + } + att_ret = GATTS_HandleValueNotification(p_buf->conn_id, p_buf->handle, p_buf->len, p_buf->value); if (((att_ret == GATT_CONGESTED) || (att_ret == GATT_NO_CREDITS)) @@ -970,8 +975,13 @@ void gatt_send_pending_rsp(tGATT_TCB& tcb, uint16_t cid) { return; } - p_buf = (tGATT_PEND_RSP*)&(gatt_rsp_q->front()); - if (p_buf != NULL) { + while (!gatt_rsp_q->empty()) { + p_buf = (tGATT_PEND_RSP*)&(gatt_rsp_q->front()); + if (!p_buf) { + VLOG(1) << __func__ << " GATT Rsp value is NULL"; + return; + } + att_ret = GATTS_SendRsp(p_buf->conn_id, p_buf->trans_id, p_buf->status, p_buf->p_msg); if (((att_ret == GATT_CONGESTED) || (att_ret == GATT_NO_CREDITS)) && p_eatt_bcb->no_credits) { @@ -1022,8 +1032,13 @@ void gatt_send_pending_disc_rsp(tGATT_TCB& tcb, uint16_t cid) { return; } - p_buf = (tGATT_PEND_SRVC_DISC_RSP*)&(gatt_rsp_q->front()); - if (p_buf != NULL) { + while (!gatt_rsp_q->empty()) { + p_buf = (tGATT_PEND_SRVC_DISC_RSP*)&(gatt_rsp_q->front()); + if (!p_buf) { + VLOG(1) << __func__ << " GATT srvc disc rsp value is NULL"; + return; + } + att_ret = attp_send_sr_msg(tcb, cid, p_buf->p_msg); if (((att_ret == GATT_CONGESTED) || (att_ret == GATT_NO_CREDITS)) diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc index 5ac951dd6..5d484adee 100644 --- a/stack/gatt/gatt_cl.cc +++ b/stack/gatt/gatt_cl.cc @@ -615,7 +615,8 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, LOG(ERROR) << StringPrintf("value resp op_code = %s len = %d", gatt_dbg_op_name(op_code), len); - if (len < GATT_PREP_WRITE_RSP_MIN_LEN) { + if (len < GATT_PREP_WRITE_RSP_MIN_LEN || + len > GATT_PREP_WRITE_RSP_MIN_LEN + sizeof(value.value)) { LOG(ERROR) << "illegal prepare write response length, discard"; gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value); return; @@ -624,7 +625,7 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, STREAM_TO_UINT16(value.handle, p); STREAM_TO_UINT16(value.offset, p); - value.len = len - 4; + value.len = len - GATT_PREP_WRITE_RSP_MIN_LEN; memcpy(value.value, p, value.len); diff --git a/stack/gatt/gatt_main.cc b/stack/gatt/gatt_main.cc index b1d52b2f6..a3fa189c2 100644 --- a/stack/gatt/gatt_main.cc +++ b/stack/gatt/gatt_main.cc @@ -75,6 +75,8 @@ #include "btif_storage.h" #include "stack_config.h" +#include "device/include/interop_config.h" + using base::StringPrintf; /* Configuration flags. */ @@ -720,7 +722,20 @@ static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr, } if (gatt_is_robust_caching_enabled()) { - GATT_EnableRobustCaching(bd_addr, BT_TRANSPORT_LE); + bool skip_caching_enable = false; + BD_NAME bd_name; + VLOG(1) << StringPrintf("[%s] BTM_GetRemoteDeviceName: %s", __func__, bd_addr.ToString().c_str()); + if (BTM_GetRemoteDeviceName(bd_addr, bd_name)) { + VLOG(1) << StringPrintf("[%s] FileDB Device name: %s", __func__, bd_name); + if (interop_database_match_name(INTEROP_SKIP_ROBUST_CACHING_READ, (char*) bd_name)) { + VLOG(1) << StringPrintf("[%s] Skip GATT_EnableRobustCaching", __func__); + skip_caching_enable = true; + } + } + VLOG(1) << StringPrintf("[%s] skip_caching_enable: %d", __func__, skip_caching_enable); + if (!skip_caching_enable) { + GATT_EnableRobustCaching(bd_addr, BT_TRANSPORT_LE); + } } } diff --git a/stack/gatt/gatt_utils.cc b/stack/gatt/gatt_utils.cc index f6c11f5c5..a37a083f9 100644 --- a/stack/gatt/gatt_utils.cc +++ b/stack/gatt/gatt_utils.cc @@ -79,6 +79,8 @@ #include <vector> #include <algorithm> +#include "device/include/interop_config.h" + using base::StringPrintf; using bluetooth::Uuid; @@ -693,6 +695,18 @@ void gatt_start_ind_ack_timer(tGATT_TCB& tcb, uint16_t lcid) { } +static tGATT_PROFILE_CLCB* gatt_find_profile_clcb_by_conn_id(uint16_t conn_id) { + uint8_t i_clcb; + tGATT_PROFILE_CLCB* p_clcb = NULL; + + for (i_clcb = 0, p_clcb = gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS; + i_clcb++, p_clcb++) { + if (p_clcb->in_use && p_clcb->conn_id == conn_id) return p_clcb; + } + + return NULL; +} + /******************************************************************************* * * Function gatt_rsp_timeout @@ -715,6 +729,24 @@ void gatt_rsp_timeout(void* data) { uint16_t lcid = p_clcb->p_tcb->att_lcid; tGATT_TCB* p_tcb = p_clcb->p_tcb; + if (p_clcb->operation == GATTC_OPTYPE_READ && + p_clcb->op_subtype == GATT_READ_BY_TYPE && + p_clcb->uuid == Uuid::From16Bit(GATT_UUID_GATT_CL_SUPP_FEATURES)) { + tGATT_PROFILE_CLCB* p_pro_clcb; + p_pro_clcb = gatt_find_profile_clcb_by_conn_id(p_clcb->conn_id); + if (p_pro_clcb && + p_pro_clcb->in_use && p_pro_clcb->connected && + p_pro_clcb->transport == BT_TRANSPORT_LE && + p_pro_clcb->robust_caching_stage == GATT_ROBUST_CACHING_CL_SUPP_FEAT_READ) { + BD_NAME bd_name; + VLOG(1) << __func__ << ": BTM_GetRemoteDeviceName peer_bda = " << p_pro_clcb->bda; + if (BTM_GetRemoteDeviceName(p_pro_clcb->bda, bd_name)) { + VLOG(1) << __func__ << ": interop_database_add_name Name = " << bd_name; + interop_database_add_name(INTEROP_SKIP_ROBUST_CACHING_READ, (char*) bd_name); + } + } + } + if (p_clcb->p_tcb->is_eatt_supported) { lcid = gatt_get_cid_by_conn_id(p_clcb->conn_id); } diff --git a/stack/include/btm_api_types.h b/stack/include/btm_api_types.h index 39ad3a0b9..958103d3c 100644 --- a/stack/include/btm_api_types.h +++ b/stack/include/btm_api_types.h @@ -55,6 +55,7 @@ enum { }; typedef uint8_t tBTM_STATUS; +typedef uint8_t tHCI_STATUS; #if (BTA_HOST_INTERLEAVE_SEARCH == TRUE) typedef enum { @@ -705,10 +706,11 @@ typedef struct { /* Structure returned with remote name request */ typedef struct { - uint16_t status; + tBTM_STATUS status; RawAddress bd_addr; uint16_t length; BD_NAME remote_bd_name; + tHCI_STATUS hci_status; } tBTM_REMOTE_DEV_NAME; typedef struct { @@ -1261,13 +1263,13 @@ typedef uint8_t tBTM_LINK_KEY_TYPE; #define BTM_SEC_SERVICE_HIDD_INTR 53 #define BTM_SEC_SERVICE_HEARING_AID_LEFT 54 #define BTM_SEC_SERVICE_HEARING_AID_RIGHT 55 -#define BTM_SEC_SERVICE_EATT 57 +#define BTM_SEC_SERVICE_EATT 56 /* Update these as services are added */ -#define BTM_SEC_SERVICE_FIRST_EMPTY 56 +#define BTM_SEC_SERVICE_FIRST_EMPTY 57 #ifndef BTM_SEC_MAX_SERVICES -#define BTM_SEC_MAX_SERVICES 80 +#define BTM_SEC_MAX_SERVICES 81 #endif /******************************************************************************* diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h index c55cc5d4e..d4ea5a65b 100644 --- a/stack/include/btm_ble_api.h +++ b/stack/include/btm_ble_api.h @@ -1326,6 +1326,8 @@ using SyncReportCb = uint8_t /*status*/, std::vector<uint8_t> /*data*/)>; using SyncLostCb = base::Callback<void(uint16_t /*sync_handle*/)>; +using BigInfoReportCb = base::Callback<void(uint16_t /*sync_handle*/, bool /*encrypted*/)>; + extern void btm_ble_periodic_adv_sync_established(uint8_t *param, uint16_t param_len); extern void btm_ble_periodic_adv_report(uint8_t *param, uint16_t param_len); extern void btm_ble_periodic_adv_sync_lost(uint8_t *param, uint16_t param_len); @@ -1350,7 +1352,8 @@ extern void BTM_BleStartPeriodicSync(uint8_t adv_sid, RawAddress address, uint16_t skip, uint16_t timeout, StartSyncCb syncCb, SyncReportCb reportCb, - SyncLostCb lostCb); + SyncLostCb lostCb, + BigInfoReportCb biginfo_reportCb); /******************************************************************************* * * Function BTM_BleStopPeriodicSync diff --git a/stack/l2cap/l2c_ble.cc b/stack/l2cap/l2c_ble.cc index 8e1e122b7..5776b73fc 100644 --- a/stack/l2cap/l2c_ble.cc +++ b/stack/l2cap/l2c_ble.cc @@ -707,7 +707,8 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { LOG(ERROR) << "invalid read"; return; } - + L2CAP_TRACE_DEBUG("Reset local_id after recving L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES"); + p_ccb->local_id = 0; STREAM_TO_UINT16(p_ccb->remote_cid, p); STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mtu, p); STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mps, p); @@ -862,7 +863,8 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { return; } uint16_t dest_cid[5] = {0}; - + L2CAP_TRACE_DEBUG("Reset local_id after recving L2CAP_CMD_CREDIT_BASED_CONNECTION_RSP"); + p_ccb->local_id = 0; STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mtu, p); STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mps, p); STREAM_TO_UINT16(p_ccb->peer_conn_cfg.credits, p); diff --git a/stack/l2cap/l2c_csm.cc b/stack/l2cap/l2c_csm.cc index 2e70f20e7..107bb0fe9 100644 --- a/stack/l2cap/l2c_csm.cc +++ b/stack/l2cap/l2c_csm.cc @@ -1943,6 +1943,14 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, uint16_t event, void* p_data) { break; case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ + if (p_ccb->p_lcb->transport == BT_TRANSPORT_BR_EDR && + p_ccb->p_rcb->psm != BT_PSM_SDP && + interop_match_addr_or_name(INTEROP_L2CAP_DISCONNECT_ACL_DIRECTLY, + &p_ccb->p_lcb->remote_bd_addr)) { + L2CAP_TRACE_ERROR("disconnect acl directly."); + btm_sec_disconnect(p_ccb->p_lcb->handle, HCI_ERR_PEER_USER); + } + if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { /* Make sure we are not in sniff mode */ { @@ -2390,8 +2398,9 @@ void l2c_enqueue_peer_data(tL2C_CCB* p_ccb, BT_HDR* p_buf) { "p_ccb->local_cid = %u p_ccb->remote_cid = %u", __func__, p_ccb, p_ccb->in_use, p_ccb->chnl_state, p_ccb->local_cid, p_ccb->remote_cid); + } else { + fixed_queue_enqueue(p_ccb->xmit_hold_q, p_buf); } - fixed_queue_enqueue(p_ccb->xmit_hold_q, p_buf); l2cu_check_channel_congestion(p_ccb); diff --git a/stack/sdp/sdp_db.cc b/stack/sdp/sdp_db.cc index 05805801f..4737282e1 100644 --- a/stack/sdp/sdp_db.cc +++ b/stack/sdp/sdp_db.cc @@ -399,6 +399,11 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type, uint16_t xx; tSDP_RECORD* p_rec = &sdp_cb.server_db.record[0]; + if (p_val == nullptr) { + SDP_TRACE_WARNING("Trying to add attribute with p_val == nullptr, skipped"); + return (false); + } + if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) { if ((attr_type == UINT_DESC_TYPE) || (attr_type == TWO_COMP_INT_DESC_TYPE) || @@ -444,6 +449,12 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type, /* Find the record in the database */ for (xx = 0; xx < sdp_cb.server_db.num_records; xx++, p_rec++) { if (p_rec->record_handle == handle) { + // 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); + } return SDP_AddAttributeToRecord (p_rec, attr_id, attr_type, attr_len, p_val); } } @@ -510,15 +521,13 @@ bool SDP_AddAttributeToRecord (tSDP_RECORD *p_rec, uint16_t attr_id, attr_len = 0; } - if ((attr_len > 0) && (p_val != 0)) { + if (attr_len > 0) { p_attr->len = attr_len; memcpy(&p_rec->attr_pad[p_rec->free_pad_ptr], p_val, (size_t)attr_len); p_attr->value_ptr = &p_rec->attr_pad[p_rec->free_pad_ptr]; p_rec->free_pad_ptr += attr_len; - } else if ((attr_len == 0 && - p_attr->len != - 0) || /* if truncate to 0 length, simply don't add */ - p_val == 0) { + } else if (attr_len == 0 && p_attr->len != 0) { + /* if truncate to 0 length, simply don't add */ SDP_TRACE_ERROR( "SDP_AddAttributeToRecord fail, length exceed maximum: ID %d: attr_len:%d ", attr_id, attr_len); diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc index 5e90662dc..6aea47b4d 100644 --- a/stack/sdp/sdp_server.cc +++ b/stack/sdp/sdp_server.cc @@ -1479,7 +1479,7 @@ static uint16_t sdp_update_pbap_blacklist_len(tCONN_CB* p_ccb, tSDP_ATTR_SEQ* at bool is_pbap_101_blacklisted = is_device_blacklisted_for_pbap(p_ccb->device_address, false); bool is_pbap_102_blacklisted = is_device_blacklisted_for_pbap(p_ccb->device_address, true); bool running_pts = false; - char pts_property[6]; + char pts_property[PROPERTY_VALUE_MAX] = {0}; osi_property_get(SDP_ENABLE_PTS_PBAP, pts_property, "false"); if (!strncmp("true", pts_property, 4)) { SDP_TRACE_DEBUG("%s pts running= %d", __func__, pts_property); @@ -1574,7 +1574,7 @@ static tSDP_RECORD *sdp_upgrade_pse_record(tSDP_RECORD * p_rec, bool is_pbap_101_blacklisted = is_device_blacklisted_for_pbap(remote_address, false); bool is_pbap_102_blacklisted = is_device_blacklisted_for_pbap(remote_address, true); bool running_pts = false; - char pts_property[6]; + char pts_property[PROPERTY_VALUE_MAX] = {0}; osi_property_get(SDP_ENABLE_PTS_PBAP, pts_property, "false"); if (!strncmp("true", pts_property, 4)) { SDP_TRACE_DEBUG("%s pts running= %d", __func__, pts_property); @@ -1957,7 +1957,7 @@ static tSDP_RECORD *sdp_upgrade_mse_record(tSDP_RECORD * p_rec, /* Check if remote supports MAP 1.4 */ is_map_104_supported = check_remote_map_version_104(remote_address); bool running_pts = false; - char pts_property[6]; + char pts_property[PROPERTY_VALUE_MAX]; osi_property_get(SDP_ENABLE_PTS_MAP, pts_property, "false"); if (!strncmp("true", pts_property, 4)) { SDP_TRACE_DEBUG("%s pts running= %s", __func__, pts_property); |