Skip to content

Commit 5fc6741

Browse files
committed
Add data dump
1 parent b015f89 commit 5fc6741

1 file changed

Lines changed: 207 additions & 0 deletions

File tree

src/NimBLEBondMigration.h

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include <stdint.h>
88
#include <stdio.h>
99
#include <string.h>
10+
#include <stdarg.h>
11+
#include <string>
12+
#include <vector>
1013

1114
#include "esp_err.h"
1215
#include "esp_log.h"
@@ -75,6 +78,107 @@ struct MigrationStats {
7578
uint16_t skippedUnknownSize;
7679
};
7780

81+
inline void appendLine(std::string& out, const char* fmt, ...) {
82+
char buf[256];
83+
va_list args;
84+
va_start(args, fmt);
85+
const int written = vsnprintf(buf, sizeof(buf), fmt, args);
86+
va_end(args);
87+
if (written > 0) {
88+
out.append(buf, strlen(buf));
89+
}
90+
}
91+
92+
inline void appendHex(std::string& out, const uint8_t* data, size_t len) {
93+
static constexpr char hex[] = "0123456789ABCDEF";
94+
out.reserve(out.size() + (len * 2));
95+
for (size_t i = 0; i < len; ++i) {
96+
const uint8_t value = data[i];
97+
out.push_back(hex[(value >> 4) & 0x0F]);
98+
out.push_back(hex[value & 0x0F]);
99+
}
100+
}
101+
102+
inline void appendAddr(std::string& out, const ble_addr_t& addr) {
103+
appendLine(out,
104+
"%02X:%02X:%02X:%02X:%02X:%02X(type=%u)",
105+
addr.val[5],
106+
addr.val[4],
107+
addr.val[3],
108+
addr.val[2],
109+
addr.val[1],
110+
addr.val[0],
111+
addr.type);
112+
}
113+
114+
inline void appendV1Record(std::string& out, const BleStoreValueSecV1& sec) {
115+
out += " peer_addr=";
116+
appendAddr(out, sec.peer_addr);
117+
out += "\n";
118+
appendLine(out,
119+
" key_size=%u ediv=%u rand_num=%llu auth=%u sc=%u\n",
120+
sec.key_size,
121+
sec.ediv,
122+
static_cast<unsigned long long>(sec.rand_num),
123+
sec.authenticated,
124+
sec.sc);
125+
appendLine(out,
126+
" ltk_present=%u irk_present=%u csrk_present=%u\n",
127+
sec.ltk_present,
128+
sec.irk_present,
129+
sec.csrk_present);
130+
if (sec.ltk_present) {
131+
out += " ltk=";
132+
appendHex(out, sec.ltk, sizeof(sec.ltk));
133+
out += "\n";
134+
}
135+
if (sec.irk_present) {
136+
out += " irk=";
137+
appendHex(out, sec.irk, sizeof(sec.irk));
138+
out += "\n";
139+
}
140+
if (sec.csrk_present) {
141+
out += " csrk=";
142+
appendHex(out, sec.csrk, sizeof(sec.csrk));
143+
out += "\n";
144+
}
145+
}
146+
147+
inline void appendCurrentRecord(std::string& out, const BleStoreValueSecCurrent& sec) {
148+
out += " peer_addr=";
149+
appendAddr(out, sec.peer_addr);
150+
out += "\n";
151+
appendLine(out,
152+
" bond_count=%u sign_counter=%u key_size=%u ediv=%u rand_num=%llu auth=%u sc=%u\n",
153+
sec.bond_count,
154+
sec.sign_counter,
155+
sec.key_size,
156+
sec.ediv,
157+
static_cast<unsigned long long>(sec.rand_num),
158+
sec.authenticated,
159+
sec.sc);
160+
appendLine(out,
161+
" ltk_present=%u irk_present=%u csrk_present=%u\n",
162+
sec.ltk_present,
163+
sec.irk_present,
164+
sec.csrk_present);
165+
if (sec.ltk_present) {
166+
out += " ltk=";
167+
appendHex(out, sec.ltk, sizeof(sec.ltk));
168+
out += "\n";
169+
}
170+
if (sec.irk_present) {
171+
out += " irk=";
172+
appendHex(out, sec.irk, sizeof(sec.irk));
173+
out += "\n";
174+
}
175+
if (sec.csrk_present) {
176+
out += " csrk=";
177+
appendHex(out, sec.csrk, sizeof(sec.csrk));
178+
out += "\n";
179+
}
180+
}
181+
78182
inline bool makeBondKey(char* out, size_t outLen, const char* prefix, uint16_t index) {
79183
const int written = snprintf(out, outLen, "%s_%u", prefix, index);
80184
return written > 0 && static_cast<size_t>(written) < outLen;
@@ -262,6 +366,109 @@ inline esp_err_t migrateBondStore(bool toCurrent, uint16_t maxEntries) {
262366

263367
} // namespace detail
264368

369+
inline std::string dumpBondData(uint16_t maxEntries = MYNEWT_VAL(BLE_STORE_MAX_BONDS)) {
370+
std::string out;
371+
out.reserve(2048);
372+
373+
nvs_handle_t nvsHandle;
374+
esp_err_t err = nvs_open(detail::kBondNamespace, NVS_READONLY, &nvsHandle);
375+
if (err != ESP_OK) {
376+
detail::appendLine(out,
377+
"Failed to open NVS namespace '%s', err=%d\n",
378+
detail::kBondNamespace,
379+
static_cast<int>(err));
380+
return out;
381+
}
382+
383+
out += "NimBLE bond dump\n";
384+
detail::appendLine(out,
385+
"v1_size=%u current_size=%u max_entries=%u\n",
386+
static_cast<unsigned>(sizeof(detail::BleStoreValueSecV1)),
387+
static_cast<unsigned>(sizeof(detail::BleStoreValueSecCurrent)),
388+
maxEntries);
389+
390+
uint16_t foundCount = 0;
391+
char key[detail::kNvsKeyMaxLen]{};
392+
393+
for (uint16_t i = 1; i <= maxEntries; ++i) {
394+
const char* prefixes[] = {detail::kOurSecPrefix, detail::kPeerSecPrefix};
395+
const char* types[] = {"our", "peer"};
396+
397+
for (size_t j = 0; j < 2; ++j) {
398+
if (!detail::makeBondKey(key, sizeof(key), prefixes[j], i)) {
399+
out += "Key format error\n";
400+
continue;
401+
}
402+
403+
size_t blobSize = 0;
404+
err = nvs_get_blob(nvsHandle, key, nullptr, &blobSize);
405+
if (err == ESP_ERR_NVS_NOT_FOUND) {
406+
continue;
407+
}
408+
if (err != ESP_OK) {
409+
detail::appendLine(out,
410+
"[%s:%u] key=%s read-size error err=%d\n",
411+
types[j],
412+
i,
413+
key,
414+
static_cast<int>(err));
415+
continue;
416+
}
417+
418+
std::vector<uint8_t> blob(blobSize);
419+
size_t readSize = blobSize;
420+
err = nvs_get_blob(nvsHandle, key, blob.data(), &readSize);
421+
if (err != ESP_OK) {
422+
detail::appendLine(out,
423+
"[%s:%u] key=%s read error err=%d\n",
424+
types[j],
425+
i,
426+
key,
427+
static_cast<int>(err));
428+
continue;
429+
}
430+
431+
foundCount++;
432+
detail::appendLine(out,
433+
"[%s:%u] key=%s size=%u ",
434+
types[j],
435+
i,
436+
key,
437+
static_cast<unsigned>(blobSize));
438+
439+
if (blobSize == sizeof(detail::BleStoreValueSecCurrent)) {
440+
out += "format=current\n";
441+
detail::BleStoreValueSecCurrent sec{};
442+
memcpy(&sec, blob.data(), sizeof(sec));
443+
detail::appendCurrentRecord(out, sec);
444+
} else if (blobSize == sizeof(detail::BleStoreValueSecV1)) {
445+
out += "format=v1\n";
446+
detail::BleStoreValueSecV1 sec{};
447+
memcpy(&sec, blob.data(), sizeof(sec));
448+
detail::appendV1Record(out, sec);
449+
} else {
450+
out += "format=unknown\n";
451+
out += " raw=";
452+
const size_t dumpLen = blobSize > 64 ? 64 : blobSize;
453+
detail::appendHex(out, blob.data(), dumpLen);
454+
if (blobSize > dumpLen) {
455+
out += "...";
456+
}
457+
out += "\n";
458+
}
459+
}
460+
}
461+
462+
if (foundCount == 0) {
463+
out += "No bond entries found\n";
464+
} else {
465+
detail::appendLine(out, "Total entries found: %u\n", foundCount);
466+
}
467+
468+
nvs_close(nvsHandle);
469+
return out;
470+
}
471+
265472
inline esp_err_t migrateBondStoreToCurrent(uint16_t maxEntries = MYNEWT_VAL(BLE_STORE_MAX_BONDS)) {
266473
return detail::migrateBondStore(true, maxEntries);
267474
}

0 commit comments

Comments
 (0)