• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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