204 lines
6.3 KiB
C++
204 lines
6.3 KiB
C++
/*
|
|
* Copyright (C) 2022 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "chre/core/ble_request.h"
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include "chre/platform/fatal_error.h"
|
|
#include "chre/util/memory.h"
|
|
|
|
namespace chre {
|
|
|
|
BleRequest::BleRequest() : BleRequest(0, false) {}
|
|
|
|
BleRequest::BleRequest(uint16_t instanceId, bool enable)
|
|
: BleRequest(instanceId, enable, CHRE_BLE_SCAN_MODE_BACKGROUND,
|
|
0 /* reportDelayMs */, nullptr /* filter */) {}
|
|
|
|
BleRequest::BleRequest(uint16_t instanceId, bool enable, chreBleScanMode mode,
|
|
uint32_t reportDelayMs, const chreBleScanFilter *filter)
|
|
: mReportDelayMs(reportDelayMs),
|
|
mInstanceId(instanceId),
|
|
mMode(mode),
|
|
mEnabled(enable),
|
|
mRssiThreshold(CHRE_BLE_RSSI_THRESHOLD_NONE),
|
|
mStatus(RequestStatus::PENDING_REQ) {
|
|
if (filter != nullptr) {
|
|
mRssiThreshold = filter->rssiThreshold;
|
|
if (filter->scanFilterCount > 0) {
|
|
if (!mFilters.resize(filter->scanFilterCount)) {
|
|
FATAL_ERROR("Unable to reserve filter count");
|
|
}
|
|
for (size_t i = 0; i < filter->scanFilterCount; i++) {
|
|
mFilters[i] = filter->scanFilters[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BleRequest::BleRequest(BleRequest &&other) {
|
|
*this = std::move(other);
|
|
}
|
|
|
|
BleRequest &BleRequest::operator=(BleRequest &&other) {
|
|
mInstanceId = other.mInstanceId;
|
|
mMode = other.mMode;
|
|
mReportDelayMs = other.mReportDelayMs;
|
|
mRssiThreshold = other.mRssiThreshold;
|
|
mFilters = std::move(other.mFilters);
|
|
mEnabled = other.mEnabled;
|
|
mStatus = other.mStatus;
|
|
return *this;
|
|
}
|
|
|
|
bool BleRequest::mergeWith(const BleRequest &request) {
|
|
bool attributesChanged = false;
|
|
// Only merge parameters of enabled requests.
|
|
if (request.mEnabled) {
|
|
// Replace disabled request parameters.
|
|
if (!mEnabled) {
|
|
mEnabled = true;
|
|
mMode = request.mMode;
|
|
mReportDelayMs = request.mReportDelayMs;
|
|
mRssiThreshold = request.mRssiThreshold;
|
|
mFilters.clear();
|
|
if (!mFilters.resize(request.mFilters.size())) {
|
|
FATAL_ERROR("Unable to reserve filter count");
|
|
}
|
|
for (size_t i = 0; i < request.mFilters.size(); i++) {
|
|
mFilters[i] = request.mFilters[i];
|
|
}
|
|
attributesChanged = true;
|
|
} else {
|
|
if (mMode < request.mMode) {
|
|
mMode = request.mMode;
|
|
attributesChanged = true;
|
|
}
|
|
if (mReportDelayMs > request.mReportDelayMs) {
|
|
mReportDelayMs = request.mReportDelayMs;
|
|
attributesChanged = true;
|
|
}
|
|
if (mRssiThreshold > request.mRssiThreshold) {
|
|
mRssiThreshold = request.mRssiThreshold;
|
|
attributesChanged = true;
|
|
}
|
|
const DynamicVector<chreBleGenericFilter> &otherFilters =
|
|
request.mFilters;
|
|
if (!otherFilters.empty()) {
|
|
attributesChanged = true;
|
|
size_t originalFilterSize = mFilters.size();
|
|
if (!mFilters.resize(originalFilterSize + otherFilters.size())) {
|
|
FATAL_ERROR("Unable to reserve filter count");
|
|
}
|
|
for (size_t i = 0; i < otherFilters.size(); i++) {
|
|
mFilters[originalFilterSize + i] = otherFilters[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return attributesChanged;
|
|
}
|
|
|
|
bool BleRequest::isEquivalentTo(const BleRequest &request) {
|
|
const DynamicVector<chreBleGenericFilter> &otherFilters = request.mFilters;
|
|
bool isEquivalent = (mEnabled && request.mEnabled && mMode == request.mMode &&
|
|
mReportDelayMs == request.mReportDelayMs &&
|
|
mRssiThreshold == request.mRssiThreshold &&
|
|
mFilters.size() == otherFilters.size());
|
|
if (isEquivalent) {
|
|
for (size_t i = 0; i < otherFilters.size(); i++) {
|
|
if (mFilters[i].len != otherFilters[i].len ||
|
|
mFilters[i].type != otherFilters[i].type ||
|
|
mFilters[i].data != otherFilters[i].data ||
|
|
mFilters[i].dataMask != otherFilters[i].dataMask) {
|
|
isEquivalent = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return isEquivalent;
|
|
}
|
|
|
|
uint16_t BleRequest::getInstanceId() const {
|
|
return mInstanceId;
|
|
}
|
|
|
|
chreBleScanMode BleRequest::getMode() const {
|
|
return mMode;
|
|
}
|
|
|
|
uint32_t BleRequest::getReportDelayMs() const {
|
|
return mReportDelayMs;
|
|
}
|
|
|
|
int8_t BleRequest::getRssiThreshold() const {
|
|
return mRssiThreshold;
|
|
}
|
|
|
|
RequestStatus BleRequest::getRequestStatus() const {
|
|
return mStatus;
|
|
}
|
|
|
|
void BleRequest::setRequestStatus(RequestStatus status) {
|
|
mStatus = status;
|
|
}
|
|
|
|
const DynamicVector<chreBleGenericFilter> &BleRequest::getGenericFilters()
|
|
const {
|
|
return mFilters;
|
|
}
|
|
|
|
chreBleScanFilter BleRequest::getScanFilter() const {
|
|
return chreBleScanFilter{
|
|
mRssiThreshold, static_cast<uint8_t>(mFilters.size()), mFilters.data()};
|
|
}
|
|
|
|
bool BleRequest::isEnabled() const {
|
|
return mEnabled;
|
|
}
|
|
|
|
void BleRequest::logStateToBuffer(DebugDumpWrapper &debugDump,
|
|
bool isPlatformRequest) const {
|
|
if (!isPlatformRequest) {
|
|
debugDump.print(" instanceId=%" PRIu32 " status=%" PRIu8, mInstanceId,
|
|
static_cast<uint8_t>(mStatus));
|
|
}
|
|
debugDump.print(" %s", mEnabled ? " enable" : " disable\n");
|
|
if (mEnabled) {
|
|
debugDump.print(" mode=%" PRIu8 " reportDelayMs=%" PRIu32
|
|
" rssiThreshold=%" PRId8,
|
|
mMode, mReportDelayMs, mRssiThreshold);
|
|
if (isPlatformRequest) {
|
|
debugDump.print(" filters=[");
|
|
for (const chreBleGenericFilter &filter : mFilters) {
|
|
debugDump.print("(type=%" PRIx8, filter.type);
|
|
if (filter.len > 0) {
|
|
debugDump.print(" data=%s dataMask=%s len=%" PRIu8 "), ",
|
|
&filter.data[0], &filter.dataMask[0], filter.len);
|
|
} else {
|
|
debugDump.print("), ");
|
|
}
|
|
}
|
|
debugDump.print("]\n");
|
|
} else {
|
|
debugDump.print(" filterCount=%" PRIu8 "\n",
|
|
static_cast<uint8_t>(mFilters.size()));
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace chre
|