1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "le_advertiser.h"
18
19 using namespace bluetooth::hci;
20
21 namespace test_vendor_lib {
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)22 void LeAdvertiser::Initialize(AddressWithType address,
23 AddressWithType peer_address,
24 LeScanningFilterPolicy filter_policy,
25 model::packets::AdvertisementType type,
26 const std::vector<uint8_t>& advertisement,
27 const std::vector<uint8_t>& scan_response,
28 std::chrono::steady_clock::duration interval) {
29 address_ = address;
30 peer_address_ = peer_address;
31 filter_policy_ = filter_policy;
32 type_ = type;
33 advertisement_ = advertisement;
34 scan_response_ = scan_response;
35 interval_ = interval;
36 }
37
InitializeExtended(AddressType address_type,AddressWithType peer_address,LeScanningFilterPolicy filter_policy,model::packets::AdvertisementType type,std::chrono::steady_clock::duration interval)38 void LeAdvertiser::InitializeExtended(
39 AddressType address_type, AddressWithType peer_address,
40 LeScanningFilterPolicy filter_policy,
41 model::packets::AdvertisementType type,
42 std::chrono::steady_clock::duration interval) {
43 address_ = AddressWithType(address_.GetAddress(), address_type);
44 peer_address_ = peer_address;
45 filter_policy_ = filter_policy;
46 type_ = type;
47 interval_ = interval;
48 LOG_INFO("%s -> %s type = %hhx interval = %d ms", address_.ToString().c_str(),
49 peer_address.ToString().c_str(), type_,
50 static_cast<int>(interval_.count()));
51 }
52
Clear()53 void LeAdvertiser::Clear() {
54 address_ = AddressWithType{};
55 peer_address_ = AddressWithType{};
56 filter_policy_ = LeScanningFilterPolicy::ACCEPT_ALL;
57 type_ = model::packets::AdvertisementType::ADV_IND;
58 advertisement_.clear();
59 scan_response_.clear();
60 interval_ = std::chrono::milliseconds(0);
61 enabled_ = false;
62 }
63
SetAddress(Address address)64 void LeAdvertiser::SetAddress(Address address) {
65 LOG_INFO("set address %s", address_.ToString().c_str());
66 address_ = AddressWithType(address, address_.GetAddressType());
67 }
68
GetAddress() const69 AddressWithType LeAdvertiser::GetAddress() const { return address_; }
70
SetData(const std::vector<uint8_t> & data)71 void LeAdvertiser::SetData(const std::vector<uint8_t>& data) {
72 advertisement_ = data;
73 }
74
Enable()75 void LeAdvertiser::Enable() {
76 enabled_ = true;
77 last_le_advertisement_ = std::chrono::steady_clock::now() - interval_;
78 LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
79 address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
80 advertisement_.size(), scan_response_.size());
81 }
82
EnableExtended(std::chrono::steady_clock::duration duration)83 void LeAdvertiser::EnableExtended(
84 std::chrono::steady_clock::duration duration) {
85 last_le_advertisement_ = std::chrono::steady_clock::now();
86 if (duration != std::chrono::milliseconds(0)) {
87 ending_time_ = std::chrono::steady_clock::now() + duration;
88 }
89 enabled_ = true;
90 LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
91 address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
92 advertisement_.size(), scan_response_.size());
93 }
94
Disable()95 void LeAdvertiser::Disable() { enabled_ = false; }
96
IsEnabled() const97 bool LeAdvertiser::IsEnabled() const { return enabled_; }
98
99 std::unique_ptr<model::packets::LeAdvertisementBuilder>
GetAdvertisement(std::chrono::steady_clock::time_point now)100 LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
101 if (!enabled_) {
102 return nullptr;
103 }
104
105 if (now - last_le_advertisement_ < interval_) {
106 return nullptr;
107 }
108
109 if (last_le_advertisement_ < ending_time_ && ending_time_ < now) {
110 enabled_ = false;
111 return nullptr;
112 }
113
114 last_le_advertisement_ = now;
115 return model::packets::LeAdvertisementBuilder::Create(
116 address_.GetAddress(), peer_address_.GetAddress(),
117 static_cast<model::packets::AddressType>(address_.GetAddressType()),
118 type_, advertisement_);
119 }
120
121 std::unique_ptr<model::packets::LeScanResponseBuilder>
GetScanResponse(bluetooth::hci::Address scanned,bluetooth::hci::Address scanner)122 LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
123 bluetooth::hci::Address scanner) {
124 if (scanned != address_.GetAddress() || !enabled_ || scan_response_.empty()) {
125 return nullptr;
126 }
127 switch (filter_policy_) {
128 case bluetooth::hci::LeScanningFilterPolicy::
129 CONNECT_LIST_AND_INITIATORS_IDENTITY:
130 case bluetooth::hci::LeScanningFilterPolicy::CONNECT_LIST_ONLY:
131 LOG_WARN("ScanResponses don't handle connect list filters");
132 return nullptr;
133 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
134 if (scanner != peer_address_.GetAddress()) {
135 return nullptr;
136 }
137 break;
138 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
139 break;
140 }
141 return model::packets::LeScanResponseBuilder::Create(
142 address_.GetAddress(), peer_address_.GetAddress(),
143 static_cast<model::packets::AddressType>(address_.GetAddressType()),
144 model::packets::AdvertisementType::SCAN_RESPONSE, scan_response_);
145 }
146
147 } // namespace test_vendor_lib
148