Browse Source

Backup of NVS-RFID-entries added (GUI will follow)

master
Torsten Stauder 5 years ago
parent
commit
22ee9bbfd9
  1. 93
      lib/nvsdump/src/nvsDump.h
  2. 104
      src/main.cpp

93
lib/nvsdump/src/nvsDump.h

@ -0,0 +1,93 @@
#include <stdio.h>
#include <string.h>
#include <esp_partition.h>
// Debug buffer size
#define DEBUG_BUFFER_SIZE 130
#define DEBUG false
struct nvs_entry {
uint8_t Ns; // Namespace ID
uint8_t Type; // Type of value
uint8_t Span; // Number of entries used for this item
uint8_t Rvs; // Reserved, should be 0xFF
uint32_t CRC; // CRC
char Key[16]; // Key in Ascii
uint64_t Data; // Data in entry
};
struct nvs_page { // For nvs entries
uint32_t State;
uint32_t Seqnr;
uint32_t Unused[5];
uint32_t CRC;
uint8_t Bitmap[32];
nvs_entry Entry[126];
};
// Common data
nvs_page buf;
//**************************************************************************************************
// D B G P R I N T *
//**************************************************************************************************
// Send a line of info to serial output. Works like vsprintf(), but checks the DEBUG flag. *
// Print only if DEBUG flag is true. Always returns the formatted string. *
//**************************************************************************************************
char* dbgprint (const char* format, ...) {
static char sbuf[DEBUG_BUFFER_SIZE]; // For debug lines
va_list varArgs; // For variable number of params
va_start (varArgs, format); // Prepare parameters
vsnprintf (sbuf, sizeof(sbuf), format, varArgs); // Format the message
va_end (varArgs); // End of using parameters
if (DEBUG) { // DEBUG on?
Serial.print ("D: "); // Yes, print prefix
Serial.println (sbuf); // and the info
}
return sbuf; // Return stored string
}
//**************************************************************************************************
// F I N D N S I D *
//**************************************************************************************************
// Find the namespace ID for the namespace passed as parameter. *
//**************************************************************************************************
uint8_t FindNsID (const esp_partition_t* nvs, const char* ns) {
esp_err_t result = ESP_OK; // Result of reading partition
uint32_t offset = 0; // Offset in nvs partition
uint8_t i; // Index in Entry 0..125
uint8_t bm; // Bitmap for an entry
uint8_t res = 0xFF; // Function result
while (offset < nvs->size) {
result = esp_partition_read ( nvs, offset, // Read 1 page in nvs partition
&buf,
sizeof(nvs_page) );
if (result != ESP_OK) {
dbgprint ("Error reading NVS!");
break;
}
i=0;
while (i < 126) {
bm = (buf.Bitmap[i/4] >> ((i % 4) * 2)) & 0x03 ; // Get bitmap for this entry
if ((bm == 2) &&
(buf.Entry[i].Ns == 0) &&
(strcmp (ns, buf.Entry[i].Key) == 0)) {
res = buf.Entry[i].Data & 0xFF; // Return the ID
offset = nvs->size; // Stop outer loop as well
break;
} else {
if (bm == 2) {
i += buf.Entry[i].Span ; // Next entry
} else {
i++;
}
}
}
offset += sizeof(nvs_page); // Prepare to read next page in nvs
}
return res;
}

104
src/main.cpp

