mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Move Bluetooth UUID16 conversion into Uuid class.
PiperOrigin-RevId: 735496175
This commit is contained in:
committed by
Copybara-Service
parent
b8815f5229
commit
b62b56c75e
@@ -20,6 +20,7 @@
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -27,9 +28,8 @@
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
@@ -165,14 +165,6 @@ constexpr absl::Duration kPeripheralExpiryTime = Minutes(15);
|
||||
// Prevent too frequent cleanup tasks.
|
||||
constexpr absl::Duration kMaxPeripheralCleanupFrequency = Minutes(3);
|
||||
|
||||
// The most significant bits and the least significant bits or Bluetooth Base
|
||||
// UUID.
|
||||
// See Bluetooth Core Specification 6.0 Vol.3, Part B, Section 2.5.1
|
||||
const std::uint64_t kBluetoothBaseUuidMsb = 0x0000000000001000;
|
||||
const std::uint64_t kBluetoothBaseUuidLsb = 0x800000805F9B34FB;
|
||||
// Mask for UUID16 bits.
|
||||
const std::uint64_t kBluetoothBaseUuid16MsbMask = 0x0000FFFF00000000;
|
||||
|
||||
// Service Data - 16-bit UUID. From Bluetooth Assigned Numbers Section 2.3.
|
||||
constexpr uint8_t kUuid16ServiceDataType = 0x16;
|
||||
} // namespace
|
||||
@@ -448,12 +440,15 @@ bool BleV2Medium::StartScanning(const Uuid& service_uuid,
|
||||
|
||||
// This assumes that service_uuid has a valid UUID16 alias.
|
||||
// Verify that service_uuid in in valid range.
|
||||
DCHECK_EQ(service_uuid_.GetMostSigBits() & ~kBluetoothBaseUuid16MsbMask,
|
||||
kBluetoothBaseUuidMsb);
|
||||
DCHECK_EQ(service_uuid_.GetLeastSigBits(), kBluetoothBaseUuidLsb);
|
||||
std::optional<uint16_t> service_uuid16 = service_uuid_.GetBtUuid16();
|
||||
if (!service_uuid16.has_value()) {
|
||||
LOG(WARNING) << __func__
|
||||
<< ": BLE cannot start to scan because the service UUID is "
|
||||
"not in valid range.";
|
||||
return false;
|
||||
}
|
||||
|
||||
service_uuid16_ =
|
||||
(service_uuid_.GetMostSigBits() & kBluetoothBaseUuid16MsbMask) >> 32;
|
||||
service_uuid16_ = *service_uuid16;
|
||||
std::unique_ptr<AdvertisementWatcher> watcher =
|
||||
CreateBleWatcher(service_uuid16_);
|
||||
if (watcher == nullptr) {
|
||||
@@ -752,17 +747,16 @@ bool BleV2Medium::StartBleAdvertising(
|
||||
|
||||
for (const auto& it : advertising_data.service_data) {
|
||||
DataWriter data_writer;
|
||||
data_writer.ByteOrder(ByteOrder::LittleEndian);
|
||||
|
||||
std::string uuid_string = it.first.Get16BitAsString();
|
||||
int uuid;
|
||||
if (!absl::SimpleHexAtoi(uuid_string, &uuid)) {
|
||||
std::optional<uint16_t> uuid16 = it.first.GetBtUuid16();
|
||||
if (!uuid16.has_value()) {
|
||||
LOG(WARNING) << "BLE failed to get service UUID.";
|
||||
return false;
|
||||
}
|
||||
LOG(WARNING) << "BLE service UUID: " << absl::StrCat(absl::Hex(*uuid16));
|
||||
|
||||
LOG(WARNING) << "BLE service UUID: " << absl::StrFormat("%#x", uuid);
|
||||
|
||||
data_writer.WriteUInt16(((uuid >> 8) & 0xff) | ((uuid & 0xff) << 8));
|
||||
data_writer.WriteUInt16(*uuid16);
|
||||
|
||||
for (int i = 0; i < it.second.size(); ++i) {
|
||||
data_writer.WriteByte(static_cast<uint8_t>(*(it.second.data() + i)));
|
||||
@@ -1271,15 +1265,17 @@ void BleV2Medium::AdvertisementFoundHandler(
|
||||
uint16_t service_uuid16 = data_reader.ReadUInt16();
|
||||
|
||||
for (auto service_uuid : service_uuid_list) {
|
||||
uint16_t uuid16 =
|
||||
(service_uuid.GetMostSigBits() & kBluetoothBaseUuid16MsbMask) >> 32;
|
||||
if (uuid16 == service_uuid16) {
|
||||
std::optional<uint16_t> uuid16 = service_uuid.GetBtUuid16();
|
||||
if (!uuid16.has_value()) {
|
||||
continue;
|
||||
}
|
||||
if (*uuid16 == service_uuid16) {
|
||||
std::string data;
|
||||
|
||||
uint8_t unconsumed_buffer_length = data_reader.UnconsumedBufferLength();
|
||||
if (unconsumed_buffer_length > 27) {
|
||||
LOG(INFO) << "Skipping extended advertisement with service "
|
||||
<< service_uuid.Get16BitAsString();
|
||||
<< absl::StrCat(absl::Hex(*uuid16));
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < unconsumed_buffer_length; i++) {
|
||||
|
||||
@@ -34,6 +34,15 @@
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
// The most significant bits and the least significant bits or Bluetooth Base
|
||||
// UUID.
|
||||
// See Bluetooth Core Specification 6.0 Vol.3, Part B, Section 2.5.1
|
||||
const std::uint64_t kBluetoothBaseUuidMsb = 0x0000000000001000;
|
||||
const std::uint64_t kBluetoothBaseUuidLsb = 0x800000805F9B34FB;
|
||||
// Mask for UUID16 bits.
|
||||
const std::uint64_t kBluetoothBaseUuid16MsbMask = 0x0000FFFF00000000;
|
||||
|
||||
|
||||
std::ostream& write_hex(std::ostream& os, absl::string_view data) {
|
||||
for (const auto b : data) {
|
||||
os << std::setfill('0') << std::setw(2) << std::hex << std::uppercase
|
||||
@@ -135,6 +144,16 @@ std::string Uuid::Get16BitAsString() const {
|
||||
return sixteen_bit_string.str();
|
||||
}
|
||||
|
||||
std::optional<uint16_t> Uuid::GetBtUuid16() const {
|
||||
// Verify that the UUID is in valid range.
|
||||
if ((GetMostSigBits() & ~kBluetoothBaseUuid16MsbMask) !=
|
||||
kBluetoothBaseUuidMsb ||
|
||||
GetLeastSigBits() != kBluetoothBaseUuidLsb) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return (GetMostSigBits() & kBluetoothBaseUuid16MsbMask) >> 32;
|
||||
}
|
||||
|
||||
std::array<char, 16> Uuid::data() const {
|
||||
std::array<char, 16> data;
|
||||
data[0] = (most_sig_bits_ >> 56) & 0x0ff;
|
||||
|
||||
@@ -58,6 +58,10 @@ class Uuid final {
|
||||
// This is needed because Android only support UUID 16 bits in service data
|
||||
// section in advertising data
|
||||
std::string Get16BitAsString() const;
|
||||
// If the UUID has a valid Bluetooth UUID16 alias, return it, otherwise
|
||||
// return nullopt.
|
||||
// See Bluetooth Core Specification 6.0 Vol.3, Part B, Section 2.5.1
|
||||
std::optional<uint16_t> GetBtUuid16() const;
|
||||
|
||||
std::uint64_t GetMostSigBits() const { return most_sig_bits_; }
|
||||
std::uint64_t GetLeastSigBits() const { return least_sig_bits_; }
|
||||
|
||||
@@ -143,5 +143,36 @@ TEST(UuidTest, ConstructUuidFromString) {
|
||||
EXPECT_EQ(std::string(*a), "12345678-1234-1234-1234-123456789012");
|
||||
}
|
||||
|
||||
TEST(UuidTest, GetBtUuid16Succeeds) {
|
||||
std::optional<Uuid> a =
|
||||
Uuid::FromString("0000ABCD-0000-1000-8000-00805F9B34FB");
|
||||
ASSERT_TRUE(a.has_value());
|
||||
|
||||
std::optional<uint16_t> bt_uuid16 = a->GetBtUuid16();
|
||||
|
||||
ASSERT_TRUE(bt_uuid16.has_value());
|
||||
EXPECT_EQ(bt_uuid16, 0xABCD);
|
||||
}
|
||||
|
||||
TEST(UuidTest, GetBtUuid16FailsMsb) {
|
||||
std::optional<Uuid> a =
|
||||
Uuid::FromString("0100ABCD-0000-1000-8000-00805F9B34FB");
|
||||
ASSERT_TRUE(a.has_value());
|
||||
|
||||
std::optional<uint16_t> bt_uuid16 = a->GetBtUuid16();
|
||||
|
||||
EXPECT_FALSE(bt_uuid16.has_value());
|
||||
}
|
||||
|
||||
TEST(UuidTest, GetBtUuid16FailsLsb) {
|
||||
std::optional<Uuid> a =
|
||||
Uuid::FromString("0000ABCD-0000-1000-8000-00905F9B34FB");
|
||||
ASSERT_TRUE(a.has_value());
|
||||
|
||||
std::optional<uint16_t> bt_uuid16 = a->GetBtUuid16();
|
||||
|
||||
EXPECT_FALSE(bt_uuid16.has_value());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
|
||||
Reference in New Issue
Block a user