Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
HCITypes.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 HCI_TYPES_HPP_
27#define HCI_TYPES_HPP_
28
29#include <cstring>
30#include <string>
31#include <cstdint>
32
33#include <algorithm>
34#include <mutex>
35
36#include <jau/basic_types.hpp>
37#include <jau/octets.hpp>
38
39#include "BTTypes0.hpp"
40#include "BTIoctl.hpp"
41#include "HCIIoctl.hpp"
42
43#include "SMPTypes.hpp"
44
45/**
46 * - - - - - - - - - - - - - - -
47 *
48 * HCITypes.hpp Module for HCIPacket Types, HCIStatusCode etc:
49 *
50 * - BT Core Spec v5.2: Vol 4, Part E Host Controller Interface (HCI): 7 HCI commands and events
51 *
52 */
53namespace direct_bt {
54
55 /** \addtogroup DBTUserAPI
56 *
57 * @{
58 */
59
61 protected:
62 HCIException(std::string type, std::string const& m, const char* file, int line) noexcept
63 : RuntimeException(std::move(type), m, file, line) {}
64
65 public:
66 HCIException(std::string const& m, const char* file, int line) noexcept
67 : RuntimeException("HCIException", m, file, line) {}
68 };
69
71 public:
72 HCIPacketException(std::string const& m, const char* file, int line) noexcept
73 : HCIException("HCIPacketException", m, file, line) {}
74 };
76 public:
77 HCIOpcodeException(std::string const& m, const char* file, int line) noexcept
78 : HCIException("HCIOpcodeException", m, file, line) {}
79 };
80
81 enum class HCIConstInt : int32_t {
82 /** le connection supervisor timeout minimum of 500ms, see getHCIConnSupervisorTimeout() and v5.2 Vol 4, Part E - 7.8.12. */
84 };
85 constexpr int32_t number(const HCIConstInt rhs) noexcept {
86 return static_cast<int>(rhs);
87 }
88
89 /**
90 * Defining the supervising timeout for LE connections to be a multiple of the maximum connection interval as follows:
91 * <pre>
92 * ( 1 + conn_latency ) * conn_interval_max_ms * max(2, multiplier) [ms]
93 * </pre>
94 * If above result is smaller than the given min_result_ms, min_result_ms/10 will be returned.
95 * @param conn_latency the connection latency
96 * @param conn_interval_max_ms the maximum connection interval in [ms]
97 * @param min_result_ms the minimum resulting supervisor timeout, defaults to HCIConstInt::LE_CONN_MIN_TIMEOUT_MS.
98 * If above formula results in a smaller value, min_result_ms/10 will be returned.
99 * @param multiplier recommendation is 6, we use 10 as default for safety.
100 * @return the resulting supervising timeout in 1/10 [ms], suitable for the HCIHandler::le_create_conn() command.
101 */
102 constexpr uint16_t getHCIConnSupervisorTimeout(const uint16_t conn_latency, const uint16_t conn_interval_max_ms,
103 const uint16_t min_result_ms=number(HCIConstInt::LE_CONN_MIN_TIMEOUT_MS),
104 const uint16_t multiplier=10) noexcept
105 {
106 return std::max<uint16_t>(min_result_ms,
107 ( 1 + conn_latency ) * conn_interval_max_ms * std::max<uint16_t>(2, multiplier)
108 ) / 10;
109 }
110
111 /**
112 * Supervisor timeout shall be in the range `[0 - ((supervision_timeout_ms / (conn_interval_max_ms*2)) - 1)]`.
113 * @param supervision_timeout_ms
114 * @param conn_interval_max_ms
115 * @return maximum supervisor timeout, applicable to given parameter
116 */
117 constexpr int32_t getHCIMaxConnLatency(const int16_t supervision_timeout_ms, const int16_t conn_interval_max_ms) {
118 return ((supervision_timeout_ms / (conn_interval_max_ms*2)) - 1);
119 }
120
121 enum class HCIConstU16 : uint16_t {
122 INDEX_NONE = 0xFFFF,
123 /* Net length w/o null-termination */
124 MAX_NAME_LENGTH = 248,
126 MAX_AD_LENGTH = 31
127 };
128 constexpr uint16_t number(const HCIConstU16 rhs) noexcept {
129 return static_cast<uint16_t>(rhs);
130 }
131
132 /**
133 * BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes
134 * <p>
135 * BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 2 Error code descriptions
136 * </p>
137 */
138 enum class HCIStatusCode : uint8_t {
139 SUCCESS = 0x00,
140 UNKNOWN_COMMAND = 0x01,
142 HARDWARE_FAILURE = 0x03,
143 PAGE_TIMEOUT = 0x04,
145 PIN_OR_KEY_MISSING = 0x06,
147 CONNECTION_TIMEOUT = 0x08,
151 COMMAND_DISALLOWED = 0x0c,
162 REPEATED_ATTEMPTS = 0x17,
163 PAIRING_NOT_ALLOWED = 0x18,
164 UNKNOWN_LMP_PDU = 0x19,
166 SCO_OFFSET_REJECTED = 0x1b,
170 UNSPECIFIED_ERROR = 0x1f,
174 LMP_OR_LL_COLLISION = 0x23,
175 LMP_PDU_NOT_ALLOWED = 0x24,
179 INSTANT_PASSED = 0x28,
183 QOS_REJECTED = 0x2d,
187 ROLE_SWITCH_PENDING = 0x32,
189 ROLE_SWITCH_FAILED = 0x35,
190 EIR_TOO_LARGE = 0x36,
192 HOST_BUSY_PAIRING = 0x38,
194 CONTROLLER_BUSY = 0x3a,
196 ADVERTISING_TIMEOUT = 0x3c,
203 LIMIT_REACHED = 0x43,
205 PACKET_TOO_LONG = 0x45,
206
207 // MgmtStatus -> HCIStatusCode
208
209 FAILED = 0xc3,
210 CONNECT_FAILED = 0xc4,
211 AUTH_FAILED = 0xc5,
212 NOT_PAIRED = 0xc6,
213 NO_RESOURCES = 0xc7,
214 TIMEOUT = 0xc8,
215 ALREADY_CONNECTED = 0xc9,
216 BUSY = 0xca,
217 REJECTED = 0xcb,
218 NOT_SUPPORTED = 0xcc,
219 INVALID_PARAMS = 0xcd,
220 DISCONNECTED = 0xce,
221 NOT_POWERED = 0xcf,
222 CANCELLED = 0xd0,
223 INVALID_INDEX = 0xd1,
224 RFKILLED = 0xd2,
225 ALREADY_PAIRED = 0xd3,
226 PERMISSION_DENIED = 0xd4,
227
228 // Direct-BT
229
230 INTERNAL_TIMEOUT = 0xfd,
231 INTERNAL_FAILURE = 0xfe,
232 UNKNOWN = 0xff
233 };
234 constexpr uint8_t number(const HCIStatusCode rhs) noexcept {
235 return static_cast<uint8_t>(rhs);
236 }
237 std::string to_string(const HCIStatusCode ec) noexcept;
238
239 class HCIStatusCodeCategory : public std::error_category {
240 public:
241 const char* name() const noexcept override { return "HCI"; }
242 std::string message(int condition) const override {
243 return "HCI::"+to_string( static_cast<HCIStatusCode>(condition) );
244 }
246 static HCIStatusCodeCategory s;
247 return s;
248 }
249 };
250 inline std::error_code make_error_code( HCIStatusCode e ) noexcept {
251 return std::error_code( number(e), HCIStatusCodeCategory::get() );
252 }
253
254 /**@}*/
255
256 /** \addtogroup DBTSystemAPI
257 *
258 * @{
259 */
260
262 /** HCIPacketType::COMMAND header size including HCIPacketType */
263 COMMAND_HDR_SIZE = 1+3,
264 /** HCIPacketType::ACLDATA header size including HCIPacketType */
265 ACL_HDR_SIZE = 1+4,
266 /** HCIPacketType::SCODATA header size including HCIPacketType */
267 SCO_HDR_SIZE = 1+3,
268 /** HCIPacketType::EVENT header size including HCIPacketType */
269 EVENT_HDR_SIZE = 1+2,
270 /** Total packet size, guaranteed to be handled by adapter. */
271 PACKET_MAX_SIZE = 255
272 };
273 constexpr jau::nsize_t number(const HCIConstSizeT rhs) noexcept {
274 return static_cast<jau::nsize_t>(rhs);
275 }
276
277 enum class HCIPacketType : uint8_t {
278 COMMAND = 0x01,
279 ACLDATA = 0x02,
280 SCODATA = 0x03,
281 EVENT = 0x04,
282 DIAG = 0xf0,
283 VENDOR = 0xff
284 };
285 constexpr uint8_t number(const HCIPacketType rhs) noexcept {
286 return static_cast<uint8_t>(rhs);
287 }
288 std::string to_string(const HCIPacketType op) noexcept;
289
290 enum class HCIOGF : uint8_t {
291 /** link control commands */
292 LINK_CTL = 0x01,
293 /** link policy commands */
294 LINK_POLICY = 0x02,
295 /** controller baseband commands */
296 BREDR_CTL = 0x03,
297 /** LE controller commands */
298 LE_CTL = 0x08
299 };
300 constexpr uint8_t number(const HCIOGF rhs) noexcept {
301 return static_cast<uint8_t>(rhs);
302 }
303 std::string to_string(const HCIOGF op) noexcept;
304
305 /**
306 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7 Events
307 */
308 enum class HCIEventType : uint8_t {
309 INVALID = 0x00,
310 INQUIRY_COMPLETE = 0x01,
311 INQUIRY_RESULT = 0x02,
312 CONN_COMPLETE = 0x03,
313 CONN_REQUEST = 0x04,
314 DISCONN_COMPLETE = 0x05,
315 AUTH_COMPLETE = 0x06,
316 REMOTE_NAME = 0x07,
317 ENCRYPT_CHANGE = 0x08,
319 REMOTE_FEATURES = 0x0b,
320 REMOTE_VERSION = 0x0c,
321 QOS_SETUP_COMPLETE = 0x0d,
322 CMD_COMPLETE = 0x0e,
323 CMD_STATUS = 0x0f,
324 HARDWARE_ERROR = 0x10,
325 ROLE_CHANGE = 0x12,
326 NUM_COMP_PKTS = 0x13,
327 MODE_CHANGE = 0x14,
328 PIN_CODE_REQ = 0x16,
329 LINK_KEY_REQ = 0x17,
330 LINK_KEY_NOTIFY = 0x18,
331 CLOCK_OFFSET = 0x1c,
332 PKT_TYPE_CHANGE = 0x1d,
336 LE_META = 0x3e,
340 // etc etc - incomplete
341 };
342 constexpr uint8_t number(const HCIEventType rhs) noexcept {
343 return static_cast<uint8_t>(rhs);
344 }
345 std::string to_string(const HCIEventType op) noexcept;
346
347 /**
348 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.65 LE Meta event
349 */
350 enum class HCIMetaEventType : uint8_t {
351 INVALID = 0x00,
352 LE_CONN_COMPLETE = 0x01,/**< LE_CONN_COMPLETE */
353 LE_ADVERTISING_REPORT = 0x02,/**< LE_ADVERTISING_REPORT */
354 LE_CONN_UPDATE_COMPLETE = 0x03,/**< LE_CONN_UPDATE_COMPLETE */
355 LE_REMOTE_FEAT_COMPLETE = 0x04,/**< LE_REMOTE_FEAT_COMPLETE */
356 LE_LTK_REQUEST = 0x05,/**< LE_LTK_REQUEST */
357 LE_REMOTE_CONN_PARAM_REQ = 0x06,/**< LE_REMOTE_CONN_PARAM_REQ */
358 LE_DATA_LENGTH_CHANGE = 0x07,/**< LE_DATA_LENGTH_CHANGE */
359 LE_READ_LOCAL_P256_PUBKEY_COMPLETE = 0x08,/**< LE_READ_LOCAL_P256_PUBKEY_COMPLETE */
360 LE_GENERATE_DHKEY_COMPLETE = 0x09,/**< LE_GENERATE_DHKEY_COMPLETE */
361 LE_EXT_CONN_COMPLETE = 0x0A,/**< LE_ENHANCED_CONN_COMPLETE */
362 LE_DIRECT_ADV_REPORT = 0x0B,/**< LE_DIRECT_ADV_REPORT */
363 LE_PHY_UPDATE_COMPLETE = 0x0C,/**< LE_PHY_UPDATE_COMPLETE */
364 LE_EXT_ADV_REPORT = 0x0D,/**< LE_EXT_ADV_REPORT */
365 LE_PERIODIC_ADV_SYNC_ESTABLISHED = 0x0E,/**< LE_PERIODIC_ADV_SYNC_ESTABLISHED */
366 LE_PERIODIC_ADV_REPORT = 0x0F,/**< LE_PERIODIC_ADV_REPORT */
367 LE_PERIODIC_ADV_SYNC_LOST = 0x10,/**< LE_PERIODIC_ADV_SYNC_LOST */
368 LE_SCAN_TIMEOUT = 0x11,/**< LE_SCAN_TIMEOUT */
369 LE_ADV_SET_TERMINATED = 0x12,/**< LE_ADV_SET_TERMINATED */
370 LE_SCAN_REQ_RECEIVED = 0x13,/**< LE_SCAN_REQ_RECEIVED */
371 LE_CHANNEL_SEL_ALGO = 0x14,/**< LE_CHANNEL_SEL_ALGO */
372 LE_CONNLESS_IQ_REPORT = 0x15,/**< LE_CONNLESS_IQ_REPORT */
373 LE_CONN_IQ_REPORT = 0x16,/**< LE_CONN_IQ_REPORT */
374 LE_CTE_REQ_FAILED = 0x17,/**< LE_CTE_REQ_FAILED */
375 LE_PERIODIC_ADV_SYNC_TRANSFER_RECV = 0x18,/**< LE_PERIODIC_ADV_SYNC_TRANSFER_RECV */
376 LE_CIS_ESTABLISHED = 0x19,/**< LE_CIS_ESTABLISHED */
377 LE_CIS_REQUEST = 0x1A,/**< LE_CIS_REQUEST */
378 LE_CREATE_BIG_COMPLETE = 0x1B,/**< LE_CREATE_BIG_COMPLETE */
379 LE_TERMINATE_BIG_COMPLETE = 0x1C,/**< LE_TERMINATE_BIG_COMPLETE */
380 LE_BIG_SYNC_ESTABLISHED = 0x1D,/**< LE_BIG_SYNC_ESTABLISHED */
381 LE_BIG_SYNC_LOST = 0x1E,/**< LE_BIG_SYNC_LOST */
382 LE_REQUEST_PEER_SCA_COMPLETE = 0x1F,/**< LE_REQUEST_PEER_SCA_COMPLETE */
383 LE_PATH_LOSS_THRESHOLD = 0x20,/**< LE_PATH_LOSS_THRESHOLD */
384 LE_TRANSMIT_POWER_REPORTING = 0x21,/**< LE_TRANSMIT_POWER_REPORTING */
385 LE_BIGINFO_ADV_REPORT = 0x22 /**< LE_BIGINFO_ADV_REPORT */
386 };
387 constexpr uint8_t number(const HCIMetaEventType rhs) noexcept {
388 return static_cast<uint8_t>(rhs);
389 }
390 std::string to_string(const HCIMetaEventType op) noexcept;
391
392 /**
393 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.1 Link Controller commands
394 * <p>
395 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.3 Controller & Baseband commands
396 * </p>
397 * <p>
398 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.4 Informational paramters
399 * </p>
400 * <p>
401 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.8 LE Controller commands
402 * </p>
403 */
404 enum class HCIOpcode : uint16_t {
405 SPECIAL = 0x0000,/**< SPECIAL */
406 CREATE_CONN = 0x0405,
407 DISCONNECT = 0x0406,
410 SET_EVENT_MASK = 0x0C01,/**< SET_EVENT_MASK */
411 RESET = 0x0C03,
412 READ_LOCAL_VERSION = 0x1001,
413 READ_LOCAL_COMMANDS = 0x1002,
414 LE_SET_EVENT_MASK = 0x2001,/**< LE_SET_EVENT_MASK */
415 LE_READ_BUFFER_SIZE = 0x2002,
416 LE_READ_LOCAL_FEATURES = 0x2003,
417 LE_SET_RANDOM_ADDR = 0x2005,
418 LE_SET_ADV_PARAM = 0x2006,
419 LE_READ_ADV_TX_POWER = 0x2007,
420 LE_SET_ADV_DATA = 0x2008,
421 LE_SET_SCAN_RSP_DATA = 0x2009,
422 LE_SET_ADV_ENABLE = 0x200a,
423 LE_SET_SCAN_PARAM = 0x200b,
424 LE_SET_SCAN_ENABLE = 0x200c,
425 LE_CREATE_CONN = 0x200d, /**< LE_CREATE_CONN */
426 LE_CREATE_CONN_CANCEL = 0x200e,
428 LE_CLEAR_WHITE_LIST = 0x2010,
429 LE_ADD_TO_WHITE_LIST = 0x2011,
430 LE_DEL_FROM_WHITE_LIST = 0x2012,
431 LE_CONN_UPDATE = 0x2013,
433 LE_ENABLE_ENC = 0x2019,
434 LE_LTK_REPLY_ACK = 0x201A,
435 LE_LTK_REPLY_REJ = 0x201B,
436 LE_ADD_TO_RESOLV_LIST = 0x2027,
438 LE_CLEAR_RESOLV_LIST = 0x2029,
440 /** FIXME: May not be supported by Linux/BlueZ */
442 /** FIXME: May not be supported by Linux/BlueZ */
445 LE_READ_PHY = 0x2030,
446 LE_SET_DEFAULT_PHY = 0x2031,
447 LE_SET_PHY = 0x2032,
448 LE_SET_EXT_ADV_PARAMS = 0x2036,
449 LE_SET_EXT_ADV_DATA = 0x2037,
451 LE_SET_EXT_ADV_ENABLE = 0x2039,
452 LE_SET_EXT_SCAN_PARAMS = 0x2041,
453 LE_SET_EXT_SCAN_ENABLE = 0x2042,
454 LE_EXT_CREATE_CONN = 0x2043,
455 // etc etc - incomplete
456 };
457 constexpr uint16_t number(const HCIOpcode rhs) noexcept {
458 return static_cast<uint16_t>(rhs);
459 }
460 std::string to_string(const HCIOpcode op) noexcept;
461
462 enum class HCIOpcodeBit : uint8_t {
463 SPECIAL = 0,
464 CREATE_CONN = 3,
465 DISCONNECT = 4,
468 SET_EVENT_MASK = 7,
469 RESET = 8,
476 LE_SET_ADV_PARAM = 24,
478 LE_SET_ADV_DATA = 26,
483 LE_CREATE_CONN = 31,
489 LE_CONN_UPDATE = 37,
491 LE_ENABLE_ENC = 39,
492 LE_LTK_REPLY_ACK = 40,
493 LE_LTK_REPLY_REJ = 41,
498 /** FIXME: May not be supported by Linux/BlueZ */
500 /** FIXME: May not be supported by Linux/BlueZ */
503 LE_READ_PHY = 49,
505 LE_SET_PHY = 51,
513 // etc etc - incomplete
514 };
515 constexpr uint8_t number(const HCIOpcodeBit rhs) noexcept {
516 return static_cast<uint8_t>(rhs);
517 }
518
519 /**
520 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4 Exchange of HCI-specific information
521 * <p>
522 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.1 HCI Command packet
523 * </p>
524 * <p>
525 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.4 HCI Event packet
526 * </p>
527 *
528 * HCIPacket:
529 * - uint8_t packet_type
530 */
532 {
533 template<typename T> friend class HCIStructCmdCompleteEvtWrap;
534 template<typename T> friend class HCIStructCmdCompleteMetaEvtWrap;
535
536 protected:
538
539 inline static void checkPacketType(const HCIPacketType type) {
540 switch(type) {
547 return; // OK
548 default:
549 throw HCIPacketException("Unsupported packet type "+jau::to_hexstring(number(type)), E_FILE_LINE);
550 }
551 }
552
553 virtual std::string nameString() const noexcept { return "HCIPacket"; }
554
555 virtual std::string baseString() const noexcept { return ""; }
556
557 virtual std::string valueString() const noexcept { return ""; }
558
559 public:
560 HCIPacket(const HCIPacketType type, const jau::nsize_t total_packet_size)
561 : pdu(total_packet_size, jau::lb_endian_t::little)
562 {
563 if( 0 == total_packet_size ) {
564 throw jau::IndexOutOfBoundsException(1, total_packet_size, E_FILE_LINE);
565 }
566 pdu.put_uint8_nc(0, number(type));
567 }
568
569 /** Persistent memory, w/ ownership ..*/
570 HCIPacket(const uint8_t *packet_data, const jau::nsize_t total_packet_size)
571 : pdu(packet_data, total_packet_size, jau::lb_endian_t::little)
572 {
573 if( 0 == total_packet_size ) {
574 throw jau::IndexOutOfBoundsException(1, total_packet_size, E_FILE_LINE);
575 }
577 }
578
579 virtual ~HCIPacket() noexcept = default;
580
581 /**
582 * Clone template for convenience, based on derived class's copy-constructor.
583 * @tparam T The derived definite class type, deducible by source argument
584 * @param source the source to be copied
585 * @return a new instance.
586 */
587 template<class T>
588 static T* clone(const T& source) noexcept { return new T(source); }
589
590 constexpr jau::nsize_t getTotalSize() const noexcept { return pdu.size(); }
591
592 /** Return the underlying octets read only */
593 jau::TROOctets & getPDU() noexcept { return pdu; }
594
595 HCIPacketType getPacketType() noexcept { return static_cast<HCIPacketType>(pdu.get_uint8_nc(0)); }
596
597 std::string toString() const noexcept {
598 return nameString()+"["+baseString()+", "+valueString()+"]";
599 }
600 };
601 inline std::string to_string(const HCIPacket& p) noexcept { return p.toString(); }
602
603 /**
604 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.1 HCI Command packet
605 * <p>
606 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.8 LE Controller Commands
607 * </p>
608 *
609 * HCIPacket:
610 * - uint8_t packet_type
611 * - HCICommand:
612 * - uint16_t command_type
613 * - uint8_t packet_len (total = 4 + packet_len)
614 */
615 class HCICommand : public HCIPacket
616 {
617 protected:
618 inline static void checkOpcode(const HCIOpcode has, const HCIOpcode min, const HCIOpcode max)
619 {
620 if( has < min || has > max ) {
621 throw HCIOpcodeException("Has opcode "+jau::to_hexstring(number(has))+
622 ", not within range ["+jau::to_hexstring(number(min))+
624 }
625 }
626 inline static void checkOpcode(const HCIOpcode has, const HCIOpcode exp)
627 {
628 if( has != exp ) {
629 throw HCIOpcodeException("Has opcode "+jau::to_hexstring(number(has))+
630 ", not matching "+jau::to_hexstring(number(exp)), E_FILE_LINE);
631 }
632 }
633
634 std::string nameString() const noexcept override { return "HCICommand"; }
635
636 std::string baseString() const noexcept override {
637 return "opcode="+jau::to_hexstring(number(getOpcode()))+" "+to_string(getOpcode());
638 }
639 std::string valueString() const noexcept override {
640 const jau::nsize_t psz = getParamSize();
641 const std::string ps = psz > 0 ? jau::bytesHexString(getParam(), 0, psz, true /* lsbFirst */) : "";
642 return "param[size "+std::to_string(getParamSize())+", data "+ps+"], tsz "+std::to_string(getTotalSize());
643 }
644
645 public:
646
647 /**
648 * Return a newly created specialized instance pointer to base class.
649 * <p>
650 * Returned memory reference is managed by caller (delete etc)
651 * </p>
652 */
653 static std::unique_ptr<HCICommand> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept;
654
655 /** Persistent memory, w/ ownership ..*/
656 HCICommand(const uint8_t* buffer, const jau::nsize_t buffer_len, const jau::nsize_t exp_param_size)
657 : HCIPacket(buffer, buffer_len)
658 {
659 const jau::nsize_t paramSize = getParamSize();
661 if( exp_param_size > paramSize ) {
662 throw jau::IndexOutOfBoundsException(exp_param_size, paramSize, E_FILE_LINE);
663 }
665 }
666
667 /** Enabling manual construction of command without given value. */
668 HCICommand(const HCIOpcode opc, const jau::nsize_t param_size)
670 {
672 if( 255 < param_size ) {
673 throw jau::IllegalArgumentException("HCICommand param size "+std::to_string(param_size)+" > 255", E_FILE_LINE);
674 }
675
676 pdu.put_uint16_nc(1, static_cast<uint16_t>(opc));
677 pdu.put_uint8_nc(3, param_size);
678 }
679
680 /** Enabling manual construction of command with given value. */
681 HCICommand(const HCIOpcode opc, const uint8_t* param, const jau::nsize_t param_size)
682 : HCICommand(opc, param_size)
683 {
684 if( param_size > 0 ) {
685 memcpy(pdu.get_wptr_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)), param, param_size);
686 }
687 }
688
689 ~HCICommand() noexcept override = default;
690
691 HCIOpcode getOpcode() const noexcept { return static_cast<HCIOpcode>( pdu.get_uint16_nc(1) ); }
692 jau::nsize_t getParamSize() const noexcept { return pdu.get_uint8_nc(3); }
693 const uint8_t* getParam() const noexcept { return pdu.get_ptr_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)); }
694
695 void trimParamSize(const jau::nsize_t param_size) {
696 if( 255 < param_size ) {
697 throw jau::IllegalArgumentException("HCICommand new param size "+std::to_string(param_size)+" > 255", E_FILE_LINE);
698 }
699 if( getParamSize() < param_size ) {
700 throw jau::IllegalArgumentException("HCICommand new param size "+std::to_string(param_size)+" > old "+std::to_string(getParamSize()), E_FILE_LINE);
701 }
702 const jau::nsize_t new_total_packet_size = number(HCIConstSizeT::COMMAND_HDR_SIZE)+param_size;
703 pdu.resize( new_total_packet_size );
704 pdu.put_uint8_nc(3, param_size);
705 }
706 };
707
708 /**
709 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.6 Disconnect command
710 *
711 * HCIPacket:
712 * - uint8_t packet_type
713 * - HCICommand:
714 * - uint16_t command_type
715 * - uint8_t packet_len (total = 4 + packet_len)
716 * - HCIDisconnectCmd:
717 * - uint16_t handle
718 * - uint8_t reason
719 */
721 {
722 protected:
723 std::string nameString() const noexcept override { return "HCIDisconnectCmd"; }
724
725 std::string valueString() const noexcept override {
726 const jau::nsize_t psz = getParamSize();
727 const std::string ps = psz > 0 ? jau::bytesHexString(getParam(), 0, psz, true /* lsbFirst */) : "";
728 return "param[size "+std::to_string(getParamSize())+", data "+ps+"], tsz "+std::to_string(getTotalSize());
729 }
730
731 public:
732 HCIDisconnectCmd(const uint8_t* buffer, const jau::nsize_t buffer_len)
733 : HCICommand(buffer, buffer_len, 2+1)
734 {
736 }
737
738 HCIDisconnectCmd(const uint16_t handle, HCIStatusCode reason)
740 {
743 }
744
745 constexpr uint16_t getHandle() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)); }
746
748 };
749
750 /**
751 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.24 LE Enable Encryption command
752 *
753 * HCIPacket:
754 * - uint8_t packet_type
755 * - HCICommand:
756 * - uint16_t command_type
757 * - uint8_t packet_len (total = 4 + packet_len)
758 * - HCILEEnableEncryptionCmd:
759 * - uint16_t handle
760 * - uint64_t random_number (8 octets)
761 * - uint16_t ediv (2 octets)
762 * - uint128_t ltk (16 octets)
763 *
764 * Controller replies to this command with HCI_Command_Status event to the Host.
765 * - If the connection wasn't encrypted yet, HCI_Encryption_Change event shall occur when encryption has been started.
766 * - Otherwise HCI_Encryption_Key_Refresh_Complete event shall occur when encryption has been resumed.
767 *
768 * This command shall only be used when the local device’s role is BTRole::Master (initiator).
769 *
770 * Encryption key belongs to the remote device having role BTRole::Slave (responder).
771 *
772 * The encryption key matches the LTK from SMP messaging in SC mode only!
773 */
775 {
776 protected:
777 std::string nameString() const noexcept override { return "HCILEEnableEncryptionCmd"; }
778
779 std::string valueString() const noexcept override {
780 return "data[handle "+jau::to_hexstring(getHandle())+
781 ", rand "+jau::bytesHexString(pdu.get_ptr_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)), 2, 8, false /* lsbFirst */)+
782 ", ediv "+jau::bytesHexString(pdu.get_ptr_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)), 2+8, 2, false /* lsbFirst */)+
783 ", ltk "+jau::bytesHexString(pdu.get_ptr_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)), 2+8+2, 16, true /* lsbFirst */)+
784 "], tsz "+std::to_string(getTotalSize());
785 }
786
787 public:
788 HCILEEnableEncryptionCmd(const uint8_t* buffer, const jau::nsize_t buffer_len)
789 : HCICommand(buffer, buffer_len, 28)
790 {
792 }
793
794 HCILEEnableEncryptionCmd(const uint16_t handle, const uint64_t rand, const uint16_t ediv, const jau::uint128dp_t ltk)
796 {
801 }
802
803 constexpr uint16_t getHandle() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)); }
804
805 /**
806 * Returns the 64-bit Rand value (8 octets) being distributed
807 * <p>
808 * See Vol 3, Part H, 2.4.2.3 SM - Generation of CSRK - LE legacy pairing - generation of LTK, EDIV and Rand.
809 * </p>
810 */
811 constexpr uint64_t getRand() const noexcept { return pdu.get_uint64_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)+2); }
812
813 /**
814 * Returns the 16-bit EDIV value (2 octets) being distributed
815 * <p>
816 * See Vol 3, Part H, 2.4.2.3 SM - Generation of CSRK - LE legacy pairing - generation of LTK, EDIV and Rand.
817 * </p>
818 */
819 constexpr uint16_t getEDIV() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)+2+8); }
820
821 /**
822 * Returns the 128-bit Long Term Key (16 octets)
823 * <p>
824 * The generated LTK value being distributed,
825 * see Vol 3, Part H, 2.4.2.3 SM - LE legacy pairing - generation of LTK, EDIV and Rand.
826 * </p>
827 */
829 };
830
831 /**
832 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.25 LE Long Term Key Request Reply command
833 *
834 * HCIPacket:
835 * - uint8_t packet_type
836 * - HCICommand:
837 * - uint16_t command_type
838 * - uint8_t packet_len (total = 4 + packet_len)
839 * - HCILELTKReplyAckCmd:
840 * - uint16_t handle
841 * - uint128_t ltk (16 octets)
842 *
843 * This command shall only be used when the local device’s role is BTRole::Slave (responder).
844 *
845 * LTK belongs to the local device having role BTRole::Slave (responder).
846 *
847 * The LTK matches the LTK from SMP messaging in SC mode only!
848 */
850 {
851 protected:
852 std::string nameString() const noexcept override { return "HCILELTKReplyAckCmd"; }
853
854 std::string valueString() const noexcept override {
855 return "data[handle "+jau::to_hexstring(getHandle())+
856 ", ltk "+jau::bytesHexString(pdu.get_ptr_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)), 2, 16, true /* lsbFirst */)+
857 "], tsz "+std::to_string(getTotalSize());
858 }
859 public:
860 HCILELTKReplyAckCmd(const uint8_t* buffer, const jau::nsize_t buffer_len)
861 : HCICommand(buffer, buffer_len, 18)
862 {
864 }
865
866 HCILELTKReplyAckCmd(const uint16_t handle, const jau::uint128dp_t ltk)
868 {
871 }
872
873 constexpr uint16_t getHandle() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)); }
874
875 /**
876 * Returns the 128-bit Long Term Key (16 octets)
877 * <p>
878 * The generated LTK value being distributed,
879 * see Vol 3, Part H, 2.4.2.3 SM - LE legacy pairing - generation of LTK, EDIV and Rand.
880 * </p>
881 */
883 };
884
885 /**
886 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.26 LE Long Term Key Request Negative Reply command
887 *
888 * HCIPacket:
889 * - uint8_t packet_type
890 * - HCICommand:
891 * - uint16_t command_type
892 * - uint8_t packet_len (total = 4 + packet_len)
893 * - HCILELTKReplyRejCmd:
894 * - uint16_t handle
895 *
896 */
898 {
899 protected:
900 std::string nameString() const noexcept override { return "HCILELTKReplyRejCmd"; }
901
902 std::string valueString() const noexcept override {
903 return "data[handle "+jau::to_hexstring(getHandle())+
904 "], tsz "+std::to_string(getTotalSize());
905 }
906
907 public:
908 HCILELTKReplyRejCmd(const uint8_t* buffer, const jau::nsize_t buffer_len)
909 : HCICommand(buffer, buffer_len, 2)
910 {
912 }
913
914 HCILELTKReplyRejCmd(const uint16_t handle)
916 {
918 }
919
920 constexpr uint16_t getHandle() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::COMMAND_HDR_SIZE)); }
921 };
922
923 /**
924 * Generic HCICommand wrapper for any HCI IOCTL structure
925 * @tparam hcistruct the template typename, e.g. 'hci_cp_create_conn' for 'struct hci_cp_create_conn'
926 */
927 template<typename hcistruct>
929 {
930 protected:
931 std::string nameString() const noexcept override { return "HCIStructCmd"; }
932
933 public:
934 /** Enabling manual construction of command with zero value. */
936 : HCICommand(opc, sizeof(hcistruct))
937 {
938 hcistruct * cp = getWStruct();
939 bzero((void*)cp, sizeof(hcistruct));
940 }
941
942 /** Enabling manual construction of command with given value. */
943 HCIStructCommand(const HCIOpcode opc, const hcistruct &cp)
944 : HCICommand(opc, (const uint8_t *)(&cp), sizeof(hcistruct))
945 { }
946
947 const hcistruct * getStruct() const noexcept { return (const hcistruct *)(getParam()); }
948 hcistruct * getWStruct() noexcept { return (hcistruct *)( pdu.get_wptr_nc( number(HCIConstSizeT::COMMAND_HDR_SIZE) ) ); }
949 };
950
951 class HCIHandler; // fwd
952
953 /**
954 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.2 HCI ACL Data packets
955 * <p>
956 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7 Events
957 * </p>
958 * <p>
959 * ACL Data allows us to receive SMPPDUMsg inside an HCIACLData::l2cap_frame
960 * via HCIACLData::getL2CAPFrame() and HCIACLData::l2cap_frame::getSMPPDUMsg().
961 * </p>
962 * <pre>
963 * uint16_t handle;
964 * uint16_t len;
965 * uint8_t data[len];
966 * </pre>
967 */
968 class HCIACLData : public HCIPacket
969 {
970 public:
971 /**
972 * Representing ACL Datas' L2CAP Frame
973 * <p>
974 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.2 HCI ACL Data packets
975 * </p>
976 */
977 struct l2cap_frame {
978 /**
979 * The Packet_Boundary_Flag
980 * <p>
981 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.2 HCI ACL Data packets
982 * </p>
983 */
984 enum class PBFlag : uint8_t {
985 /** 0b00: Start of a non-automatically-flushable PDU from Host to Controller. Value 0b00. */
986 START_NON_AUTOFLUSH_HOST = 0b00,
987 /** 0b01: Continuing fragment. Value 0b01. */
988 CONTINUING_FRAGMENT = 0b01,
989 /** 0b10: Start of an automatically flushable PDU. Value 0b10. */
990 START_AUTOFLUSH = 0b10,
991 /** A complete L2CAP PDU. Automatically flushable. Value 0b11.*/
992 COMPLETE_L2CAP_AUTOFLUSH = 0b11,
993 };
994 static constexpr uint8_t number(const PBFlag v) noexcept { return static_cast<uint8_t>(v); }
995 static std::string toString(const PBFlag v) noexcept;
996
997 /** The connection handle */
998 const uint16_t handle;
1000 /** The Broadcast_Flag */
1001 const uint8_t bc_flag;
1004 const uint16_t len;
1005
1006 /** Oly for manual injection, usually using casted pointer */
1007 l2cap_frame(const uint16_t handle_, const PBFlag pb_flag_, const uint8_t bc_flag_,
1008 const L2CAP_CID cid_, const L2CAP_PSM psm_, const uint16_t len_)
1009 : handle(handle_), pb_flag(pb_flag_), bc_flag(bc_flag_),
1010 cid(cid_), psm(psm_), len(len_) {}
1011
1012 constexpr bool isSMP() const noexcept { return L2CAP_CID::SMP == cid || L2CAP_CID::SMP_BREDR == cid; }
1013
1014 constexpr bool isGATT() const noexcept { return L2CAP_CID::ATT == cid; }
1015
1016 std::string toString() const noexcept {
1017 return "l2cap[handle "+jau::to_hexstring(handle)+", flags[pb "+toString(pb_flag)+", bc "+jau::to_hexstring(bc_flag)+
1018 "], cid "+to_string(cid)+
1019 ", psm "+to_string(psm)+", len "+std::to_string(len)+ "]";
1020 }
1021 std::string toString(const uint8_t* l2cap_data) const noexcept {
1022 const std::string ds = nullptr != l2cap_data && 0 < len ? jau::bytesHexString(l2cap_data, 0, len, true /* lsbFirst*/) : "empty";
1023 return "l2cap[handle "+jau::to_hexstring(handle)+", flags[pb "+toString(pb_flag)+", bc "+jau::to_hexstring(bc_flag)+
1024 "], cid "+to_string(cid)+
1025 ", psm "+to_string(psm)+", len "+std::to_string(len)+", data "+ds+"]";
1026 }
1027 };
1028
1029 /**
1030 * Return a newly created specialized instance pointer to base class.
1031 * <p>
1032 * Returned memory reference is managed by caller (delete etc)
1033 * </p>
1034 */
1035 static std::unique_ptr<HCIACLData> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept;
1036
1037 /**
1038 * Returns the handle.
1039 */
1040 constexpr static uint16_t get_handle(const uint16_t handle_and_flags) noexcept { return static_cast<uint16_t>(handle_and_flags & 0x0fff); }
1041
1042 /**
1043 * Returns the Packet_Boundary_Flag.
1044 */
1045 constexpr static uint8_t get_pbflag(const uint16_t handle_and_flags) noexcept { return static_cast<uint8_t>( ( handle_and_flags >> 12 ) & 0b11 ); }
1046
1047 /**
1048 * Returns the Broadcast_Flag.
1049 */
1050 constexpr static uint8_t get_bcflag(const uint16_t handle_and_flags) noexcept { return static_cast<uint8_t>( ( handle_and_flags >> 14 ) & 0b11 ); }
1051
1052 /** Persistent memory, w/ ownership ..*/
1053 HCIACLData(const uint8_t* buffer, const jau::nsize_t buffer_len)
1054 : HCIPacket(buffer, buffer_len)
1055 {
1056 const jau::nsize_t baseParamSize = getParamSize();
1058 }
1059
1060 uint16_t getHandleAndFlags() const noexcept { return pdu.get_uint16_nc(1); }
1061 jau::nsize_t getParamSize() const noexcept { return pdu.get_uint16_nc(3); }
1062 const uint8_t* getParam() const noexcept { return pdu.get_ptr_nc(number(HCIConstSizeT::ACL_HDR_SIZE)); }
1063
1064 l2cap_frame getL2CAPFrame(const uint8_t* & l2cap_data) const noexcept;
1065
1066 std::string toString() const noexcept {
1067 const uint8_t* l2cap_data;
1068 return "ACLData[size "+std::to_string(getParamSize())+", data "+getL2CAPFrame(l2cap_data).toString(l2cap_data)+", tsz "+std::to_string(getTotalSize())+"]";
1069 }
1070 std::string toString(const l2cap_frame& l2cap, const uint8_t* l2cap_data) const noexcept {
1071 return "ACLData[size "+std::to_string(getParamSize())+", data "+l2cap.toString(l2cap_data)+", tsz "+std::to_string(getTotalSize())+"]";
1072 }
1073 };
1074
1075 /**
1076 * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.4 HCI Event packet
1077 * <p>
1078 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7 Events
1079 * </p>
1080 *
1081 * HCIPacket:
1082 * - uint8_t packet_type
1083 * - HCIEvent:
1084 * - uint8_t event_type
1085 * - uint8_t packet_len (total = 3 + packet_len)
1086 */
1087 class HCIEvent : public HCIPacket
1088 {
1089 protected:
1090 uint64_t ts_creation;
1091
1092 inline static void checkEventType(const HCIEventType has, const HCIEventType min, const HCIEventType max)
1093 {
1094 if( has < min || has > max ) {
1095 throw HCIOpcodeException("Has evcode "+jau::to_hexstring(number(has))+
1096 ", not within range ["+jau::to_hexstring(number(min))+
1098 }
1099 }
1100 inline static void checkEventType(const HCIEventType has, const HCIEventType exp)
1101 {
1102 if( has != exp ) {
1103 throw HCIOpcodeException("Has evcode "+jau::to_hexstring(number(has))+
1104 ", not matching "+jau::to_hexstring(number(exp)), E_FILE_LINE);
1105 }
1106 }
1107
1108 std::string nameString() const noexcept override { return "HCIEvent"; }
1109
1110 std::string baseString() const noexcept override {
1111 return "event="+jau::to_hexstring(number(getEventType()))+" "+to_string(getEventType());
1112 }
1113 std::string valueString() const noexcept override {
1114 const jau::nsize_t d_sz_base = getBaseParamSize();
1115 const jau::nsize_t d_sz = getParamSize();
1116 const std::string d_str = d_sz > 0 ? jau::bytesHexString(getParam(), 0, d_sz, true /* lsbFirst */) : "";
1117 return "data[size "+std::to_string(d_sz)+"/"+std::to_string(d_sz_base)+", data "+d_str+"], tsz "+std::to_string(getTotalSize());
1118 }
1119
1120 jau::nsize_t getBaseParamSize() const noexcept { return pdu.get_uint8_nc(2); }
1121
1122 public:
1123
1124 /**
1125 * Return a newly created specialized instance pointer to base class.
1126 * <p>
1127 * Returned memory reference is managed by caller (delete etc)
1128 * </p>
1129 */
1130 static std::unique_ptr<HCIEvent> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept;
1131
1132 /** Persistent memory, w/ ownership ..*/
1133 HCIEvent(const uint8_t* buffer, const jau::nsize_t buffer_len, const jau::nsize_t exp_param_size)
1134 : HCIPacket(buffer, buffer_len), ts_creation(jau::getCurrentMilliseconds())
1135 {
1136 const jau::nsize_t baseParamSize = getBaseParamSize();
1138 if( exp_param_size > baseParamSize ) {
1139 throw jau::IndexOutOfBoundsException(exp_param_size, baseParamSize, E_FILE_LINE);
1140 }
1142 }
1143
1144 /** Enabling manual construction of event without given value. */
1145 HCIEvent(const HCIEventType evt, const jau::nsize_t param_size=0)
1147 {
1149 pdu.put_uint8_nc(1, number(evt));
1150 pdu.put_uint8_nc(2, param_size);
1151 }
1152
1153 /** Enabling manual construction of event with given value. */
1154 HCIEvent(const HCIEventType evt, const uint8_t* param, const jau::nsize_t param_size)
1155 : HCIEvent(evt, param_size)
1156 {
1157 if( param_size > 0 ) {
1158 memcpy(pdu.get_wptr_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)), param, param_size);
1159 }
1160 }
1161
1162 ~HCIEvent() noexcept override = default;
1163
1164 uint64_t getTimestamp() const noexcept { return ts_creation; }
1165
1166 constexpr HCIEventType getEventType() const noexcept { return static_cast<HCIEventType>( pdu.get_uint8_nc(1) ); }
1167 constexpr bool isEvent(HCIEventType t) const noexcept { return t == getEventType(); }
1168
1169 /**
1170 * The meta subevent type
1171 */
1173 bool isMetaEvent(HCIMetaEventType t) const noexcept { return t == getMetaEventType(); }
1174
1175 virtual jau::nsize_t getParamSize() const noexcept { return getBaseParamSize(); }
1176 virtual const uint8_t* getParam() const noexcept { return pdu.get_ptr_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)); }
1177
1178 virtual bool validate(const HCICommand & cmd) const noexcept { (void)cmd; return true; }
1179 };
1180
1181 /**
1182 * Generic HCIEvent wrapper for any HCI IOCTL 'command complete' alike event struct having a HCIStatusCode uint8_t status field.
1183 * @tparam hcistruct the template typename, e.g. 'hci_ev_conn_complete' for 'struct hci_ev_conn_complete'
1184 */
1185 template<typename hcistruct>
1187 {
1188 private:
1189 HCIEvent &orig;
1190
1191 public:
1193 : orig(orig_)
1194 { }
1195 std::string toString() const noexcept { return orig.toString(); }
1196
1197 bool isTypeAndSizeValid(const HCIEventType ec) const noexcept {
1198 return orig.isEvent(ec) &&
1199 orig.pdu.is_range_valid(0, number(HCIConstSizeT::EVENT_HDR_SIZE)+sizeof(hcistruct));
1200 }
1201 const hcistruct * getStruct() const noexcept { return (const hcistruct *)( orig.getParam() ); }
1202 HCIStatusCode getStatus() const noexcept { return static_cast<HCIStatusCode>( getStruct()->status ); }
1203
1204 hcistruct * getWStruct() noexcept { return (hcistruct *)( orig.pdu.get_wptr_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)) ); }
1205 };
1206
1207
1208 /**
1209 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.5 Disconnection Complete event
1210 * <p>
1211 * Size 4
1212 __u8 status;
1213 __le16 handle;
1214 __u8 reason;
1215 * </p>
1216 */
1218 {
1219 protected:
1220 std::string nameString() const noexcept override { return "HCIDisconnectionCompleteEvent"; }
1221
1222 std::string baseString() const noexcept override {
1223 return HCIEvent::baseString()+
1224 ", status "+jau::to_hexstring(static_cast<uint8_t>(getStatus()))+" "+to_string(getStatus())+
1225 ", handle "+jau::to_hexstring(getHandle())+
1226 ", reason "+jau::to_hexstring(static_cast<uint8_t>(getReason()))+" "+to_string(getReason());
1227 }
1228
1229 public:
1230 HCIDisconnectionCompleteEvent(const uint8_t* buffer, const jau::nsize_t buffer_len)
1231 : HCIEvent(buffer, buffer_len, 4)
1232 {
1234 }
1235
1237 uint16_t getHandle() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)+1); }
1239
1240 bool validate(const HCICommand & cmd) const noexcept override {
1241 return cmd.getOpcode() == HCIOpcode::DISCONNECT;
1242 }
1243 };
1244
1245 /**
1246 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.14 Command Complete event
1247 * <p>
1248 * Size 3 + return size
1249 __u8 ncmd;
1250 __le16 opcode;
1251 Return_Paramters of variable length, usually with '__u8 status' first.
1252 * </p>
1253 */
1255 {
1256 protected:
1257 std::string nameString() const noexcept override { return "HCICmdCompleteEvent"; }
1258
1259 std::string baseString() const noexcept override {
1260 return HCIEvent::baseString()+", opcode="+jau::to_hexstring(static_cast<uint16_t>(getOpcode()))+
1261 " "+to_string(getOpcode())+
1263 }
1264
1265 public:
1266 HCICommandCompleteEvent(const uint8_t* buffer, const jau::nsize_t buffer_len)
1267 : HCIEvent(buffer, buffer_len, 3)
1268 {
1270 }
1271
1272 /**
1273 * The Number of HCI Command packets which are allowed to be sent to the Controller from the Host.
1274 * <p>
1275 * Range: 0 to 255
1276 * </p>
1277 */
1279
1280 /**
1281 * The associated command
1282 */
1283 HCIOpcode getOpcode() const noexcept { return static_cast<HCIOpcode>( pdu.get_uint16_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)+1) ); }
1284
1285 jau::nsize_t getReturnParamSize() const noexcept { return getParamSize() - 3; }
1286 const uint8_t* getReturnParam() const { return pdu.get_ptr(number(HCIConstSizeT::EVENT_HDR_SIZE)+3); }
1287
1288 bool validate(const HCICommand & cmd) const noexcept override {
1289 return cmd.getOpcode() == getOpcode();
1290 }
1291 };
1292
1293 /**
1294 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.15 Command Status event
1295 * <p>
1296 * Size 4
1297 __u8 status;
1298 __u8 ncmd;
1299 __le16 opcode;
1300 * </p>
1301 */
1303 {
1304 protected:
1305 std::string nameString() const noexcept override { return "HCICmdStatusEvent"; }
1306
1307 std::string baseString() const noexcept override {
1308 return HCIEvent::baseString()+", opcode="+jau::to_hexstring(static_cast<uint16_t>(getOpcode()))+
1309 " "+to_string(getOpcode())+
1311 ", status "+jau::to_hexstring(static_cast<uint8_t>(getStatus()))+" "+to_string(getStatus());
1312 }
1313
1314 public:
1315 HCICommandStatusEvent(const uint8_t* buffer, const jau::nsize_t buffer_len)
1316 : HCIEvent(buffer, buffer_len, 4)
1317 {
1319 }
1320
1322
1323 /**
1324 * The Number of HCI Command packets which are allowed to be sent to the Controller from the Host.
1325 * <p>
1326 * Range: 0 to 255
1327 * </p>
1328 */
1330
1331 /**
1332 * The associated command
1333 */
1334 HCIOpcode getOpcode() const noexcept { return static_cast<HCIOpcode>( pdu.get_uint16_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)+1+1) ); }
1335
1336 bool validate(const HCICommand & cmd) const noexcept override {
1337 return cmd.getOpcode() == getOpcode();
1338 }
1339 };
1340
1341 /**
1342 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.65 LE Meta event
1343 *
1344 * HCIPacket:
1345 * - uint8_t packet_type
1346 * - HCIEvent:
1347 * - uint8_t event_type
1348 * - uint8_t packet_len (total = 3 + packet_len)
1349 * - HCIMetaEvent
1350 * - uint8_t meta_event_type
1351 */
1352 class HCIMetaEvent : public HCIEvent
1353 {
1354 protected:
1355 std::string nameString() const noexcept override { return "HCIMetaEvent"; }
1356
1357 static void checkMetaType(const HCIMetaEventType has, const HCIMetaEventType exp)
1358 {
1359 if( has != exp ) {
1360 throw HCIOpcodeException("Has meta "+jau::to_hexstring(number(has))+
1361 ", not matching "+jau::to_hexstring(number(exp)), E_FILE_LINE);
1362 }
1363 }
1364
1365 std::string baseString() const noexcept override {
1366 return "event="+jau::to_hexstring(number(getMetaEventType()))+" "+to_string(getMetaEventType())+" (le-meta)";
1367 }
1368
1369 public:
1370 /** Passing through preset buffer of this type */
1371 HCIMetaEvent(const uint8_t* buffer, const jau::nsize_t buffer_len, const jau::nsize_t exp_meta_param_size)
1372 : HCIEvent(buffer, buffer_len, 1+exp_meta_param_size)
1373 {
1375 }
1376
1377 /** Enabling manual construction of event without given value. */
1378 HCIMetaEvent(const HCIMetaEventType mc, const jau::nsize_t meta_param_size)
1379 : HCIEvent(HCIEventType::LE_META, 1+meta_param_size)
1380 {
1382 }
1383
1384 /** Enabling manual construction of event with given value. */
1385 HCIMetaEvent(const HCIMetaEventType mc, const uint8_t * meta_param, const jau::nsize_t meta_param_size)
1386 : HCIMetaEvent(mc, meta_param_size)
1387 {
1388 if( meta_param_size > 0 ) {
1389 memcpy(pdu.get_wptr_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)+1), meta_param, meta_param_size);
1390 }
1391 }
1392
1394
1395 jau::nsize_t getParamSize() const noexcept override { return HCIEvent::getParamSize()-1; }
1396 const uint8_t* getParam() const noexcept override { return HCIEvent::getParam()+1; }
1397 };
1398
1399
1400 /**
1401 * BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.65.5 LE Long Term Key Request event
1402 *
1403 * HCIPacket:
1404 * - uint8_t packet_type
1405 * - HCIEvent:
1406 * - uint8_t event_type
1407 * - uint8_t packet_len (total = 3 + packet_len)
1408 * - HCIMetaEvent
1409 * - uint8_t meta_event_type
1410 * - HCILELTKReqEvent:
1411 * - uint16_t connection_handle (2 octets)
1412 * - uint64_t random_number (8 octets)
1413 * - uint16_t ediv (2 octets)
1414 *
1415 * This event indicates that the peer device being BTRole::Master, attempts to encrypt or re-encrypt the link
1416 * and is requesting the LTK from the Host.
1417 *
1418 * This event shall only be generated when the local device’s role is BTRole::Slave (responder, adapter in peripheral mode).
1419 *
1420 * Rand and Ediv belong to the local device having role BTRole::Slave (responder).
1421 *
1422 * Rand and Ediv matches the LTK from SMP messaging in SC mode only!
1423 *
1424 * It shall be replied via HCILELTKReplyAckCmd (HCIOpcode::LE_LTK_REPLY_ACK) or HCILELTKReplyRejCmd (HCIOpcode::LE_LTK_REPLY_REJ)
1425 */
1427 {
1428 protected:
1429 std::string nameString() const noexcept override { return "HCILELTKReqEvent"; }
1430
1431 std::string valueString() const noexcept override {
1432 return "data[handle "+jau::to_hexstring(getHandle())+
1433 ", rand "+jau::bytesHexString(pdu.get_ptr_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)), 1+2, 8, false /* lsbFirst */)+
1434 ", ediv "+jau::bytesHexString(pdu.get_ptr_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)), 1+2+8, 2, false /* lsbFirst */)+
1435 "], tsz "+std::to_string(getTotalSize());
1436 }
1437 public:
1438 /** Passing through preset buffer of this type */
1439 HCILELTKReqEvent(const uint8_t* buffer, const jau::nsize_t buffer_len)
1440 : HCIMetaEvent(buffer, buffer_len, 12)
1441 {
1444 }
1445
1446 constexpr uint16_t getHandle() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)+1); }
1447
1448 /**
1449 * Returns the 64-bit Rand value (8 octets) being distributed
1450 * <p>
1451 * See Vol 3, Part H, 2.4.2.3 SM - Generation of CSRK - LE legacy pairing - generation of LTK, EDIV and Rand.
1452 * </p>
1453 */
1454 constexpr uint64_t getRand() const noexcept { return pdu.get_uint64_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)+1+2); }
1455
1456 /**
1457 * Returns the 16-bit EDIV value (2 octets) being distributed
1458 * <p>
1459 * See Vol 3, Part H, 2.4.2.3 SM - Generation of CSRK - LE legacy pairing - generation of LTK, EDIV and Rand.
1460 * </p>
1461 */
1462 constexpr uint16_t getEDIV() const noexcept { return pdu.get_uint16_nc(number(HCIConstSizeT::EVENT_HDR_SIZE)+1+2+8); }
1463 };
1464
1465 /**
1466 * Generic HCIMetaEvent wrapper for any HCI IOCTL 'command complete' alike meta event struct having a HCIStatusCode uint8_t status field.
1467 * @tparam hcistruct the template typename, e.g. 'hci_ev_le_conn_complete' for 'struct hci_ev_le_conn_complete'
1468 */
1469 template<typename hcistruct>
1471 {
1472 private:
1473 HCIMetaEvent & orig;
1474
1475 public:
1477 : orig(orig_)
1478 { }
1479 std::string toString() const noexcept { return orig.toString(); }
1480
1481 bool isTypeAndSizeValid(const HCIMetaEventType mc) const noexcept {
1482 return orig.isMetaEvent(mc) &&
1483 orig.pdu.is_range_valid(0, number(HCIConstSizeT::EVENT_HDR_SIZE)+1+sizeof(hcistruct));
1484 }
1485 const hcistruct * getStruct() const noexcept { return (const hcistruct *)( orig.getParam() ); }
1486 HCIStatusCode getStatus() const noexcept { return static_cast<HCIStatusCode>( getStruct()->status ); }
1487
1488 // hcistruct * getWStruct() noexcept { return (hcistruct *)( orig.pdu.get_wptr_nc(number(HCIConstU8::EVENT_HDR_SIZE)+1) ); }
1489 };
1490
1492 uint8_t hci_ver;
1493 uint16_t hci_rev;
1494 uint8_t lmp_ver;
1496 uint16_t lmp_subver;
1497
1498 std::string toString() noexcept;
1499 };
1500
1501 /**@}*/
1502
1503} // namespace direct_bt
1504
1505namespace std
1506{
1507 /** \addtogroup DBTUserAPI
1508 *
1509 * @{
1510 */
1511
1512 template <>
1513 struct is_error_code_enum<direct_bt::HCIStatusCode> : true_type {};
1514
1515 /**@}*/
1516}
1517
1518#endif /* HCI_TYPES_HPP_ */
#define E_FILE_LINE
BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.2 HCI ACL Data packets.
Definition: HCITypes.hpp:969
static constexpr uint8_t get_pbflag(const uint16_t handle_and_flags) noexcept
Returns the Packet_Boundary_Flag.
Definition: HCITypes.hpp:1045
static constexpr uint8_t get_bcflag(const uint16_t handle_and_flags) noexcept
Returns the Broadcast_Flag.
Definition: HCITypes.hpp:1050
uint16_t getHandleAndFlags() const noexcept
Definition: HCITypes.hpp:1060
l2cap_frame getL2CAPFrame(const uint8_t *&l2cap_data) const noexcept
Definition: HCITypes.cpp:425
jau::nsize_t getParamSize() const noexcept
Definition: HCITypes.hpp:1061
HCIACLData(const uint8_t *buffer, const jau::nsize_t buffer_len)
Persistent memory, w/ ownership .
Definition: HCITypes.hpp:1053
std::string toString(const l2cap_frame &l2cap, const uint8_t *l2cap_data) const noexcept
Definition: HCITypes.hpp:1070
static constexpr uint16_t get_handle(const uint16_t handle_and_flags) noexcept
Returns the handle.
Definition: HCITypes.hpp:1040
const uint8_t * getParam() const noexcept
Definition: HCITypes.hpp:1062
std::string toString() const noexcept
Definition: HCITypes.hpp:1066
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
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.14 Command Complete event.
Definition: HCITypes.hpp:1255
jau::nsize_t getReturnParamSize() const noexcept
Definition: HCITypes.hpp:1285
std::string baseString() const noexcept override
Definition: HCITypes.hpp:1259
const uint8_t * getReturnParam() const
Definition: HCITypes.hpp:1286
HCIOpcode getOpcode() const noexcept
The associated command.
Definition: HCITypes.hpp:1283
uint8_t getNumCommandPackets() const noexcept
The Number of HCI Command packets which are allowed to be sent to the Controller from the Host.
Definition: HCITypes.hpp:1278
std::string nameString() const noexcept override
Definition: HCITypes.hpp:1257
HCICommandCompleteEvent(const uint8_t *buffer, const jau::nsize_t buffer_len)
Definition: HCITypes.hpp:1266
bool validate(const HCICommand &cmd) const noexcept override
Definition: HCITypes.hpp:1288
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.15 Command Status event.
Definition: HCITypes.hpp:1303
bool validate(const HCICommand &cmd) const noexcept override
Definition: HCITypes.hpp:1336
uint8_t getNumCommandPackets() const noexcept
The Number of HCI Command packets which are allowed to be sent to the Controller from the Host.
Definition: HCITypes.hpp:1329
HCICommandStatusEvent(const uint8_t *buffer, const jau::nsize_t buffer_len)
Definition: HCITypes.hpp:1315
std::string baseString() const noexcept override
Definition: HCITypes.hpp:1307
HCIOpcode getOpcode() const noexcept
The associated command.
Definition: HCITypes.hpp:1334
std::string nameString() const noexcept override
Definition: HCITypes.hpp:1305
HCIStatusCode getStatus() const noexcept
Definition: HCITypes.hpp:1321
BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.1 HCI Command packet.
Definition: HCITypes.hpp:616
static void checkOpcode(const HCIOpcode has, const HCIOpcode exp)
Definition: HCITypes.hpp:626
const uint8_t * getParam() const noexcept
Definition: HCITypes.hpp:693
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
HCICommand(const HCIOpcode opc, const jau::nsize_t param_size)
Enabling manual construction of command without given value.
Definition: HCITypes.hpp:668
jau::nsize_t getParamSize() const noexcept
Definition: HCITypes.hpp:692
std::string nameString() const noexcept override
Definition: HCITypes.hpp:634
HCIOpcode getOpcode() const noexcept
Definition: HCITypes.hpp:691
~HCICommand() noexcept override=default
std::string valueString() const noexcept override
Definition: HCITypes.hpp:639
std::string baseString() const noexcept override
Definition: HCITypes.hpp:636
HCICommand(const HCIOpcode opc, const uint8_t *param, const jau::nsize_t param_size)
Enabling manual construction of command with given value.
Definition: HCITypes.hpp:681
static void checkOpcode(const HCIOpcode has, const HCIOpcode min, const HCIOpcode max)
Definition: HCITypes.hpp:618
HCICommand(const uint8_t *buffer, const jau::nsize_t buffer_len, const jau::nsize_t exp_param_size)
Persistent memory, w/ ownership .
Definition: HCITypes.hpp:656
void trimParamSize(const jau::nsize_t param_size)
Definition: HCITypes.hpp:695
BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.6 Disconnect command.
Definition: HCITypes.hpp:721
constexpr uint16_t getHandle() const noexcept
Definition: HCITypes.hpp:745
HCIDisconnectCmd(const uint8_t *buffer, const jau::nsize_t buffer_len)
Definition: HCITypes.hpp:732
HCIStatusCode getReason() const noexcept
Definition: HCITypes.hpp:747
std::string valueString() const noexcept override
Definition: HCITypes.hpp:725
std::string nameString() const noexcept override
Definition: HCITypes.hpp:723
HCIDisconnectCmd(const uint16_t handle, HCIStatusCode reason)
Definition: HCITypes.hpp:738
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.5 Disconnection Complete event.
Definition: HCITypes.hpp:1218
std::string baseString() const noexcept override
Definition: HCITypes.hpp:1222
HCIStatusCode getReason() const noexcept
Definition: HCITypes.hpp:1238
HCIDisconnectionCompleteEvent(const uint8_t *buffer, const jau::nsize_t buffer_len)
Definition: HCITypes.hpp:1230
uint16_t getHandle() const noexcept
Definition: HCITypes.hpp:1237
HCIStatusCode getStatus() const noexcept
Definition: HCITypes.hpp:1236
std::string nameString() const noexcept override
Definition: HCITypes.hpp:1220
bool validate(const HCICommand &cmd) const noexcept override
Definition: HCITypes.hpp:1240
BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.4 HCI Event packet.
Definition: HCITypes.hpp:1088
~HCIEvent() noexcept override=default
std::string valueString() const noexcept override
Definition: HCITypes.hpp:1113
constexpr bool isEvent(HCIEventType t) const noexcept
Definition: HCITypes.hpp:1167
virtual HCIMetaEventType getMetaEventType() const noexcept
The meta subevent type.
Definition: HCITypes.hpp:1172
static void checkEventType(const HCIEventType has, const HCIEventType min, const HCIEventType max)
Definition: HCITypes.hpp:1092
bool isMetaEvent(HCIMetaEventType t) const noexcept
Definition: HCITypes.hpp:1173
static void checkEventType(const HCIEventType has, const HCIEventType exp)
Definition: HCITypes.hpp:1100
constexpr HCIEventType getEventType() const noexcept
Definition: HCITypes.hpp:1166
jau::nsize_t getBaseParamSize() const noexcept
Definition: HCITypes.hpp:1120
uint64_t getTimestamp() const noexcept
Definition: HCITypes.hpp:1164
std::string nameString() const noexcept override
Definition: HCITypes.hpp:1108
std::string baseString() const noexcept override
Definition: HCITypes.hpp:1110
virtual bool validate(const HCICommand &cmd) const noexcept
Definition: HCITypes.hpp:1178
virtual const uint8_t * getParam() const noexcept
Definition: HCITypes.hpp:1176
HCIEvent(const HCIEventType evt, const jau::nsize_t param_size=0)
Enabling manual construction of event without given value.
Definition: HCITypes.hpp:1145
virtual jau::nsize_t getParamSize() const noexcept
Definition: HCITypes.hpp:1175
HCIEvent(const uint8_t *buffer, const jau::nsize_t buffer_len, const jau::nsize_t exp_param_size)
Persistent memory, w/ ownership .
Definition: HCITypes.hpp:1133
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
HCIEvent(const HCIEventType evt, const uint8_t *param, const jau::nsize_t param_size)
Enabling manual construction of event with given value.
Definition: HCITypes.hpp:1154
HCIException(std::string type, std::string const &m, const char *file, int line) noexcept
Definition: HCITypes.hpp:62
HCIException(std::string const &m, const char *file, int line) noexcept
Definition: HCITypes.hpp:66
BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.24 LE Enable Encryption command.
Definition: HCITypes.hpp:775
constexpr jau::uint128dp_t getLTK() const noexcept
Returns the 128-bit Long Term Key (16 octets)
Definition: HCITypes.hpp:828
std::string valueString() const noexcept override
Definition: HCITypes.hpp:779
HCILEEnableEncryptionCmd(const uint16_t handle, const uint64_t rand, const uint16_t ediv, const jau::uint128dp_t ltk)
Definition: HCITypes.hpp:794
HCILEEnableEncryptionCmd(const uint8_t *buffer, const jau::nsize_t buffer_len)
Definition: HCITypes.hpp:788
constexpr uint16_t getEDIV() const noexcept
Returns the 16-bit EDIV value (2 octets) being distributed.
Definition: HCITypes.hpp:819
constexpr uint64_t getRand() const noexcept
Returns the 64-bit Rand value (8 octets) being distributed.
Definition: HCITypes.hpp:811
constexpr uint16_t getHandle() const noexcept
Definition: HCITypes.hpp:803
std::string nameString() const noexcept override
Definition: HCITypes.hpp:777
BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.25 LE Long Term Key Request Reply command.
Definition: HCITypes.hpp:850
std::string valueString() const noexcept override
Definition: HCITypes.hpp:854
HCILELTKReplyAckCmd(const uint8_t *buffer, const jau::nsize_t buffer_len)
Definition: HCITypes.hpp:860
std::string nameString() const noexcept override
Definition: HCITypes.hpp:852
HCILELTKReplyAckCmd(const uint16_t handle, const jau::uint128dp_t ltk)
Definition: HCITypes.hpp:866
constexpr uint16_t getHandle() const noexcept
Definition: HCITypes.hpp:873
constexpr jau::uint128dp_t getLTK() const noexcept
Returns the 128-bit Long Term Key (16 octets)
Definition: HCITypes.hpp:882
BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.26 LE Long Term Key Request Negative Reply command.
Definition: HCITypes.hpp:898
HCILELTKReplyRejCmd(const uint16_t handle)
Definition: HCITypes.hpp:914
constexpr uint16_t getHandle() const noexcept
Definition: HCITypes.hpp:920
HCILELTKReplyRejCmd(const uint8_t *buffer, const jau::nsize_t buffer_len)
Definition: HCITypes.hpp:908
std::string valueString() const noexcept override
Definition: HCITypes.hpp:902
std::string nameString() const noexcept override
Definition: HCITypes.hpp:900
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.65.5 LE Long Term Key Request event.
Definition: HCITypes.hpp:1427
constexpr uint64_t getRand() const noexcept
Returns the 64-bit Rand value (8 octets) being distributed.
Definition: HCITypes.hpp:1454
std::string valueString() const noexcept override
Definition: HCITypes.hpp:1431
HCILELTKReqEvent(const uint8_t *buffer, const jau::nsize_t buffer_len)
Passing through preset buffer of this type.
Definition: HCITypes.hpp:1439
constexpr uint16_t getHandle() const noexcept
Definition: HCITypes.hpp:1446
std::string nameString() const noexcept override
Definition: HCITypes.hpp:1429
constexpr uint16_t getEDIV() const noexcept
Returns the 16-bit EDIV value (2 octets) being distributed.
Definition: HCITypes.hpp:1462
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.65 LE Meta event.
Definition: HCITypes.hpp:1353
jau::nsize_t getParamSize() const noexcept override
Definition: HCITypes.hpp:1395
std::string nameString() const noexcept override
Definition: HCITypes.hpp:1355
static void checkMetaType(const HCIMetaEventType has, const HCIMetaEventType exp)
Definition: HCITypes.hpp:1357
HCIMetaEvent(const uint8_t *buffer, const jau::nsize_t buffer_len, const jau::nsize_t exp_meta_param_size)
Passing through preset buffer of this type.
Definition: HCITypes.hpp:1371
const uint8_t * getParam() const noexcept override
Definition: HCITypes.hpp:1396
HCIMetaEvent(const HCIMetaEventType mc, const uint8_t *meta_param, const jau::nsize_t meta_param_size)
Enabling manual construction of event with given value.
Definition: HCITypes.hpp:1385
HCIMetaEventType getMetaEventType() const noexcept override
The meta subevent type.
Definition: HCITypes.hpp:1393
HCIMetaEvent(const HCIMetaEventType mc, const jau::nsize_t meta_param_size)
Enabling manual construction of event without given value.
Definition: HCITypes.hpp:1378
std::string baseString() const noexcept override
Definition: HCITypes.hpp:1365
HCIOpcodeException(std::string const &m, const char *file, int line) noexcept
Definition: HCITypes.hpp:77
HCIPacketException(std::string const &m, const char *file, int line) noexcept
Definition: HCITypes.hpp:72
BT Core Spec v5.2: Vol 4, Part E HCI: 5.4 Exchange of HCI-specific information.
Definition: HCITypes.hpp:532
constexpr jau::nsize_t getTotalSize() const noexcept
Definition: HCITypes.hpp:590
virtual std::string nameString() const noexcept
Definition: HCITypes.hpp:553
HCIPacket(const HCIPacketType type, const jau::nsize_t total_packet_size)
Definition: HCITypes.hpp:560
static T * clone(const T &source) noexcept
Clone template for convenience, based on derived class's copy-constructor.
Definition: HCITypes.hpp:588
HCIPacket(const uint8_t *packet_data, const jau::nsize_t total_packet_size)
Persistent memory, w/ ownership .
Definition: HCITypes.hpp:570
virtual ~HCIPacket() noexcept=default
HCIPacketType getPacketType() noexcept
Definition: HCITypes.hpp:595
virtual std::string valueString() const noexcept
Definition: HCITypes.hpp:557
static void checkPacketType(const HCIPacketType type)
Definition: HCITypes.hpp:539
jau::POctets pdu
Definition: HCITypes.hpp:537
std::string toString() const noexcept
Definition: HCITypes.hpp:597
virtual std::string baseString() const noexcept
Definition: HCITypes.hpp:555
jau::TROOctets & getPDU() noexcept
Return the underlying octets read only.
Definition: HCITypes.hpp:593
const char * name() const noexcept override
Definition: HCITypes.hpp:241
std::string message(int condition) const override
Definition: HCITypes.hpp:242
static HCIStatusCodeCategory & get()
Definition: HCITypes.hpp:245
Generic HCIEvent wrapper for any HCI IOCTL 'command complete' alike event struct having a HCIStatusCo...
Definition: HCITypes.hpp:1187
const hcistruct * getStruct() const noexcept
Definition: HCITypes.hpp:1201
std::string toString() const noexcept
Definition: HCITypes.hpp:1195
HCIStructCmdCompleteEvtWrap(HCIEvent &orig_)
Definition: HCITypes.hpp:1192
hcistruct * getWStruct() noexcept
Definition: HCITypes.hpp:1204
bool isTypeAndSizeValid(const HCIEventType ec) const noexcept
Definition: HCITypes.hpp:1197
HCIStatusCode getStatus() const noexcept
Definition: HCITypes.hpp:1202
Generic HCIMetaEvent wrapper for any HCI IOCTL 'command complete' alike meta event struct having a HC...
Definition: HCITypes.hpp:1471
std::string toString() const noexcept
Definition: HCITypes.hpp:1479
HCIStructCmdCompleteMetaEvtWrap(HCIMetaEvent &orig_)
Definition: HCITypes.hpp:1476
bool isTypeAndSizeValid(const HCIMetaEventType mc) const noexcept
Definition: HCITypes.hpp:1481
const hcistruct * getStruct() const noexcept
Definition: HCITypes.hpp:1485
HCIStatusCode getStatus() const noexcept
Definition: HCITypes.hpp:1486
Generic HCICommand wrapper for any HCI IOCTL structure.
Definition: HCITypes.hpp:929
HCIStructCommand(const HCIOpcode opc, const hcistruct &cp)
Enabling manual construction of command with given value.
Definition: HCITypes.hpp:943
std::string nameString() const noexcept override
Definition: HCITypes.hpp:931
const hcistruct * getStruct() const noexcept
Definition: HCITypes.hpp:947
HCIStructCommand(const HCIOpcode opc)
Enabling manual construction of command with zero value.
Definition: HCITypes.hpp:935
hcistruct * getWStruct() noexcept
Definition: HCITypes.hpp:948
Persistent endian aware octet data, i.e.
Definition: octets.hpp:560
POctets & resize(const nsize_t newCapacity, const nsize_t newSize)
Resizes this instance, including its capacity.
Definition: octets.hpp:839
RuntimeException(std::string type, std::string const &m, const char *file, int line) noexcept
constexpr void put_uint64_nc(const nsize_t i, const uint64_t &v) noexcept
Definition: octets.hpp:367
constexpr void put_uint128_nc(const nsize_t i, const uint128dp_t &v) noexcept
Definition: octets.hpp:375
constexpr void put_uint16_nc(const nsize_t i, const uint16_t v) noexcept
Definition: octets.hpp:343
constexpr void put_uint8_nc(const nsize_t i, const uint8_t v) noexcept
Definition: octets.hpp:335
uint8_t * get_wptr_nc(const nsize_t i) noexcept
Definition: octets.hpp:480
Transient read only and endian aware octet data, i.e.
Definition: octets.hpp:67
constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept
Definition: octets.hpp:184
constexpr uint128dp_t get_uint128_nc(const nsize_t i) const noexcept
Definition: octets.hpp:216
constexpr nsize_t size() const noexcept
Returns the used memory size for read and write operations, may be zero.
Definition: octets.hpp:162
constexpr bool is_range_valid(const nsize_t i, const nsize_t count) const noexcept
Definition: octets.hpp:154
void check_range(const nsize_t i, const nsize_t count, const char *file, int line) const
Definition: octets.hpp:148
constexpr uint64_t get_uint64_nc(const nsize_t i) const noexcept
Definition: octets.hpp:208
constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept
Definition: octets.hpp:168
constexpr uint8_t const * get_ptr() const noexcept
Definition: octets.hpp:272
constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept
Definition: octets.hpp:277
lb_endian_t
Simplified reduced endian type only covering little- and big-endian.
Definition: byte_util.hpp:227
HCIOpcode
BT Core Spec v5.2: Vol 4, Part E HCI: 7.1 Link Controller commands.
Definition: HCITypes.hpp:404
std::string to_string(const HCIPacket &p) noexcept
Definition: HCITypes.hpp:601
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_CREATE_CONN
LE_CREATE_CONN.
@ LE_READ_PEER_RESOLV_ADDR
FIXME: May not be supported by Linux/BlueZ.
@ LE_SET_EVENT_MASK
LE_SET_EVENT_MASK.
@ SET_EVENT_MASK
SET_EVENT_MASK.
@ LE_READ_LOCAL_RESOLV_ADDR
FIXME: May not be supported by Linux/BlueZ.
@ LE_PERIODIC_ADV_SYNC_TRANSFER_RECV
LE_PERIODIC_ADV_SYNC_TRANSFER_RECV.
@ LE_CHANNEL_SEL_ALGO
LE_CHANNEL_SEL_ALGO.
@ LE_PERIODIC_ADV_SYNC_LOST
LE_PERIODIC_ADV_SYNC_LOST.
@ LE_TRANSMIT_POWER_REPORTING
LE_TRANSMIT_POWER_REPORTING.
@ LE_EXT_CONN_COMPLETE
LE_ENHANCED_CONN_COMPLETE.
@ LE_CONN_COMPLETE
LE_CONN_COMPLETE.
@ LE_PERIODIC_ADV_REPORT
LE_PERIODIC_ADV_REPORT.
@ LE_LTK_REQUEST
LE_LTK_REQUEST.
@ LE_CONN_UPDATE_COMPLETE
LE_CONN_UPDATE_COMPLETE.
@ LE_BIGINFO_ADV_REPORT
LE_BIGINFO_ADV_REPORT.
@ LE_ADVERTISING_REPORT
LE_ADVERTISING_REPORT.
@ LE_DIRECT_ADV_REPORT
LE_DIRECT_ADV_REPORT.
@ LE_CTE_REQ_FAILED
LE_CTE_REQ_FAILED.
@ LE_REQUEST_PEER_SCA_COMPLETE
LE_REQUEST_PEER_SCA_COMPLETE.
@ LE_SCAN_TIMEOUT
LE_SCAN_TIMEOUT.
@ LE_CIS_REQUEST
LE_CIS_REQUEST.
@ LE_EXT_ADV_REPORT
LE_EXT_ADV_REPORT.
@ LE_BIG_SYNC_LOST
LE_BIG_SYNC_LOST.
@ LE_REMOTE_FEAT_COMPLETE
LE_REMOTE_FEAT_COMPLETE.
@ LE_CONN_IQ_REPORT
LE_CONN_IQ_REPORT.
@ LE_PERIODIC_ADV_SYNC_ESTABLISHED
LE_PERIODIC_ADV_SYNC_ESTABLISHED.
@ LE_CONNLESS_IQ_REPORT
LE_CONNLESS_IQ_REPORT.
@ LE_BIG_SYNC_ESTABLISHED
LE_BIG_SYNC_ESTABLISHED.
@ LE_REMOTE_CONN_PARAM_REQ
LE_REMOTE_CONN_PARAM_REQ.
@ LE_READ_LOCAL_P256_PUBKEY_COMPLETE
LE_READ_LOCAL_P256_PUBKEY_COMPLETE.
@ LE_CREATE_BIG_COMPLETE
LE_CREATE_BIG_COMPLETE.
@ LE_CIS_ESTABLISHED
LE_CIS_ESTABLISHED.
@ LE_TERMINATE_BIG_COMPLETE
LE_TERMINATE_BIG_COMPLETE.
@ LE_DATA_LENGTH_CHANGE
LE_DATA_LENGTH_CHANGE.
@ LE_SCAN_REQ_RECEIVED
LE_SCAN_REQ_RECEIVED.
@ LE_PATH_LOSS_THRESHOLD
LE_PATH_LOSS_THRESHOLD.
@ LE_ADV_SET_TERMINATED
LE_ADV_SET_TERMINATED.
@ LE_PHY_UPDATE_COMPLETE
LE_PHY_UPDATE_COMPLETE.
@ LE_GENERATE_DHKEY_COMPLETE
LE_GENERATE_DHKEY_COMPLETE.
@ EVENT_HDR_SIZE
HCIPacketType::EVENT header size including HCIPacketType.
@ ACL_HDR_SIZE
HCIPacketType::ACLDATA header size including HCIPacketType.
@ PACKET_MAX_SIZE
Total packet size, guaranteed to be handled by adapter.
@ SCO_HDR_SIZE
HCIPacketType::SCODATA header size including HCIPacketType.
@ COMMAND_HDR_SIZE
HCIPacketType::COMMAND header size including HCIPacketType.
@ LE_CTL
LE controller commands.
@ LINK_POLICY
link policy commands
@ BREDR_CTL
controller baseband commands
@ LINK_CTL
link control commands
std::string to_string(const DiscoveryPolicy v) noexcept
Definition: BTAdapter.cpp:58
constexpr int32_t getHCIMaxConnLatency(const int16_t supervision_timeout_ms, const int16_t conn_interval_max_ms)
Supervisor timeout shall be in the range [0 - ((supervision_timeout_ms / (conn_interval_max_ms*2)) - ...
Definition: HCITypes.hpp:117
L2CAP_PSM
Protocol Service Multiplexers (PSM) Assigned numbers https://www.bluetooth.com/specifications/assigne...
Definition: BTTypes0.hpp:514
std::error_code make_error_code(HCIStatusCode e) noexcept
Definition: HCITypes.hpp:250
constexpr uint16_t getHCIConnSupervisorTimeout(const uint16_t conn_latency, const uint16_t conn_interval_max_ms, const uint16_t min_result_ms=number(HCIConstInt::LE_CONN_MIN_TIMEOUT_MS), const uint16_t multiplier=10) noexcept
Defining the supervising timeout for LE connections to be a multiple of the maximum connection interv...
Definition: HCITypes.hpp:102
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
@ LE_CONN_MIN_TIMEOUT_MS
le connection supervisor timeout minimum of 500ms, see getHCIConnSupervisorTimeout() and v5....
@ REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
Definition: base_math.hpp:177
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:53
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
Definition: base_math.hpp:191
std::string bytesHexString(const void *data, const nsize_t offset, const nsize_t length, const bool lsbFirst, const bool lowerCase=true) noexcept
Produce a hexadecimal string representation of the given byte values.
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
uint64_t getCurrentMilliseconds() noexcept
Returns current monotonic time in milliseconds.
Definition: basic_types.cpp:64
STL namespace.
Representing ACL Datas' L2CAP Frame.
Definition: HCITypes.hpp:977
static std::string toString(const PBFlag v) noexcept
Definition: HCITypes.cpp:394
constexpr bool isGATT() const noexcept
Definition: HCITypes.hpp:1014
PBFlag
The Packet_Boundary_Flag.
Definition: HCITypes.hpp:984
const uint8_t bc_flag
The Broadcast_Flag.
Definition: HCITypes.hpp:1001
const uint16_t handle
The connection handle.
Definition: HCITypes.hpp:998
constexpr bool isSMP() const noexcept
Definition: HCITypes.hpp:1012
std::string toString() const noexcept
Definition: HCITypes.hpp:1016
l2cap_frame(const uint16_t handle_, const PBFlag pb_flag_, const uint8_t bc_flag_, const L2CAP_CID cid_, const L2CAP_PSM psm_, const uint16_t len_)
Oly for manual injection, usually using casted pointer.
Definition: HCITypes.hpp:1007
static constexpr uint8_t number(const PBFlag v) noexcept
Definition: HCITypes.hpp:994
std::string toString(const uint8_t *l2cap_data) const noexcept
Definition: HCITypes.hpp:1021
std::string toString() noexcept
Definition: HCITypes.cpp:389
A 128-bit packed uint8_t data array.
Definition: int_types.hpp:114