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