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