@@ -217,6 +217,7 @@ const uint8_t CFG_ROTATES = 7; // Number of flash sectors used (handles upl
217
217
218
218
uint32_t settings_location = EEPROM_LOCATION;
219
219
uint32_t settings_crc32 = 0 ;
220
+ uint32_t settings_size = 0 ;
220
221
uint8_t *settings_buffer = nullptr ;
221
222
uint8_t config_xor_on_set = CONFIG_FILE_XOR;
222
223
@@ -375,56 +376,124 @@ void SettingsSaveAll(void) {
375
376
* Settings backup and restore
376
377
\*********************************************************************************************/
377
378
379
+ String SettingsConfigFilename (void ) {
380
+ char filename[TOPSZ];
381
+ char hostname[sizeof (TasmotaGlobal.hostname )];
382
+ snprintf_P (filename, sizeof (filename), PSTR (" Config_%s_%s.dmp" ), NoAlNumToUnderscore (hostname, TasmotaGlobal.hostname ), TasmotaGlobal.version );
383
+ return String (filename);
384
+ }
385
+
386
+ void SettingsBufferXor (void ) {
387
+ if (config_xor_on_set) {
388
+ uint32_t xor_index = (settings_size > sizeof (TSettings)) ? 18 : 2 ;
389
+ for (uint32_t i = xor_index; i < settings_size; i++) {
390
+ settings_buffer[i] ^= (config_xor_on_set +i);
391
+ }
392
+ }
393
+ }
394
+
378
395
void SettingsBufferFree (void ) {
379
396
if (settings_buffer != nullptr ) {
380
397
free (settings_buffer);
381
398
settings_buffer = nullptr ;
382
399
}
400
+ settings_size = 0 ;
383
401
}
384
402
385
- bool SettingsBufferAlloc (void ) {
403
+ bool SettingsBufferAlloc (uint32_t upload_size = 0 );
404
+ bool SettingsBufferAlloc (uint32_t upload_size) {
386
405
SettingsBufferFree ();
387
- if (!(settings_buffer = (uint8_t *)malloc (sizeof (TSettings)))) {
406
+
407
+ settings_size = sizeof (TSettings);
408
+ if (upload_size >= sizeof (TSettings)) {
409
+ uint32_t mem = ESP_getFreeHeap ();
410
+ if ((mem - upload_size) < (8 * 1024 )) {
411
+ AddLog (LOG_LEVEL_DEBUG, PSTR (D_LOG_APPLICATION D_UPLOAD_ERR_2)); // Not enough (memory) space
412
+ return false ;
413
+ }
414
+ settings_size = upload_size;
415
+ } else {
416
+
417
+ #ifdef USE_UFILESYS
418
+ char filename[14 ];
419
+ for (uint32_t i = 0 ; i < 129 ; i++) {
420
+ snprintf_P (filename, sizeof (filename), PSTR (TASM_FILE_DRIVER), i);
421
+ uint32_t fsize = TfsFileSize (filename);
422
+ if (fsize) {
423
+ if (settings_size == sizeof (TSettings)) {
424
+ settings_size += 16 ; // Add tar header for total file size
425
+ }
426
+ fsize = ((fsize / 16 ) * 16 ) + 16 ; // Use 16-byte boundary
427
+ settings_size += (16 + fsize); // Tar header size is 16 bytes
428
+ }
429
+ }
430
+ #endif // USE_UFILESYS
431
+
432
+ }
433
+
434
+ if (!(settings_buffer = (uint8_t *)calloc (settings_size, 1 ))) {
388
435
AddLog (LOG_LEVEL_DEBUG, PSTR (D_LOG_APPLICATION D_UPLOAD_ERR_2)); // Not enough (memory) space
389
436
return false ;
390
437
}
391
438
return true ;
392
439
}
393
440
394
- String SettingsConfigFilename (void ) {
395
- char filename[TOPSZ];
396
- char hostname[sizeof (TasmotaGlobal.hostname )];
397
- snprintf_P (filename, sizeof (filename), PSTR (" Config_%s_%s.dmp" ), NoAlNumToUnderscore (hostname, TasmotaGlobal.hostname ), TasmotaGlobal.version );
398
- return String (filename);
399
- }
400
-
401
441
uint32_t SettingsConfigBackup (void ) {
402
442
if (!SettingsBufferAlloc ()) { return 0 ; }
403
443
404
- uint32_t cfg_crc32 = Settings->cfg_crc32 ;
405
- Settings->cfg_crc32 = GetSettingsCrc32 (); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
444
+ uint8_t *filebuf_ptr = settings_buffer;
406
445
407
- uint32_t config_len = sizeof (TSettings);
408
- memcpy (settings_buffer, Settings, config_len);
446
+ #ifdef USE_UFILESYS
447
+ if (settings_size > sizeof (TSettings)) {
448
+ snprintf_P ((char *)filebuf_ptr, 14 , PSTR (TASM_FILE_SETTINGS)); // /.settings
449
+ filebuf_ptr += 14 ;
450
+ *filebuf_ptr = settings_size;
451
+ filebuf_ptr++;
452
+ *filebuf_ptr = (settings_size >> 8 );
453
+ filebuf_ptr++;
454
+ }
455
+ #endif // USE_UFILESYS
409
456
457
+ uint32_t cfg_crc32 = Settings->cfg_crc32 ;
458
+ Settings->cfg_crc32 = GetSettingsCrc32 (); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
459
+ memcpy (filebuf_ptr, Settings, sizeof (TSettings));
410
460
Settings->cfg_crc32 = cfg_crc32; // Restore crc in case savedata = 0 to make sure settings will be noted as changed
411
461
412
- if (config_xor_on_set) {
413
- for (uint32_t i = 2 ; i < config_len; i++) {
414
- settings_buffer[i] ^= (config_xor_on_set +i);
462
+ #ifdef USE_UFILESYS
463
+ if (settings_size > sizeof (TSettings)) {
464
+ filebuf_ptr += sizeof (TSettings);
465
+ char filename[14 ];
466
+ for (uint32_t i = 0 ; i < 129 ; i++) {
467
+ snprintf_P (filename, sizeof (filename), PSTR (TASM_FILE_DRIVER), i); // /.drvset012
468
+ uint32_t fsize = TfsFileSize (filename);
469
+ if (fsize) {
470
+ memcpy (filebuf_ptr, filename, 14 );
471
+ filebuf_ptr += 14 ;
472
+ *filebuf_ptr = fsize;
473
+ filebuf_ptr++;
474
+ *filebuf_ptr = (fsize >> 8 );
475
+ filebuf_ptr++;
476
+ AddLog (LOG_LEVEL_DEBUG, PSTR (" CFG: Backup file %s (%d)" ), (char *)filebuf_ptr -16 , fsize);
477
+ TfsLoadFile ((const char *)filebuf_ptr -16 , (uint8_t *)filebuf_ptr, fsize);
478
+ filebuf_ptr += ((fsize / 16 ) * 16 ) + 16 ;
479
+ }
415
480
}
416
481
}
417
- return config_len;
482
+ #endif // USE_UFILESYS
483
+
484
+ SettingsBufferXor ();
485
+ return settings_size;
418
486
}
419
487
420
488
bool SettingsConfigRestore (void ) {
421
- uint32_t config_len = sizeof (TSettings );
489
+ SettingsBufferXor ( );
422
490
423
- if (config_xor_on_set) {
424
- for ( uint32_t i = 2 ; i < config_len; i++ ) {
425
- settings_buffer[i] ^= (config_xor_on_set +i) ;
426
- }
491
+ # ifdef USE_UFILESYS
492
+ if (settings_size > sizeof (TSettings) ) {
493
+ settings_size -= 16 ;
494
+ memmove (settings_buffer, settings_buffer + 16 , settings_size); // Skip tar header
427
495
}
496
+ #endif // USE_UFILESYS
428
497
429
498
bool valid_settings = false ;
430
499
@@ -434,11 +503,11 @@ bool SettingsConfigRestore(void) {
434
503
// uint16_t cfg_size; // 002
435
504
uint32_t buffer_size = settings_buffer[3 ] << 8 | settings_buffer[2 ];
436
505
if (buffer_version > 0x0606000A ) {
437
- // uint32_t cfg_crc32; // FFC
506
+ // uint32_t cfg_crc32; // FFC
438
507
uint32_t buffer_crc32 = settings_buffer[4095 ] << 24 | settings_buffer[4094 ] << 16 | settings_buffer[4093 ] << 8 | settings_buffer[4092 ];
439
508
valid_settings = (GetCfgCrc32 (settings_buffer, buffer_size -4 ) == buffer_crc32);
440
509
} else {
441
- // uint16_t cfg_crc; // 00E
510
+ // uint16_t cfg_crc; // 00E
442
511
uint16_t buffer_crc16 = settings_buffer[15 ] << 8 | settings_buffer[14 ];
443
512
valid_settings = (GetCfgCrc16 (settings_buffer, buffer_size) == buffer_crc16);
444
513
}
@@ -467,12 +536,27 @@ bool SettingsConfigRestore(void) {
467
536
468
537
if (valid_settings) {
469
538
SettingsDefaultSet2 ();
470
- memcpy ((char *)Settings +16 , settings_buffer +16 , config_len -16 );
539
+ memcpy ((char *)Settings +16 , settings_buffer +16 , sizeof (TSettings) -16 );
471
540
Settings->version = buffer_version; // Restore version and auto upgrade after restart
472
541
}
473
542
474
- SettingsBufferFree ();
543
+ #ifdef USE_UFILESYS
544
+ if (settings_size > sizeof (TSettings)) {
545
+ uint8_t *filebuf_ptr = settings_buffer + sizeof (TSettings);
546
+ while ((filebuf_ptr - settings_buffer) < settings_size) {
547
+ filebuf_ptr += 14 ;
548
+ uint32_t fsize = *filebuf_ptr;
549
+ filebuf_ptr++;
550
+ fsize += *filebuf_ptr << 8 ;
551
+ filebuf_ptr++;
552
+ AddLog (LOG_LEVEL_DEBUG, PSTR (" CFG: Restore file %s (%d)" ), (char *)filebuf_ptr -16 , fsize);
553
+ TfsSaveFile ((const char *)filebuf_ptr -16 , (uint8_t *)filebuf_ptr, fsize);
554
+ filebuf_ptr += ((fsize / 16 ) * 16 ) + 16 ;
555
+ }
556
+ }
557
+ #endif // USE_UFILESYS
475
558
559
+ SettingsBufferFree ();
476
560
return valid_settings;
477
561
}
478
562
0 commit comments