blob: cbb4cb70ba640c7fc6239dc04f2008470df161fb [file] [log] [blame]
/*
* 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 "le_advertiser.h"
using namespace bluetooth::hci;
namespace test_vendor_lib {
void LeAdvertiser::Initialize(AddressWithType address,
AddressWithType peer_address,
LeScanningFilterPolicy filter_policy,
model::packets::AdvertisementType type,
const std::vector<uint8_t>& advertisement,
const std::vector<uint8_t>& scan_response,
std::chrono::steady_clock::duration interval) {
address_ = address;
peer_address_ = peer_address;
filter_policy_ = filter_policy;
type_ = type;
advertisement_ = advertisement;
scan_response_ = scan_response;
interval_ = interval;
}
void LeAdvertiser::InitializeExtended(
AddressType address_type, AddressWithType peer_address,
LeScanningFilterPolicy filter_policy,
model::packets::AdvertisementType type,
std::chrono::steady_clock::duration interval) {
address_ = AddressWithType(address_.GetAddress(), address_type);
peer_address_ = peer_address;
filter_policy_ = filter_policy;
type_ = type;
interval_ = interval;
LOG_INFO("%s -> %s type = %hhx interval = %d ms", address_.ToString().c_str(),
peer_address.ToString().c_str(), type_,
static_cast<int>(interval_.count()));
}
void LeAdvertiser::Clear() {
address_ = AddressWithType{};
peer_address_ = AddressWithType{};
filter_policy_ = LeScanningFilterPolicy::ACCEPT_ALL;
type_ = model::packets::AdvertisementType::ADV_IND;
advertisement_.clear();
scan_response_.clear();
interval_ = std::chrono::milliseconds(0);
enabled_ = false;
}
void LeAdvertiser::SetAddress(Address address) {
LOG_INFO("set address %s", address_.ToString().c_str());
address_ = AddressWithType(address, address_.GetAddressType());
}
AddressWithType LeAdvertiser::GetAddress() const { return address_; }
void LeAdvertiser::SetData(const std::vector<uint8_t>& data) {
advertisement_ = data;
}
void LeAdvertiser::SetScanResponse(const std::vector<uint8_t>& data) {
scan_response_ = data;
}
void LeAdvertiser::Enable() {
enabled_ = true;
last_le_advertisement_ = std::chrono::steady_clock::now() - interval_;
num_events_ = 0;
LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
advertisement_.size(), scan_response_.size());
}
void LeAdvertiser::EnableExtended(
std::chrono::steady_clock::duration duration) {
Enable();
if (duration != std::chrono::milliseconds(0)) {
ending_time_ = std::chrono::steady_clock::now() + duration;
}
extended_ = true;
LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
advertisement_.size(), scan_response_.size());
}
void LeAdvertiser::Disable() { enabled_ = false; }
bool LeAdvertiser::IsEnabled() const { return enabled_; }
bool LeAdvertiser::IsExtended() const { return extended_; }
uint8_t LeAdvertiser::GetNumAdvertisingEvents() const { return num_events_; }
std::unique_ptr<model::packets::LeAdvertisementBuilder>
LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
if (!enabled_) {
return nullptr;
}
if (now - last_le_advertisement_ < interval_) {
return nullptr;
}
if (last_le_advertisement_ < ending_time_ && ending_time_ < now) {
enabled_ = false;
return nullptr;
}
last_le_advertisement_ = now;
num_events_ += (num_events_ < 255 ? 1 : 0);
return model::packets::LeAdvertisementBuilder::Create(
address_.GetAddress(), peer_address_.GetAddress(),
static_cast<model::packets::AddressType>(address_.GetAddressType()),
type_, advertisement_);
}
std::unique_ptr<model::packets::LeScanResponseBuilder>
LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
bluetooth::hci::Address scanner) {
if (scanned != address_.GetAddress() || !enabled_) {
return nullptr;
}
switch (filter_policy_) {
case bluetooth::hci::LeScanningFilterPolicy::
CONNECT_LIST_AND_INITIATORS_IDENTITY:
case bluetooth::hci::LeScanningFilterPolicy::CONNECT_LIST_ONLY:
LOG_WARN("ScanResponses don't handle connect list filters");
return nullptr;
case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
if (scanner != peer_address_.GetAddress()) {
return nullptr;
}
break;
case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
break;
}
return model::packets::LeScanResponseBuilder::Create(
address_.GetAddress(), peer_address_.GetAddress(),
static_cast<model::packets::AddressType>(address_.GetAddressType()),
model::packets::AdvertisementType::SCAN_RESPONSE, scan_response_);
}
} // namespace test_vendor_lib