Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
UUID.hpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  * Copyright (c) 2020 ZAFENA AB
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifndef UUID_HPP_
27 #define UUID_HPP_
28 
29 #include <cstring>
30 #include <string>
31 #include <memory>
32 #include <cstdint>
33 #include <vector>
34 
35 #include <jau/basic_types.hpp>
36 
37 namespace direct_bt {
38 
39 class uuid128_t; // forward
40 
41 /**
42  * Bluetooth UUID <https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/>
43  * <p>
44  * Bluetooth is LSB or Little-Endian!
45  * </p>
46  * <p>
47  * BASE_UUID '00000000-0000-1000-8000-00805F9B34FB'
48  * </p>
49  */
50 extern uuid128_t BT_BASE_UUID;
51 
52 class uuid_t {
53 public:
54  /** Underlying integer value present octet count */
55  enum class TypeSize : jau::nsize_t {
57  };
58  static constexpr jau::nsize_t number(const TypeSize rhs) noexcept {
59  return static_cast<jau::nsize_t>(rhs);
60  }
61 
62 private:
63  TypeSize type;
64 
65 protected:
66  uuid_t(TypeSize const type_) : type(type_) {}
67 
68 public:
69  static TypeSize toTypeSize(const jau::nsize_t size);
70  static std::unique_ptr<const uuid_t> create(TypeSize const t, uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian);
71 
72  virtual ~uuid_t() noexcept {}
73 
74  uuid_t(const uuid_t &o) noexcept = default;
75  uuid_t(uuid_t &&o) noexcept = default;
76  uuid_t& operator=(const uuid_t &o) noexcept = default;
77  uuid_t& operator=(uuid_t &&o) noexcept = default;
78 
79  virtual bool operator==(uuid_t const &o) const noexcept {
80  if( this == &o ) {
81  return true;
82  }
83  return type == o.type;
84  }
85  bool operator!=(uuid_t const &o) const noexcept
86  { return !(*this == o); }
87 
88  TypeSize getTypeSize() const noexcept { return type; }
89  jau::nsize_t getTypeSizeInt() const noexcept { return uuid_t::number(type); }
90 
91  uuid128_t toUUID128(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid32_le_octet_index=12) const noexcept;
92  /** returns the pointer to the uuid data of size getTypeSize() */
93  virtual const uint8_t * data() const noexcept { return nullptr; }
94  virtual std::string toString() const noexcept { return ""; }
95  virtual std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept;
96 };
97 
98 class uuid16_t : public uuid_t {
99 public:
100  uint16_t value;
101 
102  uuid16_t(uint16_t const v) noexcept
103  : uuid_t(TypeSize::UUID16_SZ), value(v) { }
104 
105  uuid16_t(uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept
106  : uuid_t(TypeSize::UUID16_SZ), value(jau::get_uint16(buffer, byte_offset, littleEndian)) { }
107 
108  uuid16_t(const uuid16_t &o) noexcept = default;
109  uuid16_t(uuid16_t &&o) noexcept = default;
110  uuid16_t& operator=(const uuid16_t &o) noexcept = default;
111  uuid16_t& operator=(uuid16_t &&o) noexcept = default;
112 
113  bool operator==(uuid_t const &o) const noexcept override {
114  if( this == &o ) {
115  return true;
116  }
117  return getTypeSize() == o.getTypeSize() && value == static_cast<uuid16_t const *>(&o)->value;
118  }
119 
120  const uint8_t * data() const noexcept override { return static_cast<uint8_t*>(static_cast<void*>(const_cast<uint16_t*>(&value))); }
121  std::string toString() const noexcept override;
122  std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override;
123 };
124 
125 class uuid32_t : public uuid_t {
126 public:
127  uint32_t value;
128 
129  uuid32_t(uint32_t const v) noexcept
130  : uuid_t(TypeSize::UUID32_SZ), value(v) {}
131 
132  uuid32_t(uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept
133  : uuid_t(TypeSize::UUID32_SZ), value(jau::get_uint32(buffer, byte_offset, littleEndian)) { }
134 
135  uuid32_t(const uuid32_t &o) noexcept = default;
136  uuid32_t(uuid32_t &&o) noexcept = default;
137  uuid32_t& operator=(const uuid32_t &o) noexcept = default;
138  uuid32_t& operator=(uuid32_t &&o) noexcept = default;
139 
140  bool operator==(uuid_t const &o) const noexcept override {
141  if( this == &o ) {
142  return true;
143  }
144  return getTypeSize() == o.getTypeSize() && value == static_cast<uuid32_t const *>(&o)->value;
145  }
146 
147  const uint8_t * data() const noexcept override { return static_cast<uint8_t*>(static_cast<void*>(const_cast<uint32_t*>(&value))); }
148  std::string toString() const noexcept override;
149  std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override;
150 };
151 
152 class uuid128_t : public uuid_t {
153 public:
155 
156  uuid128_t() noexcept : uuid_t(TypeSize::UUID128_SZ) { bzero(value.data, sizeof(value)); }
157 
158  uuid128_t(jau::uint128_t const v) noexcept
159  : uuid_t(TypeSize::UUID128_SZ), value(v) {}
160 
161  uuid128_t(const std::string str);
162 
163  uuid128_t(uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept
164  : uuid_t(TypeSize::UUID128_SZ), value(jau::get_uint128(buffer, byte_offset, littleEndian)) { }
165 
166  uuid128_t(uuid16_t const & uuid16, uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid16_le_octet_index=12) noexcept;
167 
168  uuid128_t(uuid32_t const & uuid32, uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid32_le_octet_index=12) noexcept;
169 
170  uuid128_t(const uuid128_t &o) noexcept = default;
171  uuid128_t(uuid128_t &&o) noexcept = default;
172  uuid128_t& operator=(const uuid128_t &o) noexcept = default;
173  uuid128_t& operator=(uuid128_t &&o) noexcept = default;
174 
175  bool operator==(uuid_t const &o) const noexcept override {
176  if( this == &o ) {
177  return true;
178  }
179  return getTypeSize() == o.getTypeSize() && value == static_cast<uuid128_t const *>(&o)->value;
180  }
181 
182  const uint8_t * data() const noexcept override { return value.data; }
183  std::string toString() const noexcept override;
184  std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override {
185  (void)base_uuid;
186  (void)le_octet_index;
187  return toString();
188  }
189 };
190 
191 inline void put_uuid(uint8_t * buffer, jau::nsize_t const byte_offset, const uuid_t &v) noexcept
192 {
193  switch(v.getTypeSize()) {
195  jau::put_uint16(buffer, byte_offset, static_cast<const uuid16_t &>(v).value);
196  break;
198  jau::put_uint32(buffer, byte_offset, static_cast<const uuid32_t &>(v).value);
199  break;
201  jau::put_uint128(buffer, byte_offset, static_cast<const uuid128_t &>(v).value);
202  break;
203  }
204 }
205 inline void put_uuid(uint8_t * buffer, jau::nsize_t const byte_offset, const uuid_t &v, bool littleEndian) noexcept
206 {
207  switch(v.getTypeSize()) {
209  jau::put_uint16(buffer, byte_offset, static_cast<const uuid16_t &>(v).value, littleEndian);
210  break;
212  jau::put_uint32(buffer, byte_offset, static_cast<const uuid32_t &>(v).value, littleEndian);
213  break;
215  jau::put_uint128(buffer, byte_offset, static_cast<const uuid128_t &>(v).value, littleEndian);
216  break;
217  }
218 }
219 
220 inline uuid16_t get_uuid16(uint8_t const * buffer, jau::nsize_t const byte_offset) noexcept
221 {
222  return uuid16_t(jau::get_uint16(buffer, byte_offset));
223 }
224 inline uuid16_t get_uuid16(uint8_t const * buffer, jau::nsize_t const byte_offset, bool littleEndian) noexcept
225 {
226  return uuid16_t(jau::get_uint16(buffer, byte_offset, littleEndian));
227 }
228 inline uuid32_t get_uuid32(uint8_t const * buffer, jau::nsize_t const byte_offset) noexcept
229 {
230  return uuid32_t(jau::get_uint32(buffer, byte_offset));
231 }
232 inline uuid32_t get_uuid32(uint8_t const * buffer, jau::nsize_t const byte_offset, bool littleEndian) noexcept
233 {
234  return uuid32_t(jau::get_uint32(buffer, byte_offset, littleEndian));
235 }
236 inline uuid128_t get_uuid128(uint8_t const * buffer, jau::nsize_t const byte_offset) noexcept
237 {
238  return uuid128_t(jau::get_uint128(buffer, byte_offset));
239 }
240 inline uuid128_t get_uuid128(uint8_t const * buffer, jau::nsize_t const byte_offset, bool littleEndian) noexcept
241 {
242  return uuid128_t(jau::get_uint128(buffer, byte_offset, littleEndian));
243 }
244 
245 } /* namespace direct_bt */
246 
247 #endif /* UUID_HPP_ */
direct_bt::put_uuid
void put_uuid(uint8_t *buffer, jau::nsize_t const byte_offset, const uuid_t &v) noexcept
Definition: UUID.hpp:191
direct_bt::uuid_t::toUUID128
uuid128_t toUUID128(uuid128_t const &base_uuid=BT_BASE_UUID, jau::nsize_t const uuid32_le_octet_index=12) const noexcept
Definition: UUID.cpp:58
direct_bt::uuid_t::create
static std::unique_ptr< const uuid_t > create(TypeSize const t, uint8_t const *const buffer, jau::nsize_t const byte_offset, bool const littleEndian)
Definition: UUID.cpp:47
direct_bt::uuid_t::uuid_t
uuid_t(uuid_t &&o) noexcept=default
direct_bt::uuid32_t::operator==
bool operator==(uuid_t const &o) const noexcept override
Definition: UUID.hpp:140
direct_bt::uuid128_t::uuid128_t
uuid128_t(jau::uint128_t const v) noexcept
Definition: UUID.hpp:158
direct_bt::uuid_t::TypeSize::UUID128_SZ
@ UUID128_SZ
direct_bt::uuid_t::uuid_t
uuid_t(const uuid_t &o) noexcept=default
direct_bt::uuid16_t::uuid16_t
uuid16_t(uint8_t const *const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept
Definition: UUID.hpp:105
direct_bt::uuid_t::operator!=
bool operator!=(uuid_t const &o) const noexcept
Definition: UUID.hpp:85
direct_bt::uuid32_t::uuid32_t
uuid32_t(const uuid32_t &o) noexcept=default
direct_bt
Definition: ATTPDUTypes.hpp:171
direct_bt::uuid128_t
Definition: UUID.hpp:152
direct_bt::uuid32_t::operator=
uuid32_t & operator=(uuid32_t &&o) noexcept=default
direct_bt::uuid16_t::operator==
bool operator==(uuid_t const &o) const noexcept override
Definition: UUID.hpp:113
direct_bt::uuid_t::operator=
uuid_t & operator=(const uuid_t &o) noexcept=default
direct_bt::uuid_t::data
virtual const uint8_t * data() const noexcept
returns the pointer to the uuid data of size getTypeSize()
Definition: UUID.hpp:93
direct_bt::uuid16_t
Definition: UUID.hpp:98
jau::put_uint32
constexpr void put_uint32(uint8_t *buffer, nsize_t const byte_offset, const uint32_t v) noexcept
Definition: byte_util.hpp:615
jau
Definition: basic_algos.hpp:34
direct_bt::uuid_t::getTypeSize
TypeSize getTypeSize() const noexcept
Definition: UUID.hpp:88
direct_bt::uuid16_t::value
uint16_t value
Definition: UUID.hpp:100
jau::put_uint128
constexpr void put_uint128(uint8_t *buffer, nsize_t const byte_offset, const uint128_t &v) noexcept
Definition: byte_util.hpp:649
direct_bt::uuid16_t::uuid16_t
uuid16_t(const uuid16_t &o) noexcept=default
direct_bt::uuid16_t::operator=
uuid16_t & operator=(uuid16_t &&o) noexcept=default
direct_bt::BT_BASE_UUID
uuid128_t BT_BASE_UUID
Bluetooth UUID https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/
direct_bt::uuid_t::TypeSize
TypeSize
Underlying integer value present octet count.
Definition: UUID.hpp:55
direct_bt::uuid32_t::value
uint32_t value
Definition: UUID.hpp:127
direct_bt::get_uuid128
uuid128_t get_uuid128(uint8_t const *buffer, jau::nsize_t const byte_offset) noexcept
Definition: UUID.hpp:236
direct_bt::uuid_t::TypeSize::UUID32_SZ
@ UUID32_SZ
jau::uint128_t::data
uint8_t data[16]
Definition: int_types.hpp:83
direct_bt::uuid_t::uuid_t
uuid_t(TypeSize const type_)
Definition: UUID.hpp:66
direct_bt::uuid16_t::uuid16_t
uuid16_t(uint16_t const v) noexcept
Definition: UUID.hpp:102
direct_bt::uuid128_t::data
const uint8_t * data() const noexcept override
returns the pointer to the uuid data of size getTypeSize()
Definition: UUID.hpp:182
direct_bt::get_uuid16
uuid16_t get_uuid16(uint8_t const *buffer, jau::nsize_t const byte_offset) noexcept
Definition: UUID.hpp:220
direct_bt::uuid128_t::value
jau::uint128_t value
Definition: UUID.hpp:154
direct_bt::uuid32_t::uuid32_t
uuid32_t(uint8_t const *const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept
Definition: UUID.hpp:132
direct_bt::uuid32_t
Definition: UUID.hpp:125
jau::get_uint32
constexpr uint32_t get_uint32(uint8_t const *buffer, nsize_t const byte_offset) noexcept
Definition: byte_util.hpp:623
direct_bt::uuid_t::operator==
virtual bool operator==(uuid_t const &o) const noexcept
Definition: UUID.hpp:79
direct_bt::uuid_t::~uuid_t
virtual ~uuid_t() noexcept
Definition: UUID.hpp:72
direct_bt::get_uuid32
uuid32_t get_uuid32(uint8_t const *buffer, jau::nsize_t const byte_offset) noexcept
Definition: UUID.hpp:228
jau::get_uint128
constexpr uint128_t get_uint128(uint8_t const *buffer, nsize_t const byte_offset) noexcept
Definition: byte_util.hpp:657
direct_bt::uuid32_t::operator=
uuid32_t & operator=(const uuid32_t &o) noexcept=default
direct_bt::uuid128_t::uuid128_t
uuid128_t() noexcept
Definition: UUID.hpp:156
direct_bt::uuid_t::toUUID128String
virtual std::string toUUID128String(uuid128_t const &base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept
Definition: UUID.cpp:68
direct_bt::uuid32_t::uuid32_t
uuid32_t(uint32_t const v) noexcept
Definition: UUID.hpp:129
jau::nsize_t
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:44
direct_bt::uuid32_t::uuid32_t
uuid32_t(uuid32_t &&o) noexcept=default
direct_bt::uuid16_t::data
const uint8_t * data() const noexcept override
returns the pointer to the uuid data of size getTypeSize()
Definition: UUID.hpp:120
jau::get_uint16
constexpr uint16_t get_uint16(uint8_t const *buffer, nsize_t const byte_offset) noexcept
Definition: byte_util.hpp:586
direct_bt::uuid_t::operator=
uuid_t & operator=(uuid_t &&o) noexcept=default
direct_bt::uuid128_t::uuid128_t
uuid128_t(uint8_t const *const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept
Definition: UUID.hpp:163
direct_bt::uuid16_t::operator=
uuid16_t & operator=(const uuid16_t &o) noexcept=default
direct_bt::uuid_t::number
static constexpr jau::nsize_t number(const TypeSize rhs) noexcept
Definition: UUID.hpp:58
jau::put_uint16
constexpr void put_uint16(uint8_t *buffer, nsize_t const byte_offset, const uint16_t v) noexcept
Definition: byte_util.hpp:561
direct_bt::uuid_t::toString
virtual std::string toString() const noexcept
Definition: UUID.hpp:94
direct_bt::uuid_t
Definition: UUID.hpp:52
jau::uint128_t
Definition: int_types.hpp:83
basic_types.hpp
direct_bt::uuid_t::TypeSize::UUID16_SZ
@ UUID16_SZ
direct_bt::uuid32_t::data
const uint8_t * data() const noexcept override
returns the pointer to the uuid data of size getTypeSize()
Definition: UUID.hpp:147
direct_bt::uuid_t::getTypeSizeInt
jau::nsize_t getTypeSizeInt() const noexcept
Definition: UUID.hpp:89
direct_bt::uuid_t::toTypeSize
static TypeSize toTypeSize(const jau::nsize_t size)
Definition: UUID.cpp:38
direct_bt::uuid16_t::uuid16_t
uuid16_t(uuid16_t &&o) noexcept=default