Merge branch 'master' into batt_stat

This commit is contained in:
gitbisector
2024-09-06 17:23:38 -07:00
committed by GitHub
32 changed files with 235 additions and 140 deletions
+3 -1
View File
@@ -97,12 +97,14 @@ Syslog &Syslog::logMask(uint8_t priMask)
void Syslog::enable()
{
this->_client->begin(this->_port);
this->_enabled = true;
}
void Syslog::disable()
{
this->_enabled = false;
this->_client->stop();
}
bool Syslog::isEnabled()
@@ -193,4 +195,4 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
return true;
}
#endif
#endif
+10 -13
View File
@@ -507,19 +507,19 @@ bool GPS::setup()
delay(250);
} else if (gnssModel == GNSS_MODEL_AG3335) {
_serial_gps->write("$PAIR066,1,0,1,0,0,1*3B"); // Enable GPS+GALILEO+NAVIC
_serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC
// Configure NMEA (sentences will output once per fix)
_serial_gps->write("$PAIR062,0,0*3F"); // GGA ON
_serial_gps->write("$PAIR062,1,0*3F"); // GLL OFF
_serial_gps->write("$PAIR062,2,1*3D"); // GSA ON
_serial_gps->write("$PAIR062,3,0*3D"); // GSV OFF
_serial_gps->write("$PAIR062,4,0*3B"); // RMC ON
_serial_gps->write("$PAIR062,5,0*3B"); // VTG OFF
_serial_gps->write("$PAIR062,6,1*39"); // ZDA ON
_serial_gps->write("$PAIR062,0,0*3F\r\n"); // GGA ON
_serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF
_serial_gps->write("$PAIR062,2,1*3D\r\n"); // GSA ON
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF
_serial_gps->write("$PAIR062,4,0*3B\r\n"); // RMC ON
_serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF
_serial_gps->write("$PAIR062,6,1*39\r\n"); // ZDA ON
delay(250);
_serial_gps->write("$PAIR513*3D"); // save configuration
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
} else if (gnssModel == GNSS_MODEL_UBLOX) {
// Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command)
@@ -1252,9 +1252,6 @@ GnssModel_t GPS::probe(int serialSpeed)
LOG_INFO("Aioha AG3335 detected, using AG3335 Module\n");
return GNSS_MODEL_AG3335;
}
// Get version information for Airoha AG3335
clearBuffer();
_serial_gps->write("$PMTK605*31\r\n");
// Get version information
clearBuffer();
@@ -1843,4 +1840,4 @@ void GPS::toggleGpsMode()
enable();
}
}
#endif // Exclude GPS
#endif // Exclude GPS
+5
View File
@@ -1766,6 +1766,11 @@ void Screen::forceDisplay(bool forceUiUpdate)
#ifdef USE_EINK
// If requested, make sure queued commands are run, and UI has rendered a new frame
if (forceUiUpdate) {
// Force a display refresh, in addition to the UI update
// Changing the GPS status bar icon apparently doesn't register as a change in image
// (False negative of the image hashing algorithm used to skip identical frames)
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST);
// No delay between UI frame rendering
setFastFramerate();
+14
View File
@@ -4,6 +4,20 @@
#define ANYKEY 0xFF
#define MATRIXKEY 0xFE
#define INPUT_BROKER_MSG_BRIGHTNESS_UP 0x11
#define INPUT_BROKER_MSG_BRIGHTNESS_DOWN 0x12
#define INPUT_BROKER_MSG_REBOOT 0x90
#define INPUT_BROKER_MSG_SHUTDOWN 0x9b
#define INPUT_BROKER_MSG_GPS_TOGGLE 0x9e
#define INPUT_BROKER_MSG_MUTE_TOGGLE 0xac
#define INPUT_BROKER_MSG_SEND_PING 0xaf
#define INPUT_BROKER_MSG_LEFT 0xb4
#define INPUT_BROKER_MSG_UP 0xb5
#define INPUT_BROKER_MSG_DOWN 0xb6
#define INPUT_BROKER_MSG_RIGHT 0xb7
#define INPUT_BROKER_MSG_FN_SYMBOL_ON 0xf1
#define INPUT_BROKER_MSG_FN_SYMBOL_OFF 0xf2
typedef struct _InputEvent {
const char *source;
char inputEvent;
+2 -2
View File
@@ -147,11 +147,11 @@ int32_t LinuxInput::runOnce()
case KEY_LEFT: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
break;
e.kbchar = 0xb4;
e.kbchar = INPUT_BROKER_MSG_LEFT;
case KEY_RIGHT: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
break;
e.kbchar = 0xb7;
e.kbchar = INPUT_BROKER_MSG_RIGHT;
case KEY_ENTER: // Enter
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
+1 -1
View File
@@ -87,7 +87,7 @@ int32_t SerialKeyboard::runOnce()
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
} else if (!(shiftRegister2 & (1 << 2))) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = 0xb7;
e.kbchar = INPUT_BROKER_MSG_RIGHT;
} else if (!(shiftRegister2 & (1 << 1))) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
} else if (!(shiftRegister2 & (1 << 0))) {
+20 -19
View File
@@ -94,7 +94,7 @@ int32_t KbI2cBase::runOnce()
case 'e': // sym e
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = 0xb5;
e.kbchar = INPUT_BROKER_MSG_UP;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
@@ -104,7 +104,7 @@ int32_t KbI2cBase::runOnce()
case 'x': // sym x
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = 0xb6;
e.kbchar = INPUT_BROKER_MSG_DOWN;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
@@ -134,8 +134,8 @@ int32_t KbI2cBase::runOnce()
case 0x13: // Code scanner says the SYM key is 0x13
is_sym = !is_sym;
e.inputEvent = ANYKEY;
e.kbchar =
is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
e.kbchar = is_sym ? INPUT_BROKER_MSG_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that
: INPUT_BROKER_MSG_FN_SYMBOL_OFF; // the modifier key is active
break;
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
@@ -214,7 +214,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0xac; // mute notifications
e.kbchar = INPUT_BROKER_MSG_MUTE_TOGGLE; // mute notifications
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -224,7 +224,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0x11; // Increase Brightness code
e.kbchar = INPUT_BROKER_MSG_BRIGHTNESS_UP; // Increase Brightness code
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -234,7 +234,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0x12; // Decrease Brightness code
e.kbchar = INPUT_BROKER_MSG_BRIGHTNESS_DOWN; // Decrease Brightness code
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -244,7 +244,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0xaf; // (fn + space)
e.kbchar = INPUT_BROKER_MSG_SEND_PING; // (fn + space)
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -254,7 +254,7 @@ int32_t KbI2cBase::runOnce()
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0x9e;
e.kbchar = INPUT_BROKER_MSG_GPS_TOGGLE;
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
@@ -269,32 +269,33 @@ int32_t KbI2cBase::runOnce()
break;
case 0xb5: // Up
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = 0xb5;
e.kbchar = INPUT_BROKER_MSG_UP;
break;
case 0xb6: // Down
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = 0xb6;
e.kbchar = INPUT_BROKER_MSG_DOWN;
break;
case 0xb4: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = 0xb4;
e.kbchar = INPUT_BROKER_MSG_LEFT;
break;
case 0xb7: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = 0xb7;
e.kbchar = INPUT_BROKER_MSG_RIGHT;
break;
case 0xc: // Modifier key: 0xc is alt+c (Other options could be: 0xea = shift+mic button or 0x4 shift+$(speaker))
// toggle moddifiers button.
is_sym = !is_sym;
e.inputEvent = ANYKEY;
e.kbchar = is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
e.kbchar = is_sym ? INPUT_BROKER_MSG_FN_SYMBOL_ON // send 0xf1 to tell CannedMessages to display that the
: INPUT_BROKER_MSG_FN_SYMBOL_OFF; // modifier key is active
break;
case 0x90: // fn+r
case 0x90: // fn+r INPUT_BROKER_MSG_REBOOT
case 0x91: // fn+t
case 0x9b: // fn+s
case 0xac: // fn+m
case 0x9e: // fn+g
case 0xaf: // fn+space
case 0x9b: // fn+s INPUT_BROKER_MSG_SHUTDOWN
case 0xac: // fn+m INPUT_BROKER_MSG_MUTE_TOGGLE
case 0x9e: // fn+g INPUT_BROKER_MSG_GPS_TOGGLE
case 0xaf: // fn+space INPUT_BROKER_MSG_SEND_PING
// just pass those unmodified
e.inputEvent = ANYKEY;
e.kbchar = c;
-2
View File
@@ -635,8 +635,6 @@ void setup()
#if !MESHTASTIC_EXCLUDE_I2C
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (acc_info.type != ScanI2C::DeviceType::NONE) {
config.display.wake_on_tap_or_motion = true;
moduleConfig.external_notification.enabled = true;
accelerometerThread = new AccelerometerThread(acc_info.type);
}
#endif
+25 -6
View File
@@ -50,11 +50,23 @@ template <typename T> bool LR11x0Interface<T>::init()
limitPower();
#ifdef TRACKER_T1000_E // Tracker T1000E uses DIO5, DIO6, DIO7, DIO8 for RF switching
static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7,
RADIOLIB_LR11X0_DIO8, RADIOLIB_NC};
static const Module::RfSwitchMode_t rfswitch_table[] = {
// mode DIO5 DIO6 DIO7 DIO8
{LR11x0::MODE_STBY, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW, LOW, HIGH}},
{LR11x0::MODE_TX, {HIGH, HIGH, LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH, LOW, HIGH}},
{LR11x0::MODE_TX_HF, {LOW, LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH, LOW}},
{LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW}}, END_OF_MODE_TABLE,
};
#else
// set RF switch configuration for Wio WM1110
// Wio WM1110 uses DIO5 and DIO6 for RF switching
// NOTE: other boards may be different. If you are
// using a different board, you may need to wrap
// this in a conditional.
static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC,
RADIOLIB_NC};
@@ -67,6 +79,8 @@ template <typename T> bool LR11x0Interface<T>::init()
{LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE,
};
#endif
// We need to do this before begin() call
#ifdef LR11X0_DIO_AS_RF_SWITCH
LOG_DEBUG("Setting DIO RF switch\n");
@@ -90,6 +104,13 @@ template <typename T> bool LR11x0Interface<T>::init()
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND)
return false;
LR11x0VersionInfo_t version;
res = lora.getVersionInfo(&version);
if (res == RADIOLIB_ERR_NONE)
LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d\n", version.device, version.hardware,
version.fwMajor, version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS,
version.almanacGNSS);
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
@@ -218,9 +239,7 @@ template <typename T> void LR11x0Interface<T>::startReceive()
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err = lora.startReceive(
RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_LR11X0_IRQ_RX_DONE,
0); // only RX_DONE IRQ is needed, we'll check for PREAMBLE_DETECTED and HEADER_VALID in isActivelyReceiving
int err = lora.startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
assert(err == RADIOLIB_ERR_NONE);
RadioLibInterface::startReceive();
+21 -33
View File
@@ -1,4 +1,5 @@
#include "MeshPacketQueue.h"
#include "NodeDB.h"
#include "configuration.h"
#include <assert.h>
@@ -16,13 +17,9 @@ bool CompareMeshPacketFunc(const meshtastic_MeshPacket *p1, const meshtastic_Mes
{
assert(p1 && p2);
auto p1p = getPriority(p1), p2p = getPriority(p2);
// If priorities differ, use that
// for equal priorities, order by id (older packets have higher priority - this will briefly be wrong when IDs roll over but
// no big deal)
return (p1p != p2p)
? (p1p < p2p) // prefer bigger priorities
: ((p1->id & ID_COUNTER_MASK) >= (p2->id & ID_COUNTER_MASK)); // Mask to counter portion, prefer smaller packet ids
// for equal priorities, prefer packets already on mesh.
return (p1p != p2p) ? (p1p > p2p) : (getFrom(p1) != nodeDB->getNodeNum() && getFrom(p2) == nodeDB->getNodeNum());
}
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}
@@ -69,8 +66,9 @@ bool MeshPacketQueue::enqueue(meshtastic_MeshPacket *p)
return replaceLowerPriorityPacket(p);
}
queue.push_back(p);
std::push_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
// Find the correct position using upper_bound to maintain a stable order
auto it = std::upper_bound(queue.begin(), queue.end(), p, CompareMeshPacketFunc);
queue.insert(it, p); // Insert packet at the found position
return true;
}
@@ -81,9 +79,7 @@ meshtastic_MeshPacket *MeshPacketQueue::dequeue()
}
auto *p = queue.front();
std::pop_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
queue.pop_back();
queue.erase(queue.begin()); // Remove the highest-priority packet
return p;
}
@@ -104,7 +100,6 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
auto p = (*it);
if (getFrom(p) == from && p->id == id) {
queue.erase(it);
std::make_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
return p;
}
}
@@ -115,28 +110,21 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p)
{
std::sort_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); // sort ascending based on priority (0 -> 127)
// find first packet which does not compare less (in priority) than parameter packet
auto low = std::lower_bound(queue.begin(), queue.end(), p, &CompareMeshPacketFunc);
if (low == queue.begin()) { // if already at start, there are no packets with lower priority
return false;
if (queue.empty()) {
return false; // No packets to replace
}
// Check if the packet at the back has a lower priority than the new packet
auto &backPacket = queue.back();
if (backPacket->priority < p->priority) {
// Remove the back packet
packetPool.release(backPacket);
queue.pop_back();
// Insert the new packet in the correct order
enqueue(p);
return true;
}
if (low == queue.end()) {
// all priorities in the vector are smaller than the incoming packet. Replace the lowest priority (first) element
low = queue.begin();
} else {
// 'low' iterator points to first packet which does not compare less than parameter
--low; // iterate to lower priority packet
}
if (getPriority(p) > getPriority(*low)) {
packetPool.release(*low); // deallocate and drop the packet we're replacing
*low = p; // replace low-pri packet at this position with incoming packet with higher priority
}
std::make_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc);
return true;
// If the back packet's priority is not lower, no replacement occurs
return false;
}
+4 -1
View File
@@ -362,6 +362,9 @@ void NodeDB::installDefaultConfig()
#ifdef DISPLAY_FLIP_SCREEN
config.display.flip_screen = true;
#endif
#ifdef RAK4630
config.display.wake_on_tap_or_motion = true;
#endif
#ifdef T_WATCH_S3
config.display.screen_on_secs = 30;
config.display.wake_on_tap_or_motion = true;
@@ -1190,4 +1193,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
LOG_ERROR("A critical failure occurred, portduino is exiting...");
exit(2);
#endif
}
}
+1 -1
View File
@@ -420,7 +420,7 @@ void RadioInterface::applyModemConfig()
switch (loraConfig.modem_preset) {
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO:
bw = (myRegion->wideLora) ? 812.5 : 500;
bw = (myRegion->wideLora) ? 1625.0 : 500;
cr = 5;
sf = 7;
break;
+1 -6
View File
@@ -12,9 +12,6 @@
#define SX126X_MAX_POWER 22
#endif
#define RADIOLIB_SX126X_IRQ_RX_DEFAULT \
RADIOLIB_SX126X_IRQ_RX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT | RADIOLIB_SX126X_IRQ_CRC_ERR | RADIOLIB_SX126X_IRQ_HEADER_ERR
template <typename T>
SX126xInterface<T>::SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy)
@@ -267,9 +264,7 @@ template <typename T> void SX126xInterface<T>::startReceive()
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8,
RADIOLIB_SX126X_IRQ_RX_DEFAULT | RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED |
RADIOLIB_SX126X_IRQ_HEADER_VALID);
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX126X startReceiveDutyCycleAuto!\n", err);
assert(err == RADIOLIB_ERR_NONE);
+1 -7
View File
@@ -12,10 +12,6 @@
#define SX128X_MAX_POWER 13
#endif
#define RADIOLIB_SX128X_IRQ_RX_DEFAULT \
RADIOLIB_SX128X_IRQ_RX_DONE | RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT | RADIOLIB_SX128X_IRQ_CRC_ERROR | \
RADIOLIB_SX128X_IRQ_HEADER_ERROR
template <typename T>
SX128xInterface<T>::SX128xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy)
@@ -260,9 +256,7 @@ template <typename T> void SX128xInterface<T>::startReceive()
#endif
// We use the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err =
lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_SX128X_IRQ_RX_DEFAULT | RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED |
RADIOLIB_SX128X_IRQ_HEADER_VALID);
int err = lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX128X startReceive!\n", err);
+14 -1
View File
@@ -5,7 +5,7 @@
template <typename T>
ServerAPI<T>::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client)
{
LOG_INFO("Incoming wifi connection\n");
LOG_INFO("Incoming API connection\n");
}
template <typename T> ServerAPI<T>::~ServerAPI()
@@ -49,6 +49,16 @@ template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
if (client) {
// Close any previous connection (see FIXME in header file)
if (openAPI) {
#if RAK_4631
// RAK13800 Ethernet requests periodically take more time
// This backoff addresses most cases keeping max wait < 1s
// Reconnections are delayed by full wait time
if (waitTime < 400) {
waitTime *= 2;
LOG_INFO("Previous TCP connection still open, trying again in %dms\n", waitTime);
return waitTime;
}
#endif
LOG_INFO("Force closing previous TCP connection\n");
delete openAPI;
}
@@ -56,5 +66,8 @@ template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
openAPI = new T(client);
}
#if RAK_4631
waitTime = 100;
#endif
return 100; // only check occasionally for incoming connections
}
+5 -1
View File
@@ -31,7 +31,7 @@ template <class T> class ServerAPI : public StreamAPI, private concurrency::OSTh
};
/**
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
* Listens for incoming connections and does accepts and creates instances of ServerAPI as needed
*/
template <class T, class U> class APIServerPort : public U, private concurrency::OSThread
{
@@ -41,6 +41,10 @@ template <class T, class U> class APIServerPort : public U, private concurrency:
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
*/
T *openAPI = NULL;
#if RAK_4631
// Track wait time for RAK13800 Ethernet requests
int32_t waitTime = 100;
#endif
public:
explicit APIServerPort(int port);
+1 -1
View File
@@ -14,7 +14,7 @@ class ethServerAPI : public ServerAPI<EthernetClient>
};
/**
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
* Listens for incoming connections and does accepts and creates instances of EthernetServerAPI as needed
*/
class ethServerPort : public APIServerPort<ethServerAPI, EthernetServer>
{
+4 -3
View File
@@ -38,7 +38,7 @@ static int32_t reconnectETH()
Ethernet.maintain();
if (!ethStartupComplete) {
// Start web server
LOG_INFO("... Starting network services\n");
LOG_INFO("Starting Ethernet network services\n");
#ifndef DISABLE_NTP
LOG_INFO("Starting NTP time client\n");
@@ -131,7 +131,8 @@ bool initEthernet()
status = Ethernet.begin(mac);
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
LOG_INFO("starting Ethernet Static\n");
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.gateway,
config.network.ipv4_config.subnet);
status = 1;
} else {
LOG_INFO("Ethernet Disabled\n");
@@ -186,4 +187,4 @@ bool isEthernetAvailable()
}
}
#endif
#endif
+1 -1
View File
@@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
#define meshtastic_ChannelSet_size 676
#define meshtastic_ChannelSet_size 679
#ifdef __cplusplus
} /* extern "C" */
+8 -4
View File
@@ -510,6 +510,8 @@ typedef struct _meshtastic_Config_LoRaConfig {
uint32_t ignore_incoming[3];
/* If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. */
bool ignore_mqtt;
/* Sets the ok_to_mqtt bit on outgoing packets */
bool config_ok_to_mqtt;
} meshtastic_Config_LoRaConfig;
typedef struct _meshtastic_Config_BluetoothConfig {
@@ -656,7 +658,7 @@ extern "C" {
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0}
#define meshtastic_Config_SessionkeyConfig_init_default {0}
@@ -667,7 +669,7 @@ extern "C" {
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
#define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_SecurityConfig_init_zero {{0, {0}}, {0, {0}}, 0, {{0, {0}}}, 0, 0, 0, 0}
#define meshtastic_Config_SessionkeyConfig_init_zero {0}
@@ -746,6 +748,7 @@ extern "C" {
#define meshtastic_Config_LoRaConfig_pa_fan_disabled_tag 15
#define meshtastic_Config_LoRaConfig_ignore_incoming_tag 103
#define meshtastic_Config_LoRaConfig_ignore_mqtt_tag 104
#define meshtastic_Config_LoRaConfig_config_ok_to_mqtt_tag 105
#define meshtastic_Config_BluetoothConfig_enabled_tag 1
#define meshtastic_Config_BluetoothConfig_mode_tag 2
#define meshtastic_Config_BluetoothConfig_fixed_pin_tag 3
@@ -887,7 +890,8 @@ X(a, STATIC, SINGULAR, BOOL, sx126x_rx_boosted_gain, 13) \
X(a, STATIC, SINGULAR, FLOAT, override_frequency, 14) \
X(a, STATIC, SINGULAR, BOOL, pa_fan_disabled, 15) \
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \
X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104)
X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104) \
X(a, STATIC, SINGULAR, BOOL, config_ok_to_mqtt, 105)
#define meshtastic_Config_LoRaConfig_CALLBACK NULL
#define meshtastic_Config_LoRaConfig_DEFAULT NULL
@@ -944,7 +948,7 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg;
#define meshtastic_Config_BluetoothConfig_size 10
#define meshtastic_Config_DeviceConfig_size 98
#define meshtastic_Config_DisplayConfig_size 30
#define meshtastic_Config_LoRaConfig_size 82
#define meshtastic_Config_LoRaConfig_size 85
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 196
#define meshtastic_Config_PositionConfig_size 62
@@ -358,7 +358,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
#define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 183
#define meshtastic_OEMStore_size 3497
#define meshtastic_OEMStore_size 3500
#define meshtastic_PositionLite_size 28
#define meshtastic_UserLite_size 96
+1 -1
View File
@@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size
#define meshtastic_LocalConfig_size 664
#define meshtastic_LocalConfig_size 667
#define meshtastic_LocalModuleConfig_size 687
#ifdef __cplusplus
+10 -5
View File
@@ -580,6 +580,9 @@ typedef struct _meshtastic_Data {
/* Defaults to false. If true, then what is in the payload should be treated as an emoji like giving
a message a heart or poop emoji. */
uint32_t emoji;
/* Bitfield for extra flags. First use is to indicate that user approves the packet being uploaded to MQTT. */
bool has_bitfield;
uint8_t bitfield;
} meshtastic_Data;
/* Waypoint message, used to share arbitrary locations across the mesh */
@@ -1082,7 +1085,7 @@ extern "C" {
#define meshtastic_User_init_default {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
@@ -1107,7 +1110,7 @@ extern "C" {
#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
@@ -1176,6 +1179,7 @@ extern "C" {
#define meshtastic_Data_request_id_tag 6
#define meshtastic_Data_reply_id_tag 7
#define meshtastic_Data_emoji_tag 8
#define meshtastic_Data_bitfield_tag 9
#define meshtastic_Waypoint_id_tag 1
#define meshtastic_Waypoint_latitude_i_tag 2
#define meshtastic_Waypoint_longitude_i_tag 3
@@ -1351,7 +1355,8 @@ X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
X(a, STATIC, SINGULAR, FIXED32, source, 5) \
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
X(a, STATIC, SINGULAR, FIXED32, emoji, 8)
X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \
X(a, STATIC, OPTIONAL, UINT32, bitfield, 9)
#define meshtastic_Data_CALLBACK NULL
#define meshtastic_Data_DEFAULT NULL
@@ -1629,13 +1634,13 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_ChunkedPayload_size 245
#define meshtastic_ClientNotification_size 415
#define meshtastic_Compressed_size 243
#define meshtastic_Data_size 270
#define meshtastic_Data_size 273
#define meshtastic_DeviceMetadata_size 46
#define meshtastic_FileInfo_size 236
#define meshtastic_FromRadio_size 510
#define meshtastic_Heartbeat_size 0
#define meshtastic_LogRecord_size 426
#define meshtastic_MeshPacket_size 364
#define meshtastic_MeshPacket_size 367
#define meshtastic_MqttClientProxyMessage_size 501
#define meshtastic_MyNodeInfo_size 18
#define meshtastic_NeighborInfo_size 258
+2 -4
View File
@@ -15,10 +15,8 @@
#include <WiFiUdp.h>
#ifdef ARCH_ESP32
#if !MESHTASTIC_EXCLUDE_WEBSERVER
#if !MESHTASTIC_EXCLUDE_WEBSERVER
#include "mesh/http/WebServer.h"
#endif
#endif
#include <ESPmDNS.h>
#include <esp_wifi.h>
static void WiFiEvent(WiFiEvent_t event);
@@ -58,7 +56,7 @@ static void onNetworkConnected()
{
if (!APStartupComplete) {
// Start web server
LOG_INFO("Starting network services\n");
LOG_INFO("Starting WiFi network services\n");
#ifdef ARCH_ESP32
// start mdns
@@ -422,4 +420,4 @@ uint8_t getWifiDisconnectReason()
{
return wifiDisconnectReason;
}
#endif
#endif
+4 -2
View File
@@ -406,7 +406,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
LOG_INFO("Setting config: Device\n");
config.has_device = true;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true) {
if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true &&
accelerometerThread->enabled == false) {
accelerometerThread->start();
}
#endif
@@ -484,7 +485,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
requiresReboot = false;
}
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true) {
if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true &&
accelerometerThread->enabled == false) {
accelerometerThread->start();
}
#endif
+18 -18
View File
@@ -190,17 +190,17 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
#if defined(T_WATCH_S3) || defined(RAK14014)
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
this->payload = 0xb4;
this->payload = INPUT_BROKER_MSG_LEFT;
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
this->payload = 0xb7;
this->payload = INPUT_BROKER_MSG_RIGHT;
}
#else
// tweak for left/right events generated via trackball/touch with empty kbchar
if (!event->kbchar) {
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
this->payload = 0xb4;
this->payload = INPUT_BROKER_MSG_LEFT;
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
this->payload = 0xb7;
this->payload = INPUT_BROKER_MSG_RIGHT;
}
} else {
// pass the pressed key
@@ -222,26 +222,26 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
// Run modifier key code below, (doesnt inturrupt typing or reset to start screen page)
switch (event->kbchar) {
case 0x11: // make screen brighter
case INPUT_BROKER_MSG_BRIGHTNESS_UP: // make screen brighter
if (screen)
screen->increaseBrightness();
LOG_DEBUG("increasing Screen Brightness\n");
break;
case 0x12: // make screen dimmer
case INPUT_BROKER_MSG_BRIGHTNESS_DOWN: // make screen dimmer
if (screen)
screen->decreaseBrightness();
LOG_DEBUG("Decreasing Screen Brightness\n");
break;
case 0xf1: // draw modifier (function) symbal
case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbal
if (screen)
screen->setFunctionSymbal("Fn");
break;
case 0xf2: // remove modifier (function) symbal
case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbal
if (screen)
screen->removeFunctionSymbal("Fn");
break;
// mute (switch off/toggle) external notifications on fn+m
case 0xac:
case INPUT_BROKER_MSG_MUTE_TOGGLE:
if (moduleConfig.external_notification.enabled == true) {
if (externalNotificationModule->getMute()) {
externalNotificationModule->setMute(false);
@@ -257,7 +257,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
}
}
break;
case 0x9e: // toggle GPS like triple press does
case INPUT_BROKER_MSG_GPS_TOGGLE: // toggle GPS like triple press does
#if !MESHTASTIC_EXCLUDE_GPS
if (gps != nullptr) {
gps->toggleGpsMode();
@@ -267,7 +267,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
showTemporaryMessage("GPS Toggled");
#endif
break;
case 0xaf: // fn+space send network ping like double press does
case INPUT_BROKER_MSG_SEND_PING: // fn+space send network ping like double press does
service->refreshLocalMeshNode();
if (service->trySendPosition(NODENUM_BROADCAST, true)) {
showTemporaryMessage("Position \nUpdate Sent");
@@ -283,7 +283,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
validEvent = true;
break;
}
if (screen && (event->kbchar != 0xf1)) {
if (screen && (event->kbchar != INPUT_BROKER_MSG_FN_SYMBOL_ON)) {
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal
}
}
@@ -505,7 +505,7 @@ int32_t CannedMessageModule::runOnce()
}
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
switch (this->payload) {
case 0xb4: // left
case INPUT_BROKER_MSG_LEFT:
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
size_t numMeshNodes = nodeDB->getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) {
@@ -540,7 +540,7 @@ int32_t CannedMessageModule::runOnce()
}
}
break;
case 0xb7: // right
case INPUT_BROKER_MSG_RIGHT:
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
size_t numMeshNodes = nodeDB->getNumMeshNodes();
if (this->dest == NODENUM_BROADCAST) {
@@ -602,19 +602,19 @@ int32_t CannedMessageModule::runOnce()
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
}
break;
case 0xb4: // left
case 0xb7: // right
case INPUT_BROKER_MSG_LEFT:
case INPUT_BROKER_MSG_RIGHT:
// already handled above
break;
// handle fn+s for shutdown
case 0x9b:
case INPUT_BROKER_MSG_SHUTDOWN:
if (screen)
screen->startAlert("Shutting down...");
shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000;
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
break;
// and fn+r for reboot
case 0x90:
case INPUT_BROKER_MSG_REBOOT:
if (screen)
screen->startAlert("Rebooting...");
rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000;
+1 -1
View File
@@ -223,4 +223,4 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
};
extern CannedMessageModule *cannedMessageModule;
#endif
#endif
+4
View File
@@ -146,7 +146,11 @@ bool PositionModule::hasQualityTimesource()
{
bool setFromPhoneOrNtpToday =
lastSetFromPhoneNtpOrGps == 0 ? false : (millis() - lastSetFromPhoneNtpOrGps) <= (SEC_PER_DAY * 1000UL);
#if MESHTASTIC_EXCLUDE_GPS
bool hasGpsOrRtc = (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#else
bool hasGpsOrRtc = (gps && gps->isConnected()) || (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#endif
return hasGpsOrRtc || setFromPhoneOrNtpToday;
}