11#include < Arduino.h>
22#include " DataStore.h"
33
4- DataStore::DataStore (FILESYSTEM& fs, mesh::RTCClock& clock) : _fs(&fs), _clock(&clock),
4+ #if defined(EXTRAFS) || defined(QSPIFLASH)
5+ #define MAX_BLOBRECS 100
6+ #else
7+ #define MAX_BLOBRECS 20
8+ #endif
9+
10+ DataStore::DataStore (FILESYSTEM& fs, mesh::RTCClock& clock) : _fs(&fs), _fsExtra(nullptr ), _clock(&clock),
11+ #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
12+ identity_store (fs, " " )
13+ #elif defined(RP2040_PLATFORM)
14+ identity_store (fs, " /identity" )
15+ #else
16+ identity_store (fs, " /identity" )
17+ #endif
18+ {
19+ }
20+
21+ #if defined(EXTRAFS) || defined(QSPIFLASH)
22+ DataStore::DataStore (FILESYSTEM& fs, FILESYSTEM& fsExtra, mesh::RTCClock& clock) : _fs(&fs), _fsExtra(&fsExtra), _clock(&clock),
523#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
624 identity_store (fs, " " )
725#elif defined(RP2040_PLATFORM)
@@ -11,15 +29,16 @@ DataStore::DataStore(FILESYSTEM& fs, mesh::RTCClock& clock) : _fs(&fs), _clock(&
1129#endif
1230{
1331}
32+ #endif
1433
15- static File openWrite (FILESYSTEM* _fs , const char * filename) {
34+ static File openWrite (FILESYSTEM* fs , const char * filename) {
1635#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
17- _fs ->remove (filename);
18- return _fs ->open (filename, FILE_O_WRITE);
36+ fs ->remove (filename);
37+ return fs ->open (filename, FILE_O_WRITE);
1938#elif defined(RP2040_PLATFORM)
20- return _fs ->open (filename, " w" );
39+ return fs ->open (filename, " w" );
2140#else
22- return _fs ->open (filename, " w" , true );
41+ return fs ->open (filename, " w" , true );
2342#endif
2443}
2544
@@ -30,6 +49,9 @@ void DataStore::begin() {
3049
3150#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
3251 checkAdvBlobFile ();
52+ #if defined(EXTRAFS) || defined(QSPIFLASH)
53+ migrateToSecondaryFS ();
54+ #endif
3355#else
3456 // init 'blob store' support
3557 _fs->mkdir (" /bl" );
@@ -41,7 +63,13 @@ void DataStore::begin() {
4163#elif defined(RP2040_PLATFORM)
4264 #include < LittleFS.h>
4365#elif defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
44- #include < InternalFileSystem.h>
66+ #if defined(QSPIFLASH)
67+ #include < CustomLFS_QSPIFlash.h>
68+ #elif defined(EXTRAFS)
69+ #include < CustomLFS.h>
70+ #else
71+ #include < InternalFileSystem.h>
72+ #endif
4573#endif
4674
4775#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
@@ -51,9 +79,9 @@ int _countLfsBlock(void *p, lfs_block_t block){
5179 return 0 ;
5280}
5381
54- lfs_ssize_t _getLfsUsedBlockCount () {
82+ lfs_ssize_t _getLfsUsedBlockCount (FILESYSTEM* fs ) {
5583 lfs_size_t size = 0 ;
56- lfs_traverse (InternalFS. _getFS (), _countLfsBlock, &size);
84+ lfs_traverse (fs-> _getFS (), _countLfsBlock, &size);
5785 return size;
5886}
5987#endif
@@ -67,8 +95,8 @@ uint32_t DataStore::getStorageUsedKb() const {
6795 _fs->info (info);
6896 return info.usedBytes / 1024 ;
6997#elif defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
70- const lfs_config* config = InternalFS. _getFS ()->cfg ;
71- int usedBlockCount = _getLfsUsedBlockCount ();
98+ const lfs_config* config = _getContactsChannelsFS ()-> _getFS ()->cfg ;
99+ int usedBlockCount = _getLfsUsedBlockCount (_getContactsChannelsFS () );
72100 int usedBytes = config->block_size * usedBlockCount;
73101 return usedBytes / 1024 ;
74102#else
@@ -85,7 +113,7 @@ uint32_t DataStore::getStorageTotalKb() const {
85113 _fs->info (info);
86114 return info.totalBytes / 1024 ;
87115#elif defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
88- const lfs_config* config = InternalFS. _getFS ()->cfg ;
116+ const lfs_config* config = _getContactsChannelsFS ()-> _getFS ()->cfg ;
89117 int totalBytes = config->block_size * config->block_count ;
90118 return totalBytes / 1024 ;
91119#else
@@ -103,13 +131,31 @@ File DataStore::openRead(const char* filename) {
103131#endif
104132}
105133
134+ File DataStore::openRead (FILESYSTEM* fs, const char * filename) {
135+ #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
136+ return fs->open (filename, FILE_O_READ);
137+ #elif defined(RP2040_PLATFORM)
138+ return fs->open (filename, " r" );
139+ #else
140+ return fs->open (filename, " r" , false );
141+ #endif
142+ }
143+
106144bool DataStore::removeFile (const char * filename) {
107145 return _fs->remove (filename);
108146}
109147
148+ bool DataStore::removeFile (FILESYSTEM* fs, const char * filename) {
149+ return fs->remove (filename);
150+ }
151+
110152bool DataStore::formatFileSystem () {
111153#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
112- return _fs->format ();
154+ if (_fsExtra == nullptr ) {
155+ return _fs->format ();
156+ } else {
157+ return _fs->format () && _fsExtra->format ();
158+ }
113159#elif defined(RP2040_PLATFORM)
114160 return LittleFS.format ();
115161#elif defined(ESP32)
@@ -203,11 +249,15 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
203249}
204250
205251void DataStore::loadContacts (DataStoreHost* host) {
206- if (_fs->exists (" /contacts3" )) {
207- #if defined(RP2040_PLATFORM)
252+ #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
253+ if (_getContactsChannelsFS ()->exists (" /contacts3" )) {
254+ File file = _getContactsChannelsFS ()->open (" /contacts3" );
255+ #elif defined(RP2040_PLATFORM)
256+ if (_fs->exists (" /contacts3" )) {
208257 File file = _fs->open (" /contacts3" , " r" );
209258#else
210- File file = _fs->open (" /contacts3" );
259+ if (_fs->exists (" /contacts3" )) {
260+ File file = _fs->open (" /contacts3" , " r" , false );
211261#endif
212262 if (file) {
213263 bool full = false ;
@@ -240,7 +290,7 @@ void DataStore::loadContacts(DataStoreHost* host) {
240290}
241291
242292void DataStore::saveContacts (DataStoreHost* host) {
243- File file = openWrite (_fs , " /contacts3" );
293+ File file = openWrite (_getContactsChannelsFS () , " /contacts3" );
244294 if (file) {
245295 uint32_t idx = 0 ;
246296 ContactInfo c;
@@ -269,11 +319,15 @@ void DataStore::saveContacts(DataStoreHost* host) {
269319}
270320
271321void DataStore::loadChannels (DataStoreHost* host) {
322+ #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
323+ if (_getContactsChannelsFS ()->exists (" /channels2" )) {
324+ File file = _getContactsChannelsFS ()->open (" /channels2" );
325+ #elif defined(RP2040_PLATFORM)
272326 if (_fs->exists (" /channels2" )) {
273- #if defined(RP2040_PLATFORM)
274327 File file = _fs->open (" /channels2" , " r" );
275328#else
276- File file = _fs->open (" /channels2" );
329+ if (_fs->exists (" /channels2" )) {
330+ File file = _fs->open (" /channels2" , " r" , false );
277331#endif
278332 if (file) {
279333 bool full = false ;
@@ -300,7 +354,7 @@ void DataStore::loadChannels(DataStoreHost* host) {
300354}
301355
302356void DataStore::saveChannels (DataStoreHost* host) {
303- File file = openWrite (_fs , " /channels2" );
357+ File file = openWrite (_getContactsChannelsFS () , " /channels2" );
304358 if (file) {
305359 uint8_t channel_idx = 0 ;
306360 ChannelDetails ch;
@@ -331,23 +385,130 @@ struct BlobRec {
331385};
332386
333387void DataStore::checkAdvBlobFile () {
334- if (!_fs ->exists (" /adv_blobs" )) {
335- File file = openWrite (_fs , " /adv_blobs" );
388+ if (!_getContactsChannelsFS () ->exists (" /adv_blobs" )) {
389+ File file = openWrite (_getContactsChannelsFS () , " /adv_blobs" );
336390 if (file) {
337391 BlobRec zeroes;
338392 memset (&zeroes, 0 , sizeof (zeroes));
339- for (int i = 0 ; i < 20 ; i++) { // pre-allocate to fixed size
393+ for (int i = 0 ; i < MAX_BLOBRECS ; i++) { // pre-allocate to fixed size
340394 file.write ((uint8_t *) &zeroes, sizeof (zeroes));
341395 }
342396 file.close ();
343397 }
344398 }
345399}
346400
401+ void DataStore::migrateToSecondaryFS () {
402+ // migrate old adv_blobs, contacts3 and channels2 files to secondary FS if they don't already exist
403+ if (!_fsExtra->exists (" /adv_blobs" )) {
404+ if (_fs->exists (" /adv_blobs" )) {
405+ File oldAdvBlobs = openRead (_fs, " /adv_blobs" );
406+ File newAdvBlobs = openWrite (_fsExtra, " /adv_blobs" );
407+
408+ if (oldAdvBlobs && newAdvBlobs) {
409+ BlobRec rec;
410+ size_t count = 0 ;
411+
412+ // Copy 20 BlobRecs from old to new
413+ while (count < 20 && oldAdvBlobs.read ((uint8_t *)&rec, sizeof (rec)) == sizeof (rec)) {
414+ newAdvBlobs.seek (count * sizeof (BlobRec));
415+ newAdvBlobs.write ((uint8_t *)&rec, sizeof (rec));
416+ count++;
417+ }
418+ }
419+ if (oldAdvBlobs) oldAdvBlobs.close ();
420+ if (newAdvBlobs) newAdvBlobs.close ();
421+ _fs->remove (" /adv_blobs" );
422+ }
423+ }
424+ if (!_fsExtra->exists (" /contacts3" )) {
425+ if (_fs->exists (" /contacts3" )) {
426+ File oldFile = openRead (_fs, " /contacts3" );
427+ File newFile = openWrite (_fsExtra, " /contacts3" );
428+
429+ if (oldFile && newFile) {
430+ uint8_t buf[64 ];
431+ int n;
432+ while ((n = oldFile.read (buf, sizeof (buf))) > 0 ) {
433+ newFile.write (buf, n);
434+ }
435+ }
436+ if (oldFile) oldFile.close ();
437+ if (newFile) newFile.close ();
438+ _fs->remove (" /contacts3" );
439+ }
440+ }
441+ if (!_fsExtra->exists (" /channels2" )) {
442+ if (_fs->exists (" /channels2" )) {
443+ File oldFile = openRead (_fs, " /channels2" );
444+ File newFile = openWrite (_fsExtra, " /channels2" );
445+
446+ if (oldFile && newFile) {
447+ uint8_t buf[64 ];
448+ int n;
449+ while ((n = oldFile.read (buf, sizeof (buf))) > 0 ) {
450+ newFile.write (buf, n);
451+ }
452+ }
453+ if (oldFile) oldFile.close ();
454+ if (newFile) newFile.close ();
455+ _fs->remove (" /channels2" );
456+ }
457+ }
458+ // cleanup nodes which have been testing the extra fs, copy _main.id and new_prefs back to primary
459+ if (_fsExtra->exists (" /_main.id" )) {
460+ if (_fs->exists (" /_main.id" )) {_fs->remove (" /_main.id" );}
461+ File oldFile = openRead (_fsExtra, " /_main.id" );
462+ File newFile = openWrite (_fs, " /_main.id" );
463+
464+ if (oldFile && newFile) {
465+ uint8_t buf[64 ];
466+ int n;
467+ while ((n = oldFile.read (buf, sizeof (buf))) > 0 ) {
468+ newFile.write (buf, n);
469+ }
470+ }
471+ if (oldFile) oldFile.close ();
472+ if (newFile) newFile.close ();
473+ _fsExtra->remove (" /_main.id" );
474+ }
475+ if (_fsExtra->exists (" /new_prefs" )) {
476+ if (_fs->exists (" /new_prefs" )) {_fs->remove (" /new_prefs" );}
477+ File oldFile = openRead (_fsExtra, " /new_prefs" );
478+ File newFile = openWrite (_fs, " /new_prefs" );
479+
480+ if (oldFile && newFile) {
481+ uint8_t buf[64 ];
482+ int n;
483+ while ((n = oldFile.read (buf, sizeof (buf))) > 0 ) {
484+ newFile.write (buf, n);
485+ }
486+ }
487+ if (oldFile) oldFile.close ();
488+ if (newFile) newFile.close ();
489+ _fsExtra->remove (" /new_prefs" );
490+ }
491+ // remove files from where they should not be anymore
492+ if (_fs->exists (" /adv_blobs" )) {
493+ _fs->remove (" /adv_blobs" );
494+ }
495+ if (_fs->exists (" /contacts3" )) {
496+ _fs->remove (" /contacts3" );
497+ }
498+ if (_fs->exists (" /channels2" )) {
499+ _fs->remove (" /channels2" );
500+ }
501+ if (_fsExtra->exists (" /_main.id" )) {
502+ _fsExtra->remove (" /_main.id" );
503+ }
504+ if (_fsExtra->exists (" /new_prefs" )) {
505+ _fsExtra->remove (" /new_prefs" );
506+ }
507+ }
508+
347509uint8_t DataStore::getBlobByKey (const uint8_t key[], int key_len, uint8_t dest_buf[]) {
348- File file = _fs ->open (" /adv_blobs" );
510+ File file = _getContactsChannelsFS () ->open (" /adv_blobs" );
349511 uint8_t len = 0 ; // 0 = not found
350-
351512 if (file) {
352513 BlobRec tmp;
353514 while (file.read ((uint8_t *) &tmp, sizeof (tmp)) == sizeof (tmp)) {
@@ -364,10 +525,8 @@ uint8_t DataStore::getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_b
364525
365526bool DataStore::putBlobByKey (const uint8_t key[], int key_len, const uint8_t src_buf[], uint8_t len) {
366527 if (len < PUB_KEY_SIZE+4 +SIGNATURE_SIZE || len > MAX_ADVERT_PKT_LEN) return false ;
367-
368528 checkAdvBlobFile ();
369-
370- File file = _fs->open (" /adv_blobs" , FILE_O_WRITE);
529+ File file = _getContactsChannelsFS ()->open (" /adv_blobs" , FILE_O_WRITE);
371530 if (file) {
372531 uint32_t pos = 0 , found_pos = 0 ;
373532 uint32_t min_timestamp = 0xFFFFFFFF ;
0 commit comments