Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
SMPKeyBin.cpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2021 Gothel Software e.K.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <cstring>
26 #include <string>
27 #include <memory>
28 #include <cstdint>
29 #include <cstdio>
30 
31 #include "SMPKeyBin.hpp"
32 
33 // #define USE_CXX17lib_FS 1
34 #if USE_CXX17lib_FS
35  #include <filesystem>
36  namespace fs = std::filesystem;
37 #endif
38 
39 using namespace direct_bt;
40 
41 static bool file_exists(const std::string& name) {
42  std::ifstream f(name.c_str());
43  return f.good();
44 }
45 
47  const BTSecurityLevel sec_lvl = device.getConnSecurityLevel();
48  const SMPPairingState pstate = device.getPairingState();
49  const PairingMode pmode = device.getPairingMode(); // Skip PairingMode::PRE_PAIRED (write again)
50 
51  SMPKeyBin smpKeyBin(device.getAddressAndType(),
52  device.getConnSecurityLevel(), device.getConnIOCapability());
53 
54  if( ( BTSecurityLevel::NONE < sec_lvl && SMPPairingState::COMPLETED == pstate && PairingMode::NEGOTIATING < pmode ) ||
55  ( BTSecurityLevel::NONE == sec_lvl && SMPPairingState::NONE == pstate && PairingMode::NONE == pmode ) )
56  {
57  const SMPKeyType keys_resp = device.getAvailableSMPKeys(true /* responder */);
58  const SMPKeyType keys_init = device.getAvailableSMPKeys(false /* responder */);
59 
60  if( ( SMPKeyType::ENC_KEY & keys_init ) != SMPKeyType::NONE ) {
61  smpKeyBin.setLTKInit( device.getLongTermKeyInfo(false /* responder */) );
62  }
63  if( ( SMPKeyType::ENC_KEY & keys_resp ) != SMPKeyType::NONE ) {
64  smpKeyBin.setLTKResp( device.getLongTermKeyInfo(true /* responder */) );
65  }
66 
67  if( ( SMPKeyType::SIGN_KEY & keys_init ) != SMPKeyType::NONE ) {
68  smpKeyBin.setCSRKInit( device.getSignatureResolvingKeyInfo(false /* responder */) );
69  }
70  if( ( SMPKeyType::SIGN_KEY & keys_resp ) != SMPKeyType::NONE ) {
71  smpKeyBin.setCSRKResp( device.getSignatureResolvingKeyInfo(true /* responder */) );
72  }
73  } else {
74  smpKeyBin.size = 0; // explicitly mark invalid
75  }
76  return smpKeyBin;
77 }
78 
79 bool SMPKeyBin::createAndWrite(const BTDevice& device, const std::string& path, const bool overwrite, const bool verbose_) {
80  SMPKeyBin smpKeyBin = SMPKeyBin::create(device);
81  if( smpKeyBin.isValid() ) {
82  smpKeyBin.setVerbose( verbose_ );
83  return smpKeyBin.write( getFilename(path, device.getAddressAndType()), overwrite );
84  } else {
85  if( verbose_ ) {
86  jau::fprintf_td(stderr, "Create SMPKeyBin: Invalid %s, %s\n", smpKeyBin.toString().c_str(), device.toString().c_str());
87  }
88  return false;
89  }
90 }
91 
92 HCIStatusCode SMPKeyBin::readAndApply(const std::string& path, BTDevice& device, const BTSecurityLevel minSecLevel, const bool verbose_) {
93  const std::string fname = getFilename(path, device.getAddressAndType());
94  SMPKeyBin smpKeyBin = read(fname, verbose_);
95  if( smpKeyBin.isValid() ) {
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",
99  to_string(smpKeyBin.sec_level).c_str(),
100  to_string(minSecLevel).c_str(),
101  smpKeyBin.toString().c_str(), fname.c_str());
102  }
103  remove_impl(fname);
105  }
106  const HCIStatusCode res = smpKeyBin.apply(device);
107  if( HCIStatusCode::SUCCESS != res ) {
108  if( smpKeyBin.verbose ) {
109  jau::fprintf_td(stderr, "SMPKeyBin::readAndApply: Apply failed %s, %s, removing file %s\n",
110  to_string(res).c_str(), device.toString().c_str(), fname.c_str());
111  }
112  remove_impl(fname);
113  }
114  return res;
115  } else {
117  }
118 }
119 
120 std::string SMPKeyBin::toString() const noexcept {
121  std::string res = "SMPKeyBin["+addrAndType.toString()+", sec "+to_string(sec_level)+
122  ", io "+to_string(io_cap)+
123  ", ";
124  if( isVersionValid() ) {
125  res += "Init[";
126  if( hasLTKInit() ) {
127  res += ltk_init.toString();
128  }
129  if( hasCSRKInit() ) {
130  if( hasLTKInit() ) {
131  res += ", ";
132  }
133  res += csrk_init.toString();
134  }
135  res += "], Resp[";
136  if( hasLTKResp() ) {
137  res += ltk_resp.toString();
138  }
139  if( hasCSRKResp() ) {
140  if( hasLTKResp() ) {
141  res += ", ";
142  }
143  res += csrk_resp.toString();
144  }
145  res += "], ";
146  }
147  res += "ver["+jau::to_hexstring(version)+", ok "+std::to_string( isVersionValid() )+
148  "], size["+std::to_string(size);
149  if( verbose ) {
150  res += ", calc "+std::to_string( calcSize() );
151  }
152  res += ", valid "+std::to_string( isSizeValid() )+
153  "], ";
154  {
155  std::time_t t0 = static_cast<std::time_t>(ts_creation_sec);
156  struct std::tm tm_0;
157  if( nullptr == ::gmtime_r( &t0, &tm_0 ) ) {
158  res += "1970-01-01 00:00:00"; // 19 + 1
159  } else {
160  char b[20];
161  strftime(b, sizeof(b), "%Y-%m-%d %H:%M:%S", &tm_0);
162  res += std::string(b);
163  }
164  }
165  res += ", valid "+std::to_string( isValid() )+"]";
166  return res;
167 }
168 
169 std::string SMPKeyBin::getFileBasename() const noexcept {
170  std::string r("bd_"+addrAndType.address.toString()+":"+std::to_string(number(addrAndType.type))+"-smpkey.bin");
171  std::replace( r.begin(), r.end(), ':', '_');
172  return r;
173 }
174 std::string SMPKeyBin::getFileBasename(const BDAddressAndType& addrAndType_) {
175  std::string r("bd_"+addrAndType_.address.toString()+":"+std::to_string(number(addrAndType_.type))+"-smpkey.bin");
176  std::replace( r.begin(), r.end(), ':', '_');
177  return r;
178 }
179 
180 bool SMPKeyBin::remove_impl(const std::string& fname) {
181 #if USE_CXX17lib_FS
182  const fs::path fname2 = fname;
183  return fs::remove(fname);
184 #else
185  return 0 == std::remove( fname.c_str() );
186 #endif
187 }
188 
189 bool SMPKeyBin::write(const std::string& fname, const bool overwrite) const noexcept {
190  if( !isValid() ) {
191  if( verbose ) {
192  jau::fprintf_td(stderr, "Write SMPKeyBin: Invalid (skipped) %s\n", toString().c_str());
193  }
194  return false;
195  }
196  if( file_exists(fname) ) {
197  if( overwrite ) {
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());
200  return false;
201  }
202  } else {
203  jau::fprintf_td(stderr, "Write SMPKeyBin: Not overwriting existing file %s, %s\n", fname.c_str(), toString().c_str());
204  return false;
205  }
206  }
207  std::ofstream file(fname, std::ios::out | std::ios::binary);
208 
209  if ( !file.good() || !file.is_open() ) {
210  if( verbose ) {
211  jau::fprintf_td(stderr, "Write SMPKeyBin: Failed: File not open %s: %s\n", fname.c_str(), toString().c_str());
212  }
213  return false;
214  }
215  uint8_t buffer[8];
216 
217  jau::put_uint16(buffer, 0, version, true /* littleEndian */);
218  file.write((char*)buffer, sizeof(version));
219 
220  jau::put_uint16(buffer, 0, size, true /* littleEndian */);
221  file.write((char*)buffer, sizeof(size));
222 
223  jau::put_uint64(buffer, 0, ts_creation_sec, true /* littleEndian */);
224  file.write((char*)buffer, sizeof(ts_creation_sec));
225 
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));
230 
231  file.write((char*)&keys_init, sizeof(keys_init));
232  file.write((char*)&keys_resp, sizeof(keys_resp));
233 
234  if( hasLTKInit() ) {
235  file.write((char*)&ltk_init, sizeof(ltk_init));
236  }
237  if( hasCSRKInit() ) {
238  file.write((char*)&csrk_init, sizeof(csrk_init));
239  }
240 
241  if( hasLTKResp() ) {
242  file.write((char*)&ltk_resp, sizeof(ltk_resp));
243  }
244  if( hasCSRKResp() ) {
245  file.write((char*)&csrk_resp, sizeof(csrk_resp));
246  }
247 
248  const bool res = file.good() && file.is_open();
249  if( verbose ) {
250  if( res ) {
251  jau::fprintf_td(stderr, "Write SMPKeyBin: Success: %s: %s\n", fname.c_str(), toString().c_str());
252  } else {
253  jau::fprintf_td(stderr, "Write SMPKeyBin: Failed: %s: %s\n", fname.c_str(), toString().c_str());
254  }
255  }
256  file.close();
257  return res;
258 }
259 
260 bool SMPKeyBin::read(const std::string& fname) {
261  std::ifstream file(fname, std::ios::binary);
262  if ( !file.is_open() ) {
263  if( verbose ) {
264  jau::fprintf_td(stderr, "Read SMPKeyBin failed: %s\n", fname.c_str());
265  }
266  size = 0; // explicitly mark invalid
267  return false;
268  }
269  bool err = false;
270  uint8_t buffer[8];
271 
272  file.read((char*)buffer, sizeof(version));
273  version = jau::get_uint16(buffer, 0, true /* littleEndian */);
274  err = file.fail();
275 
276  if( !err ) {
277  file.read((char*)buffer, sizeof(size));
278  size = jau::get_uint16(buffer, 0, true /* littleEndian */);
279  err = file.fail();
280  }
281  uint16_t remaining = size - sizeof(version) - sizeof(size);
282 
283  if( !err && 8 <= remaining ) {
284  file.read((char*)buffer, sizeof(ts_creation_sec));
285  ts_creation_sec = jau::get_uint64(buffer, 0, true /* littleEndian */);
286  remaining -= 8;
287  err = file.fail();
288  } else {
289  err = true;
290  }
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));
296 
297  file.read((char*)&keys_init, sizeof(keys_init));
298  file.read((char*)&keys_resp, sizeof(keys_resp));
299  remaining -= 11;
300  err = file.fail();
301  } else {
302  err = true;
303  }
304  addrAndType.clearHash();
305 
306  if( !err && hasLTKInit() ) {
307  if( sizeof(ltk_init) <= remaining ) {
308  file.read((char*)&ltk_init, sizeof(ltk_init));
309  remaining -= sizeof(ltk_init);
310  err = file.fail();
311  } else {
312  err = true;
313  }
314  }
315  if( !err && hasCSRKInit() ) {
316  if( sizeof(csrk_init) <= remaining ) {
317  file.read((char*)&csrk_init, sizeof(csrk_init));
318  remaining -= sizeof(csrk_init);
319  err = file.fail();
320  } else {
321  err = true;
322  }
323  }
324 
325  if( !err && hasLTKResp() ) {
326  if( sizeof(ltk_resp) <= remaining ) {
327  file.read((char*)&ltk_resp, sizeof(ltk_resp));
328  remaining -= sizeof(ltk_resp);
329  err = file.fail();
330  } else {
331  err = true;
332  }
333  }
334  if( !err && hasCSRKResp() ) {
335  if( sizeof(csrk_resp) <= remaining ) {
336  file.read((char*)&csrk_resp, sizeof(csrk_resp));
337  remaining -= sizeof(csrk_resp);
338  err = file.fail();
339  } else {
340  err = true;
341  }
342  }
343  if( !err ) {
344  err = !isValid();
345  }
346 
347  file.close();
348  if( err ) {
349  remove_impl( fname );
350  if( verbose ) {
351  jau::fprintf_td(stderr, "Read SMPKeyBin: Failed %s (removed): %s, remaining %u\n",
352  fname.c_str(), toString().c_str(), remaining);
353  }
354  size = 0; // explicitly mark invalid
355  } else {
356  if( verbose ) {
357  jau::fprintf_td(stderr, "Read SMPKeyBin: OK %s: %s, remaining %u\n",
358  fname.c_str(), toString().c_str(), remaining);
359  }
360  }
361  return err;
362 }
363 
364 HCIStatusCode SMPKeyBin::apply(BTDevice & device) const noexcept {
366 
367  // Must be a valid SMPKeyBin instance and at least one LTK key if using encryption.
368  if( !isValid() || ( BTSecurityLevel::NONE != sec_level && !hasLTKInit() && !hasLTKResp() ) ) {
370  if( verbose ) {
371  jau::fprintf_td(stderr, "Apply SMPKeyBin failed: SMPKeyBin Status: %s, %s\n",
372  to_string(res).c_str(), this->toString().c_str());
373  }
374  return res;
375  }
376  if( !device.isValid() ) {
378  if( verbose ) {
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());
381  }
382  return res;
383  }
384 
385  // Allow no encryption at all, i.e. BTSecurityLevel::NONE
386  const BTSecurityLevel applySecLevel = BTSecurityLevel::NONE == sec_level ?
388 
389  if( !device.setConnSecurity(applySecLevel, SMPIOCapability::NO_INPUT_NO_OUTPUT) ) {
391  if( verbose ) {
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());
394  }
395  return res;
396  }
397 
398  if( hasLTKInit() ) {
399  res = device.setLongTermKeyInfo( getLTKInit() );
400  if( HCIStatusCode::SUCCESS != res && verbose ) {
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());
403  }
404  }
405 
406  if( HCIStatusCode::SUCCESS == res && hasLTKResp() ) {
407  res = device.setLongTermKeyInfo( getLTKResp() );
408  if( HCIStatusCode::SUCCESS != res && verbose ) {
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());
411  }
412  }
413 
414  return res;
415 }
416 
direct_bt::SMPKeyBin::apply
HCIStatusCode apply(BTDevice &device) const noexcept
If this instance isValid() and initiator or responder LTK available, i.e.
Definition: SMPKeyBin.cpp:364
direct_bt::HCIStatusCode::ENCRYPTION_MODE_NOT_ACCEPTED
@ ENCRYPTION_MODE_NOT_ACCEPTED
direct_bt::SMPKeyBin::read
static SMPKeyBin read(const std::string &fname, const bool verbose_)
Create a new SMPKeyBin instance based upon stored file denoted by fname.
Definition: SMPKeyBin.hpp:169
direct_bt::BTDevice::getPairingMode
PairingMode getPairingMode() const noexcept
Returns the current PairingMode used by the device.
Definition: BTDevice.cpp:1373
direct_bt::SMPKeyBin::setCSRKResp
void setCSRKResp(const SMPSignatureResolvingKeyInfo &v) noexcept
Definition: SMPKeyBin.hpp:255
direct_bt::BTDevice::getPairingState
SMPPairingState getPairingState() const noexcept
Returns the current SMPPairingState.
Definition: BTDevice.cpp:1378
direct_bt::BTDevice::getSignatureResolvingKeyInfo
SMPSignatureResolvingKeyInfo getSignatureResolvingKeyInfo(const bool responder) const noexcept
Returns a copy of the Signature Resolving Key (LTK) info, valid after connection and SMP pairing has ...
Definition: BTDevice.cpp:1144
direct_bt::BTDevice::getLongTermKeyInfo
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...
Definition: BTDevice.cpp:1116
direct_bt::SMPKeyType
SMPKeyType
SMP Key Type for Distribution, indicates keys distributed in the Transport Specific Key Distribution ...
Definition: SMPTypes.hpp:385
direct_bt::EUI48::toString
std::string toString() const noexcept
Definition: BTTypes0.cpp:274
direct_bt::SMPKeyBin::setCSRKInit
void setCSRKInit(const SMPSignatureResolvingKeyInfo &v) noexcept
Definition: SMPKeyBin.hpp:240
direct_bt::SMPLongTermKeyInfo::toString
std::string toString() const noexcept
Definition: SMPTypes.hpp:522
direct_bt::PairingMode::NONE
@ NONE
No pairing mode, implying no secure connections, no encryption and no MITM protection.
direct_bt::SMPKeyBin::write
bool write(const std::string &fname, const bool overwrite) const noexcept
Definition: SMPKeyBin.cpp:189
direct_bt
Definition: ATTPDUTypes.hpp:171
direct_bt::SMPKeyBin::getFilename
static std::string getFilename(const std::string &path, const BDAddressAndType &addrAndType_)
Definition: SMPKeyBin.hpp:292
direct_bt::BDAddressAndType::toString
std::string toString() const noexcept
Definition: BTTypes0.cpp:333
direct_bt::BTDevice::getConnIOCapability
SMPIOCapability getConnIOCapability() const noexcept
Return the set SMPIOCapability value, determined when the connection is established.
Definition: BTDevice.cpp:1232
direct_bt::BTSecurityLevel::NONE
@ NONE
No encryption and no authentication.
direct_bt::SMPKeyType::SIGN_KEY
@ SIGN_KEY
Indicates that the device shall distribute CSRK using the Signing Information command.
direct_bt::BTDevice::toString
std::string toString() const noexcept override
Definition: BTDevice.hpp:303
direct_bt::BTDevice::getAddressAndType
constexpr BDAddressAndType const & getAddressAndType() const noexcept
Returns the unique device EUI48 address and BDAddressType type.
Definition: BTDevice.hpp:278
jau::to_string
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
Definition: byte_util.hpp:198
direct_bt::SMPKeyBin::setVerbose
void setVerbose(bool v) noexcept
Definition: SMPKeyBin.hpp:261
direct_bt::BTSecurityLevel
BTSecurityLevel
Bluetooth Security Level.
Definition: BTTypes0.hpp:211
direct_bt::SMPIOCapability::NO_INPUT_NO_OUTPUT
@ NO_INPUT_NO_OUTPUT
No input not output, value 3.
direct_bt::SMPKeyBin::hasLTKResp
constexpr bool hasLTKResp() const noexcept
Definition: SMPKeyBin.hpp:246
jau::put_uint64
constexpr void put_uint64(uint8_t *buffer, nsize_t const byte_offset, const uint64_t &v) noexcept
Definition: byte_util.hpp:632
direct_bt::HCIStatusCode
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
Definition: HCITypes.hpp:124
direct_bt::BTDevice::getAvailableSMPKeys
SMPKeyType getAvailableSMPKeys(const bool responder) const noexcept
Returns the available SMPKeyType mask for the responder (LL slave) or initiator (LL master).
Definition: BTDevice.cpp:1107
direct_bt::SMPKeyBin::getFileBasename
std::string getFileBasename() const noexcept
Returns the base filename, see SMPKeyBin API doc for naming scheme.
Definition: SMPKeyBin.cpp:169
direct_bt::SMPKeyBin::hasCSRKInit
constexpr bool hasCSRKInit() const noexcept
Definition: SMPKeyBin.hpp:232
direct_bt::SMPKeyType::ENC_KEY
@ ENC_KEY
LE legacy pairing: Indicates device shall distribute LTK using the Encryption Information command,...
direct_bt::SMPKeyBin::isVersionValid
constexpr bool isVersionValid() const noexcept
Definition: SMPKeyBin.hpp:218
direct_bt::BDAddressAndType::type
BDAddressType type
Definition: BTAddress.hpp:429
jau::fprintf_td
int fprintf_td(FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the environment::getElapsedMillisecond() timestamp.
Definition: debug.cpp:188
direct_bt::BDAddressAndType::clearHash
void clearHash()
Method clears the cached hash value.
Definition: BTAddress.hpp:515
file_exists
static bool file_exists(const std::string &name)
Definition: SMPKeyBin.cpp:41
direct_bt::SMPKeyBin::create
static SMPKeyBin create(const BTDevice &device)
Create a new SMPKeyBin instance based upon given BTDevice's BTSecurityLevel, SMPPairingState,...
Definition: SMPKeyBin.cpp:46
direct_bt::number
constexpr uint8_t number(const BDAddressType rhs) noexcept
Definition: BTAddress.hpp:67
direct_bt::HCIStatusCode::INVALID_PARAMS
@ INVALID_PARAMS
direct_bt::PairingMode
PairingMode
Bluetooth secure pairing mode.
Definition: BTTypes0.hpp:261
direct_bt::SMPKeyBin
Storage for SMP keys including the required connection parameter.
Definition: SMPKeyBin.hpp:62
direct_bt::PairingMode::NEGOTIATING
@ NEGOTIATING
Pairing mode in negotiating, i.e.
direct_bt::SMPKeyBin::setLTKInit
void setLTKInit(const SMPLongTermKeyInfo &v) noexcept
Definition: SMPKeyBin.hpp:235
direct_bt::SMPKeyBin::toString
std::string toString() const noexcept
Definition: SMPKeyBin.cpp:120
jau::get_uint64
constexpr uint64_t get_uint64(uint8_t const *buffer, nsize_t const byte_offset) noexcept
Definition: byte_util.hpp:640
direct_bt::SMPKeyBin::readAndApply
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...
Definition: SMPKeyBin.cpp:92
SMPKeyBin.hpp
direct_bt::to_string
std::string to_string(const BDAddressType type) noexcept
Definition: BTTypes0.cpp:129
direct_bt::SMPKeyBin::setLTKResp
void setLTKResp(const SMPLongTermKeyInfo &v) noexcept
Definition: SMPKeyBin.hpp:250
direct_bt::BDAddressAndType::address
EUI48 address
Definition: BTAddress.hpp:428
jau::to_hexstring
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
Definition: string_util.hpp:104
jau::get_uint16
constexpr uint16_t get_uint16(uint8_t const *buffer, nsize_t const byte_offset) noexcept
Definition: byte_util.hpp:586
direct_bt::SMPKeyBin::hasLTKInit
constexpr bool hasLTKInit() const noexcept
Definition: SMPKeyBin.hpp:231
direct_bt::SMPPairingState::NONE
@ NONE
No pairing in process.
jau::put_uint16
constexpr void put_uint16(uint8_t *buffer, nsize_t const byte_offset, const uint16_t v) noexcept
Definition: byte_util.hpp:561
direct_bt::HCIStatusCode::SUCCESS
@ SUCCESS
direct_bt::SMPKeyBin::hasCSRKResp
constexpr bool hasCSRKResp() const noexcept
Definition: SMPKeyBin.hpp:247
direct_bt::SMPKeyBin::createAndWrite
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,...
Definition: SMPKeyBin.cpp:79
direct_bt::HCIStatusCode::CONNECTION_ALREADY_EXISTS
@ CONNECTION_ALREADY_EXISTS
direct_bt::SMPSignatureResolvingKeyInfo::toString
std::string toString() const noexcept
Definition: SMPTypes.hpp:598
direct_bt::SMPKeyBin::isValid
constexpr bool isValid() const noexcept
Returns true if.
Definition: SMPKeyBin.hpp:272
direct_bt::SMPPairingState
SMPPairingState
SMP Pairing Process state definition.
Definition: SMPTypes.hpp:101
direct_bt::BTDevice::getConnSecurityLevel
BTSecurityLevel getConnSecurityLevel() const noexcept
Return the BTSecurityLevel, determined when the connection is established.
Definition: BTDevice.cpp:1204
direct_bt::SMPKeyBin::isSizeValid
constexpr bool isSizeValid() const noexcept
Definition: SMPKeyBin.hpp:221
direct_bt::BDAddressAndType
Unique Bluetooth EUI48 address and BDAddressType tuple.
Definition: BTAddress.hpp:417
direct_bt::BTDevice
Definition: BTDevice.hpp:57
direct_bt::BTSecurityLevel::ENC_ONLY
@ ENC_ONLY
Encryption and no authentication (no MITM).
direct_bt::SMPPairingState::COMPLETED
@ COMPLETED
Phase 3: Key & value distribution completed by responding (slave) device sending SMPIdentInfoMsg (#1)...
direct_bt::SMPKeyType::NONE
@ NONE