xref: /aosp_15_r20/system/chre/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.cc (revision 84e339476a462649f82315436d70fd732297a399)
1 #include "location/lbs/contexthub/nanoapps/nearby/tracker_filter.h"
2 
3 #include <inttypes.h>
4 #include <cstddef>
5 #include <cstdint>
6 #include <cstring>
7 #include <utility>
8 
9 #include "chre_api/chre.h"
10 #include "location/lbs/contexthub/nanoapps/nearby/byte_array.h"
11 #include "location/lbs/contexthub/nanoapps/nearby/hw_filter.h"
12 #include "location/lbs/contexthub/nanoapps/nearby/nearby_extension.h"
13 #include "location/lbs/contexthub/nanoapps/nearby/proto/nearby_extension.nanopb.h"
14 #include "location/lbs/contexthub/nanoapps/nearby/tracker_storage.h"
15 #include "third_party/contexthub/chre/util/include/chre/util/dynamic_vector.h"
16 #include "third_party/contexthub/chre/util/include/chre/util/nanoapp/log.h"
17 #include "third_party/nanopb/pb.h"
18 #include "third_party/nanopb/pb_encode.h"
19 
20 #define LOG_TAG "[NEARBY][TRACKER_FILTER]"
21 
22 namespace nearby {
23 
24 const size_t kChreBleGenericFilterDataSize = 29;
25 constexpr nearby_extension_TrackerReport kEmptyTrackerReport =
26     nearby_extension_TrackerReport_init_zero;
27 
Update(const chreHostEndpointInfo & host_info,const nearby_extension_ExtConfigRequest_TrackerFilterConfig & filter_config,chre::DynamicVector<chreBleGenericFilter> * generic_filters,nearby_extension_ExtConfigResponse * config_response)28 void TrackerFilter::Update(
29     const chreHostEndpointInfo &host_info,
30     const nearby_extension_ExtConfigRequest_TrackerFilterConfig &filter_config,
31     chre::DynamicVector<chreBleGenericFilter> *generic_filters,
32     nearby_extension_ExtConfigResponse *config_response) {
33   host_info_ = host_info;
34   LOGD("Update tracker filters %u from %s", filter_config.hardware_filter_count,
35        host_info_.packageName);
36   config_response->has_result = true;
37   config_response->result = CHREX_NEARBY_RESULT_OK;
38   // Sets scan filter configuration and returns hardware filters to
39   // generic_filters used in ble scanner's scan settings.
40   chre::DynamicVector<chreBleGenericFilter> hardware_filters;
41   for (int i = 0; i < filter_config.hardware_filter_count; i++) {
42     const nearby_extension_ChreBleGenericFilter &hw_filter =
43         filter_config.hardware_filter[i];
44     chreBleGenericFilter generic_filter;
45     generic_filter.type = hw_filter.type;
46     generic_filter.len = static_cast<uint8_t>(hw_filter.len);
47     memcpy(generic_filter.data, hw_filter.data, kChreBleGenericFilterDataSize);
48     memcpy(generic_filter.dataMask, hw_filter.data_mask,
49            kChreBleGenericFilterDataSize);
50     generic_filters->push_back(generic_filter);
51     hardware_filters.push_back(generic_filter);
52   }
53   scan_filter_config_.hardware_filters = std::move(hardware_filters);
54   scan_filter_config_.rssi_threshold = filter_config.rssi_threshold;
55   scan_filter_config_.active_interval_ms = filter_config.active_interval_ms;
56   scan_filter_config_.active_window_ms = filter_config.active_window_ms;
57   ConfigureActiveState();
58   ConfigureScanControlTimers();
59   // Sets batch configuration
60   batch_config_.sample_interval_ms = filter_config.sample_interval_ms;
61   batch_config_.max_tracker_count = filter_config.max_tracker_count;
62   batch_config_.notify_threshold_tracker_count =
63       filter_config.notify_threshold_tracker_count;
64   batch_config_.max_history_count = filter_config.max_history_count;
65   batch_config_.lost_timeout_ms = filter_config.lost_timeout_ms;
66   batch_config_.opportunistic_flush_threshold_time_ms =
67       filter_config.opportunistic_flush_threshold_time_ms;
68 }
69 
ConfigureActiveState()70 void TrackerFilter::ConfigureActiveState() {
71   if (!scan_filter_config_.hardware_filters.empty()) {
72     SetActiveState();
73   } else {
74     ClearActiveState();
75   }
76 }
77 
ConfigureScanControlTimers()78 void TrackerFilter::ConfigureScanControlTimers() {
79   // The timer based scan is only enabled when the hardware scan filters are not
80   // empty and the active window and interval are valid. The active interval
81   // must be greater than the active window so that the timer based scan can
82   // function properly.
83   if (!scan_filter_config_.hardware_filters.empty() &&
84       scan_filter_config_.active_window_ms > 0) {
85     if (scan_filter_config_.active_interval_ms <=
86         scan_filter_config_.active_window_ms) {
87       LOGE("Invalid active interval %" PRIu32
88            " ms, must be greater than active window %" PRIu32 " ms.",
89            scan_filter_config_.active_interval_ms,
90            scan_filter_config_.active_window_ms);
91       return;
92     }
93     // Sets active interval and window timer duration.
94     active_interval_timer_.SetDurationMs(
95         scan_filter_config_.active_interval_ms);
96     active_window_timer_.SetDurationMs(scan_filter_config_.active_window_ms);
97     // Starts active interval and window timers.
98     if (active_interval_timer_.StartTimer()) {
99       active_window_timer_.StartTimer();
100     }
101   } else if (scan_filter_config_.hardware_filters.empty()) {
102     active_interval_timer_.StopTimer();
103   }
104 }
105 
MatchAndSave(const chre::DynamicVector<chreBleAdvertisingReport> & ble_adv_reports,TrackerStorage & tracker_storage)106 void TrackerFilter::MatchAndSave(
107     const chre::DynamicVector<chreBleAdvertisingReport> &ble_adv_reports,
108     TrackerStorage &tracker_storage) {
109   for (const auto &report : ble_adv_reports) {
110     if (HwFilter::CheckRssi(scan_filter_config_.rssi_threshold, report) &&
111         HwFilter::Match(scan_filter_config_.hardware_filters, report)) {
112       tracker_storage.Push(report, batch_config_);
113     }
114   }
115 }
116 
EncodeTrackerReport(TrackerReport & tracker_report,ByteArray data_buf,size_t * encoded_size)117 bool TrackerFilter::EncodeTrackerReport(TrackerReport &tracker_report,
118                                         ByteArray data_buf,
119                                         size_t *encoded_size) {
120   nearby_extension_TrackerReport filter_result = kEmptyTrackerReport;
121   filter_result.has_report = true;
122   nearby_extension_ChreBleAdvertisingReport &report_proto =
123       filter_result.report;
124   report_proto.has_timestamp = true;
125   report_proto.timestamp =
126       tracker_report.header.timestamp +
127       static_cast<uint64_t>(chreGetEstimatedHostTimeOffset());
128   report_proto.has_event_type_and_data_status = true;
129   report_proto.event_type_and_data_status =
130       tracker_report.header.eventTypeAndDataStatus;
131   report_proto.has_address_type = true;
132   report_proto.address_type =
133       static_cast<nearby_extension_ChreBleAdvertisingReport_AddressType>(
134           tracker_report.header.addressType);
135   report_proto.has_address = true;
136   for (size_t i = 0; i < CHRE_BLE_ADDRESS_LEN; i++) {
137     report_proto.address[i] = tracker_report.header.address[i];
138   }
139   report_proto.has_tx_power = true;
140   report_proto.tx_power = tracker_report.header.txPower;
141   report_proto.has_rssi = true;
142   report_proto.rssi = tracker_report.header.rssi;
143   report_proto.has_data_length = true;
144   report_proto.data_length = tracker_report.header.dataLength;
145   if (tracker_report.header.dataLength > 0) {
146     report_proto.has_data = true;
147   }
148   for (size_t i = 0; i < tracker_report.header.dataLength; i++) {
149     report_proto.data[i] = tracker_report.data[i];
150   }
151   size_t idx = 0;
152   for (const auto &history : tracker_report.historian) {
153     nearby_extension_TrackerHistory &history_proto =
154         filter_result.historian[idx];
155     history_proto.has_found_count = true;
156     history_proto.found_count = history.found_count;
157     history_proto.has_first_found_time_ms = true;
158     history_proto.first_found_time_ms = history.first_found_time_ms;
159     history_proto.has_last_found_time_ms = true;
160     history_proto.last_found_time_ms = history.last_found_time_ms;
161     history_proto.has_lost_time_ms = true;
162     history_proto.lost_time_ms = history.lost_time_ms;
163     history_proto.has_state = true;
164     history_proto.state =
165         history.state == TrackerState::kPresent
166             ? nearby_extension_TrackerHistory_TrackerState_PRESENT
167             : nearby_extension_TrackerHistory_TrackerState_ABSENT;
168     ++idx;
169   }
170   filter_result.historian_count = static_cast<pb_size_t>(idx);
171   if (!pb_get_encoded_size(encoded_size, nearby_extension_TrackerReport_fields,
172                            &filter_result)) {
173     LOGE("Failed to get batch filter result size.");
174     return false;
175   }
176   pb_ostream_t ostream = pb_ostream_from_buffer(data_buf.data, data_buf.length);
177   if (!pb_encode(&ostream, nearby_extension_TrackerReport_fields,
178                  &filter_result)) {
179     LOGE("Unable to encode protobuf for BatchFilterResult, error %s",
180          PB_GET_ERROR(&ostream));
181     return false;
182   }
183   return true;
184 }
185 
186 }  // namespace nearby
187