Direct-BT v3.3.0-1-gc2d430c
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 JAU_UUID_HPP_
27#define JAU_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
37namespace jau {
38
39/** \addtogroup NetUtils
40 *
41 * @{
42 */
43
44class uuid128_t; // forward
45
46/**
47 * Bluetooth UUID <https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/>
48 * <p>
49 * Bluetooth is LSB or Little-Endian!
50 * </p>
51 * <p>
52 * BASE_UUID '00000000-0000-1000-8000-00805F9B34FB'
53 * </p>
54 */
55extern uuid128_t BT_BASE_UUID;
56
57class uuid_t {
58public:
59 /** Underlying integer value present octet count */
60 enum class TypeSize : jau::nsize_t {
61 UUID16_SZ=2, UUID32_SZ=4, UUID128_SZ=16
62 };
63 static constexpr jau::nsize_t number(const TypeSize rhs) noexcept {
64 return static_cast<jau::nsize_t>(rhs);
65 }
66 static std::string getTypeSizeString(const TypeSize v) noexcept;
67
68private:
69 TypeSize type;
70
71protected:
72 uuid_t(TypeSize const type_) : type(type_) {}
73
74public:
75 static TypeSize toTypeSize(const jau::nsize_t size);
76 static std::unique_ptr<uuid_t> create(TypeSize const t, uint8_t const * const buffer, lb_endian_t const le_or_be);
77 static std::unique_ptr<uuid_t> create(const std::string& str);
78
79 virtual ~uuid_t() noexcept = default;
80
81 uuid_t(const uuid_t &o) noexcept = default;
82 uuid_t(uuid_t &&o) noexcept = default;
83 uuid_t& operator=(const uuid_t &o) noexcept = default;
84 uuid_t& operator=(uuid_t &&o) noexcept = default;
85
86 std::unique_ptr<uuid_t> clone() const noexcept;
87
88 /**
89 * Strict equality operator.
90 *
91 * Only returns true if type and value are equal.
92 *
93 * @param o other comparison argument
94 * @return true if equal, otherwise false.
95 */
96 bool operator==(uuid_t const &o) const noexcept;
97
98 /**
99 * Strict not-equal operator.
100 *
101 * Returns true if type and/or value are not equal.
102 *
103 * @param o other comparison argument
104 * @return true if equal, otherwise false.
105 */
106 bool operator!=(uuid_t const &o) const noexcept
107 { return !(*this == o); }
108
109 /**
110 * Relaxed equality operator.
111 *
112 * Returns true if both uuid values are equivalent.
113 *
114 * If their uuid_t type differs, i.e. their TypeSize,
115 * both values will be transformed to uuid128_t before comparison.
116 *
117 * Potential uuid128_t conversion is performed using toUUDI128(),
118 * placing the sub-uuid at index 12 on BT_BASE_UUID (default).
119 *
120 * @param o other comparison argument
121 * @return true if equal, otherwise false.
122 */
123 bool equivalent(uuid_t const &o) const noexcept;
124
125 TypeSize getTypeSize() const noexcept { return type; }
126 jau::nsize_t getTypeSizeInt() const noexcept { return uuid_t::number(type); }
127 std::string getTypeSizeString() const noexcept { return getTypeSizeString(type); }
128
129 uuid128_t toUUID128(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid32_le_octet_index=12) const noexcept;
130
131 /** returns the pointer to the uuid data of size getTypeSize() */
132 virtual const uint8_t * data() const noexcept = 0;
133
134 /**
135 * Returns the string representation in BE network order, i.e. `00000000-0000-1000-8000-00805F9B34FB`.
136 */
137 virtual std::string toString() const noexcept = 0;
138
139 /**
140 * Returns the uuid128_t string representation in BE network order, i.e. `00000000-0000-1000-8000-00805F9B34FB`.
141 */
142 virtual std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept = 0;
143
144 virtual jau::nsize_t put(uint8_t * const buffer, lb_endian_t const le_or_be) const noexcept = 0;
145};
146
147inline std::string to_string(const uuid_t::TypeSize v) noexcept {
149}
150
151class uuid16_t : public uuid_t {
152public:
153 uint16_t value;
154
155 uuid16_t(uint16_t const v) noexcept
156 : uuid_t(TypeSize::UUID16_SZ), value(v) { }
157
158 uuid16_t(const std::string& str);
159
160 uuid16_t(uint8_t const * const buffer, lb_endian_t const le_or_be) noexcept
161 : uuid_t(TypeSize::UUID16_SZ), value(jau::get_uint16(buffer, le_or_be)) { }
162
163 uuid16_t(const uuid16_t &o) noexcept = default;
164 uuid16_t(uuid16_t &&o) noexcept = default;
165 uuid16_t& operator=(const uuid16_t &o) noexcept = default;
166 uuid16_t& operator=(uuid16_t &&o) noexcept = default;
167
168 const uint8_t * data() const noexcept override { return static_cast<uint8_t*>(static_cast<void*>(const_cast<uint16_t*>(&value))); }
169 std::string toString() const noexcept override;
170 std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override;
171
172 jau::nsize_t put(uint8_t * const buffer, lb_endian_t const le_or_be) const noexcept override {
173 jau::put_uint16(buffer, value, le_or_be);
174 return 2;
175 }
176};
177
178class uuid32_t : public uuid_t {
179public:
180 uint32_t value;
181
182 uuid32_t(uint32_t const v) noexcept
183 : uuid_t(TypeSize::UUID32_SZ), value(v) {}
184
185 uuid32_t(const std::string& str);
186
187 uuid32_t(uint8_t const * const buffer, lb_endian_t const le_or_be) noexcept
188 : uuid_t(TypeSize::UUID32_SZ), value(jau::get_uint32(buffer, le_or_be)) { }
189
190 uuid32_t(const uuid32_t &o) noexcept = default;
191 uuid32_t(uuid32_t &&o) noexcept = default;
192 uuid32_t& operator=(const uuid32_t &o) noexcept = default;
193 uuid32_t& operator=(uuid32_t &&o) noexcept = default;
194
195 const uint8_t * data() const noexcept override { return static_cast<uint8_t*>(static_cast<void*>(const_cast<uint32_t*>(&value))); }
196 std::string toString() const noexcept override;
197 std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override;
198
199 jau::nsize_t put(uint8_t * const buffer, lb_endian_t const le_or_be) const noexcept override {
200 jau::put_uint32(buffer, value, le_or_be);
201 return 4;
202 }
203};
204
205class uuid128_t : public uuid_t {
206public:
208
209 uuid128_t() noexcept : uuid_t(TypeSize::UUID128_SZ) { bzero(value.data, sizeof(value)); }
210
211 uuid128_t(jau::uint128dp_t const v) noexcept
212 : uuid_t(TypeSize::UUID128_SZ), value(v) {}
213
214 uuid128_t(const std::string& str);
215
216 uuid128_t(uint8_t const * const buffer, lb_endian_t const le_or_be) noexcept
217 : uuid_t(TypeSize::UUID128_SZ), value(jau::get_uint128(buffer, le_or_be)) { }
218
219 uuid128_t(uuid16_t const & uuid16, uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid16_le_octet_index=12) noexcept;
220
221 uuid128_t(uuid32_t const & uuid32, uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid32_le_octet_index=12) noexcept;
222
223 uuid128_t(const uuid128_t &o) noexcept = default;
224 uuid128_t(uuid128_t &&o) noexcept = default;
225 uuid128_t& operator=(const uuid128_t &o) noexcept = default;
226 uuid128_t& operator=(uuid128_t &&o) noexcept = default;
227
228 const uint8_t * data() const noexcept override { return value.data; }
229 std::string toString() const noexcept override;
230 std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override {
231 (void)base_uuid;
232 (void)le_octet_index;
233 return toString();
234 }
235
236 jau::nsize_t put(uint8_t * const buffer, lb_endian_t const le_or_be) const noexcept override {
237 jau::put_uint128(buffer, value, le_or_be);
238 return 16;
239 }
240};
241
242inline uuid16_t get_uuid16(uint8_t const * buffer) noexcept
243{
244 return uuid16_t(jau::get_uint16(buffer));
245}
246inline uuid16_t get_uuid16(uint8_t const * buffer, lb_endian_t const le_or_be) noexcept
247{
248 return uuid16_t(jau::get_uint16(buffer, le_or_be));
249}
250inline uuid32_t get_uuid32(uint8_t const * buffer) noexcept
251{
252 return uuid32_t(jau::get_uint32(buffer));
253}
254inline uuid32_t get_uuid32(uint8_t const * buffer, lb_endian_t const le_or_be) noexcept
255{
256 return uuid32_t(jau::get_uint32(buffer, le_or_be));
257}
258inline uuid128_t get_uuid128(uint8_t const * buffer) noexcept
259{
260 return uuid128_t(jau::get_uint128(buffer));
261}
262inline uuid128_t get_uuid128(uint8_t const * buffer, lb_endian_t const le_or_be) noexcept
263{
264 return uuid128_t(jau::get_uint128(buffer, le_or_be));
265}
266
267/**@}*/
268
269} /* namespace jau */
270
271#endif /* JAU_UUID_HPP_ */
uuid128_t() noexcept
Definition: uuid.hpp:209
uuid128_t(jau::uint128dp_t const v) noexcept
Definition: uuid.hpp:211
jau::nsize_t put(uint8_t *const buffer, lb_endian_t const le_or_be) const noexcept override
Definition: uuid.hpp:236
jau::uint128dp_t value
Definition: uuid.hpp:207
uuid128_t(uint8_t const *const buffer, lb_endian_t const le_or_be) noexcept
Definition: uuid.hpp:216
uuid16_t & operator=(uuid16_t &&o) noexcept=default
uuid16_t(uint8_t const *const buffer, lb_endian_t const le_or_be) noexcept
Definition: uuid.hpp:160
uint16_t value
Definition: uuid.hpp:153
const uint8_t * data() const noexcept override
returns the pointer to the uuid data of size getTypeSize()
Definition: uuid.hpp:168
uuid16_t(uuid16_t &&o) noexcept=default
uuid16_t & operator=(const uuid16_t &o) noexcept=default
uuid16_t(uint16_t const v) noexcept
Definition: uuid.hpp:155
uuid16_t(const uuid16_t &o) noexcept=default
uuid32_t & operator=(uuid32_t &&o) noexcept=default
uuid32_t(const uuid32_t &o) noexcept=default
uuid32_t(uint8_t const *const buffer, lb_endian_t const le_or_be) noexcept
Definition: uuid.hpp:187
uuid32_t(uuid32_t &&o) noexcept=default
uint32_t value
Definition: uuid.hpp:180
uuid32_t & operator=(const uuid32_t &o) noexcept=default
uuid32_t(uint32_t const v) noexcept
Definition: uuid.hpp:182
const uint8_t * data() const noexcept override
returns the pointer to the uuid data of size getTypeSize()
Definition: uuid.hpp:195
static TypeSize toTypeSize(const jau::nsize_t size)
Definition: uuid.cpp:47
static constexpr jau::nsize_t number(const TypeSize rhs) noexcept
Definition: uuid.hpp:63
virtual jau::nsize_t put(uint8_t *const buffer, lb_endian_t const le_or_be) const noexcept=0
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:119
TypeSize getTypeSize() const noexcept
Definition: uuid.hpp:125
virtual const uint8_t * data() const noexcept=0
returns the pointer to the uuid data of size getTypeSize()
TypeSize
Underlying integer value present octet count.
Definition: uuid.hpp:60
uuid_t(TypeSize const type_)
Definition: uuid.hpp:72
std::string getTypeSizeString() const noexcept
Definition: uuid.hpp:127
virtual ~uuid_t() noexcept=default
virtual std::string toString() const noexcept=0
Returns the string representation in BE network order, i.e.
jau::nsize_t getTypeSizeInt() const noexcept
Definition: uuid.hpp:126
bool equivalent(uuid_t const &o) const noexcept
Relaxed equality operator.
Definition: uuid.cpp:109
static std::unique_ptr< uuid_t > create(TypeSize const t, uint8_t const *const buffer, lb_endian_t const le_or_be)
Definition: uuid.cpp:56
std::unique_ptr< uuid_t > clone() const noexcept
Definition: uuid.cpp:84
virtual std::string toUUID128String(uuid128_t const &base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept=0
Returns the uuid128_t string representation in BE network order, i.e.
constexpr uint128dp_t get_uint128(uint8_t const *buffer) noexcept
See get_uint16() for reference.
Definition: byte_util.hpp:765
constexpr uint16_t get_uint16(uint8_t const *buffer) noexcept
Returns a uint16_t value from the given byte address using packed_t to resolve a potential memory ali...
Definition: byte_util.hpp:661
constexpr uint32_t get_uint32(uint8_t const *buffer) noexcept
See get_uint16() for reference.
Definition: byte_util.hpp:699
constexpr void put_uint32(uint8_t *buffer, const uint32_t v) noexcept
See put_uint16() for reference.
Definition: byte_util.hpp:683
lb_endian_t
Simplified reduced endian type only covering little- and big-endian.
Definition: byte_util.hpp:227
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr void put_uint16(uint8_t *buffer, const uint16_t v) noexcept
Put the given uint16_t value into the given byte address using packed_t to resolve a potential memory...
Definition: byte_util.hpp:638
constexpr void put_uint128(uint8_t *buffer, const uint128dp_t &v) noexcept
See put_uint16() for reference.
Definition: byte_util.hpp:749
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:53
uuid32_t get_uuid32(uint8_t const *buffer) noexcept
Definition: uuid.hpp:250
uuid128_t BT_BASE_UUID
Bluetooth UUID https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/
uuid16_t get_uuid16(uint8_t const *buffer) noexcept
Definition: uuid.hpp:242
uuid128_t get_uuid128(uint8_t const *buffer) noexcept
Definition: uuid.hpp:258
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
STL namespace.
A 128-bit packed uint8_t data array.
Definition: int_types.hpp:114
uint8_t data[16]
Definition: int_types.hpp:114