@ -29,6 +29,7 @@
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include <nvsDump.h>
@ -150,6 +151,11 @@ typedef struct { // Bit field
} playProps;
playProps playProperties;
typedef struct {
char *nvsKey;
char *nvsEntry;
} nvs_t;
// Configuration of initial values (for the first start) goes here....
// There's no need to change them here as they can be configured via webinterface
// Neopixel
@ -311,13 +317,15 @@ static int arrSortHelper(const void* a, const void* b);
void callback(const char *topic, const byte *payload, uint32_t length);
#endif
void buttonHandler();
void deepSleepManager(void);
void doButtonActions(void);
void doRfidCardModifications(const uint32_t mod);
void deepSleepManager(void);
bool dumpNvsToSd(char *_namespace, char *_destFile);
bool endsWith (const char *str, const char *suf);
bool fileValid(const char *_fileItem);
void freeMultiCharArray(char **arr, const uint32_t cnt);
uint8_t getRepeatMode(void);
bool isNumber(const char *str);
void loggerNl(const char *str, const uint8_t logLevel);
void logger(const char *str, const uint8_t logLevel);
#ifdef MQTT_ENABLE
@ -2620,19 +2628,23 @@ bool processJsonRequest(char *_serialJson) {
if (s.compareTo(rfidString)) {
return false;
}
dumpNvsToSd("rfidTags", "/backup.txt");
} else if (doc.containsKey("rfidAssign")) {
const char *_rfidIdModId = object["rfidAssign"]["rfidIdMusic"];
const char *_rfidIdAssinId = object["rfidAssign"]["rfidIdMusic"];
const char *_fileOrUrl = object["rfidAssign"]["fileOrUrl"];
uint8_t _playMode = object["rfidAssign"]["playMode"];
char rfidString[275];
snprintf(rfidString, sizeof(rfidString) / sizeof(rfidString[0]), "%s%s%s0%s%u%s0", stringDelimiter, _fileOrUrl, stringDelimiter, stringDelimiter, _playMode, stringDelimiter);
prefsRfid.putString(_rfidIdModId, rfidString);
prefsRfid.putString(_rfidIdAssinId, rfidString);
Serial.println(_rfidIdAssinId);
Serial.println(rfidString);
String s = prefsRfid.getString(_rfidIdModId, "-1");
String s = prefsRfid.getString(_rfidIdAssinId, "-1");
if (s.compareTo(rfidString)) {
return false;
}
dumpNvsToSd("rfidTags", "/backup.txt");
} else if (doc.containsKey("wifiConfig")) {
const char *_ssid = object["wifiConfig"]["ssid"];
@ -2726,6 +2738,90 @@ void onWebsocketEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, Aw
}
bool isNumber(const char *str) {
byte i = 0;
while (*(str + i) != '\0') {
if (!isdigit(*(str + i++))) {
return false;
}
}
if (i>0) {
return true;
} else {
return false;
}
}
// Dumps all RFID-entries from NVS into a file on SD-card
bool dumpNvsToSd(char *_namespace, char *_destFile) {
esp_partition_iterator_t pi; // Iterator for find
const esp_partition_t* nvs; // Pointer to partition struct
esp_err_t result = ESP_OK;
const char* partname = "nvs";
uint8_t pagenr = 0; // Page number in NVS
uint8_t i; // Index in Entry 0..125
uint8_t bm; // Bitmap for an entry
uint32_t offset = 0; // Offset in nvs partition
uint8_t namespace_ID; // Namespace ID found
pi = esp_partition_find ( ESP_PARTITION_TYPE_DATA, // Get partition iterator for
ESP_PARTITION_SUBTYPE_ANY, // this partition
partname ) ;
if (pi) {
nvs = esp_partition_get(pi); // Get partition struct
esp_partition_iterator_release(pi); // Release the iterator
dbgprint ( "Partition %s found, %d bytes",
partname,
nvs->size ) ;
} else {
Serial.printf("Partition %s not found!", partname) ;
return NULL;
}
namespace_ID = FindNsID (nvs, _namespace) ; // Find ID of our namespace in NVS
File backupFile = SD.open(_destFile, FILE_WRITE);
if (!backupFile) {
return false;
}
while (offset < nvs->size) {
result = esp_partition_read (nvs, offset, // Read 1 page in nvs partition
&buf,
sizeof(nvs_page));
if (result != ESP_OK) {
Serial.println(F("Error reading NVS!"));
return false;
}
i = 0;
while (i < 126) {
bm = (buf.Bitmap[i/4] >> ((i % 4) * 2 )) & 0x03; // Get bitmap for this entry
if (bm == 2) {
if ((namespace_ID == 0xFF) || // Show all if ID = 0xFF
(buf.Entry[i].Ns == namespace_ID)) { // otherwise just my namespace
if (isNumber(buf.Entry[i].Key)) {
String s = prefsRfid.getString((const char *)buf.Entry[i].Key);
backupFile.printf("%s^%s\n", buf.Entry[i].Key, s.c_str());
}
}
i += buf.Entry[i].Span; // Next entry
} else {
i++;
}
}
offset += sizeof(nvs_page); // Prepare to read next page in nvs
pagenr++;
}
backupFile.close();
return true;
}
void setup() {
Serial.begin(115200);
srand(esp_random());

Loading…
Cancel
Save