mirror of
https://github.com/meshtastic/firmware.git
synced 2025-05-05 05:13:10 +00:00
Use SD card as store&forward memory
This commit is contained in:
parent
f77c87dca8
commit
b1125513f3
@ -49,6 +49,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "modules/ExternalNotificationModule.h"
|
#include "modules/ExternalNotificationModule.h"
|
||||||
#include "modules/TextMessageModule.h"
|
#include "modules/TextMessageModule.h"
|
||||||
#include "modules/WaypointModule.h"
|
#include "modules/WaypointModule.h"
|
||||||
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||||
|
#include "modules/StoreForwardModule.h"
|
||||||
|
#endif
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
|
|
||||||
@ -58,11 +61,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
#include "modules/StoreForwardModule.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
#include "modules/StoreForwardModule.h"
|
|
||||||
#include "platform/portduino/PortduinoGlue.h"
|
#include "platform/portduino/PortduinoGlue.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2397,9 +2398,9 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
// Draw the channel name
|
// Draw the channel name
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr);
|
display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr);
|
||||||
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||||
// Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo
|
// Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo
|
||||||
if (moduleConfig.store_forward.enabled) {
|
if (moduleConfig.store_forward.enabled) {
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
|
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
|
||||||
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
@ -2426,6 +2427,9 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
imgSF);
|
imgSF);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// No store and forward, show a exclamation mark
|
||||||
|
if (false) {
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// TODO: Raspberry Pi supports more than just the one screen size
|
// TODO: Raspberry Pi supports more than just the one screen size
|
||||||
|
@ -57,6 +57,8 @@ uint32_t MemGet::getFreePsram()
|
|||||||
{
|
{
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
return ESP.getFreePsram();
|
return ESP.getFreePsram();
|
||||||
|
#elif defined(HAS_SDCARD)
|
||||||
|
return SD.totalBytes() - SD.usedBytes();
|
||||||
#elif defined(ARCH_PORTDUINO)
|
#elif defined(ARCH_PORTDUINO)
|
||||||
return 4194252;
|
return 4194252;
|
||||||
#else
|
#else
|
||||||
@ -73,6 +75,8 @@ uint32_t MemGet::getPsramSize()
|
|||||||
{
|
{
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
return ESP.getPsramSize();
|
return ESP.getPsramSize();
|
||||||
|
#elif defined(HAS_SDCARD)
|
||||||
|
return SD.totalBytes();
|
||||||
#elif defined(ARCH_PORTDUINO)
|
#elif defined(ARCH_PORTDUINO)
|
||||||
return 4194252;
|
return 4194252;
|
||||||
#else
|
#else
|
||||||
|
@ -284,7 +284,6 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
|||||||
{
|
{
|
||||||
perhapsDecode(p);
|
perhapsDecode(p);
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
|
||||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||||
if (moduleConfig.store_forward.enabled && storeForwardModule->isServer() &&
|
if (moduleConfig.store_forward.enabled && storeForwardModule->isServer() &&
|
||||||
p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
||||||
@ -292,7 +291,6 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
|||||||
fromNum++; // Notify observers for packet from radio
|
fromNum++; // Notify observers for packet from radio
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (toPhoneQueue.numFree() == 0) {
|
if (toPhoneQueue.numFree() == 0) {
|
||||||
|
@ -13,11 +13,9 @@
|
|||||||
#if defined(ARCH_PORTDUINO) && !HAS_RADIO
|
#if defined(ARCH_PORTDUINO) && !HAS_RADIO
|
||||||
#include "../platform/portduino/SimRadio.h"
|
#include "../platform/portduino/SimRadio.h"
|
||||||
#endif
|
#endif
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
|
||||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||||
#include "modules/StoreForwardModule.h"
|
#include "modules/StoreForwardModule.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
extern Allocator<meshtastic_QueueStatus> &queueStatusPool;
|
extern Allocator<meshtastic_QueueStatus> &queueStatusPool;
|
||||||
extern Allocator<meshtastic_MqttClientProxyMessage> &mqttClientProxyMessagePool;
|
extern Allocator<meshtastic_MqttClientProxyMessage> &mqttClientProxyMessagePool;
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
#include "modules/NeighborInfoModule.h"
|
#include "modules/NeighborInfoModule.h"
|
||||||
|
// #if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||||
|
// #include "modules/StoreForwardModule.h"
|
||||||
|
// #endif
|
||||||
#include <ErriezCRC32.h>
|
#include <ErriezCRC32.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -32,13 +35,12 @@
|
|||||||
#if HAS_WIFI
|
#if HAS_WIFI
|
||||||
#include "mesh/wifi/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#endif
|
#endif
|
||||||
#include "modules/StoreForwardModule.h"
|
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
#include <nvs_flash.h>
|
#include <nvs_flash.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
#include "modules/StoreForwardModule.h"
|
|
||||||
#include "platform/portduino/PortduinoGlue.h"
|
#include "platform/portduino/PortduinoGlue.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -47,9 +47,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
#include "input/LinuxInputImpl.h"
|
#include "input/LinuxInputImpl.h"
|
||||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
|
||||||
#include "modules/StoreForwardModule.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#if HAS_TELEMETRY
|
#if HAS_TELEMETRY
|
||||||
#include "modules/Telemetry/DeviceTelemetry.h"
|
#include "modules/Telemetry/DeviceTelemetry.h"
|
||||||
@ -63,6 +60,9 @@
|
|||||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
|
||||||
#include "modules/Telemetry/PowerTelemetry.h"
|
#include "modules/Telemetry/PowerTelemetry.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||||
|
#include "modules/StoreForwardModule.h"
|
||||||
|
#endif
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
|
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
|
||||||
#include "modules/esp32/AudioModule.h"
|
#include "modules/esp32/AudioModule.h"
|
||||||
@ -70,9 +70,6 @@
|
|||||||
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER
|
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER
|
||||||
#include "modules/esp32/PaxcounterModule.h"
|
#include "modules/esp32/PaxcounterModule.h"
|
||||||
#endif
|
#endif
|
||||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
|
||||||
#include "modules/StoreForwardModule.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
||||||
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
||||||
|
@ -32,7 +32,7 @@ StoreForwardModule *storeForwardModule;
|
|||||||
|
|
||||||
int32_t StoreForwardModule::runOnce()
|
int32_t StoreForwardModule::runOnce()
|
||||||
{
|
{
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||||
if (moduleConfig.store_forward.enabled && is_server) {
|
if (moduleConfig.store_forward.enabled && is_server) {
|
||||||
// Send out the message queue.
|
// Send out the message queue.
|
||||||
if (this->busy) {
|
if (this->busy) {
|
||||||
@ -89,6 +89,27 @@ void StoreForwardModule::populatePSRAM()
|
|||||||
LOG_DEBUG("After PSRAM init: heap %d/%d PSRAM %d/%d", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(),
|
LOG_DEBUG("After PSRAM init: heap %d/%d PSRAM %d/%d", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(),
|
||||||
memGet.getPsramSize());
|
memGet.getPsramSize());
|
||||||
LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets);
|
LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets);
|
||||||
|
this->storageType = StorageType::PSRAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if we have an SDCARD, format it for store&forward use
|
||||||
|
*/
|
||||||
|
void StoreForwardModule::populateSDCard()
|
||||||
|
{
|
||||||
|
#if defined(HAS_SDCARD)
|
||||||
|
if (SD.cardType() != CARD_NONE) {
|
||||||
|
if (!SD.exists("/storeforward")) {
|
||||||
|
LOG_INFO("Creating StoreForward directory");
|
||||||
|
SD.mkdir("/storeforward");
|
||||||
|
}
|
||||||
|
this->storageType = StorageType::SDCARD;
|
||||||
|
uint32_t numberOfPackets = (this->records ? this->records : (((SD.totalBytes() / 3) * 2) / sizeof(PacketHistoryStruct)));
|
||||||
|
// only allocate space for one temp copy
|
||||||
|
this->packetHistory = (PacketHistoryStruct *)malloc(sizeof(PacketHistoryStruct));
|
||||||
|
LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,6 +156,7 @@ uint32_t StoreForwardModule::getNumAvailablePackets(NodeNum dest, uint32_t last_
|
|||||||
lastRequest.emplace(dest, 0);
|
lastRequest.emplace(dest, 0);
|
||||||
}
|
}
|
||||||
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
||||||
|
if (this->storageType == StorageType::PSRAM) {
|
||||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||||
// Client is only interested in packets not from itself and only in broadcast packets or packets towards it.
|
// Client is only interested in packets not from itself and only in broadcast packets or packets towards it.
|
||||||
if (this->packetHistory[i].from != dest &&
|
if (this->packetHistory[i].from != dest &&
|
||||||
@ -142,6 +164,20 @@ uint32_t StoreForwardModule::getNumAvailablePackets(NodeNum dest, uint32_t last_
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
auto handler = SD.open("/storeforward/" + String(i), FILE_READ);
|
||||||
|
if (handler) {
|
||||||
|
handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct));
|
||||||
|
handler.close();
|
||||||
|
if (this->packetHistory[0].time && (this->packetHistory[0].time > last_time)) {
|
||||||
|
// Client is only interested in packets not from itself and only in broadcast packets or packets towards it.
|
||||||
|
if (this->packetHistory[0].from != dest &&
|
||||||
|
(this->packetHistory[0].to == NODENUM_BROADCAST || this->packetHistory[0].to == dest)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -187,19 +223,33 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
|
|||||||
const auto &p = mp.decoded;
|
const auto &p = mp.decoded;
|
||||||
|
|
||||||
if (this->packetHistoryTotalCount == this->records) {
|
if (this->packetHistoryTotalCount == this->records) {
|
||||||
LOG_WARN("S&F - PSRAM Full. Starting overwrite.");
|
LOG_WARN("S&F - Storage Full. Starting overwrite.");
|
||||||
this->packetHistoryTotalCount = 0;
|
this->packetHistoryTotalCount = 0;
|
||||||
for (auto &i : lastRequest) {
|
for (auto &i : lastRequest) {
|
||||||
i.second = 0; // Clear the last request index for each client device
|
i.second = 0; // Clear the last request index for each client device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->storageType == StorageType::PSRAM) {
|
||||||
this->packetHistory[this->packetHistoryTotalCount].time = getTime();
|
this->packetHistory[this->packetHistoryTotalCount].time = getTime();
|
||||||
this->packetHistory[this->packetHistoryTotalCount].to = mp.to;
|
this->packetHistory[this->packetHistoryTotalCount].to = mp.to;
|
||||||
this->packetHistory[this->packetHistoryTotalCount].channel = mp.channel;
|
this->packetHistory[this->packetHistoryTotalCount].channel = mp.channel;
|
||||||
this->packetHistory[this->packetHistoryTotalCount].from = getFrom(&mp);
|
this->packetHistory[this->packetHistoryTotalCount].from = getFrom(&mp);
|
||||||
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
||||||
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes,
|
||||||
|
meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||||
|
} else {
|
||||||
|
// Save to SDCARD
|
||||||
|
this->packetHistory[0].time = getTime();
|
||||||
|
this->packetHistory[0].to = mp.to;
|
||||||
|
this->packetHistory[0].channel = mp.channel;
|
||||||
|
this->packetHistory[0].from = getFrom(&mp);
|
||||||
|
this->packetHistory[0].payload_size = p.payload.size;
|
||||||
|
memcpy(this->packetHistory[0].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||||
|
auto handler = SD.open("/storeforward/" + String(this->packetHistoryTotalCount), FILE_WRITE);
|
||||||
|
handler.write((uint8_t *)&this->packetHistory, sizeof(PacketHistoryStruct));
|
||||||
|
handler.close();
|
||||||
|
}
|
||||||
|
|
||||||
this->packetHistoryTotalCount++;
|
this->packetHistoryTotalCount++;
|
||||||
}
|
}
|
||||||
@ -233,6 +283,8 @@ bool StoreForwardModule::sendPayload(NodeNum dest, uint32_t last_time)
|
|||||||
meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t last_time, bool local)
|
meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t last_time, bool local)
|
||||||
{
|
{
|
||||||
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
||||||
|
if (this->storageType == StorageType::PSRAM) {
|
||||||
|
|
||||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||||
/* Copy the messages that were received by the server in the last msAgo
|
/* Copy the messages that were received by the server in the last msAgo
|
||||||
to the packetHistoryTXQueue structure.
|
to the packetHistoryTXQueue structure.
|
||||||
@ -275,6 +327,51 @@ meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
auto handler = SD.open("/storeforward/" + String(i), FILE_READ);
|
||||||
|
if (handler) {
|
||||||
|
handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct));
|
||||||
|
handler.close();
|
||||||
|
if (this->packetHistory[0].time && (this->packetHistory[0].time > last_time)) {
|
||||||
|
if (this->packetHistory[0].from != dest &&
|
||||||
|
(this->packetHistory[0].to == NODENUM_BROADCAST || this->packetHistory[0].to == dest)) {
|
||||||
|
|
||||||
|
meshtastic_MeshPacket *p = allocDataPacket();
|
||||||
|
|
||||||
|
p->to = local ? this->packetHistory[0].to : dest; // PhoneAPI can handle original `to`
|
||||||
|
p->from = this->packetHistory[0].from;
|
||||||
|
p->channel = this->packetHistory[0].channel;
|
||||||
|
p->rx_time = this->packetHistory[0].time;
|
||||||
|
|
||||||
|
// Let's assume that if the server received the S&F request that the client is in range.
|
||||||
|
p->want_ack = false;
|
||||||
|
|
||||||
|
if (local) { // PhoneAPI gets normal TEXT_MESSAGE_APP
|
||||||
|
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||||
|
memcpy(p->decoded.payload.bytes, this->packetHistory[0].payload, this->packetHistory[0].payload_size);
|
||||||
|
p->decoded.payload.size = this->packetHistory[0].payload_size;
|
||||||
|
} else {
|
||||||
|
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||||
|
sf.which_variant = meshtastic_StoreAndForward_text_tag;
|
||||||
|
sf.variant.text.size = this->packetHistory[0].payload_size;
|
||||||
|
memcpy(sf.variant.text.bytes, this->packetHistory[0].payload, this->packetHistory[0].payload_size);
|
||||||
|
if (this->packetHistory[0].to == NODENUM_BROADCAST) {
|
||||||
|
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_BROADCAST;
|
||||||
|
} else {
|
||||||
|
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_DIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->decoded.payload.size = pb_encode_to_bytes(
|
||||||
|
p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_StoreAndForward_msg, &sf);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastRequest[dest] = i + 1; // Update the last request index for the client device
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -377,7 +474,7 @@ void StoreForwardModule::statsSend(uint32_t to)
|
|||||||
*/
|
*/
|
||||||
ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &mp)
|
ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||||
{
|
{
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||||
if (moduleConfig.store_forward.enabled) {
|
if (moduleConfig.store_forward.enabled) {
|
||||||
|
|
||||||
if ((mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) && is_server) {
|
if ((mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) && is_server) {
|
||||||
@ -556,7 +653,7 @@ StoreForwardModule::StoreForwardModule()
|
|||||||
ProtobufModule("StoreForward", meshtastic_PortNum_STORE_FORWARD_APP, &meshtastic_StoreAndForward_msg)
|
ProtobufModule("StoreForward", meshtastic_PortNum_STORE_FORWARD_APP, &meshtastic_StoreAndForward_msg)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||||
|
|
||||||
isPromiscuous = true; // Brown chicken brown cow
|
isPromiscuous = true; // Brown chicken brown cow
|
||||||
|
|
||||||
@ -601,12 +698,17 @@ StoreForwardModule::StoreForwardModule()
|
|||||||
this->populatePSRAM();
|
this->populatePSRAM();
|
||||||
is_server = true;
|
is_server = true;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO(".");
|
|
||||||
LOG_INFO("S&F: not enough PSRAM free, disabling.");
|
LOG_INFO("S&F: not enough PSRAM free, disabling.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("S&F: device doesn't have PSRAM, disabling.");
|
LOG_INFO("S&F: device doesn't have PSRAM, disabling.");
|
||||||
}
|
}
|
||||||
|
#ifdef HAS_SDCARD
|
||||||
|
// If we have an SDCARD, format it for store&forward use
|
||||||
|
this->populateSDCard();
|
||||||
|
LOG_INFO("S&F: SDCARD initialized");
|
||||||
|
is_server = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Client
|
// Client
|
||||||
} else {
|
} else {
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#ifdef HAS_SDCARD
|
||||||
|
#include <SD.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct PacketHistoryStruct {
|
struct PacketHistoryStruct {
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
uint32_t to;
|
uint32_t to;
|
||||||
@ -18,6 +22,9 @@ struct PacketHistoryStruct {
|
|||||||
pb_size_t payload_size;
|
pb_size_t payload_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// enum for the storage type
|
||||||
|
enum StorageType { PSRAM, SDCARD };
|
||||||
|
|
||||||
class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<meshtastic_StoreAndForward>
|
class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<meshtastic_StoreAndForward>
|
||||||
{
|
{
|
||||||
bool busy = 0;
|
bool busy = 0;
|
||||||
@ -80,6 +87,10 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void populatePSRAM();
|
void populatePSRAM();
|
||||||
|
void populateSDCard();
|
||||||
|
|
||||||
|
// Storage Type
|
||||||
|
StorageType storageType = PSRAM;
|
||||||
|
|
||||||
// S&F Defaults
|
// S&F Defaults
|
||||||
uint32_t historyReturnMax = 25; // Return maximum of 25 records by default.
|
uint32_t historyReturnMax = 25; // Return maximum of 25 records by default.
|
||||||
|
Loading…
Reference in New Issue
Block a user