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
BleRequest()26 BleRequest::BleRequest() : BleRequest(0, false) {}
27
BleRequest(uint16_t instanceId,bool enable)28 BleRequest::BleRequest(uint16_t instanceId, bool enable)
29 : BleRequest(instanceId, enable, CHRE_BLE_SCAN_MODE_BACKGROUND,
30 0 /* reportDelayMs */, nullptr /* filter */) {}
31
BleRequest(uint16_t instanceId,bool enable,chreBleScanMode mode,uint32_t reportDelayMs,const chreBleScanFilter * filter)32 BleRequest::BleRequest(uint16_t instanceId, bool enable, chreBleScanMode mode,
33 uint32_t reportDelayMs, const chreBleScanFilter *filter)
34 : mReportDelayMs(reportDelayMs),
35 mInstanceId(instanceId),
36 mMode(mode),
37 mEnabled(enable),
38 mRssiThreshold(CHRE_BLE_RSSI_THRESHOLD_NONE),
39 mStatus(RequestStatus::PENDING_REQ) {
40 if (filter != nullptr) {
41 mRssiThreshold = filter->rssiThreshold;
42 if (filter->scanFilterCount > 0) {
43 if (!mFilters.resize(filter->scanFilterCount)) {
44 FATAL_ERROR("Unable to reserve filter count");
45 }
46 for (size_t i = 0; i < filter->scanFilterCount; i++) {
47 mFilters[i] = filter->scanFilters[i];
48 }
49 }
50 }
51 }
52
BleRequest(BleRequest && other)53 BleRequest::BleRequest(BleRequest &&other) {
54 *this = std::move(other);
55 }
56
operator =(BleRequest && other)57 BleRequest &BleRequest::operator=(BleRequest &&other) {
58 mInstanceId = other.mInstanceId;
59 mMode = other.mMode;
60 mReportDelayMs = other.mReportDelayMs;
61 mRssiThreshold = other.mRssiThreshold;
62 mFilters = std::move(other.mFilters);
63 mEnabled = other.mEnabled;
64 mStatus = other.mStatus;
65 return *this;
66 }
67
mergeWith(const BleRequest & request)68 bool BleRequest::mergeWith(const BleRequest &request) {
69 bool attributesChanged = false;
70 // Only merge parameters of enabled requests.
71 if (request.mEnabled) {
72 // Replace disabled request parameters.
73 if (!mEnabled) {
74 mEnabled = true;
75 mMode = request.mMode;
76 mReportDelayMs = request.mReportDelayMs;
77 mRssiThreshold = request.mRssiThreshold;
78 mFilters.clear();
79 if (!mFilters.resize(request.mFilters.size())) {
80 FATAL_ERROR("Unable to reserve filter count");
81 }
82 for (size_t i = 0; i < request.mFilters.size(); i++) {
83 mFilters[i] = request.mFilters[i];
84 }
85 attributesChanged = true;
86 } else {
87 if (mMode < request.mMode) {
88 mMode = request.mMode;
89 attributesChanged = true;
90 }
91 if (mReportDelayMs > request.mReportDelayMs) {
92 mReportDelayMs = request.mReportDelayMs;
93 attributesChanged = true;
94 }
95 if (mRssiThreshold > request.mRssiThreshold) {
96 mRssiThreshold = request.mRssiThreshold;
97 attributesChanged = true;
98 }
99 const DynamicVector<chreBleGenericFilter> &otherFilters =
100 request.mFilters;
101 if (!otherFilters.empty()) {
102 attributesChanged = true;
103 size_t originalFilterSize = mFilters.size();
104 if (!mFilters.resize(originalFilterSize + otherFilters.size())) {
105 FATAL_ERROR("Unable to reserve filter count");
106 }
107 for (size_t i = 0; i < otherFilters.size(); i++) {
108 mFilters[originalFilterSize + i] = otherFilters[i];
109 }
110 }
111 }
112 }
113 return attributesChanged;
114 }
115
isEquivalentTo(const BleRequest & request)116 bool BleRequest::isEquivalentTo(const BleRequest &request) {
117 const DynamicVector<chreBleGenericFilter> &otherFilters = request.mFilters;
118 bool isEquivalent = (mEnabled && request.mEnabled && mMode == request.mMode &&
119 mReportDelayMs == request.mReportDelayMs &&
120 mRssiThreshold == request.mRssiThreshold &&
121 mFilters.size() == otherFilters.size());
122 if (isEquivalent) {
123 for (size_t i = 0; i < otherFilters.size(); i++) {
124 if (mFilters[i].len != otherFilters[i].len ||
125 mFilters[i].type != otherFilters[i].type ||
126 mFilters[i].data != otherFilters[i].data ||
127 mFilters[i].dataMask != otherFilters[i].dataMask) {
128 isEquivalent = false;
129 break;
130 }
131 }
132 }
133 return isEquivalent;
134 }
135
getInstanceId() const136 uint16_t BleRequest::getInstanceId() const {
137 return mInstanceId;
138 }
139
getMode() const140 chreBleScanMode BleRequest::getMode() const {
141 return mMode;
142 }
143
getReportDelayMs() const144 uint32_t BleRequest::getReportDelayMs() const {
145 return mReportDelayMs;
146 }
147
getRssiThreshold() const148 int8_t BleRequest::getRssiThreshold() const {
149 return mRssiThreshold;
150 }
151
getRequestStatus() const152 RequestStatus BleRequest::getRequestStatus() const {
153 return mStatus;
154 }
155
setRequestStatus(RequestStatus status)156 void BleRequest::setRequestStatus(RequestStatus status) {
157 mStatus = status;
158 }
159
getGenericFilters() const160 const DynamicVector<chreBleGenericFilter> &BleRequest::getGenericFilters()
161 const {
162 return mFilters;
163 }
164
getScanFilter() const165 chreBleScanFilter BleRequest::getScanFilter() const {
166 return chreBleScanFilter{
167 mRssiThreshold, static_cast<uint8_t>(mFilters.size()), mFilters.data()};
168 }
169
isEnabled() const170 bool BleRequest::isEnabled() const {
171 return mEnabled;
172 }
173
logStateToBuffer(DebugDumpWrapper & debugDump,bool isPlatformRequest) const174 void BleRequest::logStateToBuffer(DebugDumpWrapper &debugDump,
175 bool isPlatformRequest) const {
176 if (!isPlatformRequest) {
177 debugDump.print(" instanceId=%" PRIu32 " status=%" PRIu8, mInstanceId,
178 static_cast<uint8_t>(mStatus));
179 }
180 debugDump.print(" %s", mEnabled ? " enable" : " disable\n");
181 if (mEnabled) {
182 debugDump.print(" mode=%" PRIu8 " reportDelayMs=%" PRIu32
183 " rssiThreshold=%" PRId8,
184 mMode, mReportDelayMs, mRssiThreshold);
185 if (isPlatformRequest) {
186 debugDump.print(" filters=[");
187 for (const chreBleGenericFilter &filter : mFilters) {
188 debugDump.print("(type=%" PRIx8, filter.type);
189 if (filter.len > 0) {
190 debugDump.print(" data=%s dataMask=%s len=%" PRIu8 "), ",
191 &filter.data[0], &filter.dataMask[0], filter.len);
192 } else {
193 debugDump.print("), ");
194 }
195 }
196 debugDump.print("]\n");
197 } else {
198 debugDump.print(" filterCount=%" PRIu8 "\n",
199 static_cast<uint8_t>(mFilters.size()));
200 }
201 }
202 }
203
204 } // namespace chre