Direct-BT
2.3.1
Direct-BT - Direct Bluetooth Programming.
|
Go to the documentation of this file.
36 namespace fs = std::filesystem;
42 std::ifstream f(name.c_str());
96 if( smpKeyBin.sec_level < minSecLevel ) {
97 if( smpKeyBin.verbose ) {
98 jau::fprintf_td(stderr,
"SMPKeyBin::readAndApply: sec_level %s < minimum %s: Key ignored %s, removing file %s\n",
101 smpKeyBin.
toString().c_str(), fname.c_str());
108 if( smpKeyBin.verbose ) {
109 jau::fprintf_td(stderr,
"SMPKeyBin::readAndApply: Apply failed %s, %s, removing file %s\n",
121 std::string res =
"SMPKeyBin["+addrAndType.
toString()+
", sec "+
to_string(sec_level)+
155 std::time_t t0 =
static_cast<std::time_t
>(ts_creation_sec);
157 if(
nullptr == ::gmtime_r( &t0, &tm_0 ) ) {
158 res +=
"1970-01-01 00:00:00";
161 strftime(b,
sizeof(b),
"%Y-%m-%d %H:%M:%S", &tm_0);
162 res += std::string(b);
171 std::replace( r.begin(), r.end(),
':',
'_');
176 std::replace( r.begin(), r.end(),
':',
'_');
180 bool SMPKeyBin::remove_impl(
const std::string& fname) {
182 const fs::path fname2 = fname;
183 return fs::remove(fname);
185 return 0 == std::remove( fname.c_str() );
192 jau::fprintf_td(stderr,
"Write SMPKeyBin: Invalid (skipped) %s\n", toString().c_str());
198 if( !remove_impl(fname) ) {
199 jau::fprintf_td(stderr,
"Write SMPKeyBin: Failed deletion of existing file %s, %s\n", fname.c_str(), toString().c_str());
203 jau::fprintf_td(stderr,
"Write SMPKeyBin: Not overwriting existing file %s, %s\n", fname.c_str(), toString().c_str());
207 std::ofstream file(fname, std::ios::out | std::ios::binary);
209 if ( !file.good() || !file.is_open() ) {
211 jau::fprintf_td(stderr,
"Write SMPKeyBin: Failed: File not open %s: %s\n", fname.c_str(), toString().c_str());
218 file.write((
char*)buffer,
sizeof(version));
221 file.write((
char*)buffer,
sizeof(size));
224 file.write((
char*)buffer,
sizeof(ts_creation_sec));
226 file.write((
char*)&addrAndType.address,
sizeof(addrAndType.address));
227 file.write((
char*)&addrAndType.type,
sizeof(addrAndType.type));
228 file.write((
char*)&sec_level,
sizeof(sec_level));
229 file.write((
char*)&io_cap,
sizeof(io_cap));
231 file.write((
char*)&keys_init,
sizeof(keys_init));
232 file.write((
char*)&keys_resp,
sizeof(keys_resp));
235 file.write((
char*)<k_init,
sizeof(ltk_init));
237 if( hasCSRKInit() ) {
238 file.write((
char*)&csrk_init,
sizeof(csrk_init));
242 file.write((
char*)<k_resp,
sizeof(ltk_resp));
244 if( hasCSRKResp() ) {
245 file.write((
char*)&csrk_resp,
sizeof(csrk_resp));
248 const bool res = file.good() && file.is_open();
251 jau::fprintf_td(stderr,
"Write SMPKeyBin: Success: %s: %s\n", fname.c_str(), toString().c_str());
253 jau::fprintf_td(stderr,
"Write SMPKeyBin: Failed: %s: %s\n", fname.c_str(), toString().c_str());
261 std::ifstream file(fname, std::ios::binary);
262 if ( !file.is_open() ) {
272 file.read((
char*)buffer,
sizeof(version));
277 file.read((
char*)buffer,
sizeof(size));
281 uint16_t remaining = size -
sizeof(version) -
sizeof(size);
283 if( !err && 8 <= remaining ) {
284 file.read((
char*)buffer,
sizeof(ts_creation_sec));
291 if( !err && 11 <= remaining ) {
292 file.read((
char*)&addrAndType.
address,
sizeof(addrAndType.
address));
293 file.read((
char*)&addrAndType.
type,
sizeof(addrAndType.
type));
294 file.read((
char*)&sec_level,
sizeof(sec_level));
295 file.read((
char*)&io_cap,
sizeof(io_cap));
297 file.read((
char*)&keys_init,
sizeof(keys_init));
298 file.read((
char*)&keys_resp,
sizeof(keys_resp));
307 if(
sizeof(ltk_init) <= remaining ) {
308 file.read((
char*)<k_init,
sizeof(ltk_init));
309 remaining -=
sizeof(ltk_init);
316 if(
sizeof(csrk_init) <= remaining ) {
317 file.read((
char*)&csrk_init,
sizeof(csrk_init));
318 remaining -=
sizeof(csrk_init);
326 if(
sizeof(ltk_resp) <= remaining ) {
327 file.read((
char*)<k_resp,
sizeof(ltk_resp));
328 remaining -=
sizeof(ltk_resp);
335 if(
sizeof(csrk_resp) <= remaining ) {
336 file.read((
char*)&csrk_resp,
sizeof(csrk_resp));
337 remaining -=
sizeof(csrk_resp);
349 remove_impl( fname );
351 jau::fprintf_td(stderr,
"Read SMPKeyBin: Failed %s (removed): %s, remaining %u\n",
352 fname.c_str(),
toString().c_str(), remaining);
358 fname.c_str(),
toString().c_str(), remaining);
371 jau::fprintf_td(stderr,
"Apply SMPKeyBin failed: SMPKeyBin Status: %s, %s\n",
372 to_string(res).c_str(), this->toString().c_str());
376 if( !device.isValid() ) {
379 jau::fprintf_td(stderr,
"Apply SMPKeyBin failed: Device Invalid: %s, %s, %s\n",
380 to_string(res).c_str(), this->toString().c_str(), device.toString().c_str());
392 jau::fprintf_td(stderr,
"Apply SMPKeyBin failed: Device Connected/ing: %s, %s, %s\n",
393 to_string(res).c_str(), this->toString().c_str(), device.toString().c_str());
399 res = device.setLongTermKeyInfo( getLTKInit() );
401 jau::fprintf_td(stderr,
"Apply SMPKeyBin failed: Init-LTK Upload: %s, %s, %s\n",
402 to_string(res).c_str(), this->toString().c_str(), device.toString().c_str());
407 res = device.setLongTermKeyInfo( getLTKResp() );
409 jau::fprintf_td(stderr,
"Apply SMPKeyBin failed: Resp-LTK Upload: %s, %s, %s\n",
410 to_string(res).c_str(), this->toString().c_str(), device.toString().c_str());
HCIStatusCode apply(BTDevice &device) const noexcept
If this instance isValid() and initiator or responder LTK available, i.e.
@ ENCRYPTION_MODE_NOT_ACCEPTED
static SMPKeyBin read(const std::string &fname, const bool verbose_)
Create a new SMPKeyBin instance based upon stored file denoted by fname.
PairingMode getPairingMode() const noexcept
Returns the current PairingMode used by the device.
void setCSRKResp(const SMPSignatureResolvingKeyInfo &v) noexcept
SMPPairingState getPairingState() const noexcept
Returns the current SMPPairingState.
SMPSignatureResolvingKeyInfo getSignatureResolvingKeyInfo(const bool responder) const noexcept
Returns a copy of the Signature Resolving Key (LTK) info, valid after connection and SMP pairing has ...
SMPLongTermKeyInfo getLongTermKeyInfo(const bool responder) const noexcept
Returns a copy of the Long Term Key (LTK) info, valid after connection and SMP pairing has been compl...
SMPKeyType
SMP Key Type for Distribution, indicates keys distributed in the Transport Specific Key Distribution ...
std::string toString() const noexcept
void setCSRKInit(const SMPSignatureResolvingKeyInfo &v) noexcept
std::string toString() const noexcept
@ NONE
No pairing mode, implying no secure connections, no encryption and no MITM protection.
bool write(const std::string &fname, const bool overwrite) const noexcept
static std::string getFilename(const std::string &path, const BDAddressAndType &addrAndType_)
std::string toString() const noexcept
SMPIOCapability getConnIOCapability() const noexcept
Return the set SMPIOCapability value, determined when the connection is established.
@ NONE
No encryption and no authentication.
@ SIGN_KEY
Indicates that the device shall distribute CSRK using the Signing Information command.
std::string toString() const noexcept override
constexpr BDAddressAndType const & getAddressAndType() const noexcept
Returns the unique device EUI48 address and BDAddressType type.
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
void setVerbose(bool v) noexcept
BTSecurityLevel
Bluetooth Security Level.
@ NO_INPUT_NO_OUTPUT
No input not output, value 3.
constexpr bool hasLTKResp() const noexcept
constexpr void put_uint64(uint8_t *buffer, nsize_t const byte_offset, const uint64_t &v) noexcept
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
SMPKeyType getAvailableSMPKeys(const bool responder) const noexcept
Returns the available SMPKeyType mask for the responder (LL slave) or initiator (LL master).
std::string getFileBasename() const noexcept
Returns the base filename, see SMPKeyBin API doc for naming scheme.
constexpr bool hasCSRKInit() const noexcept
@ ENC_KEY
LE legacy pairing: Indicates device shall distribute LTK using the Encryption Information command,...
constexpr bool isVersionValid() const noexcept
int fprintf_td(FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the environment::getElapsedMillisecond() timestamp.
void clearHash()
Method clears the cached hash value.
static bool file_exists(const std::string &name)
static SMPKeyBin create(const BTDevice &device)
Create a new SMPKeyBin instance based upon given BTDevice's BTSecurityLevel, SMPPairingState,...
constexpr uint8_t number(const BDAddressType rhs) noexcept
PairingMode
Bluetooth secure pairing mode.
Storage for SMP keys including the required connection parameter.
@ NEGOTIATING
Pairing mode in negotiating, i.e.
void setLTKInit(const SMPLongTermKeyInfo &v) noexcept
std::string toString() const noexcept
constexpr uint64_t get_uint64(uint8_t const *buffer, nsize_t const byte_offset) noexcept
static HCIStatusCode readAndApply(const std::string &path, BTDevice &device, const BTSecurityLevel minSecLevel, const bool verbose_)
Create a new SMPKeyBin instance on the fly based upon stored file denoted by path and BTDevice::getAd...
std::string to_string(const BDAddressType type) noexcept
void setLTKResp(const SMPLongTermKeyInfo &v) noexcept
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
constexpr uint16_t get_uint16(uint8_t const *buffer, nsize_t const byte_offset) noexcept
constexpr bool hasLTKInit() const noexcept
@ NONE
No pairing in process.
constexpr void put_uint16(uint8_t *buffer, nsize_t const byte_offset, const uint16_t v) noexcept
constexpr bool hasCSRKResp() const noexcept
static bool createAndWrite(const BTDevice &device, const std::string &path, const bool overwrite, const bool verbose_)
Create a new SMPKeyBin instance on the fly based upon given BTDevice's BTSecurityLevel,...
@ CONNECTION_ALREADY_EXISTS
std::string toString() const noexcept
constexpr bool isValid() const noexcept
Returns true if.
SMPPairingState
SMP Pairing Process state definition.
BTSecurityLevel getConnSecurityLevel() const noexcept
Return the BTSecurityLevel, determined when the connection is established.
constexpr bool isSizeValid() const noexcept
Unique Bluetooth EUI48 address and BDAddressType tuple.
@ ENC_ONLY
Encryption and no authentication (no MITM).
@ COMPLETED
Phase 3: Key & value distribution completed by responding (slave) device sending SMPIdentInfoMsg (#1)...