@@ -7,7 +7,7 @@ | |||
namespace config { | |||
namespace main { | |||
Config value; | |||
Config_t value; | |||
namespace details { | |||
@@ -17,7 +17,6 @@ namespace config { | |||
hardware::i2c::eeprom.readBlock(CONFIG_ADDR, value); | |||
if (!String(CONFIG_SEED).equals(value.seed)) reset(); | |||
hardware::i2c::powerOff(); | |||
} | |||
void write() { | |||
@@ -29,21 +28,21 @@ namespace config { | |||
} | |||
} | |||
Config get() { | |||
Config_t get() { | |||
if (value.seed[0] == '\0') details::read(); | |||
VERBOSE_FORMAT("get", "%s, %s, %s, %d, %d", value.seed, value.version, value.apn, value.firstEntry, value.lastEntry); | |||
return value; | |||
} | |||
void set(const Config config) { | |||
void set(const Config_t config) { | |||
value = config; | |||
details::write(); | |||
} | |||
void reset() { | |||
VERBOSE("reset"); | |||
Config config = { | |||
Config_t config = { | |||
CONFIG_SEED, | |||
VERSION, | |||
"Vodafone", //TODO : read from SD | |||
@@ -7,7 +7,7 @@ struct sleepTimings_t { | |||
uint16_t seconds; | |||
}; | |||
struct Config { | |||
struct Config_t { | |||
char seed[5]; | |||
char version[5]; | |||
char apn[20]; | |||
@@ -38,8 +38,8 @@ namespace config { | |||
}; | |||
namespace main { | |||
Config get(); | |||
void set(const Config config); | |||
Config_t get(); | |||
void set(const Config_t config); | |||
void reset(); | |||
} |
@@ -70,7 +70,7 @@ namespace positions { | |||
strlcpy(entry.position, gps::lastPosition, POSITION_SIZE); | |||
hardware::i2c::powerOn(); | |||
Config config = config::main::get(); | |||
Config_t config = config::main::get(); | |||
config.lastEntry++; | |||
if (config.lastEntry > details::maxEntryIndex) config.lastEntry = 0; | |||
@@ -109,6 +109,13 @@ namespace positions { | |||
return true; | |||
} | |||
uint16_t count(uint16_t fromIndex) { | |||
Config_t config = config::main::get(); | |||
if (config.lastEntry < config.firstEntry) { config.lastEntry += details::maxEntryIndex; } | |||
return config.lastEntry - fromIndex; | |||
} | |||
void doBackup() { | |||
for (int i = 0; i < _backupLength; i++) { | |||
_backups[i]->backup(); | |||
@@ -26,6 +26,7 @@ namespace positions { | |||
bool get(uint16_t index, PositionEntry &entry); | |||
bool moveNext(uint16_t &index); | |||
uint16_t count(uint16_t fromIndex); | |||
void doBackup(); | |||
} |
@@ -1,21 +1,57 @@ | |||
#include "SdPositionsBackup.h" | |||
#include "SdPositionsConfig.h" | |||
#include "SdCard.h" | |||
#include "Hardware.h" | |||
#include "Config.h" | |||
#include "SdFat.h" | |||
#include "Positions.h" | |||
namespace positions { | |||
namespace backup { | |||
namespace sd { | |||
namespace details { | |||
bool isBackupNeeded(SdPositionConfig_t &sdConfig) { | |||
Config_t referenceConfig = config::main::get(); | |||
sdConfig = config::backup::sd::get(); | |||
return sdConfig.lastSavedEntry == 0xFFFF || | |||
positions::count(sdConfig.lastSavedEntry) > sdConfig.saveThreshold; | |||
} | |||
void appendPositions(const File &file, SdPositionConfig_t &sdConfig) { | |||
uint16_t currentEntryIndex = sdConfig.lastSavedEntry + 1; | |||
PositionEntry currentEntry; | |||
hardware::i2c::powerOn(); | |||
do { | |||
if (!positions::get(currentEntryIndex, currentEntry)) break; | |||
sdConfig.filePosition = file.position(); | |||
} while (true); | |||
hardware::i2c::powerOff(); | |||
} | |||
} | |||
void SdPositionsBackup::setup() { | |||
config::backup::sd::setup(); | |||
_config = new RawSdFile(&hardware::sdcard::filesystem, POSITIONS_CONFIG_FILENAME); | |||
} | |||
void SdPositionsBackup::backup() { | |||
Config referenceConfig = config::main::get(); | |||
SdPositionConfig_t sdConfig; | |||
if (!details::isBackupNeeded(sdConfig)) return; | |||
char *filename; | |||
hardware::sdcard::filesystem.chdir("positions"); | |||
File file = hardware::sdcard::filesystem.open(filename, O_RDWR | O_CREAT); | |||
file.seek(sdConfig.filePosition); | |||
file.find('\n'); | |||
details::appendPositions(file, sdConfig); | |||
} | |||
} | |||
@@ -3,8 +3,6 @@ | |||
#include "PositionsBackup.h" | |||
#include "RawSdFile.h" | |||
#define POSITIONS_CONFIG_FILENAME "positions.config" | |||
using namespace sd; | |||
namespace positions { | |||
@@ -13,7 +11,6 @@ namespace positions { | |||
class SdPositionsBackup : public PositionsBackup { | |||
private: | |||
RawSdFile * _config; | |||
public: | |||
void setup(); | |||
void backup(); | |||
@@ -1,11 +1,71 @@ | |||
#include "SdPositionsConfig.h" | |||
#include "SdCard.h" | |||
#include "RawSdFile.h" | |||
#include "Debug.h" | |||
using namespace sd; | |||
#define LOGGER_NAME "Config::backup::sd" | |||
namespace config { | |||
namespace backup { | |||
namespace sd { | |||
void setup() { | |||
SdPositionConfig_t value; | |||
File configFile; | |||
namespace details { | |||
void ensureOpened() { | |||
if (!configFile.isOpen()) { | |||
hardware::sdcard::filesystem.chdir(); | |||
configFile.open(POSITIONS_CONFIG_FILENAME, O_RDWR | O_CREAT); | |||
} | |||
configFile.rewind(); | |||
} | |||
void read() { | |||
VERBOSE("read"); | |||
ensureOpened(); | |||
configFile.read((void*)&value, sizeof(value)); | |||
if (value.seed != POSITIONS_CONFIG_SEED) reset(); | |||
} | |||
void write() { | |||
VERBOSE("write"); | |||
ensureOpened(); | |||
configFile.write((void*)&value, sizeof(value)); | |||
} | |||
} | |||
void setup() { } | |||
SdPositionConfig_t get() { | |||
if (value.seed != POSITIONS_CONFIG_SEED) details::read(); | |||
return value; | |||
} | |||
void set(SdPositionConfig_t config) { | |||
value = config; | |||
details::write(); | |||
} | |||
void reset() { | |||
VERBOSE("reset"); | |||
SdPositionConfig_t config = { | |||
POSITIONS_CONFIG_SEED, | |||
POSITIONS_CONFIG_DeFAULT_SAVE_THRESHOLD, | |||
0xFFFF, | |||
0, | |||
0, | |||
0 | |||
}; | |||
value = config; | |||
details::write(); | |||
} | |||
} | |||
@@ -2,10 +2,17 @@ | |||
#include <Arduino.h> | |||
#define POSITIONS_CONFIG_FILENAME "positions.config" | |||
#define POSITIONS_CONFIG_SEED 45 | |||
#define POSITIONS_CONFIG_DeFAULT_SAVE_THRESHOLD 10 | |||
struct SdPositionConfig_t { | |||
uint8_t seed; | |||
uint8_t saveThreshold; | |||
uint16_t lastSavedEntry; | |||
uint16_t fileIndex; | |||
uint32_t position; | |||
size_t size; | |||
uint32_t filePosition; | |||
size_t fileRecords; | |||
}; | |||
namespace config { | |||