xref: /aosp_15_r20/system/chre/apps/nearby/location/lbs/contexthub/nanoapps/nearby/filter.cc (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2023 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 "location/lbs/contexthub/nanoapps/nearby/filter.h"
18 
19 #include <chre/util/macros.h>
20 #include <inttypes.h>
21 #include <pb_decode.h>
22 
23 #include <cstdint>
24 #include <iterator>
25 
26 #include "chre_api/chre.h"
27 #include "location/lbs/contexthub/nanoapps/nearby/ble_scan_record.h"
28 #include "location/lbs/contexthub/nanoapps/nearby/fast_pair_filter.h"
29 #ifdef ENABLE_PRESENCE
30 #include "location/lbs/contexthub/nanoapps/nearby/presence_crypto_mic.h"
31 #include "location/lbs/contexthub/nanoapps/nearby/presence_filter.h"
32 #endif
33 #include "third_party/contexthub/chre/util/include/chre/util/nanoapp/log.h"
34 
35 #define LOG_TAG "[NEARBY][FILTER]"
36 
37 namespace nearby {
38 
39 constexpr nearby_BleFilters kDefaultBleFilters = nearby_BleFilters_init_zero;
40 
Update(const uint8_t * message,uint32_t message_size)41 bool Filter::Update(const uint8_t *message, uint32_t message_size) {
42   LOGD("Decode a Filters message with size %" PRIu32, message_size);
43   ble_filters_ = kDefaultBleFilters;
44   pb_istream_t stream = pb_istream_from_buffer(message, message_size);
45   if (!pb_decode(&stream, nearby_BleFilters_fields, &ble_filters_)) {
46     LOGE("Failed to decode a Filters message.");
47     return false;
48   }
49   // Print filters for debug.
50   LOGD_SENSITIVE_INFO("BLE filters counter %d", ble_filters_.filter_count);
51   if (ble_filters_.filter_count > 0) {
52     LOGD_SENSITIVE_INFO("BLE filter 0 data element count %d",
53                         ble_filters_.filter[0].data_element_count);
54     if (ble_filters_.filter[0].data_element_count > 0) {
55       LOGD_SENSITIVE_INFO(
56           "Data Element 0, key: %" PRIi32
57           " value[0]: %d,"
58           " has key: %d, has value: %d, has value length %d,"
59           " value length %" PRIu32,
60           ble_filters_.filter[0].data_element[0].key,
61           ble_filters_.filter[0].data_element[0].value[0],
62           ble_filters_.filter[0].data_element[0].has_key,
63           ble_filters_.filter[0].data_element[0].has_value,
64           ble_filters_.filter[0].data_element[0].has_value_length,
65           ble_filters_.filter[0].data_element[0].value_length);
66     }
67   }
68   for (int i = 0; i < ble_filters_.filter_count; i++) {
69     const nearby_BleFilter *filter = &ble_filters_.filter[i];
70     // Sets the scan interval to satisfy the minimal latency requirement.
71     if (filter->has_latency_ms && filter->latency_ms < scan_interval_ms_) {
72       scan_interval_ms_ = filter->latency_ms;
73     }
74   }
75   return true;
76 }
77 
MatchBle(const chreBleAdvertisingReport & report,chre::DynamicVector<nearby_BleFilterResult> * filter_results,chre::DynamicVector<nearby_BleFilterResult> * fp_filter_results)78 void Filter::MatchBle(
79     const chreBleAdvertisingReport &report,
80     chre::DynamicVector<nearby_BleFilterResult> *filter_results,
81     chre::DynamicVector<nearby_BleFilterResult> *fp_filter_results) {
82 #ifndef ENABLE_PRESENCE
83   UNUSED_VAR(filter_results);
84 #endif
85   LOGD("MatchBle");
86 
87   nearby_BleFilterResult result;
88   auto record = BleScanRecord::Parse(report.data, report.dataLength);
89   // Log the service data for debug only.
90   for (const auto &ble_service_data : record.service_data) {
91     LOGD_SENSITIVE_INFO("Receive service data with uuid %" PRIX16,
92                         ble_service_data.uuid);
93     for (int i = 0; i < ble_service_data.length; i++) {
94       LOGD_SENSITIVE_INFO("%" PRIx8, ble_service_data.data[i]);
95     }
96     LOGD_SENSITIVE_INFO("Service data end.");
97   }
98   for (int filter_index = 0; filter_index < ble_filters_.filter_count;
99        filter_index++) {
100     LOGD("MatchPresence advertisements.");
101     // TODO(b/193756395): multiple matched results can share the same BLE
102     // event. Optimize the memory usage by avoiding duplicated BLE events
103     // across multiple results.
104     result = nearby_BleFilterResult_init_zero;
105     result.has_id = true;
106     result.id = static_cast<uint32_t>(filter_index);
107     result.has_tx_power = true;
108     result.tx_power = static_cast<int32_t>(report.txPower);
109     result.has_rssi = true;
110     result.rssi = static_cast<int32_t>(report.rssi);
111     result.has_bluetooth_address = true;
112     // The buffer size has already been checked.
113     static_assert(std::size(result.bluetooth_address) == CHRE_BLE_ADDRESS_LEN);
114     memcpy(result.bluetooth_address, report.address, std::size(report.address));
115     result.has_timestamp_ns = true;
116     result.timestamp_ns =
117         report.timestamp +
118         static_cast<uint64_t>(chreGetEstimatedHostTimeOffset());
119     if (MatchFastPair(ble_filters_.filter[filter_index], record, &result)) {
120       LOGD("Add a matched Fast Pair filter result");
121       fp_filter_results->push_back(result);
122       return;
123     }
124 #ifdef ENABLE_PRESENCE
125     if (MatchPresenceV0(ble_filters_.filter[filter_index], record, &result) ||
126         MatchPresenceV1(ble_filters_.filter[filter_index], record,
127                         PresenceCryptoMicImpl(), &result)) {
128       LOGD("Filter result TX power %" PRId32 ", RSSI %" PRId32, result.tx_power,
129            result.rssi);
130 
131       LOGD("Add a matched Presence filter result");
132       filter_results->push_back(result);
133     }
134 #endif
135   }
136 }
137 
138 }  // namespace nearby
139