210 lines
6.2 KiB
C++
210 lines
6.2 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 {
|
|
|
|
namespace {
|
|
|
|
bool filtersMatch(const chreBleGenericFilter &filter,
|
|
const chreBleGenericFilter &otherFilter) {
|
|
return filter.len == otherFilter.len && filter.type == otherFilter.type &&
|
|
(memcmp(filter.data, otherFilter.data, filter.len) == 0) &&
|
|
(memcmp(filter.dataMask, otherFilter.dataMask, filter.len) == 0);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
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) {
|
|
// Only merge parameters of enabled requests.
|
|
if (!request.mEnabled) {
|
|
return false;
|
|
}
|
|
bool attributesChanged = false;
|
|
// Replace disabled request parameters.
|
|
if (!mEnabled) {
|
|
mEnabled = true;
|
|
mMode = request.mMode;
|
|
mReportDelayMs = request.mReportDelayMs;
|
|
mRssiThreshold = request.mRssiThreshold;
|
|
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;
|
|
for (const chreBleGenericFilter &otherFilter : otherFilters) {
|
|
bool addFilter = true;
|
|
for (const chreBleGenericFilter &filter : mFilters) {
|
|
if (filtersMatch(filter, otherFilter)) {
|
|
addFilter = false;
|
|
break;
|
|
}
|
|
}
|
|
if (addFilter) {
|
|
attributesChanged = true;
|
|
if (!mFilters.push_back(otherFilter)) {
|
|
FATAL_ERROR("Unable to merge filters");
|
|
}
|
|
}
|
|
}
|
|
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 (!filtersMatch(mFilters[i], otherFilters[i])) {
|
|
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=%" PRIu16 " 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,
|
|
static_cast<uint8_t>(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
|