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 <stdint.h> 22 23 #include <array> 24 #include <string> 25 26 namespace bluetooth { 27 28 // This class is representing Bluetooth UUIDs across whole stack. 29 // Here are some general endianness rules: 30 // 1. UUID is internally kept as as Big Endian. 31 // 2. Bytes representing UUID coming from upper layers, Java or Binder, are Big 32 // Endian. 33 // 3. Bytes representing UUID coming from lower layer, HCI packets, are Little 34 // Endian. 35 // 4. UUID in storage is always string. 36 class Uuid final { 37 public: 38 static constexpr size_t kNumBytes128 = 16; 39 static constexpr size_t kNumBytes32 = 4; 40 static constexpr size_t kNumBytes16 = 2; 41 42 static constexpr size_t kString128BitLen = 36; 43 44 static const Uuid kEmpty; // 00000000-0000-0000-0000-000000000000 45 46 using UUID128Bit = std::array<uint8_t, kNumBytes128>; 47 48 Uuid() = default; 49 50 // Returns the shortest possible representation of this UUID in bytes. Either 51 // kNumBytes16, kNumBytes32, or kNumBytes128 52 size_t GetShortestRepresentationSize() const; 53 54 // Returns true if this UUID can be represented as 16 bit. 55 bool Is16Bit() const; 56 57 // Returns 16 bit Little Endian representation of this UUID. Use 58 // GetShortestRepresentationSize() or Is16Bit() before using this method. 59 uint16_t As16Bit() const; 60 61 // Returns 32 bit Little Endian representation of this UUID. Use 62 // GetShortestRepresentationSize() before using this method. 63 uint32_t As32Bit() const; 64 65 // Converts string representing 128, 32, or 16 bit UUID in 66 // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, xxxxxxxx, or xxxx format to UUID. If 67 // set, optional is_valid parameter will be set to true if conversion is 68 // successfull, false otherwise. 69 static Uuid FromString(const std::string& uuid, bool* is_valid = nullptr); 70 71 // Converts 16bit Little Endian representation of UUID to UUID 72 static Uuid From16Bit(uint16_t uuid16bit); 73 74 // Converts 32bit Little Endian representation of UUID to UUID 75 static Uuid From32Bit(uint32_t uuid32bit); 76 77 // Converts 128 bit Big Endian array representing UUID to UUID. From128BitBE(const UUID128Bit & uuid)78 static constexpr Uuid From128BitBE(const UUID128Bit& uuid) { 79 Uuid u(uuid); 80 return u; 81 } 82 83 // Converts 128 bit Big Endian array representing UUID to UUID. |uuid| points 84 // to beginning of array. 85 static Uuid From128BitBE(const uint8_t* uuid); 86 87 // Converts 128 bit Little Endian array representing UUID to UUID. 88 static Uuid From128BitLE(const UUID128Bit& uuid); 89 90 // Converts 128 bit Little Endian array representing UUID to UUID. |uuid| 91 // points to beginning of array. 92 static Uuid From128BitLE(const uint8_t* uuid); 93 94 // Returns 128 bit Little Endian representation of this UUID 95 const UUID128Bit To128BitLE() const; 96 97 // Returns 128 bit Big Endian representation of this UUID 98 const UUID128Bit& To128BitBE() const; 99 100 // Returns string representing this UUID in 101 // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format, lowercase. 102 std::string ToString() const; 103 104 // Returns true if this UUID is equal to kEmpty 105 bool IsEmpty() const; 106 107 // Returns true if this UUID is equal to kBase 108 bool IsBase() const; 109 110 // Update UUID with new value 111 void UpdateUuid(const Uuid& uuid); 112 113 bool operator<(const Uuid& rhs) const; 114 bool operator==(const Uuid& rhs) const; 115 bool operator!=(const Uuid& rhs) const; 116 117 private: Uuid(const UUID128Bit & val)118 constexpr Uuid(const UUID128Bit& val) : uu{val} {} 119 120 // Network-byte-ordered ID (Big Endian). 121 UUID128Bit uu; 122 }; 123 124 inline std::ostream& operator<<(std::ostream& os, const bluetooth::Uuid& a) { 125 os << a.ToString(); 126 return os; 127 } 128 129 } // namespace bluetooth 130 131 // Custom std::hash specialization so that bluetooth::UUID can be used as a key 132 // in std::unordered_map. 133 namespace std { 134 135 template <> 136 struct hash<bluetooth::Uuid> { 137 std::size_t operator()(const bluetooth::Uuid& key) const { 138 const auto& uuid_bytes = key.To128BitBE(); 139 std::hash<std::string> hash_fn; 140 return hash_fn( 141 std::string(reinterpret_cast<const char*>(uuid_bytes.data()), uuid_bytes.size())); 142 } 143 }; 144 145 } // namespace std 146 147 // This file is used outside bluetooth in components 148 // that do not have access to bluetooth/log.h 149 #if __has_include(<bluetooth/log.h>) 150 151 #include <bluetooth/log.h> 152 153 namespace std { 154 template <> 155 struct formatter<bluetooth::Uuid> : ostream_formatter {}; 156 } // namespace std 157 158 #endif // __has_include(<bluetooth/log.h>) 159