mirror of
https://github.com/meshtastic/firmware.git
synced 2025-10-27 15:02:41 +00:00
This reverts commit 5bcc47dddb.
This commit is contained in:
parent
95d3ecb239
commit
664d17c519
@ -839,8 +839,11 @@ void Power::readPowerStatus()
|
|||||||
|
|
||||||
// Notify any status instances that are observing us
|
// Notify any status instances that are observing us
|
||||||
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isChargingNow, batteryVoltageMv, batteryChargePercent);
|
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isChargingNow, batteryVoltageMv, batteryChargePercent);
|
||||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
|
if (millis() > lastLogTime + 50 * 1000) {
|
||||||
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(),
|
||||||
|
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||||
|
lastLogTime = millis();
|
||||||
|
}
|
||||||
newStatus.notifyObservers(&powerStatus2);
|
newStatus.notifyObservers(&powerStatus2);
|
||||||
#ifdef DEBUG_HEAP
|
#ifdef DEBUG_HEAP
|
||||||
if (lastheap != memGet.getFreeHeap()) {
|
if (lastheap != memGet.getFreeHeap()) {
|
||||||
|
|||||||
@ -1659,8 +1659,12 @@ bool GPS::lookForLocation()
|
|||||||
|
|
||||||
#ifndef TINYGPS_OPTION_NO_STATISTICS
|
#ifndef TINYGPS_OPTION_NO_STATISTICS
|
||||||
if (reader.failedChecksum() > lastChecksumFailCount) {
|
if (reader.failedChecksum() > lastChecksumFailCount) {
|
||||||
LOG_WARN("%u new GPS checksum failures, for a total of %u", reader.failedChecksum() - lastChecksumFailCount,
|
// In a GPS_DEBUG build we want to log all of these. In production, we only care if there are many of them.
|
||||||
reader.failedChecksum());
|
#ifndef GPS_DEBUG
|
||||||
|
if (reader.failedChecksum() > 4)
|
||||||
|
#endif
|
||||||
|
LOG_WARN("%u new GPS checksum failures, for a total of %u", reader.failedChecksum() - lastChecksumFailCount,
|
||||||
|
reader.failedChecksum());
|
||||||
lastChecksumFailCount = reader.failedChecksum();
|
lastChecksumFailCount = reader.failedChecksum();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -31,33 +31,8 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
wasSeenRecently(p, true, nullptr, nullptr, &wasUpgraded); // Updates history; returns false when an upgrade is detected
|
wasSeenRecently(p, true, nullptr, nullptr, &wasUpgraded); // Updates history; returns false when an upgrade is detected
|
||||||
|
|
||||||
// Handle hop_limit upgrade scenario for rebroadcasters
|
// Handle hop_limit upgrade scenario for rebroadcasters
|
||||||
// isRebroadcaster() is duplicated in perhapsRebroadcast(), but this avoids confusing log messages
|
if (wasUpgraded && perhapsHandleUpgradedPacket(p)) {
|
||||||
if (wasUpgraded && isRebroadcaster() && iface && p->hop_limit > 0) {
|
return true; // we handled it, so stop processing
|
||||||
// wasSeenRecently() reports false in upgrade cases so we handle replacement before the duplicate short-circuit
|
|
||||||
// If we overhear a duplicate copy of the packet with more hops left than the one we are waiting to
|
|
||||||
// rebroadcast, then remove the packet currently sitting in the TX queue and use this one instead.
|
|
||||||
uint8_t dropThreshold = p->hop_limit; // remove queued packets that have fewer hops remaining
|
|
||||||
if (iface->removePendingTXPacket(getFrom(p), p->id, dropThreshold)) {
|
|
||||||
LOG_DEBUG("Processing upgraded packet 0x%08x for rebroadcast with hop limit %d (dropping queued < %d)", p->id,
|
|
||||||
p->hop_limit, dropThreshold);
|
|
||||||
|
|
||||||
if (nodeDB)
|
|
||||||
nodeDB->updateFrom(*p);
|
|
||||||
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
|
|
||||||
if (traceRouteModule && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
|
||||||
p->decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP)
|
|
||||||
traceRouteModule->processUpgradedPacket(*p);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
perhapsRebroadcast(p);
|
|
||||||
|
|
||||||
// We already enqueued the improved copy, so make sure the incoming packet stops here.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No queue entry was replaced by this upgraded copy, so treat it as a duplicate to avoid
|
|
||||||
// delivering the same packet to applications/phone twice with different hop limits.
|
|
||||||
seenRecently = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seenRecently) {
|
if (seenRecently) {
|
||||||
@ -70,8 +45,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
if (isRepeated) {
|
if (isRepeated) {
|
||||||
LOG_DEBUG("Repeated reliable tx");
|
LOG_DEBUG("Repeated reliable tx");
|
||||||
// Check if it's still in the Tx queue, if not, we have to relay it again
|
// Check if it's still in the Tx queue, if not, we have to relay it again
|
||||||
if (!findInTxQueue(p->from, p->id))
|
if (!findInTxQueue(p->from, p->id)) {
|
||||||
|
reprocessPacket(p);
|
||||||
perhapsRebroadcast(p);
|
perhapsRebroadcast(p);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
perhapsCancelDupe(p);
|
perhapsCancelDupe(p);
|
||||||
}
|
}
|
||||||
@ -82,6 +59,40 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
return Router::shouldFilterReceived(p);
|
return Router::shouldFilterReceived(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FloodingRouter::perhapsHandleUpgradedPacket(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
// isRebroadcaster() is duplicated in perhapsRebroadcast(), but this avoids confusing log messages
|
||||||
|
if (isRebroadcaster() && iface && p->hop_limit > 0) {
|
||||||
|
// If we overhear a duplicate copy of the packet with more hops left than the one we are waiting to
|
||||||
|
// rebroadcast, then remove the packet currently sitting in the TX queue and use this one instead.
|
||||||
|
uint8_t dropThreshold = p->hop_limit; // remove queued packets that have fewer hops remaining
|
||||||
|
if (iface->removePendingTXPacket(getFrom(p), p->id, dropThreshold)) {
|
||||||
|
LOG_DEBUG("Processing upgraded packet 0x%08x for rebroadcast with hop limit %d (dropping queued < %d)", p->id,
|
||||||
|
p->hop_limit, dropThreshold);
|
||||||
|
|
||||||
|
reprocessPacket(p);
|
||||||
|
perhapsRebroadcast(p);
|
||||||
|
|
||||||
|
rxDupe++;
|
||||||
|
// We already enqueued the improved copy, so make sure the incoming packet stops here.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloodingRouter::reprocessPacket(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
if (nodeDB)
|
||||||
|
nodeDB->updateFrom(*p);
|
||||||
|
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
|
||||||
|
if (traceRouteModule && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
||||||
|
p->decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP)
|
||||||
|
traceRouteModule->processUpgradedPacket(*p);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool FloodingRouter::roleAllowsCancelingDupe(const meshtastic_MeshPacket *p)
|
bool FloodingRouter::roleAllowsCancelingDupe(const meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
||||||
@ -121,41 +132,6 @@ bool FloodingRouter::isRebroadcaster()
|
|||||||
config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE;
|
config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloodingRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
|
|
||||||
{
|
|
||||||
if (!isToUs(p) && (p->hop_limit > 0) && !isFromUs(p)) {
|
|
||||||
if (p->id != 0) {
|
|
||||||
if (isRebroadcaster()) {
|
|
||||||
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
|
||||||
|
|
||||||
// Use shared logic to determine if hop_limit should be decremented
|
|
||||||
if (shouldDecrementHopLimit(p)) {
|
|
||||||
tosend->hop_limit--; // bump down the hop count
|
|
||||||
} else {
|
|
||||||
LOG_INFO("favorite-ROUTER/CLIENT_BASE-to-ROUTER/CLIENT_BASE flood: preserving hop_limit");
|
|
||||||
}
|
|
||||||
#if USERPREFS_EVENT_MODE
|
|
||||||
if (tosend->hop_limit > 2) {
|
|
||||||
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
|
|
||||||
tosend->hop_start -= (tosend->hop_limit - 2);
|
|
||||||
tosend->hop_limit = 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tosend->next_hop = NO_NEXT_HOP_PREFERENCE; // this should already be the case, but just in case
|
|
||||||
|
|
||||||
LOG_INFO("Rebroadcast received floodmsg");
|
|
||||||
// Note: we are careful to resend using the original senders node id
|
|
||||||
send(tosend);
|
|
||||||
} else {
|
|
||||||
LOG_DEBUG("No rebroadcast: Role = CLIENT_MUTE or Rebroadcast Mode = NONE");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG_DEBUG("Ignore 0 id broadcast");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
||||||
{
|
{
|
||||||
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) &&
|
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) &&
|
||||||
|
|||||||
@ -27,10 +27,6 @@
|
|||||||
*/
|
*/
|
||||||
class FloodingRouter : public Router
|
class FloodingRouter : public Router
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
/* Check if we should rebroadcast this packet, and do so if needed */
|
|
||||||
void perhapsRebroadcast(const meshtastic_MeshPacket *p);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -59,6 +55,17 @@ class FloodingRouter : public Router
|
|||||||
*/
|
*/
|
||||||
virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override;
|
virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override;
|
||||||
|
|
||||||
|
/* Check if we should rebroadcast this packet, and do so if needed */
|
||||||
|
virtual bool perhapsRebroadcast(const meshtastic_MeshPacket *p) = 0;
|
||||||
|
|
||||||
|
/* Check if we should handle an upgraded packet (with higher hop_limit)
|
||||||
|
* @return true if we handled it (so stop processing)
|
||||||
|
*/
|
||||||
|
bool perhapsHandleUpgradedPacket(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
|
/* Call when we receive a packet that needs some reprocessing, but afterwards should be filtered */
|
||||||
|
void reprocessPacket(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
// Return false for roles like ROUTER which should always rebroadcast even when we've heard another rebroadcast of
|
// Return false for roles like ROUTER which should always rebroadcast even when we've heard another rebroadcast of
|
||||||
// the same packet
|
// the same packet
|
||||||
bool roleAllowsCancelingDupe(const meshtastic_MeshPacket *p);
|
bool roleAllowsCancelingDupe(const meshtastic_MeshPacket *p);
|
||||||
|
|||||||
@ -43,31 +43,8 @@ bool NextHopRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
&wasUpgraded); // Updates history; returns false when an upgrade is detected
|
&wasUpgraded); // Updates history; returns false when an upgrade is detected
|
||||||
|
|
||||||
// Handle hop_limit upgrade scenario for rebroadcasters
|
// Handle hop_limit upgrade scenario for rebroadcasters
|
||||||
// isRebroadcaster() is duplicated in perhapsRelay(), but this avoids confusing log messages
|
if (wasUpgraded && perhapsHandleUpgradedPacket(p)) {
|
||||||
if (wasUpgraded && isRebroadcaster() && iface && p->hop_limit > 0) {
|
return true; // we handled it, so stop processing
|
||||||
// Upgrade detection bypasses the duplicate short-circuit so we replace the queued packet before exiting
|
|
||||||
uint8_t dropThreshold = p->hop_limit; // remove queued packets that have fewer hops remaining
|
|
||||||
if (iface->removePendingTXPacket(getFrom(p), p->id, dropThreshold)) {
|
|
||||||
LOG_DEBUG("Processing upgraded packet 0x%08x for relay with hop limit %d (dropping queued < %d)", p->id, p->hop_limit,
|
|
||||||
dropThreshold);
|
|
||||||
|
|
||||||
if (nodeDB)
|
|
||||||
nodeDB->updateFrom(*p);
|
|
||||||
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
|
|
||||||
if (traceRouteModule && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
|
||||||
p->decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP)
|
|
||||||
traceRouteModule->processUpgradedPacket(*p);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
perhapsRelay(p);
|
|
||||||
|
|
||||||
// We already enqueued the improved copy, so make sure the incoming packet stops here.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No queue entry was replaced by this upgraded copy, so treat it as a duplicate to avoid
|
|
||||||
// delivering the same packet to applications/phone twice with different hop limits.
|
|
||||||
seenRecently = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seenRecently) {
|
if (seenRecently) {
|
||||||
@ -82,14 +59,20 @@ bool NextHopRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
if (wasFallback) {
|
if (wasFallback) {
|
||||||
LOG_INFO("Fallback to flooding from relay_node=0x%x", p->relay_node);
|
LOG_INFO("Fallback to flooding from relay_node=0x%x", p->relay_node);
|
||||||
// Check if it's still in the Tx queue, if not, we have to relay it again
|
// Check if it's still in the Tx queue, if not, we have to relay it again
|
||||||
if (!findInTxQueue(p->from, p->id))
|
if (!findInTxQueue(p->from, p->id)) {
|
||||||
perhapsRelay(p);
|
reprocessPacket(p);
|
||||||
|
perhapsRebroadcast(p);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
bool isRepeated = p->hop_start > 0 && p->hop_start == p->hop_limit;
|
bool isRepeated = p->hop_start > 0 && p->hop_start == p->hop_limit;
|
||||||
// If repeated and not in Tx queue anymore, try relaying again, or if we are the destination, send the ACK again
|
// If repeated and not in Tx queue anymore, try relaying again, or if we are the destination, send the ACK again
|
||||||
if (isRepeated) {
|
if (isRepeated) {
|
||||||
if (!findInTxQueue(p->from, p->id) && !perhapsRelay(p) && isToUs(p) && p->want_ack)
|
if (!findInTxQueue(p->from, p->id)) {
|
||||||
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, 0);
|
reprocessPacket(p);
|
||||||
|
if (!perhapsRebroadcast(p) && isToUs(p) && p->want_ack) {
|
||||||
|
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (!weWereNextHop) {
|
} else if (!weWereNextHop) {
|
||||||
perhapsCancelDupe(p); // If it's a dupe, cancel relay if we were not explicitly asked to relay
|
perhapsCancelDupe(p); // If it's a dupe, cancel relay if we were not explicitly asked to relay
|
||||||
}
|
}
|
||||||
@ -107,13 +90,14 @@ void NextHopRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtast
|
|||||||
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) &&
|
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) &&
|
||||||
(p->decoded.request_id != 0 || p->decoded.reply_id != 0);
|
(p->decoded.request_id != 0 || p->decoded.reply_id != 0);
|
||||||
if (isAckorReply) {
|
if (isAckorReply) {
|
||||||
// Update next-hop for the original transmitter of this successful transmission to the relay node, but ONLY if "from" is
|
// Update next-hop for the original transmitter of this successful transmission to the relay node, but ONLY if "from"
|
||||||
// not 0 (means implicit ACK) and original packet was also relayed by this node, or we sent it directly to the destination
|
// is not 0 (means implicit ACK) and original packet was also relayed by this node, or we sent it directly to the
|
||||||
|
// destination
|
||||||
if (p->from != 0) {
|
if (p->from != 0) {
|
||||||
meshtastic_NodeInfoLite *origTx = nodeDB->getMeshNode(p->from);
|
meshtastic_NodeInfoLite *origTx = nodeDB->getMeshNode(p->from);
|
||||||
if (origTx) {
|
if (origTx) {
|
||||||
// Either relayer of ACK was also a relayer of the packet, or we were the *only* relayer and the ACK came directly
|
// Either relayer of ACK was also a relayer of the packet, or we were the *only* relayer and the ACK came
|
||||||
// from the destination
|
// directly from the destination
|
||||||
bool wasAlreadyRelayer = wasRelayer(p->relay_node, p->decoded.request_id, p->to);
|
bool wasAlreadyRelayer = wasRelayer(p->relay_node, p->decoded.request_id, p->to);
|
||||||
bool weWereSoleRelayer = false;
|
bool weWereSoleRelayer = false;
|
||||||
bool weWereRelayer = wasRelayer(ourRelayID, p->decoded.request_id, p->to, &weWereSoleRelayer);
|
bool weWereRelayer = wasRelayer(ourRelayID, p->decoded.request_id, p->to, &weWereSoleRelayer);
|
||||||
@ -134,34 +118,49 @@ void NextHopRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtast
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
perhapsRelay(p);
|
perhapsRebroadcast(p);
|
||||||
|
|
||||||
// handle the packet as normal
|
// handle the packet as normal
|
||||||
Router::sniffReceived(p, c);
|
Router::sniffReceived(p, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we should be relaying this packet if so, do so. */
|
/* Check if we should be rebroadcasting this packet if so, do so. */
|
||||||
bool NextHopRouter::perhapsRelay(const meshtastic_MeshPacket *p)
|
bool NextHopRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
if (!isToUs(p) && !isFromUs(p) && p->hop_limit > 0) {
|
if (!isToUs(p) && !isFromUs(p) && p->hop_limit > 0) {
|
||||||
if (p->next_hop == NO_NEXT_HOP_PREFERENCE || p->next_hop == nodeDB->getLastByteOfNodeNum(getNodeNum())) {
|
if (p->id != 0) {
|
||||||
if (isRebroadcaster()) {
|
if (isRebroadcaster()) {
|
||||||
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
if (p->next_hop == NO_NEXT_HOP_PREFERENCE || p->next_hop == nodeDB->getLastByteOfNodeNum(getNodeNum())) {
|
||||||
LOG_INFO("Relaying received message coming from %x", p->relay_node);
|
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
||||||
|
LOG_INFO("Rebroadcast received message coming from %x", p->relay_node);
|
||||||
|
|
||||||
// Use shared logic to determine if hop_limit should be decremented
|
// Use shared logic to determine if hop_limit should be decremented
|
||||||
if (shouldDecrementHopLimit(p)) {
|
if (shouldDecrementHopLimit(p)) {
|
||||||
tosend->hop_limit--; // bump down the hop count
|
tosend->hop_limit--; // bump down the hop count
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Router/CLIENT_BASE-to-favorite-router/CLIENT_BASE relay: preserving hop_limit");
|
LOG_INFO("favorite-ROUTER/CLIENT_BASE-to-ROUTER/CLIENT_BASE rebroadcast: preserving hop_limit");
|
||||||
|
}
|
||||||
|
#if USERPREFS_EVENT_MODE
|
||||||
|
if (tosend->hop_limit > 2) {
|
||||||
|
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
|
||||||
|
tosend->hop_start -= (tosend->hop_limit - 2);
|
||||||
|
tosend->hop_limit = 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (p->next_hop == NO_NEXT_HOP_PREFERENCE) {
|
||||||
|
FloodingRouter::send(tosend);
|
||||||
|
} else {
|
||||||
|
NextHopRouter::send(tosend);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NextHopRouter::send(tosend);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Not rebroadcasting: Role = CLIENT_MUTE or Rebroadcast Mode = NONE");
|
LOG_DEBUG("No rebroadcast: Role = CLIENT_MUTE or Rebroadcast Mode = NONE");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("Ignore 0 id broadcast");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,13 +230,13 @@ bool NextHopRouter::stopRetransmission(GlobalPacketId key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regardless of whether or not we canceled this packet from the txQueue, remove it from our pending list so it doesn't
|
// Regardless of whether or not we canceled this packet from the txQueue, remove it from our pending list so it
|
||||||
// get scheduled again. (This is the core of stopRetransmission.)
|
// doesn't get scheduled again. (This is the core of stopRetransmission.)
|
||||||
auto numErased = pending.erase(key);
|
auto numErased = pending.erase(key);
|
||||||
assert(numErased == 1);
|
assert(numErased == 1);
|
||||||
|
|
||||||
// When we remove an entry from pending, always be sure to release the copy of the packet that was allocated in the call
|
// When we remove an entry from pending, always be sure to release the copy of the packet that was allocated in the
|
||||||
// to startRetransmission.
|
// call to startRetransmission.
|
||||||
packetPool.release(p);
|
packetPool.release(p);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -148,7 +148,7 @@ class NextHopRouter : public FloodingRouter
|
|||||||
*/
|
*/
|
||||||
uint8_t getNextHop(NodeNum to, uint8_t relay_node);
|
uint8_t getNextHop(NodeNum to, uint8_t relay_node);
|
||||||
|
|
||||||
/** Check if we should be relaying this packet if so, do so.
|
/** Check if we should be rebroadcasting this packet if so, do so.
|
||||||
* @return true if we did relay */
|
* @return true if we did rebroadcast */
|
||||||
bool perhapsRelay(const meshtastic_MeshPacket *p);
|
bool perhapsRebroadcast(const meshtastic_MeshPacket *p) override;
|
||||||
};
|
};
|
||||||
@ -94,7 +94,6 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd
|
|||||||
LOG_DEBUG("Packet History - Hop limit upgrade: packet 0x%08x from hop_limit=%d to hop_limit=%d", p->id, found->hop_limit,
|
LOG_DEBUG("Packet History - Hop limit upgrade: packet 0x%08x from hop_limit=%d to hop_limit=%d", p->id, found->hop_limit,
|
||||||
p->hop_limit);
|
p->hop_limit);
|
||||||
*wasUpgraded = true;
|
*wasUpgraded = true;
|
||||||
seenRecently = false; // Allow router processing but prevent duplicate app delivery
|
|
||||||
} else if (wasUpgraded) {
|
} else if (wasUpgraded) {
|
||||||
*wasUpgraded = false; // Initialize to false if not an upgrade
|
*wasUpgraded = false; // Initialize to false if not an upgrade
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,6 +148,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
|
|
||||||
void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
|
if (webServerThread)
|
||||||
|
webServerThread->markActivity();
|
||||||
|
|
||||||
LOG_DEBUG("webAPI handleAPIv1FromRadio");
|
LOG_DEBUG("webAPI handleAPIv1FromRadio");
|
||||||
|
|
||||||
@ -391,6 +393,9 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
|
if (webServerThread)
|
||||||
|
webServerThread->markActivity();
|
||||||
|
|
||||||
// Get access to the parameters
|
// Get access to the parameters
|
||||||
ResourceParameters *params = req->getParams();
|
ResourceParameters *params = req->getParams();
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,12 @@ Preferences prefs;
|
|||||||
using namespace httpsserver;
|
using namespace httpsserver;
|
||||||
#include "mesh/http/ContentHandler.h"
|
#include "mesh/http/ContentHandler.h"
|
||||||
|
|
||||||
|
static const uint32_t ACTIVE_THRESHOLD_MS = 5000;
|
||||||
|
static const uint32_t MEDIUM_THRESHOLD_MS = 30000;
|
||||||
|
static const int32_t ACTIVE_INTERVAL_MS = 50;
|
||||||
|
static const int32_t MEDIUM_INTERVAL_MS = 200;
|
||||||
|
static const int32_t IDLE_INTERVAL_MS = 1000;
|
||||||
|
|
||||||
static SSLCert *cert;
|
static SSLCert *cert;
|
||||||
static HTTPSServer *secureServer;
|
static HTTPSServer *secureServer;
|
||||||
static HTTPServer *insecureServer;
|
static HTTPServer *insecureServer;
|
||||||
@ -175,6 +181,32 @@ WebServerThread::WebServerThread() : concurrency::OSThread("WebServer")
|
|||||||
if (!config.network.wifi_enabled && !config.network.eth_enabled) {
|
if (!config.network.wifi_enabled && !config.network.eth_enabled) {
|
||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
|
lastActivityTime = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebServerThread::markActivity()
|
||||||
|
{
|
||||||
|
lastActivityTime = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t WebServerThread::getAdaptiveInterval()
|
||||||
|
{
|
||||||
|
uint32_t currentTime = millis();
|
||||||
|
uint32_t timeSinceActivity;
|
||||||
|
|
||||||
|
if (currentTime >= lastActivityTime) {
|
||||||
|
timeSinceActivity = currentTime - lastActivityTime;
|
||||||
|
} else {
|
||||||
|
timeSinceActivity = (UINT32_MAX - lastActivityTime) + currentTime + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeSinceActivity < ACTIVE_THRESHOLD_MS) {
|
||||||
|
return ACTIVE_INTERVAL_MS;
|
||||||
|
} else if (timeSinceActivity < MEDIUM_THRESHOLD_MS) {
|
||||||
|
return MEDIUM_INTERVAL_MS;
|
||||||
|
} else {
|
||||||
|
return IDLE_INTERVAL_MS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t WebServerThread::runOnce()
|
int32_t WebServerThread::runOnce()
|
||||||
@ -189,8 +221,7 @@ int32_t WebServerThread::runOnce()
|
|||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop every 5ms.
|
return getAdaptiveInterval();
|
||||||
return (5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initWebServer()
|
void initWebServer()
|
||||||
|
|||||||
@ -10,13 +10,17 @@ void createSSLCert();
|
|||||||
|
|
||||||
class WebServerThread : private concurrency::OSThread
|
class WebServerThread : private concurrency::OSThread
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
uint32_t lastActivityTime = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WebServerThread();
|
WebServerThread();
|
||||||
uint32_t requestRestart = 0;
|
uint32_t requestRestart = 0;
|
||||||
|
void markActivity();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
int32_t getAdaptiveInterval();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WebServerThread *webServerThread;
|
extern WebServerThread *webServerThread;
|
||||||
|
|||||||
@ -21,6 +21,11 @@ void TraceRouteModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtasti
|
|||||||
{
|
{
|
||||||
const meshtastic_Data &incoming = p.decoded;
|
const meshtastic_Data &incoming = p.decoded;
|
||||||
|
|
||||||
|
// Update next-hops using returned route
|
||||||
|
if (incoming.request_id) {
|
||||||
|
updateNextHops(p, r);
|
||||||
|
}
|
||||||
|
|
||||||
// Insert unknown hops if necessary
|
// Insert unknown hops if necessary
|
||||||
insertUnknownHops(p, r, !incoming.request_id);
|
insertUnknownHops(p, r, !incoming.request_id);
|
||||||
|
|
||||||
@ -153,6 +158,65 @@ void TraceRouteModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtasti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TraceRouteModule::updateNextHops(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r)
|
||||||
|
{
|
||||||
|
// E.g. if the route is A->B->C->D and we are B, we can set C as next-hop for C and D
|
||||||
|
// Similarly, if we are C, we can set D as next-hop for D
|
||||||
|
// If we are A, we can set B as next-hop for B, C and D
|
||||||
|
|
||||||
|
// First check if we were the original sender or in the original route
|
||||||
|
int8_t nextHopIndex = -1;
|
||||||
|
if (isToUs(&p)) {
|
||||||
|
nextHopIndex = 0; // We are the original sender, next hop is first in route
|
||||||
|
} else {
|
||||||
|
// Check if we are in the original route
|
||||||
|
for (uint8_t i = 0; i < r->route_count; i++) {
|
||||||
|
if (r->route[i] == nodeDB->getNodeNum()) {
|
||||||
|
nextHopIndex = i + 1; // Next hop is the one after us
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are in the original route, update the next hops
|
||||||
|
if (nextHopIndex != -1) {
|
||||||
|
// For every node after us, we can set the next-hop to the first node after us
|
||||||
|
NodeNum nextHop;
|
||||||
|
if (nextHopIndex == r->route_count) {
|
||||||
|
nextHop = p.from; // We are the last in the route, next hop is destination
|
||||||
|
} else {
|
||||||
|
nextHop = r->route[nextHopIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextHop == NODENUM_BROADCAST) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t nextHopByte = nodeDB->getLastByteOfNodeNum(nextHop);
|
||||||
|
|
||||||
|
// For the rest of the nodes in the route, set their next-hop
|
||||||
|
// Note: if we are the last in the route, this loop will not run
|
||||||
|
for (int8_t i = nextHopIndex; i < r->route_count; i++) {
|
||||||
|
NodeNum targetNode = r->route[i];
|
||||||
|
maybeSetNextHop(targetNode, nextHopByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also set next-hop for the destination node
|
||||||
|
maybeSetNextHop(p.from, nextHopByte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TraceRouteModule::maybeSetNextHop(NodeNum target, uint8_t nextHopByte)
|
||||||
|
{
|
||||||
|
if (target == NODENUM_BROADCAST)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(target);
|
||||||
|
if (node && node->next_hop != nextHopByte) {
|
||||||
|
LOG_INFO("Updating next-hop for 0x%08x to 0x%02x based on traceroute", target, nextHopByte);
|
||||||
|
node->next_hop = nextHopByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TraceRouteModule::processUpgradedPacket(const meshtastic_MeshPacket &mp)
|
void TraceRouteModule::processUpgradedPacket(const meshtastic_MeshPacket &mp)
|
||||||
{
|
{
|
||||||
if (mp.which_payload_variant != meshtastic_MeshPacket_decoded_tag || mp.decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP)
|
if (mp.which_payload_variant != meshtastic_MeshPacket_decoded_tag || mp.decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP)
|
||||||
|
|||||||
@ -55,6 +55,12 @@ class TraceRouteModule : public ProtobufModule<meshtastic_RouteDiscovery>,
|
|||||||
// Call to add your ID to the route array of a RouteDiscovery message
|
// Call to add your ID to the route array of a RouteDiscovery message
|
||||||
void appendMyIDandSNR(meshtastic_RouteDiscovery *r, float snr, bool isTowardsDestination, bool SNRonly);
|
void appendMyIDandSNR(meshtastic_RouteDiscovery *r, float snr, bool isTowardsDestination, bool SNRonly);
|
||||||
|
|
||||||
|
// Update next-hops in the routing table based on the returned route
|
||||||
|
void updateNextHops(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r);
|
||||||
|
|
||||||
|
// Helper to update next-hop for a single node
|
||||||
|
void maybeSetNextHop(NodeNum target, uint8_t nextHopByte);
|
||||||
|
|
||||||
/* Call to print the route array of a RouteDiscovery message.
|
/* Call to print the route array of a RouteDiscovery message.
|
||||||
Set origin to where the request came from.
|
Set origin to where the request came from.
|
||||||
Set dest to the ID of its destination, or NODENUM_BROADCAST if it has not yet arrived there. */
|
Set dest to the ID of its destination, or NODENUM_BROADCAST if it has not yet arrived there. */
|
||||||
|
|||||||
@ -138,6 +138,7 @@ class Power : private concurrency::OSThread
|
|||||||
void reboot();
|
void reboot();
|
||||||
// open circuit voltage lookup table
|
// open circuit voltage lookup table
|
||||||
uint8_t low_voltage_counter;
|
uint8_t low_voltage_counter;
|
||||||
|
int32_t lastLogTime = 0;
|
||||||
#ifdef DEBUG_HEAP
|
#ifdef DEBUG_HEAP
|
||||||
uint32_t lastheap;
|
uint32_t lastheap;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user