• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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