blob: 11854aecbec0db6b65711c9f84a67b8a6ddd61d2 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device_address.h"
#include <zircon/assert.h>
#include "src/lib/fxl/strings/string_printf.h"
namespace bt {
namespace {
std::string TypeToString(DeviceAddress::Type type) {
switch (type) {
case DeviceAddress::Type::kBREDR:
return "(BD_ADDR) ";
case DeviceAddress::Type::kLEPublic:
return "(LE publ) ";
case DeviceAddress::Type::kLERandom:
return "(LE rand) ";
case DeviceAddress::Type::kLEAnonymous:
return "(LE anon) ";
}
return "(invalid) ";
}
} // namespace
DeviceAddressBytes::DeviceAddressBytes() { SetToZero(); }
DeviceAddressBytes::DeviceAddressBytes(std::array<uint8_t, kDeviceAddressSize> bytes) {
bytes_ = std::move(bytes);
}
DeviceAddressBytes::DeviceAddressBytes(const ByteBuffer& bytes) {
ZX_DEBUG_ASSERT(bytes.size() == bytes_.size());
std::copy(bytes.cbegin(), bytes.cend(), bytes_.begin());
}
std::string DeviceAddressBytes::ToString() const {
return fxl::StringPrintf("%02X:%02X:%02X:%02X:%02X:%02X", bytes_[5], bytes_[4], bytes_[3],
bytes_[2], bytes_[1], bytes_[0]);
}
void DeviceAddressBytes::SetToZero() { bytes_.fill(0); }
std::size_t DeviceAddressBytes::Hash() const {
uint64_t bytes_as_int = 0;
int shift_amount = 0;
for (const uint8_t& byte : bytes_) {
bytes_as_int |= (static_cast<uint64_t>(byte) << shift_amount);
shift_amount += 8;
}
std::hash<uint64_t> hash_func;
return hash_func(bytes_as_int);
}
DeviceAddress::DeviceAddress() : type_(Type::kBREDR) {}
DeviceAddress::DeviceAddress(Type type, const DeviceAddressBytes& value)
: type_(type), value_(value) {}
DeviceAddress::DeviceAddress(Type type, std::array<uint8_t, kDeviceAddressSize> bytes)
: DeviceAddress(type, DeviceAddressBytes(bytes)) {}
bool DeviceAddress::IsResolvablePrivate() const {
// "The two most significant bits of [a RPA] shall be equal to 0 and 1".
// (Vol 6, Part B, 1.3.2.2).
uint8_t msb = value_.bytes()[5];
return type_ == Type::kLERandom && (msb & 0b01000000) && (~msb & 0b10000000);
}
bool DeviceAddress::IsNonResolvablePrivate() const {
// "The two most significant bits of [a NRPA] shall be equal to 0".
// (Vol 6, Part B, 1.3.2.2).
uint8_t msb = value_.bytes()[5];
return type_ == Type::kLERandom && !(msb & 0b11000000);
}
bool DeviceAddress::IsStaticRandom() const {
// "The two most significant bits of [a static random address] shall be equal
// to 1". (Vol 6, Part B, 1.3.2.1).
uint8_t msb = value_.bytes()[5];
return type_ == Type::kLERandom && ((msb & 0b11000000) == 0b11000000);
}
std::size_t DeviceAddress::Hash() const {
std::size_t const h1(std::hash<int>{}(static_cast<int>(type_)));
std::size_t h2 = value_.Hash();
return h1 ^ (h2 << 1);
}
std::string DeviceAddress::ToString() const { return TypeToString(type_) + value_.ToString(); }
} // namespace bt
namespace std {
hash<bt::DeviceAddress>::result_type hash<bt::DeviceAddress>::operator()(
argument_type const& value) const {
return value.Hash();
}
} // namespace std