| /****************************************************************************** |
| * |
| * 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 <array> |
| #include <cstdint> |
| #include <optional> |
| #include <string> |
| |
| #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<Uuid> { |
| 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<uint8_t, kNumBytes128>; |
| |
| 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<Uuid> FromString(const std::string& uuid); |
| static std::optional<Uuid> 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<bluetooth::hci::Uuid> { |
| std::size_t operator()(const bluetooth::hci::Uuid& key) const { |
| const auto& uuid_bytes = key.To128BitBE(); |
| std::hash<std::string> hash_fn; |
| return hash_fn(std::string(reinterpret_cast<const char*>(uuid_bytes.data()), uuid_bytes.size())); |
| } |
| }; |
| |
| } // namespace std |