Populate Tx Power for Legacy BLE Adv Reports
Bug: 309912569
Test: Verify using ble_world and pixel buds that Tx Power is populated
Change-Id: I8cb005bd30c716c3391a9c1c743b1838ca185205
diff --git a/core/ble_request_manager.cc b/core/ble_request_manager.cc
index 7eac94d..0b1237f 100644
--- a/core/ble_request_manager.cc
+++ b/core/ble_request_manager.cc
@@ -21,6 +21,7 @@
#include "chre/platform/log.h"
#include "chre/util/fixed_size_vector.h"
#include "chre/util/nested_data_ptr.h"
+#include "chre/util/system/ble_util.h"
#include "chre/util/system/event_callbacks.h"
namespace chre {
@@ -273,6 +274,10 @@
void BleRequestManager::handleAdvertisementEvent(
struct chreBleAdvertisementEvent *event) {
+ for (uint16_t i = 0; i < event->numReports; i++) {
+ populateLegacyAdvertisingReportFields(
+ const_cast<chreBleAdvertisingReport &>(event->reports[i]));
+ }
EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
CHRE_EVENT_BLE_ADVERTISEMENT, event, freeAdvertisingEventCallback);
}
diff --git a/util/include/chre/util/system/ble_util.h b/util/include/chre/util/system/ble_util.h
new file mode 100644
index 0000000..5072008
--- /dev/null
+++ b/util/include/chre/util/system/ble_util.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef CHRE_UTIL_SYSTEM_BLE_UTIL_H_
+#define CHRE_UTIL_SYSTEM_BLE_UTIL_H_
+
+#include "chre_api/chre.h"
+
+namespace chre {
+
+/**
+ * Populates a legacy chreBleAdvertisingReport's fields with values from the
+ * payload. The chreBleAdvertisingReport is based on the LE Extended Advertising
+ * Report Event defined in the BT Core Spec v5.3, Vol 4, Part E,
+ * Section 7.7.65.13. But for legacy LE Advertising Report Events (BT Core Spec
+ * v5.3, Vol 4, Part E, Section 7.7.65.2), some of these fields are only
+ * included in the payload. We parse out these fields to make it easier for the
+ * nanoapp to access this data.
+ *
+ * @param report CHRE BLE Advertising Report
+ */
+void populateLegacyAdvertisingReportFields(chreBleAdvertisingReport &report);
+
+} // namespace chre
+
+#endif // CHRE_UTIL_SYSTEM_BLE_UTIL_H_
diff --git a/util/system/ble_util.cc b/util/system/ble_util.cc
new file mode 100644
index 0000000..eb61426
--- /dev/null
+++ b/util/system/ble_util.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 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/util/system/ble_util.h"
+
+#include <cinttypes>
+
+#include "chre/platform/log.h"
+
+namespace chre {
+
+namespace {
+
+// Tx Power Level AD Type defined in the BT Core Spec v5.3 Assigned Numbers,
+// Generic Access Profile (ref:
+// https://www.bluetooth.com/specifications/assigned-numbers/).
+constexpr uint8_t kTxPowerLevelAdType = 0x0A;
+constexpr uint8_t kAdTypeOffset = 1;
+constexpr uint8_t kExpectedAdDataLength = 2;
+
+/**
+ * Gets the TX Power from the data field of legacy AD reports. This function
+ * parses the advertising data which is defined in the BT Core Spec v5.3, Vol 3,
+ * Part C, Section 11, Advertising and Scan Response Data Format, and checks for
+ * the presence of the Tx Power Level AD Type.
+ *
+ * @param data Advertising data.
+ * @param dataLength Length of advertising data.
+ * @return int8_t Tx Power value.
+ */
+int8_t getTxPowerFromLegacyReport(const uint8_t *data, size_t dataLength) {
+ size_t i = 0;
+ while (i < dataLength) {
+ uint8_t adDataLength = data[i];
+ if (adDataLength == 0 || (adDataLength >= dataLength - i)) {
+ break;
+ }
+ if (data[i + kAdTypeOffset] == kTxPowerLevelAdType &&
+ adDataLength == kExpectedAdDataLength) {
+ return static_cast<int8_t>(data[i + kExpectedAdDataLength]);
+ }
+ i += kAdTypeOffset + adDataLength;
+ }
+ return CHRE_BLE_TX_POWER_NONE;
+}
+
+} // namespace
+
+void populateLegacyAdvertisingReportFields(chreBleAdvertisingReport &report) {
+ if ((report.eventTypeAndDataStatus & CHRE_BLE_EVENT_TYPE_FLAG_LEGACY) != 0 &&
+ report.txPower == CHRE_BLE_TX_POWER_NONE) {
+ report.txPower = getTxPowerFromLegacyReport(report.data, report.dataLength);
+ }
+}
+
+} // namespace chre
diff --git a/util/tests/ble_util_test.cc b/util/tests/ble_util_test.cc
new file mode 100644
index 0000000..762a6aa
--- /dev/null
+++ b/util/tests/ble_util_test.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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 "gtest/gtest.h"
+
+#include <string.h>
+
+#include "chre/util/system/ble_util.h"
+
+TEST(BleUtil, PopulateTxPower) {
+ chreBleAdvertisingReport report;
+ memset(&report, 0, sizeof(report));
+ report.txPower = CHRE_BLE_TX_POWER_NONE;
+ report.eventTypeAndDataStatus = CHRE_BLE_EVENT_TYPE_FLAG_LEGACY;
+ int8_t txPower = -11;
+ uint8_t data[3] = {0x02, 0x0A, static_cast<uint8_t>(txPower)};
+ report.data = data;
+ report.dataLength = 3;
+ chre::populateLegacyAdvertisingReportFields(report);
+ EXPECT_EQ(report.txPower, txPower);
+}
diff --git a/util/util.mk b/util/util.mk
index 2baf4f4..1a7ae3e 100644
--- a/util/util.mk
+++ b/util/util.mk
@@ -18,6 +18,7 @@
COMMON_SRCS += $(CHRE_PREFIX)/util/nanoapp/debug.cc
COMMON_SRCS += $(CHRE_PREFIX)/util/nanoapp/string.cc
COMMON_SRCS += $(CHRE_PREFIX)/util/nanoapp/wifi.cc
+COMMON_SRCS += $(CHRE_PREFIX)/util/system/ble_util.cc
COMMON_SRCS += $(CHRE_PREFIX)/util/system/event_callbacks.cc
COMMON_SRCS += $(CHRE_PREFIX)/util/system/debug_dump.cc