• 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 
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