Remove dead code (#11082)
Removed: - MessageStore::addFromPacket and addFromString, superseded by tryAddFromPacket - GeoCoord rangeRadiansToMeters, distanceTo, bearingTo - Router::rawSend, declared virtual with no override and no caller - ContentHandler handleHotspot, handleFs, handleAdminSettings, handleAdminSettingsApply, handleDeleteFsContent and their commented route registrations, plus the now unreachable htmlDeleteDir and the handleUpdateFs declaration that had no definition - ContentHelper replaceAll - OnScreenKeyboardModule popup chain: showPopup, clearPopup, drawPopup, drawPopupOverlay and their state, unreachable since the frame based UI was replaced by baseUI - DebugRenderer drawDebugInfoTrampoline, drawDebugInfoSettingsTrampoline and the orphaned drawFrameSettings - NodeListRenderer calculateMaxScroll, drawColumns and a stale extern haveGlyphs declaration with no definition - UIRenderer::haveGlyphs, Screen::blink, NotificationRenderer::showKeyboardMessagePopupWithTitle, VirtualKeyboard::getInputText - InkHUD touchNavLeft, touchNavRight, Applet::getActiveNodeCount, ThreadedMessageApplet::saveMessagesToFlash - TwoButton::setHandlerUp, TwoButtonExtended setHandlerUp, setJoystickDownHandlers, setJoystickUpHandlers - CannedMessageModule LaunchRepeatDestination, isCharInputAllowed, hasMessages - TrafficManagementModule resetStats, recordRouterHopPreserved, saturatingIncrement - UnitConversions::MetersPerSecondToMilesPerHour - EncryptedStorage getSessionRemainingSeconds - BMI270Sensor::writeRegisters, GPS::hasFlow, FSCommon copyFile, SerialConsole consolePrintf, buzz playLongPressLeadUp, memGet displayPercentHeapFree
This commit is contained in:
@@ -30,44 +30,6 @@ SPIClass SPI_HSPI(HSPI);
|
|||||||
|
|
||||||
#endif // HAS_SDCARD
|
#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
|
|
||||||
// take SPI Lock
|
|
||||||
concurrency::LockGuard g(spiLock);
|
|
||||||
unsigned char cbuffer[16];
|
|
||||||
|
|
||||||
File f1 = FSCom.open(from, FILE_O_READ);
|
|
||||||
if (!f1) {
|
|
||||||
LOG_ERROR("Failed to open source file %s", from);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
File f2 = FSCom.open(to, FILE_O_WRITE);
|
|
||||||
if (!f2) {
|
|
||||||
LOG_ERROR("Failed to open destination file %s", to);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (f1.available() > 0) {
|
|
||||||
byte i = f1.read(cbuffer, 16);
|
|
||||||
f2.write(cbuffer, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
f2.flush();
|
|
||||||
f2.close();
|
|
||||||
f1.close();
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renames a file from pathFrom to pathTo.
|
* Renames a file from pathFrom to pathTo.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ using namespace Adafruit_LittleFS_Namespace;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void fsInit();
|
void fsInit();
|
||||||
bool copyFile(const char *from, const char *to);
|
|
||||||
bool renameFile(const char *pathFrom, const char *pathTo);
|
bool renameFile(const char *pathFrom, const char *pathTo);
|
||||||
bool fsFormat();
|
bool fsFormat();
|
||||||
std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels, size_t maxCount = 64, bool *wasLimited = nullptr);
|
std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels, size_t maxCount = 64, bool *wasLimited = nullptr);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "SafeFile.h"
|
#include "SafeFile.h"
|
||||||
#include "gps/RTC.h"
|
#include "gps/RTC.h"
|
||||||
#include "memory/MemAudit.h"
|
#include "memory/MemAudit.h"
|
||||||
#include <cassert>
|
|
||||||
#include <cstring> // memcpy
|
#include <cstring> // memcpy
|
||||||
|
|
||||||
#ifndef MESSAGE_TEXT_POOL_SIZE
|
#ifndef MESSAGE_TEXT_POOL_SIZE
|
||||||
@@ -244,40 +243,6 @@ const StoredMessage *MessageStore::tryAddFromPacket(const meshtastic_MeshPacket
|
|||||||
return &liveMessages.back();
|
return &liveMessages.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
const StoredMessage &MessageStore::addFromPacket(const meshtastic_MeshPacket &packet)
|
|
||||||
{
|
|
||||||
const StoredMessage *stored = tryAddFromPacket(packet);
|
|
||||||
assert(stored);
|
|
||||||
return *stored;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outgoing/manual message
|
|
||||||
void MessageStore::addFromString(uint32_t sender, uint8_t channelIndex, const std::string &text)
|
|
||||||
{
|
|
||||||
StoredMessage sm;
|
|
||||||
|
|
||||||
// Always use our local time (helper handles RTC vs boot time)
|
|
||||||
assignTimestamp(sm);
|
|
||||||
|
|
||||||
sm.sender = sender;
|
|
||||||
sm.channelIndex = channelIndex;
|
|
||||||
sm.textOffset = storeTextInPool(text.c_str(), text.size());
|
|
||||||
sm.textLength = text.size();
|
|
||||||
|
|
||||||
// Use the provided destination
|
|
||||||
sm.dest = sender;
|
|
||||||
sm.type = MessageType::DM_TO_US;
|
|
||||||
|
|
||||||
// Outgoing messages always start with unknown ack status
|
|
||||||
sm.ackStatus = AckStatus::NONE;
|
|
||||||
|
|
||||||
addLiveMessage(sm);
|
|
||||||
|
|
||||||
#if ENABLE_MESSAGE_PERSISTENCE
|
|
||||||
markMessageStoreUnsaved();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLE_MESSAGE_PERSISTENCE
|
#if ENABLE_MESSAGE_PERSISTENCE
|
||||||
|
|
||||||
// Compact, fixed-size on-flash representation using offset + length
|
// Compact, fixed-size on-flash representation using offset + length
|
||||||
|
|||||||
+1
-3
@@ -93,10 +93,8 @@ class MessageStore
|
|||||||
void addLiveMessage(StoredMessage &&msg);
|
void addLiveMessage(StoredMessage &&msg);
|
||||||
void addLiveMessage(const StoredMessage &msg); // convenience overload
|
void addLiveMessage(const StoredMessage &msg); // convenience overload
|
||||||
const std::deque<StoredMessage> &getLiveMessages() const { return liveMessages; }
|
const std::deque<StoredMessage> &getLiveMessages() const { return liveMessages; }
|
||||||
|
// Add new messages from packets. Returns nullptr if the packet is filtered out.
|
||||||
const StoredMessage *tryAddFromPacket(const meshtastic_MeshPacket &mp); // Incoming/outgoing -> RAM only
|
const StoredMessage *tryAddFromPacket(const meshtastic_MeshPacket &mp); // Incoming/outgoing -> RAM only
|
||||||
// Add new messages from packets or manual input
|
|
||||||
const StoredMessage &addFromPacket(const meshtastic_MeshPacket &mp); // Incoming/outgoing → RAM only
|
|
||||||
void addFromString(uint32_t sender, uint8_t channelIndex, const std::string &text); // Manual add
|
|
||||||
|
|
||||||
// Persistence methods (used only on boot/shutdown)
|
// Persistence methods (used only on boot/shutdown)
|
||||||
void saveToFlash(); // Save messages to flash
|
void saveToFlash(); // Save messages to flash
|
||||||
|
|||||||
@@ -57,16 +57,6 @@ void consoleInit()
|
|||||||
DEBUG_PORT.rpInit(); // Simply sets up semaphore
|
DEBUG_PORT.rpInit(); // Simply sets up semaphore
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print and flush an unclassified formatted console message.
|
|
||||||
void consolePrintf(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list arg;
|
|
||||||
va_start(arg, format);
|
|
||||||
console->vprintf(nullptr, format, arg);
|
|
||||||
va_end(arg);
|
|
||||||
console->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialize console, protobuf transport, serial port, and worker thread state.
|
/// Initialize console, protobuf transport, serial port, and worker thread state.
|
||||||
SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), concurrency::OSThread("SerialConsole")
|
SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), concurrency::OSThread("SerialConsole")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ class SerialConsole : public StreamAPI, public RedirectablePrint, private concur
|
|||||||
};
|
};
|
||||||
|
|
||||||
// A simple wrapper to allow non class aware code write to the console
|
// A simple wrapper to allow non class aware code write to the console
|
||||||
void consolePrintf(const char *format, ...);
|
|
||||||
void consoleInit();
|
void consoleInit();
|
||||||
|
|
||||||
extern SerialConsole *console;
|
extern SerialConsole *console;
|
||||||
@@ -194,18 +194,6 @@ void playBoop()
|
|||||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||||
}
|
}
|
||||||
|
|
||||||
void playLongPressLeadUp()
|
|
||||||
{
|
|
||||||
// An ascending lead-up sequence for long press - builds anticipation
|
|
||||||
ToneDuration melody[] = {
|
|
||||||
{NOTE_C3, 100}, // Start low
|
|
||||||
{NOTE_E3, 100}, // Step up
|
|
||||||
{NOTE_G3, 100}, // Keep climbing
|
|
||||||
{NOTE_B3, 150} // Peak with longer note for emphasis
|
|
||||||
};
|
|
||||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static state for progressive lead-up notes
|
// Static state for progressive lead-up notes
|
||||||
static int leadUpNoteIndex = 0;
|
static int leadUpNoteIndex = 0;
|
||||||
static const ToneDuration leadUpNotes[] = {
|
static const ToneDuration leadUpNotes[] = {
|
||||||
|
|||||||
@@ -12,6 +12,5 @@ void play4ClickUp();
|
|||||||
void playBoop();
|
void playBoop();
|
||||||
void playChirp();
|
void playChirp();
|
||||||
void playClick();
|
void playClick();
|
||||||
void playLongPressLeadUp();
|
|
||||||
bool playNextLeadUpNote(); // Play the next note in the lead-up sequence
|
bool playNextLeadUpNote(); // Play the next note in the lead-up sequence
|
||||||
void resetLeadUpSequence(); // Reset the lead-up sequence to start from beginning
|
void resetLeadUpSequence(); // Reset the lead-up sequence to start from beginning
|
||||||
@@ -2201,11 +2201,6 @@ bool GPS::hasLock()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPS::hasFlow()
|
|
||||||
{
|
|
||||||
return reader.passedChecksum() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GPS::whileActive()
|
bool GPS::whileActive()
|
||||||
{
|
{
|
||||||
unsigned int charsInBuf = 0;
|
unsigned int charsInBuf = 0;
|
||||||
|
|||||||
@@ -111,9 +111,6 @@ class GPS : private concurrency::OSThread
|
|||||||
/// Returns true if we have acquired GPS lock.
|
/// Returns true if we have acquired GPS lock.
|
||||||
virtual bool hasLock();
|
virtual bool hasLock();
|
||||||
|
|
||||||
/// Returns true if there's valid data flow with the chip.
|
|
||||||
virtual bool hasFlow();
|
|
||||||
|
|
||||||
/// Return true if we are connected to a GPS
|
/// Return true if we are connected to a GPS
|
||||||
bool isConnected() const { return hasGPS; }
|
bool isConnected() const { return hasGPS; }
|
||||||
|
|
||||||
|
|||||||
@@ -496,34 +496,6 @@ float GeoCoord::rangeMetersToRadians(double range_meters)
|
|||||||
return (PI / (180 * 60)) * distance_nm;
|
return (PI / (180 * 60)) * distance_nm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Ported from http://www.edwilliams.org/avform147.htm#Intro
|
|
||||||
* @brief Convert from radians to range in meters on a great circle
|
|
||||||
* @param range_radians
|
|
||||||
* The range in radians
|
|
||||||
* @return Range in meters on a great circle
|
|
||||||
*/
|
|
||||||
float GeoCoord::rangeRadiansToMeters(double range_radians)
|
|
||||||
{
|
|
||||||
double distance_nm = ((180 * 60) / PI) * range_radians;
|
|
||||||
// 1 meter is 0.000539957 nm
|
|
||||||
return distance_nm * 0.000539957;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find distance from point to passed in point
|
|
||||||
int32_t GeoCoord::distanceTo(const GeoCoord &pointB)
|
|
||||||
{
|
|
||||||
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
|
|
||||||
pointB.getLongitude() * 1e-7);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find bearing from point to passed in point
|
|
||||||
int32_t GeoCoord::bearingTo(const GeoCoord &pointB)
|
|
||||||
{
|
|
||||||
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
|
|
||||||
pointB.getLongitude() * 1e-7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new point based on the passed-in point
|
* Create a new point based on the passed-in point
|
||||||
* Ported from http://www.edwilliams.org/avform147.htm#LL
|
* Ported from http://www.edwilliams.org/avform147.htm#LL
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ class GeoCoord
|
|||||||
static void convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude);
|
static void convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude);
|
||||||
static float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b);
|
static float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b);
|
||||||
static float bearing(double lat1, double lon1, double lat2, double lon2);
|
static float bearing(double lat1, double lon1, double lat2, double lon2);
|
||||||
static float rangeRadiansToMeters(double range_radians);
|
|
||||||
static float rangeMetersToRadians(double range_meters);
|
static float rangeMetersToRadians(double range_meters);
|
||||||
static unsigned int bearingToDegrees(const char *bearing);
|
static unsigned int bearingToDegrees(const char *bearing);
|
||||||
static const char *degreesToBearing(unsigned int degrees);
|
static const char *degreesToBearing(unsigned int degrees);
|
||||||
@@ -114,8 +113,6 @@ class GeoCoord
|
|||||||
static double toDegrees(double r);
|
static double toDegrees(double r);
|
||||||
|
|
||||||
// Point to point conversions
|
// Point to point conversions
|
||||||
int32_t distanceTo(const GeoCoord &pointB);
|
|
||||||
int32_t bearingTo(const GeoCoord &pointB);
|
|
||||||
std::shared_ptr<GeoCoord> pointAtDistance(double bearing, double range);
|
std::shared_ptr<GeoCoord> pointAtDistance(double bearing, double range);
|
||||||
|
|
||||||
// Lat lon alt getters
|
// Lat lon alt getters
|
||||||
|
|||||||
@@ -1846,40 +1846,6 @@ void Screen::handleStartFirmwareUpdateScreen()
|
|||||||
setFrameImmediateDraw(frames);
|
setFrameImmediateDraw(frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::blink()
|
|
||||||
{
|
|
||||||
#ifdef MESHTASTIC_LOCKDOWN
|
|
||||||
// L4: defensive guard. blink() paints arbitrary geometry, not node
|
|
||||||
// data, so it doesn't actually leak today. But it bypasses the normal
|
|
||||||
// ui->update() path that the lockdown short-circuit gates, so any
|
|
||||||
// future change that puts content into blink would silently leak past
|
|
||||||
// redaction. Refuse to draw when the redaction latch is set.
|
|
||||||
if (meshtastic_security::shouldRedactDisplay())
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
setFastFramerate();
|
|
||||||
uint8_t count = 10;
|
|
||||||
dispdev->setBrightness(254);
|
|
||||||
while (count > 0) {
|
|
||||||
dispdev->fillRect(0, 0, dispdev->getWidth(), dispdev->getHeight());
|
|
||||||
#if GRAPHICS_TFT_COLORING_ENABLED
|
|
||||||
prepareFrameColorRegions();
|
|
||||||
#endif
|
|
||||||
dispdev->display();
|
|
||||||
delay(50);
|
|
||||||
dispdev->clear();
|
|
||||||
#if GRAPHICS_TFT_COLORING_ENABLED
|
|
||||||
prepareFrameColorRegions();
|
|
||||||
#endif
|
|
||||||
dispdev->display();
|
|
||||||
delay(50);
|
|
||||||
count = count - 1;
|
|
||||||
}
|
|
||||||
// The dispdev->setBrightness does not work for t-deck display, it seems to run the setBrightness function in
|
|
||||||
// OLEDDisplay.
|
|
||||||
dispdev->setBrightness(brightness);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Screen::increaseBrightness()
|
void Screen::increaseBrightness()
|
||||||
{
|
{
|
||||||
brightness = ((brightness + 62) > 254) ? brightness : (brightness + 62);
|
brightness = ((brightness + 62) > 254) ? brightness : (brightness + 62);
|
||||||
|
|||||||
@@ -310,8 +310,6 @@ class Screen : public concurrency::OSThread
|
|||||||
*/
|
*/
|
||||||
void doDeepSleep();
|
void doDeepSleep();
|
||||||
|
|
||||||
void blink();
|
|
||||||
|
|
||||||
// Draw north
|
// Draw north
|
||||||
float estimatedHeading(double lat, double lon);
|
float estimatedHeading(double lat, double lon);
|
||||||
|
|
||||||
|
|||||||
@@ -718,11 +718,6 @@ void VirtualKeyboard::setInputText(const std::string &text)
|
|||||||
inputText = text;
|
inputText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VirtualKeyboard::getInputText() const
|
|
||||||
{
|
|
||||||
return inputText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualKeyboard::setHeader(const std::string &header)
|
void VirtualKeyboard::setHeader(const std::string &header)
|
||||||
{
|
{
|
||||||
headerText = header;
|
headerText = header;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ class VirtualKeyboard
|
|||||||
|
|
||||||
void draw(OLEDDisplay *display, int16_t offsetX, int16_t offsetY);
|
void draw(OLEDDisplay *display, int16_t offsetX, int16_t offsetY);
|
||||||
void setInputText(const std::string &text);
|
void setInputText(const std::string &text);
|
||||||
std::string getInputText() const;
|
|
||||||
void setHeader(const std::string &header);
|
void setHeader(const std::string &header);
|
||||||
void setCallback(std::function<void(const std::string &)> callback);
|
void setCallback(std::function<void(const std::string &)> callback);
|
||||||
|
|
||||||
|
|||||||
@@ -230,131 +230,7 @@ void drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, i
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
display->setFont(FONT_SMALL);
|
|
||||||
|
|
||||||
// The coordinates define the left starting point of the text
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
||||||
|
|
||||||
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
|
|
||||||
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
|
||||||
display->setColor(BLACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
char batStr[20];
|
|
||||||
if (powerStatus->getHasBattery()) {
|
|
||||||
int batV = powerStatus->getBatteryVoltageMv() / 1000;
|
|
||||||
int batCv = (powerStatus->getBatteryVoltageMv() % 1000) / 10;
|
|
||||||
|
|
||||||
snprintf(batStr, sizeof(batStr), "B %01d.%02dV %3d%% %c%c", batV, batCv, powerStatus->getBatteryChargePercent(),
|
|
||||||
powerStatus->getIsCharging() ? '+' : ' ', powerStatus->getHasUSB() ? 'U' : ' ');
|
|
||||||
|
|
||||||
// Line 1
|
|
||||||
display->drawString(x, y, batStr);
|
|
||||||
if (config.display.heading_bold)
|
|
||||||
display->drawString(x + 1, y, batStr);
|
|
||||||
} else {
|
|
||||||
// Line 1
|
|
||||||
display->drawString(x, y, "USB");
|
|
||||||
if (config.display.heading_bold)
|
|
||||||
display->drawString(x + 1, y, "USB");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t currentMillis = millis();
|
|
||||||
uint32_t seconds = currentMillis / 1000;
|
|
||||||
uint32_t minutes = seconds / 60;
|
|
||||||
uint32_t hours = minutes / 60;
|
|
||||||
uint32_t days = hours / 24;
|
|
||||||
// currentMillis %= 1000;
|
|
||||||
// seconds %= 60;
|
|
||||||
// minutes %= 60;
|
|
||||||
// hours %= 24;
|
|
||||||
|
|
||||||
// Show uptime as days, hours, minutes OR seconds
|
|
||||||
std::string uptime = UIRenderer::drawTimeDelta(days, hours, minutes, seconds);
|
|
||||||
|
|
||||||
// Line 1 (Still)
|
|
||||||
if (currentResolution != graphics::ScreenResolution::UltraLow) {
|
|
||||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str());
|
|
||||||
if (config.display.heading_bold)
|
|
||||||
display->drawString(x - 1 + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str());
|
|
||||||
|
|
||||||
display->setColor(WHITE);
|
|
||||||
}
|
|
||||||
// Setup string to assemble analogClock string
|
|
||||||
std::string analogClock = "";
|
|
||||||
|
|
||||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
|
|
||||||
if (rtc_sec > 0) {
|
|
||||||
long hms = rtc_sec % SEC_PER_DAY;
|
|
||||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
|
||||||
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
|
||||||
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
|
||||||
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
|
||||||
|
|
||||||
// Tear apart hms into h:m:s
|
|
||||||
int hour, min, sec;
|
|
||||||
graphics::decomposeTime(rtc_sec, hour, min, sec);
|
|
||||||
|
|
||||||
char timebuf[12];
|
|
||||||
|
|
||||||
if (config.display.use_12h_clock) {
|
|
||||||
std::string meridiem = "am";
|
|
||||||
if (hour >= 12) {
|
|
||||||
if (hour > 12)
|
|
||||||
hour -= 12;
|
|
||||||
meridiem = "pm";
|
|
||||||
}
|
|
||||||
if (hour == 00) {
|
|
||||||
hour = 12;
|
|
||||||
}
|
|
||||||
snprintf(timebuf, sizeof(timebuf), "%d:%02d:%02d%s", hour, min, sec, meridiem.c_str());
|
|
||||||
} else {
|
|
||||||
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d", hour, min, sec);
|
|
||||||
}
|
|
||||||
analogClock += timebuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line 2
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, analogClock.c_str());
|
|
||||||
|
|
||||||
// Display Channel Utilization
|
|
||||||
char chUtil[13];
|
|
||||||
snprintf(chUtil, sizeof(chUtil), "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
|
|
||||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
|
|
||||||
|
|
||||||
#if HAS_GPS
|
|
||||||
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
|
||||||
// Line 3
|
|
||||||
if (uiconfig.gps_format != meshtastic_DeviceUIConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
|
|
||||||
UIRenderer::drawGpsAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
|
||||||
|
|
||||||
// Line 4
|
|
||||||
UIRenderer::drawGpsCoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
|
|
||||||
} else {
|
|
||||||
UIRenderer::drawGpsPowerStatus(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
|
||||||
#ifdef SHOW_REDRAWS
|
|
||||||
if (heartbeat)
|
|
||||||
display->setPixel(0, 0);
|
|
||||||
heartbeat = !heartbeat;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trampoline functions for DebugInfo class access
|
// Trampoline functions for DebugInfo class access
|
||||||
void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
drawFrame(display, state, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawDebugInfoSettingsTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
drawFrameSettings(display, state, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
drawFrameWiFi(display, state, x, y);
|
drawFrameWiFi(display, state, x, y);
|
||||||
|
|||||||
@@ -20,12 +20,9 @@ namespace DebugRenderer
|
|||||||
{
|
{
|
||||||
// Debug frame functions
|
// Debug frame functions
|
||||||
void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
|
||||||
void drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
void drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
// Trampoline functions for framework callback compatibility
|
// Trampoline functions for framework callback compatibility
|
||||||
void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
|
||||||
void drawDebugInfoSettingsTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
|
||||||
void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
// LoRa information display
|
// LoRa information display
|
||||||
|
|||||||
@@ -17,12 +17,6 @@
|
|||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// Forward declarations for functions defined in Screen.cpp
|
|
||||||
namespace graphics
|
|
||||||
{
|
|
||||||
extern bool haveGlyphs(const char *str);
|
|
||||||
} // namespace graphics
|
|
||||||
|
|
||||||
// Global screen instance
|
// Global screen instance
|
||||||
extern graphics::Screen *screen;
|
extern graphics::Screen *screen;
|
||||||
|
|
||||||
@@ -180,11 +174,6 @@ unsigned long getModeCycleIntervalMs()
|
|||||||
return 3000;
|
return 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculateMaxScroll(int totalEntries, int visibleRows)
|
|
||||||
{
|
|
||||||
return max(0, (totalEntries - 1) / (visibleRows * 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawColumnSeparator(OLEDDisplay *display, int16_t x, int16_t yStart, int16_t yEnd)
|
void drawColumnSeparator(OLEDDisplay *display, int16_t x, int16_t yStart, int16_t yEnd)
|
||||||
{
|
{
|
||||||
x = (currentResolution == ScreenResolution::High) ? x - 2 : (currentResolution == ScreenResolution::Low) ? x - 1 : x;
|
x = (currentResolution == ScreenResolution::High) ? x - 2 : (currentResolution == ScreenResolution::Low) ? x - 1 : x;
|
||||||
@@ -910,29 +899,6 @@ void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
drawNodeListScreen(display, state, x, y, "Bearings", drawEntryCompass, drawCompassArrow, headingRadian, lat, lon);
|
drawNodeListScreen(display, state, x, y, "Bearings", drawEntryCompass, drawCompassArrow, headingRadian, lat, lon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a series of fields in a column, wrapping to multiple columns if needed
|
|
||||||
void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields)
|
|
||||||
{
|
|
||||||
// The coordinates define the left starting point of the text
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
||||||
|
|
||||||
const char **f = fields;
|
|
||||||
int xo = x, yo = y;
|
|
||||||
while (*f) {
|
|
||||||
display->drawString(xo, yo, *f);
|
|
||||||
if ((display->getColor() == BLACK) && config.display.heading_bold)
|
|
||||||
display->drawString(xo + 1, yo, *f);
|
|
||||||
|
|
||||||
display->setColor(WHITE);
|
|
||||||
yo += FONT_HEIGHT_SMALL;
|
|
||||||
if (yo > SCREEN_HEIGHT - FONT_HEIGHT_SMALL) {
|
|
||||||
xo += SCREEN_WIDTH / 2;
|
|
||||||
yo = 0;
|
|
||||||
}
|
|
||||||
f++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NodeListRenderer
|
} // namespace NodeListRenderer
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#endif
|
#endif
|
||||||
@@ -58,7 +58,6 @@ void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
const char *getCurrentModeTitle_Nodes(int screenWidth);
|
const char *getCurrentModeTitle_Nodes(int screenWidth);
|
||||||
const char *getCurrentModeTitle_Location(int screenWidth);
|
const char *getCurrentModeTitle_Location(int screenWidth);
|
||||||
std::string getSafeNodeName(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int columnWidth);
|
std::string getSafeNodeName(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int columnWidth);
|
||||||
void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields);
|
|
||||||
|
|
||||||
// Scrolling controls
|
// Scrolling controls
|
||||||
void scrollUp();
|
void scrollUp();
|
||||||
|
|||||||
@@ -207,8 +207,6 @@ void NotificationRenderer::resetBanner()
|
|||||||
alertBannerMessage[0] = '\0';
|
alertBannerMessage[0] = '\0';
|
||||||
current_notification_type = notificationTypeEnum::none;
|
current_notification_type = notificationTypeEnum::none;
|
||||||
|
|
||||||
OnScreenKeyboardModule::instance().clearPopup();
|
|
||||||
|
|
||||||
inEvent.inputEvent = INPUT_BROKER_NONE;
|
inEvent.inputEvent = INPUT_BROKER_NONE;
|
||||||
inEvent.kbchar = 0;
|
inEvent.kbchar = 0;
|
||||||
curSelected = 0;
|
curSelected = 0;
|
||||||
@@ -1187,9 +1185,6 @@ void NotificationRenderer::drawTextInput(OLEDDisplay *display, OLEDDisplayUiStat
|
|||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
// Draw the virtual keyboard
|
// Draw the virtual keyboard
|
||||||
virtualKeyboard->draw(display, 0, 0);
|
virtualKeyboard->draw(display, 0, 0);
|
||||||
|
|
||||||
// Draw transient popup overlay (if any) managed by OnScreenKeyboardModule
|
|
||||||
OnScreenKeyboardModule::instance().drawPopupOverlay(display);
|
|
||||||
} else {
|
} else {
|
||||||
// If virtualKeyboard is null, reset the banner to avoid getting stuck
|
// If virtualKeyboard is null, reset the banner to avoid getting stuck
|
||||||
LOG_INFO("Virtual keyboard is null - resetting banner");
|
LOG_INFO("Virtual keyboard is null - resetting banner");
|
||||||
@@ -1202,12 +1197,5 @@ bool NotificationRenderer::isOverlayBannerShowing()
|
|||||||
return strlen(alertBannerMessage) > 0 && (alertBannerUntil == 0 || millis() <= alertBannerUntil);
|
return strlen(alertBannerMessage) > 0 && (alertBannerUntil == 0 || millis() <= alertBannerUntil);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationRenderer::showKeyboardMessagePopupWithTitle(const char *title, const char *content, uint32_t durationMs)
|
|
||||||
{
|
|
||||||
if (!title || !content || current_notification_type != notificationTypeEnum::text_input)
|
|
||||||
return;
|
|
||||||
OnScreenKeyboardModule::instance().showPopup(title, content, durationMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#endif
|
#endif
|
||||||
@@ -39,7 +39,6 @@ class NotificationRenderer
|
|||||||
static BannerFont alertBannerLineFonts[MAX_LINES + 1];
|
static BannerFont alertBannerLineFonts[MAX_LINES + 1];
|
||||||
static void parseBannerMessageWithFonts(const char *message);
|
static void parseBannerMessageWithFonts(const char *message);
|
||||||
static void resetBanner();
|
static void resetBanner();
|
||||||
static void showKeyboardMessagePopupWithTitle(const char *title, const char *content, uint32_t durationMs);
|
|
||||||
static void drawBannercallback(OLEDDisplay *display, OLEDDisplayUiState *state);
|
static void drawBannercallback(OLEDDisplay *display, OLEDDisplayUiState *state);
|
||||||
static void drawAlertBannerOverlay(OLEDDisplay *display, OLEDDisplayUiState *state);
|
static void drawAlertBannerOverlay(OLEDDisplay *display, OLEDDisplayUiState *state);
|
||||||
static void drawNumberPicker(OLEDDisplay *display, OLEDDisplayUiState *state);
|
static void drawNumberPicker(OLEDDisplay *display, OLEDDisplayUiState *state);
|
||||||
|
|||||||
@@ -1386,30 +1386,6 @@ int UIRenderer::formatDateTime(char *buf, size_t bufSize, uint32_t rtc_sec, OLED
|
|||||||
return display->getStringWidth(buf);
|
return display->getStringWidth(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the display can render a string (detect special chars; emoji)
|
|
||||||
bool UIRenderer::haveGlyphs(const char *str)
|
|
||||||
{
|
|
||||||
#if defined(OLED_PL) || defined(OLED_UA) || defined(OLED_RU) || defined(OLED_CS)
|
|
||||||
// Don't want to make any assumptions about custom language support
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check each character with the lookup function for the OLED library
|
|
||||||
// We're not really meant to use this directly..
|
|
||||||
bool have = true;
|
|
||||||
for (uint16_t i = 0; i < strlen(str); i++) {
|
|
||||||
uint8_t result = Screen::customFontTableLookup((uint8_t)str[i]);
|
|
||||||
// If font doesn't support a character, it is substituted for ¿
|
|
||||||
if (result == 191 && (uint8_t)str[i] != 191) {
|
|
||||||
have = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LOG_DEBUG("haveGlyphs=%d", have);
|
|
||||||
return have;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_EINK
|
#ifdef USE_EINK
|
||||||
/// Used on eink displays while in deep sleep
|
/// Used on eink displays while in deep sleep
|
||||||
void UIRenderer::drawDeepSleepFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void UIRenderer::drawDeepSleepFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
|||||||
@@ -104,9 +104,6 @@ class UIRenderer
|
|||||||
{
|
{
|
||||||
drawStringWithEmotes(display, x, y, line.c_str(), fontHeight, emoteSpacing, fauxBold);
|
drawStringWithEmotes(display, x, y, line.c_str(), fontHeight, emoteSpacing, fauxBold);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the display can render a string (detect special chars; emoji)
|
|
||||||
static bool haveGlyphs(const char *str);
|
|
||||||
}; // namespace UIRenderer
|
}; // namespace UIRenderer
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
@@ -649,30 +649,6 @@ std::string InkHUD::Applet::getTimeString()
|
|||||||
return getTimeString(getValidTime(RTCQuality::RTCQualityDevice, true));
|
return getTimeString(getValidTime(RTCQuality::RTCQualityDevice, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate how many nodes have been seen within our preferred window of activity
|
|
||||||
// This period is set by user, via the menu
|
|
||||||
// Todo: optimize to calculate once only per WindowManager::render
|
|
||||||
uint16_t InkHUD::Applet::getActiveNodeCount()
|
|
||||||
{
|
|
||||||
// Don't even try to count nodes if RTC isn't set
|
|
||||||
// The last heard values in nodedb will be incomprehensible
|
|
||||||
if (getRTCQuality() == RTCQualityNone)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint16_t count = 0;
|
|
||||||
|
|
||||||
// For each node in db
|
|
||||||
for (uint16_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
|
|
||||||
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
|
|
||||||
|
|
||||||
// Check if heard recently, and not our own node
|
|
||||||
if (sinceLastSeen(node) < settings->recentlyActiveSeconds && node->num != nodeDB->getNodeNum())
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get an abbreviated, human readable, distance string
|
// Get an abbreviated, human readable, distance string
|
||||||
// Honors config.display.units, to offer both metric and imperial
|
// Honors config.display.units, to offer both metric and imperial
|
||||||
std::string InkHUD::Applet::localizeDistance(uint32_t meters)
|
std::string InkHUD::Applet::localizeDistance(uint32_t meters)
|
||||||
|
|||||||
@@ -183,7 +183,6 @@ class Applet : public GFX
|
|||||||
SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
|
SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
|
||||||
std::string getTimeString(uint32_t epochSeconds); // Human readable
|
std::string getTimeString(uint32_t epochSeconds); // Human readable
|
||||||
std::string getTimeString(); // Current time, human readable
|
std::string getTimeString(); // Current time, human readable
|
||||||
uint16_t getActiveNodeCount(); // Duration determined by user, in onscreen menu
|
|
||||||
std::string localizeDistance(uint32_t meters); // Human readable distance, imperial or metric
|
std::string localizeDistance(uint32_t meters); // Human readable distance, imperial or metric
|
||||||
std::string parse(const std::string &text); // Handle text which might contain special chars
|
std::string parse(const std::string &text); // Handle text which might contain special chars
|
||||||
std::string parseShortName(meshtastic_NodeInfoLite *node); // Get the shortname, or a substitute if has unprintable chars
|
std::string parseShortName(meshtastic_NodeInfoLite *node); // Get the shortname, or a substitute if has unprintable chars
|
||||||
|
|||||||
@@ -217,13 +217,6 @@ bool InkHUD::ThreadedMessageApplet::approveNotification(Notification &n)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save messages to flash via the global messageStore.
|
|
||||||
// The global store holds messages for all channels; no per-channel file is needed.
|
|
||||||
void InkHUD::ThreadedMessageApplet::saveMessagesToFlash()
|
|
||||||
{
|
|
||||||
messageStore.saveToFlash();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Messages are loaded once by InkHUD::begin() before applets start.
|
// Messages are loaded once by InkHUD::begin() before applets start.
|
||||||
// Nothing to do here at per-applet activation time.
|
// Nothing to do here at per-applet activation time.
|
||||||
void InkHUD::ThreadedMessageApplet::loadMessagesFromFlash()
|
void InkHUD::ThreadedMessageApplet::loadMessagesFromFlash()
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ class ThreadedMessageApplet : public Applet, public SinglePortModule
|
|||||||
bool approveNotification(Notification &n) override; // Which notifications to suppress
|
bool approveNotification(Notification &n) override; // Which notifications to suppress
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void saveMessagesToFlash();
|
|
||||||
void loadMessagesFromFlash();
|
void loadMessagesFromFlash();
|
||||||
|
|
||||||
uint8_t channelIndex = 0;
|
uint8_t channelIndex = 0;
|
||||||
|
|||||||
@@ -326,44 +326,6 @@ void InkHUD::InkHUD::touchNavDown()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this when touch input needs joystick-like left navigation independent of joystick-enabled mode
|
|
||||||
void InkHUD::InkHUD::touchNavLeft()
|
|
||||||
{
|
|
||||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
|
||||||
case 1: // 90 deg
|
|
||||||
events->onTouchNavDown();
|
|
||||||
break;
|
|
||||||
case 2: // 180 deg
|
|
||||||
events->onTouchNavRight();
|
|
||||||
break;
|
|
||||||
case 3: // 270 deg
|
|
||||||
events->onTouchNavUp();
|
|
||||||
break;
|
|
||||||
default: // 0 deg
|
|
||||||
events->onTouchNavLeft();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this when touch input needs joystick-like right navigation independent of joystick-enabled mode
|
|
||||||
void InkHUD::InkHUD::touchNavRight()
|
|
||||||
{
|
|
||||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
|
||||||
case 1: // 90 deg
|
|
||||||
events->onTouchNavUp();
|
|
||||||
break;
|
|
||||||
case 2: // 180 deg
|
|
||||||
events->onTouchNavLeft();
|
|
||||||
break;
|
|
||||||
case 3: // 270 deg
|
|
||||||
events->onTouchNavDown();
|
|
||||||
break;
|
|
||||||
default: // 0 deg
|
|
||||||
events->onTouchNavRight();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InkHUD::InkHUD::touchTap(uint16_t x, uint16_t y)
|
void InkHUD::InkHUD::touchTap(uint16_t x, uint16_t y)
|
||||||
{
|
{
|
||||||
events->onTouchTap(x, y, false);
|
events->onTouchTap(x, y, false);
|
||||||
|
|||||||
@@ -71,8 +71,6 @@ class InkHUD
|
|||||||
void navRight();
|
void navRight();
|
||||||
void touchNavUp();
|
void touchNavUp();
|
||||||
void touchNavDown();
|
void touchNavDown();
|
||||||
void touchNavLeft();
|
|
||||||
void touchNavRight();
|
|
||||||
void touchTap(uint16_t x, uint16_t y);
|
void touchTap(uint16_t x, uint16_t y);
|
||||||
void touchLongPress(uint16_t x, uint16_t y);
|
void touchLongPress(uint16_t x, uint16_t y);
|
||||||
|
|
||||||
|
|||||||
@@ -496,8 +496,10 @@ We keep this separate latest-message cache for this purpose, because:
|
|||||||
|
|
||||||
Broadcasts and DMs take different paths into `messageStore`:
|
Broadcasts and DMs take different paths into `messageStore`:
|
||||||
|
|
||||||
- **Broadcasts** - `ThreadedMessageApplet::handleReceived()` calls `messageStore.addFromPacket()`. `Events::onReceiveTextMessage()` then updates `latestMessage.broadcast` separately for fast access by `AllMessageApplet` and `NotificationApplet`.
|
- **Broadcasts** - `ThreadedMessageApplet::handleReceived()` calls `messageStore.tryAddFromPacket()`. `Events::onReceiveTextMessage()` then updates `latestMessage.broadcast` separately for fast access by `AllMessageApplet` and `NotificationApplet`.
|
||||||
- **DMs** - `ThreadedMessageApplet` skips DMs entirely. `Events::onReceiveTextMessage()` calls `messageStore.addFromPacket()` directly and stores the result in `latestMessage.dm`.
|
- **DMs** - `ThreadedMessageApplet` skips DMs entirely. `Events::onReceiveTextMessage()` calls `messageStore.tryAddFromPacket()` directly and stores the result in `latestMessage.dm`.
|
||||||
|
|
||||||
|
`tryAddFromPacket()` returns `nullptr` when the packet is filtered out (see `shouldStorePacket()`), so both paths must null-check before use.
|
||||||
|
|
||||||
#### Saving / Loading
|
#### Saving / Loading
|
||||||
|
|
||||||
|
|||||||
@@ -117,14 +117,6 @@ void TwoButton::setHandlerDown(uint8_t whichButton, Callback onDown)
|
|||||||
buttons[whichButton].onDown = onDown;
|
buttons[whichButton].onDown = onDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set what should happen when a button becomes unpressed
|
|
||||||
// Use this to implement a "While held" behavior
|
|
||||||
void TwoButton::setHandlerUp(uint8_t whichButton, Callback onUp)
|
|
||||||
{
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].onUp = onUp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a "short press" event has occurred
|
// Set what should happen when a "short press" event has occurred
|
||||||
void TwoButton::setHandlerShortPress(uint8_t whichButton, Callback onShortPress)
|
void TwoButton::setHandlerShortPress(uint8_t whichButton, Callback onShortPress)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ class TwoButton : protected concurrency::OSThread
|
|||||||
void setWiring(uint8_t whichButton, uint8_t pin, bool internalPullup = false);
|
void setWiring(uint8_t whichButton, uint8_t pin, bool internalPullup = false);
|
||||||
void setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs);
|
void setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs);
|
||||||
void setHandlerDown(uint8_t whichButton, Callback onDown);
|
void setHandlerDown(uint8_t whichButton, Callback onDown);
|
||||||
void setHandlerUp(uint8_t whichButton, Callback onUp);
|
|
||||||
void setHandlerShortPress(uint8_t whichButton, Callback onShortPress);
|
void setHandlerShortPress(uint8_t whichButton, Callback onShortPress);
|
||||||
void setHandlerLongPress(uint8_t whichButton, Callback onLongPress);
|
void setHandlerLongPress(uint8_t whichButton, Callback onLongPress);
|
||||||
|
|
||||||
|
|||||||
@@ -194,14 +194,6 @@ void TwoButtonExtended::setHandlerDown(uint8_t whichButton, Callback onDown)
|
|||||||
buttons[whichButton].onDown = onDown;
|
buttons[whichButton].onDown = onDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set what should happen when a button becomes unpressed
|
|
||||||
// Use this to implement a "While held" behavior
|
|
||||||
void TwoButtonExtended::setHandlerUp(uint8_t whichButton, Callback onUp)
|
|
||||||
{
|
|
||||||
assert(whichButton < 2);
|
|
||||||
buttons[whichButton].onUp = onUp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a "short press" event has occurred
|
// Set what should happen when a "short press" event has occurred
|
||||||
void TwoButtonExtended::setHandlerShortPress(uint8_t whichButton, Callback onPress)
|
void TwoButtonExtended::setHandlerShortPress(uint8_t whichButton, Callback onPress)
|
||||||
{
|
{
|
||||||
@@ -217,26 +209,6 @@ void TwoButtonExtended::setHandlerLongPress(uint8_t whichButton, Callback onLong
|
|||||||
buttons[whichButton].onLongPress = onLongPress;
|
buttons[whichButton].onLongPress = onLongPress;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set what should happen when a joystick button becomes pressed
|
|
||||||
// Use this to implement a "while held" behavior
|
|
||||||
void TwoButtonExtended::setJoystickDownHandlers(Callback uDown, Callback dDown, Callback lDown, Callback rDown)
|
|
||||||
{
|
|
||||||
joystick[Direction::UP].onDown = uDown;
|
|
||||||
joystick[Direction::DOWN].onDown = dDown;
|
|
||||||
joystick[Direction::LEFT].onDown = lDown;
|
|
||||||
joystick[Direction::RIGHT].onDown = rDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a joystick button becomes unpressed
|
|
||||||
// Use this to implement a "while held" behavior
|
|
||||||
void TwoButtonExtended::setJoystickUpHandlers(Callback uUp, Callback dUp, Callback lUp, Callback rUp)
|
|
||||||
{
|
|
||||||
joystick[Direction::UP].onUp = uUp;
|
|
||||||
joystick[Direction::DOWN].onUp = dUp;
|
|
||||||
joystick[Direction::LEFT].onUp = lUp;
|
|
||||||
joystick[Direction::RIGHT].onUp = rUp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set what should happen when a "press" event has fired
|
// Set what should happen when a "press" event has fired
|
||||||
// Note: this will occur while the joystick button is still held
|
// Note: this will occur while the joystick button is still held
|
||||||
void TwoButtonExtended::setJoystickPressHandlers(Callback uPress, Callback dPress, Callback lPress, Callback rPress)
|
void TwoButtonExtended::setJoystickPressHandlers(Callback uPress, Callback dPress, Callback lPress, Callback rPress)
|
||||||
|
|||||||
@@ -49,11 +49,8 @@ class TwoButtonExtended : protected concurrency::OSThread
|
|||||||
void setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs);
|
void setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs);
|
||||||
void setJoystickDebounce(uint32_t debounceMs);
|
void setJoystickDebounce(uint32_t debounceMs);
|
||||||
void setHandlerDown(uint8_t whichButton, Callback onDown);
|
void setHandlerDown(uint8_t whichButton, Callback onDown);
|
||||||
void setHandlerUp(uint8_t whichButton, Callback onUp);
|
|
||||||
void setHandlerShortPress(uint8_t whichButton, Callback onShortPress);
|
void setHandlerShortPress(uint8_t whichButton, Callback onShortPress);
|
||||||
void setHandlerLongPress(uint8_t whichButton, Callback onLongPress);
|
void setHandlerLongPress(uint8_t whichButton, Callback onLongPress);
|
||||||
void setJoystickDownHandlers(Callback uDown, Callback dDown, Callback ldown, Callback rDown);
|
|
||||||
void setJoystickUpHandlers(Callback uUp, Callback dUp, Callback lUp, Callback rUp);
|
|
||||||
void setJoystickPressHandlers(Callback uPress, Callback dPress, Callback lPress, Callback rPress);
|
void setJoystickPressHandlers(Callback uPress, Callback dPress, Callback lPress, Callback rPress);
|
||||||
void setTwoWayRockerPressHandlers(Callback lPress, Callback rPress);
|
void setTwoWayRockerPressHandlers(Callback lPress, Callback rPress);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1222,7 +1222,7 @@ bool runASAP;
|
|||||||
// TODO find better home than main.cpp
|
// TODO find better home than main.cpp
|
||||||
extern meshtastic_DeviceMetadata getDeviceMetadata()
|
extern meshtastic_DeviceMetadata getDeviceMetadata()
|
||||||
{
|
{
|
||||||
meshtastic_DeviceMetadata deviceMetadata;
|
meshtastic_DeviceMetadata deviceMetadata = meshtastic_DeviceMetadata_init_default;
|
||||||
strncpy(deviceMetadata.firmware_version, optstr(APP_VERSION), sizeof(deviceMetadata.firmware_version));
|
strncpy(deviceMetadata.firmware_version, optstr(APP_VERSION), sizeof(deviceMetadata.firmware_version));
|
||||||
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
|
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
|
||||||
deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
|
deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "memGet.h"
|
#include "memGet.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "memory/MemAudit.h"
|
|
||||||
|
|
||||||
#if defined(MESHTASTIC_DYNAMIC_SBRK_HEAP)
|
#if defined(MESHTASTIC_DYNAMIC_SBRK_HEAP)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
@@ -108,16 +107,3 @@ uint32_t MemGet::getPsramSize()
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayPercentHeapFree()
|
|
||||||
{
|
|
||||||
uint32_t freeHeap = memGet.getFreeHeap();
|
|
||||||
uint32_t totalHeap = memGet.getHeapSize();
|
|
||||||
if (totalHeap == 0 || totalHeap == UINT32_MAX) {
|
|
||||||
LOG_INFO("Heap size unavailable");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int percent = (int)((freeHeap * 100) / totalHeap);
|
|
||||||
LOG_INFO("Heap free: %d%% (%u/%u bytes)", percent, freeHeap, totalHeap);
|
|
||||||
memaudit::logBreakdown("heap"); // per-subsystem breakdown rides along with the periodic heap log
|
|
||||||
}
|
|
||||||
@@ -280,15 +280,6 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
return send(p);
|
return send(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Send a packet on a suitable interface.
|
|
||||||
*/
|
|
||||||
ErrorCode Router::rawSend(meshtastic_MeshPacket *p)
|
|
||||||
{
|
|
||||||
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
|
|
||||||
return iface->send(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet on a suitable interface. This routine will
|
* Send a packet on a suitable interface. This routine will
|
||||||
* later free() the packet to pool. This routine is not allowed to stall.
|
* later free() the packet to pool. This routine is not allowed to stall.
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ class Router : protected concurrency::OSThread, protected PacketHistory
|
|||||||
* NOTE: This method will free the provided packet (even if we return an error code)
|
* NOTE: This method will free the provided packet (even if we return an error code)
|
||||||
*/
|
*/
|
||||||
virtual ErrorCode send(meshtastic_MeshPacket *p);
|
virtual ErrorCode send(meshtastic_MeshPacket *p);
|
||||||
virtual ErrorCode rawSend(meshtastic_MeshPacket *p);
|
|
||||||
|
|
||||||
/* Statistics for the amount of duplicate received packets and the amount of times we cancel a relay because someone did it
|
/* Statistics for the amount of duplicate received packets and the amount of times we cancel a relay because someone did it
|
||||||
before us */
|
before us */
|
||||||
|
|||||||
@@ -74,15 +74,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
ResourceNode *nodeAPIv1FromRadioOptions = new ResourceNode("/api/v1/fromradio", "OPTIONS", &handleAPIv1FromRadio);
|
ResourceNode *nodeAPIv1FromRadioOptions = new ResourceNode("/api/v1/fromradio", "OPTIONS", &handleAPIv1FromRadio);
|
||||||
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
|
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
|
||||||
|
|
||||||
// ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
|
|
||||||
// ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
|
|
||||||
|
|
||||||
ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin);
|
ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin);
|
||||||
// ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings);
|
|
||||||
// ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply);
|
|
||||||
// ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs);
|
|
||||||
// ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs);
|
|
||||||
// ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent);
|
|
||||||
|
|
||||||
ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart);
|
ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart);
|
||||||
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
||||||
@@ -100,8 +92,6 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
secureServer->registerNode(nodeAPIv1ToRadio);
|
secureServer->registerNode(nodeAPIv1ToRadio);
|
||||||
secureServer->registerNode(nodeAPIv1FromRadioOptions);
|
secureServer->registerNode(nodeAPIv1FromRadioOptions);
|
||||||
secureServer->registerNode(nodeAPIv1FromRadio);
|
secureServer->registerNode(nodeAPIv1FromRadio);
|
||||||
// secureServer->registerNode(nodeHotspotApple);
|
|
||||||
// secureServer->registerNode(nodeHotspotAndroid);
|
|
||||||
secureServer->registerNode(nodeRestart);
|
secureServer->registerNode(nodeRestart);
|
||||||
secureServer->registerNode(nodeFormUpload);
|
secureServer->registerNode(nodeFormUpload);
|
||||||
secureServer->registerNode(nodeJsonScanNetworks);
|
secureServer->registerNode(nodeJsonScanNetworks);
|
||||||
@@ -109,12 +99,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
secureServer->registerNode(nodeJsonDelete);
|
secureServer->registerNode(nodeJsonDelete);
|
||||||
secureServer->registerNode(nodeJsonReport);
|
secureServer->registerNode(nodeJsonReport);
|
||||||
secureServer->registerNode(nodeJsonNodes);
|
secureServer->registerNode(nodeJsonNodes);
|
||||||
// secureServer->registerNode(nodeUpdateFs);
|
|
||||||
// secureServer->registerNode(nodeDeleteFs);
|
|
||||||
secureServer->registerNode(nodeAdmin);
|
secureServer->registerNode(nodeAdmin);
|
||||||
// secureServer->registerNode(nodeAdminFs);
|
|
||||||
// secureServer->registerNode(nodeAdminSettings);
|
|
||||||
// secureServer->registerNode(nodeAdminSettingsApply);
|
|
||||||
secureServer->registerNode(nodeRoot); // This has to be last
|
secureServer->registerNode(nodeRoot); // This has to be last
|
||||||
|
|
||||||
// Insecure nodes
|
// Insecure nodes
|
||||||
@@ -122,20 +107,13 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
insecureServer->registerNode(nodeAPIv1ToRadio);
|
insecureServer->registerNode(nodeAPIv1ToRadio);
|
||||||
insecureServer->registerNode(nodeAPIv1FromRadioOptions);
|
insecureServer->registerNode(nodeAPIv1FromRadioOptions);
|
||||||
insecureServer->registerNode(nodeAPIv1FromRadio);
|
insecureServer->registerNode(nodeAPIv1FromRadio);
|
||||||
// insecureServer->registerNode(nodeHotspotApple);
|
|
||||||
// insecureServer->registerNode(nodeHotspotAndroid);
|
|
||||||
insecureServer->registerNode(nodeRestart);
|
insecureServer->registerNode(nodeRestart);
|
||||||
insecureServer->registerNode(nodeFormUpload);
|
insecureServer->registerNode(nodeFormUpload);
|
||||||
insecureServer->registerNode(nodeJsonScanNetworks);
|
insecureServer->registerNode(nodeJsonScanNetworks);
|
||||||
insecureServer->registerNode(nodeJsonFsBrowseStatic);
|
insecureServer->registerNode(nodeJsonFsBrowseStatic);
|
||||||
insecureServer->registerNode(nodeJsonDelete);
|
insecureServer->registerNode(nodeJsonDelete);
|
||||||
insecureServer->registerNode(nodeJsonReport);
|
insecureServer->registerNode(nodeJsonReport);
|
||||||
// insecureServer->registerNode(nodeUpdateFs);
|
|
||||||
// insecureServer->registerNode(nodeDeleteFs);
|
|
||||||
insecureServer->registerNode(nodeAdmin);
|
insecureServer->registerNode(nodeAdmin);
|
||||||
// insecureServer->registerNode(nodeAdminFs);
|
|
||||||
// insecureServer->registerNode(nodeAdminSettings);
|
|
||||||
// insecureServer->registerNode(nodeAdminSettingsApply);
|
|
||||||
insecureServer->registerNode(nodeRoot); // This has to be last
|
insecureServer->registerNode(nodeRoot); // This has to be last
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,36 +208,6 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
LOG_DEBUG("webAPI handleAPIv1ToRadio");
|
LOG_DEBUG("webAPI handleAPIv1ToRadio");
|
||||||
}
|
}
|
||||||
|
|
||||||
void htmlDeleteDir(const char *dirname)
|
|
||||||
{
|
|
||||||
|
|
||||||
File root = FSCom.open(dirname);
|
|
||||||
if (!root) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!root.isDirectory()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File file = root.openNextFile();
|
|
||||||
while (file) {
|
|
||||||
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
|
|
||||||
htmlDeleteDir(file.name());
|
|
||||||
file.flush();
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
String fileName = String(file.name());
|
|
||||||
file.flush();
|
|
||||||
file.close();
|
|
||||||
LOG_DEBUG(" %s", fileName.c_str());
|
|
||||||
FSCom.remove(fileName);
|
|
||||||
}
|
|
||||||
file = root.openNextFile();
|
|
||||||
}
|
|
||||||
root.flush();
|
|
||||||
root.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escape a string into a JSON double-quoted literal. Matches the previous
|
// Escape a string into a JSON double-quoted literal. Matches the previous
|
||||||
// SimpleJSON StringifyString behavior (0x00-0x1F and 0x7F -> \u00xx lowercase,
|
// SimpleJSON StringifyString behavior (0x00-0x1F and 0x7F -> \u00xx lowercase,
|
||||||
// escapes " \ / \b \f \n \r \t, UTF-8 passes through unchanged).
|
// escapes " \ / \b \f \n \r \t, UTF-8 passes through unchanged).
|
||||||
@@ -858,45 +806,6 @@ void handleNodes(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->print(out.c_str());
|
res->print(out.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
This supports the Apple Captive Network Assistant (CNA) Portal
|
|
||||||
*/
|
|
||||||
void handleHotspot(HTTPRequest *req, HTTPResponse *res)
|
|
||||||
{
|
|
||||||
LOG_INFO("Hotspot Request");
|
|
||||||
|
|
||||||
/*
|
|
||||||
If we don't do a redirect, be sure to return a "Success" message
|
|
||||||
otherwise iOS will have trouble detecting that the connection to the SoftAP worked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Status code is 200 OK by default.
|
|
||||||
// We want to deliver a simple HTML page, so we send a corresponding content type:
|
|
||||||
res->setHeader("Content-Type", "text/html");
|
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
|
||||||
|
|
||||||
// res->println("<!DOCTYPE html>");
|
|
||||||
res->println("<meta http-equiv=\"refresh\" content=\"0;url=/\" />");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res)
|
|
||||||
{
|
|
||||||
res->setHeader("Content-Type", "text/html");
|
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
|
||||||
|
|
||||||
res->println("<h1>Meshtastic</h1>");
|
|
||||||
res->println("Delete Content in /static/*");
|
|
||||||
|
|
||||||
LOG_INFO("Delete files from /static/* : ");
|
|
||||||
|
|
||||||
concurrency::LockGuard g(spiLock);
|
|
||||||
htmlDeleteDir("/static");
|
|
||||||
|
|
||||||
res->println("<p><hr><p><a href=/admin>Back to admin</a>");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleAdmin(HTTPRequest *req, HTTPResponse *res)
|
void handleAdmin(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
res->setHeader("Content-Type", "text/html");
|
res->setHeader("Content-Type", "text/html");
|
||||||
@@ -909,52 +818,6 @@ void handleAdmin(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->println("<a href=/json/report>Device Report</a><br>");
|
res->println("<a href=/json/report>Device Report</a><br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleAdminSettings(HTTPRequest *req, HTTPResponse *res)
|
|
||||||
{
|
|
||||||
res->setHeader("Content-Type", "text/html");
|
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
|
||||||
|
|
||||||
res->println("<h1>Meshtastic</h1>");
|
|
||||||
res->println("This isn't done.");
|
|
||||||
res->println("<form action=/admin/settings/apply method=post>");
|
|
||||||
res->println("<table border=1>");
|
|
||||||
res->println("<tr><td>Set?</td><td>Setting</td><td>current value</td><td>new value</td></tr>");
|
|
||||||
res->println("<tr><td><input type=checkbox></td><td>WiFi SSID</td><td>false</td><td><input type=radio></td></tr>");
|
|
||||||
res->println("<tr><td><input type=checkbox></td><td>WiFi Password</td><td>false</td><td><input type=radio></td></tr>");
|
|
||||||
res->println(
|
|
||||||
"<tr><td><input type=checkbox></td><td>Smart Position Update</td><td>false</td><td><input type=radio></td></tr>");
|
|
||||||
res->println("</table>");
|
|
||||||
res->println("<table>");
|
|
||||||
res->println("<input type=submit value=Apply New Settings>");
|
|
||||||
res->println("<form>");
|
|
||||||
res->println("<p><hr><p><a href=/admin>Back to admin</a>");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res)
|
|
||||||
{
|
|
||||||
res->setHeader("Content-Type", "text/html");
|
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
res->setHeader("Access-Control-Allow-Methods", "POST");
|
|
||||||
res->println("<h1>Meshtastic</h1>");
|
|
||||||
res->println(
|
|
||||||
"<html><head><meta http-equiv=\"refresh\" content=\"1;url=/admin/settings\" /><title>Settings Applied. </title>");
|
|
||||||
|
|
||||||
res->println("Settings Applied. Please wait.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleFs(HTTPRequest *req, HTTPResponse *res)
|
|
||||||
{
|
|
||||||
res->setHeader("Content-Type", "text/html");
|
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
|
||||||
|
|
||||||
res->println("<h1>Meshtastic</h1>");
|
|
||||||
res->println("<a href=/admin/fs/delete>Delete Web Content</a><p><form action=/admin/fs/update "
|
|
||||||
"method=post><input type=submit value=UPDATE_WEB_CONTENT></form>Be patient!");
|
|
||||||
res->println("<p><hr><p><a href=/admin>Back to admin</a>");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleRestart(HTTPRequest *req, HTTPResponse *res)
|
void handleRestart(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
res->setHeader("Content-Type", "text/html");
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
|
|||||||
// Declare some handler functions for the various URLs on the server
|
// Declare some handler functions for the various URLs on the server
|
||||||
void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res);
|
void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res);
|
void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleHotspot(HTTPRequest *req, HTTPResponse *res);
|
|
||||||
void handleStatic(HTTPRequest *req, HTTPResponse *res);
|
void handleStatic(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleRestart(HTTPRequest *req, HTTPResponse *res);
|
void handleRestart(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleFormUpload(HTTPRequest *req, HTTPResponse *res);
|
void handleFormUpload(HTTPRequest *req, HTTPResponse *res);
|
||||||
@@ -13,12 +12,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res);
|
|||||||
void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
|
void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleReport(HTTPRequest *req, HTTPResponse *res);
|
void handleReport(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleNodes(HTTPRequest *req, HTTPResponse *res);
|
void handleNodes(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleUpdateFs(HTTPRequest *req, HTTPResponse *res);
|
|
||||||
void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res);
|
|
||||||
void handleFs(HTTPRequest *req, HTTPResponse *res);
|
|
||||||
void handleAdmin(HTTPRequest *req, HTTPResponse *res);
|
void handleAdmin(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleAdminSettings(HTTPRequest *req, HTTPResponse *res);
|
|
||||||
void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res);
|
|
||||||
|
|
||||||
// Interface to the PhoneAPI to access the protobufs with messages
|
// Interface to the PhoneAPI to access the protobufs with messages
|
||||||
class HttpAPI : public PhoneAPI
|
class HttpAPI : public PhoneAPI
|
||||||
|
|||||||
@@ -1,14 +1,3 @@
|
|||||||
#include "mesh/http/ContentHelper.h"
|
#include "mesh/http/ContentHelper.h"
|
||||||
// #include <Arduino.h>
|
// #include <Arduino.h>
|
||||||
// #include "main.h"
|
// #include "main.h"
|
||||||
|
|
||||||
void replaceAll(std::string &str, const std::string &from, const std::string &to)
|
|
||||||
{
|
|
||||||
if (from.empty())
|
|
||||||
return;
|
|
||||||
size_t start_pos = 0;
|
|
||||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
|
||||||
str.replace(start_pos, from.length(), to);
|
|
||||||
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,5 +3,3 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define BoolToString(x) ((x) ? "true" : "false")
|
#define BoolToString(x) ((x) ? "true" : "false")
|
||||||
|
|
||||||
void replaceAll(std::string &str, const std::string &from, const std::string &to);
|
|
||||||
@@ -82,7 +82,6 @@ CannedMessageModule::CannedMessageModule()
|
|||||||
void CannedMessageModule::LaunchWithDestination(NodeNum newDest, uint8_t newChannel)
|
void CannedMessageModule::LaunchWithDestination(NodeNum newDest, uint8_t newChannel)
|
||||||
{
|
{
|
||||||
// Do NOT override explicit broadcast replies
|
// Do NOT override explicit broadcast replies
|
||||||
// Only reuse lastDest in LaunchRepeatDestination()
|
|
||||||
|
|
||||||
if (newDest == 0) {
|
if (newDest == 0) {
|
||||||
dest = NODENUM_BROADCAST;
|
dest = NODENUM_BROADCAST;
|
||||||
@@ -114,19 +113,9 @@ void CannedMessageModule::LaunchWithDestination(NodeNum newDest, uint8_t newChan
|
|||||||
LOG_DEBUG("[CannedMessage] LaunchWithDestination dest=0x%08x ch=%d", dest, channel);
|
LOG_DEBUG("[CannedMessage] LaunchWithDestination dest=0x%08x ch=%d", dest, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CannedMessageModule::LaunchRepeatDestination()
|
|
||||||
{
|
|
||||||
if (!lastDestSet) {
|
|
||||||
LaunchWithDestination(NODENUM_BROADCAST, 0);
|
|
||||||
} else {
|
|
||||||
LaunchWithDestination(lastDest, lastChannel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CannedMessageModule::LaunchFreetextWithDestination(NodeNum newDest, uint8_t newChannel)
|
void CannedMessageModule::LaunchFreetextWithDestination(NodeNum newDest, uint8_t newChannel)
|
||||||
{
|
{
|
||||||
// Do NOT override explicit broadcast replies
|
// Do NOT override explicit broadcast replies
|
||||||
// Only reuse lastDest in LaunchRepeatDestination()
|
|
||||||
|
|
||||||
if (newDest == 0) {
|
if (newDest == 0) {
|
||||||
dest = NODENUM_BROADCAST;
|
dest = NODENUM_BROADCAST;
|
||||||
@@ -308,12 +297,6 @@ void CannedMessageModule::updateDestinationSelectionList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if character input is currently allowed (used for search/freetext states)
|
|
||||||
bool CannedMessageModule::isCharInputAllowed() const
|
|
||||||
{
|
|
||||||
return runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || runState == CANNED_MESSAGE_RUN_STATE_DESTINATION_SELECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getRowHeightForEmoteText(const char *text, int minimumHeight, int emoteSpacing = 2)
|
static int getRowHeightForEmoteText(const char *text, int minimumHeight, int emoteSpacing = 2)
|
||||||
{
|
{
|
||||||
// Grow the row only when an emote is taller than the font.
|
// Grow the row only when an emote is taller than the font.
|
||||||
@@ -1437,13 +1420,6 @@ bool CannedMessageModule::shouldDraw()
|
|||||||
this->runState == CANNED_MESSAGE_RUN_STATE_EMOTE_PICKER);
|
this->runState == CANNED_MESSAGE_RUN_STATE_EMOTE_PICKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has the user defined any canned messages?
|
|
||||||
// Expose publicly whether canned message module is ready for use
|
|
||||||
bool CannedMessageModule::hasMessages()
|
|
||||||
{
|
|
||||||
return (this->messagesCount > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CannedMessageModule::getNextIndex()
|
int CannedMessageModule::getNextIndex()
|
||||||
{
|
{
|
||||||
if (this->currentMessageIndex >= (this->messagesCount - 1)) {
|
if (this->currentMessageIndex >= (this->messagesCount - 1)) {
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
CannedMessageModule();
|
CannedMessageModule();
|
||||||
|
|
||||||
void LaunchWithDestination(NodeNum, uint8_t newChannel = 0);
|
void LaunchWithDestination(NodeNum, uint8_t newChannel = 0);
|
||||||
void LaunchRepeatDestination();
|
|
||||||
void LaunchFreetextWithDestination(NodeNum, uint8_t newChannel = 0);
|
void LaunchFreetextWithDestination(NodeNum, uint8_t newChannel = 0);
|
||||||
|
|
||||||
// === Emote Picker navigation ===
|
// === Emote Picker navigation ===
|
||||||
@@ -70,11 +69,9 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
|
|
||||||
// === State/UI ===
|
// === State/UI ===
|
||||||
bool shouldDraw();
|
bool shouldDraw();
|
||||||
bool hasMessages();
|
|
||||||
void resetSearch();
|
void resetSearch();
|
||||||
void updateDestinationSelectionList();
|
void updateDestinationSelectionList();
|
||||||
void drawDestinationSelectionScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
void drawDestinationSelectionScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
bool isCharInputAllowed() const;
|
|
||||||
String drawWithCursor(String text, int cursor);
|
String drawWithCursor(String text, int cursor);
|
||||||
|
|
||||||
// === Emote Picker ===
|
// === Emote Picker ===
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ void OnScreenKeyboardModule::stop(bool callEmptyCallback)
|
|||||||
// Keep NotificationRenderer legacy pointers in sync
|
// Keep NotificationRenderer legacy pointers in sync
|
||||||
NotificationRenderer::virtualKeyboard = nullptr;
|
NotificationRenderer::virtualKeyboard = nullptr;
|
||||||
NotificationRenderer::textInputCallback = nullptr;
|
NotificationRenderer::textInputCallback = nullptr;
|
||||||
clearPopup();
|
|
||||||
if (callEmptyCallback && cb)
|
if (callEmptyCallback && cb)
|
||||||
cb("");
|
cb("");
|
||||||
}
|
}
|
||||||
@@ -131,9 +130,6 @@ bool OnScreenKeyboardModule::draw(OLEDDisplay *display)
|
|||||||
display->fillRect(0, 0, display->getWidth(), display->getHeight());
|
display->fillRect(0, 0, display->getWidth(), display->getHeight());
|
||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
keyboard->draw(display, 0, 0);
|
keyboard->draw(display, 0, 0);
|
||||||
|
|
||||||
// Draw popup overlay if needed
|
|
||||||
drawPopup(display);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,123 +146,6 @@ void OnScreenKeyboardModule::onCancel()
|
|||||||
stop(true);
|
stop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnScreenKeyboardModule::showPopup(const char *title, const char *content, uint32_t durationMs)
|
|
||||||
{
|
|
||||||
if (!title || !content)
|
|
||||||
return;
|
|
||||||
strncpy(popupTitle, title, sizeof(popupTitle) - 1);
|
|
||||||
popupTitle[sizeof(popupTitle) - 1] = '\0';
|
|
||||||
strncpy(popupMessage, content, sizeof(popupMessage) - 1);
|
|
||||||
popupMessage[sizeof(popupMessage) - 1] = '\0';
|
|
||||||
popupUntil = millis() + durationMs;
|
|
||||||
popupVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnScreenKeyboardModule::clearPopup()
|
|
||||||
{
|
|
||||||
popupTitle[0] = '\0';
|
|
||||||
popupMessage[0] = '\0';
|
|
||||||
popupUntil = 0;
|
|
||||||
popupVisible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnScreenKeyboardModule::drawPopupOverlay(OLEDDisplay *display)
|
|
||||||
{
|
|
||||||
// Only render the popup overlay (without drawing the keyboard)
|
|
||||||
drawPopup(display);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnScreenKeyboardModule::drawPopup(OLEDDisplay *display)
|
|
||||||
{
|
|
||||||
if (!popupVisible)
|
|
||||||
return;
|
|
||||||
if (millis() > popupUntil || popupMessage[0] == '\0') {
|
|
||||||
popupVisible = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build lines and leverage NotificationRenderer inverted box drawing for consistent style
|
|
||||||
constexpr uint16_t maxContentLines = 3;
|
|
||||||
const bool hasTitle = popupTitle[0] != '\0';
|
|
||||||
|
|
||||||
display->setFont(FONT_SMALL);
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
||||||
const uint16_t maxWrapWidth = display->width() - 40;
|
|
||||||
|
|
||||||
auto wrapText = [&](const char *text, uint16_t availableWidth) -> std::vector<std::string> {
|
|
||||||
std::vector<std::string> wrapped;
|
|
||||||
std::string current;
|
|
||||||
std::string word;
|
|
||||||
const char *p = text;
|
|
||||||
while (*p && wrapped.size() < maxContentLines) {
|
|
||||||
while (*p && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) {
|
|
||||||
if (*p == '\n') {
|
|
||||||
if (!current.empty()) {
|
|
||||||
wrapped.push_back(current);
|
|
||||||
current.clear();
|
|
||||||
if (wrapped.size() >= maxContentLines)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
if (!*p || wrapped.size() >= maxContentLines)
|
|
||||||
break;
|
|
||||||
word.clear();
|
|
||||||
while (*p && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
|
|
||||||
word += *p++;
|
|
||||||
if (word.empty())
|
|
||||||
continue;
|
|
||||||
std::string test = current.empty() ? word : (current + " " + word);
|
|
||||||
uint16_t w = display->getStringWidth(test.c_str(), test.length(), true);
|
|
||||||
if (w <= availableWidth)
|
|
||||||
current = test;
|
|
||||||
else {
|
|
||||||
if (!current.empty()) {
|
|
||||||
wrapped.push_back(current);
|
|
||||||
current = word;
|
|
||||||
if (wrapped.size() >= maxContentLines)
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
current = word;
|
|
||||||
while (current.size() > 1 &&
|
|
||||||
display->getStringWidth(current.c_str(), current.length(), true) > availableWidth)
|
|
||||||
current.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!current.empty() && wrapped.size() < maxContentLines)
|
|
||||||
wrapped.push_back(current);
|
|
||||||
return wrapped;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::string> allLines;
|
|
||||||
if (hasTitle)
|
|
||||||
allLines.emplace_back(popupTitle);
|
|
||||||
|
|
||||||
char buf[sizeof(popupMessage)];
|
|
||||||
strncpy(buf, popupMessage, sizeof(buf) - 1);
|
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
|
||||||
char *paragraph = strtok(buf, "\n");
|
|
||||||
while (paragraph && allLines.size() < maxContentLines + (hasTitle ? 1 : 0)) {
|
|
||||||
auto wrapped = wrapText(paragraph, maxWrapWidth);
|
|
||||||
for (const auto &ln : wrapped) {
|
|
||||||
if (allLines.size() >= maxContentLines + (hasTitle ? 1 : 0))
|
|
||||||
break;
|
|
||||||
allLines.push_back(ln);
|
|
||||||
}
|
|
||||||
paragraph = strtok(nullptr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char *> ptrs;
|
|
||||||
for (const auto &ln : allLines)
|
|
||||||
ptrs.push_back(ln.c_str());
|
|
||||||
ptrs.push_back(nullptr);
|
|
||||||
|
|
||||||
// Use the standard notification box drawing from NotificationRenderer
|
|
||||||
NotificationRenderer::drawNotificationBox(display, nullptr, ptrs.data(), allLines.size(), 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
|
|
||||||
#endif // HAS_SCREEN
|
#endif // HAS_SCREEN
|
||||||
@@ -25,11 +25,6 @@ class OnScreenKeyboardModule
|
|||||||
static bool processVirtualKeyboardInput(const InputEvent &event, VirtualKeyboard *keyboard);
|
static bool processVirtualKeyboardInput(const InputEvent &event, VirtualKeyboard *keyboard);
|
||||||
bool draw(OLEDDisplay *display);
|
bool draw(OLEDDisplay *display);
|
||||||
|
|
||||||
void showPopup(const char *title, const char *content, uint32_t durationMs);
|
|
||||||
void clearPopup();
|
|
||||||
// Draw only the popup overlay (used when legacy virtualKeyboard draws the keyboard)
|
|
||||||
void drawPopupOverlay(OLEDDisplay *display);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OnScreenKeyboardModule() = default;
|
OnScreenKeyboardModule() = default;
|
||||||
~OnScreenKeyboardModule();
|
~OnScreenKeyboardModule();
|
||||||
@@ -39,15 +34,8 @@ class OnScreenKeyboardModule
|
|||||||
void onSubmit(const std::string &text);
|
void onSubmit(const std::string &text);
|
||||||
void onCancel();
|
void onCancel();
|
||||||
|
|
||||||
void drawPopup(OLEDDisplay *display);
|
|
||||||
|
|
||||||
VirtualKeyboard *keyboard = nullptr;
|
VirtualKeyboard *keyboard = nullptr;
|
||||||
std::function<void(const std::string &)> callback;
|
std::function<void(const std::string &)> callback;
|
||||||
|
|
||||||
char popupTitle[64] = {0};
|
|
||||||
char popupMessage[256] = {0};
|
|
||||||
uint32_t popupUntil = 0;
|
|
||||||
bool popupVisible = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ float UnitConversions::MetersPerSecondToKnots(float metersPerSecond)
|
|||||||
return metersPerSecond * 1.94384;
|
return metersPerSecond * 1.94384;
|
||||||
}
|
}
|
||||||
|
|
||||||
float UnitConversions::MetersPerSecondToMilesPerHour(float metersPerSecond)
|
|
||||||
{
|
|
||||||
return metersPerSecond * 2.23694;
|
|
||||||
}
|
|
||||||
|
|
||||||
float UnitConversions::HectoPascalToInchesOfMercury(float hectoPascal)
|
float UnitConversions::HectoPascalToInchesOfMercury(float hectoPascal)
|
||||||
{
|
{
|
||||||
return hectoPascal * 0.029529983071445;
|
return hectoPascal * 0.029529983071445;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ class UnitConversions
|
|||||||
public:
|
public:
|
||||||
static float CelsiusToFahrenheit(float celsius);
|
static float CelsiusToFahrenheit(float celsius);
|
||||||
static float MetersPerSecondToKnots(float metersPerSecond);
|
static float MetersPerSecondToKnots(float metersPerSecond);
|
||||||
static float MetersPerSecondToMilesPerHour(float metersPerSecond);
|
|
||||||
static float HectoPascalToInchesOfMercury(float hectoPascal);
|
static float HectoPascalToInchesOfMercury(float hectoPascal);
|
||||||
|
|
||||||
// Bound a float before Arduino String(float) renders it: its fixed char[33] + dtostrf overflow
|
// Bound a float before Arduino String(float) renders it: its fixed char[33] + dtostrf overflow
|
||||||
|
|||||||
@@ -78,16 +78,6 @@ uint8_t sanitizePositionPrecision(uint8_t precision)
|
|||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Saturating increment for uint8_t counters.
|
|
||||||
* Prevents overflow by capping at UINT8_MAX (255).
|
|
||||||
*/
|
|
||||||
inline void saturatingIncrement(uint8_t &counter)
|
|
||||||
{
|
|
||||||
if (counter < UINT8_MAX)
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a short human-readable name for common port numbers.
|
* Return a short human-readable name for common port numbers.
|
||||||
* Falls back to "port:<N>" for unknown ports.
|
* Falls back to "port:<N>" for unknown ports.
|
||||||
@@ -224,19 +214,6 @@ meshtastic_TrafficManagementStats TrafficManagementModule::getStats() const
|
|||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrafficManagementModule::resetStats()
|
|
||||||
{
|
|
||||||
concurrency::LockGuard guard(&cacheLock);
|
|
||||||
stats = meshtastic_TrafficManagementStats_init_zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrafficManagementModule::recordRouterHopPreserved()
|
|
||||||
{
|
|
||||||
// router_preserve_hops: not suitable right now - removed from config until
|
|
||||||
// the right heuristic for when to preserve vs. exhaust is clearer.
|
|
||||||
(void)stats.router_hops_preserved;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrafficManagementModule::incrementStat(uint32_t *field)
|
void TrafficManagementModule::incrementStat(uint32_t *field)
|
||||||
{
|
{
|
||||||
concurrency::LockGuard guard(&cacheLock);
|
concurrency::LockGuard guard(&cacheLock);
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ class TrafficManagementModule : public MeshModule, private concurrency::OSThread
|
|||||||
TrafficManagementModule &operator=(const TrafficManagementModule &) = delete;
|
TrafficManagementModule &operator=(const TrafficManagementModule &) = delete;
|
||||||
|
|
||||||
meshtastic_TrafficManagementStats getStats() const;
|
meshtastic_TrafficManagementStats getStats() const;
|
||||||
void resetStats();
|
|
||||||
void recordRouterHopPreserved();
|
|
||||||
|
|
||||||
// Next-hop overflow cache (routing hint).
|
// Next-hop overflow cache (routing hint).
|
||||||
// setNextHop: store a confirmed last-byte next hop for `dest`. Called by
|
// setNextHop: store a confirmed last-byte next hop for `dest`. Called by
|
||||||
|
|||||||
@@ -444,16 +444,6 @@ bool BMI270Sensor::writeRegister(uint8_t reg, uint8_t value)
|
|||||||
return wire->endTransmission() == 0;
|
return wire->endTransmission() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BMI270Sensor::writeRegisters(uint8_t reg, const uint8_t *data, size_t len)
|
|
||||||
{
|
|
||||||
wire->beginTransmission(deviceAddress());
|
|
||||||
wire->write(reg);
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
wire->write(data[i]);
|
|
||||||
}
|
|
||||||
return wire->endTransmission() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t BMI270Sensor::readRegister(uint8_t reg)
|
uint8_t BMI270Sensor::readRegister(uint8_t reg)
|
||||||
{
|
{
|
||||||
wire->beginTransmission(deviceAddress());
|
wire->beginTransmission(deviceAddress());
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ class BMI270Sensor : public MotionSensor
|
|||||||
|
|
||||||
// BMI270 register access
|
// BMI270 register access
|
||||||
bool writeRegister(uint8_t reg, uint8_t value);
|
bool writeRegister(uint8_t reg, uint8_t value);
|
||||||
bool writeRegisters(uint8_t reg, const uint8_t *data, size_t len);
|
|
||||||
uint8_t readRegister(uint8_t reg);
|
uint8_t readRegister(uint8_t reg);
|
||||||
bool readRegisters(uint8_t reg, uint8_t *data, size_t len);
|
bool readRegisters(uint8_t reg, uint8_t *data, size_t len);
|
||||||
|
|
||||||
|
|||||||
@@ -1078,16 +1078,6 @@ bool isSessionExpired()
|
|||||||
return (millis() - s_sessionStartedMs) > s_sessionMaxMs;
|
return (millis() - s_sessionStartedMs) > s_sessionMaxMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getSessionRemainingSeconds()
|
|
||||||
{
|
|
||||||
if (s_sessionMaxMs == 0)
|
|
||||||
return 0;
|
|
||||||
uint32_t elapsedMs = millis() - s_sessionStartedMs;
|
|
||||||
if (elapsedMs >= s_sessionMaxMs)
|
|
||||||
return 0;
|
|
||||||
return (s_sessionMaxMs - elapsedMs) / 1000UL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t consumeSessionBoot()
|
uint8_t consumeSessionBoot()
|
||||||
{
|
{
|
||||||
if (s_bootsRemaining == 0) {
|
if (s_bootsRemaining == 0) {
|
||||||
|
|||||||
@@ -243,10 +243,6 @@ void setSession(uint32_t maxSeconds);
|
|||||||
/// from the main loop on a low-frequency tick.
|
/// from the main loop on a low-frequency tick.
|
||||||
bool isSessionExpired();
|
bool isSessionExpired();
|
||||||
|
|
||||||
/// Seconds remaining in the current session. 0 if no timer is set, or if
|
|
||||||
/// the timer has expired (use isSessionExpired() to distinguish).
|
|
||||||
uint32_t getSessionRemainingSeconds();
|
|
||||||
|
|
||||||
/// Consume one boot from the on-flash token (the rollback ledger) and
|
/// Consume one boot from the on-flash token (the rollback ledger) and
|
||||||
/// re-arm the session timer in place - no reboot. Called from the main
|
/// re-arm the session timer in place - no reboot. Called from the main
|
||||||
/// loop when a session expires AND there is still budget. Decrements
|
/// loop when a session expires AND there is still budget. Decrements
|
||||||
|
|||||||
Reference in New Issue
Block a user