blob: 92ff834da481786d265b0a637ebd097f7732fe98 [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.
#pragma once
#include <string>
#include <unordered_set>
#include "garnet/drivers/bluetooth/lib/common/uint128.h"
namespace bluetooth {
namespace common {
class ByteBuffer;
class MutableByteBuffer;
// Represents a 128-bit Bluetooth UUID. This class allows UUID values to be
// constructed in the official Bluetooth 16-bit, 32-bit, and 128-bit formats and
// to be compared against any other Bluetooth UUID.
class UUID final {
public:
// Constructs a UUID from |bytes|. |bytes| should contain a 16-, 32-, or
// 128-bit UUID in little-endian byte order. Returns false if |bytes| contains
// an unsupported size.
static bool FromBytes(const common::ByteBuffer& bytes, UUID* out_uuid);
explicit UUID(const UInt128& uuid128);
explicit UUID(uint16_t uuid16);
explicit UUID(uint32_t uuid32);
// The default constructor initializes all values to zero.
UUID();
// Equality operators.
bool operator==(const UUID& uuid) const;
bool operator==(uint16_t uuid16) const;
bool operator==(uint32_t uuid32) const;
bool operator==(const UInt128& uuid128) const;
bool operator!=(const UUID& uuid) const { return !(*this == uuid); }
bool operator!=(uint16_t uuid16) const { return !(*this == uuid16); }
bool operator!=(uint32_t uuid32) const { return !(*this == uuid32); }
bool operator!=(const UInt128& uuid128) const { return !(*this == uuid128); }
// Compares a UUID with the contents of a raw buffer in little-endian byte
// order. This is useful for making a direct comparison with UUIDs received
// over PDUs. Returns false if |bytes| has an unaccepted size; the only
// accepted sizes for are 2, 4, and 16 for 16-bit, 32-bit, and 128-bit
// formats, respectively.
bool CompareBytes(const common::ByteBuffer& bytes) const;
// Returns the underlying value in little-endian byte order.
const UInt128& value() const { return value_; }
// Returns a string representation of this UUID in the following format:
//
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
//
// where x is one of the alphanumeric characters in the string
// 0123456789abcdef.
std::string ToString() const;
// Returns the number of bytes required to store this UUID.
size_t CompactSize() const;
// Writes a representation of this UUID to |buffer|. Returns the number of
// bytes used. there must be enough space in |buffer| to store
// |compact_size()| bytes.
size_t ToBytes(common::MutableByteBuffer* buffer) const;
// Returns a hash of this UUID.
std::size_t Hash() const;
private:
// We store the type that this was initialized with to allow quick comparison
// with short Bluetooth SIG UUIDs.
enum class Type : uint8_t {
k16Bit,
k32Bit,
k128Bit,
};
// If a quick conversion is possible, these return the 16 or 32 bit values of
// the UUID in host byte order.
uint16_t ValueAs16Bit() const;
uint32_t ValueAs32Bit() const;
Type type_;
UInt128 value_;
};
// Returns true if the given |uuid_string| contains a valid UUID in the
// following format:
//
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
//
// where x is one of the alphanumeric characters in the string
// 0123456789abcdefABCDEF.
bool IsStringValidUuid(const std::string& uuid_string);
// Constructs a 128-bit UUID from a string representation in the following
// formats:
//
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
//
// where x is one of the alphanumeric characters in the string
// 0123456789abcdefABCDEF.
//
// Returns false if the string does not represent a valid Bluetooth UUID.
// Otherwise returns true and populates |out_uuid|.
bool StringToUuid(const std::string& uuid_string, UUID* out_uuid);
// Equality operators
inline bool operator==(uint16_t lhs, const UUID& rhs) {
return rhs == lhs;
}
inline bool operator==(uint32_t lhs, const UUID& rhs) {
return rhs == lhs;
}
inline bool operator==(const UInt128& lhs, const UUID& rhs) {
return rhs == lhs;
}
inline bool operator!=(uint16_t lhs, const UUID& rhs) {
return rhs != lhs;
}
inline bool operator!=(uint32_t lhs, const UUID& rhs) {
return rhs != lhs;
}
inline bool operator!=(const UInt128& lhs, const UUID& rhs) {
return rhs != lhs;
}
} // namespace common
} // namespace bluetooth
// Specialization of std::hash for std::unordered_set, std::unordered_map, etc.
namespace std {
template <>
struct hash<::bluetooth::common::UUID> {
size_t operator()(const ::bluetooth::common::UUID& k) const {
return k.Hash();
}
};
} // namespace std