199 lines
5.1 KiB

  1. #include "Config.h"
  2. #include "Positions.h"
  3. #include "Gps.h"
  4. #include "Rtc.h"
  5. #include "Logging.h"
  6. #if BACKUP_ENABLE_SDCARD || BACKUP_ENABLE_NETWORK
  7. #define BACKUPS_ENABLED (BACKUP_ENABLE_SDCARD + BACKUP_ENABLE_NETWORK)
  8. #endif
  9. #if BACKUP_ENABLE_SDCARD
  10. #include "SdPositionsBackup.h"
  11. #endif
  12. #if BACKUP_ENABLE_NETWORK
  13. #include "NetworkPositionsBackup.h"
  14. #endif
  15. #define ENTRY_RESERVED_SIZE 128
  16. #define ENTRIES_ADDR CONFIG_RESERVED_SIZE
  17. namespace positions {
  18. #define CURRENT_LOGGER "positions"
  19. #if BACKUPS_ENABLED > 1
  20. backup::PositionsBackup **_backups;
  21. #elif BACKUPS_ENABLED == 1
  22. backup::PositionsBackup * _backup;
  23. #endif
  24. namespace details {
  25. uint16_t maxEntryIndex = 0;
  26. uint16_t getEntryAddress(uint16_t index) {
  27. if (index > maxEntryIndex) return -1;
  28. return ENTRIES_ADDR + (ENTRY_RESERVED_SIZE * index);
  29. }
  30. }
  31. void setup() {
  32. details::maxEntryIndex = (E24_MAX_ADDRESS(hardware::i2c::eeprom.getSize()) - ENTRIES_ADDR) / ENTRY_RESERVED_SIZE;
  33. #if BACKUPS_ENABLED > 0
  34. backup::PositionsBackup * backup = NULL;
  35. #if BACKUPS_ENABLED > 1
  36. uint8_t backupIdx = 0;
  37. _backups = new backup::PositionsBackup*[BACKUPS_ENABLED];
  38. #endif //BACKUPS_ENABLED > 1
  39. #if BACKUP_ENABLE_SDCARD
  40. backup = new backup::sd::SdPositionsBackup();
  41. backup->setup();
  42. #if BACKUPS_ENABLED > 1
  43. _backups[backupIdx] = backup;
  44. backupIdx++;
  45. #endif //BACKUPS_ENABLED > 1
  46. #endif //BACKUP_ENABLE_SDCARD
  47. #if BACKUP_ENABLE_NETWORK
  48. backup = new backup::net::NetworkPositionsBackup();
  49. backup->setup();
  50. #if BACKUPS_ENABLED > 1
  51. _backups[backupIdx] = backup;
  52. backupIdx++;
  53. #endif //BACKUPS_ENABLED > 1
  54. #endif //BACKUP_ENABLE_NETWORK
  55. #if BACKUPS_ENABLED == 1
  56. _backup = backup;
  57. #endif //BACKUPS_ENABLED == 1
  58. #endif //BACKUPS_ENABLED > 0
  59. }
  60. bool acquire(PositionEntryMetadata &metadata) {
  61. #define CURRENT_LOGGER_FUNCTION "acquire"
  62. NOTICE;
  63. timestamp_t before;
  64. gps::powerOn();
  65. before = rtc::getTime();
  66. SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS);
  67. uint16_t timeToFix = rtc::getTime() - before;
  68. SIM808ChargingStatus battery = hardware::sim808::device.getChargingState();
  69. gps::powerOff();
  70. bool acquired = gpsStatus >= SIM808_GPS_STATUS::FIX; //prety useless wins 14 bytes on the hex size rather than return gpStatus >= ...
  71. NOTICE_FORMAT("Status : %d", gpsStatus);
  72. metadata = {
  73. battery.level,
  74. battery.voltage,
  75. rtc::getTemperature(),
  76. timeToFix,
  77. gpsStatus
  78. };
  79. return acquired;
  80. }
  81. void appendLast(const PositionEntryMetadata &metadata) {
  82. #define CURRENT_LOGGER_FUNCTION "appendLast"
  83. VERBOSE;
  84. uint16_t entryIndex;
  85. uint16_t entryAddress;
  86. PositionEntry entry = { metadata };
  87. strlcpy(entry.position, gps::lastPosition, POSITION_SIZE);
  88. config_t* config = &config::main::value;
  89. entryIndex = config->lastEntry + 1;
  90. entryAddress = details::getEntryAddress(entryIndex);
  91. print(entryIndex, entry);
  92. hardware::i2c::powerOn();
  93. hardware::i2c::eeprom.writeBlock(entryAddress, entry);
  94. NOTICE_MSG("Saved");
  95. config->lastEntry++;
  96. if (config->lastEntry > details::maxEntryIndex) config->lastEntry = 0;
  97. if (config->lastEntry == config->firstEntry) config->firstEntry++;
  98. if (config->firstEntry > details::maxEntryIndex) config->firstEntry = 0;
  99. config::main::save();
  100. hardware::i2c::powerOff();
  101. }
  102. bool get(uint16_t index, PositionEntry &entry) {
  103. #define CURRENT_LOGGER_FUNCTION "get"
  104. VERBOSE;
  105. uint16_t entryAddress = details::getEntryAddress(index);
  106. if (entryAddress == -1) return false;
  107. VERBOSE_FORMAT("Reading entry %d @ %X", index, entryAddress);
  108. hardware::i2c::powerOn();
  109. hardware::i2c::eeprom.readBlock(entryAddress, entry);
  110. hardware::i2c::powerOff();
  111. print(index, entry);
  112. return true;
  113. }
  114. bool moveNext(uint16_t &index) {
  115. if (index == config::main::value.lastEntry) return false;
  116. if (index == details::maxEntryIndex) index = 0; //could use a modulo but easier to understand that way
  117. else index++;
  118. return true;
  119. }
  120. uint16_t count(uint16_t fromIndex) {
  121. config_t *config = &config::main::value;
  122. uint16_t lastEntry = config->lastEntry;
  123. if (lastEntry < fromIndex) { lastEntry += details::maxEntryIndex; }
  124. return lastEntry - fromIndex;
  125. }
  126. void prepareBackup(bool force) {
  127. #if BACKUPS_ENABLED > 1
  128. for (int i = 0; i < BACKUPS_ENABLED; i++) {
  129. _backups[i]->prepare(force);
  130. }
  131. #elif BACKUPS_ENABLED == 1
  132. _backup->prepare(force);
  133. #endif
  134. }
  135. void doBackup(bool force) {
  136. #if BACKUPS_ENABLED > 1
  137. for (int i = 0; i < BACKUPS_ENABLED; i++) {
  138. _backups[i]->backup(force);
  139. }
  140. #elif BACKUPS_ENABLED == 1
  141. _backup->backup(force);
  142. #endif
  143. }
  144. void print(uint16_t index, PositionEntry &entry) {
  145. #define CURRENT_LOGGER_FUNCTION "print"
  146. uint16_t address = details::getEntryAddress(index);
  147. NOTICE_FORMAT("%X : %d,%d,%d,%d,%d,%s",
  148. address,
  149. entry.metadata.batteryLevel,
  150. entry.metadata.batteryVoltage,
  151. entry.metadata.temperature,
  152. static_cast<uint8_t>(entry.metadata.status),
  153. entry.metadata.timeToFix,
  154. entry.position);
  155. }
  156. }