/****************************************************************************** * * Copyright (C) 2017 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. * ******************************************************************************/ #pragma once #include #include #include #include #include "storage/serializable.h" namespace bluetooth { namespace hci { // This class is representing Bluetooth UUIDs across whole stack. // Here are some general endianness rules: // 1. UUID is internally kept as as Big Endian. // 2. Bytes representing UUID coming from upper layers, Java or Binder, are Big Endian. // 3. Bytes representing UUID coming from lower layer, HCI packets, are Little Endian. // 4. UUID in storage is always string. class Uuid final : public storage::Serializable { public: static constexpr size_t kNumBytes128 = 16; static constexpr size_t kNumBytes32 = 4; static constexpr size_t kNumBytes16 = 2; static constexpr size_t kString128BitLen = 36; static const Uuid kEmpty; // 00000000-0000-0000-0000-000000000000 using UUID128Bit = std::array; Uuid() = default; inline uint8_t* data() { return uu.data(); } inline const uint8_t* data() const { return uu.data(); } // storage::Serializable methods // Converts string representing 128, 32, or 16 bit UUID in // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, xxxxxxxx, or xxxx format to UUID. // return uuid on success, std::nullopt otherwise static std::optional FromString(const std::string& uuid); static std::optional FromLegacyConfigString(const std::string& uuid); // Returns string representing this UUID in // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format, lowercase. std::string ToString() const override; std::string ToLegacyConfigString() const override; // Creates and returns a random 128-bit UUID. static Uuid GetRandom(); // Returns the shortest possible representation of this UUID in bytes. Either // kNumBytes16, kNumBytes32, or kNumBytes128 size_t GetShortestRepresentationSize() const; // Returns true if this UUID can be represented as 16 bit. bool Is16Bit() const; // Returns 16 bit Little Endian representation of this UUID. Use // GetShortestRepresentationSize() or Is16Bit() before using this method. uint16_t As16Bit() const; // Returns 32 bit Little Endian representation of this UUID. Use // GetShortestRepresentationSize() before using this method. uint32_t As32Bit() const; // Converts 16bit Little Endian representation of UUID to UUID static Uuid From16Bit(uint16_t uuid16bit); // Converts 32bit Little Endian representation of UUID to UUID static Uuid From32Bit(uint32_t uuid32bit); // Converts 128 bit Big Endian array representing UUID to UUID. static Uuid From128BitBE(const UUID128Bit& uuid) { Uuid u(uuid); return u; } // Converts 128 bit Big Endian array representing UUID to UUID. |uuid| points // to beginning of array. static Uuid From128BitBE(const uint8_t* uuid); // Converts 128 bit Little Endian array representing UUID to UUID. static Uuid From128BitLE(const UUID128Bit& uuid); // Converts 128 bit Little Endian array representing UUID to UUID. |uuid| // points to beginning of array. static Uuid From128BitLE(const uint8_t* uuid); // Returns 128 bit Little Endian representation of this UUID UUID128Bit To128BitLE() const; // Returns 128 bit Big Endian representation of this UUID const UUID128Bit& To128BitBE() const; // Returns true if this UUID is equal to kEmpty bool IsEmpty() const; bool operator<(const Uuid& rhs) const; bool operator==(const Uuid& rhs) const; bool operator!=(const Uuid& rhs) const; private: constexpr Uuid(const UUID128Bit& val) : uu{val} {}; // Network-byte-ordered ID (Big Endian). UUID128Bit uu = {}; }; } // namespace hci } // namespace bluetooth inline std::ostream& operator<<(std::ostream& os, const bluetooth::hci::Uuid& a) { os << a.ToString(); return os; } // Custom std::hash specialization so that bluetooth::UUID can be used as a key // in std::unordered_map. namespace std { template <> struct hash { std::size_t operator()(const bluetooth::hci::Uuid& key) const { const auto& uuid_bytes = key.To128BitBE(); std::hash hash_fn; return hash_fn(std::string(reinterpret_cast(uuid_bytes.data()), uuid_bytes.size())); } }; } // namespace std