1 /****************************************************************************** 2 * 3 * Copyright (C) 2017 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #pragma once 20 21 #include <array> 22 #include <cstdint> 23 #include <optional> 24 #include <string> 25 26 #include "storage/serializable.h" 27 28 namespace bluetooth { 29 30 namespace hci { 31 32 // This class is representing Bluetooth UUIDs across whole stack. 33 // Here are some general endianness rules: 34 // 1. UUID is internally kept as as Big Endian. 35 // 2. Bytes representing UUID coming from upper layers, Java or Binder, are Big Endian. 36 // 3. Bytes representing UUID coming from lower layer, HCI packets, are Little Endian. 37 // 4. UUID in storage is always string. 38 class Uuid final : public storage::Serializable<Uuid> { 39 public: 40 static constexpr size_t kNumBytes128 = 16; 41 static constexpr size_t kNumBytes32 = 4; 42 static constexpr size_t kNumBytes16 = 2; 43 44 static constexpr size_t kString128BitLen = 36; 45 46 static const Uuid kEmpty; // 00000000-0000-0000-0000-000000000000 47 48 using UUID128Bit = std::array<uint8_t, kNumBytes128>; 49 50 Uuid() = default; 51 data()52 inline uint8_t* data() { 53 return uu.data(); 54 } 55 data()56 inline const uint8_t* data() const { 57 return uu.data(); 58 } 59 60 // storage::Serializable methods 61 // Converts string representing 128, 32, or 16 bit UUID in 62 // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, xxxxxxxx, or xxxx format to UUID. 63 // return uuid on success, std::nullopt otherwise 64 static std::optional<Uuid> FromString(const std::string& uuid); 65 static std::optional<Uuid> FromLegacyConfigString(const std::string& uuid); 66 // Returns string representing this UUID in 67 // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format, lowercase. 68 std::string ToString() const override; 69 std::string ToLegacyConfigString() const override; 70 71 // Creates and returns a random 128-bit UUID. 72 static Uuid GetRandom(); 73 74 // Returns the shortest possible representation of this UUID in bytes. Either 75 // kNumBytes16, kNumBytes32, or kNumBytes128 76 size_t GetShortestRepresentationSize() const; 77 78 // Returns true if this UUID can be represented as 16 bit. 79 bool Is16Bit() const; 80 81 // Returns 16 bit Little Endian representation of this UUID. Use 82 // GetShortestRepresentationSize() or Is16Bit() before using this method. 83 uint16_t As16Bit() const; 84 85 // Returns 32 bit Little Endian representation of this UUID. Use 86 // GetShortestRepresentationSize() before using this method. 87 uint32_t As32Bit() const; 88 89 // Converts 16bit Little Endian representation of UUID to UUID 90 static Uuid From16Bit(uint16_t uuid16bit); 91 92 // Converts 32bit Little Endian representation of UUID to UUID 93 static Uuid From32Bit(uint32_t uuid32bit); 94 95 // Converts 128 bit Big Endian array representing UUID to UUID. From128BitBE(const UUID128Bit & uuid)96 static Uuid From128BitBE(const UUID128Bit& uuid) { 97 Uuid u(uuid); 98 return u; 99 } 100 101 // Converts 128 bit Big Endian array representing UUID to UUID. |uuid| points 102 // to beginning of array. 103 static Uuid From128BitBE(const uint8_t* uuid); 104 105 // Converts 128 bit Little Endian array representing UUID to UUID. 106 static Uuid From128BitLE(const UUID128Bit& uuid); 107 108 // Converts 128 bit Little Endian array representing UUID to UUID. |uuid| 109 // points to beginning of array. 110 static Uuid From128BitLE(const uint8_t* uuid); 111 112 // Returns 128 bit Little Endian representation of this UUID 113 UUID128Bit To128BitLE() const; 114 115 // Returns 128 bit Big Endian representation of this UUID 116 const UUID128Bit& To128BitBE() const; 117 118 // Returns true if this UUID is equal to kEmpty 119 bool IsEmpty() const; 120 121 bool operator<(const Uuid& rhs) const; 122 bool operator==(const Uuid& rhs) const; 123 bool operator!=(const Uuid& rhs) const; 124 125 private: Uuid(const UUID128Bit & val)126 constexpr Uuid(const UUID128Bit& val) : uu{val} {}; 127 128 // Network-byte-ordered ID (Big Endian). 129 UUID128Bit uu = {}; 130 }; 131 } // namespace hci 132 133 } // namespace bluetooth 134 135 inline std::ostream& operator<<(std::ostream& os, const bluetooth::hci::Uuid& a) { 136 os << a.ToString(); 137 return os; 138 } 139 140 // Custom std::hash specialization so that bluetooth::UUID can be used as a key 141 // in std::unordered_map. 142 namespace std { 143 144 template <> 145 struct hash<bluetooth::hci::Uuid> { 146 std::size_t operator()(const bluetooth::hci::Uuid& key) const { 147 const auto& uuid_bytes = key.To128BitBE(); 148 std::hash<std::string> hash_fn; 149 return hash_fn(std::string(reinterpret_cast<const char*>(uuid_bytes.data()), uuid_bytes.size())); 150 } 151 }; 152 153 } // namespace std 154