43 #include <sys/param.h>
45 #include <sys/types.h>
46 #include <sys/ioctl.h>
47 #include <sys/socket.h>
53#define HCI_STATUS_CODE(X) \
56 X(UNKNOWN_CONNECTION_IDENTIFIER) \
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) \
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) \
95 X(PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) \
96 X(DIFFERENT_TRANSACTION_COLLISION) \
97 X(QOS_UNACCEPTABLE_PARAMETER) \
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) \
106 X(SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST) \
107 X(HOST_BUSY_PAIRING) \
108 X(CONNECTION_REJECTED_NO_SUITABLE_CHANNEL) \
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) \
119 X(OPERATION_CANCELLED_BY_HOST) \
127 X(ALREADY_CONNECTED) \
138 X(PERMISSION_DENIED) \
139 X(INTERNAL_TIMEOUT) \
140 X(INTERNAL_FAILURE) \
143#define HCI_STATUS_CODE_CASE_TO_STRING(V) case HCIStatusCode::V: return #V;
150 return "Unknown HCIStatusCode";
162 return "Unknown HCIPacketType";
170#define HCI_OPCODE(X) \
174 X(IO_CAPABILITY_REQ_REPLY) \
175 X(IO_CAPABILITY_REQ_NEG_REPLY) \
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) \
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) \
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) \
198 X(LE_READ_REMOTE_FEATURES) \
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) \
210 X(LE_SET_DEFAULT_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)
221#define HCI_OPCODE_CASE_TO_STRING(V) case HCIOpcode::V: return #V;
228 return "Unknown HCIOpcode";
231#define HCI_EVENTTYPE(X) \
233 X(INQUIRY_COMPLETE) \
237 X(DISCONN_COMPLETE) \
241 X(CHANGE_LINK_KEY_COMPLETE) \
244 X(QOS_SETUP_COMPLETE) \
256 X(ENCRYPT_KEY_REFRESH_COMPLETE) \
257 X(IO_CAPABILITY_REQUEST) \
258 X(IO_CAPABILITY_RESPONSE) \
260 X(DISCONN_PHY_LINK_COMPLETE) \
261 X(DISCONN_LOGICAL_LINK_COMPLETE) \
262 X(AMP_Receiver_Report)
264#define HCI_EVENTTYPE_CASE_TO_STRING(V) case HCIEventType::V: return #V;
271 return "Unknown HCIEventType";
274#define HCI_METATYPE(X) \
276 X(LE_CONN_COMPLETE) \
277 X(LE_ADVERTISING_REPORT) \
278 X(LE_CONN_UPDATE_COMPLETE) \
279 X(LE_REMOTE_FEAT_COMPLETE) \
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) \
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) \
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)
311#define HCI_METATYPE_CASE_TO_STRING(V) case HCIMetaEventType::V: return #V;
318 return "Unknown HCIMetaType";
330 WARN_PRINT(
"HCIEvent::getSpecialized: length mismatch %u < COMMAND_HDR_SIZE(%u) + %u",
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);
347 return std::make_unique<HCICommand>(buffer, buffer_size, 0);
360 WARN_PRINT(
"HCIEvent::getSpecialized: length mismatch %u < EVENT_HDR_SIZE(%u) + %u",
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);
377 return std::make_unique<HCILELTKReqEvent>(buffer, buffer_size);
380 return std::make_unique<HCIMetaEvent>(buffer, buffer_size, 1);
385 return std::make_unique<HCIEvent>(buffer, buffer_size, 0);
400 default:
return "Unknown PBFlag";
412 WARN_PRINT(
"HCIACLData::getSpecialized: length mismatch %u < ACL_HDR_SIZE(%u) + %u",
417 return std::make_unique<HCIACLData>(buffer, buffer_size);
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);
431 const uint8_t bc_flag = get_bcflag(h_f);
434 l2cap_data =
nullptr;
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);
449 data +=
sizeof(*hdr);
450 size -=
sizeof(*hdr);
455 COND_PRINT(
HCIEnv::get().DEBUG_EVENT,
"l2cap DROP frame-size %d < l2cap-size %d, handle ", size, len, handle);
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);
#define HCI_STATUS_CODE_CASE_TO_STRING(V)
#define HCI_STATUS_CODE(X)
#define HCI_EVENTTYPE_CASE_TO_STRING(V)
#define HCI_OPCODE_CASE_TO_STRING(V)
#define HCI_METATYPE_CASE_TO_STRING(V)
l2cap_frame getL2CAPFrame(const uint8_t *&l2cap_data) const noexcept
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.
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.
static HCIEnv & get() noexcept
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.
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] '.
#define WARN_PRINT(...)
Use for unconditional warning messages, prefix '[elapsed_time] Warning @ FILE:LINE FUNC: '.
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...
constexpr uint16_t le_to_cpu(uint16_t const l) noexcept
constexpr uint8_t get_uint8(uint8_t const *buffer) noexcept
@ little
Identifier for little endian, equivalent to endian::little.
std::string to_string(const alphabet &v) noexcept
HCIOpcode
BT Core Spec v5.2: Vol 4, Part E HCI: 7.1 Link Controller commands.
HCIEventType
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7 Events.
HCIMetaEventType
BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.65 LE Meta event.
@ 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
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
constexpr uint8_t number(const DiscoveryPolicy rhs) noexcept
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
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.
PBFlag
The Packet_Boundary_Flag.
@ 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
std::string toString() noexcept