41static void append_bitstr(std::string& out, T mask, T bit,
const std::string& bitstr,
bool& comma) {
42 if( bit == ( mask & bit ) ) {
43 if( comma ) { out.append(
", "); }
44 out.append(bitstr); comma =
true;
47#define APPEND_BITSTR(U,V,M) append_bitstr(out, M, U::V, #V, comma);
49#define PAIRSTATE_ENUM(X) \
52 X(REQUESTED_BY_RESPONDER) \
53 X(FEATURE_EXCHANGE_STARTED) \
54 X(FEATURE_EXCHANGE_COMPLETED) \
56 X(NUMERIC_COMPARE_EXPECTED) \
62#define CASE_TO_STRING_PAIRSTATE(V) case SMPPairingState::V: return #V;
69 return "Unknown SMP PairingState";
76 snprintf(&pin[0], pin.capacity(),
"%06u", passKey%1000000u );
80#define IOCAP_ENUM(X) \
84 X(NO_INPUT_NO_OUTPUT) \
88#define CASE_TO_STRING_IOCAP(V) case SMPIOCapability::V: return #V;
95 return "Unknown SMP IOCapability";
100 case SMPOOBDataFlag::OOB_AUTH_DATA_NOT_PRESENT:
return "OOB_AUTH_DATA_NOT_PRESENT";
101 case SMPOOBDataFlag::OOB_AUTH_DATA_REMOTE_PRESENT:
return "OOB_AUTH_DATA_REMOTE_PRESENT";
104 return "Unknown SMP OOBDataFlag";
109 std::string out(
"[");
110 if(
is_set(mask, SMPAuthReqs::BONDING) ) {
111 out.append(
"Bonding");
113 out.append(
"No bonding");
115 if(
is_set(mask, SMPAuthReqs::BONDING_RFU) ) {
117 out.append(
"Bonding Reserved");
120 if(
is_set(mask, SMPAuthReqs::MITM) ) {
123 out.append(
"No MITM");
126 if(
is_set(mask, SMPAuthReqs::SECURE_CONNECTIONS) ) {
129 out.append(
"Legacy");
132 if(
is_set(mask, SMPAuthReqs::KEYPRESS) ) {
133 out.append(
"Keypresses");
135 out.append(
"No keypresses");
137 if(
is_set(mask, SMPAuthReqs::CT2_H7_FUNC_SUPPORT) ) {
139 out.append(
"CT2_H7");
141 if(
is_set(mask, SMPAuthReqs::RFU_1) ) {
145 if(
is_set(mask, SMPAuthReqs::RFU_2) ) {
164 if( SMPOOBDataFlag::OOB_AUTH_DATA_REMOTE_PRESENT == oobFlag_ini &&
165 SMPOOBDataFlag::OOB_AUTH_DATA_REMOTE_PRESENT == oobFlag_res )
167 return PairingMode::OUT_OF_BAND;
171 if(
is_set( authReqs_ini, SMPAuthReqs::MITM ) ||
172 is_set( authReqs_res, SMPAuthReqs::MITM ) )
178 return PairingMode::JUST_WORKS;
185 if( SMPOOBDataFlag::OOB_AUTH_DATA_REMOTE_PRESENT == oobFlag_ini ||
186 SMPOOBDataFlag::OOB_AUTH_DATA_REMOTE_PRESENT == oobFlag_res )
188 return PairingMode::OUT_OF_BAND;
192 if(
is_set( authReqs_ini, SMPAuthReqs::MITM ) ||
193 is_set( authReqs_res, SMPAuthReqs::MITM ) )
199 return PairingMode::JUST_WORKS;
218#define PM_JUST__WORKS PairingMode::JUST_WORKS
219#define PM_PASSKEY_INI PairingMode::PASSKEY_ENTRY_ini
220#define PM_PASSKEY_RES PairingMode::PASSKEY_ENTRY_res
221#define PM_PASSKEY_ALL PairingMode::PASSKEY_ENTRY_ini
222#define PM_NUMCOMP_INI PairingMode::NUMERIC_COMPARE_ini
223#define PM_NUMCOMP_RES PairingMode::NUMERIC_COMPARE_res
224#define PM_NUMCOMP_ANY PairingMode::NUMERIC_COMPARE_ini
247 const uint8_t ioCap_ini_int =
number(ioCap_ini);
248 const uint8_t ioCap_res_int =
number(ioCap_res);
249 if( ioCap_ini_int > 4) {
250 ABORT(
"Invalid ioCap_init %s, %d",
to_string(ioCap_ini).c_str(), ioCap_ini_int);
252 if( ioCap_res_int > 4) {
253 ABORT(
"Invalid ioCap_resp %s, %d",
to_string(ioCap_res).c_str(), ioCap_res_int);
263#define KEYDISTFMT_ENUM(X,M) \
264 X(SMPKeyType,ENC_KEY,M) \
265 X(SMPKeyType,ID_KEY,M) \
266 X(SMPKeyType,SIGN_KEY,M) \
267 X(SMPKeyType,LINK_KEY,M) \
268 X(SMPKeyType,RFU_1,M) \
269 X(SMPKeyType,RFU_2,M) \
270 X(SMPKeyType,RFU_3,M) \
271 X(SMPKeyType,RFU_4,M)
274 std::string out(
"[");
281#define LTKPROP_ENUM(X,M) \
282 X(SMPLongTermKey::Property,RESPONDER,M) \
283 X(SMPLongTermKey::Property,AUTH,M) \
284 X(SMPLongTermKey::Property,SC,M)
286std::string SMPLongTermKey::getPropertyString(
const Property mask)
noexcept {
287 std::string out(
"[");
294bool SMPLongTermKey::isResponder() const noexcept {
298#define IRKPROP_ENUM(X,M) \
299 X(SMPIdentityResolvingKey::Property,RESPONDER,M) \
300 X(SMPIdentityResolvingKey::Property,AUTH,M)
303 std::string out(
"[");
322#define CSRKPROP_ENUM(X,M) \
323 X(SMPSignatureResolvingKey::Property,RESPONDER,M) \
324 X(SMPSignatureResolvingKey::Property,AUTH,M)
327 std::string out(
"[");
338#define SMP_LINKKEYTYPE_ENUM(X) \
343 X(UNAUTH_COMBI_P192) \
346 X(UNAUTH_COMBI_P256) \
350#define SMP_LINKKEYTYPE_TO_STRING(V) case SMPLinkKey::KeyType::V: return #V;
357 return "Unknown SMPLinkKeyType";
360#define OPCODE_ENUM(X) \
363 X(PAIRING_RESPONSE) \
367 X(ENCRYPTION_INFORMATION) \
368 X(MASTER_IDENTIFICATION) \
369 X(IDENTITY_INFORMATION) \
370 X(IDENTITY_ADDRESS_INFORMATION) \
371 X(SIGNING_INFORMATION) \
372 X(SECURITY_REQUEST) \
373 X(PAIRING_PUBLIC_KEY) \
374 X(PAIRING_DHKEY_CHECK) \
375 X(PAIRING_KEYPRESS_NOTIFICATION)
377#define CASE_TO_STRING_OPCODE(V) case Opcode::V: return #V;
384 return "Unknown SMP Opcode";
389 case ReasonCode::UNDEFINED:
return "Undefined";
390 case ReasonCode::PASSKEY_ENTRY_FAILED:
return "Passkey Entry Failed";
391 case ReasonCode::OOB_NOT_AVAILABLE:
return "OOB Not Available";
392 case ReasonCode::AUTHENTICATION_REQUIREMENTS:
return "Authentication Requirements";
393 case ReasonCode::CONFIRM_VALUE_FAILED:
return "Confirm Value Failed";
394 case ReasonCode::PAIRING_NOT_SUPPORTED:
return "Pairing Not Supported";
395 case ReasonCode::ENCRYPTION_KEY_SIZE:
return "Encryption Key Size";
396 case ReasonCode::COMMON_NOT_SUPPORTED:
return "Common Not Supported";
397 case ReasonCode::UNSPECIFIED_REASON:
return "Unspecified Reason";
398 case ReasonCode::REPEATED_ATTEMPTS:
return "Repeated Attempts";
399 case ReasonCode::INVALID_PARAMTERS:
return "Invalid Paramters";
400 case ReasonCode::DHKEY_CHECK_FAILED:
return "DHKey Check Failed";
401 case ReasonCode::NUMERIC_COMPARISON_FAILED:
return "Numeric Comparison Failed";
402 case ReasonCode::BREDR_PAIRING_IN_PROGRESS:
return "BR/EDR pairing in process";
403 case ReasonCode::CROSSXPORT_KEY_DERIGEN_NOT_ALLOWED:
return "Cross-transport Key Derivation/Generation not allowed";
406 return "Reason reserved for future use";
409#define TYPECODE_ENUM(X) \
410 X(PASSKEY_ENTRY_STARTED) \
411 X(PASSKEY_DIGIT_ENTERED) \
412 X(PASSKEY_DIGIT_ERASED) \
414 X(PASSKEY_ENTRY_COMPLETED)
416#define CASE_TO_STRING_TYPECODE(V) case TypeCode::V: return #V;
423 return "Unknown TypeCode";
429 case Opcode::PAIRING_REQUEST:
return std::make_unique<SMPPairingMsg>(
true , buffer, buffer_size);
430 case Opcode::PAIRING_RESPONSE:
return std::make_unique<SMPPairingMsg>(
false , buffer, buffer_size);
431 case Opcode::PAIRING_CONFIRM:
return std::make_unique<SMPPairConfirmMsg>(buffer, buffer_size);
432 case Opcode::PAIRING_RANDOM:
return std::make_unique<SMPPairRandMsg>(buffer, buffer_size);
433 case Opcode::PAIRING_FAILED:
return std::make_unique<SMPPairFailedMsg>(buffer, buffer_size);
434 case Opcode::ENCRYPTION_INFORMATION:
return std::make_unique<SMPEncInfoMsg>(buffer, buffer_size);
435 case Opcode::MASTER_IDENTIFICATION:
return std::make_unique<SMPMasterIdentMsg>(buffer, buffer_size);
436 case Opcode::IDENTITY_INFORMATION:
return std::make_unique<SMPIdentInfoMsg>(buffer, buffer_size);
437 case Opcode::IDENTITY_ADDRESS_INFORMATION:
return std::make_unique<SMPIdentAddrInfoMsg>(buffer, buffer_size);
438 case Opcode::SIGNING_INFORMATION:
return std::make_unique<SMPSignInfoMsg>(buffer, buffer_size);
439 case Opcode::SECURITY_REQUEST:
return std::make_unique<SMPSecurityReqMsg>(buffer, buffer_size);
440 case Opcode::PAIRING_PUBLIC_KEY:
return std::make_unique<SMPPairPubKeyMsg>(buffer, buffer_size);
441 case Opcode::PAIRING_DHKEY_CHECK:
return std::make_unique<SMPPairDHKeyCheckMsg>(buffer, buffer_size);
442 case Opcode::PAIRING_KEYPRESS_NOTIFICATION:
return std::make_unique<SMPPasskeyNotification>(buffer, buffer_size);
443 default:
return std::make_unique<SMPPDUMsg>(buffer, buffer_size);
#define CSRKPROP_ENUM(X, M)
#define KEYDISTFMT_ENUM(X, M)
static void append_bitstr(std::string &out, T mask, T bit, const std::string &bitstr, bool &comma)
#define CASE_TO_STRING_TYPECODE(V)
#define SMP_LINKKEYTYPE_ENUM(X)
#define SMP_LINKKEYTYPE_TO_STRING(V)
#define CASE_TO_STRING_PAIRSTATE(V)
#define PAIRSTATE_ENUM(X)
#define PM_JUST__WORKS
Mapping SMPIOCapability from initiator and responder to PairingMode.
static const PairingMode legacy_pairing[5][5]
#define CASE_TO_STRING_OPCODE(V)
static const PairingMode seccon_pairing[5][5]
#define LTKPROP_ENUM(X, M)
#define CASE_TO_STRING_IOCAP(V)
#define APPEND_BITSTR(U, V, M)
#define IRKPROP_ENUM(X, M)
static std::string getOpcodeString(const Opcode opc) noexcept
static std::unique_ptr< const SMPPDUMsg > getSpecialized(const uint8_t *buffer, jau::nsize_t const buffer_size) noexcept
Return a newly created specialized instance pointer to base class.
Opcode
SMP Command Codes Vol 3, Part H (SM): 3.3.
static std::string getReasonCodeString(const ReasonCode reasonCode) noexcept
static std::string getTypeCodeString(const TypeCode tc) noexcept
#define ABORT(...)
Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line fu...
std::string to_string(const alphabet &v) noexcept
SMPAuthReqs
SMP Authentication Requirements Bits, denotes specific bits or whole protocol uint8_t bit-mask.
SMPPairingState
SMP Pairing Process state definition.
SMPKeyType
SMP Key Type for Distribution, indicates keys distributed in the Transport Specific Key Distribution ...
std::string toPassKeyString(const std::uint32_t passKey) noexcept
Returns given passKey ranging [0..999999] as a canonical string, e.g.
SMPOOBDataFlag
Vol 3, Part H, 2.3.3 OOB authentication data.
SMPIOCapability
Vol 3, Part H, 2.3.2 IO capabilities.
PairingMode getPairingMode(const bool use_sc, const SMPAuthReqs authReqs_ini, const SMPIOCapability ioCap_ini, const SMPOOBDataFlag oobFlag_ini, const SMPAuthReqs authReqs_res, const SMPIOCapability ioCap_res, const SMPOOBDataFlag oobFlag_res) noexcept
Returns the PairingMode derived from both devices' sets of SMPAuthReqs, SMPIOCapability and SMPOOBDat...
std::string to_string(const DiscoveryPolicy v) noexcept
PairingMode
Bluetooth secure pairing mode.
constexpr uint32_t number(const iostate rhs) noexcept
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
constexpr bool is_set(const cpu_family_t mask, const cpu_family_t bit) noexcept
bool smp_crypto_rpa_irk_matches(const jau::uint128dp_t irk, const EUI48 &rpa) noexcept
Returns true if the given IRK matches the given random private address (RPA).
@ NONE
No specific property.
Property properties
SMPIdentityResolvingKey::Property bit mask.
bool isResponder() const noexcept
static std::string getPropertyString(const Property mask) noexcept
bool matches(const EUI48 &rpa) noexcept
Returns true if this IRK matches the given random private address (RPA).
static std::string getTypeString(const KeyType type) noexcept
@ NONE
No specific property.
Property properties
SMPLongTermKey::Property bit mask.
bool isResponder() const noexcept
static std::string getPropertyString(const Property mask) noexcept
Property properties
SMPSignatureResolvingKey::Property bit mask.
@ NONE
No specific property.
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
A 128-bit packed uint8_t data array.