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), [&](auto it) {
32 return it.filter_index == apcf_filter_index;
33 });
34 }
35
ClearFilterIndex(uint8_t apcf_filter_index)36 void ApcfScanner::ClearFilterIndex(uint8_t apcf_filter_index) {
37 broadcaster_address_filters.erase(
38 std::remove_if(
39 std::begin(broadcaster_address_filters),
40 std::end(broadcaster_address_filters),
41 [&](auto it) { return it.filter_index == apcf_filter_index; }),
42 std::end(broadcaster_address_filters));
43 service_uuid_filters.erase(
44 std::remove_if(
45 std::begin(service_uuid_filters), std::end(service_uuid_filters),
46 [&](auto it) { return it.filter_index == apcf_filter_index; }),
47 std::end(service_uuid_filters));
48 service_solicitation_uuid_filters.erase(
49 std::remove_if(
50 std::begin(service_solicitation_uuid_filters),
51 std::end(service_solicitation_uuid_filters),
52 [&](auto it) { return it.filter_index == apcf_filter_index; }),
53 std::end(service_solicitation_uuid_filters));
54 local_name_filters.erase(
55 std::remove_if(
56 std::begin(local_name_filters), std::end(local_name_filters),
57 [&](auto it) { return it.filter_index == apcf_filter_index; }),
58 std::end(local_name_filters));
59 manufacturer_data_filters.erase(
60 std::remove_if(
61 std::begin(manufacturer_data_filters),
62 std::end(manufacturer_data_filters),
63 [&](auto it) { return it.filter_index == apcf_filter_index; }),
64 std::end(manufacturer_data_filters));
65 service_data_filters.erase(
66 std::remove_if(
67 std::begin(service_data_filters), std::end(service_data_filters),
68 [&](auto it) { return it.filter_index == apcf_filter_index; }),
69 std::end(service_data_filters));
70 ad_type_filters.erase(
71 std::remove_if(
72 std::begin(ad_type_filters), std::end(ad_type_filters),
73 [&](auto it) { return it.filter_index == apcf_filter_index; }),
74 std::end(ad_type_filters));
75 }
76
Clear()77 void ApcfScanner::Clear() {
78 filters.clear();
79 broadcaster_address_filters.clear();
80 service_uuid_filters.clear();
81 service_solicitation_uuid_filters.clear();
82 local_name_filters.clear();
83 manufacturer_data_filters.clear();
84 service_data_filters.clear();
85 ad_type_filters.clear();
86 }
87
88 template <typename T>
UpdateFilterList(std::vector<T> & filter_list,size_t max_filter_list_size,bluetooth::hci::ApcfAction action,T filter)89 ErrorCode ApcfScanner::UpdateFilterList(std::vector<T>& filter_list,
90 size_t max_filter_list_size,
91 bluetooth::hci::ApcfAction action,
92 T filter) {
93 if (!HasFilterIndex(filter.filter_index)) {
94 return ErrorCode::UNKNOWN_CONNECTION;
95 }
96
97 switch (action) {
98 case ApcfAction::ADD: {
99 if (filter_list.size() == max_filter_list_size) {
100 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
101 }
102
103 filter_list.emplace_back(std::move(filter));
104 return ErrorCode::SUCCESS;
105 }
106 case ApcfAction::DELETE: {
107 // Delete will delete the specified data in the specified filter.
108 filter_list.erase(
109 std::remove_if(std::begin(filter_list), std::end(filter_list),
110 [&](auto it) { return it == filter; }),
111 std::end(filter_list));
112 return ErrorCode::SUCCESS;
113 }
114 case ApcfAction::CLEAR: {
115 // Clear will clear all data in the specified filter.
116 filter_list.erase(
117 std::remove_if(
118 std::begin(filter_list), std::end(filter_list),
119 [&](auto it) { return it.filter_index == filter.filter_index; }),
120 std::end(filter_list));
121 return ErrorCode::SUCCESS;
122 }
123 default:
124 break;
125 }
126
127 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
128 }
129
operator ==(BroadcasterAddressFilter const & lhs,BroadcasterAddressFilter const & rhs)130 bool operator==(BroadcasterAddressFilter const& lhs,
131 BroadcasterAddressFilter const& rhs) {
132 return lhs.filter_index == rhs.filter_index &&
133 lhs.broadcaster_address == rhs.broadcaster_address &&
134 lhs.application_address_type == rhs.application_address_type;
135 }
136
operator ==(GapDataFilter const & lhs,GapDataFilter const & rhs)137 bool operator==(GapDataFilter const& lhs, GapDataFilter const& rhs) {
138 return lhs.filter_index == rhs.filter_index && lhs.gap_data == rhs.gap_data &&
139 lhs.gap_data_mask == rhs.gap_data_mask;
140 }
141
operator ==(AdTypeFilter const & lhs,AdTypeFilter const & rhs)142 bool operator==(AdTypeFilter const& lhs, AdTypeFilter const& rhs) {
143 return lhs.filter_index == rhs.filter_index && lhs.ad_type == rhs.ad_type &&
144 lhs.ad_data == rhs.ad_data && lhs.ad_data_mask == rhs.ad_data_mask;
145 }
146
147 } // namespace rootcanal::apcf
148
149 namespace rootcanal {
150
151 using bluetooth::hci::ApcfAction;
152
LeApcfEnable(bool apcf_enable)153 ErrorCode LinkLayerController::LeApcfEnable(bool apcf_enable) {
154 apcf_scanner_.enable = apcf_enable;
155 return ErrorCode::SUCCESS;
156 }
157
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)158 ErrorCode LinkLayerController::LeApcfAddFilteringParameters(
159 uint8_t apcf_filter_index, uint16_t apcf_feature_selection,
160 uint16_t apcf_list_logic_type, uint8_t apcf_filter_logic_type,
161 uint8_t rssi_high_thresh, bluetooth::hci::DeliveryMode delivery_mode,
162 uint16_t onfound_timeout, uint8_t onfound_timeout_cnt,
163 uint8_t rssi_low_thresh, uint16_t onlost_timeout,
164 uint16_t num_of_tracking_entries, uint8_t* apcf_available_spaces) {
165 *apcf_available_spaces =
166 properties_.le_apcf_filter_list_size - apcf_scanner_.filters.size();
167
168 if (apcf_scanner_.HasFilterIndex(apcf_filter_index)) {
169 INFO(id_, "apcf filter index {} already configured", apcf_filter_index);
170 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
171 }
172
173 if (*apcf_available_spaces == 0) {
174 INFO(id_, "reached max number of apcf filters");
175 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
176 }
177
178 apcf_scanner_.filters.push_back(rootcanal::apcf::Filter{
179 .filter_index = apcf_filter_index,
180 .feature_selection = apcf_feature_selection,
181 .list_logic_type = apcf_list_logic_type,
182 .filter_logic_type = apcf_filter_logic_type,
183 .rssi_high_thresh = rssi_high_thresh,
184 .delivery_mode = delivery_mode,
185 .onfound_timeout = onfound_timeout,
186 .onfound_timeout_cnt = onfound_timeout_cnt,
187 .rssi_low_thresh = rssi_low_thresh,
188 .onlost_timeout = onlost_timeout,
189 .num_of_tracking_entries = num_of_tracking_entries,
190 });
191
192 *apcf_available_spaces -= 1;
193 return ErrorCode::SUCCESS;
194 }
195
LeApcfDeleteFilteringParameters(uint8_t apcf_filter_index,uint8_t * apcf_available_spaces)196 ErrorCode LinkLayerController::LeApcfDeleteFilteringParameters(
197 uint8_t apcf_filter_index, uint8_t* apcf_available_spaces) {
198 *apcf_available_spaces =
199 properties_.le_apcf_filter_list_size - apcf_scanner_.filters.size();
200
201 if (!apcf_scanner_.HasFilterIndex(apcf_filter_index)) {
202 INFO(id_, "apcf filter index {} is not configured", apcf_filter_index);
203 return ErrorCode::UNKNOWN_CONNECTION;
204 }
205
206 apcf_scanner_.filters.erase(
207 std::remove_if(
208 std::begin(apcf_scanner_.filters),
209 std::end(apcf_scanner_.filters),
210 [&](auto it) { return it.filter_index == apcf_filter_index; }),
211 std::end(apcf_scanner_.filters));
212
213 apcf_scanner_.ClearFilterIndex(apcf_filter_index);
214 *apcf_available_spaces += 1;
215 return ErrorCode::SUCCESS;
216 }
217
LeApcfClearFilteringParameters(uint8_t * apcf_available_spaces)218 ErrorCode LinkLayerController::LeApcfClearFilteringParameters(
219 uint8_t* apcf_available_spaces) {
220 apcf_scanner_.Clear();
221 *apcf_available_spaces = properties_.le_apcf_filter_list_size;
222 return ErrorCode::SUCCESS;
223 }
224
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)225 ErrorCode LinkLayerController::LeApcfBroadcasterAddress(
226 ApcfAction apcf_action, uint8_t apcf_filter_index,
227 bluetooth::hci::Address apcf_broadcaster_address,
228 bluetooth::hci::ApcfApplicationAddressType apcf_application_address_type,
229 uint8_t* apcf_available_spaces) {
230 ErrorCode status = apcf_scanner_.UpdateFilterList(
231 apcf_scanner_.broadcaster_address_filters,
232 properties_.le_apcf_broadcaster_address_filter_list_size, apcf_action,
233 rootcanal::apcf::BroadcasterAddressFilter{
234 .filter_index = apcf_filter_index,
235 .broadcaster_address = apcf_broadcaster_address,
236 .application_address_type = apcf_application_address_type,
237 });
238
239 *apcf_available_spaces =
240 properties_.le_apcf_broadcaster_address_filter_list_size -
241 apcf_scanner_.broadcaster_address_filters.size();
242
243 return status;
244 }
245
LeApcfServiceUuid(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_uuid_data,uint8_t * apcf_available_spaces)246 ErrorCode LinkLayerController::LeApcfServiceUuid(
247 ApcfAction apcf_action, uint8_t apcf_filter_index,
248 std::vector<uint8_t> apcf_uuid_data, uint8_t* apcf_available_spaces) {
249 size_t uuid_data_size = apcf_uuid_data.size() / 2;
250 std::vector<uint8_t> uuid_data(std::begin(apcf_uuid_data),
251 std::begin(apcf_uuid_data) + uuid_data_size);
252 std::vector<uint8_t> uuid_data_mask(
253 std::begin(apcf_uuid_data) + uuid_data_size, std::end(apcf_uuid_data));
254
255 ErrorCode status = apcf_scanner_.UpdateFilterList(
256 apcf_scanner_.service_uuid_filters,
257 properties_.le_apcf_service_uuid_filter_list_size, apcf_action,
258 rootcanal::apcf::GapDataFilter{
259 .filter_index = apcf_filter_index,
260 .gap_data = uuid_data,
261 .gap_data_mask = uuid_data_mask,
262 });
263
264 *apcf_available_spaces = properties_.le_apcf_service_uuid_filter_list_size -
265 apcf_scanner_.service_uuid_filters.size();
266
267 return status;
268 }
269
LeApcfServiceSolicitationUuid(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_uuid_data,uint8_t * apcf_available_spaces)270 ErrorCode LinkLayerController::LeApcfServiceSolicitationUuid(
271 ApcfAction apcf_action, uint8_t apcf_filter_index,
272 std::vector<uint8_t> apcf_uuid_data, uint8_t* apcf_available_spaces) {
273 size_t uuid_data_size = apcf_uuid_data.size() / 2;
274 std::vector<uint8_t> uuid_data(std::begin(apcf_uuid_data),
275 std::begin(apcf_uuid_data) + uuid_data_size);
276 std::vector<uint8_t> uuid_data_mask(
277 std::begin(apcf_uuid_data) + uuid_data_size, std::end(apcf_uuid_data));
278
279 ErrorCode status = apcf_scanner_.UpdateFilterList(
280 apcf_scanner_.service_solicitation_uuid_filters,
281 properties_.le_apcf_service_solicitation_uuid_filter_list_size,
282 apcf_action,
283 rootcanal::apcf::GapDataFilter{
284 .filter_index = apcf_filter_index,
285 .gap_data = uuid_data,
286 .gap_data_mask = uuid_data_mask,
287 });
288
289 *apcf_available_spaces =
290 properties_.le_apcf_service_solicitation_uuid_filter_list_size -
291 apcf_scanner_.service_solicitation_uuid_filters.size();
292
293 return status;
294 }
295
LeApcfLocalName(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_local_name,uint8_t * apcf_available_spaces)296 ErrorCode LinkLayerController::LeApcfLocalName(
297 ApcfAction apcf_action, uint8_t apcf_filter_index,
298 std::vector<uint8_t> apcf_local_name, uint8_t* apcf_available_spaces) {
299 size_t local_name_size = apcf_local_name.size() / 2;
300 std::vector<uint8_t> local_name(
301 std::begin(apcf_local_name),
302 std::begin(apcf_local_name) + local_name_size);
303 std::vector<uint8_t> local_name_mask(
304 std::begin(apcf_local_name) + local_name_size, std::end(apcf_local_name));
305
306 ErrorCode status = apcf_scanner_.UpdateFilterList(
307 apcf_scanner_.local_name_filters,
308 properties_.le_apcf_local_name_filter_list_size, apcf_action,
309 rootcanal::apcf::GapDataFilter{
310 .filter_index = apcf_filter_index,
311 .gap_data = local_name,
312 .gap_data_mask = local_name_mask,
313 });
314
315 *apcf_available_spaces = properties_.le_apcf_local_name_filter_list_size -
316 apcf_scanner_.local_name_filters.size();
317
318 return status;
319 }
320
LeApcfManufacturerData(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_manufacturer_data,uint8_t * apcf_available_spaces)321 ErrorCode LinkLayerController::LeApcfManufacturerData(
322 ApcfAction apcf_action, uint8_t apcf_filter_index,
323 std::vector<uint8_t> apcf_manufacturer_data,
324 uint8_t* apcf_available_spaces) {
325 size_t manufacturer_data_size = apcf_manufacturer_data.size() / 2;
326 std::vector<uint8_t> manufacturer_data(
327 std::begin(apcf_manufacturer_data),
328 std::begin(apcf_manufacturer_data) + manufacturer_data_size);
329 std::vector<uint8_t> manufacturer_data_mask(
330 std::begin(apcf_manufacturer_data) + manufacturer_data_size,
331 std::end(apcf_manufacturer_data));
332
333 ErrorCode status = apcf_scanner_.UpdateFilterList(
334 apcf_scanner_.manufacturer_data_filters,
335 properties_.le_apcf_manufacturer_data_filter_list_size, apcf_action,
336 rootcanal::apcf::GapDataFilter{
337 .filter_index = apcf_filter_index,
338 .gap_data = manufacturer_data,
339 .gap_data_mask = manufacturer_data_mask,
340 });
341
342 *apcf_available_spaces =
343 properties_.le_apcf_manufacturer_data_filter_list_size -
344 apcf_scanner_.manufacturer_data_filters.size();
345
346 return status;
347 }
348
LeApcfServiceData(ApcfAction apcf_action,uint8_t apcf_filter_index,std::vector<uint8_t> apcf_service_data,uint8_t * apcf_available_spaces)349 ErrorCode LinkLayerController::LeApcfServiceData(
350 ApcfAction apcf_action, uint8_t apcf_filter_index,
351 std::vector<uint8_t> apcf_service_data, uint8_t* apcf_available_spaces) {
352 size_t service_data_size = apcf_service_data.size() / 2;
353 std::vector<uint8_t> service_data(
354 std::begin(apcf_service_data),
355 std::begin(apcf_service_data) + service_data_size);
356 std::vector<uint8_t> service_data_mask(
357 std::begin(apcf_service_data) + service_data_size,
358 std::end(apcf_service_data));
359
360 ErrorCode status = apcf_scanner_.UpdateFilterList(
361 apcf_scanner_.service_data_filters,
362 properties_.le_apcf_service_data_filter_list_size, apcf_action,
363 rootcanal::apcf::GapDataFilter{
364 .filter_index = apcf_filter_index,
365 .gap_data = service_data,
366 .gap_data_mask = service_data_mask,
367 });
368
369 *apcf_available_spaces = properties_.le_apcf_service_data_filter_list_size -
370 apcf_scanner_.service_data_filters.size();
371
372 return status;
373 }
374
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)375 ErrorCode LinkLayerController::LeApcfAdTypeFilter(
376 ApcfAction apcf_action, uint8_t apcf_filter_index, uint8_t apcf_ad_type,
377 std::vector<uint8_t> apcf_ad_data, std::vector<uint8_t> apcf_ad_data_mask,
378 uint8_t* apcf_available_spaces) {
379 ErrorCode status = apcf_scanner_.UpdateFilterList(
380 apcf_scanner_.ad_type_filters,
381 properties_.le_apcf_ad_type_filter_list_size, apcf_action,
382 rootcanal::apcf::AdTypeFilter{
383 .filter_index = apcf_filter_index,
384 .ad_type = apcf_ad_type,
385 .ad_data = std::move(apcf_ad_data),
386 .ad_data_mask = std::move(apcf_ad_data_mask),
387 });
388
389 *apcf_available_spaces = properties_.le_apcf_ad_type_filter_list_size -
390 apcf_scanner_.ad_type_filters.size();
391
392 return status;
393 }
394
395 } // namespace rootcanal
396