1 /*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License") {
5
6 }
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <algorithm>
20 #include <cstdint>
21
22 #include "log.h"
23 #include "model/controller/link_layer_controller.h"
24 #include "packets/hci_packets.h"
25
26 #pragma GCC diagnostic ignored "-Wunused-parameter"
27
28 namespace rootcanal::apcf {
29
HasFilterIndex(uint8_t apcf_filter_index) const30 bool ApcfScanner::HasFilterIndex(uint8_t apcf_filter_index) const {
31 return std::any_of(std::begin(filters), std::end(filters),
32 [&](auto it) { return it.filter_index == apcf_filter_index; });
33 }
34
ClearFilterIndex(uint8_t apcf_filter_index)35 void ApcfScanner::ClearFilterIndex(uint8_t apcf_filter_index) {
36 broadcaster_address_filters.erase(
37 std::remove_if(std::begin(broadcaster_address_filters),
38 std::end(broadcaster_address_filters),
39 [&](auto it) { return it.filter_index == apcf_filter_index; }),
40 std::end(broadcaster_address_filters));
41 service_uuid_filters.erase(
42 std::remove_if(std::begin(service_uuid_filters), std::end(service_uuid_filters),
43 [&](auto it) { return it.filter_index == apcf_filter_index; }),
44 std::end(service_uuid_filters));
45 service_solicitation_uuid_filters.erase(
46 std::remove_if(std::begin(service_solicitation_uuid_filters),
47 std::end(service_solicitation_uuid_filters),
48 [&](auto it) { return it.filter_index == apcf_filter_index; }),
49 std::end(service_solicitation_uuid_filters));
50 local_name_filters.erase(
51 std::remove_if(std::begin(local_name_filters), std::end(local_name_filters),
52 [&](auto it) { return it.filter_index == apcf_filter_index; }),
53 std::end(local_name_filters));
54 manufacturer_data_filters.erase(
55 std::remove_if(std::begin(manufacturer_data_filters), std::end(manufacturer_data_filters),
56 [&](auto it) { return it.filter_index == apcf_filter_index; }),
57 std::end(manufacturer_data_filters));
58 service_data_filters.erase(
59 std::remove_if(std::begin(service_data_filters), std::end(service_data_filters),
60 [&](auto it) { return it.filter_index == apcf_filter_index; }),
61 std::end(service_data_filters));
62 ad_type_filters.erase(
63 std::remove_if(std::begin(ad_type_filters), std::end(ad_type_filters),
64 [&](auto it) { return it.filter_index == apcf_filter_index; }),
65 std::end(ad_type_filters));
66 }
67
Clear()68 void ApcfScanner::Clear() {
69 filters.clear();
70 broadcaster_address_filters.clear();
71 service_uuid_filters.clear();
72 service_solicitation_uuid_filters.clear();
73 local_name_filters.clear();
74 manufacturer_data_filters.clear();
75 service_data_filters.clear();
76 ad_type_filters.clear();
77 }
78
79 template <typename T>
UpdateFilterList(std::vector<T> & filter_list,size_t max_filter_list_size,bluetooth::hci::ApcfAction action,T filter)80 ErrorCode ApcfScanner::UpdateFilterList(std::vector<T>& filter_list, size_t max_filter_list_size,
81 bluetooth::hci::ApcfAction action, T filter) {
82 if (!HasFilterIndex(filter.filter_index)) {
83 return ErrorCode::UNKNOWN_CONNECTION;
84 }
85
86 switch (action) {
87 case ApcfAction::ADD: {
88 if (filter_list.size() == max_filter_list_size) {
89 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
90 }
91
92 filter_list.emplace_back(std::move(filter));
93 return ErrorCode::SUCCESS;
94 }
95 case ApcfAction::DELETE: {
96 // Delete will delete the specified data in the specified filter.
97 filter_list.erase(std::remove_if(std::begin(filter_list), std::end(filter_list),
98 [&](auto it) { return it == filter; }),
99 std::end(filter_list));
100 return ErrorCode::SUCCESS;
101 }
102 case ApcfAction::CLEAR: {
103 // Clear will clear all data in the specified filter.
104 filter_list.erase(
105 std::remove_if(std::begin(filter_list), std::end(filter_list),
106 [&](auto it) { return it.filter_index == filter.filter_index; }),
107 std::end(filter_list));
108 return ErrorCode::SUCCESS;
109 }
110 default:
111 break;
112 }
113
114 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
115 }
116
operator ==(BroadcasterAddressFilter const & lhs,BroadcasterAddressFilter const & rhs)117 bool operator==(BroadcasterAddressFilter const& lhs, BroadcasterAddressFilter const& rhs) {
118 return lhs.filter_index == rhs.filter_index &&
119 lhs.broadcaster_address == rhs.broadcaster_address &&
120 lhs.application_address_type == rhs.application_address_type;
121 }
122
operator ==(GapDataFilter const & lhs,GapDataFilter const & rhs)123 bool operator==(GapDataFilter const& lhs, GapDataFilter const& rhs) {
124 return lhs.filter_index == rhs.filter_index && lhs.gap_data == rhs.gap_data &&
125 lhs.gap_data_mask == rhs.gap_data_mask;
126 }
127
operator ==(AdTypeFilter const & lhs,AdTypeFilter const & rhs)128 bool operator==(AdTypeFilter const& lhs, AdTypeFilter const& rhs) {
129 return lhs.filter_index == rhs.filter_index && lhs.ad_type == rhs.ad_type &&
130 lhs.ad_data == rhs.ad_data && lhs.ad_data_mask == rhs.ad_data_mask;
131 }
132
133 } // namespace rootcanal::apcf
134
135 namespace rootcanal {
136
137 using bluetooth::hci::ApcfAction;
138
LeApcfEnable(bool apcf_enable)139 ErrorCode LinkLayerController::LeApcfEnable(bool apcf_enable) {
140 apcf_scanner_.enable = apcf_enable;
141 return ErrorCode::SUCCESS;
142 }
143
LeApcfAddFilteringParameters(uint8_t apcf_filter_index,uint16_t apcf_feature_selection,uint16_t apcf_list_logic_type,uint8_t apcf_filter_logic_type,uint8_t rssi_high_thresh,bluetooth::hci::DeliveryMode delivery_mode,uint16_t onfound_timeout,uint8_t onfound_timeout_cnt,uint8_t rssi_low_thresh,uint16_t onlost_timeout,uint16_t num_of_tracking_entries,uint8_t * apcf_available_spaces)144 ErrorCode LinkLayerController::LeApcfAddFilteringParameters(
145 uint8_t apcf_filter_index, uint16_t apcf_feature_selection, uint16_t apcf_list_logic_type,
146 uint8_t apcf_filter_logic_type, uint8_t rssi_high_thresh,
147 bluetooth::hci::DeliveryMode delivery_mode, uint16_t onfound_timeout,
148 uint8_t onfound_timeout_cnt, uint8_t rssi_low_thresh, uint16_t onlost_timeout,
149 uint16_t num_of_tracking_entries, uint8_t* apcf_available_spaces) {
150 *apcf_available_spaces = properties_.le_apcf_filter_list_size - apcf_scanner_.filters.size();
151
152 if (apcf_scanner_.HasFilterIndex(apcf_filter_index)) {
153 INFO(id_, "apcf filter index {} already configured", apcf_filter_index);
154 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
155 }
156
157 if (*apcf_available_spaces == 0) {
158 INFO(id_, "reached max number of apcf filters");
159 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
160 }
161
162 apcf_scanner_.filters.push_back(rootcanal::apcf::Filter{
163 .filter_index = apcf_filter_index,
164 .feature_selection = apcf_feature_selection,
165 .list_logic_type = apcf_list_logic_type,
166 .filter_logic_type = apcf_filter_logic_type,
167 .rssi_high_thresh = rssi_high_thresh,
168 .delivery_mode = delivery_mode,
169 .onfound_timeout = onfound_timeout,
170 .onfound_timeout_cnt = onfound_timeout_cnt,
171 .rssi_low_thresh = rssi_low_thresh,
172 .onlost_timeout = onlost_timeout,
173 .num_of_tracking_entries = num_of_tracking_entries,
174 });
175
176 *apcf_available_spaces -= 1;
177 return ErrorCode::SUCCESS;
178 }
179
LeApcfDeleteFilteringParameters(uint8_t apcf_filter_index,uint8_t * apcf_available_spaces)180 ErrorCode LinkLayerController::LeApcfDeleteFilteringParameters(uint8_t apcf_filter_index,
181 uint8_t* apcf_available_spaces) {
182 *apcf_available_spaces = properties_.le_apcf_filter_list_size - apcf_scanner_.filters.size();
183
184 if (!apcf_scanner_.HasFilterIndex(apcf_filter_index)) {
185 INFO(id_, "apcf filter index {} is not configured", apcf_filter_index);
186 return ErrorCode::UNKNOWN_CONNECTION;
187 }
188
189 apcf_scanner_.filters.erase(
190 std::remove_if(std::begin(apcf_scanner_.filters), std::end(apcf_scanner_.filters),
191 [&](auto it) { return it.filter_index == apcf_filter_index; }),
192 std::end(apcf_scanner_.filters));
193
194 apcf_scanner_.ClearFilterIndex(apcf_filter_index);
195 *apcf_available_spaces += 1;
196 return ErrorCode::SUCCESS;
197 }
198
LeApcfClearFilteringParameters(uint8_t * apcf_available_spaces)199 ErrorCode LinkLayerController::LeApcfClearFilteringParameters(uint8_t* apcf_available_spaces) {
200 apcf_scanner_.Clear();
201 *apcf_available_spaces = properties_.le_apcf_filter_list_size;
202 return ErrorCode::SUCCESS;
203 }
204
LeApcfBroadcasterAddress(ApcfAction apcf_action,uint8_t apcf_filter_index,bluetooth::hci::Address apcf_broadcaster_address,bluetooth::hci::ApcfApplicationAddressType apcf_application_address_type,uint8_t * apcf_available_spaces)205 ErrorCode LinkLayerController::LeApcfBroadcasterAddress(
206 ApcfAction apcf_action, uint8_t apcf_filter_index,
207 bluetooth::hci::Address apcf_broadcaster_address,
208 bluetooth::hci::ApcfApplicationAddressType apcf_application_address_type,
209 uint8_t* apcf_available_spaces) {
210 ErrorCode status = apcf_scanner_.UpdateFilterList(
211 apcf_scanner_.broadcaster_address_filters,
212 properties_.le_apcf_broadcaster_address_filter_list_size, apcf_action,
213 rootcanal::apcf::BroadcasterAddressFilter{
214 .filter_index = apcf_filter_index,
215 .broadcaster_address = apcf_broadcaster_address,
216 .application_address_type = apcf_application_address_type,
217 });
218
219 *apcf_available_spaces = properties_.le_apcf_broadcaster_address_filter_list_size -
220 apcf_scanner_.broadcaster_address_filters.size();
221
222 return status;
223 }
224
LeApcfServiceUuid(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_uuid_data,uint8_t * apcf_available_spaces)225 ErrorCode LinkLayerController::LeApcfServiceUuid(ApcfAction apcf_action, uint8_t apcf_filter_index,
226 std::vector<uint8_t> apcf_uuid_data,
227 uint8_t* apcf_available_spaces) {
228 size_t uuid_data_size = apcf_uuid_data.size() / 2;
229 std::vector<uint8_t> uuid_data(std::begin(apcf_uuid_data),
230 std::begin(apcf_uuid_data) + uuid_data_size);
231 std::vector<uint8_t> uuid_data_mask(std::begin(apcf_uuid_data) + uuid_data_size,
232 std::end(apcf_uuid_data));
233
234 ErrorCode status = apcf_scanner_.UpdateFilterList(
235 apcf_scanner_.service_uuid_filters, properties_.le_apcf_service_uuid_filter_list_size,
236 apcf_action,
237 rootcanal::apcf::GapDataFilter{
238 .filter_index = apcf_filter_index,
239 .gap_data = uuid_data,
240 .gap_data_mask = uuid_data_mask,
241 });
242
243 *apcf_available_spaces = properties_.le_apcf_service_uuid_filter_list_size -
244 apcf_scanner_.service_uuid_filters.size();
245
246 return status;
247 }
248
LeApcfServiceSolicitationUuid(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_uuid_data,uint8_t * apcf_available_spaces)249 ErrorCode LinkLayerController::LeApcfServiceSolicitationUuid(ApcfAction apcf_action,
250 uint8_t apcf_filter_index,
251 std::vector<uint8_t> apcf_uuid_data,
252 uint8_t* apcf_available_spaces) {
253 size_t uuid_data_size = apcf_uuid_data.size() / 2;
254 std::vector<uint8_t> uuid_data(std::begin(apcf_uuid_data),
255 std::begin(apcf_uuid_data) + uuid_data_size);
256 std::vector<uint8_t> uuid_data_mask(std::begin(apcf_uuid_data) + uuid_data_size,
257 std::end(apcf_uuid_data));
258
259 ErrorCode status = apcf_scanner_.UpdateFilterList(
260 apcf_scanner_.service_solicitation_uuid_filters,
261 properties_.le_apcf_service_solicitation_uuid_filter_list_size, apcf_action,
262 rootcanal::apcf::GapDataFilter{
263 .filter_index = apcf_filter_index,
264 .gap_data = uuid_data,
265 .gap_data_mask = uuid_data_mask,
266 });
267
268 *apcf_available_spaces = properties_.le_apcf_service_solicitation_uuid_filter_list_size -
269 apcf_scanner_.service_solicitation_uuid_filters.size();
270
271 return status;
272 }
273
LeApcfLocalName(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_local_name,uint8_t * apcf_available_spaces)274 ErrorCode LinkLayerController::LeApcfLocalName(ApcfAction apcf_action, uint8_t apcf_filter_index,
275 std::vector<uint8_t> apcf_local_name,
276 uint8_t* apcf_available_spaces) {
277 size_t local_name_size = apcf_local_name.size() / 2;
278 std::vector<uint8_t> local_name(std::begin(apcf_local_name),
279 std::begin(apcf_local_name) + local_name_size);
280 std::vector<uint8_t> local_name_mask(std::begin(apcf_local_name) + local_name_size,
281 std::end(apcf_local_name));
282
283 ErrorCode status = apcf_scanner_.UpdateFilterList(apcf_scanner_.local_name_filters,
284 properties_.le_apcf_local_name_filter_list_size,
285 apcf_action,
286 rootcanal::apcf::GapDataFilter{
287 .filter_index = apcf_filter_index,
288 .gap_data = local_name,
289 .gap_data_mask = local_name_mask,
290 });
291
292 *apcf_available_spaces =
293 properties_.le_apcf_local_name_filter_list_size - apcf_scanner_.local_name_filters.size();
294
295 return status;
296 }
297
LeApcfManufacturerData(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_manufacturer_data,uint8_t * apcf_available_spaces)298 ErrorCode LinkLayerController::LeApcfManufacturerData(ApcfAction apcf_action,
299 uint8_t apcf_filter_index,
300 std::vector<uint8_t> apcf_manufacturer_data,
301 uint8_t* apcf_available_spaces) {
302 size_t manufacturer_data_size = apcf_manufacturer_data.size() / 2;
303 std::vector<uint8_t> manufacturer_data(
304 std::begin(apcf_manufacturer_data),
305 std::begin(apcf_manufacturer_data) + manufacturer_data_size);
306 std::vector<uint8_t> manufacturer_data_mask(
307 std::begin(apcf_manufacturer_data) + manufacturer_data_size,
308 std::end(apcf_manufacturer_data));
309
310 ErrorCode status = apcf_scanner_.UpdateFilterList(
311 apcf_scanner_.manufacturer_data_filters,
312 properties_.le_apcf_manufacturer_data_filter_list_size, apcf_action,
313 rootcanal::apcf::GapDataFilter{
314 .filter_index = apcf_filter_index,
315 .gap_data = manufacturer_data,
316 .gap_data_mask = manufacturer_data_mask,
317 });
318
319 *apcf_available_spaces = properties_.le_apcf_manufacturer_data_filter_list_size -
320 apcf_scanner_.manufacturer_data_filters.size();
321
322 return status;
323 }
324
LeApcfServiceData(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_service_data,uint8_t * apcf_available_spaces)325 ErrorCode LinkLayerController::LeApcfServiceData(ApcfAction apcf_action, uint8_t apcf_filter_index,
326 std::vector<uint8_t> apcf_service_data,
327 uint8_t* apcf_available_spaces) {
328 size_t service_data_size = apcf_service_data.size() / 2;
329 std::vector<uint8_t> service_data(std::begin(apcf_service_data),
330 std::begin(apcf_service_data) + service_data_size);
331 std::vector<uint8_t> service_data_mask(std::begin(apcf_service_data) + service_data_size,
332 std::end(apcf_service_data));
333
334 ErrorCode status = apcf_scanner_.UpdateFilterList(
335 apcf_scanner_.service_data_filters, properties_.le_apcf_service_data_filter_list_size,
336 apcf_action,
337 rootcanal::apcf::GapDataFilter{
338 .filter_index = apcf_filter_index,
339 .gap_data = service_data,
340 .gap_data_mask = service_data_mask,
341 });
342
343 *apcf_available_spaces = properties_.le_apcf_service_data_filter_list_size -
344 apcf_scanner_.service_data_filters.size();
345
346 return status;
347 }
348
LeApcfAdTypeFilter(ApcfAction apcf_action,uint8_t apcf_filter_index,uint8_t apcf_ad_type,std::vector<uint8_t> apcf_ad_data,std::vector<uint8_t> apcf_ad_data_mask,uint8_t * apcf_available_spaces)349 ErrorCode LinkLayerController::LeApcfAdTypeFilter(ApcfAction apcf_action, uint8_t apcf_filter_index,
350 uint8_t apcf_ad_type,
351 std::vector<uint8_t> apcf_ad_data,
352 std::vector<uint8_t> apcf_ad_data_mask,
353 uint8_t* apcf_available_spaces) {
354 ErrorCode status = apcf_scanner_.UpdateFilterList(
355 apcf_scanner_.ad_type_filters, properties_.le_apcf_ad_type_filter_list_size, apcf_action,
356 rootcanal::apcf::AdTypeFilter{
357 .filter_index = apcf_filter_index,
358 .ad_type = apcf_ad_type,
359 .ad_data = std::move(apcf_ad_data),
360 .ad_data_mask = std::move(apcf_ad_data_mask),
361 });
362
363 *apcf_available_spaces =
364 properties_.le_apcf_ad_type_filter_list_size - apcf_scanner_.ad_type_filters.size();
365
366 return status;
367 }
368
369 } // namespace rootcanal
370