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