232 lines
9.4 KiB
C++
232 lines
9.4 KiB
C++
|
|
/*
|
||
|
|
* Copyright 2020 The Android Open Source Project
|
||
|
|
*
|
||
|
|
* 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.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "main/shim/acl_api.h"
|
||
|
|
|
||
|
|
#include <cstddef>
|
||
|
|
#include <cstdint>
|
||
|
|
#include <future>
|
||
|
|
#include <optional>
|
||
|
|
|
||
|
|
#include "gd/hci/acl_manager.h"
|
||
|
|
#include "gd/hci/remote_name_request.h"
|
||
|
|
#include "main/shim/dumpsys.h"
|
||
|
|
#include "main/shim/entry.h"
|
||
|
|
#include "main/shim/helpers.h"
|
||
|
|
#include "main/shim/stack.h"
|
||
|
|
#include "osi/include/allocator.h"
|
||
|
|
#include "stack/btm/btm_sec.h"
|
||
|
|
#include "stack/btm/security_device_record.h"
|
||
|
|
#include "stack/include/bt_hdr.h"
|
||
|
|
#include "stack/include/btu.h" // do_in_main_thread
|
||
|
|
#include "stack/include/inq_hci_link_interface.h"
|
||
|
|
#include "types/ble_address_with_type.h"
|
||
|
|
#include "types/raw_address.h"
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_CreateClassicConnection(
|
||
|
|
const RawAddress& raw_address) {
|
||
|
|
auto address = ToGdAddress(raw_address);
|
||
|
|
Stack::GetInstance()->GetAcl()->CreateClassicConnection(address);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_CancelClassicConnection(
|
||
|
|
const RawAddress& raw_address) {
|
||
|
|
auto address = ToGdAddress(raw_address);
|
||
|
|
Stack::GetInstance()->GetAcl()->CancelClassicConnection(address);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool bluetooth::shim::ACL_AcceptLeConnectionFrom(
|
||
|
|
const tBLE_BD_ADDR& legacy_address_with_type, bool is_direct) {
|
||
|
|
std::promise<bool> promise;
|
||
|
|
auto future = promise.get_future();
|
||
|
|
Stack::GetInstance()->GetAcl()->AcceptLeConnectionFrom(
|
||
|
|
ToAddressWithTypeFromLegacy(legacy_address_with_type), is_direct,
|
||
|
|
std::move(promise));
|
||
|
|
return future.get();
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_IgnoreLeConnectionFrom(
|
||
|
|
const tBLE_BD_ADDR& legacy_address_with_type) {
|
||
|
|
Stack::GetInstance()->GetAcl()->IgnoreLeConnectionFrom(
|
||
|
|
ToAddressWithTypeFromLegacy(legacy_address_with_type));
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_WriteData(uint16_t handle, BT_HDR* p_buf) {
|
||
|
|
std::unique_ptr<bluetooth::packet::RawBuilder> packet = MakeUniquePacket(
|
||
|
|
p_buf->data + p_buf->offset + HCI_DATA_PREAMBLE_SIZE,
|
||
|
|
p_buf->len - HCI_DATA_PREAMBLE_SIZE, IsPacketFlushable(p_buf));
|
||
|
|
Stack::GetInstance()->GetAcl()->WriteData(handle, std::move(packet));
|
||
|
|
osi_free(p_buf);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_ConfigureLePrivacy(bool is_le_privacy_enabled) {
|
||
|
|
hci::LeAddressManager::AddressPolicy address_policy =
|
||
|
|
is_le_privacy_enabled
|
||
|
|
? hci::LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS
|
||
|
|
: hci::LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS;
|
||
|
|
hci::AddressWithType empty_address_with_type(
|
||
|
|
hci::Address{}, hci::AddressType::RANDOM_DEVICE_ADDRESS);
|
||
|
|
/* 7 minutes minimum, 15 minutes maximum for random address refreshing */
|
||
|
|
auto minimum_rotation_time = std::chrono::minutes(7);
|
||
|
|
auto maximum_rotation_time = std::chrono::minutes(15);
|
||
|
|
|
||
|
|
Stack::GetInstance()
|
||
|
|
->GetStackManager()
|
||
|
|
->GetInstance<bluetooth::hci::AclManager>()
|
||
|
|
->SetPrivacyPolicyForInitiatorAddress(
|
||
|
|
address_policy, empty_address_with_type, minimum_rotation_time,
|
||
|
|
maximum_rotation_time);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_Disconnect(uint16_t handle, bool is_classic,
|
||
|
|
tHCI_STATUS reason, std::string comment) {
|
||
|
|
(is_classic)
|
||
|
|
? Stack::GetInstance()->GetAcl()->DisconnectClassic(handle, reason,
|
||
|
|
comment)
|
||
|
|
: Stack::GetInstance()->GetAcl()->DisconnectLe(handle, reason, comment);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_Shutdown() {
|
||
|
|
Stack::GetInstance()->GetAcl()->Shutdown();
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_IgnoreAllLeConnections() {
|
||
|
|
return Stack::GetInstance()->GetAcl()->ClearFilterAcceptList();
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_ReadConnectionAddress(const RawAddress& pseudo_addr,
|
||
|
|
RawAddress& conn_addr,
|
||
|
|
tBLE_ADDR_TYPE* p_addr_type) {
|
||
|
|
auto local_address =
|
||
|
|
Stack::GetInstance()->GetAcl()->GetConnectionLocalAddress(pseudo_addr);
|
||
|
|
conn_addr = ToRawAddress(local_address.GetAddress());
|
||
|
|
*p_addr_type = static_cast<tBLE_ADDR_TYPE>(local_address.GetAddressType());
|
||
|
|
}
|
||
|
|
|
||
|
|
std::optional<uint8_t> bluetooth::shim::ACL_GetAdvertisingSetConnectedTo(
|
||
|
|
const RawAddress& addr) {
|
||
|
|
return Stack::GetInstance()->GetAcl()->GetAdvertisingSetConnectedTo(addr);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_AddToAddressResolution(
|
||
|
|
const tBLE_BD_ADDR& legacy_address_with_type, const Octet16& peer_irk,
|
||
|
|
const Octet16& local_irk) {
|
||
|
|
Stack::GetInstance()->GetAcl()->AddToAddressResolution(
|
||
|
|
ToAddressWithType(legacy_address_with_type.bda,
|
||
|
|
legacy_address_with_type.type),
|
||
|
|
peer_irk, local_irk);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_RemoveFromAddressResolution(
|
||
|
|
const tBLE_BD_ADDR& legacy_address_with_type) {
|
||
|
|
Stack::GetInstance()->GetAcl()->RemoveFromAddressResolution(ToAddressWithType(
|
||
|
|
legacy_address_with_type.bda, legacy_address_with_type.type));
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_ClearAddressResolution() {
|
||
|
|
Stack::GetInstance()->GetAcl()->ClearAddressResolution();
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_ClearFilterAcceptList() {
|
||
|
|
Stack::GetInstance()->GetAcl()->ClearFilterAcceptList();
|
||
|
|
}
|
||
|
|
void bluetooth::shim::ACL_LeSetDefaultSubrate(uint16_t subrate_min,
|
||
|
|
uint16_t subrate_max,
|
||
|
|
uint16_t max_latency,
|
||
|
|
uint16_t cont_num,
|
||
|
|
uint16_t sup_tout) {
|
||
|
|
Stack::GetInstance()->GetAcl()->LeSetDefaultSubrate(
|
||
|
|
subrate_min, subrate_max, max_latency, cont_num, sup_tout);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_LeSubrateRequest(
|
||
|
|
uint16_t hci_handle, uint16_t subrate_min, uint16_t subrate_max,
|
||
|
|
uint16_t max_latency, uint16_t cont_num, uint16_t sup_tout) {
|
||
|
|
Stack::GetInstance()->GetAcl()->LeSubrateRequest(
|
||
|
|
hci_handle, subrate_min, subrate_max, max_latency, cont_num, sup_tout);
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_RemoteNameRequest(const RawAddress& addr,
|
||
|
|
uint8_t page_scan_rep_mode,
|
||
|
|
uint8_t page_scan_mode,
|
||
|
|
uint16_t clock_offset) {
|
||
|
|
bluetooth::shim::GetRemoteNameRequest()->StartRemoteNameRequest(
|
||
|
|
ToGdAddress(addr),
|
||
|
|
hci::RemoteNameRequestBuilder::Create(
|
||
|
|
ToGdAddress(addr), hci::PageScanRepetitionMode(page_scan_rep_mode),
|
||
|
|
clock_offset & (~BTM_CLOCK_OFFSET_VALID),
|
||
|
|
(clock_offset & BTM_CLOCK_OFFSET_VALID)
|
||
|
|
? hci::ClockOffsetValid::VALID
|
||
|
|
: hci::ClockOffsetValid::INVALID),
|
||
|
|
GetGdShimHandler()->BindOnce([](hci::ErrorCode status) {
|
||
|
|
if (status != hci::ErrorCode::SUCCESS) {
|
||
|
|
do_in_main_thread(
|
||
|
|
FROM_HERE,
|
||
|
|
base::Bind(
|
||
|
|
[](hci::ErrorCode status) {
|
||
|
|
// NOTE: we intentionally don't supply the address, to match
|
||
|
|
// the legacy behavior.
|
||
|
|
// Callsites that want the address should use
|
||
|
|
// StartRemoteNameRequest() directly, rather than going
|
||
|
|
// through this shim.
|
||
|
|
btm_process_remote_name(nullptr, nullptr, 0,
|
||
|
|
static_cast<tHCI_STATUS>(status));
|
||
|
|
btm_sec_rmt_name_request_complete(
|
||
|
|
nullptr, nullptr, static_cast<tHCI_STATUS>(status));
|
||
|
|
},
|
||
|
|
status));
|
||
|
|
}
|
||
|
|
}),
|
||
|
|
GetGdShimHandler()->BindOnce(
|
||
|
|
[](RawAddress addr, uint64_t features) {
|
||
|
|
static_assert(sizeof(features) == 8);
|
||
|
|
auto addr_array = addr.ToArray();
|
||
|
|
auto p = (uint8_t*)osi_malloc(addr_array.size() + sizeof(features));
|
||
|
|
std::copy(addr_array.rbegin(), addr_array.rend(), p);
|
||
|
|
for (int i = 0; i != sizeof(features); ++i) {
|
||
|
|
p[addr_array.size() + i] = features & ((1 << 8) - 1);
|
||
|
|
features >>= 8;
|
||
|
|
}
|
||
|
|
do_in_main_thread(FROM_HERE,
|
||
|
|
base::Bind(btm_sec_rmt_host_support_feat_evt, p));
|
||
|
|
},
|
||
|
|
addr),
|
||
|
|
GetGdShimHandler()->BindOnce(
|
||
|
|
[](RawAddress addr, hci::ErrorCode status,
|
||
|
|
std::array<uint8_t, 248> name) {
|
||
|
|
do_in_main_thread(
|
||
|
|
FROM_HERE,
|
||
|
|
base::Bind(
|
||
|
|
[](RawAddress addr, hci::ErrorCode status,
|
||
|
|
std::array<uint8_t, 248> name) {
|
||
|
|
auto p = (uint8_t*)osi_malloc(name.size());
|
||
|
|
std::copy(name.begin(), name.end(), p);
|
||
|
|
|
||
|
|
btm_process_remote_name(&addr, p, name.size(),
|
||
|
|
static_cast<tHCI_STATUS>(status));
|
||
|
|
btm_sec_rmt_name_request_complete(
|
||
|
|
&addr, p, static_cast<tHCI_STATUS>(status));
|
||
|
|
},
|
||
|
|
addr, status, name));
|
||
|
|
},
|
||
|
|
addr));
|
||
|
|
}
|
||
|
|
|
||
|
|
void bluetooth::shim::ACL_CancelRemoteNameRequest(const RawAddress& addr) {
|
||
|
|
bluetooth::shim::GetRemoteNameRequest()->CancelRemoteNameRequest(
|
||
|
|
ToGdAddress(addr));
|
||
|
|
}
|