mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-07 21:52:05 +00:00
Merge 3fb4ab35f1
into 46c7d74760
This commit is contained in:
commit
658c196632
@ -23,11 +23,16 @@ SPIClass SPI_HSPI(HSPI);
|
||||
#else
|
||||
#define SDHandler SPI
|
||||
#endif
|
||||
|
||||
#elif defined(ARCH_NRF52)
|
||||
#if defined(SDCARD_USE_SPI1)
|
||||
#define SDHandler SPI1
|
||||
#elif defined(SDCARD_USE_SPI)
|
||||
#define SDHandler SPI
|
||||
#endif // NRF52 SPI or SPI1
|
||||
#endif // ESP32/NRF52
|
||||
#ifndef SD_SPI_FREQUENCY
|
||||
#define SD_SPI_FREQUENCY 4000000U
|
||||
#endif
|
||||
|
||||
#endif // HAS_SDCARD
|
||||
|
||||
/**
|
||||
@ -309,7 +314,13 @@ void setupSDCard()
|
||||
{
|
||||
#if defined(HAS_SDCARD) && !defined(SDCARD_USE_SOFT_SPI)
|
||||
concurrency::LockGuard g(spiLock);
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52))
|
||||
#if (defined(ARCH_ESP32))
|
||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||
#elif (defined(ARCH_NRF52))
|
||||
SDHandler.begin();
|
||||
#endif
|
||||
|
||||
if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) {
|
||||
LOG_DEBUG("No SD_MMC card detected");
|
||||
return;
|
||||
@ -319,20 +330,23 @@ void setupSDCard()
|
||||
LOG_DEBUG("No SD_MMC card attached");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("SD_MMC Card Type: ");
|
||||
if (cardType == CARD_MMC) {
|
||||
LOG_DEBUG("MMC");
|
||||
LOG_DEBUG("SD_MMC Card Type: MMC");
|
||||
} else if (cardType == CARD_SD) {
|
||||
LOG_DEBUG("SDSC");
|
||||
LOG_DEBUG("SD_MMC Card Type: SDSC");
|
||||
} else if (cardType == CARD_SDHC) {
|
||||
LOG_DEBUG("SDHC");
|
||||
LOG_DEBUG("SD_MMC Card Type: SDHC");
|
||||
} else {
|
||||
LOG_DEBUG("UNKNOWN");
|
||||
LOG_DEBUG("SD_MMC Card Type: UNKNOWN");
|
||||
}
|
||||
|
||||
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
|
||||
LOG_DEBUG("SD Card Size: %lu MB", (uint32_t)cardSize);
|
||||
LOG_DEBUG("Total space: %lu MB", (uint32_t)(SD.totalBytes() / (1024 * 1024)));
|
||||
LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024)));
|
||||
LOG_INFO("Now scanning free clusters on SD card, this may take some time...");
|
||||
delay(100); // let serial print the above statement properly
|
||||
LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024))); // This might take some time during boot
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
@ -49,6 +49,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#include "modules/TextMessageModule.h"
|
||||
#include "modules/WaypointModule.h"
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#endif
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
|
||||
@ -58,11 +61,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#include "esp_task_wdt.h"
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#endif
|
||||
|
||||
#if ARCH_PORTDUINO
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
@ -2495,9 +2496,9 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
display->setColor(WHITE);
|
||||
// Draw the channel name
|
||||
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
|
||||
if (moduleConfig.store_forward.enabled) {
|
||||
#ifdef ARCH_ESP32
|
||||
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
|
||||
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
@ -2524,6 +2525,9 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
imgSF);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
// No store and forward, show a exclamation mark
|
||||
if (false) {
|
||||
#endif
|
||||
} else {
|
||||
// TODO: Raspberry Pi supports more than just the one screen size
|
||||
|
@ -724,6 +724,8 @@ void setup()
|
||||
i2cScanner.reset();
|
||||
#endif
|
||||
|
||||
// initSPI() must have called at this point (must be before screen and lora)
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
setupSDCard();
|
||||
#endif
|
||||
@ -817,7 +819,6 @@ void setup()
|
||||
drv.setMode(DRV2605_MODE_INTTRIG);
|
||||
#endif
|
||||
|
||||
// Init our SPI controller (must be before screen and lora)
|
||||
#ifdef ARCH_RP2040
|
||||
#ifdef HW_SPI1_DEVICE
|
||||
SPI1.setSCK(LORA_SCK);
|
||||
|
@ -57,6 +57,8 @@ uint32_t MemGet::getFreePsram()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
return ESP.getFreePsram();
|
||||
#elif (defined(HAS_SDCARD) && defined(ARCH_ESP32))
|
||||
return SD.totalBytes() - SD.usedBytes();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
return 4194252;
|
||||
#else
|
||||
@ -73,6 +75,8 @@ uint32_t MemGet::getPsramSize()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
return ESP.getPsramSize();
|
||||
#elif (defined(HAS_SDCARD) && defined(ARCH_ESP32))
|
||||
return SD.totalBytes();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
return 4194252;
|
||||
#else
|
||||
|
@ -283,7 +283,6 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||
{
|
||||
perhapsDecode(p);
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
if (moduleConfig.store_forward.enabled && storeForwardModule->isServer() &&
|
||||
p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
||||
@ -291,7 +290,6 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||
fromNum++; // Notify observers for packet from radio
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (toPhoneQueue.numFree() == 0) {
|
||||
|
@ -13,11 +13,9 @@
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
#include "../platform/portduino/SimRadio.h"
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern Allocator<meshtastic_QueueStatus> &queueStatusPool;
|
||||
extern Allocator<meshtastic_MqttClientProxyMessage> &mqttClientProxyMessagePool;
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "meshUtils.h"
|
||||
#include "modules/NeighborInfoModule.h"
|
||||
// #if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
// #include "modules/StoreForwardModule.h"
|
||||
// #endif
|
||||
#include <ErriezCRC32.h>
|
||||
#include <algorithm>
|
||||
#include <pb_decode.h>
|
||||
@ -31,8 +34,6 @@
|
||||
#if HAS_WIFI
|
||||
#include "mesh/wifi/WiFiAPClient.h"
|
||||
#endif
|
||||
#include "SPILock.h"
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#include <Preferences.h>
|
||||
#include <esp_efuse.h>
|
||||
#include <esp_efuse_table.h>
|
||||
@ -41,8 +42,10 @@
|
||||
#include <soc/soc.h>
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "SPILock.h"
|
||||
#include "modules/StoreForwardModule.h"
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
|
@ -188,7 +188,7 @@ bool RF95Interface::init()
|
||||
#endif
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora->setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
|
||||
res = lora->setCRC(true);
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
startReceive(); // start receiving
|
||||
|
@ -69,7 +69,6 @@
|
||||
#if !MESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE
|
||||
#include "modules/GenericThreadModule.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
|
||||
#include "modules/esp32/AudioModule.h"
|
||||
@ -77,9 +76,6 @@
|
||||
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER
|
||||
#include "modules/esp32/PaxcounterModule.h"
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)
|
||||
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
||||
@ -233,7 +229,7 @@ void setupModules()
|
||||
paxcounterModule = new PaxcounterModule();
|
||||
#endif
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
storeForwardModule = new StoreForwardModule();
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@ StoreForwardModule *storeForwardModule;
|
||||
|
||||
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) {
|
||||
// Send out the message queue.
|
||||
if (this->busy) {
|
||||
@ -89,6 +89,32 @@ void StoreForwardModule::populatePSRAM()
|
||||
LOG_DEBUG("After PSRAM init: heap %d/%d PSRAM %d/%d", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(),
|
||||
memGet.getPsramSize());
|
||||
LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets);
|
||||
this->storageType = StorageType::ST_PSRAM;
|
||||
}
|
||||
|
||||
/**
|
||||
* if we have an SDCARD, format it for store&forward use
|
||||
*/
|
||||
void StoreForwardModule::populateSDCard()
|
||||
{
|
||||
#if defined(HAS_SDCARD)
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52))
|
||||
spiLock->lock();
|
||||
if (SD.cardType() != CARD_NONE) {
|
||||
if (!SD.exists("/storeforward")) {
|
||||
LOG_INFO("Creating StoreForward directory");
|
||||
SD.mkdir("/storeforward");
|
||||
}
|
||||
this->storageType = StorageType::ST_SDCARD;
|
||||
uint32_t numberOfPackets = (this->records ? this->records : (((SD.totalBytes() / 3) * 2) / sizeof(PacketHistoryStruct)));
|
||||
this->records = numberOfPackets;
|
||||
// only allocate space for one temp copy
|
||||
this->packetHistory = (PacketHistoryStruct *)malloc(sizeof(PacketHistoryStruct));
|
||||
LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets);
|
||||
}
|
||||
spiLock->unlock();
|
||||
#endif // ARCH_ESP32 || ARCH_NRF52
|
||||
#endif // HAS_SDCARD
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,14 +161,42 @@ uint32_t StoreForwardModule::getNumAvailablePackets(NodeNum dest, uint32_t last_
|
||||
lastRequest.emplace(dest, 0);
|
||||
}
|
||||
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
||||
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.
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
count++;
|
||||
if (this->storageType == StorageType::ST_PSRAM) {
|
||||
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.
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else if (this->storageType == StorageType::ST_SDCARD) {
|
||||
#if defined(HAS_SDCARD)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
spiLock->lock();
|
||||
auto handler = SD.open("/storeforward/" + String(i), FILE_READ);
|
||||
if (handler) {
|
||||
if (handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct)) !=
|
||||
sizeof(PacketHistoryStruct)) {
|
||||
LOG_ERROR("SD card reading error");
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
LOG_ERROR("S&F: Unknown storage type");
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -187,23 +241,47 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
|
||||
const auto &p = mp.decoded;
|
||||
|
||||
if (this->packetHistoryTotalCount == this->records) {
|
||||
LOG_WARN("S&F - PSRAM Full. Starting overwrite");
|
||||
LOG_WARN("S&F - Storage Full. Starting overwrite");
|
||||
this->packetHistoryTotalCount = 0;
|
||||
for (auto &i : lastRequest) {
|
||||
i.second = 0; // Clear the last request index for each client device
|
||||
}
|
||||
}
|
||||
|
||||
this->packetHistory[this->packetHistoryTotalCount].time = getTime();
|
||||
this->packetHistory[this->packetHistoryTotalCount].to = mp.to;
|
||||
this->packetHistory[this->packetHistoryTotalCount].channel = mp.channel;
|
||||
this->packetHistory[this->packetHistoryTotalCount].from = getFrom(&mp);
|
||||
this->packetHistory[this->packetHistoryTotalCount].id = mp.id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].reply_id = p.reply_id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].emoji = (bool)p.emoji;
|
||||
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
|
||||
if (this->storageType == StorageType::ST_PSRAM) {
|
||||
this->packetHistory[this->packetHistoryTotalCount].time = getTime();
|
||||
this->packetHistory[this->packetHistoryTotalCount].to = mp.to;
|
||||
this->packetHistory[this->packetHistoryTotalCount].channel = mp.channel;
|
||||
this->packetHistory[this->packetHistoryTotalCount].from = getFrom(&mp);
|
||||
this->packetHistory[this->packetHistoryTotalCount].id = mp.id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].reply_id = p.reply_id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].emoji = (bool)p.emoji;
|
||||
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes,
|
||||
meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
} else if (this->storageType == StorageType::ST_SDCARD) {
|
||||
// Save to SDCARD
|
||||
#if defined(HAS_SDCARD)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
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].id = mp.id;
|
||||
this->packetHistory[0].reply_id = p.reply_id;
|
||||
this->packetHistory[0].emoji = (bool)p.emoji;
|
||||
this->packetHistory[0].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[0].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
spiLock->lock();
|
||||
auto handler = SD.open("/storeforward/" + String(this->packetHistoryTotalCount), FILE_WRITE, true);
|
||||
handler.write((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct));
|
||||
handler.close();
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
LOG_ERROR("S&F: Unknown storage type");
|
||||
}
|
||||
this->packetHistoryTotalCount++;
|
||||
}
|
||||
|
||||
@ -236,50 +314,108 @@ bool StoreForwardModule::sendPayload(NodeNum dest, uint32_t last_time)
|
||||
meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t last_time, bool local)
|
||||
{
|
||||
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||
/* Copy the messages that were received by the server in the last msAgo
|
||||
to the packetHistoryTXQueue structure.
|
||||
Client not interested in packets from itself and only in broadcast packets or packets towards it. */
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
if (this->storageType == StorageType::ST_PSRAM) {
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||
/* Copy the messages that were received by the server in the last msAgo
|
||||
to the packetHistoryTXQueue structure.
|
||||
Client not interested in packets from itself and only in broadcast packets or packets towards it. */
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
|
||||
p->to = local ? this->packetHistory[i].to : dest; // PhoneAPI can handle original `to`
|
||||
p->from = this->packetHistory[i].from;
|
||||
p->id = this->packetHistory[i].id;
|
||||
p->channel = this->packetHistory[i].channel;
|
||||
p->decoded.reply_id = this->packetHistory[i].reply_id;
|
||||
p->rx_time = this->packetHistory[i].time;
|
||||
p->decoded.emoji = (uint32_t)this->packetHistory[i].emoji;
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
|
||||
// Let's assume that if the server received the S&F request that the client is in range.
|
||||
// TODO: Make this configurable.
|
||||
p->want_ack = false;
|
||||
p->to = local ? this->packetHistory[i].to : dest; // PhoneAPI can handle original `to`
|
||||
p->from = this->packetHistory[i].from;
|
||||
p->id = this->packetHistory[i].id;
|
||||
p->channel = this->packetHistory[i].channel;
|
||||
p->decoded.reply_id = this->packetHistory[i].reply_id;
|
||||
p->rx_time = this->packetHistory[i].time;
|
||||
p->decoded.emoji = (uint32_t)this->packetHistory[i].emoji;
|
||||
|
||||
// Let's assume that if the server received the S&F request that the client is in range.
|
||||
// TODO: Make this configurable.
|
||||
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[i].payload, this->packetHistory[i].payload_size);
|
||||
p->decoded.payload.size = this->packetHistory[i].payload_size;
|
||||
|
||||
if (local) { // PhoneAPI gets normal TEXT_MESSAGE_APP
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
memcpy(p->decoded.payload.bytes, this->packetHistory[i].payload, this->packetHistory[i].payload_size);
|
||||
p->decoded.payload.size = this->packetHistory[i].payload_size;
|
||||
} else {
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.which_variant = meshtastic_StoreAndForward_text_tag;
|
||||
sf.variant.text.size = this->packetHistory[i].payload_size;
|
||||
memcpy(sf.variant.text.bytes, this->packetHistory[i].payload, this->packetHistory[i].payload_size);
|
||||
if (this->packetHistory[i].to == NODENUM_BROADCAST) {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_BROADCAST;
|
||||
} else {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_DIRECT;
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.which_variant = meshtastic_StoreAndForward_text_tag;
|
||||
sf.variant.text.size = this->packetHistory[i].payload_size;
|
||||
memcpy(sf.variant.text.bytes, this->packetHistory[i].payload, this->packetHistory[i].payload_size);
|
||||
if (this->packetHistory[i].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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
lastRequest[dest] = i + 1; // Update the last request index for the client device
|
||||
|
||||
return p;
|
||||
}
|
||||
} else if (this->storageType == StorageType::ST_SDCARD) {
|
||||
#if defined(HAS_SDCARD)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
spiLock->lock();
|
||||
auto handler = SD.open("/storeforward/" + String(i), FILE_READ);
|
||||
if (handler) {
|
||||
handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct));
|
||||
handler.close();
|
||||
spiLock->unlock();
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
spiLock->unlock();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
LOG_ERROR("S&F: Unknown storage type");
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@ -383,7 +519,7 @@ void StoreForwardModule::statsSend(uint32_t to)
|
||||
*/
|
||||
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 ((mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) && is_server) {
|
||||
@ -562,7 +698,7 @@ StoreForwardModule::StoreForwardModule()
|
||||
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
|
||||
|
||||
@ -613,7 +749,14 @@ StoreForwardModule::StoreForwardModule()
|
||||
} else {
|
||||
LOG_INFO("S&F: device doesn't have PSRAM, Disable");
|
||||
}
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
// If we have an SDCARD, format it for store&forward use
|
||||
if (SD.cardType() != CARD_NONE) {
|
||||
this->populateSDCard();
|
||||
LOG_INFO("S&F: SDCARD initialized");
|
||||
is_server = true;
|
||||
}
|
||||
#endif
|
||||
// Client
|
||||
} else {
|
||||
is_client = true;
|
||||
|
@ -9,6 +9,11 @@
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
#include "SPILock.h"
|
||||
#include <SD.h>
|
||||
#endif
|
||||
|
||||
struct PacketHistoryStruct {
|
||||
uint32_t time;
|
||||
uint32_t to;
|
||||
@ -21,6 +26,9 @@ struct PacketHistoryStruct {
|
||||
pb_size_t payload_size;
|
||||
};
|
||||
|
||||
// enum for the storage type
|
||||
enum StorageType { ST_PSRAM, ST_SDCARD };
|
||||
|
||||
class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<meshtastic_StoreAndForward>
|
||||
{
|
||||
bool busy = 0;
|
||||
@ -83,6 +91,10 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
||||
|
||||
private:
|
||||
void populatePSRAM();
|
||||
void populateSDCard();
|
||||
|
||||
// Storage Type
|
||||
StorageType storageType = ST_PSRAM;
|
||||
|
||||
// S&F Defaults
|
||||
uint32_t historyReturnMax = 25; // Return maximum of 25 records by default.
|
||||
|
@ -61,7 +61,9 @@ class XModemAdapter
|
||||
|
||||
uint16_t packetno = 0;
|
||||
|
||||
#if defined(ARCH_NRF52) || defined(ARCH_STM32WL)
|
||||
#if defined(ARCH_NRF52)
|
||||
Adafruit_LittleFS_Namespace::File file = Adafruit_LittleFS_Namespace::File(FSCom);
|
||||
#elif defined(ARCH_STM32WL)
|
||||
File file = File(FSCom);
|
||||
#else
|
||||
File file;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
// SD card - TODO: test, currently untested, copied from T3S3 variant
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
// TODO: rename this to make this SD-card specific
|
||||
#define SPI_CS 13
|
||||
#define SPI_SCK 14
|
||||
|
@ -5,7 +5,7 @@
|
||||
// #define HAS_SCREEN 0
|
||||
|
||||
// #define HAS_SDCARD
|
||||
// #define SDCARD_USE_SPI1
|
||||
// #define SDCARD_USE_HSPI
|
||||
|
||||
#define USE_SSD1306
|
||||
#define I2C_SDA 12
|
||||
|
@ -70,7 +70,7 @@
|
||||
#endif
|
||||
|
||||
#define HAS_SDCARD // Have SPI interface SD card slot
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
#define LORA_RESET 3
|
||||
#define LORA_SCK 12
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// #define HAS_SCREEN 0
|
||||
// #define HAS_SDCARD
|
||||
// #define SDCARD_USE_SPI1
|
||||
// #define SDCARD_USE_HSPI
|
||||
|
||||
// #define USE_SSD1306
|
||||
|
||||
|
@ -19,6 +19,8 @@ lib_deps =
|
||||
https://github.com/RAKWireless/RAK13800-W5100S/archive/1.0.2.zip
|
||||
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
|
||||
https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip
|
||||
https://github.com/Woutvstk/SdFat_wrapper25.git#6f8f48d56c15cbeac753560dfeede4a487f81f4c
|
||||
|
||||
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
|
||||
|
@ -108,11 +108,14 @@ static const uint8_t AREF = PIN_AREF;
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 2
|
||||
#define SPI_32MHZ_INTERFACE 0 // 0: use SPIM3 for SPI and SPIM2 for SPI1; 1: the opposite
|
||||
|
||||
// SPI pins for SX1262
|
||||
#define PIN_SPI_MISO (45)
|
||||
#define PIN_SPI_MOSI (44)
|
||||
#define PIN_SPI_SCK (43)
|
||||
|
||||
// SPI1 pins for external(rak4630) spi (incl. SDCard)
|
||||
#define PIN_SPI1_MISO (29) // (0 + 29)
|
||||
#define PIN_SPI1_MOSI (30) // (0 + 30)
|
||||
#define PIN_SPI1_SCK (3) // (0 + 3)
|
||||
@ -122,6 +125,19 @@ static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
// SD card SPI pin definitions
|
||||
|
||||
#define HAS_SDCARD 1
|
||||
#define SDCARD_USE_SPI1 1
|
||||
|
||||
#define SDCARD_CS (26)
|
||||
|
||||
// Some settings for the SdFat library to optimize flash usage
|
||||
#define SDFAT_FILE_TYPE 1 // only support FAT16/FAT32, not exFAT
|
||||
#define CHECK_FLASH_PROGRAMMING \
|
||||
0 // this reduces flash usage but may cause higher power usage when sd card is idle TODO:Check if power usage is higher
|
||||
#define MAINTAIN_FREE_CLUSTER_COUNT 1 // maintain free cluster count
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
|
@ -58,7 +58,7 @@
|
||||
#define GPS_1PPS_PIN 6
|
||||
|
||||
#define HAS_SDCARD // Have SPI interface SD card slot
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
// PCF8563 RTC Module
|
||||
// #define PCF8563_RTC 0x51 //Putting definitions in variant. h does not compile correctly
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
// Display (E-Ink)
|
||||
#define PIN_EINK_CS 15
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
#define USE_SSD1306
|
||||
|
||||
@ -76,4 +76,4 @@
|
||||
#endif
|
||||
|
||||
#define HAS_SDCARD // Have SPI interface SD card slot
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
@ -3,6 +3,11 @@ extends = esp32_base
|
||||
board = ttgo-lora32-v21
|
||||
board_check = true
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TLORA_V2_1_16 -I variants/tlora_v2_1_16
|
||||
${esp32_base.build_flags}
|
||||
-D TLORA_V2_1_16
|
||||
-I variants/tlora_v2_1_16
|
||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
upload_speed = 115200
|
||||
-DRADIOLIB_EXCLUDE_SX128X=1
|
||||
-DRADIOLIB_EXCLUDE_SX126X=1
|
||||
-DRADIOLIB_EXCLUDE_LR11X0=1
|
||||
upload_speed = 115200
|
||||
|
@ -22,4 +22,15 @@
|
||||
#define LORA_DIO1 33 // https://www.thethingsnetwork.org/forum/t/big-esp32-sx127x-topic-part-3/18436
|
||||
#endif
|
||||
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
|
||||
/*
|
||||
* Use SD Card for Store and Forward
|
||||
*/
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_HSPI
|
||||
#define SPI_MOSI 15
|
||||
#define SPI_MISO 2
|
||||
#define SPI_SCK 14
|
||||
#define SPI_CS 13
|
||||
#define SDCARD_CS SPI_CS
|
@ -51,6 +51,9 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
|
||||
// #define HAS_SDCARD 1 // causes hang if defined
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
#define SD_SPI_FREQUENCY 25000000
|
||||
#define SDCARD_CS 43
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user