1 /*
2 * Copyright (C) 2022 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 "chre/core/ble_request.h"
18
19 #include <inttypes.h>
20
21 #include "chre/platform/fatal_error.h"
22 #include "chre/util/memory.h"
23
24 namespace chre {
25
26 namespace {
27
filtersMatch(const chreBleGenericFilter & filter,const chreBleGenericFilter & otherFilter)28 bool filtersMatch(const chreBleGenericFilter &filter,
29 const chreBleGenericFilter &otherFilter) {
30 return filter.len == otherFilter.len && filter.type == otherFilter.type &&
31 (memcmp(filter.data, otherFilter.data, filter.len) == 0) &&
32 (memcmp(filter.dataMask, otherFilter.dataMask, filter.len) == 0);
33 }
34
broadcasterFiltersMatch(const chreBleBroadcasterAddressFilter & filter,const chreBleBroadcasterAddressFilter & otherFilter)35 bool broadcasterFiltersMatch(
36 const chreBleBroadcasterAddressFilter &filter,
37 const chreBleBroadcasterAddressFilter &otherFilter) {
38 return (memcmp(filter.broadcasterAddress, otherFilter.broadcasterAddress,
39 sizeof(filter.broadcasterAddress)) == 0);
40 }
41
42 } // namespace
43
BleRequest()44 BleRequest::BleRequest()
45 : BleRequest(0 /* instanceId */, false /* enable */, nullptr /* cookie */) {
46 }
47
BleRequest(uint16_t instanceId,bool enable,const void * cookie)48 BleRequest::BleRequest(uint16_t instanceId, bool enable, const void *cookie)
49 : BleRequest(instanceId, enable, CHRE_BLE_SCAN_MODE_BACKGROUND,
50 0 /* reportDelayMs */, nullptr /* filter */, cookie) {}
51
BleRequest(uint16_t instanceId,bool enable,chreBleScanMode mode,uint32_t reportDelayMs,const chreBleScanFilterV1_9 * filter,const void * cookie)52 BleRequest::BleRequest(uint16_t instanceId, bool enable, chreBleScanMode mode,
53 uint32_t reportDelayMs,
54 const chreBleScanFilterV1_9 *filter, const void *cookie)
55 : mReportDelayMs(reportDelayMs),
56 mInstanceId(instanceId),
57 mMode(mode),
58 mEnabled(enable),
59 mRssiThreshold(CHRE_BLE_RSSI_THRESHOLD_NONE),
60 mStatus(RequestStatus::PENDING_REQ),
61 mCookie(cookie) {
62 if (filter != nullptr) {
63 mRssiThreshold = filter->rssiThreshold;
64 if (filter->genericFilterCount > 0) {
65 if (!mGenericFilters.resize(filter->genericFilterCount)) {
66 FATAL_ERROR("Unable to reserve filter count");
67 }
68 memcpy(mGenericFilters.data(), filter->genericFilters,
69 sizeof(chreBleGenericFilter) * filter->genericFilterCount);
70 }
71 if (filter->broadcasterAddressFilterCount > 0) {
72 if (!mBroadcasterFilters.resize(filter->broadcasterAddressFilterCount)) {
73 FATAL_ERROR("Unable to reserve broadcaster address filter count");
74 }
75 memcpy(mBroadcasterFilters.data(), filter->broadcasterAddressFilters,
76 sizeof(chreBleBroadcasterAddressFilter) *
77 filter->broadcasterAddressFilterCount);
78 }
79 }
80 }
81
BleRequest(BleRequest && other)82 BleRequest::BleRequest(BleRequest &&other) {
83 *this = std::move(other);
84 }
85
operator =(BleRequest && other)86 BleRequest &BleRequest::operator=(BleRequest &&other) {
87 mInstanceId = other.mInstanceId;
88 mMode = other.mMode;
89 mReportDelayMs = other.mReportDelayMs;
90 mRssiThreshold = other.mRssiThreshold;
91 mGenericFilters = std::move(other.mGenericFilters);
92 mBroadcasterFilters = std::move(other.mBroadcasterFilters);
93 mEnabled = other.mEnabled;
94 mStatus = other.mStatus;
95 mCookie = other.mCookie;
96 return *this;
97 }
98
mergeWith(const BleRequest & request)99 bool BleRequest::mergeWith(const BleRequest &request) {
100 // Only merge parameters of enabled requests.
101 if (!request.mEnabled) {
102 return false;
103 }
104 bool attributesChanged = false;
105 // Replace disabled request parameters.
106 if (!mEnabled) {
107 mEnabled = true;
108 mMode = request.mMode;
109 mReportDelayMs = request.mReportDelayMs;
110 mRssiThreshold = request.mRssiThreshold;
111 attributesChanged = true;
112 } else {
113 if (mMode < request.mMode) {
114 mMode = request.mMode;
115 attributesChanged = true;
116 }
117 if (mReportDelayMs > request.mReportDelayMs) {
118 mReportDelayMs = request.mReportDelayMs;
119 attributesChanged = true;
120 }
121 if (mRssiThreshold > request.mRssiThreshold) {
122 mRssiThreshold = request.mRssiThreshold;
123 attributesChanged = true;
124 }
125 }
126 const DynamicVector<chreBleGenericFilter> &otherFilters =
127 request.mGenericFilters;
128 for (const chreBleGenericFilter &otherFilter : otherFilters) {
129 bool addFilter = true;
130 for (const chreBleGenericFilter &filter : mGenericFilters) {
131 if (filtersMatch(filter, otherFilter)) {
132 addFilter = false;
133 break;
134 }
135 }
136 if (addFilter) {
137 attributesChanged = true;
138 if (!mGenericFilters.push_back(otherFilter)) {
139 FATAL_ERROR("Unable to merge filters");
140 }
141 }
142 }
143 const DynamicVector<chreBleBroadcasterAddressFilter>
144 &otherBroadcasterFilters = request.mBroadcasterFilters;
145 for (const chreBleBroadcasterAddressFilter &otherFilter :
146 otherBroadcasterFilters) {
147 bool addFilter = true;
148 for (const chreBleBroadcasterAddressFilter &filter : mBroadcasterFilters) {
149 if (broadcasterFiltersMatch(filter, otherFilter)) {
150 addFilter = false;
151 break;
152 }
153 }
154 if (addFilter) {
155 attributesChanged = true;
156 if (!mBroadcasterFilters.push_back(otherFilter)) {
157 FATAL_ERROR("Unable to merge filters");
158 }
159 }
160 }
161 return attributesChanged;
162 }
163
isEquivalentTo(const BleRequest & request)164 bool BleRequest::isEquivalentTo(const BleRequest &request) {
165 const DynamicVector<chreBleGenericFilter> &otherFilters =
166 request.mGenericFilters;
167 const DynamicVector<chreBleBroadcasterAddressFilter>
168 &otherBroadcasterFilters = request.mBroadcasterFilters;
169 bool isEquivalent =
170 (mEnabled && request.mEnabled && mMode == request.mMode &&
171 mReportDelayMs == request.mReportDelayMs &&
172 mRssiThreshold == request.mRssiThreshold &&
173 mGenericFilters.size() == otherFilters.size() &&
174 mBroadcasterFilters.size() == otherBroadcasterFilters.size());
175 if (isEquivalent) {
176 for (size_t i = 0; i < otherFilters.size(); i++) {
177 if (!filtersMatch(mGenericFilters[i], otherFilters[i])) {
178 isEquivalent = false;
179 break;
180 }
181 }
182 for (size_t i = 0; i < otherBroadcasterFilters.size(); i++) {
183 if (!broadcasterFiltersMatch(mBroadcasterFilters[i],
184 otherBroadcasterFilters[i])) {
185 isEquivalent = false;
186 break;
187 }
188 }
189 }
190 return isEquivalent;
191 }
192
getInstanceId() const193 uint16_t BleRequest::getInstanceId() const {
194 return mInstanceId;
195 }
196
getMode() const197 chreBleScanMode BleRequest::getMode() const {
198 return mMode;
199 }
200
getReportDelayMs() const201 uint32_t BleRequest::getReportDelayMs() const {
202 return mReportDelayMs;
203 }
204
getRssiThreshold() const205 int8_t BleRequest::getRssiThreshold() const {
206 return mRssiThreshold;
207 }
208
getRequestStatus() const209 RequestStatus BleRequest::getRequestStatus() const {
210 return mStatus;
211 }
212
setRequestStatus(RequestStatus status)213 void BleRequest::setRequestStatus(RequestStatus status) {
214 mStatus = status;
215 }
216
getGenericFilters() const217 const DynamicVector<chreBleGenericFilter> &BleRequest::getGenericFilters()
218 const {
219 return mGenericFilters;
220 }
221
222 const DynamicVector<chreBleBroadcasterAddressFilter> &
getBroadcasterFilters() const223 BleRequest::getBroadcasterFilters() const {
224 return mBroadcasterFilters;
225 }
226
getScanFilter() const227 chreBleScanFilterV1_9 BleRequest::getScanFilter() const {
228 return chreBleScanFilterV1_9{
229 mRssiThreshold, static_cast<uint8_t>(mGenericFilters.size()),
230 mGenericFilters.data(), static_cast<uint8_t>(mBroadcasterFilters.size()),
231 mBroadcasterFilters.data()};
232 }
233
isEnabled() const234 bool BleRequest::isEnabled() const {
235 return mEnabled;
236 }
237
getCookie() const238 const void *BleRequest::getCookie() const {
239 return mCookie;
240 }
241
logStateToBuffer(DebugDumpWrapper & debugDump,bool isPlatformRequest) const242 void BleRequest::logStateToBuffer(DebugDumpWrapper &debugDump,
243 bool isPlatformRequest) const {
244 if (!isPlatformRequest) {
245 debugDump.print(" instanceId=%" PRIu16 " status=%" PRIu8, mInstanceId,
246 static_cast<uint8_t>(mStatus));
247 }
248 debugDump.print(" %s", mEnabled ? " enable" : " disable\n");
249 if (mEnabled) {
250 debugDump.print(
251 " mode=%" PRIu8 " reportDelayMs=%" PRIu32 " rssiThreshold=%" PRId8,
252 static_cast<uint8_t>(mMode), mReportDelayMs, mRssiThreshold);
253 if (isPlatformRequest) {
254 debugDump.print(" genericFilters=[");
255 for (const chreBleGenericFilter &filter : mGenericFilters) {
256 debugDump.print("(type=%" PRIx8, filter.type);
257 if (filter.len > 0) {
258 debugDump.print(" data=%s dataMask=%s len=%" PRIu8 "), ",
259 &filter.data[0], &filter.dataMask[0], filter.len);
260 } else {
261 debugDump.print("), ");
262 }
263 }
264 debugDump.print("]\n");
265 debugDump.print(" broadcasterAddressFilters=[");
266 for (const chreBleBroadcasterAddressFilter &filter :
267 mBroadcasterFilters) {
268 debugDump.print(
269 "(address=%02X:%02X:%02X:%02X:%02X:%02X), ",
270 filter.broadcasterAddress[5], filter.broadcasterAddress[4],
271 filter.broadcasterAddress[3], filter.broadcasterAddress[2],
272 filter.broadcasterAddress[1], filter.broadcasterAddress[0]);
273 }
274 debugDump.print("]\n");
275 } else {
276 debugDump.print(" genericFilterCount=%" PRIu8
277 " broadcasterFilterCount=%" PRIu8 "\n",
278 static_cast<uint8_t>(mGenericFilters.size()),
279 static_cast<uint8_t>(mBroadcasterFilters.size()));
280 }
281 }
282 }
283
284 } // namespace chre