41#include "HCIIoctl.hpp"
56#define CASE_TO_STRING(V) case V: return #V;
57#define CASE2_TO_STRING(U,V) case U::V: return #V;
59#define MGMT_STATUS_ENUM(X) \
69 X(ALREADY_CONNECTED) \
82#define MGMT_STATUS_CASE_TO_STRING(V) case MgmtStatus::V: return #V;
89 return "Unknown Status";
92#define MGMT_LINKKEYTYPE_ENUM(X) \
97 X(UNAUTH_COMBI_P192) \
100 X(UNAUTH_COMBI_P256) \
104#define MGMT_LINKKEYTYPE_TO_STRING(V) case MgmtLinkKeyType::V: return #V;
111 return "Unknown MgmtLinkKeyType";
114#define MGMT_LTKTYPE_ENUM(X) \
117 X(UNAUTHENTICATED_P256) \
118 X(AUTHENTICATED_P256) \
122#define MGMT_LTKTYPE_TO_STRING(V) case MgmtLTKType::V: return #V;
129 return "Unknown MgmtLTKType";
133 if( ( SMPLongTermKey::Property::AUTH & mask ) != SMPLongTermKey::Property::NONE ) {
134 return ( SMPLongTermKey::Property::SC & mask ) != SMPLongTermKey::Property::NONE ?
135 MgmtLTKType::AUTHENTICATED_P256 : MgmtLTKType::AUTHENTICATED;
137 return ( SMPLongTermKey::Property::SC & mask ) != SMPLongTermKey::Property::NONE ?
138 MgmtLTKType::UNAUTHENTICATED_P256 : MgmtLTKType::UNAUTHENTICATED;
142#define MGMT_CSRKTYPE_ENUM(X) \
143 X(UNAUTHENTICATED_LOCAL) \
144 X(UNAUTHENTICATED_REMOTE) \
145 X(AUTHENTICATED_LOCAL) \
146 X(AUTHENTICATED_REMOTE) \
149#define MGMT_CSRKTYPE_TO_STRING(V) case MgmtCSRKType::V: return #V;
156 return "Unknown MgmtCSRKType";
164#define MGMT_OPCODE_ENUM(X) \
170 X(SET_DISCOVERABLE) \
172 X(SET_FAST_CONNECTABLE) \
174 X(SET_LINK_SECURITY) \
183 X(LOAD_LONG_TERM_KEYS) \
187 X(PIN_CODE_NEG_REPLY) \
188 X(SET_IO_CAPABILITY) \
190 X(CANCEL_PAIR_DEVICE) \
192 X(USER_CONFIRM_REPLY) \
193 X(USER_CONFIRM_NEG_REPLY) \
194 X(USER_PASSKEY_REPLY) \
195 X(USER_PASSKEY_NEG_REPLY) \
196 X(READ_LOCAL_OOB_DATA) \
197 X(ADD_REMOTE_OOB_DATA) \
198 X(REMOVE_REMOTE_OOB_DATA) \
207 X(SET_STATIC_ADDRESS) \
215 X(ADD_DEVICE_WHITELIST) \
216 X(REMOVE_DEVICE_WHITELIST) \
218 X(READ_UNCONF_INDEX_LIST) \
219 X(READ_CONFIG_INFO) \
220 X(SET_EXTERNAL_CONFIG) \
221 X(SET_PUBLIC_ADDRESS) \
222 X(START_SERVICE_DISCOVERY) \
223 X(READ_LOCAL_OOB_EXT_DATA) \
224 X(READ_EXT_INDEX_LIST) \
225 X(READ_ADV_FEATURES) \
227 X(REMOVE_ADVERTISING) \
228 X(GET_ADV_SIZE_INFO) \
229 X(START_LIMITED_DISCOVERY) \
232 X(GET_PHY_CONFIGURATION) \
233 X(SET_PHY_CONFIGURATION) \
234 X(SET_BLOCKED_KEYS) \
235 X(SET_WIDEBAND_SPEECH) \
236 X(READ_SECURITY_INFO) \
237 X(READ_EXP_FEATURES_INFO) \
239 X(READ_DEF_SYSTEM_CONFIG) \
240 X(SET_DEF_SYSTEM_CONFIG) \
241 X(READ_DEF_RUNTIME_CONFIG) \
242 X(SET_DEF_RUNTIME_CONFIG) \
243 X(GET_DEVICE_FLAGS) \
244 X(SET_DEVICE_FLAGS) \
245 X(READ_ADV_MONITOR_FEATURES) \
246 X(ADD_ADV_PATTERNS_MONITOR) \
247 X(REMOVE_ADV_MONITOR)
249#define MGMT_OPCODE_CASE_TO_STRING(V) case MgmtCommand::Opcode::V: return #V;
251std::string MgmtCommand::getOpcodeString(
const Opcode op)
noexcept {
256 return "Unknown Operation";
263#define MGMT_DEFPARAMTYPE_ENUM(X) \
264 X(BREDR_PAGE_SCAN_TYPE) \
265 X(BREDR_PAGE_SCAN_INTERVAL) \
266 X(BREDR_PAGE_SCAN_WINDOW) \
267 X(BREDR_INQUIRY_TYPE) \
268 X(BREDR_INQUIRY_INTERVAL) \
269 X(BREDR_INQUIRY_WINDOW) \
270 X(BREDR_LINK_SUPERVISOR_TIMEOUT) \
271 X(BREDR_PAGE_TIMEOUT) \
272 X(BREDR_MIN_SNIFF_INTERVAL) \
273 X(BREDR_MAX_SNIFF_INTERVAL) \
274 X(LE_ADV_MIN_INTERVAL) \
275 X(LE_ADV_MAX_INTERVAL) \
276 X(LE_MULTI_ADV_ROT_INTERVAL) \
277 X(LE_SCAN_INTERVAL_AUTOCONN) \
278 X(LE_SCAN_WINDOW_AUTOCONN) \
279 X(LE_SCAN_INTERVAL_WAKESCENARIO) \
280 X(LE_SCAN_WINDOW_WAKESCENARIO) \
281 X(LE_SCAN_INTERVAL_DISCOVERY) \
282 X(LE_SCAN_WINDOW_DISCOVERY) \
283 X(LE_SCAN_INTERVAL_ADVMON) \
284 X(LE_SCAN_WINDOW_ADVMON) \
285 X(LE_SCAN_INTERVAL_CONNECT) \
286 X(LE_SCAN_WINDOW_CONNECT) \
287 X(LE_MIN_CONN_INTERVAL) \
288 X(LE_MAX_CONN_INTERVAL) \
290 X(LE_CONN_SUPERVISOR_TIMEOUT) \
291 X(LE_AUTOCONN_TIMEOUT) \
294#define MGMT_DEFPARAMTYPE_CASE_TO_STRING(V) case MgmtDefaultParam::Type::V: return #V;
296std::string MgmtDefaultParam::getTypeString(
const Type op)
noexcept {
301 return "Unknown Type";
309 if( length < 2U + 1U ) {
313 if( value_length != to_size(type) ) {
316 if( length < 2U + 1U + value_length ) {
319 switch( value_length ) {
327std::vector<MgmtDefaultParam> MgmtReadDefaultSysParamCmd::getParams(
const uint8_t *data,
const jau::nsize_t length)
noexcept {
328 std::vector<MgmtDefaultParam> res;
330 while( consumed < length && ( length - consumed ) > 2U + 1U ) {
331 MgmtDefaultParam p = MgmtDefaultParam::read(data+consumed, length-consumed);
336 res.push_back( std::move(p) );
345#define MGMT_EV_OPCODE_ENUM(X) \
349 X(CONTROLLER_ERROR) \
353 X(CLASS_OF_DEV_CHANGED) \
354 X(LOCAL_NAME_CHANGED) \
356 X(NEW_LONG_TERM_KEY) \
357 X(DEVICE_CONNECTED) \
358 X(DEVICE_DISCONNECTED) \
360 X(PIN_CODE_REQUEST) \
361 X(USER_CONFIRM_REQUEST) \
362 X(USER_PASSKEY_REQUEST) \
367 X(DEVICE_UNBLOCKED) \
372 X(DEVICE_WHITELIST_ADDED) \
373 X(DEVICE_WHITELIST_REMOVED) \
375 X(UNCONF_INDEX_ADDED) \
376 X(UNCONF_INDEX_REMOVED) \
377 X(NEW_CONFIG_OPTIONS) \
379 X(EXT_INDEX_REMOVED) \
380 X(LOCAL_OOB_DATA_UPDATED) \
381 X(ADVERTISING_ADDED) \
382 X(ADVERTISING_REMOVED) \
383 X(EXT_INFO_CHANGED) \
384 X(PHY_CONFIGURATION_CHANGED) \
385 X(EXP_FEATURE_CHANGED) \
386 X(DEVICE_FLAGS_CHANGED) \
387 X(ADV_MONITOR_ADDED) \
388 X(ADV_MONITOR_REMOVED) \
389 X(PAIR_DEVICE_COMPLETE) \
391 X(HCI_ENC_KEY_REFRESH_COMPLETE) \
392 X(HCI_LE_REMOTE_FEATURES) \
393 X(HCI_LE_PHY_UPDATE_COMPLETE) \
394 X(HCI_LE_LTK_REQUEST) \
395 X(HCI_LE_LTK_REPLY_ACK) \
396 X(HCI_LE_LTK_REPLY_REJ) \
399#define MGMT_EV_OPCODE_CASE_TO_STRING(V) case MgmtEvent::Opcode::V: return #V;
401std::string MgmtEvent::getOpcodeString(
const Opcode opc)
noexcept {
406 return "Unknown Opcode";
409std::unique_ptr<MgmtEvent> MgmtEvent::getSpecialized(
const uint8_t * buffer,
jau::nsize_t const buffer_size)
noexcept {
412 case MgmtEvent::Opcode::CMD_COMPLETE: {
415 if( buffer_size >= MgmtEvtAdapterInfo::getRequiredTotalSize() &&
416 MgmtCommand::Opcode::READ_INFO == cmdOpcode ) {
417 return std::make_unique<MgmtEvtAdapterInfo>(buffer, buffer_size);
418 }
else if( buffer_size >= MgmtEvtPairDeviceComplete::getRequiredTotalSize() &&
419 MgmtCommand::Opcode::PAIR_DEVICE == cmdOpcode ) {
420 return std::make_unique<MgmtEvtPairDeviceComplete>(buffer, buffer_size);
422 return std::make_unique<MgmtEvtCmdComplete>(buffer, buffer_size);
425 case MgmtEvent::Opcode::CMD_STATUS:
426 return std::make_unique<MgmtEvtCmdStatus>(buffer, buffer_size);
427 case MgmtEvent::Opcode::CONTROLLER_ERROR:
428 return std::make_unique<MgmtEvtControllerError>(buffer, buffer_size);
429 case MgmtEvent::Opcode::INDEX_ADDED:
430 return std::make_unique<MgmtEvent>(buffer, buffer_size, 0);
431 case MgmtEvent::Opcode::INDEX_REMOVED:
432 return std::make_unique<MgmtEvent>(buffer, buffer_size, 0);
433 case MgmtEvent::Opcode::NEW_SETTINGS:
434 return std::make_unique<MgmtEvtNewSettings>(buffer, buffer_size);
435 case MgmtEvent::Opcode::LOCAL_NAME_CHANGED:
436 return std::make_unique<MgmtEvtLocalNameChanged>(buffer, buffer_size);
437 case Opcode::NEW_LINK_KEY:
438 return std::make_unique<MgmtEvtNewLinkKey>(buffer, buffer_size);
439 case Opcode::NEW_LONG_TERM_KEY:
440 return std::make_unique<MgmtEvtNewLongTermKey>(buffer, buffer_size);
441 case MgmtEvent::Opcode::DEVICE_CONNECTED:
442 return std::make_unique<MgmtEvtDeviceConnected>(buffer, buffer_size);
443 case MgmtEvent::Opcode::DEVICE_DISCONNECTED:
444 return std::make_unique<MgmtEvtDeviceDisconnected>(buffer, buffer_size);
445 case MgmtEvent::Opcode::CONNECT_FAILED:
446 return std::make_unique<MgmtEvtDeviceConnectFailed>(buffer, buffer_size);
447 case MgmtEvent::Opcode::PIN_CODE_REQUEST:
448 return std::make_unique<MgmtEvtPinCodeRequest>(buffer, buffer_size);
449 case MgmtEvent::Opcode::USER_CONFIRM_REQUEST:
450 return std::make_unique<MgmtEvtUserConfirmRequest>(buffer, buffer_size);
451 case MgmtEvent::Opcode::USER_PASSKEY_REQUEST:
452 return std::make_unique<MgmtEvtUserPasskeyRequest>(buffer, buffer_size);
453 case MgmtEvent::Opcode::PASSKEY_NOTIFY:
454 return std::make_unique<MgmtEvtPasskeyNotify>(buffer, buffer_size);
455 case Opcode::AUTH_FAILED:
456 return std::make_unique<MgmtEvtAuthFailed>(buffer, buffer_size);
457 case MgmtEvent::Opcode::DEVICE_FOUND:
458 return std::make_unique<MgmtEvtDeviceFound>(buffer, buffer_size);
459 case MgmtEvent::Opcode::DISCOVERING:
460 return std::make_unique<MgmtEvtDiscovering>(buffer, buffer_size);
461 case MgmtEvent::Opcode::DEVICE_UNPAIRED:
462 return std::make_unique<MgmtEvtDeviceUnpaired>(buffer, buffer_size);
463 case Opcode::NEW_IRK:
464 return std::make_unique<MgmtEvtNewIdentityResolvingKey>(buffer, buffer_size);
465 case Opcode::NEW_CSRK:
466 return std::make_unique<MgmtEvtNewSignatureResolvingKey>(buffer, buffer_size);
467 case MgmtEvent::Opcode::DEVICE_WHITELIST_ADDED:
468 return std::make_unique<MgmtEvtDeviceWhitelistAdded>(buffer, buffer_size);
469 case MgmtEvent::Opcode::DEVICE_WHITELIST_REMOVED:
470 return std::make_unique<MgmtEvtDeviceWhitelistRemoved>(buffer, buffer_size);
471 case MgmtEvent::Opcode::NEW_CONN_PARAM:
472 return std::make_unique<MgmtEvtNewConnectionParam>(buffer, buffer_size);
474 return std::make_unique<MgmtEvent>(buffer, buffer_size, 0);
482bool MgmtEvtCmdComplete::getCurrentSettings(
AdapterSetting& current_settings)
const noexcept {
483 if( 4 != getDataSize() ) {
488 case MgmtCommand::Opcode::SET_POWERED:
490 case MgmtCommand::Opcode::SET_DISCOVERABLE:
492 case MgmtCommand::Opcode::SET_CONNECTABLE:
494 case MgmtCommand::Opcode::SET_FAST_CONNECTABLE:
496 case MgmtCommand::Opcode::SET_BONDABLE:
498 case MgmtCommand::Opcode::SET_LINK_SECURITY:
500 case MgmtCommand::Opcode::SET_SSP:
502 case MgmtCommand::Opcode::SET_HS:
504 case MgmtCommand::Opcode::SET_LE:
506 case MgmtCommand::Opcode::SET_ADVERTISING:
508 case MgmtCommand::Opcode::SET_BREDR:
510 case MgmtCommand::Opcode::SET_STATIC_ADDRESS:
512 case MgmtCommand::Opcode::SET_SECURE_CONN:
514 case MgmtCommand::Opcode::SET_DEBUG_KEYS:
516 case MgmtCommand::Opcode::SET_PRIVACY:
517 current_settings =
static_cast<AdapterSetting>( pdu.get_uint32_nc(getDataOffset()) );
524std::shared_ptr<ConnectionInfo> MgmtEvtCmdComplete::toConnectionInfo() const noexcept {
539 const uint8_t *data =
getData();
540 if(
nullptr == data ) {
550 return std::make_shared<ConnectionInfo>(address, addressType, rssi, tx_power, max_tx_power);
569 const uint8_t *data =
getData();
570 std::string name = std::string( (
const char*) ( data ) );
573 return std::make_shared<NameAndShortName>(name, short_name);
581 return std::make_unique<AdapterInfo>(
591 if( info.dev_id != getDevID() || info.addressAndType.address != getAddress() ) {
594 info.setSettingMasks(getSupportedSetting(), getCurrentSetting());
595 info.setDevClass(getDevClass());
596 info.setName(getName());
597 info.setShortName(getShortName());
603 case DisconnectReason::TIMEOUT:
return "TIMEOUT";
604 case DisconnectReason::LOCAL_HOST:
return "LOCAL_HOST";
605 case DisconnectReason::REMOTE:
return "REMOTE";
606 case DisconnectReason::AUTH_FAILURE:
return "AUTH_FAILURE";
608 case DisconnectReason::UNKNOWN:
612 return "Unknown DisconnectReason";
618 return DisconnectReason::TIMEOUT;
622 return DisconnectReason::REMOTE;
624 return DisconnectReason::LOCAL_HOST;
626 return DisconnectReason::AUTH_FAILURE;
631 return DisconnectReason::UNKNOWN;
642 case DisconnectReason::UNKNOWN:
#define MGMT_CSRKTYPE_TO_STRING(V)
#define MGMT_EV_OPCODE_CASE_TO_STRING(V)
#define MGMT_LTKTYPE_TO_STRING(V)
#define MGMT_LINKKEYTYPE_ENUM(X)
#define MGMT_DEFPARAMTYPE_ENUM(X)
#define MGMT_STATUS_ENUM(X)
#define MGMT_LTKTYPE_ENUM(X)
#define MGMT_LINKKEYTYPE_TO_STRING(V)
#define MGMT_OPCODE_ENUM(X)
#define MGMT_STATUS_CASE_TO_STRING(V)
#define MGMT_EV_OPCODE_ENUM(X)
#define MGMT_CSRKTYPE_ENUM(X)
#define MGMT_DEFPARAMTYPE_CASE_TO_STRING(V)
#define MGMT_OPCODE_CASE_TO_STRING(V)
Unique Bluetooth EUI48 address and BDAddressType tuple.
static jau::nsize_t minimumDataSize() noexcept
std::string toString() const noexcept override
AdapterSetting getSupportedSetting() const noexcept
bool updateAdapterInfo(AdapterInfo &info) const noexcept
AdapterSetting getCurrentSetting() const noexcept
std::unique_ptr< AdapterInfo > toAdapterInfo() const noexcept
uint32_t getDevClass() const noexcept
const EUI48 & getAddress() const noexcept
The adapter address reported is always the public address, i.e.
std::string getShortName() const noexcept
uint16_t getManufacturer() const noexcept
uint8_t getVersion() const noexcept
std::string getName() const noexcept
std::shared_ptr< NameAndShortName > toNameAndShortName() const noexcept
Convert this instance into ConnectionInfo if getCmdOpcode() == SET_LOCAL_NAME, getStatus() == SUCCESS...
MgmtStatus getStatus() const noexcept
const uint8_t * getData() const noexcept override
jau::nsize_t getDataSize() const noexcept override
MgmtCommand::Opcode getCmdOpcode() const noexcept
static std::string getDisconnectReasonString(DisconnectReason mgmtReason) noexcept
static DisconnectReason getDisconnectReason(HCIStatusCode hciReason) noexcept
BlueZ Kernel Mgmt mapping of HCI disconnect reason, which reduces some information.
HCIStatusCode getHCIReason() const noexcept
Returns either the HCI reason if given, or the translated DisconnectReason.
std::shared_ptr< NameAndShortName > toNameAndShortName() const noexcept
const std::string getName() const noexcept
const std::string getShortName() const noexcept
static jau::nsize_t namesDataSize() noexcept
uint16_t getDevID() const noexcept
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ 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 int8_t get_int8(uint8_t const *buffer) noexcept
constexpr uint8_t get_uint8(uint8_t const *buffer) noexcept
@ native
Identifier for native platform type, one of the above.
@ little
Identifier for little endian, equivalent to endian::little.
HCIStatusCode to_HCIStatusCode(const MgmtStatus mstatus) noexcept
MgmtCSRKType
Signature Resolving Key Types compatible with Mgmt's MgmtSignatureResolvingKey.
MgmtLinkKeyType
Link Key Types compatible with Mgmt's MgmtLinkKeyInfo.
MgmtLTKType
Long Term Key Types compatible with Mgmt's MgmtLongTermKey.
MgmtLTKType to_MgmtLTKType(const SMPLongTermKey::Property ltk_prop_mask) noexcept
std::string to_string(const DiscoveryPolicy v) noexcept
AdapterSetting
Adapter Setting Bits.
BDAddressType
BT Core Spec v5.2: Vol 3, Part C Generic Access Profile (GAP): 15.1.1.1 Public Bluetooth address.
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
@ BDADDR_LE_PUBLIC
Bluetooth LE public address.
@ UNKNOWN_CONNECTION_IDENTIFIER
@ CONNECTION_TERMINATED_BY_LOCAL_HOST
@ REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES
@ REMOTE_USER_TERMINATED_CONNECTION
@ REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Used in MgmtReadDefaultSysParamCmd and MgmtSetDefaultConnParamCmd.
jau::nsize_t mgmt_size() const
Mgmt size, i.e.
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...