/******************************************************************************
*
* Copyright 2003-2014 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This is the API implementation file for the BTA device manager.
*
******************************************************************************/
#include
#include
#include
#include
#include "bta/dm/bta_dm_device_search.h"
#include "bta/dm/bta_dm_disc.h"
#include "bta/dm/bta_dm_int.h"
#include "bta/dm/bta_dm_sec_int.h"
#include "hci/le_rand_callback.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/btm_client_interface.h"
#include "stack/include/main_thread.h"
#include "stack/include/sdp_api.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
using namespace bluetooth::legacy::stack::sdp;
using namespace bluetooth;
using bluetooth::Uuid;
/*****************************************************************************
* Constants
****************************************************************************/
void BTA_dm_init() {
/* if UUID list is not provided as static data */
bta_sys_eir_register(bta_dm_eir_update_uuid);
bta_sys_cust_eir_register(bta_dm_eir_update_cust_uuid);
get_btm_client_interface().ble.BTM_SetConsolidationCallback(bta_dm_consolidate);
}
/** Enables bluetooth device under test mode */
void BTA_EnableTestMode(void) {
do_in_main_thread(base::BindOnce(base::IgnoreResult(BTM_EnableTestMode)));
}
/** This function sets the Bluetooth name of local device */
void BTA_DmSetDeviceName(const char* p_name) {
std::vector name(BD_NAME_LEN + 1);
bd_name_from_char_pointer(name.data(), p_name);
do_in_main_thread(base::BindOnce(bta_dm_set_dev_name, name));
}
/*******************************************************************************
*
* Function BTA_DmSearch
*
* Description This function searches for peer Bluetooth devices. It
* performs an inquiry and gets the remote name for devices.
* Service discovery is done if services is non zero
*
* Returns void
*
******************************************************************************/
void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback) { bta_dm_disc_start_device_discovery(p_cback); }
/*******************************************************************************
*
* Function BTA_DmSearchCancel
*
* Description This function cancels a search initiated by BTA_DmSearch
*
* Returns void
*
******************************************************************************/
void BTA_DmSearchCancel(void) { bta_dm_disc_stop_device_discovery(); }
/*******************************************************************************
*
* Function BTA_DmDiscover
*
* Description This function does service discovery for services of a
* peer device
*
*
* Returns void
*
******************************************************************************/
void BTA_DmDiscover(const RawAddress& bd_addr, service_discovery_callbacks cbacks,
tBT_TRANSPORT transport) {
bta_dm_disc_start_service_discovery(cbacks, bd_addr, transport);
}
/*******************************************************************************
*
* Function BTA_DmGetConnectionState
*
* Description Returns whether the remote device is currently connected.
*
* Returns 0 if the device is NOT connected.
*
******************************************************************************/
bool BTA_DmGetConnectionState(const RawAddress& bd_addr) {
tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
return p_dev && p_dev->is_connected();
}
/*******************************************************************************
* Device Identification (DI) Server Functions
******************************************************************************/
/*******************************************************************************
*
* Function BTA_DmSetLocalDiRecord
*
* Description This function adds a DI record to the local SDP database.
*
* Returns BTA_SUCCESS if record set sucessfully, otherwise error code.
*
******************************************************************************/
tBTA_STATUS BTA_DmSetLocalDiRecord(tSDP_DI_RECORD* p_device_info, uint32_t* p_handle) {
tBTA_STATUS status = BTA_FAILURE;
if (bta_dm_di_cb.di_num < BTA_DI_NUM_MAX) {
if (get_legacy_stack_sdp_api()->device_id.SDP_SetLocalDiRecord(
(tSDP_DI_RECORD*)p_device_info, p_handle) == tSDP_STATUS::SDP_SUCCESS) {
if (!p_device_info->primary_record) {
bta_dm_di_cb.di_handle[bta_dm_di_cb.di_num] = *p_handle;
bta_dm_di_cb.di_num++;
}
bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION);
status = BTA_SUCCESS;
}
}
return status;
}
/*******************************************************************************
*
* Function BTA_DmSetBlePrefConnParams
*
* Description This function is called to set the preferred connection
* parameters when default connection parameter is not desired.
*
* Parameters: bd_addr - BD address of the peripheral
* scan_interval - scan interval
* scan_window - scan window
* min_conn_int - minimum preferred connection interval
* max_conn_int - maximum preferred connection interval
* peripheral_latency - preferred peripheral latency
* supervision_tout - preferred supervision timeout
*
*
* Returns void
*
******************************************************************************/
void BTA_DmSetBlePrefConnParams(const RawAddress& bd_addr, uint16_t min_conn_int,
uint16_t max_conn_int, uint16_t peripheral_latency,
uint16_t supervision_tout) {
do_in_main_thread(base::BindOnce(bta_dm_ble_set_conn_params, bd_addr, min_conn_int, max_conn_int,
peripheral_latency, supervision_tout));
}
/*******************************************************************************
*
* Function BTA_DmBleUpdateConnectionParam
*
* Description Update connection parameters, can only be used when
* connection is up.
*
* Parameters: bd_addr - BD address of the peer
* min_int - minimum connection interval,
* [0x0004 ~ 0x4000]
* max_int - maximum connection interval,
* [0x0004 ~ 0x4000]
* latency - peripheral latency [0 ~ 500]
* timeout - supervision timeout [0x000a ~ 0xc80]
*
* Returns void
*
******************************************************************************/
void BTA_DmBleUpdateConnectionParams(const RawAddress& bd_addr, uint16_t min_int, uint16_t max_int,
uint16_t latency, uint16_t timeout, uint16_t min_ce_len,
uint16_t max_ce_len) {
do_in_main_thread(base::BindOnce(bta_dm_ble_update_conn_params, bd_addr, min_int, max_int,
latency, timeout, min_ce_len, max_ce_len));
}
/*******************************************************************************
*
* Function BTA_DmBleConfigLocalPrivacy
*
* Description Enable/disable privacy on the local device
*
* Parameters: privacy_enable - enable/disable privacy on remote device.
*
* Returns void
*
******************************************************************************/
void BTA_DmBleConfigLocalPrivacy(bool privacy_enable) {
bta_dm_ble_config_local_privacy(privacy_enable);
}
/*******************************************************************************
*
* Function BTA_DmBleGetEnergyInfo
*
* Description This function is called to obtain the energy info
*
* Parameters p_cmpl_cback - Command complete callback
*
* Returns void
*
******************************************************************************/
void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK* p_cmpl_cback) {
do_in_main_thread(base::BindOnce(bta_dm_ble_get_energy_info, p_cmpl_cback));
}
/** This function is to set maximum LE data packet size */
void BTA_DmBleRequestMaxTxDataLength(const RawAddress& remote_device) {
do_in_main_thread(base::BindOnce(bta_dm_ble_set_data_length, remote_device));
}
/*******************************************************************************
*
* Function BTA_DmBleScan
*
* Description Start or stop the scan procedure.
*
* Parameters start: start or stop the scan procedure,
* duration_sec: Duration of the scan. Continuous scan if 0 is
* passed,
*
* Returns void
*
******************************************************************************/
void BTA_DmBleScan(bool start, uint8_t duration_sec) {
log::verbose("start = {}", start);
do_in_main_thread(base::BindOnce(bta_dm_ble_scan, start, duration_sec));
}
/*******************************************************************************
*
* Function BTA_DmBleCsisObserve
*
* Description This procedure keeps the external observer listening for
* advertising events from a CSIS grouped device.
*
* Parameters observe: enable or disable passive observe,
* p_results_cb: Callback to be called with scan results,
*
* Returns void
*
******************************************************************************/
void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) {
log::verbose("enable = {}", observe);
do_in_main_thread(base::BindOnce(bta_dm_ble_csis_observe, observe, p_results_cb));
}
/*******************************************************************************
*
* Function BTA_DmClearEventFilter
*
* Description This function clears the event filter
*
* Returns void
*
******************************************************************************/
void BTA_DmClearEventFilter(void) {
log::verbose("BTA_DmClearEventFilter");
do_in_main_thread(base::BindOnce(bta_dm_clear_event_filter));
}
/*******************************************************************************
*
* Function BTA_DmClearEventMask
*
* Description This function clears the event mask
*
* Returns void
*
******************************************************************************/
void BTA_DmClearEventMask(void) {
log::verbose("BTA_DmClearEventMask");
do_in_main_thread(base::BindOnce(bta_dm_clear_event_mask));
}
/*******************************************************************************
*
* Function BTA_DmClearEventMask
*
* Description This function clears the filter accept list
*
* Returns void
*
******************************************************************************/
void BTA_DmClearFilterAcceptList(void) {
log::verbose("BTA_DmClearFilterAcceptList");
do_in_main_thread(base::BindOnce(bta_dm_clear_filter_accept_list));
}
/*******************************************************************************
*
* Function BTA_DmLeRand
*
* Description This function clears the event filter
*
* Returns cb: callback to receive the resulting random number
*
******************************************************************************/
void BTA_DmLeRand(bluetooth::hci::LeRandCallback cb) {
log::verbose("BTA_DmLeRand");
do_in_main_thread(base::BindOnce(bta_dm_le_rand, std::move(cb)));
}
/*******************************************************************************
*
* Function BTA_DmDisconnectAllAcls
*
* Description This function will disconnect all LE and Classic ACLs.
*
* Returns void
*
******************************************************************************/
void BTA_DmDisconnectAllAcls() {
log::verbose("BTA_DmLeRand");
do_in_main_thread(base::BindOnce(bta_dm_disconnect_all_acls));
}
void BTA_DmSetEventFilterConnectionSetupAllDevices() {
log::verbose("BTA_DmSetEventFilterConnectionSetupAllDevices");
do_in_main_thread(base::BindOnce(bta_dm_set_event_filter_connection_setup_all_devices));
}
void BTA_DmAllowWakeByHid(std::vector classic_hid_devices,
std::vector> le_hid_devices) {
log::verbose("BTA_DmAllowWakeByHid");
do_in_main_thread(base::BindOnce(bta_dm_allow_wake_by_hid, std::move(classic_hid_devices),
std::move(le_hid_devices)));
}
void BTA_DmRestoreFilterAcceptList(std::vector> le_devices) {
log::verbose("BTA_DmRestoreFilterAcceptList");
do_in_main_thread(base::BindOnce(bta_dm_restore_filter_accept_list, std::move(le_devices)));
}
void BTA_DmSetDefaultEventMaskExcept(uint64_t mask, uint64_t le_mask) {
log::verbose("BTA_DmSetDefaultEventMaskExcept");
do_in_main_thread(base::BindOnce(bta_dm_set_default_event_mask_except, mask, le_mask));
}
void BTA_DmSetEventFilterInquiryResultAllDevices() {
log::verbose("BTA_DmSetEventFilterInquiryResultAllDevices");
do_in_main_thread(base::BindOnce(bta_dm_set_event_filter_inquiry_result_all_devices));
}
/*******************************************************************************
*
* Function BTA_DmBleResetId
*
* Description This function resets the ble keys such as IRK
*
* Returns void
*
******************************************************************************/
void BTA_DmBleResetId(void) {
log::verbose("BTA_DmBleResetId");
do_in_main_thread(base::BindOnce(bta_dm_ble_reset_id));
}
/*******************************************************************************
*
* Function BTA_DmBleSubrateRequest
*
* Description subrate request, can only be used when connection is up.
*
* Parameters: bd_addr - BD address of the peer
* subrate_min - subrate factor minimum, [0x0001 - 0x01F4]
* subrate_max - subrate factor maximum, [0x0001 - 0x01F4]
* max_latency - max peripheral latency [0x0000 - 01F3]
* cont_num - continuation number [0x0000 - 01F3]
* timeout - supervision timeout [0x000a - 0xc80]
*
* Returns void
*
******************************************************************************/
void BTA_DmBleSubrateRequest(const RawAddress& bd_addr, uint16_t subrate_min, uint16_t subrate_max,
uint16_t max_latency, uint16_t cont_num, uint16_t timeout) {
log::verbose("");
do_in_main_thread(base::BindOnce(bta_dm_ble_subrate_request, bd_addr, subrate_min, subrate_max,
max_latency, cont_num, timeout));
}
bool BTA_DmCheckLeAudioCapable(const RawAddress& address) {
for (tBTM_INQ_INFO* inq_ent = get_btm_client_interface().db.BTM_InqDbFirst(); inq_ent != nullptr;
inq_ent = get_btm_client_interface().db.BTM_InqDbNext(inq_ent)) {
if (inq_ent->results.remote_bd_addr != address) {
continue;
}
if (inq_ent->results.ble_ad_is_le_audio_capable) {
log::info("Device is LE Audio capable based on AD content");
return true;
}
return false;
}
return false;
}