@@ -12,13 +12,28 @@ DataStore::DataStore(FILESYSTEM& fs) : _fs(&fs),
1212{
1313}
1414
15+ static File openWrite (FILESYSTEM* _fs, const char * filename) {
16+ #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
17+ _fs->remove (filename);
18+ return _fs->open (filename, FILE_O_WRITE);
19+ #elif defined(RP2040_PLATFORM)
20+ return _fs->open (filename, " w" );
21+ #else
22+ return _fs->open (filename, " w" , true );
23+ #endif
24+ }
25+
1526void DataStore::begin () {
1627#if defined(RP2040_PLATFORM)
1728 identity_store.begin ();
1829#endif
1930
31+ #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
32+ checkAdvBlobFile ();
33+ #else
2034 // init 'blob store' support
2135 _fs->mkdir (" /bl" );
36+ #endif
2237}
2338
2439#if defined(ESP32)
@@ -90,14 +105,7 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
90105}
91106
92107void DataStore::savePrefs (const NodePrefs& _prefs, double node_lat, double node_lon) {
93- #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
94- _fs->remove (" /new_prefs" );
95- File file = _fs->open (" /new_prefs" , FILE_O_WRITE);
96- #elif defined(RP2040_PLATFORM)
97- File file = _fs->open (" /new_prefs" , " w" );
98- #else
99- File file = _fs->open (" /new_prefs" , " w" , true );
100- #endif
108+ File file = openWrite (_fs, " /new_prefs" );
101109 if (file) {
102110 uint8_t pad[8 ];
103111 memset (pad, 0 , sizeof (pad));
@@ -163,14 +171,7 @@ void DataStore::loadContacts(DataStoreHost* host) {
163171}
164172
165173void DataStore::saveContacts (DataStoreHost* host) {
166- #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
167- _fs->remove (" /contacts3" );
168- File file = _fs->open (" /contacts3" , FILE_O_WRITE);
169- #elif defined(RP2040_PLATFORM)
170- File file = _fs->open (" /contacts3" , " w" );
171- #else
172- File file = _fs->open (" /contacts3" , " w" , true );
173- #endif
174+ File file = openWrite (_fs, " /contacts3" );
174175 if (file) {
175176 uint32_t idx = 0 ;
176177 ContactInfo c;
@@ -230,14 +231,7 @@ void DataStore::loadChannels(DataStoreHost* host) {
230231}
231232
232233void DataStore::saveChannels (DataStoreHost* host) {
233- #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
234- _fs->remove (" /channels2" );
235- File file = _fs->open (" /channels2" , FILE_O_WRITE);
236- #elif defined(RP2040_PLATFORM)
237- File file = _fs->open (" /channels2" , " w" );
238- #else
239- File file = _fs->open (" /channels2" , " w" , true );
240- #endif
234+ File file = openWrite (_fs, " /channels2" );
241235 if (file) {
242236 uint8_t channel_idx = 0 ;
243237 ChannelDetails ch;
@@ -256,7 +250,79 @@ void DataStore::saveChannels(DataStoreHost* host) {
256250 }
257251}
258252
259- int DataStore::getBlobByKey (const uint8_t key[], int key_len, uint8_t dest_buf[]) {
253+ #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
254+
255+ #define MAX_ADVERT_PKT_LEN (PUB_KEY_SIZE + 4 + SIGNATURE_SIZE + MAX_ADVERT_DATA_SIZE)
256+
257+ void DataStore::checkAdvBlobFile () {
258+ if (!_fs->exists (" /adv_blobs" )) {
259+ File file = openWrite (_fs, " /adv_blobs" );
260+ if (file) {
261+ uint8_t zeroes[1 + MAX_ADVERT_PKT_LEN];
262+ memset (zeroes, 0 , sizeof (zeroes));
263+ for (int i = 0 ; i < 24 ; i++) { // pre-allocate to fixed size
264+ file.write (zeroes, sizeof (zeroes));
265+ }
266+ file.close ();
267+ }
268+ }
269+ }
270+
271+ uint8_t DataStore::getBlobByKey (const uint8_t key[], int key_len, uint8_t dest_buf[]) {
272+ File file = _fs->open (" /adv_blobs" );
273+ uint8_t len = 0 ; // 0 = not found
274+ if (file) {
275+ uint8_t tmp[1 + MAX_ADVERT_PKT_LEN];
276+ while (file.read (tmp, sizeof (tmp)) == sizeof (tmp)) {
277+ if (memcmp (key, &tmp[1 ], PUB_KEY_SIZE) == 0 ) { // public key is first 32 bytes of advert blob
278+ len = tmp[0 ];
279+ memcpy (dest_buf, &tmp[1 ], len);
280+ break ;
281+ }
282+ }
283+ file.close ();
284+ }
285+ return len;
286+ }
287+
288+ bool DataStore::putBlobByKey (const uint8_t key[], int key_len, const uint8_t src_buf[], uint8_t len) {
289+ if (len < PUB_KEY_SIZE+4 +SIGNATURE_SIZE || len > MAX_ADVERT_PKT_LEN) return false ;
290+
291+ checkAdvBlobFile ();
292+
293+ File file = _fs->open (" /adv_blobs" , FILE_O_WRITE);
294+ if (file) {
295+ uint32_t pos = 0 , found_pos = 0 ;
296+ uint32_t min_timestamp = 0xFFFFFFFF ;
297+
298+ // search for matching key OR evict by oldest timestmap
299+ uint8_t tmp[1 + MAX_ADVERT_PKT_LEN];
300+ while (file.read (tmp, sizeof (tmp)) == sizeof (tmp)) {
301+ if (memcmp (src_buf, &tmp[1 ], PUB_KEY_SIZE) == 0 ) { // public key is first 32 bytes of advert blob
302+ found_pos = pos;
303+ break ;
304+ }
305+ uint32_t timestamp;
306+ memcpy (×tamp, &tmp[1 + PUB_KEY_SIZE], 4 );
307+ if (timestamp < min_timestamp) {
308+ min_timestamp = timestamp;
309+ found_pos = pos;
310+ }
311+
312+ pos += sizeof (tmp);
313+ }
314+
315+ file.seek (found_pos);
316+ file.write (&len, 1 );
317+ file.write (src_buf, len);
318+
319+ file.close ();
320+ return true ;
321+ }
322+ return false ; // error
323+ }
324+ #else
325+ uint8_t DataStore::getBlobByKey (const uint8_t key[], int key_len, uint8_t dest_buf[]) {
260326 char path[64 ];
261327 char fname[18 ];
262328
@@ -279,22 +345,15 @@ int DataStore::getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]
279345 return 0 ; // not found
280346}
281347
282- bool DataStore::putBlobByKey (const uint8_t key[], int key_len, const uint8_t src_buf[], int len) {
348+ bool DataStore::putBlobByKey (const uint8_t key[], int key_len, const uint8_t src_buf[], uint8_t len) {
283349 char path[64 ];
284350 char fname[18 ];
285351
286352 if (key_len > 8 ) key_len = 8 ; // just use first 8 bytes (prefix)
287353 mesh::Utils::toHex (fname, key, key_len);
288354 sprintf (path, " /bl/%s" , fname);
289355
290- #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
291- _fs->remove (path);
292- File f = _fs->open (path, FILE_O_WRITE);
293- #elif defined(RP2040_PLATFORM)
294- File f = _fs->open (path, " w" );
295- #else
296- File f = _fs->open (path, " w" , true );
297- #endif
356+ File f = openWrite (_fs, path);
298357 if (f) {
299358 int n = f.write (src_buf, len);
300359 f.close ();
@@ -304,3 +363,4 @@ bool DataStore::putBlobByKey(const uint8_t key[], int key_len, const uint8_t src
304363 }
305364 return false ; // error
306365}
366+ #endif
0 commit comments