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 // Returns the shortest possible representation of this UUID in bytes. Either 72 // kNumBytes16, kNumBytes32, or kNumBytes128 73 size_t GetShortestRepresentationSize() const; 74 75 // Returns true if this UUID can be represented as 16 bit. 76 bool Is16Bit() const; 77 78 // Returns 16 bit Little Endian representation of this UUID. Use 79 // GetShortestRepresentationSize() or Is16Bit() before using this method. 80 uint16_t As16Bit() const; 81 82 // Returns 32 bit Little Endian representation of this UUID. Use 83 // GetShortestRepresentationSize() before using this method. 84 uint32_t As32Bit() const; 85 86 // Converts 16bit Little Endian representation of UUID to UUID 87 static Uuid From16Bit(uint16_t uuid16bit); 88 89 // Converts 32bit Little Endian representation of UUID to UUID 90 static Uuid From32Bit(uint32_t uuid32bit); 91 92 // Converts 128 bit Big Endian array representing UUID to UUID. From128BitBE(const UUID128Bit & uuid)93 static Uuid From128BitBE(const UUID128Bit& uuid) { 94 Uuid u(uuid); 95 return u; 96 } 97 98 // Converts 128 bit Big Endian array representing UUID to UUID. |uuid| points 99 // to beginning of array. 100 static Uuid From128BitBE(const uint8_t* uuid); 101 102 // Converts 128 bit Little Endian array representing UUID to UUID. 103 static Uuid From128BitLE(const UUID128Bit& uuid); 104 105 // Converts 128 bit Little Endian array representing UUID to UUID. |uuid| 106 // points to beginning of array. 107 static Uuid From128BitLE(const uint8_t* uuid); 108 109 // Returns 128 bit Little Endian representation of this UUID 110 UUID128Bit To128BitLE() const; 111 112 // Returns 128 bit Big Endian representation of this UUID 113 const UUID128Bit& To128BitBE() const; 114 115 // Returns true if this UUID is equal to kEmpty 116 bool IsEmpty() const; 117 118 bool operator<(const Uuid& rhs) const; 119 bool operator==(const Uuid& rhs) const; 120 bool operator!=(const Uuid& rhs) const; 121 122 private: Uuid(const UUID128Bit & val)123 constexpr Uuid(const UUID128Bit& val) : uu{val} {}; 124 125 // Network-byte-ordered ID (Big Endian). 126 UUID128Bit uu = {}; 127 }; 128 } // namespace hci 129 130 } // namespace bluetooth 131 132 inline std::ostream& operator<<(std::ostream& os, const bluetooth::hci::Uuid& a) { 133 os << a.ToString(); 134 return os; 135 } 136 137 // Custom std::hash specialization so that bluetooth::UUID can be used as a key 138 // in std::unordered_map. 139 namespace std { 140 141 template <> 142 struct hash<bluetooth::hci::Uuid> { 143 std::size_t operator()(const bluetooth::hci::Uuid& key) const { 144 const auto& uuid_bytes = key.To128BitBE(); 145 std::hash<std::string> hash_fn; 146 return hash_fn(std::string(reinterpret_cast<const char*>(uuid_bytes.data()), uuid_bytes.size())); 147 } 148 }; 149 150 } // namespace std 151