Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
HCITypes.cpp
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#include <cstring>
27#include <string>
28#include <memory>
29#include <cstdint>
30#include <vector>
31#include <cstdio>
32
33#include <algorithm>
34
35#include <jau/ringbuffer.hpp>
36
37#include "HCITypes.hpp"
38#include "HCIHandler.hpp"
39
40extern "C" {
41 #include <inttypes.h>
42 #include <unistd.h>
43 #include <sys/param.h>
44 #include <sys/uio.h>
45 #include <sys/types.h>
46 #include <sys/ioctl.h>
47 #include <sys/socket.h>
48 #include <poll.h>
49}
50
51namespace direct_bt {
52
53#define HCI_STATUS_CODE(X) \
54 X(SUCCESS) \
55 X(UNKNOWN_COMMAND) \
56 X(UNKNOWN_CONNECTION_IDENTIFIER) \
57 X(HARDWARE_FAILURE) \
58 X(PAGE_TIMEOUT) \
59 X(AUTHENTICATION_FAILURE) \
60 X(PIN_OR_KEY_MISSING) \
61 X(MEMORY_CAPACITY_EXCEEDED) \
62 X(CONNECTION_TIMEOUT) \
63 X(CONNECTION_LIMIT_EXCEEDED) \
64 X(SYNC_DEVICE_CONNECTION_LIMIT_EXCEEDED) \
65 X(CONNECTION_ALREADY_EXISTS) \
66 X(COMMAND_DISALLOWED) \
67 X(CONNECTION_REJECTED_LIMITED_RESOURCES) \
68 X(CONNECTION_REJECTED_SECURITY) \
69 X(CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR) \
70 X(CONNECTION_ACCEPT_TIMEOUT_EXCEEDED) \
71 X(UNSUPPORTED_FEATURE_OR_PARAM_VALUE) \
72 X(INVALID_HCI_COMMAND_PARAMETERS) \
73 X(REMOTE_USER_TERMINATED_CONNECTION) \
74 X(REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES) \
75 X(REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF) \
76 X(CONNECTION_TERMINATED_BY_LOCAL_HOST) \
77 X(REPEATED_ATTEMPTS) \
78 X(PAIRING_NOT_ALLOWED) \
79 X(UNKNOWN_LMP_PDU) \
80 X(UNSUPPORTED_REMOTE_OR_LMP_FEATURE) \
81 X(SCO_OFFSET_REJECTED) \
82 X(SCO_INTERVAL_REJECTED) \
83 X(SCO_AIR_MODE_REJECTED) \
84 X(INVALID_LMP_OR_LL_PARAMETERS) \
85 X(UNSPECIFIED_ERROR) \
86 X(UNSUPPORTED_LMP_OR_LL_PARAMETER_VALUE) \
87 X(ROLE_CHANGE_NOT_ALLOWED) \
88 X(LMP_OR_LL_RESPONSE_TIMEOUT) \
89 X(LMP_OR_LL_COLLISION) \
90 X(LMP_PDU_NOT_ALLOWED) \
91 X(ENCRYPTION_MODE_NOT_ACCEPTED) \
92 X(LINK_KEY_CANNOT_BE_CHANGED) \
93 X(REQUESTED_QOS_NOT_SUPPORTED) \
94 X(INSTANT_PASSED) \
95 X(PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) \
96 X(DIFFERENT_TRANSACTION_COLLISION) \
97 X(QOS_UNACCEPTABLE_PARAMETER) \
98 X(QOS_REJECTED) \
99 X(CHANNEL_ASSESSMENT_NOT_SUPPORTED) \
100 X(INSUFFICIENT_SECURITY) \
101 X(PARAMETER_OUT_OF_RANGE) \
102 X(ROLE_SWITCH_PENDING) \
103 X(RESERVED_SLOT_VIOLATION) \
104 X(ROLE_SWITCH_FAILED) \
105 X(EIR_TOO_LARGE) \
106 X(SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST) \
107 X(HOST_BUSY_PAIRING) \
108 X(CONNECTION_REJECTED_NO_SUITABLE_CHANNEL) \
109 X(CONTROLLER_BUSY) \
110 X(UNACCEPTABLE_CONNECTION_PARAM) \
111 X(ADVERTISING_TIMEOUT) \
112 X(CONNECTION_TERMINATED_MIC_FAILURE) \
113 X(CONNECTION_EST_FAILED_OR_SYNC_TIMEOUT) \
114 X(MAX_CONNECTION_FAILED) \
115 X(COARSE_CLOCK_ADJ_REJECTED) \
116 X(TYPE0_SUBMAP_NOT_DEFINED) \
117 X(UNKNOWN_ADVERTISING_IDENTIFIER) \
118 X(LIMIT_REACHED) \
119 X(OPERATION_CANCELLED_BY_HOST) \
120 X(PACKET_TOO_LONG) \
121 X(FAILED) \
122 X(CONNECT_FAILED) \
123 X(AUTH_FAILED) \
124 X(NOT_PAIRED) \
125 X(NO_RESOURCES) \
126 X(TIMEOUT) \
127 X(ALREADY_CONNECTED) \
128 X(BUSY) \
129 X(REJECTED) \
130 X(NOT_SUPPORTED) \
131 X(INVALID_PARAMS) \
132 X(DISCONNECTED) \
133 X(NOT_POWERED) \
134 X(CANCELLED) \
135 X(INVALID_INDEX) \
136 X(RFKILLED) \
137 X(ALREADY_PAIRED) \
138 X(PERMISSION_DENIED) \
139 X(INTERNAL_TIMEOUT) \
140 X(INTERNAL_FAILURE) \
141 X(UNKNOWN)
142
143#define HCI_STATUS_CODE_CASE_TO_STRING(V) case HCIStatusCode::V: return #V;
144
145std::string to_string(const HCIStatusCode ec) noexcept {
146 switch(ec) {
148 default: ; // fall through intended
149 }
150 return "Unknown HCIStatusCode";
151}
152
153std::string to_string(const HCIPacketType op) noexcept {
154 switch(op) {
155 case HCIPacketType::COMMAND: return "COMMAND";
156 case HCIPacketType::ACLDATA: return "ACLDATA";
157 case HCIPacketType::SCODATA: return "SCODATA";
158 case HCIPacketType::EVENT: return "EVENT";
159 case HCIPacketType::DIAG: return "DIAG";
160 case HCIPacketType::VENDOR: return "VENDOR";
161 }
162 return "Unknown HCIPacketType";
163}
164
165std::string to_string(const HCIOGF op) noexcept {
166 (void)op;
167 return "";
168}
169
170#define HCI_OPCODE(X) \
171 X(SPECIAL) \
172 X(CREATE_CONN) \
173 X(DISCONNECT) \
174 X(IO_CAPABILITY_REQ_REPLY) \
175 X(IO_CAPABILITY_REQ_NEG_REPLY) \
176 X(SET_EVENT_MASK) \
177 X(RESET) \
178 X(READ_LOCAL_VERSION) \
179 X(READ_LOCAL_COMMANDS) \
180 X(LE_SET_EVENT_MASK) \
181 X(LE_READ_BUFFER_SIZE) \
182 X(LE_READ_LOCAL_FEATURES) \
183 X(LE_SET_RANDOM_ADDR) \
184 X(LE_SET_ADV_PARAM) \
185 X(LE_READ_ADV_TX_POWER) \
186 X(LE_SET_ADV_DATA) \
187 X(LE_SET_SCAN_RSP_DATA) \
188 X(LE_SET_ADV_ENABLE) \
189 X(LE_SET_SCAN_PARAM) \
190 X(LE_SET_SCAN_ENABLE) \
191 X(LE_CREATE_CONN) \
192 X(LE_CREATE_CONN_CANCEL) \
193 X(LE_READ_WHITE_LIST_SIZE) \
194 X(LE_CLEAR_WHITE_LIST) \
195 X(LE_ADD_TO_WHITE_LIST) \
196 X(LE_DEL_FROM_WHITE_LIST) \
197 X(LE_CONN_UPDATE) \
198 X(LE_READ_REMOTE_FEATURES) \
199 X(LE_ENABLE_ENC) \
200 X(LE_LTK_REPLY_ACK) \
201 X(LE_LTK_REPLY_REJ) \
202 X(LE_ADD_TO_RESOLV_LIST) \
203 X(LE_DEL_FROM_RESOLV_LIST) \
204 X(LE_CLEAR_RESOLV_LIST) \
205 X(LE_READ_RESOLV_LIST_SIZE) \
206 X(LE_READ_PEER_RESOLV_ADDR) \
207 X(LE_READ_LOCAL_RESOLV_ADDR) \
208 X(LE_SET_ADDR_RESOLV_ENABLE) \
209 X(LE_READ_PHY) \
210 X(LE_SET_DEFAULT_PHY) \
211 X(LE_SET_PHY) \
212 X(LE_SET_EXT_ADV_PARAMS) \
213 X(LE_SET_EXT_ADV_DATA) \
214 X(LE_SET_EXT_SCAN_RSP_DATA) \
215 X(LE_SET_EXT_ADV_ENABLE) \
216 X(LE_SET_EXT_SCAN_PARAMS) \
217 X(LE_SET_EXT_SCAN_ENABLE) \
218 X(LE_EXT_CREATE_CONN)
219
220
221#define HCI_OPCODE_CASE_TO_STRING(V) case HCIOpcode::V: return #V;
222
223std::string to_string(const HCIOpcode op) noexcept {
224 switch(op) {
226 default: ; // fall through intended
227 }
228 return "Unknown HCIOpcode";
229}
230
231#define HCI_EVENTTYPE(X) \
232 X(INVALID) \
233 X(INQUIRY_COMPLETE) \
234 X(INQUIRY_RESULT) \
235 X(CONN_COMPLETE) \
236 X(CONN_REQUEST) \
237 X(DISCONN_COMPLETE) \
238 X(AUTH_COMPLETE) \
239 X(REMOTE_NAME) \
240 X(ENCRYPT_CHANGE) \
241 X(CHANGE_LINK_KEY_COMPLETE) \
242 X(REMOTE_FEATURES) \
243 X(REMOTE_VERSION) \
244 X(QOS_SETUP_COMPLETE) \
245 X(CMD_COMPLETE) \
246 X(CMD_STATUS) \
247 X(HARDWARE_ERROR) \
248 X(ROLE_CHANGE) \
249 X(NUM_COMP_PKTS) \
250 X(MODE_CHANGE) \
251 X(PIN_CODE_REQ) \
252 X(LINK_KEY_REQ) \
253 X(LINK_KEY_NOTIFY) \
254 X(CLOCK_OFFSET) \
255 X(PKT_TYPE_CHANGE) \
256 X(ENCRYPT_KEY_REFRESH_COMPLETE) \
257 X(IO_CAPABILITY_REQUEST) \
258 X(IO_CAPABILITY_RESPONSE) \
259 X(LE_META) \
260 X(DISCONN_PHY_LINK_COMPLETE) \
261 X(DISCONN_LOGICAL_LINK_COMPLETE) \
262 X(AMP_Receiver_Report)
263
264#define HCI_EVENTTYPE_CASE_TO_STRING(V) case HCIEventType::V: return #V;
265
266std::string to_string(const HCIEventType op) noexcept {
267 switch(op) {
269 default: ; // fall through intended
270 }
271 return "Unknown HCIEventType";
272}
273
274#define HCI_METATYPE(X) \
275 X(INVALID) \
276 X(LE_CONN_COMPLETE) \
277 X(LE_ADVERTISING_REPORT) \
278 X(LE_CONN_UPDATE_COMPLETE) \
279 X(LE_REMOTE_FEAT_COMPLETE) \
280 X(LE_LTK_REQUEST) \
281 X(LE_REMOTE_CONN_PARAM_REQ) \
282 X(LE_DATA_LENGTH_CHANGE) \
283 X(LE_READ_LOCAL_P256_PUBKEY_COMPLETE) \
284 X(LE_GENERATE_DHKEY_COMPLETE) \
285 X(LE_EXT_CONN_COMPLETE) \
286 X(LE_DIRECT_ADV_REPORT) \
287 X(LE_PHY_UPDATE_COMPLETE) \
288 X(LE_EXT_ADV_REPORT) \
289 X(LE_PERIODIC_ADV_SYNC_ESTABLISHED) \
290 X(LE_PERIODIC_ADV_REPORT) \
291 X(LE_PERIODIC_ADV_SYNC_LOST) \
292 X(LE_SCAN_TIMEOUT) \
293 X(LE_ADV_SET_TERMINATED) \
294 X(LE_SCAN_REQ_RECEIVED) \
295 X(LE_CHANNEL_SEL_ALGO) \
296 X(LE_CONNLESS_IQ_REPORT) \
297 X(LE_CONN_IQ_REPORT) \
298 X(LE_CTE_REQ_FAILED) \
299 X(LE_PERIODIC_ADV_SYNC_TRANSFER_RECV) \
300 X(LE_CIS_ESTABLISHED) \
301 X(LE_CIS_REQUEST) \
302 X(LE_CREATE_BIG_COMPLETE) \
303 X(LE_TERMINATE_BIG_COMPLETE) \
304 X(LE_BIG_SYNC_ESTABLISHED) \
305 X(LE_BIG_SYNC_LOST) \
306 X(LE_REQUEST_PEER_SCA_COMPLETE) \
307 X(LE_PATH_LOSS_THRESHOLD) \
308 X(LE_TRANSMIT_POWER_REPORTING) \
309 X(LE_BIGINFO_ADV_REPORT)
310
311#define HCI_METATYPE_CASE_TO_STRING(V) case HCIMetaEventType::V: return #V;
312
313std::string to_string(const HCIMetaEventType op) noexcept {
314 switch(op) {
316 default: ; // fall through intended
317 }
318 return "Unknown HCIMetaType";
319}
320
321std::unique_ptr<HCICommand> HCICommand::getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept {
322 const HCIPacketType pc = static_cast<HCIPacketType>( jau::get_uint8(buffer + 0) );
323
324 if( HCIPacketType::COMMAND != pc ) {
325 return nullptr;
326 }
327
328 const jau::nsize_t paramSize = buffer_size >= number(HCIConstSizeT::COMMAND_HDR_SIZE) ? jau::get_uint8(buffer + 3) : 0;
329 if( buffer_size < number(HCIConstSizeT::COMMAND_HDR_SIZE) + paramSize ) {
330 WARN_PRINT("HCIEvent::getSpecialized: length mismatch %u < COMMAND_HDR_SIZE(%u) + %u",
331 buffer_size, number(HCIConstSizeT::COMMAND_HDR_SIZE), paramSize);
332 return nullptr;
333 }
334
335 const HCIOpcode oc = static_cast<HCIOpcode>( jau::get_uint16(buffer + 1, jau::lb_endian_t::little) );
336 switch( oc ) {
338 return std::make_unique<HCIDisconnectCmd>(buffer, buffer_size);
340 return std::make_unique<HCILEEnableEncryptionCmd>(buffer, buffer_size);
342 return std::make_unique<HCILELTKReplyAckCmd>(buffer, buffer_size);
344 return std::make_unique<HCILELTKReplyRejCmd>(buffer, buffer_size);
345 default:
346 // No further specialization, use HCIStructCmdCompleteEvt template
347 return std::make_unique<HCICommand>(buffer, buffer_size, 0);
348 }
349}
350
351std::unique_ptr<HCIEvent> HCIEvent::getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept {
352 const HCIPacketType pc = static_cast<HCIPacketType>( jau::get_uint8(buffer + 0) );
353
354 if( HCIPacketType::EVENT != pc ) {
355 return nullptr;
356 }
357
358 const jau::nsize_t paramSize = buffer_size >= number(HCIConstSizeT::EVENT_HDR_SIZE) ? jau::get_uint8(buffer + 2) : 0;
359 if( buffer_size < number(HCIConstSizeT::EVENT_HDR_SIZE) + paramSize ) {
360 WARN_PRINT("HCIEvent::getSpecialized: length mismatch %u < EVENT_HDR_SIZE(%u) + %u",
361 buffer_size, number(HCIConstSizeT::EVENT_HDR_SIZE), paramSize);
362 return nullptr;
363 }
364
365 const HCIEventType ec = static_cast<HCIEventType>( jau::get_uint8(buffer + 1) );
366 switch( ec ) {
368 return std::make_unique<HCIDisconnectionCompleteEvent>(buffer, buffer_size);
370 return std::make_unique<HCICommandCompleteEvent>(buffer, buffer_size);
372 return std::make_unique<HCICommandStatusEvent>(buffer, buffer_size);
375 switch( mec ) {
377 return std::make_unique<HCILELTKReqEvent>(buffer, buffer_size);
378 default:
379 // May use HCIStructCmdCompleteMetaEvt template based on HCIMetaEvent.
380 return std::make_unique<HCIMetaEvent>(buffer, buffer_size, 1);
381 }
382 }
383 default:
384 // No further specialization, use HCIStructCmdCompleteEvt template
385 return std::make_unique<HCIEvent>(buffer, buffer_size, 0);
386 }
387}
388
389std::string HCILocalVersion::toString() noexcept {
390 return "LocalVersion[version "+std::to_string(hci_ver)+"."+std::to_string(hci_rev)+
392}
393
394std::string HCIACLData::l2cap_frame::toString(const PBFlag v) noexcept {
395 switch( v ) {
396 case HCIACLData::l2cap_frame::PBFlag::START_NON_AUTOFLUSH_HOST: return "START_NON_AUTOFLUSH_HOST";
397 case HCIACLData::l2cap_frame::PBFlag::CONTINUING_FRAGMENT: return "CONTINUING_FRAGMENT";
398 case HCIACLData::l2cap_frame::PBFlag::START_AUTOFLUSH: return "START_AUTOFLUSH";
399 case HCIACLData::l2cap_frame::PBFlag::COMPLETE_L2CAP_AUTOFLUSH: return "COMPLETE_L2CAP_AUTOFLUSH";
400 default: return "Unknown PBFlag";
401 }
402}
403
404std::unique_ptr<HCIACLData> HCIACLData::getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept {
405 const HCIPacketType pc = static_cast<HCIPacketType>( jau::get_uint8(buffer + 0) );
406 if( HCIPacketType::ACLDATA != pc ) {
407 return nullptr;
408 }
409 const jau::nsize_t paramSize = buffer_size >= number(HCIConstSizeT::ACL_HDR_SIZE) ? jau::get_uint16(buffer + 3) : 0;
410 if( buffer_size < number(HCIConstSizeT::ACL_HDR_SIZE) + paramSize ) {
411 if( jau::environment::get().verbose ) {
412 WARN_PRINT("HCIACLData::getSpecialized: length mismatch %u < ACL_HDR_SIZE(%u) + %u",
413 buffer_size, number(HCIConstSizeT::ACL_HDR_SIZE), paramSize);
414 }
415 return nullptr;
416 }
417 return std::make_unique<HCIACLData>(buffer, buffer_size);
418}
419
420__pack ( struct l2cap_hdr {
421 uint16_t len;
422 uint16_t cid;
423} );
424
425HCIACLData::l2cap_frame HCIACLData::getL2CAPFrame(const uint8_t* & l2cap_data) const noexcept {
426 const uint16_t h_f = getHandleAndFlags();
427 uint16_t size = static_cast<uint16_t>(getParamSize());
428 const uint8_t * data = getParam();
429 const uint16_t handle = get_handle(h_f);
430 const HCIACLData::l2cap_frame::PBFlag pb_flag { get_pbflag(h_f) };
431 const uint8_t bc_flag = get_bcflag(h_f);
432 const l2cap_hdr* hdr = reinterpret_cast<const l2cap_hdr*>(data);
433
434 l2cap_data = nullptr;
435
436 switch( pb_flag ) {
438 [[fallthrough]];
440 [[fallthrough]];
442 {
443 if( size < sizeof(*hdr) ) {
444 COND_PRINT(HCIEnv::get().DEBUG_EVENT, "l2cap DROP frame-size %d < hdr-size %z, handle ", size, sizeof(*hdr), handle);
445 return l2cap_frame { handle, pb_flag, bc_flag, L2CAP_CID::UNDEFINED, L2CAP_PSM::UNDEFINED, 0 };
446 }
447 const uint16_t len = jau::le_to_cpu(hdr->len);
448 const L2CAP_CID cid = L2CAP_CID( jau::le_to_cpu(hdr->cid) );
449 data += sizeof(*hdr);
450 size -= sizeof(*hdr);
451 if( len <= size ) { // tolerate frame size > len, cutting-off excess octets
452 l2cap_data = data;
453 return l2cap_frame { handle, pb_flag, bc_flag, cid, L2CAP_PSM::UNDEFINED, len };
454 } else {
455 COND_PRINT(HCIEnv::get().DEBUG_EVENT, "l2cap DROP frame-size %d < l2cap-size %d, handle ", size, len, handle);
456 return l2cap_frame { handle, pb_flag, bc_flag, L2CAP_CID::UNDEFINED, L2CAP_PSM::UNDEFINED, 0 };
457 }
458 } break;
459
461 [[fallthrough]];
462 default: // not supported
463 COND_PRINT(HCIEnv::get().DEBUG_EVENT, "l2cap DROP frame flag 0x%2.2x not supported, handle %d, packet-size %d", pb_flag, handle, size);
464 return l2cap_frame { handle, pb_flag, bc_flag, L2CAP_CID::UNDEFINED, L2CAP_PSM::UNDEFINED, 0 };
465 }
466}
467
468} /* namespace direct_bt */
#define HCI_STATUS_CODE_CASE_TO_STRING(V)
Definition: HCITypes.cpp:143
#define HCI_STATUS_CODE(X)
Definition: HCITypes.cpp:53
#define HCI_METATYPE(X)
Definition: HCITypes.cpp:274
#define HCI_EVENTTYPE_CASE_TO_STRING(V)
Definition: HCITypes.cpp:264
#define HCI_OPCODE_CASE_TO_STRING(V)
Definition: HCITypes.cpp:221
#define HCI_METATYPE_CASE_TO_STRING(V)
Definition: HCITypes.cpp:311
#define HCI_EVENTTYPE(X)
Definition: HCITypes.cpp:231
#define HCI_OPCODE(X)
Definition: HCITypes.cpp:170
l2cap_frame getL2CAPFrame(const uint8_t *&l2cap_data) const noexcept
Definition: HCITypes.cpp:425
static std::unique_ptr< HCIACLData > getSpecialized(const uint8_t *buffer, jau::nsize_t const buffer_size) noexcept
Return a newly created specialized instance pointer to base class.
Definition: HCITypes.cpp:404
static std::unique_ptr< HCICommand > getSpecialized(const uint8_t *buffer, jau::nsize_t const buffer_size) noexcept
Return a newly created specialized instance pointer to base class.
Definition: HCITypes.cpp:321
static HCIEnv & get() noexcept
Definition: HCIHandler.hpp:150
static std::unique_ptr< HCIEvent > getSpecialized(const uint8_t *buffer, jau::nsize_t const buffer_size) noexcept
Return a newly created specialized instance pointer to base class.
Definition: HCITypes.cpp:351
static environment & get(const std::string &root_prefix_domain="jau") noexcept
Static singleton initialization of this project's environment with the given global root prefix_domai...
#define COND_PRINT(C,...)
Use for conditional plain messages, prefix '[elapsed_time] '.
Definition: debug.hpp:151
#define WARN_PRINT(...)
Use for unconditional warning messages, prefix '[elapsed_time] Warning @ FILE:LINE FUNC: '.
Definition: debug.hpp:123
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 uint16_t le_to_cpu(uint16_t const l) noexcept
Definition: byte_util.hpp:396
constexpr uint8_t get_uint8(uint8_t const *buffer) noexcept
Definition: byte_util.hpp:611
@ little
Identifier for little endian, equivalent to endian::little.
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
HCIOpcode
BT Core Spec v5.2: Vol 4, Part E HCI: 7.1 Link Controller commands.
Definition: HCITypes.hpp:404
HCIEventType
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7 Events.
Definition: HCITypes.hpp:308
HCIMetaEventType
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.65 LE Meta event.
Definition: HCITypes.hpp:350
@ LE_LTK_REQUEST
LE_LTK_REQUEST.
@ EVENT_HDR_SIZE
HCIPacketType::EVENT header size including HCIPacketType.
@ ACL_HDR_SIZE
HCIPacketType::ACLDATA header size including HCIPacketType.
@ COMMAND_HDR_SIZE
HCIPacketType::COMMAND header size including HCIPacketType.
std::string to_string(const DiscoveryPolicy v) noexcept
Definition: BTAdapter.cpp:58
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
Definition: HCITypes.hpp:138
constexpr uint8_t number(const DiscoveryPolicy rhs) noexcept
Definition: BTAdapter.hpp:100
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:53
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
Representing ACL Datas' L2CAP Frame.
Definition: HCITypes.hpp:977
PBFlag
The Packet_Boundary_Flag.
Definition: HCITypes.hpp:984
@ START_AUTOFLUSH
0b10: Start of an automatically flushable PDU.
@ START_NON_AUTOFLUSH_HOST
0b00: Start of a non-automatically-flushable PDU from Host to Controller.
@ CONTINUING_FRAGMENT
0b01: Continuing fragment.
@ COMPLETE_L2CAP_AUTOFLUSH
A complete L2CAP PDU.
std::string toString() const noexcept
Definition: HCITypes.hpp:1016
std::string toString() noexcept
Definition: HCITypes.cpp:389