mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-08 22:22:05 +00:00
Merge branch 'master' into raspi-portduino
This commit is contained in:
commit
1e71d346ae
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@ -6,4 +6,4 @@
|
||||
"platformio.platformio-ide",
|
||||
"trunk.io"
|
||||
],
|
||||
}
|
||||
}
|
@ -5,7 +5,9 @@ extends = arduino_base
|
||||
|
||||
build_type = debug ; I'm debugging with ICE a lot now
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
${arduino_base.build_flags}
|
||||
-DSERIAL_BUFFER_SIZE=1024
|
||||
-Wno-unused-variable
|
||||
-Isrc/platform/nrf52
|
||||
|
||||
build_src_filter =
|
||||
|
@ -1,3 +1,13 @@
|
||||
/**
|
||||
* @file FSCommon.cpp
|
||||
* @brief This file contains functions for common filesystem operations such as copying, renaming, listing and deleting files and
|
||||
* directories.
|
||||
*
|
||||
* The functions in this file are used to perform common filesystem operations such as copying, renaming, listing and deleting
|
||||
* files and directories. These functions are used in the Meshtastic-device project to manage files and directories on the
|
||||
* device's filesystem.
|
||||
*
|
||||
*/
|
||||
#include "FSCommon.h"
|
||||
#include "configuration.h"
|
||||
|
||||
@ -14,6 +24,13 @@ SPIClass SPI1(HSPI);
|
||||
|
||||
#endif // HAS_SDCARD
|
||||
|
||||
/**
|
||||
* @brief Copies a file from one location to another.
|
||||
*
|
||||
* @param from The path of the source file.
|
||||
* @param to The path of the destination file.
|
||||
* @return true if the file was successfully copied, false otherwise.
|
||||
*/
|
||||
bool copyFile(const char *from, const char *to)
|
||||
{
|
||||
#ifdef FSCom
|
||||
@ -43,6 +60,14 @@ bool copyFile(const char *from, const char *to)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a file from pathFrom to pathTo.
|
||||
*
|
||||
* @param pathFrom The original path of the file.
|
||||
* @param pathTo The new path of the file.
|
||||
*
|
||||
* @return True if the file was successfully renamed, false otherwise.
|
||||
*/
|
||||
bool renameFile(const char *pathFrom, const char *pathTo)
|
||||
{
|
||||
#ifdef FSCom
|
||||
@ -59,6 +84,13 @@ bool renameFile(const char *pathFrom, const char *pathTo)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the contents of a directory.
|
||||
*
|
||||
* @param dirname The name of the directory to list.
|
||||
* @param levels The number of levels of subdirectories to list.
|
||||
* @param del Whether or not to delete the contents of the directory after listing.
|
||||
*/
|
||||
void listDir(const char *dirname, uint8_t levels, bool del = false)
|
||||
{
|
||||
#ifdef FSCom
|
||||
@ -154,6 +186,13 @@ void listDir(const char *dirname, uint8_t levels, bool del = false)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a directory and all its contents.
|
||||
*
|
||||
* This function recursively removes a directory and all its contents, including subdirectories and files.
|
||||
*
|
||||
* @param dirname The name of the directory to remove.
|
||||
*/
|
||||
void rmDir(const char *dirname)
|
||||
{
|
||||
#ifdef FSCom
|
||||
@ -182,6 +221,9 @@ void fsInit()
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the SD card and mounts the file system.
|
||||
*/
|
||||
void setupSDCard()
|
||||
{
|
||||
#ifdef HAS_SDCARD
|
||||
@ -212,4 +254,4 @@ void setupSDCard()
|
||||
LOG_DEBUG("Total space: %llu MB\n", SD.totalBytes() / (1024 * 1024));
|
||||
LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
|
||||
#endif
|
||||
}
|
||||
}
|
@ -29,6 +29,16 @@ static void IRAM_ATTR onTimer()
|
||||
(*tCallback)(tParam1, tParam2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a hardware callback function to be executed after a specified delay.
|
||||
*
|
||||
* @param callback The function to be executed.
|
||||
* @param param1 The first parameter to be passed to the function.
|
||||
* @param param2 The second parameter to be passed to the function.
|
||||
* @param delayMsec The delay time in milliseconds before the function is executed.
|
||||
*
|
||||
* @return True if the function was successfully scheduled, false otherwise.
|
||||
*/
|
||||
bool scheduleHWCallback(PendableFunction callback, void *param1, uint32_t param2, uint32_t delayMsec)
|
||||
{
|
||||
if (!timer) {
|
||||
|
@ -1,3 +1,15 @@
|
||||
/**
|
||||
* @file Power.cpp
|
||||
* @brief This file contains the implementation of the Power class, which is responsible for managing power-related functionality
|
||||
* of the device. It includes battery level sensing, power management unit (PMU) control, and power state machine management. The
|
||||
* Power class is used by the main device class to manage power-related functionality.
|
||||
*
|
||||
* The file also includes implementations of various battery level sensors, such as the AnalogBatteryLevel class, which assumes
|
||||
* the battery voltage is attached via a voltage-divider to an analog input.
|
||||
*
|
||||
* This file is part of the Meshtastic project.
|
||||
* For more information, see: https://meshtastic.org/
|
||||
*/
|
||||
#include "power.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
@ -366,6 +378,11 @@ bool Power::analogInit()
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Power class.
|
||||
*
|
||||
* @return true if the setup was successful, false otherwise.
|
||||
*/
|
||||
bool Power::setup()
|
||||
{
|
||||
bool found = axpChipInit();
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file PowerFSM.cpp
|
||||
* @brief Implements the finite state machine for power management.
|
||||
*
|
||||
* This file contains the implementation of the finite state machine (FSM) for power management.
|
||||
* The FSM controls the power states of the device, including SDS (shallow deep sleep), LS (light sleep),
|
||||
* NB (normal mode), and POWER (powered mode). The FSM also handles transitions between states and
|
||||
* actions to be taken upon entering or exiting each state.
|
||||
*/
|
||||
#include "PowerFSM.h"
|
||||
#include "GPS.h"
|
||||
#include "MeshService.h"
|
||||
|
@ -107,6 +107,14 @@ bool NMEAGPS::lookForLocation()
|
||||
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?)
|
||||
fixQual = reader.fixQuality();
|
||||
|
||||
#ifndef TINYGPS_OPTION_NO_STATISTICS
|
||||
if (reader.failedChecksum() > lastChecksumFailCount) {
|
||||
LOG_WARN("Warning, %u new GPS checksum failures, for a total of %u.\n", reader.failedChecksum() - lastChecksumFailCount,
|
||||
reader.failedChecksum());
|
||||
lastChecksumFailCount = reader.failedChecksum();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
fixType = atoi(gsafixtype.value()); // will set to zero if no data
|
||||
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
|
||||
@ -174,8 +182,10 @@ bool NMEAGPS::lookForLocation()
|
||||
#endif
|
||||
|
||||
// Discard incomplete or erroneous readings
|
||||
if (reader.hdop.value() == 0)
|
||||
if (reader.hdop.value() == 0) {
|
||||
LOG_WARN("BOGUS hdop.value() REJECTED: %d\n", reader.hdop.value());
|
||||
return false;
|
||||
}
|
||||
|
||||
p.latitude_i = toDegInt(loc.lat);
|
||||
p.longitude_i = toDegInt(loc.lng);
|
||||
@ -243,7 +253,8 @@ bool NMEAGPS::hasFlow()
|
||||
bool NMEAGPS::whileIdle()
|
||||
{
|
||||
bool isValid = false;
|
||||
|
||||
// if (_serial_gps->available() > 0)
|
||||
// LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available());
|
||||
// First consume any chars that have piled up at the receiver
|
||||
while (_serial_gps->available() > 0) {
|
||||
int c = _serial_gps->read();
|
||||
|
@ -13,6 +13,7 @@ class NMEAGPS : public GPS
|
||||
{
|
||||
TinyGPSPlus reader;
|
||||
uint8_t fixQual = 0; // fix quality from GPGGA
|
||||
uint32_t lastChecksumFailCount = 0;
|
||||
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
|
||||
@ -53,4 +54,4 @@ class NMEAGPS : public GPS
|
||||
virtual bool hasLock() override;
|
||||
|
||||
virtual bool hasFlow() override;
|
||||
};
|
||||
};
|
@ -17,6 +17,10 @@ static uint32_t
|
||||
timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time
|
||||
static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock
|
||||
|
||||
/**
|
||||
* Reads the current date and time from the RTC module and updates the system time.
|
||||
* @return True if the RTC was successfully read and the system time was updated, false otherwise.
|
||||
*/
|
||||
void readFromRTC()
|
||||
{
|
||||
struct timeval tv; /* btw settimeofday() is helpful here too*/
|
||||
@ -83,7 +87,15 @@ void readFromRTC()
|
||||
#endif
|
||||
}
|
||||
|
||||
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
||||
/**
|
||||
* Sets the RTC (Real-Time Clock) if the provided time is of higher quality than the current RTC time.
|
||||
*
|
||||
* @param q The quality of the provided time.
|
||||
* @param tv A pointer to a timeval struct containing the time to potentially set the RTC to.
|
||||
* @return True if the RTC was set, false otherwise.
|
||||
*
|
||||
* If we haven't yet set our RTC this boot, set it from a GPS derived time
|
||||
*/
|
||||
bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||
{
|
||||
static uint32_t lastSetMsec = 0;
|
||||
@ -151,6 +163,13 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RTC time if the provided time is of higher quality than the current RTC time.
|
||||
*
|
||||
* @param q The quality of the provided time.
|
||||
* @param t The time to potentially set the RTC to.
|
||||
* @return True if the RTC was set to the provided time, false otherwise.
|
||||
*/
|
||||
bool perhapsSetRTC(RTCQuality q, struct tm &t)
|
||||
{
|
||||
/* Convert to unix time
|
||||
@ -171,11 +190,22 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current time in seconds since the Unix epoch (January 1, 1970).
|
||||
*
|
||||
* @return The current time in seconds since the Unix epoch.
|
||||
*/
|
||||
uint32_t getTime()
|
||||
{
|
||||
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current time from the RTC if the quality of the time is at least minQuality.
|
||||
*
|
||||
* @param minQuality The minimum quality of the RTC time required for it to be considered valid.
|
||||
* @return The current time from the RTC if it meets the minimum quality requirement, or 0 if the time is not valid.
|
||||
*/
|
||||
uint32_t getValidTime(RTCQuality minQuality)
|
||||
{
|
||||
return (currentQuality >= minQuality) ? getTime() : 0;
|
||||
|
@ -103,7 +103,8 @@ static uint16_t displayWidth, displayHeight;
|
||||
#define SCREEN_WIDTH displayWidth
|
||||
#define SCREEN_HEIGHT displayHeight
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
||||
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
|
||||
@ -493,7 +494,8 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *no
|
||||
{
|
||||
char usersString[20];
|
||||
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
||||
#else
|
||||
display->drawFastImage(x, y, 8, 8, imgUser);
|
||||
@ -1527,7 +1529,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
#ifdef ARCH_ESP32
|
||||
if (millis() - storeForwardModule->lastHeartbeat >
|
||||
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgQuestionL1);
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
@ -1537,7 +1540,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
imgQuestion);
|
||||
#endif
|
||||
} else {
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
||||
imgSFL1);
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8,
|
||||
@ -1549,7 +1553,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgInfoL1);
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
|
@ -14,7 +14,8 @@ const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3
|
||||
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
||||
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
||||
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||
const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff};
|
||||
|
@ -1,8 +1,21 @@
|
||||
/**
|
||||
* @file memGet.cpp
|
||||
* @brief Implementation of MemGet class that provides functions to get memory information.
|
||||
*
|
||||
* This file contains the implementation of MemGet class that provides functions to get
|
||||
* information about free heap, heap size, free psram and psram size. The functions are
|
||||
* implemented for ESP32 and NRF52 architectures. If the platform does not have heap
|
||||
* management function implemented, the functions return UINT32_MAX or 0.
|
||||
*/
|
||||
#include "memGet.h"
|
||||
#include "configuration.h"
|
||||
|
||||
MemGet memGet;
|
||||
|
||||
/**
|
||||
* Returns the amount of free heap memory in bytes.
|
||||
* @return uint32_t The amount of free heap memory in bytes.
|
||||
*/
|
||||
uint32_t MemGet::getFreeHeap()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
@ -15,6 +28,10 @@ uint32_t MemGet::getFreeHeap()
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the heap memory in bytes.
|
||||
* @return uint32_t The size of the heap memory in bytes.
|
||||
*/
|
||||
uint32_t MemGet::getHeapSize()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
@ -27,6 +44,11 @@ uint32_t MemGet::getHeapSize()
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of free psram memory in bytes.
|
||||
*
|
||||
* @return The amount of free psram memory in bytes.
|
||||
*/
|
||||
uint32_t MemGet::getFreePsram()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
@ -36,6 +58,11 @@ uint32_t MemGet::getFreePsram()
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the PSRAM memory.
|
||||
*
|
||||
* @return uint32_t The size of the PSRAM memory.
|
||||
*/
|
||||
uint32_t MemGet::getPsramSize()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
@ -43,4 +70,4 @@ uint32_t MemGet::getPsramSize()
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
@ -82,8 +82,13 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
|
||||
powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping
|
||||
|
||||
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
|
||||
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getMeshNode(mp->from)->has_user &&
|
||||
nodeInfoModule) {
|
||||
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
||||
mp->decoded.portnum == meshtastic_PortNum_TELEMETRY_APP && mp->decoded.request_id > 0) {
|
||||
LOG_DEBUG(
|
||||
"Received telemetry response. Skip sending our NodeInfo because this potentially a Repeater which will ignore our "
|
||||
"request for its NodeInfo.\n");
|
||||
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getMeshNode(mp->from)->has_user &&
|
||||
nodeInfoModule) {
|
||||
LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel);
|
||||
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
|
||||
}
|
||||
|
@ -18,7 +18,9 @@
|
||||
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
|
@ -1,3 +1,18 @@
|
||||
/**
|
||||
* @file ExternalNotificationModule.cpp
|
||||
* @brief Implementation of the ExternalNotificationModule class.
|
||||
*
|
||||
* This file contains the implementation of the ExternalNotificationModule class, which is responsible for handling external
|
||||
* notifications such as vibration, buzzer, and LED lights. The class provides methods to turn on and off the external
|
||||
* notification outputs and to play ringtones using PWM buzzer. It also includes default configurations and a runOnce() method to
|
||||
* handle the module's behavior.
|
||||
*
|
||||
* Documentation:
|
||||
* https://meshtastic.org/docs/settings/moduleconfig/external-notification
|
||||
*
|
||||
* @author Jm Casler & Meshtastic Team
|
||||
* @date [Insert Date]
|
||||
*/
|
||||
#include "ExternalNotificationModule.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
@ -113,6 +128,11 @@ int32_t ExternalNotificationModule::runOnce()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the external notification on for the specified index.
|
||||
*
|
||||
* @param index The index of the external notification to turn on.
|
||||
*/
|
||||
void ExternalNotificationModule::setExternalOn(uint8_t index)
|
||||
{
|
||||
externalCurrentState[index] = 1;
|
||||
|
@ -92,6 +92,9 @@ void setupModules()
|
||||
#endif
|
||||
} else {
|
||||
adminModule = new AdminModule();
|
||||
#if HAS_TELEMETRY
|
||||
new DeviceTelemetryModule();
|
||||
#endif
|
||||
traceRouteModule = new TraceRouteModule();
|
||||
}
|
||||
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra
|
||||
|
@ -1,3 +1,13 @@
|
||||
/**
|
||||
* @file RangeTestModule.cpp
|
||||
* @brief Implementation of the RangeTestModule class and RangeTestModuleRadio class.
|
||||
*
|
||||
* As a sender, this module sends packets every n seconds with an incremented PacketID.
|
||||
* As a receiver, this module receives packets from multiple senders and saves them to the Filesystem.
|
||||
*
|
||||
* The RangeTestModule class is an OSThread that runs the module.
|
||||
* The RangeTestModuleRadio class handles sending and receiving packets.
|
||||
*/
|
||||
#include "RangeTestModule.h"
|
||||
#include "FSCommon.h"
|
||||
#include "MeshService.h"
|
||||
@ -10,11 +20,6 @@
|
||||
#include "gps/GeoCoord.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
/*
|
||||
As a sender, I can send packets every n seconds. These packets include an incremented PacketID.
|
||||
As a receiver, I can receive packets from multiple senders. These packets can be saved to the Filesystem.
|
||||
*/
|
||||
|
||||
RangeTestModule *rangeTestModule;
|
||||
RangeTestModuleRadio *rangeTestModuleRadio;
|
||||
|
||||
@ -97,6 +102,12 @@ int32_t RangeTestModule::runOnce()
|
||||
return disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a payload to a specified destination node.
|
||||
*
|
||||
* @param dest The destination node number.
|
||||
* @param wantReplies Whether or not to request replies from the destination node.
|
||||
*/
|
||||
void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
|
@ -86,7 +86,13 @@ SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
|
||||
}
|
||||
}
|
||||
|
||||
// For the serial2 port we can't really detect if any client is on the other side, so instead just look for recent messages
|
||||
/**
|
||||
* @brief Checks if the serial connection is established.
|
||||
*
|
||||
* @return true if the serial connection is established, false otherwise.
|
||||
*
|
||||
* For the serial2 port we can't really detect if any client is on the other side, so instead just look for recent messages
|
||||
*/
|
||||
bool SerialModule::checkIsConnected()
|
||||
{
|
||||
uint32_t now = millis();
|
||||
@ -191,6 +197,11 @@ int32_t SerialModule::runOnce()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new mesh packet for use as a reply to a received packet.
|
||||
*
|
||||
* @return A pointer to the newly allocated mesh packet.
|
||||
*/
|
||||
meshtastic_MeshPacket *SerialModuleRadio::allocReply()
|
||||
{
|
||||
auto reply = allocDataPacket(); // Allocate a packet for sending
|
||||
@ -198,6 +209,12 @@ meshtastic_MeshPacket *SerialModuleRadio::allocReply()
|
||||
return reply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a payload to a specified destination node.
|
||||
*
|
||||
* @param dest The destination node number.
|
||||
* @param wantReplies Whether or not to request replies from the destination node.
|
||||
*/
|
||||
void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
meshtastic_Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL;
|
||||
@ -216,6 +233,12 @@ void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
|
||||
service.sendToMesh(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a received mesh packet.
|
||||
*
|
||||
* @param mp The received mesh packet.
|
||||
* @return The processed message.
|
||||
*/
|
||||
ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
if (moduleConfig.serial.enabled) {
|
||||
@ -277,6 +300,11 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
|
||||
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the baud rate of the serial module from the module configuration.
|
||||
*
|
||||
* @return uint32_t The baud rate of the serial module.
|
||||
*/
|
||||
uint32_t SerialModule::getBaudRate()
|
||||
{
|
||||
if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) {
|
||||
|
@ -17,7 +17,8 @@ int32_t DeviceTelemetryModule::runOnce()
|
||||
uint32_t now = millis();
|
||||
if (((lastSentToMesh == 0) ||
|
||||
((now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval))) &&
|
||||
airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil()) {
|
||||
airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil() &&
|
||||
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||
sendTelemetry();
|
||||
lastSentToMesh = now;
|
||||
} else if (service.isToPhoneQueueEmpty()) {
|
||||
@ -30,6 +31,10 @@ int32_t DeviceTelemetryModule::runOnce()
|
||||
|
||||
bool DeviceTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
|
||||
{
|
||||
// Don't worry about storing telemetry in NodeDB if we're a repeater
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
|
||||
return false;
|
||||
|
||||
if (t->which_variant == meshtastic_Telemetry_device_metrics_tag) {
|
||||
#ifdef DEBUG_PORT
|
||||
const char *sender = getSenderShortName(mp);
|
||||
@ -43,7 +48,19 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &
|
||||
return false; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
meshtastic_MeshPacket *DeviceTelemetryModule::allocReply()
|
||||
{
|
||||
if (ignoreRequest) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOG_INFO("Device telemetry replying to request\n");
|
||||
|
||||
meshtastic_Telemetry telemetry = getDeviceTelemetry();
|
||||
return allocDataProtobuf(telemetry);
|
||||
}
|
||||
|
||||
meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry()
|
||||
{
|
||||
meshtastic_Telemetry t;
|
||||
|
||||
@ -60,16 +77,22 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
t.variant.device_metrics.channel_utilization = airTime->channelUtilizationPercent();
|
||||
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
|
||||
|
||||
LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
|
||||
t.variant.device_metrics.air_util_tx, t.variant.device_metrics.channel_utilization,
|
||||
t.variant.device_metrics.battery_level, t.variant.device_metrics.voltage);
|
||||
return t;
|
||||
}
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataProtobuf(t);
|
||||
bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
{
|
||||
meshtastic_Telemetry telemetry = getDeviceTelemetry();
|
||||
LOG_INFO("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
|
||||
telemetry.variant.device_metrics.air_util_tx, telemetry.variant.device_metrics.channel_utilization,
|
||||
telemetry.variant.device_metrics.battery_level, telemetry.variant.device_metrics.voltage);
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataProtobuf(telemetry);
|
||||
p->to = dest;
|
||||
p->decoded.want_response = false;
|
||||
p->priority = meshtastic_MeshPacket_Priority_MIN;
|
||||
|
||||
nodeDB.updateTelemetry(nodeDB.getNodeNum(), t, RX_SRC_LOCAL);
|
||||
nodeDB.updateTelemetry(nodeDB.getNodeNum(), telemetry, RX_SRC_LOCAL);
|
||||
if (phoneOnly) {
|
||||
LOG_INFO("Sending packet to phone\n");
|
||||
service.sendToPhone(p);
|
||||
|
@ -21,6 +21,7 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
|
||||
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
*/
|
||||
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *p) override;
|
||||
virtual meshtastic_MeshPacket *allocReply() override;
|
||||
virtual int32_t runOnce() override;
|
||||
/**
|
||||
* Send our Telemetry into the mesh
|
||||
@ -28,6 +29,7 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
|
||||
bool sendTelemetry(NodeNum dest = NODENUM_BROADCAST, bool phoneOnly = false);
|
||||
|
||||
private:
|
||||
meshtastic_Telemetry getDeviceTelemetry();
|
||||
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
|
||||
uint32_t lastSentToMesh = 0;
|
||||
};
|
||||
|
@ -31,7 +31,9 @@ SHT31Sensor sht31Sensor;
|
||||
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||
|
||||
#ifdef USE_EINK
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
|
@ -48,7 +48,9 @@ AudioModule *audioModule;
|
||||
#define YIELD_FROM_ISR(x) portYIELD_FROM_ISR(x)
|
||||
#endif
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
|
@ -1,3 +1,17 @@
|
||||
/**
|
||||
* @file StoreForwardModule.cpp
|
||||
* @brief Implementation of the StoreForwardModule class.
|
||||
*
|
||||
* This file contains the implementation of the StoreForwardModule class, which is responsible for managing the store and forward
|
||||
* functionality of the Meshtastic device. The class provides methods for sending and receiving messages, as well as managing the
|
||||
* message history queue. It also initializes and manages the data structures used for storing the message history.
|
||||
*
|
||||
* The StoreForwardModule class is used by the MeshService class to provide store and forward functionality to the Meshtastic
|
||||
* device.
|
||||
*
|
||||
* @author Jm Casler
|
||||
* @date [Insert Date]
|
||||
*/
|
||||
#include "StoreForwardModule.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
@ -52,9 +66,9 @@ int32_t StoreForwardModule::runOnce()
|
||||
return disable();
|
||||
}
|
||||
|
||||
/*
|
||||
Create our data structure in the PSRAM.
|
||||
*/
|
||||
/**
|
||||
* Populates the PSRAM with data to be sent later when a device is out of range.
|
||||
*/
|
||||
void StoreForwardModule::populatePSRAM()
|
||||
{
|
||||
/*
|
||||
@ -82,6 +96,12 @@ void StoreForwardModule::populatePSRAM()
|
||||
LOG_DEBUG("*** numberOfPackets for packetHistory - %u\n", numberOfPackets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages from the message history to the specified recipient.
|
||||
*
|
||||
* @param msAgo The number of milliseconds ago from which to start sending messages.
|
||||
* @param to The recipient ID to send the messages to.
|
||||
*/
|
||||
void StoreForwardModule::historySend(uint32_t msAgo, uint32_t to)
|
||||
{
|
||||
uint32_t queueSize = storeForwardModule->historyQueueCreate(msAgo, to);
|
||||
@ -101,6 +121,13 @@ void StoreForwardModule::historySend(uint32_t msAgo, uint32_t to)
|
||||
storeForwardModule->sendMessage(to, sf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new history queue with messages that were received within the specified time frame.
|
||||
*
|
||||
* @param msAgo The number of milliseconds ago to start the history queue.
|
||||
* @param to The maximum number of messages to include in the history queue.
|
||||
* @return The ID of the newly created history queue.
|
||||
*/
|
||||
uint32_t StoreForwardModule::historyQueueCreate(uint32_t msAgo, uint32_t to)
|
||||
{
|
||||
|
||||
@ -141,6 +168,11 @@ uint32_t StoreForwardModule::historyQueueCreate(uint32_t msAgo, uint32_t to)
|
||||
return this->packetHistoryTXQueue_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mesh packet to the history buffer for store-and-forward functionality.
|
||||
*
|
||||
* @param mp The mesh packet to add to the history buffer.
|
||||
*/
|
||||
void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
const auto &p = mp.decoded;
|
||||
@ -162,6 +194,12 @@ meshtastic_MeshPacket *StoreForwardModule::allocReply()
|
||||
return reply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a payload to a specified destination node using the store and forward mechanism.
|
||||
*
|
||||
* @param dest The destination node number.
|
||||
* @param packetHistory_index The index of the packet in the packet history buffer.
|
||||
*/
|
||||
void StoreForwardModule::sendPayload(NodeNum dest, uint32_t packetHistory_index)
|
||||
{
|
||||
LOG_INFO("*** Sending S&F Payload\n");
|
||||
@ -183,6 +221,12 @@ void StoreForwardModule::sendPayload(NodeNum dest, uint32_t packetHistory_index)
|
||||
service.sendToMesh(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to a specified destination node using the store and forward protocol.
|
||||
*
|
||||
* @param dest The destination node number.
|
||||
* @param payload The message payload to be sent.
|
||||
*/
|
||||
void StoreForwardModule::sendMessage(NodeNum dest, meshtastic_StoreAndForward &payload)
|
||||
{
|
||||
meshtastic_MeshPacket *p = allocDataProtobuf(payload);
|
||||
@ -203,6 +247,12 @@ void StoreForwardModule::sendMessage(NodeNum dest, meshtastic_StoreAndForward &p
|
||||
service.sendToMesh(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a store-and-forward message to the specified destination node.
|
||||
*
|
||||
* @param dest The destination node number.
|
||||
* @param rr The store-and-forward request/response message to send.
|
||||
*/
|
||||
void StoreForwardModule::sendMessage(NodeNum dest, meshtastic_StoreAndForward_RequestResponse rr)
|
||||
{
|
||||
// Craft an empty response, save some bytes in flash
|
||||
@ -211,6 +261,11 @@ void StoreForwardModule::sendMessage(NodeNum dest, meshtastic_StoreAndForward_Re
|
||||
storeForwardModule->sendMessage(dest, sf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends statistics about the store and forward module to the specified node.
|
||||
*
|
||||
* @param to The node ID to send the statistics to.
|
||||
*/
|
||||
void StoreForwardModule::statsSend(uint32_t to)
|
||||
{
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
@ -231,6 +286,12 @@ void StoreForwardModule::statsSend(uint32_t to)
|
||||
storeForwardModule->sendMessage(to, sf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a received mesh packet, potentially storing it for later forwarding.
|
||||
*
|
||||
* @param mp The received mesh packet.
|
||||
* @return A `ProcessMessage` indicating whether the packet was successfully handled.
|
||||
*/
|
||||
ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
@ -287,6 +348,13 @@ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &m
|
||||
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a received protobuf message for the Store and Forward module.
|
||||
*
|
||||
* @param mp The received MeshPacket to handle.
|
||||
* @param p A pointer to the StoreAndForward object.
|
||||
* @return True if the message was successfully handled, false otherwise.
|
||||
*/
|
||||
bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_StoreAndForward *p)
|
||||
{
|
||||
if (!moduleConfig.store_forward.enabled) {
|
||||
@ -488,4 +556,4 @@ StoreForwardModule::StoreForwardModule()
|
||||
disable();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,3 +1,21 @@
|
||||
/**
|
||||
* @file xmodem.cpp
|
||||
* @brief Implementation of XMODEM protocol for Meshtastic devices.
|
||||
*
|
||||
* This file contains the implementation of the XMODEM protocol for Meshtastic devices. It is based on the XMODEM implementation
|
||||
* by Georges Menie (www.menie.org) and has been adapted for protobuf encapsulation.
|
||||
*
|
||||
* The XMODEM protocol is used for reliable transmission of binary data over a serial connection. This implementation supports
|
||||
* both sending and receiving of data.
|
||||
*
|
||||
* The XModemAdapter class provides the main functionality for the protocol, including CRC calculation, packet handling, and
|
||||
* control signal sending.
|
||||
*
|
||||
* @copyright Copyright (c) 2001-2019 Georges Menie
|
||||
* @author
|
||||
* @author
|
||||
* @date
|
||||
*/
|
||||
/***********************************************************************************************************************
|
||||
* based on XMODEM implementation by Georges Menie (www.menie.org)
|
||||
***********************************************************************************************************************
|
||||
@ -36,6 +54,13 @@ XModemAdapter xModem;
|
||||
|
||||
XModemAdapter::XModemAdapter() {}
|
||||
|
||||
/**
|
||||
* Calculates the CRC-16 CCITT checksum of the given buffer.
|
||||
*
|
||||
* @param buffer The buffer to calculate the checksum for.
|
||||
* @param length The length of the buffer.
|
||||
* @return The calculated checksum.
|
||||
*/
|
||||
unsigned short XModemAdapter::crc16_ccitt(const pb_byte_t *buffer, int length)
|
||||
{
|
||||
unsigned short crc16 = 0;
|
||||
@ -52,6 +77,15 @@ unsigned short XModemAdapter::crc16_ccitt(const pb_byte_t *buffer, int length)
|
||||
return crc16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the checksum of the given buffer and compares it to the given
|
||||
* expected checksum. Returns 1 if the checksums match, 0 otherwise.
|
||||
*
|
||||
* @param buf The buffer to calculate the checksum of.
|
||||
* @param sz The size of the buffer.
|
||||
* @param tcrc The expected checksum.
|
||||
* @return 1 if the checksums match, 0 otherwise.
|
||||
*/
|
||||
int XModemAdapter::check(const pb_byte_t *buf, int sz, unsigned short tcrc)
|
||||
{
|
||||
return crc16_ccitt(buf, sz) == tcrc;
|
||||
@ -214,4 +248,4 @@ void XModemAdapter::handlePacket(meshtastic_XModem xmodemPacket)
|
||||
// Unknown control character
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
#define TFT_OFFSET_Y 0
|
||||
#define VTFT_CTRL 46 // Heltec Tracker needs this pulled low for TFT
|
||||
#define SCREEN_TRANSITION_FRAMERATE 1 // fps
|
||||
#define DISPLAY_FORCE_SMALL_FONTS
|
||||
|
||||
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
|
||||
#define BUTTON_PIN 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 2
|
||||
minor = 1
|
||||
build = 22
|
||||
build = 23
|
||||
|
Loading…
Reference in New Issue
Block a user