2020-04-17 09:48:54 -07:00
|
|
|
#include "Router.h"
|
2021-02-22 12:57:26 +08:00
|
|
|
#include "Channels.h"
|
2020-05-09 17:51:20 -07:00
|
|
|
#include "CryptoEngine.h"
|
2022-11-26 20:50:00 +01:00
|
|
|
#include "MeshRadio.h"
|
2024-08-10 08:33:42 -05:00
|
|
|
#include "MeshService.h"
|
2023-01-21 14:34:29 +01:00
|
|
|
#include "NodeDB.h"
|
2020-10-08 07:28:57 +08:00
|
|
|
#include "RTC.h"
|
2025-09-13 11:59:50 -05:00
|
|
|
|
2022-04-11 20:09:48 -07:00
|
|
|
#include "configuration.h"
|
2024-12-03 13:21:24 +01:00
|
|
|
#include "detect/LoRaRadioType.h"
|
2021-03-28 12:16:37 +08:00
|
|
|
#include "main.h"
|
2020-04-17 09:48:54 -07:00
|
|
|
#include "mesh-pb-constants.h"
|
2024-08-09 01:43:13 -05:00
|
|
|
#include "meshUtils.h"
|
2022-02-27 00:18:35 -08:00
|
|
|
#include "modules/RoutingModule.h"
|
2024-03-25 05:33:57 -06:00
|
|
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
2021-04-05 13:00:56 +08:00
|
|
|
#include "mqtt/MQTT.h"
|
2024-03-25 05:33:57 -06:00
|
|
|
#endif
|
2024-07-29 20:16:47 -05:00
|
|
|
#include "Default.h"
|
2024-07-28 19:49:10 -05:00
|
|
|
#if ARCH_PORTDUINO
|
|
|
|
|
#include "platform/portduino/PortduinoGlue.h"
|
|
|
|
|
#endif
|
|
|
|
|
#if ENABLE_JSON_LOGGING || ARCH_PORTDUINO
|
|
|
|
|
#include "serialization/MeshPacketSerializer.h"
|
|
|
|
|
#endif
|
2020-04-17 09:48:54 -07:00
|
|
|
|
2023-01-28 06:39:14 -06:00
|
|
|
#define MAX_RX_FROMRADIO \
|
2020-04-17 09:48:54 -07:00
|
|
|
4 // max number of packets destined to our queue, we dispatch packets quickly so it doesn't need to be big
|
|
|
|
|
|
|
|
|
|
// I think this is right, one packet for each of the three fifos + one packet being currently assembled for TX or RX
|
2020-06-13 08:27:44 -07:00
|
|
|
// And every TX packet might have a retransmission packet or an ack alive at any moment
|
2025-09-13 11:59:50 -05:00
|
|
|
|
|
|
|
|
#ifdef ARCH_PORTDUINO
|
|
|
|
|
// Portduino (native) targets can use dynamic memory pools with runtime-configurable sizes
|
2023-01-28 06:39:14 -06:00
|
|
|
#define MAX_PACKETS \
|
|
|
|
|
(MAX_RX_TOPHONE + MAX_RX_FROMRADIO + 2 * MAX_TX_QUEUE + \
|
2020-04-17 09:48:54 -07:00
|
|
|
2) // max number of packets which can be in flight (either queued from reception or queued for sending)
|
|
|
|
|
|
2025-10-19 10:35:30 +01:00
|
|
|
static MemoryDynamic<meshtastic_MeshPacket> dynamicPool;
|
|
|
|
|
Allocator<meshtastic_MeshPacket> &packetPool = dynamicPool;
|
2025-12-10 13:23:23 +01:00
|
|
|
#elif defined(ARCH_STM32WL) || defined(BOARD_HAS_PSRAM)
|
|
|
|
|
// On STM32 and boards with PSRAM, there isn't enough heap left over for the rest of the firmware if we allocate this statically.
|
2025-10-19 10:35:30 +01:00
|
|
|
// For now, make it dynamic again.
|
|
|
|
|
#define MAX_PACKETS \
|
|
|
|
|
(MAX_RX_TOPHONE + MAX_RX_FROMRADIO + 2 * MAX_TX_QUEUE + \
|
|
|
|
|
2) // max number of packets which can be in flight (either queued from reception or queued for sending)
|
|
|
|
|
|
2025-09-13 12:07:14 -05:00
|
|
|
static MemoryDynamic<meshtastic_MeshPacket> dynamicPool;
|
2025-09-13 11:59:50 -05:00
|
|
|
Allocator<meshtastic_MeshPacket> &packetPool = dynamicPool;
|
|
|
|
|
#else
|
|
|
|
|
// Embedded targets use static memory pools with compile-time constants
|
|
|
|
|
#define MAX_PACKETS_STATIC \
|
|
|
|
|
(MAX_RX_TOPHONE + MAX_RX_FROMRADIO + 2 * MAX_TX_QUEUE + \
|
|
|
|
|
2) // max number of packets which can be in flight (either queued from reception or queued for sending)
|
2020-06-12 11:53:59 -07:00
|
|
|
|
2025-09-13 11:59:50 -05:00
|
|
|
static MemoryPool<meshtastic_MeshPacket, MAX_PACKETS_STATIC> staticPool;
|
2023-01-21 18:22:19 +01:00
|
|
|
Allocator<meshtastic_MeshPacket> &packetPool = staticPool;
|
2025-09-13 11:59:50 -05:00
|
|
|
#endif
|
2020-04-17 09:48:54 -07:00
|
|
|
|
2024-09-30 18:07:11 -05:00
|
|
|
static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1] __attribute__((__aligned__));
|
2023-01-07 14:57:00 +01:00
|
|
|
|
2020-04-17 09:48:54 -07:00
|
|
|
/**
|
|
|
|
|
* Constructor
|
|
|
|
|
*
|
|
|
|
|
* Currently we only allow one interface, that may change in the future
|
|
|
|
|
*/
|
2020-10-09 14:16:51 +08:00
|
|
|
Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRADIO)
|
2020-06-16 19:55:14 -07:00
|
|
|
{
|
2020-07-10 13:52:26 -07:00
|
|
|
// This is called pre main(), don't touch anything here, the following code is not safe
|
2020-06-17 16:04:37 -07:00
|
|
|
|
2024-10-14 06:11:43 +02:00
|
|
|
/* LOG_DEBUG("Size of NodeInfo %d", sizeof(NodeInfo));
|
|
|
|
|
LOG_DEBUG("Size of SubPacket %d", sizeof(SubPacket));
|
|
|
|
|
LOG_DEBUG("Size of MeshPacket %d", sizeof(MeshPacket)); */
|
2020-10-10 09:57:57 +08:00
|
|
|
|
|
|
|
|
fromRadioQueue.setReader(this);
|
2023-04-07 15:05:19 +02:00
|
|
|
|
|
|
|
|
// init Lockguard for crypt operations
|
|
|
|
|
assert(!cryptLock);
|
|
|
|
|
cryptLock = new concurrency::Lock();
|
2020-06-16 19:55:14 -07:00
|
|
|
}
|
2020-04-17 09:48:54 -07:00
|
|
|
|
2025-09-25 03:17:51 -07:00
|
|
|
bool Router::shouldDecrementHopLimit(const meshtastic_MeshPacket *p)
|
|
|
|
|
{
|
|
|
|
|
// First hop MUST always decrement to prevent retry issues
|
|
|
|
|
bool isFirstHop = (p->hop_start != 0 && p->hop_start == p->hop_limit);
|
|
|
|
|
if (isFirstHop) {
|
|
|
|
|
return true; // Always decrement on first hop
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if both local device and previous relay are routers (including CLIENT_BASE)
|
|
|
|
|
bool localIsRouter =
|
|
|
|
|
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE,
|
|
|
|
|
meshtastic_Config_DeviceConfig_Role_CLIENT_BASE);
|
|
|
|
|
|
|
|
|
|
// If local device isn't a router, always decrement
|
|
|
|
|
if (!localIsRouter) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For subsequent hops, check if previous relay is a favorite router
|
|
|
|
|
// Optimized search for favorite routers with matching last byte
|
|
|
|
|
// Check ordering optimized for IoT devices (cheapest checks first)
|
2025-09-27 08:32:43 -05:00
|
|
|
for (size_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
|
2025-09-25 03:17:51 -07:00
|
|
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
|
|
|
|
|
if (!node)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Check 1: is_favorite (cheapest - single bool)
|
|
|
|
|
if (!node->is_favorite)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Check 2: has_user (cheap - single bool)
|
|
|
|
|
if (!node->has_user)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Check 3: role check (moderate cost - multiple comparisons)
|
|
|
|
|
if (!IS_ONE_OF(node->user.role, meshtastic_Config_DeviceConfig_Role_ROUTER,
|
2025-09-27 08:32:43 -05:00
|
|
|
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) {
|
2025-09-25 03:17:51 -07:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check 4: last byte extraction and comparison (most expensive)
|
|
|
|
|
if (nodeDB->getLastByteOfNodeNum(node->num) == p->relay_node) {
|
|
|
|
|
// Found a favorite router match
|
|
|
|
|
LOG_DEBUG("Identified favorite relay router 0x%x from last byte 0x%x", node->num, p->relay_node);
|
|
|
|
|
return false; // Don't decrement hop_limit
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// No favorite router match found, decrement hop_limit
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-17 09:48:54 -07:00
|
|
|
/**
|
|
|
|
|
* do idle processing
|
|
|
|
|
* Mostly looking in our incoming rxPacket queue and calling handleReceived.
|
|
|
|
|
*/
|
2020-10-10 09:57:57 +08:00
|
|
|
int32_t Router::runOnce()
|
2020-04-17 09:48:54 -07:00
|
|
|
{
|
2023-01-21 18:22:19 +01:00
|
|
|
meshtastic_MeshPacket *mp;
|
2023-01-28 06:39:14 -06:00
|
|
|
while ((mp = fromRadioQueue.dequeuePtr(0)) != NULL) {
|
2021-03-28 12:16:37 +08:00
|
|
|
// printPacket("handle fromRadioQ", mp);
|
2020-05-23 09:24:22 -07:00
|
|
|
perhapsHandleReceived(mp);
|
2020-04-17 09:48:54 -07:00
|
|
|
}
|
2020-10-09 14:16:51 +08:00
|
|
|
|
2024-11-04 19:15:59 -06:00
|
|
|
// LOG_DEBUG("Sleep forever!");
|
2020-10-10 09:57:57 +08:00
|
|
|
return INT32_MAX; // Wait a long time - until we get woken for the message queue
|
2020-04-17 09:48:54 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-05 09:24:00 +08:00
|
|
|
/**
|
|
|
|
|
* RadioInterface calls this to queue up packets that have been received from the radio. The router is now responsible for
|
|
|
|
|
* freeing the packet
|
|
|
|
|
*/
|
2023-01-21 18:22:19 +01:00
|
|
|
void Router::enqueueReceivedMessage(meshtastic_MeshPacket *p)
|
2021-04-05 09:24:00 +08:00
|
|
|
{
|
2024-11-01 21:48:55 +01:00
|
|
|
// Try enqueue until successful
|
|
|
|
|
while (!fromRadioQueue.enqueue(p, 0)) {
|
|
|
|
|
meshtastic_MeshPacket *old_p;
|
|
|
|
|
old_p = fromRadioQueue.dequeuePtr(0); // Dequeue and discard the oldest packet
|
|
|
|
|
if (old_p) {
|
|
|
|
|
printPacket("fromRadioQ full, drop oldest!", old_p);
|
|
|
|
|
packetPool.release(old_p);
|
|
|
|
|
}
|
2021-04-05 09:24:00 +08:00
|
|
|
}
|
2024-11-01 21:48:55 +01:00
|
|
|
// Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME
|
|
|
|
|
setReceivedMessage();
|
2021-04-05 09:24:00 +08:00
|
|
|
}
|
|
|
|
|
|
2020-05-19 11:56:17 -07:00
|
|
|
/// Generate a unique packet id
|
|
|
|
|
// FIXME, move this someplace better
|
|
|
|
|
PacketId generatePacketId()
|
|
|
|
|
{
|
2024-07-23 11:52:14 -05:00
|
|
|
static uint32_t rollingPacketId; // Note: trying to keep this in noinit didn't help for working across reboots
|
2020-05-19 11:56:17 -07:00
|
|
|
static bool didInit = false;
|
|
|
|
|
|
2023-01-28 06:39:14 -06:00
|
|
|
if (!didInit) {
|
2020-05-19 11:56:17 -07:00
|
|
|
didInit = true;
|
2020-06-06 13:16:36 -07:00
|
|
|
|
|
|
|
|
// pick a random initial sequence number at boot (to prevent repeated reboots always starting at 0)
|
|
|
|
|
// Note: we mask the high order bit to ensure that we never pass a 'negative' number to random
|
2024-07-23 11:52:14 -05:00
|
|
|
rollingPacketId = random(UINT32_MAX & 0x7fffffff);
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Initial packet id %u", rollingPacketId);
|
2020-05-19 11:56:17 -07:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 11:52:14 -05:00
|
|
|
rollingPacketId++;
|
|
|
|
|
|
2024-08-26 15:48:47 -05:00
|
|
|
rollingPacketId &= ID_COUNTER_MASK; // Mask out the top 22 bits
|
2024-07-23 11:52:14 -05:00
|
|
|
PacketId id = rollingPacketId | random(UINT32_MAX & 0x7fffffff) << 10; // top 22 bits
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Partially randomized packet id %u", id);
|
2020-06-03 13:15:45 -07:00
|
|
|
return id;
|
2020-05-19 11:56:17 -07:00
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
meshtastic_MeshPacket *Router::allocForSending()
|
2020-05-19 11:56:17 -07:00
|
|
|
{
|
2023-01-21 18:22:19 +01:00
|
|
|
meshtastic_MeshPacket *p = packetPool.allocZeroed();
|
2020-05-19 11:56:17 -07:00
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // Assume payload is decoded at start.
|
2024-03-21 09:06:37 -05:00
|
|
|
p->from = nodeDB->getNodeNum();
|
2020-05-19 11:56:17 -07:00
|
|
|
p->to = NODENUM_BROADCAST;
|
2024-07-29 20:16:47 -05:00
|
|
|
p->hop_limit = Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit);
|
2020-05-19 11:56:17 -07:00
|
|
|
p->id = generatePacketId();
|
2020-12-13 16:11:38 +08:00
|
|
|
p->rx_time =
|
|
|
|
|
getValidTime(RTCQualityFromNet); // Just in case we process the packet locally - make sure it has a valid timestamp
|
2020-05-19 11:56:17 -07:00
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-07 10:26:11 +08:00
|
|
|
/**
|
|
|
|
|
* Send an ack or a nak packet back towards whoever sent idFrom
|
|
|
|
|
*/
|
2025-10-01 16:31:53 -04:00
|
|
|
void Router::sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, uint8_t hopLimit,
|
|
|
|
|
bool ackWantsAck)
|
2021-02-07 10:26:11 +08:00
|
|
|
{
|
2025-10-01 16:31:53 -04:00
|
|
|
routingModule->sendAckNak(err, to, idFrom, chIndex, hopLimit, ackWantsAck);
|
2021-02-07 10:26:11 +08:00
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
void Router::abortSendAndNak(meshtastic_Routing_Error err, meshtastic_MeshPacket *p)
|
2021-02-22 12:57:26 +08:00
|
|
|
{
|
2024-11-04 19:15:59 -06:00
|
|
|
LOG_ERROR("Error=%d, return NAK and drop packet", err);
|
2023-01-10 21:12:40 +01:00
|
|
|
sendAckNak(err, getFrom(p), p->id, p->channel);
|
2021-02-22 12:57:26 +08:00
|
|
|
packetPool.release(p);
|
|
|
|
|
}
|
2021-02-11 17:39:53 +08:00
|
|
|
|
2021-03-24 13:25:10 +08:00
|
|
|
void Router::setReceivedMessage()
|
|
|
|
|
{
|
2024-10-14 06:11:43 +02:00
|
|
|
// LOG_DEBUG("set interval to ASAP");
|
2021-03-06 11:13:33 +08:00
|
|
|
setInterval(0); // Run ASAP, so we can figure out our correct sleep time
|
2021-03-28 12:16:37 +08:00
|
|
|
runASAP = true;
|
2021-03-06 11:13:33 +08:00
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
meshtastic_QueueStatus Router::getQueueStatus()
|
2023-01-04 14:56:52 +02:00
|
|
|
{
|
2023-08-06 15:18:23 +02:00
|
|
|
if (!iface) {
|
|
|
|
|
meshtastic_QueueStatus qs;
|
|
|
|
|
qs.res = qs.mesh_packet_id = qs.free = qs.maxlen = 0;
|
|
|
|
|
return qs;
|
2023-08-06 15:51:37 +02:00
|
|
|
} else
|
|
|
|
|
return iface->getQueueStatus();
|
2023-01-04 14:56:52 +02:00
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
|
2020-05-21 16:34:16 -07:00
|
|
|
{
|
2024-08-31 15:04:35 -05:00
|
|
|
if (p->to == 0) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_ERROR("Packet received with to: of 0!");
|
2024-08-31 15:04:35 -05:00
|
|
|
}
|
2020-12-13 16:11:38 +08:00
|
|
|
// No need to deliver externally if the destination is the local node
|
2024-10-04 13:28:51 +02:00
|
|
|
if (isToUs(p)) {
|
2021-04-05 09:24:00 +08:00
|
|
|
printPacket("Enqueued local", p);
|
|
|
|
|
enqueueReceivedMessage(p);
|
2020-05-21 16:34:16 -07:00
|
|
|
return ERRNO_OK;
|
2023-01-28 06:39:14 -06:00
|
|
|
} else if (!iface) {
|
2021-02-07 10:26:11 +08:00
|
|
|
// We must be sending to remote nodes also, fail if no interface found
|
2023-01-21 18:22:19 +01:00
|
|
|
abortSendAndNak(meshtastic_Routing_Error_NO_INTERFACE, p);
|
2020-12-13 16:11:38 +08:00
|
|
|
|
2021-02-07 10:26:11 +08:00
|
|
|
return ERRNO_NO_INTERFACES;
|
2023-01-28 06:39:14 -06:00
|
|
|
} else {
|
2021-02-07 10:26:11 +08:00
|
|
|
// If we are sending a broadcast, we also treat it as if we just received it ourself
|
|
|
|
|
// this allows local apps (and PCs) to see broadcasts sourced locally
|
2024-10-19 12:48:00 -05:00
|
|
|
if (isBroadcast(p->to)) {
|
2021-10-27 13:16:51 +00:00
|
|
|
handleReceived(p, src);
|
2021-02-07 10:26:11 +08:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 04:30:12 +01:00
|
|
|
// don't override if a channel was requested and no need to set it when PKI is enforced
|
2025-01-10 04:46:26 -06:00
|
|
|
if (!p->channel && !p->pki_encrypted && !isBroadcast(p->to)) {
|
2025-03-29 14:14:24 +01:00
|
|
|
meshtastic_NodeInfoLite const *node = nodeDB->getMeshNode(p->to);
|
2024-11-09 04:30:12 +01:00
|
|
|
if (node) {
|
2024-09-15 09:26:43 -05:00
|
|
|
p->channel = node->channel;
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("localSend to channel %d", p->channel);
|
2024-09-15 09:26:43 -05:00
|
|
|
}
|
2023-03-29 15:14:48 +02:00
|
|
|
}
|
2023-03-29 13:51:22 +02:00
|
|
|
|
2021-02-07 10:26:11 +08:00
|
|
|
return send(p);
|
|
|
|
|
}
|
2020-05-21 16:34:16 -07:00
|
|
|
}
|
2025-03-16 08:19:17 -05:00
|
|
|
/**
|
|
|
|
|
* 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);
|
|
|
|
|
}
|
2020-05-21 16:34:16 -07:00
|
|
|
|
2020-04-17 09:48:54 -07:00
|
|
|
/**
|
|
|
|
|
* Send a packet on a suitable interface. This routine will
|
|
|
|
|
* later free() the packet to pool. This routine is not allowed to stall.
|
2020-05-09 17:51:20 -07:00
|
|
|
* If the txmit queue is full it might return an error.
|
2020-04-17 09:48:54 -07:00
|
|
|
*/
|
2023-01-21 18:22:19 +01:00
|
|
|
ErrorCode Router::send(meshtastic_MeshPacket *p)
|
2020-04-17 09:48:54 -07:00
|
|
|
{
|
2024-10-04 13:28:51 +02:00
|
|
|
if (isToUs(p)) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_ERROR("BUG! send() called with packet destined for local node!");
|
2023-01-07 14:57:00 +01:00
|
|
|
packetPool.release(p);
|
2023-01-21 18:22:19 +01:00
|
|
|
return meshtastic_Routing_Error_BAD_REQUEST;
|
2023-01-07 14:57:00 +01:00
|
|
|
} // should have already been handled by sendLocal
|
2020-05-21 16:34:16 -07:00
|
|
|
|
2022-11-26 20:50:00 +01:00
|
|
|
// Abort sending if we are violating the duty cycle
|
2023-01-28 06:39:14 -06:00
|
|
|
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
|
2023-01-10 21:12:17 +01:00
|
|
|
float hourlyTxPercent = airTime->utilizationTXPercent();
|
2023-01-28 06:39:14 -06:00
|
|
|
if (hourlyTxPercent > myRegion->dutyCycle) {
|
2023-01-21 14:34:29 +01:00
|
|
|
uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
|
2025-07-28 23:51:38 +01:00
|
|
|
|
2024-11-04 20:09:23 +08:00
|
|
|
LOG_WARN("Duty cycle limit exceeded. Aborting send for now, you can send again in %d mins", silentMinutes);
|
2025-07-28 23:51:38 +01:00
|
|
|
|
2024-08-10 08:33:42 -05:00
|
|
|
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
|
|
|
|
|
cn->has_reply_id = true;
|
|
|
|
|
cn->reply_id = p->id;
|
|
|
|
|
cn->level = meshtastic_LogRecord_Level_WARNING;
|
|
|
|
|
cn->time = getValidTime(RTCQualityFromNet);
|
2024-11-04 20:09:23 +08:00
|
|
|
sprintf(cn->message, "Duty cycle limit exceeded. You can send again in %d mins", silentMinutes);
|
2024-08-10 08:33:42 -05:00
|
|
|
service->sendClientNotification(cn);
|
2025-07-28 23:51:38 +01:00
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
meshtastic_Routing_Error err = meshtastic_Routing_Error_DUTY_CYCLE_LIMIT;
|
2024-10-04 13:28:51 +02:00
|
|
|
if (isFromUs(p)) { // only send NAK to API, not to the mesh
|
2023-01-10 21:12:17 +01:00
|
|
|
abortSendAndNak(err, p);
|
2023-01-28 06:39:14 -06:00
|
|
|
} else {
|
2023-01-10 21:12:17 +01:00
|
|
|
packetPool.release(p);
|
|
|
|
|
}
|
|
|
|
|
return err;
|
|
|
|
|
}
|
2022-11-26 20:50:00 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-17 13:06:23 +08:00
|
|
|
// PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
|
2021-02-22 12:57:26 +08:00
|
|
|
// assert(!nakId); // I don't think we ever send 0hop naks over the wire (other than to the phone), test that assumption with
|
|
|
|
|
// assert
|
2020-05-23 15:48:23 -07:00
|
|
|
|
2020-05-21 16:34:16 -07:00
|
|
|
// Never set the want_ack flag on broadcast packets sent over the air.
|
2024-10-19 12:48:00 -05:00
|
|
|
if (isBroadcast(p->to))
|
2020-05-21 16:34:16 -07:00
|
|
|
p->want_ack = false;
|
|
|
|
|
|
2021-03-05 10:19:27 +08:00
|
|
|
// Up until this point we might have been using 0 for the from address (if it started with the phone), but when we send over
|
|
|
|
|
// the lora we need to make sure we have replaced it with our local address
|
|
|
|
|
p->from = getFrom(p);
|
|
|
|
|
|
2.6 changes (#5806)
* 2.6 protos
* [create-pull-request] automated change (#5789)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Hello world support for UDP broadcasts over the LAN on ESP32 (#5779)
* UDP local area network meshing on ESP32
* Logs
* Comment
* Update UdpMulticastThread.h
* Changes
* Only use router->send
* Make NodeDatabase (and file) independent of DeviceState (#5813)
* Make NodeDatabase (and file) independent of DeviceState
* 70
* Remove logging statement no longer needed
* Explicitly set CAD symbols, improve slot time calculation and adjust CW size accordingly (#5772)
* File system persistence fixes
* [create-pull-request] automated change (#6000)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Update ref
* Back to 80
* [create-pull-request] automated change (#6002)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* 2.6 <- Next hop router (#6005)
* Initial version of NextHopRouter
* Set original hop limit in header flags
* Short-circuit to FloodingRouter for broadcasts
* If packet traveled 1 hop, set `relay_node` as `next_hop` for the original transmitter
* Set last byte to 0xFF if it ended at 0x00
As per an idea of @S5NC
* Also update next-hop based on received DM for us
* temp
* Add 1 retransmission for intermediate hops when using NextHopRouter
* Add next_hop and relayed_by in PacketHistory for setting next-hop and handle flooding fallback
* Update protos, store multiple relayers
* Remove next-hop update logic from NeighborInfoModule
* Fix retransmissions
* Improve ACKs for repeated packets and responses
* Stop retransmission even if there's not relay node
* Revert perhapsRebroadcast()
* Remove relayer if we cancel a transmission
* Better checking for fallback to flooding
* Fix newlines in traceroute print logs
* Stop retransmission for original packet
* Use relayID
* Also when want_ack is set, we should try to retransmit
* Fix cppcheck error
* Fix 'router' not in scope error
* Fix another cppcheck error
* Check for hop_limit and also update next hop when `hop_start == hop_limit` on ACK
Also check for broadcast in `getNextHop()`
* Formatting and correct NUM_RETRANSMISSIONS
* Update protos
* Start retransmissions in NextHopRouter if ReliableRouter didn't do it
* Handle repeated/fallback to flooding packets properly
First check if it's not still in the TxQueue
* Guard against clients setting `next_hop`/`relay_node`
* Don't cancel relay if we were the assigned next-hop
* Replies (e.g. tapback emoji) are also a valid confirmation of receipt
---------
Co-authored-by: GUVWAF <thijs@havinga.eu>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
* fix "native" compiler errors/warnings NodeDB.h
* fancy T-Deck / SenseCAP Indicator / unPhone / PICOmputer-S3 TFT screen (#3259)
* lib update: light theme
* fix merge issue
* lib update: home buttons + button try-fix
* lib update: icon color fix
* lib update: fix instability/crash on notification
* update lib: timezone
* timezone label
* lib update: fix set owner
* fix spiLock in RadioLibInterface
* add picomputer tft build
* picomputer build
* fix compiler error std::find()
* fix merge
* lib update: theme runtime config
* lib update: packet logger + T-Deck Plus
* lib update: mesh detector
* lib update: fix brightness & trackball crash
* try-fix less paranoia
* sensecap indicator updates
* lib update: indicator fix
* lib update: statistic & some fixes
* lib-update: other T-Deck touch driver
* use custom touch driver for Indicator
* lower tft task prio
* prepare LVGL ST7789 driver
* lib update: try-fix audio
* Drop received packets from self
* Additional decoded packet ignores
* Honor flip & color for Heltec T114 and T190 (#4786)
* Honor TFT_MESH color if defined for Heltec T114 or T190
* Temporary: point lib_deps at fork of Heltec's ST7789 library
For demo only, until ST7789 is merged
* Update lib_deps; tidy preprocessor logic
* Download debian files after firmware zip
* set title for protobufs bump PR (#4792)
* set title for version bump PR (#4791)
* Enable Dependabot
* chore: trunk fmt
* fix dependabot syntax (#4795)
* fix dependabot syntax
* Update dependabot.yml
* Update dependabot.yml
* Bump peter-evans/create-pull-request from 6 to 7 in /.github/workflows (#4797)
* Bump docker/build-push-action from 5 to 6 in /.github/workflows (#4800)
* Actions: Semgrep Images have moved from returntocorp to semgrep (#4774)
https://hub.docker.com/r/returntocorp/semgrep notes: "We've moved!
Official Docker images for Semgrep now available at semgrep/semgrep."
Patch updates our CI workflow for these images.
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* Bump meshtestic from `31ee3d9` to `37245b3` (#4799)
Bumps [meshtestic](https://github.com/meshtastic/meshTestic) from `31ee3d9` to `37245b3`.
- [Commits](https://github.com/meshtastic/meshTestic/compare/31ee3d90c8bef61e835c3271be2c7cda8c4a5cc2...37245b3d612a9272f546bbb092837bafdad46bc2)
---
updated-dependencies:
- dependency-name: meshtestic
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* [create-pull-request] automated change (#4789)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Bump pnpm/action-setup from 2 to 4 in /.github/workflows (#4798)
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 2 to 4.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v2...v4)
---
updated-dependencies:
- dependency-name: pnpm/action-setup
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Raspberry Pico2 - needs protos
* Re-order doDeepSleep (#4802)
Make sure PMU sleep takes place before I2C ends
* [create-pull-request] automated change
* heltec-wireless-bridge
requires Proto PR first
* feat: trigger class update when protobufs are changed
* meshtastic/ is a test suite; protobufs/ contains protobufs;
* Update platform-native to pick up portduino crash fix (#4807)
* Hopefully extract and commit to meshtastic.github.io
* CI fixes
* [Board] DIY "t-energy-s3_e22" (#4782)
* New variant "t-energy-s3_e22"
- Lilygo T-Energy-S3
- NanoVHF "Mesh-v1.06-TTGO-T18" board
- Ebyte E22 Series
* add board_level = extra
* Update variant.h
---------
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
* Consolidate variant build steps (#4806)
* poc: consolidate variant build steps
* use build-variant action
* only checkout once and clean up after run
* Revert "Consolidate variant build steps (#4806)" (#4816)
This reverts commit 9f8d86cb25febfb86c57f395549b7deb82458065.
* Make Ublox code more readable (#4727)
* Simplify Ublox code
Ublox comes in a myriad of versions and settings. Presently our
configuration code does a lot of branching based on versions being
or not being present.
This patch adds version detection earlier in the piece and branches
on the set gnssModel instead to create separate setup methods for Ublox 6,
Ublox 7/8/9, and Ublox10.
Additionally, adds a macro to make the code much shorter and more
readable.
* Make trunk happy
* Make trunk happy
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* Consider the LoRa header when checking packet length
* Minor fix (#4666)
* Minor fixes
It turns out setting a map value with the index notation causes
an lookup that can be avoided with emplace. Apply this to one line in
the StoreForward module.
Fix also Cppcheck-determined highly minor performance increase by
passing gpiochipname as a const reference :)
The amount of cycles used on this laptop while learning about these
callouts from cppcheck is unlikely to ever be more than the cycles
saved by the fixes ;)
* Update PortduinoGlue.cpp
* Revert "Update classes on protobufs update" (#4824)
* Revert "Update classes on protobufs update"
* remove quotes to fix trunk.
---------
Co-authored-by: Tom Fifield <tom@tomfifield.net>
* Implement optional second I2C bus for NRF52840
Enabled at compile-time if WIRE_INFERFACES_COUNT defined as 2
* Add I2C bus to Heltec T114 header pins
SDA: P0.13
SCL: P0.16
Uses bus 1, leaving bus 0 routed to the unpopulated footprint for the RTC (general future-proofing)
* Tidier macros
* Swap SDA and SCL
SDA=P0.16, SCL=P0.13
* Refactor and consolidate time window logic (#4826)
* Refactor and consolidate windowing logic
* Trunk
* Fixes
* More
* Fix braces and remove unused now variables.
There was a brace in src/mesh/RadioLibInterface.cpp that was breaking
compile on some architectures.
Additionally, there were some brace errors in
src/modules/Telemetry/AirQualityTelemetry.cpp
src/modules/Telemetry/EnvironmentTelemetry.cpp
src/mesh/wifi/WiFiAPClient.cpp
Move throttle include in WifiAPClient.cpp to top.
Add Default.h to sleep.cpp
rest of files just remove unused now variables.
* Remove a couple more meows
---------
Co-authored-by: Tom Fifield <tom@tomfifield.net>
* Rename message length headers and set payload max to 255 (#4827)
* Rename message length headers and set payload max to 255
* Add MESHTASTIC_PKC_OVERHEAD
* compare to MESHTASTIC_HEADER_LENGTH
---------
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
* Check for null before printing debug (#4835)
* fix merge
* try-fix crash
* lib update: fix neighbors
* fix GPIO0 mode after I2S audio
* lib update: audio fix
* lib update: fixes and improvements
* extra
* added ILI9342 (from master)
* device-ui persistency
* review update
* fix request, add handled
* fix merge issue
* fix merge issue
* remove newline
* remove newlines from debug log
* playing with locks; but needs more testing
* diy mesh-tab initial files
* board definition for mesh-tab (not yet used)
* use DISPLAY_SET_RESOLUTION to avoid hw dependency in code
* no telemetry for Indicator
* 16MB partition for Indicator
* 8MB partition for Indicator
* stability: add SPI lock before saving via littleFS
* dummy for config transfer (#5154)
* update indicator (due to compile and linker errors)
* remove faulty partition line
* fix missing include
* update indicator board
* update mesh-tab ILI9143 TFT
* fix naming
* mesh-tab targets
* try: disable duplicate locks
* fix nodeDB erase loop when free mem returns invalid value (0, -1).
* upgrade toolchain for nrf52 to gcc 9.3.1
* try-fix (workaround) T-Deck audio crash
* update mesh-tab tft configs
* set T-Deck audio to unused 48 (mem mclk)
* swap mclk to gpio 21
* update meshtab voltage divider
* update mesh-tab ini
* Fixed the issue that indicator device uploads via rp2040 serial port in some cases.
* Fixed the issue that the touch I2C address definition was not effective.
* Fixed the issue that the wifi configuration saved to RAM did not take effect.
* rotation fix; added ST7789 3.2" display
* dreamcatcher: assign GPIO44 to audio mclk
* mesh-tab touch updates
* add mesh-tab powersave as default
* fix DIO1 wakeup
* mesh-tab: enable alert message menu
* Streamline board definitions for first tech preview. (#5390)
* Streamline board definitions for first tech preview. TBD: Indicator Support
* add point-of-checkin
* use board/unphone.json
---------
Co-authored-by: mverch67 <manuel.verch@gmx.de>
* fix native targets
* add RadioLib debugging options for (T-Deck)
* fix T-Deck build
* fix native tft targets for rpi
* remove wrong debug defines
* t-deck-tft button is handled in device-ui
* disable default lightsleep for indicator
* Windows Support - Trunk and Platformio (#5397)
* Add support for GPG
* Add usb device support
* Add trunk.io to devcontainer
* Trunk things
* trunk fmt
* formatting
* fix trivy/DS002, checkov/CKV_DOCKER_3
* hide docker extension popup
* fix trivy/DS026, checkov/CKV_DOCKER_2
* fix radioLib warnings for T-Deck target
* wake screen with button only
* use custom touch driver
* define wake button for unphone
* use board definition for mesh-tab
* mesh-tab rotation upside-down
* update platform native
* use MESH_TAB hardware model definition
* radioLib update (fix crash/assert)
* reference seeed indicator fix commit arduino-esp32
* Remove unneeded file change :)
* disable serial module and tcp socket api for standalone devices (#5591)
* disable serial module and tcp socket api for standalone devices
* just disable webserver, leave wifi available
* disable socket api
* mesh-tab: lower I2C touch frequency
* log error when packet queue is full
* add more locking for shared SPI devices (#5595)
* add more locking for shared SPI devices
* call initSPI before the lock is used
* remove old one
* don't double lock
* Add missing unlock
* More missing unlocks
* Add locks to SafeFile, remove from `readcb`, introduce some LockGuards
* fix lock in setupSDCard()
* pull radiolib trunk with SPI-CS fixes
* change ContentHandler to Constructor type locks, where applicable
---------
Co-authored-by: mverch67 <manuel.verch@gmx.de>
Co-authored-by: GUVWAF <thijs@havinga.eu>
Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com>
* T-Deck: revert back to lovyanGFX touch driver
* T-Deck: increase allocated PSRAM by 50%
* mesh-tab: streamline target definitions
* update RadioLib 7.1.2
* mesh-tab: fix touch rotation 4.0 inch display
* Mesh-Tab platformio: 4.0inch: increase SPI frequency to max
* mesh-tab: fix rotation for 3.5 IPS capacitive display
* mesh-tab: fix rotation for 3.2 IPS capacitive display
* restructure device-ui library into sub-directories
* preparations for generic DisplayDriverFactory
* T-Deck: increase LVGL memory size
* update lib
* trunk fmt
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
Co-authored-by: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com>
Co-authored-by: Jason Murray <jason@chaosaffe.io>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
Co-authored-by: Austin <vidplace7@gmail.com>
Co-authored-by: virgil <virgil.wang.cj@gmail.com>
Co-authored-by: Mark Trevor Birss <markbirss@gmail.com>
Co-authored-by: Kalle Lilja <15094562+ThatKalle@users.noreply.github.com>
Co-authored-by: GUVWAF <thijs@havinga.eu>
* Version this
* Update platformio.ini (#6006)
* tested higher speed and it works
* Un-extra
* Add -tft environments to the ci matrix
* Exclude unphone tft for now. Something is wonky
* fixed Indicator touch issue (causing IO expander issues), added more RAM
* update lib
* fixed Indicator touch issue (causing IO expander issues), added more RAM (#6013)
* increase T-Deck PSRAM to avoid too early out-of-memory when messages fill up the storage
* update device-ui lib
* Fix T-Deck SD card detection (#6023)
* increase T-Deck PSRAM to avoid too early out-of-memory when messages fill up the storage
* fix SDCard for T-Deck; allow SPI frequency config
* meshtasticd: Add X11 480x480 preset (#6020)
* Littlefs per device
* 2.6 update
* [create-pull-request] automated change (#6037)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* InkHUD UI for E-Ink (#6034)
* Decouple ButtonThread from sleep.cpp
Reorganize sleep observables. Don't call ButtonThread methods inside doLightSleep. Instead, handle in class with new lightsleep Observables.
* InkHUD: initial commit (WIP)
Publicly discloses the current work in progress. Not ready for use.
* feat: battery icon
* chore: implement meshtastic/firmware #5454
Clean up some inline functions
* feat: menu & settings for "jump to applet"
* Remove the beforeRender pattern
It hugely complicates things. If we can achieve acceptable performance without it, so much the better.
* Remove previous Map Applet
Needs re-implementation to work without the beforeRender pattern
* refactor: reimplement map applet
Doesn't require own position
Doesn't require the beforeRender pattern to precalculate; now all-at-once in render
Lays groundwork for fixed-size map with custom background image
* feat: autoshow
Allow user to select which applets (if any) should be automatically brought to foreground when they have new data to display
* refactor: tidy-up applet constructors
misc. jobs including:
- consistent naming
- move initializer-list-only constructors to header
- give derived applets unique identifiers for MeshModule and OSThread logging
* hotfix: autoshow always uses FAST update
In future, it *will* often use FAST, but this will be controlled by a WindowManager component which has not yet been written.
Hotfixed, in case anybody is attempting to use this development version on their deployed devices.
* refactor: bringToForeground no longer requests FAST update
In situations where an applet has moved to foreground because of user input, requestUpdate can be manually called, to upgrade to FAST refresh.
More permanent solution for #23e1dfc
* refactor: extract string storage from ThreadedMessageApplet
Separates the code responsible for storing the limited message history, which was previously part of the ThreadedMessageApplet.
We're now also using this code to store the "most recent message". Previously, this was stored in the `InkHUD::settings` struct, which was much less space-efficient.
We're also now storing the latest DM, laying the foundation for an applet to display only DMs, which will complement the threaded message applet.
* fix: text wrapping
Attempts to fix a disparity between `Applet::printWrapped` and `Applet::getWrappedTextHeight`, which would occasionally cause a ThreadedMessageApplet message to render "too short", overlapping other text.
* fix: purge old constructor
This one slipped through the last commit..
* feat: DM Applet
Useful in combination with the ThreadedMessageApplets, which don't show DMs
* fix: applets shouldn't handle events while deactivated
Only one or two applets were actually doing this, but I'm making a habit of having all applets return early from their event handling methods (as good practice), even if those methods are disabled elsewhere (e.g. not observing observable, return false from wantPacket)
* refactor: allow requesting update without requesting autoshow
Some applets may want to redraw, if they are displayed, but not feel the information is worth being brought to foreground for. Example: ActiveNodesApplet, when purging old nodes from list.
* feat: custom "Recently Active" duration
Allows users to tailor how long nodes will appear in the "Recents" applets, to suit the activity level of their mesh.
* refactor: rename some applets
* fix: autoshow
* fix: getWrappedTextHeight
Remove the "simulate" option from printWrapped; too hard to keep inline with genuine printing (because of AdafruitGFX Fonts' xAdvance, mabye?). Instead of simulating, we printWrapped as normal, and discard pixel output by setting crop. Both methods are similarly inefficient, apparently.
* fix: text wrapping in ThreadedMessageApplet
Wrong arguments were passed to Applet::printWrapped
* feat: notifications for text messages
Only shown if current applet does not already display the same info. Autoshow takes priority over notifications, if both would be used to display the same info.
* feat: optimize FAST vs FULL updates
New UpdateMediator class counts the number of each update type, and suggets which one to use, if the code doesn't already have an explicit prefence. Also performs "maintenance refreshes" unprovoked if display is not given an opportunity to before a FULL refresh through organic use.
* chore: update todo list
* fix: rare lock-up of buttons
* refactor: backlight
Replaces the initial proof-of-concept frontlight code for T-Echo
Presses less than 5 seconds momentarily illuminate the display
Presses longer than 5 seconds latch the light, requiring another tap to disable
If user has previously removed the T-Echo's capacitive touch button (some DIY projects), the light is controlled by the on-screen menu. This fallback is used by all T-Echo devices, until a press of the capacitive touch button is detected.
* feat: change tile with aux button
Applied to VM-E290.
Working as is, but a refactor of WindowManager::render is expected shortly, which will also tidy code from this push.
* fix: specify out-of-the-box tile assignments
Prevents placeholder applet showing on initial boot, for devices which use a mult-tile layout by default (VM-E290)
* fix: verify settings version when loading
* fix: wrong settings version
* refactor: remove unimplemented argument from requestUpdate
Specified whether or not to update "async", however the implementation was slightly broken, Applet::requestUpdate is only handled next time WindowManager::runOnce is called. This didn't allow code to actually await an update, which was misleading.
* refactor: renaming
Applet::render becomes Applet::onRender.
Tile::displayedApplet becomes Tile::assignedApplet.
New onRender method name allows us to move some of the pre and post render code from WindowManager into new Applet::render method, which will call onRender for us.
* refactor: rendering
Bit of a tidy-up. No intended change in behavior.
* fix: optimize refresh times
Shorter wait between retrying update if display was previously busy.
Set anticipated update durations closer to observed values. No signifacant performance increase, but does decrease the amount of polling required.
* feat: blocking update for E-Ink
Option to wait for display update to complete before proceeding. Important when shutting down the device.
* refactor: allow system applets to lock rendering
Temporarily prevents other applets from rendering.
* feat: boot and shutdown screens
* feat: BluetoothStatus
Adds a meshtastic::Status object which exposes the state of the Bluetooth connection. Intends to allow decoupling of UI code.
* feat: Bluetooth pairing screen
* fix: InkHUD defaults not honored
* fix: random Bluetooth pin for NicheGraphics UIs
* chore: button interrupts tested
* fix: emoji reactions show as blank messages
* fix: autoshow and notification triggered by outgoing message
* feat: save InkHUD data before reboot
Implemented with a new Observable. Previously, config and a few recent messages were saved on shutdown. These were lost if the device rebooted, for example when firmware settings were changed by a client. Now, the InkHUD config and recent messages saved on reboot, the same as during an intentional shutdown.
* feat: imperial distances
Controlled by the config.display.units setting
* fix: hide features which are not yet implemented
* refactor: faster rendering
Previously, only tiles which requested update were re-rendered. Affected tiles had their region blanked before render, pixel by pixel. Benchmarking revealed that it is significantly faster to memset the framebuffer and redraw all tiles.
* refactor: tile ownership
Tiles and Applets now maintain a reciprocal link, which is enforced by asserts. Less confusing than the old situation, where an applet and a tile may disagree on their relationship. Empty tiles are now identified by a nullptr *Applet, instead of by having the placeholderApplet assigned.
* fix: notifications and battery when menu open
Do render notifications in front of menu; don't render battery icon in front of menu.
* fix: simpler defaults
Don't expose new users to multiplexed applets straight away: make them enable the feature for themselves.
* fix: Inputs::TwoButton interrupts, when only one button in use
* fix: ensure display update is complete when ESP32 enters light sleep
Many panels power down automatically, but some require active intervention from us. If light sleep (ESP32) occurs during a display update, these panels could potentially remain powered on, applying voltage the pixels for an extended period of time, and potentially damaging the display.
* fix: honor per-variant user tile limit
Set as the default value for InkHUD::settings.userTiles.maxCount in nicheGraphics.h
* feat: initial InkHUD support for Wireless Paper v1.1 and VM-E213
* refactor: Heard and Recents Applets
Tidier code, significant speed boost. Possibly no noticable change in responsiveness, but rendering now spends much less time blocking execution, which is important for correction functioning of the other firmware components.
* refactor: use a common pio base config
Easier to make any future PlatformIO config changes
* feat: tips
Show information that we think the user might find helpful. Some info shown first boot only. Other info shown when / if relevant.
* fix: text wrapping for '\n'
Previously, the newline was honored, but the adojining word was not printed.
* Decouple ButtonThread from sleep.cpp
Reorganize sleep observables. Don't call ButtonThread methods inside doLightSleep. Instead, handle in class with new lightsleep Observables.
* feat: BluetoothStatus
Adds a meshtastic::Status object which exposes the state of the Bluetooth connection. Intends to allow decoupling of UI code.
* feat: observable for reboot
* refactor: Heltec VM-E290 installDefaultConfig
* fix: random Bluetooth pin for NicheGraphics UIs
* update device-ui: fix touch/crash issue while light sleep
* Collect inkhud
* fix: InkHUD shouldn't nag about timezone (#6040)
* Guard eink drivers w/ MESHTASTIC_INCLUDE_NICHE_GRAPHICS
* Case sensitive perhaps?
* More case-sensitivity instances
* Moar
* RTC
* Yet another case issue!
* Sigh...
* MUI: BT programming mode (#6046)
* allow BT connection with disabled MUI
* Update device-ui
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* MUI: fix nag timeout, disable BT programming mode for native (#6052)
* allow BT connection with disabled MUI
* Update device-ui
* MUI: fix nag timeout default and remove programming mode for native
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* remove debuglog leftover
* Wireless Paper: remove stray board_level = extra (#6060)
Makes sure the InkHUD version gets build into the release zip
* Fixed persistence stragglers from NodeDB / Device State divorce (#6059)
* Increase `MAX_THREADS` for InkHUD variants with WiFi (#6064)
* Licensed usage compliance (#6047)
* Prevent psk and legacy admin channel on licensed mode
* Move it
* Consolidate warning strings
* More holes
* Device UI submodule bump
* Prevent licensed users from rebroadcasting unlicensed traffic (#6068)
* Prevent licensed users from rebroadcasting unlicensed traffic
* Added method and enum to make user license status more clear
* MUI: move UI initialization out of main.cpp and adding lightsleep observer + mutex (#6078)
* added device-ui to lightSleep observers for handling graceful sleep; refactoring main.cpp
* bump lib version
* Update device-ui
* unPhone TFT: include into build, enable SD card, increase PSRAM (#6082)
* unPhone-tft: include into build, enable SD card, increase assigned PSRAM
* lib update
* Backup / migrate pub private keys when upgrading to new files in 2.6 (#6096)
* Save a backup of pub/private keys before factory reset
* Fix licensed mode warning
* Unlock spi on else file doesn't exist
* Update device-ui
* Update protos and device-ui
* [create-pull-request] automated change (#6129)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Proto
* [create-pull-request] automated change (#6131)
* Proto update for backup
* [create-pull-request] automated change (#6133)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Update protobufs
* Space
* [create-pull-request] automated change (#6144)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Protos
* [create-pull-request] automated change (#6152)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Updeet
* device-ui lib update
* fix channel OK button
* device-lib update: fix settings panel -> no scrolling
* device-ui lib: last minute update
* defined(SENSECAP_INDICATOR)
* MUI hot-fix pub/priv keys
* MUI hot-fix username dialog
* MUI: BT programming mode button
* Update protobufs
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
Co-authored-by: GUVWAF <thijs@havinga.eu>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
Co-authored-by: mverch67 <manuel.verch@gmx.de>
Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com>
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
Co-authored-by: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com>
Co-authored-by: Jason Murray <jason@chaosaffe.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
Co-authored-by: Austin <vidplace7@gmail.com>
Co-authored-by: virgil <virgil.wang.cj@gmail.com>
Co-authored-by: Mark Trevor Birss <markbirss@gmail.com>
Co-authored-by: Kalle Lilja <15094562+ThatKalle@users.noreply.github.com>
Co-authored-by: rcarteraz <robert.l.carter2@gmail.com>
2025-03-01 06:18:33 -06:00
|
|
|
p->relay_node = nodeDB->getLastByteOfNodeNum(getNodeNum()); // set the relayer to us
|
2024-03-08 14:13:57 +01:00
|
|
|
// If we are the original transmitter, set the hop limit with which we start
|
2024-10-04 13:28:51 +02:00
|
|
|
if (isFromUs(p))
|
2024-03-08 14:13:57 +01:00
|
|
|
p->hop_start = p->hop_limit;
|
|
|
|
|
|
2020-05-21 16:34:16 -07:00
|
|
|
// If the packet hasn't yet been encrypted, do so now (it might already be encrypted if we are just forwarding it)
|
|
|
|
|
|
2024-07-03 16:29:07 -05:00
|
|
|
if (!(p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag ||
|
|
|
|
|
p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)) {
|
|
|
|
|
return meshtastic_Routing_Error_BAD_REQUEST;
|
|
|
|
|
}
|
2020-05-21 16:34:16 -07:00
|
|
|
|
2024-08-30 21:54:44 +02:00
|
|
|
fixPriority(p); // Before encryption, fix the priority if it's unset
|
|
|
|
|
|
2021-04-04 09:20:37 +08:00
|
|
|
// If the packet is not yet encrypted, do so now
|
2023-01-28 06:39:14 -06:00
|
|
|
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
2021-04-04 09:20:37 +08:00
|
|
|
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
2025-09-09 10:29:07 -05:00
|
|
|
|
2025-09-11 07:57:42 -05:00
|
|
|
DEBUG_HEAP_BEFORE;
|
2024-01-25 11:42:34 -03:00
|
|
|
meshtastic_MeshPacket *p_decoded = packetPool.allocCopy(*p);
|
2025-09-11 07:57:42 -05:00
|
|
|
DEBUG_HEAP_AFTER("Router::send", p_decoded);
|
2022-01-29 06:03:48 +13:00
|
|
|
|
2021-04-05 09:24:00 +08:00
|
|
|
auto encodeResult = perhapsEncode(p);
|
2024-08-13 09:15:20 -05:00
|
|
|
if (encodeResult != meshtastic_Routing_Error_NONE) {
|
2024-01-25 11:42:34 -03:00
|
|
|
packetPool.release(p_decoded);
|
2024-12-05 03:00:19 +01:00
|
|
|
p->channel = 0; // Reset the channel to 0, so we don't use the failing hash again
|
2021-04-05 09:24:00 +08:00
|
|
|
abortSendAndNak(encodeResult, p);
|
|
|
|
|
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
|
|
|
|
}
|
2024-03-25 05:33:57 -06:00
|
|
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
2024-02-21 20:00:14 +01:00
|
|
|
// Only publish to MQTT if we're the original transmitter of the packet
|
2024-10-04 13:28:51 +02:00
|
|
|
if (moduleConfig.mqtt.enabled && isFromUs(p) && mqtt) {
|
2024-02-21 20:00:14 +01:00
|
|
|
mqtt->onSend(*p, *p_decoded, chIndex);
|
2022-12-30 14:51:00 +01:00
|
|
|
}
|
2024-03-25 05:33:57 -06:00
|
|
|
#endif
|
2024-01-25 11:42:34 -03:00
|
|
|
packetPool.release(p_decoded);
|
2020-05-21 16:34:16 -07:00
|
|
|
}
|
|
|
|
|
|
2025-04-09 13:13:49 +02:00
|
|
|
#if HAS_UDP_MULTICAST
|
2025-04-30 12:52:42 +02:00
|
|
|
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
|
|
|
|
udpHandler->onSend(const_cast<meshtastic_MeshPacket *>(p));
|
2025-04-09 13:13:49 +02:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-02-07 10:26:11 +08:00
|
|
|
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
|
|
|
|
|
return iface->send(p);
|
2020-04-17 09:48:54 -07:00
|
|
|
}
|
|
|
|
|
|
2021-02-11 17:39:53 +08:00
|
|
|
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
|
2021-02-22 12:57:26 +08:00
|
|
|
bool Router::cancelSending(NodeNum from, PacketId id)
|
|
|
|
|
{
|
2.6 changes (#5806)
* 2.6 protos
* [create-pull-request] automated change (#5789)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Hello world support for UDP broadcasts over the LAN on ESP32 (#5779)
* UDP local area network meshing on ESP32
* Logs
* Comment
* Update UdpMulticastThread.h
* Changes
* Only use router->send
* Make NodeDatabase (and file) independent of DeviceState (#5813)
* Make NodeDatabase (and file) independent of DeviceState
* 70
* Remove logging statement no longer needed
* Explicitly set CAD symbols, improve slot time calculation and adjust CW size accordingly (#5772)
* File system persistence fixes
* [create-pull-request] automated change (#6000)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Update ref
* Back to 80
* [create-pull-request] automated change (#6002)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* 2.6 <- Next hop router (#6005)
* Initial version of NextHopRouter
* Set original hop limit in header flags
* Short-circuit to FloodingRouter for broadcasts
* If packet traveled 1 hop, set `relay_node` as `next_hop` for the original transmitter
* Set last byte to 0xFF if it ended at 0x00
As per an idea of @S5NC
* Also update next-hop based on received DM for us
* temp
* Add 1 retransmission for intermediate hops when using NextHopRouter
* Add next_hop and relayed_by in PacketHistory for setting next-hop and handle flooding fallback
* Update protos, store multiple relayers
* Remove next-hop update logic from NeighborInfoModule
* Fix retransmissions
* Improve ACKs for repeated packets and responses
* Stop retransmission even if there's not relay node
* Revert perhapsRebroadcast()
* Remove relayer if we cancel a transmission
* Better checking for fallback to flooding
* Fix newlines in traceroute print logs
* Stop retransmission for original packet
* Use relayID
* Also when want_ack is set, we should try to retransmit
* Fix cppcheck error
* Fix 'router' not in scope error
* Fix another cppcheck error
* Check for hop_limit and also update next hop when `hop_start == hop_limit` on ACK
Also check for broadcast in `getNextHop()`
* Formatting and correct NUM_RETRANSMISSIONS
* Update protos
* Start retransmissions in NextHopRouter if ReliableRouter didn't do it
* Handle repeated/fallback to flooding packets properly
First check if it's not still in the TxQueue
* Guard against clients setting `next_hop`/`relay_node`
* Don't cancel relay if we were the assigned next-hop
* Replies (e.g. tapback emoji) are also a valid confirmation of receipt
---------
Co-authored-by: GUVWAF <thijs@havinga.eu>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
* fix "native" compiler errors/warnings NodeDB.h
* fancy T-Deck / SenseCAP Indicator / unPhone / PICOmputer-S3 TFT screen (#3259)
* lib update: light theme
* fix merge issue
* lib update: home buttons + button try-fix
* lib update: icon color fix
* lib update: fix instability/crash on notification
* update lib: timezone
* timezone label
* lib update: fix set owner
* fix spiLock in RadioLibInterface
* add picomputer tft build
* picomputer build
* fix compiler error std::find()
* fix merge
* lib update: theme runtime config
* lib update: packet logger + T-Deck Plus
* lib update: mesh detector
* lib update: fix brightness & trackball crash
* try-fix less paranoia
* sensecap indicator updates
* lib update: indicator fix
* lib update: statistic & some fixes
* lib-update: other T-Deck touch driver
* use custom touch driver for Indicator
* lower tft task prio
* prepare LVGL ST7789 driver
* lib update: try-fix audio
* Drop received packets from self
* Additional decoded packet ignores
* Honor flip & color for Heltec T114 and T190 (#4786)
* Honor TFT_MESH color if defined for Heltec T114 or T190
* Temporary: point lib_deps at fork of Heltec's ST7789 library
For demo only, until ST7789 is merged
* Update lib_deps; tidy preprocessor logic
* Download debian files after firmware zip
* set title for protobufs bump PR (#4792)
* set title for version bump PR (#4791)
* Enable Dependabot
* chore: trunk fmt
* fix dependabot syntax (#4795)
* fix dependabot syntax
* Update dependabot.yml
* Update dependabot.yml
* Bump peter-evans/create-pull-request from 6 to 7 in /.github/workflows (#4797)
* Bump docker/build-push-action from 5 to 6 in /.github/workflows (#4800)
* Actions: Semgrep Images have moved from returntocorp to semgrep (#4774)
https://hub.docker.com/r/returntocorp/semgrep notes: "We've moved!
Official Docker images for Semgrep now available at semgrep/semgrep."
Patch updates our CI workflow for these images.
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* Bump meshtestic from `31ee3d9` to `37245b3` (#4799)
Bumps [meshtestic](https://github.com/meshtastic/meshTestic) from `31ee3d9` to `37245b3`.
- [Commits](https://github.com/meshtastic/meshTestic/compare/31ee3d90c8bef61e835c3271be2c7cda8c4a5cc2...37245b3d612a9272f546bbb092837bafdad46bc2)
---
updated-dependencies:
- dependency-name: meshtestic
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* [create-pull-request] automated change (#4789)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Bump pnpm/action-setup from 2 to 4 in /.github/workflows (#4798)
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 2 to 4.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v2...v4)
---
updated-dependencies:
- dependency-name: pnpm/action-setup
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Raspberry Pico2 - needs protos
* Re-order doDeepSleep (#4802)
Make sure PMU sleep takes place before I2C ends
* [create-pull-request] automated change
* heltec-wireless-bridge
requires Proto PR first
* feat: trigger class update when protobufs are changed
* meshtastic/ is a test suite; protobufs/ contains protobufs;
* Update platform-native to pick up portduino crash fix (#4807)
* Hopefully extract and commit to meshtastic.github.io
* CI fixes
* [Board] DIY "t-energy-s3_e22" (#4782)
* New variant "t-energy-s3_e22"
- Lilygo T-Energy-S3
- NanoVHF "Mesh-v1.06-TTGO-T18" board
- Ebyte E22 Series
* add board_level = extra
* Update variant.h
---------
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
* Consolidate variant build steps (#4806)
* poc: consolidate variant build steps
* use build-variant action
* only checkout once and clean up after run
* Revert "Consolidate variant build steps (#4806)" (#4816)
This reverts commit 9f8d86cb25febfb86c57f395549b7deb82458065.
* Make Ublox code more readable (#4727)
* Simplify Ublox code
Ublox comes in a myriad of versions and settings. Presently our
configuration code does a lot of branching based on versions being
or not being present.
This patch adds version detection earlier in the piece and branches
on the set gnssModel instead to create separate setup methods for Ublox 6,
Ublox 7/8/9, and Ublox10.
Additionally, adds a macro to make the code much shorter and more
readable.
* Make trunk happy
* Make trunk happy
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* Consider the LoRa header when checking packet length
* Minor fix (#4666)
* Minor fixes
It turns out setting a map value with the index notation causes
an lookup that can be avoided with emplace. Apply this to one line in
the StoreForward module.
Fix also Cppcheck-determined highly minor performance increase by
passing gpiochipname as a const reference :)
The amount of cycles used on this laptop while learning about these
callouts from cppcheck is unlikely to ever be more than the cycles
saved by the fixes ;)
* Update PortduinoGlue.cpp
* Revert "Update classes on protobufs update" (#4824)
* Revert "Update classes on protobufs update"
* remove quotes to fix trunk.
---------
Co-authored-by: Tom Fifield <tom@tomfifield.net>
* Implement optional second I2C bus for NRF52840
Enabled at compile-time if WIRE_INFERFACES_COUNT defined as 2
* Add I2C bus to Heltec T114 header pins
SDA: P0.13
SCL: P0.16
Uses bus 1, leaving bus 0 routed to the unpopulated footprint for the RTC (general future-proofing)
* Tidier macros
* Swap SDA and SCL
SDA=P0.16, SCL=P0.13
* Refactor and consolidate time window logic (#4826)
* Refactor and consolidate windowing logic
* Trunk
* Fixes
* More
* Fix braces and remove unused now variables.
There was a brace in src/mesh/RadioLibInterface.cpp that was breaking
compile on some architectures.
Additionally, there were some brace errors in
src/modules/Telemetry/AirQualityTelemetry.cpp
src/modules/Telemetry/EnvironmentTelemetry.cpp
src/mesh/wifi/WiFiAPClient.cpp
Move throttle include in WifiAPClient.cpp to top.
Add Default.h to sleep.cpp
rest of files just remove unused now variables.
* Remove a couple more meows
---------
Co-authored-by: Tom Fifield <tom@tomfifield.net>
* Rename message length headers and set payload max to 255 (#4827)
* Rename message length headers and set payload max to 255
* Add MESHTASTIC_PKC_OVERHEAD
* compare to MESHTASTIC_HEADER_LENGTH
---------
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
* Check for null before printing debug (#4835)
* fix merge
* try-fix crash
* lib update: fix neighbors
* fix GPIO0 mode after I2S audio
* lib update: audio fix
* lib update: fixes and improvements
* extra
* added ILI9342 (from master)
* device-ui persistency
* review update
* fix request, add handled
* fix merge issue
* fix merge issue
* remove newline
* remove newlines from debug log
* playing with locks; but needs more testing
* diy mesh-tab initial files
* board definition for mesh-tab (not yet used)
* use DISPLAY_SET_RESOLUTION to avoid hw dependency in code
* no telemetry for Indicator
* 16MB partition for Indicator
* 8MB partition for Indicator
* stability: add SPI lock before saving via littleFS
* dummy for config transfer (#5154)
* update indicator (due to compile and linker errors)
* remove faulty partition line
* fix missing include
* update indicator board
* update mesh-tab ILI9143 TFT
* fix naming
* mesh-tab targets
* try: disable duplicate locks
* fix nodeDB erase loop when free mem returns invalid value (0, -1).
* upgrade toolchain for nrf52 to gcc 9.3.1
* try-fix (workaround) T-Deck audio crash
* update mesh-tab tft configs
* set T-Deck audio to unused 48 (mem mclk)
* swap mclk to gpio 21
* update meshtab voltage divider
* update mesh-tab ini
* Fixed the issue that indicator device uploads via rp2040 serial port in some cases.
* Fixed the issue that the touch I2C address definition was not effective.
* Fixed the issue that the wifi configuration saved to RAM did not take effect.
* rotation fix; added ST7789 3.2" display
* dreamcatcher: assign GPIO44 to audio mclk
* mesh-tab touch updates
* add mesh-tab powersave as default
* fix DIO1 wakeup
* mesh-tab: enable alert message menu
* Streamline board definitions for first tech preview. (#5390)
* Streamline board definitions for first tech preview. TBD: Indicator Support
* add point-of-checkin
* use board/unphone.json
---------
Co-authored-by: mverch67 <manuel.verch@gmx.de>
* fix native targets
* add RadioLib debugging options for (T-Deck)
* fix T-Deck build
* fix native tft targets for rpi
* remove wrong debug defines
* t-deck-tft button is handled in device-ui
* disable default lightsleep for indicator
* Windows Support - Trunk and Platformio (#5397)
* Add support for GPG
* Add usb device support
* Add trunk.io to devcontainer
* Trunk things
* trunk fmt
* formatting
* fix trivy/DS002, checkov/CKV_DOCKER_3
* hide docker extension popup
* fix trivy/DS026, checkov/CKV_DOCKER_2
* fix radioLib warnings for T-Deck target
* wake screen with button only
* use custom touch driver
* define wake button for unphone
* use board definition for mesh-tab
* mesh-tab rotation upside-down
* update platform native
* use MESH_TAB hardware model definition
* radioLib update (fix crash/assert)
* reference seeed indicator fix commit arduino-esp32
* Remove unneeded file change :)
* disable serial module and tcp socket api for standalone devices (#5591)
* disable serial module and tcp socket api for standalone devices
* just disable webserver, leave wifi available
* disable socket api
* mesh-tab: lower I2C touch frequency
* log error when packet queue is full
* add more locking for shared SPI devices (#5595)
* add more locking for shared SPI devices
* call initSPI before the lock is used
* remove old one
* don't double lock
* Add missing unlock
* More missing unlocks
* Add locks to SafeFile, remove from `readcb`, introduce some LockGuards
* fix lock in setupSDCard()
* pull radiolib trunk with SPI-CS fixes
* change ContentHandler to Constructor type locks, where applicable
---------
Co-authored-by: mverch67 <manuel.verch@gmx.de>
Co-authored-by: GUVWAF <thijs@havinga.eu>
Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com>
* T-Deck: revert back to lovyanGFX touch driver
* T-Deck: increase allocated PSRAM by 50%
* mesh-tab: streamline target definitions
* update RadioLib 7.1.2
* mesh-tab: fix touch rotation 4.0 inch display
* Mesh-Tab platformio: 4.0inch: increase SPI frequency to max
* mesh-tab: fix rotation for 3.5 IPS capacitive display
* mesh-tab: fix rotation for 3.2 IPS capacitive display
* restructure device-ui library into sub-directories
* preparations for generic DisplayDriverFactory
* T-Deck: increase LVGL memory size
* update lib
* trunk fmt
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
Co-authored-by: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com>
Co-authored-by: Jason Murray <jason@chaosaffe.io>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
Co-authored-by: Austin <vidplace7@gmail.com>
Co-authored-by: virgil <virgil.wang.cj@gmail.com>
Co-authored-by: Mark Trevor Birss <markbirss@gmail.com>
Co-authored-by: Kalle Lilja <15094562+ThatKalle@users.noreply.github.com>
Co-authored-by: GUVWAF <thijs@havinga.eu>
* Version this
* Update platformio.ini (#6006)
* tested higher speed and it works
* Un-extra
* Add -tft environments to the ci matrix
* Exclude unphone tft for now. Something is wonky
* fixed Indicator touch issue (causing IO expander issues), added more RAM
* update lib
* fixed Indicator touch issue (causing IO expander issues), added more RAM (#6013)
* increase T-Deck PSRAM to avoid too early out-of-memory when messages fill up the storage
* update device-ui lib
* Fix T-Deck SD card detection (#6023)
* increase T-Deck PSRAM to avoid too early out-of-memory when messages fill up the storage
* fix SDCard for T-Deck; allow SPI frequency config
* meshtasticd: Add X11 480x480 preset (#6020)
* Littlefs per device
* 2.6 update
* [create-pull-request] automated change (#6037)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* InkHUD UI for E-Ink (#6034)
* Decouple ButtonThread from sleep.cpp
Reorganize sleep observables. Don't call ButtonThread methods inside doLightSleep. Instead, handle in class with new lightsleep Observables.
* InkHUD: initial commit (WIP)
Publicly discloses the current work in progress. Not ready for use.
* feat: battery icon
* chore: implement meshtastic/firmware #5454
Clean up some inline functions
* feat: menu & settings for "jump to applet"
* Remove the beforeRender pattern
It hugely complicates things. If we can achieve acceptable performance without it, so much the better.
* Remove previous Map Applet
Needs re-implementation to work without the beforeRender pattern
* refactor: reimplement map applet
Doesn't require own position
Doesn't require the beforeRender pattern to precalculate; now all-at-once in render
Lays groundwork for fixed-size map with custom background image
* feat: autoshow
Allow user to select which applets (if any) should be automatically brought to foreground when they have new data to display
* refactor: tidy-up applet constructors
misc. jobs including:
- consistent naming
- move initializer-list-only constructors to header
- give derived applets unique identifiers for MeshModule and OSThread logging
* hotfix: autoshow always uses FAST update
In future, it *will* often use FAST, but this will be controlled by a WindowManager component which has not yet been written.
Hotfixed, in case anybody is attempting to use this development version on their deployed devices.
* refactor: bringToForeground no longer requests FAST update
In situations where an applet has moved to foreground because of user input, requestUpdate can be manually called, to upgrade to FAST refresh.
More permanent solution for #23e1dfc
* refactor: extract string storage from ThreadedMessageApplet
Separates the code responsible for storing the limited message history, which was previously part of the ThreadedMessageApplet.
We're now also using this code to store the "most recent message". Previously, this was stored in the `InkHUD::settings` struct, which was much less space-efficient.
We're also now storing the latest DM, laying the foundation for an applet to display only DMs, which will complement the threaded message applet.
* fix: text wrapping
Attempts to fix a disparity between `Applet::printWrapped` and `Applet::getWrappedTextHeight`, which would occasionally cause a ThreadedMessageApplet message to render "too short", overlapping other text.
* fix: purge old constructor
This one slipped through the last commit..
* feat: DM Applet
Useful in combination with the ThreadedMessageApplets, which don't show DMs
* fix: applets shouldn't handle events while deactivated
Only one or two applets were actually doing this, but I'm making a habit of having all applets return early from their event handling methods (as good practice), even if those methods are disabled elsewhere (e.g. not observing observable, return false from wantPacket)
* refactor: allow requesting update without requesting autoshow
Some applets may want to redraw, if they are displayed, but not feel the information is worth being brought to foreground for. Example: ActiveNodesApplet, when purging old nodes from list.
* feat: custom "Recently Active" duration
Allows users to tailor how long nodes will appear in the "Recents" applets, to suit the activity level of their mesh.
* refactor: rename some applets
* fix: autoshow
* fix: getWrappedTextHeight
Remove the "simulate" option from printWrapped; too hard to keep inline with genuine printing (because of AdafruitGFX Fonts' xAdvance, mabye?). Instead of simulating, we printWrapped as normal, and discard pixel output by setting crop. Both methods are similarly inefficient, apparently.
* fix: text wrapping in ThreadedMessageApplet
Wrong arguments were passed to Applet::printWrapped
* feat: notifications for text messages
Only shown if current applet does not already display the same info. Autoshow takes priority over notifications, if both would be used to display the same info.
* feat: optimize FAST vs FULL updates
New UpdateMediator class counts the number of each update type, and suggets which one to use, if the code doesn't already have an explicit prefence. Also performs "maintenance refreshes" unprovoked if display is not given an opportunity to before a FULL refresh through organic use.
* chore: update todo list
* fix: rare lock-up of buttons
* refactor: backlight
Replaces the initial proof-of-concept frontlight code for T-Echo
Presses less than 5 seconds momentarily illuminate the display
Presses longer than 5 seconds latch the light, requiring another tap to disable
If user has previously removed the T-Echo's capacitive touch button (some DIY projects), the light is controlled by the on-screen menu. This fallback is used by all T-Echo devices, until a press of the capacitive touch button is detected.
* feat: change tile with aux button
Applied to VM-E290.
Working as is, but a refactor of WindowManager::render is expected shortly, which will also tidy code from this push.
* fix: specify out-of-the-box tile assignments
Prevents placeholder applet showing on initial boot, for devices which use a mult-tile layout by default (VM-E290)
* fix: verify settings version when loading
* fix: wrong settings version
* refactor: remove unimplemented argument from requestUpdate
Specified whether or not to update "async", however the implementation was slightly broken, Applet::requestUpdate is only handled next time WindowManager::runOnce is called. This didn't allow code to actually await an update, which was misleading.
* refactor: renaming
Applet::render becomes Applet::onRender.
Tile::displayedApplet becomes Tile::assignedApplet.
New onRender method name allows us to move some of the pre and post render code from WindowManager into new Applet::render method, which will call onRender for us.
* refactor: rendering
Bit of a tidy-up. No intended change in behavior.
* fix: optimize refresh times
Shorter wait between retrying update if display was previously busy.
Set anticipated update durations closer to observed values. No signifacant performance increase, but does decrease the amount of polling required.
* feat: blocking update for E-Ink
Option to wait for display update to complete before proceeding. Important when shutting down the device.
* refactor: allow system applets to lock rendering
Temporarily prevents other applets from rendering.
* feat: boot and shutdown screens
* feat: BluetoothStatus
Adds a meshtastic::Status object which exposes the state of the Bluetooth connection. Intends to allow decoupling of UI code.
* feat: Bluetooth pairing screen
* fix: InkHUD defaults not honored
* fix: random Bluetooth pin for NicheGraphics UIs
* chore: button interrupts tested
* fix: emoji reactions show as blank messages
* fix: autoshow and notification triggered by outgoing message
* feat: save InkHUD data before reboot
Implemented with a new Observable. Previously, config and a few recent messages were saved on shutdown. These were lost if the device rebooted, for example when firmware settings were changed by a client. Now, the InkHUD config and recent messages saved on reboot, the same as during an intentional shutdown.
* feat: imperial distances
Controlled by the config.display.units setting
* fix: hide features which are not yet implemented
* refactor: faster rendering
Previously, only tiles which requested update were re-rendered. Affected tiles had their region blanked before render, pixel by pixel. Benchmarking revealed that it is significantly faster to memset the framebuffer and redraw all tiles.
* refactor: tile ownership
Tiles and Applets now maintain a reciprocal link, which is enforced by asserts. Less confusing than the old situation, where an applet and a tile may disagree on their relationship. Empty tiles are now identified by a nullptr *Applet, instead of by having the placeholderApplet assigned.
* fix: notifications and battery when menu open
Do render notifications in front of menu; don't render battery icon in front of menu.
* fix: simpler defaults
Don't expose new users to multiplexed applets straight away: make them enable the feature for themselves.
* fix: Inputs::TwoButton interrupts, when only one button in use
* fix: ensure display update is complete when ESP32 enters light sleep
Many panels power down automatically, but some require active intervention from us. If light sleep (ESP32) occurs during a display update, these panels could potentially remain powered on, applying voltage the pixels for an extended period of time, and potentially damaging the display.
* fix: honor per-variant user tile limit
Set as the default value for InkHUD::settings.userTiles.maxCount in nicheGraphics.h
* feat: initial InkHUD support for Wireless Paper v1.1 and VM-E213
* refactor: Heard and Recents Applets
Tidier code, significant speed boost. Possibly no noticable change in responsiveness, but rendering now spends much less time blocking execution, which is important for correction functioning of the other firmware components.
* refactor: use a common pio base config
Easier to make any future PlatformIO config changes
* feat: tips
Show information that we think the user might find helpful. Some info shown first boot only. Other info shown when / if relevant.
* fix: text wrapping for '\n'
Previously, the newline was honored, but the adojining word was not printed.
* Decouple ButtonThread from sleep.cpp
Reorganize sleep observables. Don't call ButtonThread methods inside doLightSleep. Instead, handle in class with new lightsleep Observables.
* feat: BluetoothStatus
Adds a meshtastic::Status object which exposes the state of the Bluetooth connection. Intends to allow decoupling of UI code.
* feat: observable for reboot
* refactor: Heltec VM-E290 installDefaultConfig
* fix: random Bluetooth pin for NicheGraphics UIs
* update device-ui: fix touch/crash issue while light sleep
* Collect inkhud
* fix: InkHUD shouldn't nag about timezone (#6040)
* Guard eink drivers w/ MESHTASTIC_INCLUDE_NICHE_GRAPHICS
* Case sensitive perhaps?
* More case-sensitivity instances
* Moar
* RTC
* Yet another case issue!
* Sigh...
* MUI: BT programming mode (#6046)
* allow BT connection with disabled MUI
* Update device-ui
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* MUI: fix nag timeout, disable BT programming mode for native (#6052)
* allow BT connection with disabled MUI
* Update device-ui
* MUI: fix nag timeout default and remove programming mode for native
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* remove debuglog leftover
* Wireless Paper: remove stray board_level = extra (#6060)
Makes sure the InkHUD version gets build into the release zip
* Fixed persistence stragglers from NodeDB / Device State divorce (#6059)
* Increase `MAX_THREADS` for InkHUD variants with WiFi (#6064)
* Licensed usage compliance (#6047)
* Prevent psk and legacy admin channel on licensed mode
* Move it
* Consolidate warning strings
* More holes
* Device UI submodule bump
* Prevent licensed users from rebroadcasting unlicensed traffic (#6068)
* Prevent licensed users from rebroadcasting unlicensed traffic
* Added method and enum to make user license status more clear
* MUI: move UI initialization out of main.cpp and adding lightsleep observer + mutex (#6078)
* added device-ui to lightSleep observers for handling graceful sleep; refactoring main.cpp
* bump lib version
* Update device-ui
* unPhone TFT: include into build, enable SD card, increase PSRAM (#6082)
* unPhone-tft: include into build, enable SD card, increase assigned PSRAM
* lib update
* Backup / migrate pub private keys when upgrading to new files in 2.6 (#6096)
* Save a backup of pub/private keys before factory reset
* Fix licensed mode warning
* Unlock spi on else file doesn't exist
* Update device-ui
* Update protos and device-ui
* [create-pull-request] automated change (#6129)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Proto
* [create-pull-request] automated change (#6131)
* Proto update for backup
* [create-pull-request] automated change (#6133)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Update protobufs
* Space
* [create-pull-request] automated change (#6144)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Protos
* [create-pull-request] automated change (#6152)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
* Updeet
* device-ui lib update
* fix channel OK button
* device-lib update: fix settings panel -> no scrolling
* device-ui lib: last minute update
* defined(SENSECAP_INDICATOR)
* MUI hot-fix pub/priv keys
* MUI hot-fix username dialog
* MUI: BT programming mode button
* Update protobufs
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
Co-authored-by: GUVWAF <thijs@havinga.eu>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
Co-authored-by: mverch67 <manuel.verch@gmx.de>
Co-authored-by: Manuel <71137295+mverch67@users.noreply.github.com>
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
Co-authored-by: Jason Murray <15822260+scruplelesswizard@users.noreply.github.com>
Co-authored-by: Jason Murray <jason@chaosaffe.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
Co-authored-by: Austin <vidplace7@gmail.com>
Co-authored-by: virgil <virgil.wang.cj@gmail.com>
Co-authored-by: Mark Trevor Birss <markbirss@gmail.com>
Co-authored-by: Kalle Lilja <15094562+ThatKalle@users.noreply.github.com>
Co-authored-by: rcarteraz <robert.l.carter2@gmail.com>
2025-03-01 06:18:33 -06:00
|
|
|
if (iface && iface->cancelSending(from, id)) {
|
|
|
|
|
// We are not a relayer of this packet anymore
|
|
|
|
|
removeRelayer(nodeDB->getLastByteOfNodeNum(nodeDB->getNodeNum()), id, from);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Attempt to find a packet in the TxQueue. Returns true if the packet was found. */
|
|
|
|
|
bool Router::findInTxQueue(NodeNum from, PacketId id)
|
|
|
|
|
{
|
|
|
|
|
return iface->findInTxQueue(from, id);
|
2021-02-11 17:39:53 +08:00
|
|
|
}
|
|
|
|
|
|
2020-05-18 17:57:58 -07:00
|
|
|
/**
|
|
|
|
|
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
|
|
|
|
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
|
|
|
|
*/
|
2023-01-21 18:22:19 +01:00
|
|
|
void Router::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
2020-05-18 17:57:58 -07:00
|
|
|
{
|
2020-06-14 15:30:42 -07:00
|
|
|
// FIXME, update nodedb here for any packet that passes through us
|
2020-05-18 17:57:58 -07:00
|
|
|
}
|
|
|
|
|
|
2025-03-16 08:19:17 -05:00
|
|
|
DecodeState perhapsDecode(meshtastic_MeshPacket *p)
|
2020-04-17 09:48:54 -07:00
|
|
|
{
|
2023-04-07 15:05:19 +02:00
|
|
|
concurrency::LockGuard g(cryptLock);
|
|
|
|
|
|
2023-12-06 14:02:41 -06:00
|
|
|
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY &&
|
2024-03-21 09:06:37 -05:00
|
|
|
(nodeDB->getMeshNode(p->from) == NULL || !nodeDB->getMeshNode(p->from)->has_user)) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Node 0x%x not in nodeDB-> Rebroadcast mode KNOWN_ONLY will ignore packet", p->from);
|
2025-03-16 08:19:17 -05:00
|
|
|
return DecodeState::DECODE_FAILURE;
|
2023-12-06 14:02:41 -06:00
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)
|
2025-03-16 08:19:17 -05:00
|
|
|
return DecodeState::DECODE_SUCCESS; // If packet was already decoded just return
|
2020-04-17 09:48:54 -07:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
size_t rawSize = p->encrypted.size;
|
|
|
|
|
if (rawSize > sizeof(bytes)) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_ERROR("Packet too large to attempt decryption! (rawSize=%d > 256)", rawSize);
|
2025-03-16 08:19:17 -05:00
|
|
|
return DecodeState::DECODE_FATAL;
|
2024-08-10 13:45:41 -05:00
|
|
|
}
|
|
|
|
|
bool decrypted = false;
|
|
|
|
|
ChannelIndex chIndex = 0;
|
|
|
|
|
#if !(MESHTASTIC_EXCLUDE_PKI)
|
|
|
|
|
// Attempt PKI decryption first
|
2024-10-19 12:48:00 -05:00
|
|
|
if (p->channel == 0 && isToUs(p) && p->to > 0 && !isBroadcast(p->to) && nodeDB->getMeshNode(p->from) != nullptr &&
|
2024-10-04 13:28:51 +02:00
|
|
|
nodeDB->getMeshNode(p->from)->user.public_key.size > 0 && nodeDB->getMeshNode(p->to)->user.public_key.size > 0 &&
|
|
|
|
|
rawSize > MESHTASTIC_PKC_OVERHEAD) {
|
2024-11-04 12:16:25 -06:00
|
|
|
LOG_DEBUG("Attempt PKI decryption");
|
2024-08-10 13:45:41 -05:00
|
|
|
|
2024-12-19 17:14:27 -08:00
|
|
|
if (crypto->decryptCurve25519(p->from, nodeDB->getMeshNode(p->from)->user.public_key, p->id, rawSize, p->encrypted.bytes,
|
2024-10-10 05:14:11 -05:00
|
|
|
bytes)) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_INFO("PKI Decryption worked!");
|
2025-03-16 08:19:17 -05:00
|
|
|
|
|
|
|
|
meshtastic_Data decodedtmp;
|
|
|
|
|
memset(&decodedtmp, 0, sizeof(decodedtmp));
|
2024-09-23 09:20:32 -05:00
|
|
|
rawSize -= MESHTASTIC_PKC_OVERHEAD;
|
2025-03-16 08:19:17 -05:00
|
|
|
if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &decodedtmp) &&
|
|
|
|
|
decodedtmp.portnum != meshtastic_PortNum_UNKNOWN_APP) {
|
2024-08-10 13:45:41 -05:00
|
|
|
decrypted = true;
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_INFO("Packet decrypted using PKI!");
|
2024-08-10 13:45:41 -05:00
|
|
|
p->pki_encrypted = true;
|
|
|
|
|
memcpy(&p->public_key.bytes, nodeDB->getMeshNode(p->from)->user.public_key.bytes, 32);
|
|
|
|
|
p->public_key.size = 32;
|
2025-03-17 19:24:47 -05:00
|
|
|
p->decoded = decodedtmp;
|
2025-03-16 08:19:17 -05:00
|
|
|
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
|
2024-08-10 13:45:41 -05:00
|
|
|
} else {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_ERROR("PKC Decrypted, but pb_decode failed!");
|
2025-03-16 08:19:17 -05:00
|
|
|
return DecodeState::DECODE_FAILURE;
|
2024-05-19 07:24:10 -05:00
|
|
|
}
|
2024-09-17 06:31:39 -05:00
|
|
|
} else {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_WARN("PKC decrypt attempted but failed!");
|
2024-08-10 13:45:41 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2021-02-23 10:45:03 +08:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
// assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
|
|
|
|
|
if (!decrypted) {
|
|
|
|
|
// Try to find a channel that works with this hash
|
|
|
|
|
for (chIndex = 0; chIndex < channels.getNumChannels(); chIndex++) {
|
|
|
|
|
// Try to use this hash/channel pair
|
|
|
|
|
if (channels.decryptForHash(chIndex, p->channel)) {
|
2024-12-19 17:14:27 -08:00
|
|
|
// we have to copy into a scratch buffer, because these bytes are a union with the decoded protobuf. Create a
|
|
|
|
|
// fresh copy for each decrypt attempt.
|
|
|
|
|
memcpy(bytes, p->encrypted.bytes, rawSize);
|
2024-08-10 13:45:41 -05:00
|
|
|
// Try to decrypt the packet if we can
|
|
|
|
|
crypto->decrypt(p->from, p->id, rawSize, bytes);
|
|
|
|
|
|
|
|
|
|
// printBytes("plaintext", bytes, p->encrypted.size);
|
|
|
|
|
|
|
|
|
|
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
2025-03-16 08:19:17 -05:00
|
|
|
meshtastic_Data decodedtmp;
|
|
|
|
|
memset(&decodedtmp, 0, sizeof(decodedtmp));
|
|
|
|
|
if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &decodedtmp)) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!", p->id);
|
2025-03-16 08:19:17 -05:00
|
|
|
} else if (decodedtmp.portnum == meshtastic_PortNum_UNKNOWN_APP) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_ERROR("Invalid portnum (bad psk?)!");
|
2025-11-06 06:28:13 -06:00
|
|
|
#if !(MESHTASTIC_EXCLUDE_PKI)
|
|
|
|
|
} else if (!owner.is_licensed && isToUs(p) && decodedtmp.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
|
|
|
|
LOG_WARN("Rejecting legacy DM");
|
|
|
|
|
return DecodeState::DECODE_FAILURE;
|
|
|
|
|
#endif
|
2024-08-10 13:45:41 -05:00
|
|
|
} else {
|
2025-03-16 08:19:17 -05:00
|
|
|
p->decoded = decodedtmp;
|
|
|
|
|
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
|
2024-08-10 13:45:41 -05:00
|
|
|
decrypted = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-16 02:29:47 +02:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
if (decrypted) {
|
|
|
|
|
// parsing was successful
|
2025-03-16 08:19:17 -05:00
|
|
|
p->channel = chIndex; // change to store the index instead of the hash
|
2024-09-07 18:21:59 -05:00
|
|
|
if (p->decoded.has_bitfield)
|
|
|
|
|
p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK;
|
2022-04-13 19:23:35 -07:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
/* Not actually ever used.
|
|
|
|
|
// Decompress if needed. jm
|
|
|
|
|
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
|
|
|
|
// Decompress the payload
|
|
|
|
|
char compressed_in[meshtastic_Constants_DATA_PAYLOAD_LEN] = {};
|
|
|
|
|
char decompressed_out[meshtastic_Constants_DATA_PAYLOAD_LEN] = {};
|
|
|
|
|
int decompressed_len;
|
2022-04-13 19:23:35 -07:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
memcpy(compressed_in, p->decoded.payload.bytes, p->decoded.payload.size);
|
2022-04-25 08:02:51 -07:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
decompressed_len = unishox2_decompress_simple(compressed_in, p->decoded.payload.size, decompressed_out);
|
2022-04-25 08:02:51 -07:00
|
|
|
|
2024-10-14 06:11:43 +02:00
|
|
|
// LOG_DEBUG("**Decompressed length - %d ", decompressed_len);
|
2022-04-25 08:02:51 -07:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
memcpy(p->decoded.payload.bytes, decompressed_out, decompressed_len);
|
2022-05-24 17:42:46 -07:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
// Switch the port from PortNum_TEXT_MESSAGE_COMPRESSED_APP to PortNum_TEXT_MESSAGE_APP
|
|
|
|
|
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
|
|
|
|
} */
|
2022-04-13 19:23:35 -07:00
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
printPacket("decoded message", p);
|
2024-07-28 19:49:10 -05:00
|
|
|
#if ENABLE_JSON_LOGGING
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
|
2024-07-28 19:49:10 -05:00
|
|
|
#elif ARCH_PORTDUINO
|
2025-09-03 17:50:26 -05:00
|
|
|
if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
|
2021-02-22 12:57:26 +08:00
|
|
|
}
|
2024-08-10 13:45:41 -05:00
|
|
|
#endif
|
2025-03-16 08:19:17 -05:00
|
|
|
return DecodeState::DECODE_SUCCESS;
|
2024-08-10 13:45:41 -05:00
|
|
|
} else {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_WARN("No suitable channel found for decoding, hash was 0x%x!", p->channel);
|
2025-03-16 08:19:17 -05:00
|
|
|
return DecodeState::DECODE_FAILURE;
|
2020-05-19 11:56:17 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-02 20:25:05 -05:00
|
|
|
/** Return 0 for success or a Routing_Error code for failure
|
2021-04-05 09:24:00 +08:00
|
|
|
*/
|
2023-01-21 18:22:19 +01:00
|
|
|
meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
|
2021-04-05 09:24:00 +08:00
|
|
|
{
|
2023-04-07 15:05:19 +02:00
|
|
|
concurrency::LockGuard g(cryptLock);
|
|
|
|
|
|
2024-08-13 17:16:40 -05:00
|
|
|
int16_t hash;
|
|
|
|
|
|
2021-04-05 09:24:00 +08:00
|
|
|
// If the packet is not yet encrypted, do so now
|
2023-01-28 06:39:14 -06:00
|
|
|
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
2024-10-04 13:28:51 +02:00
|
|
|
if (isFromUs(p)) {
|
2024-09-07 18:21:59 -05:00
|
|
|
p->decoded.has_bitfield = true;
|
|
|
|
|
p->decoded.bitfield |= (config.lora.config_ok_to_mqtt << BITFIELD_OK_TO_MQTT_SHIFT);
|
|
|
|
|
p->decoded.bitfield |= (p->decoded.want_response << BITFIELD_WANT_RESPONSE_SHIFT);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 07:02:06 -05:00
|
|
|
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
|
|
|
|
|
|
2024-04-12 14:06:05 -05:00
|
|
|
/* Not actually used, so save the cycles
|
2022-04-13 19:23:35 -07:00
|
|
|
// TODO: Allow modules to opt into compression.
|
2023-01-28 06:39:14 -06:00
|
|
|
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
2022-04-11 22:12:04 -07:00
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
char original_payload[meshtastic_Constants_DATA_PAYLOAD_LEN];
|
2022-04-11 22:12:04 -07:00
|
|
|
memcpy(original_payload, p->decoded.payload.bytes, p->decoded.payload.size);
|
|
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
char compressed_out[meshtastic_Constants_DATA_PAYLOAD_LEN] = {0};
|
2022-04-11 20:09:48 -07:00
|
|
|
|
2022-04-18 17:00:36 -07:00
|
|
|
int compressed_len;
|
2022-04-25 08:02:51 -07:00
|
|
|
compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out);
|
2022-04-11 22:12:04 -07:00
|
|
|
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Original length - %d ", p->decoded.payload.size);
|
|
|
|
|
LOG_DEBUG("Compressed length - %d ", compressed_len);
|
|
|
|
|
LOG_DEBUG("Original message - %s ", p->decoded.payload.bytes);
|
2022-04-13 19:23:35 -07:00
|
|
|
|
|
|
|
|
// If the compressed length is greater than or equal to the original size, don't use the compressed form
|
2023-01-28 06:39:14 -06:00
|
|
|
if (compressed_len >= p->decoded.payload.size) {
|
2023-09-26 07:02:06 -05:00
|
|
|
|
2024-11-04 20:09:23 +08:00
|
|
|
LOG_DEBUG("Not using compressing message");
|
2023-09-26 07:02:06 -05:00
|
|
|
// Set the uncompressed payload variant anyway. Shouldn't hurt?
|
|
|
|
|
// p->decoded.which_payloadVariant = Data_payload_tag;
|
|
|
|
|
|
2022-04-13 19:23:35 -07:00
|
|
|
// Otherwise we use the compressor
|
2023-01-28 06:39:14 -06:00
|
|
|
} else {
|
2024-11-04 12:16:25 -06:00
|
|
|
LOG_DEBUG("Use compressed message");
|
2022-04-13 19:23:35 -07:00
|
|
|
// Copy the compressed data into the meshpacket
|
|
|
|
|
|
2022-05-24 17:42:46 -07:00
|
|
|
p->decoded.payload.size = compressed_len;
|
|
|
|
|
memcpy(p->decoded.payload.bytes, compressed_out, compressed_len);
|
2022-04-13 19:23:35 -07:00
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP;
|
2022-04-13 19:23:35 -07:00
|
|
|
}
|
2024-04-12 14:06:05 -05:00
|
|
|
} */
|
2022-04-11 20:09:48 -07:00
|
|
|
|
2024-09-23 09:20:32 -05:00
|
|
|
if (numbytes + MESHTASTIC_HEADER_LENGTH > MAX_LORA_PAYLOAD_LEN)
|
2023-01-21 18:22:19 +01:00
|
|
|
return meshtastic_Routing_Error_TOO_LARGE;
|
2021-04-05 09:24:00 +08:00
|
|
|
|
|
|
|
|
// printBytes("plaintext", bytes, numbytes);
|
|
|
|
|
|
|
|
|
|
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
|
|
|
|
|
2024-08-10 13:45:41 -05:00
|
|
|
#if !(MESHTASTIC_EXCLUDE_PKI)
|
|
|
|
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to);
|
2024-09-15 09:26:43 -05:00
|
|
|
// We may want to retool things so we can send a PKC packet when the client specifies a key and nodenum, even if the node
|
|
|
|
|
// is not in the local nodedb
|
2024-11-06 22:00:26 +01:00
|
|
|
// First, only PKC encrypt packets we are originating
|
|
|
|
|
if (isFromUs(p) &&
|
2025-08-19 14:15:05 -05:00
|
|
|
#if ARCH_PORTDUINO
|
|
|
|
|
// Sim radio via the cli flag skips PKC
|
|
|
|
|
!portduino_config.force_simradio &&
|
|
|
|
|
#endif
|
2024-09-15 09:26:43 -05:00
|
|
|
// Don't use PKC with Ham mode
|
|
|
|
|
!owner.is_licensed &&
|
2025-08-24 10:13:18 -05:00
|
|
|
// Don't use PKC on 'serial' or 'gpio' channels unless explicitly requested
|
|
|
|
|
!(p->pki_encrypted != true && (strcasecmp(channels.getName(chIndex), Channels::serialChannel) == 0 ||
|
|
|
|
|
strcasecmp(channels.getName(chIndex), Channels::gpioChannel) == 0)) &&
|
2024-09-15 09:26:43 -05:00
|
|
|
// Check for valid keys and single node destination
|
2024-10-19 12:48:00 -05:00
|
|
|
config.security.private_key.size == 32 && !isBroadcast(p->to) && node != nullptr &&
|
2024-09-15 09:26:43 -05:00
|
|
|
// Check for a known public key for the destination
|
|
|
|
|
(node->user.public_key.size == 32) &&
|
|
|
|
|
// Some portnums either make no sense to send with PKC
|
|
|
|
|
p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP && p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP &&
|
|
|
|
|
p->decoded.portnum != meshtastic_PortNum_ROUTING_APP && p->decoded.portnum != meshtastic_PortNum_POSITION_APP) {
|
2024-11-04 12:16:25 -06:00
|
|
|
LOG_DEBUG("Use PKI!");
|
2024-09-23 09:20:32 -05:00
|
|
|
if (numbytes + MESHTASTIC_HEADER_LENGTH + MESHTASTIC_PKC_OVERHEAD > MAX_LORA_PAYLOAD_LEN)
|
2024-08-10 13:45:41 -05:00
|
|
|
return meshtastic_Routing_Error_TOO_LARGE;
|
2024-08-13 22:34:21 -05:00
|
|
|
if (p->pki_encrypted && !memfll(p->public_key.bytes, 0, 32) &&
|
|
|
|
|
memcmp(p->public_key.bytes, node->user.public_key.bytes, 32) != 0) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_WARN("Client public key differs from requested: 0x%02x, stored key begins 0x%02x", *p->public_key.bytes,
|
2024-10-01 15:38:36 -05:00
|
|
|
*node->user.public_key.bytes);
|
2024-08-13 17:16:40 -05:00
|
|
|
return meshtastic_Routing_Error_PKI_FAILED;
|
|
|
|
|
}
|
2024-12-19 17:14:27 -08:00
|
|
|
crypto->encryptCurve25519(p->to, getFrom(p), node->user.public_key, p->id, numbytes, bytes, p->encrypted.bytes);
|
2024-09-23 09:20:32 -05:00
|
|
|
numbytes += MESHTASTIC_PKC_OVERHEAD;
|
2024-08-10 13:45:41 -05:00
|
|
|
p->channel = 0;
|
2024-08-13 12:10:46 -05:00
|
|
|
p->pki_encrypted = true;
|
2024-08-10 13:45:41 -05:00
|
|
|
} else {
|
2024-08-13 12:10:46 -05:00
|
|
|
if (p->pki_encrypted == true) {
|
|
|
|
|
// Client specifically requested PKI encryption
|
|
|
|
|
return meshtastic_Routing_Error_PKI_FAILED;
|
|
|
|
|
}
|
2024-08-13 17:16:40 -05:00
|
|
|
hash = channels.setActiveByIndex(chIndex);
|
|
|
|
|
|
|
|
|
|
// Now that we are encrypting the packet channel should be the hash (no longer the index)
|
|
|
|
|
p->channel = hash;
|
2024-08-13 12:10:46 -05:00
|
|
|
if (hash < 0) {
|
2025-08-29 12:09:22 -05:00
|
|
|
// No suitable channel could be found for
|
2024-08-13 12:10:46 -05:00
|
|
|
return meshtastic_Routing_Error_NO_CHANNEL;
|
|
|
|
|
}
|
2024-08-10 22:38:05 -05:00
|
|
|
crypto->encryptPacket(getFrom(p), p->id, numbytes, bytes);
|
2024-08-10 13:45:41 -05:00
|
|
|
memcpy(p->encrypted.bytes, bytes, numbytes);
|
|
|
|
|
}
|
|
|
|
|
#else
|
2024-08-13 12:10:46 -05:00
|
|
|
if (p->pki_encrypted == true) {
|
|
|
|
|
// Client specifically requested PKI encryption
|
|
|
|
|
return meshtastic_Routing_Error_PKI_FAILED;
|
|
|
|
|
}
|
2024-08-13 17:16:40 -05:00
|
|
|
hash = channels.setActiveByIndex(chIndex);
|
|
|
|
|
|
|
|
|
|
// Now that we are encrypting the packet channel should be the hash (no longer the index)
|
|
|
|
|
p->channel = hash;
|
2024-08-13 12:10:46 -05:00
|
|
|
if (hash < 0) {
|
2025-08-29 12:09:22 -05:00
|
|
|
// No suitable channel could be found for
|
2024-08-13 12:10:46 -05:00
|
|
|
return meshtastic_Routing_Error_NO_CHANNEL;
|
|
|
|
|
}
|
2024-08-10 23:11:04 -05:00
|
|
|
crypto->encryptPacket(getFrom(p), p->id, numbytes, bytes);
|
2024-08-10 13:45:41 -05:00
|
|
|
memcpy(p->encrypted.bytes, bytes, numbytes);
|
|
|
|
|
#endif
|
2021-04-05 09:24:00 +08:00
|
|
|
|
|
|
|
|
// Copy back into the packet and set the variant type
|
|
|
|
|
p->encrypted.size = numbytes;
|
2023-01-21 18:22:19 +01:00
|
|
|
p->which_payload_variant = meshtastic_MeshPacket_encrypted_tag;
|
2021-04-05 09:24:00 +08:00
|
|
|
}
|
2024-08-13 09:15:20 -05:00
|
|
|
|
|
|
|
|
return meshtastic_Routing_Error_NONE;
|
2021-04-05 09:24:00 +08:00
|
|
|
}
|
|
|
|
|
|
2020-05-19 11:56:17 -07:00
|
|
|
NodeNum Router::getNodeNum()
|
|
|
|
|
{
|
2024-03-21 09:06:37 -05:00
|
|
|
return nodeDB->getNodeNum();
|
2020-05-19 11:56:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle any packet that is received by an interface on this node.
|
|
|
|
|
* Note: some packets may merely being passed through this node and will be forwarded elsewhere.
|
|
|
|
|
*/
|
2023-01-21 18:22:19 +01:00
|
|
|
void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
2020-05-19 11:56:17 -07:00
|
|
|
{
|
2024-03-03 08:36:36 -06:00
|
|
|
bool skipHandle = false;
|
2020-05-19 11:56:17 -07:00
|
|
|
// Also, we should set the time from the ISR and it should have msec level resolution
|
2020-10-09 10:01:13 +08:00
|
|
|
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
|
2025-09-11 07:57:42 -05:00
|
|
|
|
2024-02-21 20:00:14 +01:00
|
|
|
// Store a copy of encrypted packet for MQTT
|
2025-09-11 07:57:42 -05:00
|
|
|
DEBUG_HEAP_BEFORE;
|
2024-02-21 20:00:14 +01:00
|
|
|
meshtastic_MeshPacket *p_encrypted = packetPool.allocCopy(*p);
|
2025-09-11 07:57:42 -05:00
|
|
|
DEBUG_HEAP_AFTER("Router::handleReceived", p_encrypted);
|
2020-05-19 11:56:17 -07:00
|
|
|
|
|
|
|
|
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
2025-03-16 08:19:17 -05:00
|
|
|
auto decodedState = perhapsDecode(p);
|
|
|
|
|
if (decodedState == DecodeState::DECODE_FATAL) {
|
|
|
|
|
// Fatal decoding error, we can't do anything with this packet
|
|
|
|
|
LOG_WARN("Fatal decode error, dropping packet");
|
|
|
|
|
cancelSending(p->from, p->id);
|
|
|
|
|
skipHandle = true;
|
|
|
|
|
} else if (decodedState == DecodeState::DECODE_SUCCESS) {
|
2020-05-19 11:56:17 -07:00
|
|
|
// parsing was successful, queue for our recipient
|
2021-10-09 13:54:42 +00:00
|
|
|
if (src == RX_SRC_LOCAL)
|
2021-10-28 11:33:32 +00:00
|
|
|
printPacket("handleReceived(LOCAL)", p);
|
|
|
|
|
else if (src == RX_SRC_USER)
|
|
|
|
|
printPacket("handleReceived(USER)", p);
|
2021-10-09 13:54:42 +00:00
|
|
|
else
|
2021-10-28 11:33:32 +00:00
|
|
|
printPacket("handleReceived(REMOTE)", p);
|
2024-02-21 20:00:14 +01:00
|
|
|
|
2024-03-03 08:36:36 -06:00
|
|
|
// Neighbor info module is disabled, ignore expensive neighbor info packets
|
|
|
|
|
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
|
|
|
|
p->decoded.portnum == meshtastic_PortNum_NEIGHBORINFO_APP &&
|
|
|
|
|
(!moduleConfig.has_neighbor_info || !moduleConfig.neighbor_info.enabled)) {
|
2024-11-04 19:15:59 -06:00
|
|
|
LOG_DEBUG("Neighbor info module is disabled, ignore neighbor packet");
|
2024-03-03 08:36:36 -06:00
|
|
|
cancelSending(p->from, p->id);
|
|
|
|
|
skipHandle = true;
|
|
|
|
|
}
|
2024-07-31 05:52:17 -05:00
|
|
|
|
2024-10-29 05:44:32 -05:00
|
|
|
bool shouldIgnoreNonstandardPorts =
|
|
|
|
|
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
|
2024-10-02 06:14:24 -05:00
|
|
|
#if USERPREFS_EVENT_MODE
|
2024-10-29 05:44:32 -05:00
|
|
|
shouldIgnoreNonstandardPorts = true;
|
|
|
|
|
#endif
|
|
|
|
|
if (shouldIgnoreNonstandardPorts && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
2025-07-28 12:37:37 -05:00
|
|
|
!IS_ONE_OF(p->decoded.portnum, meshtastic_PortNum_TEXT_MESSAGE_APP, meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP,
|
|
|
|
|
meshtastic_PortNum_POSITION_APP, meshtastic_PortNum_NODEINFO_APP, meshtastic_PortNum_ROUTING_APP,
|
|
|
|
|
meshtastic_PortNum_TELEMETRY_APP, meshtastic_PortNum_ADMIN_APP, meshtastic_PortNum_ALERT_APP,
|
|
|
|
|
meshtastic_PortNum_KEY_VERIFICATION_APP, meshtastic_PortNum_WAYPOINT_APP,
|
|
|
|
|
meshtastic_PortNum_STORE_FORWARD_APP, meshtastic_PortNum_TRACEROUTE_APP)) {
|
|
|
|
|
LOG_DEBUG("Ignore packet on non-standard portnum for CORE_PORTNUMS_ONLY");
|
2024-07-31 05:52:17 -05:00
|
|
|
cancelSending(p->from, p->id);
|
|
|
|
|
skipHandle = true;
|
|
|
|
|
}
|
2023-01-28 06:39:14 -06:00
|
|
|
} else {
|
2023-01-28 13:40:14 -06:00
|
|
|
printPacket("packet decoding failed or skipped (no PSK?)", p);
|
2020-05-09 17:51:20 -07:00
|
|
|
}
|
2021-04-05 08:44:47 +08:00
|
|
|
|
2022-02-27 00:29:05 -08:00
|
|
|
// call modules here
|
2025-08-12 16:08:03 -05:00
|
|
|
// If this could be a spoofed packet, don't let the modules see it.
|
2025-09-11 18:57:30 -05:00
|
|
|
if (!skipHandle) {
|
2024-04-17 00:47:56 +02:00
|
|
|
MeshModule::callModules(*p, src);
|
2024-04-19 00:44:13 +02:00
|
|
|
|
|
|
|
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
2024-10-10 22:11:58 +02:00
|
|
|
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not to
|
|
|
|
|
// us (because we would be able to decrypt it)
|
2025-03-16 08:19:17 -05:00
|
|
|
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
|
|
|
|
|
!isBroadcast(p->to) && !isToUs(p))
|
2024-10-10 22:11:58 +02:00
|
|
|
p_encrypted->pki_encrypted = true;
|
2024-04-19 00:44:13 +02:00
|
|
|
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
2025-03-16 08:19:17 -05:00
|
|
|
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
|
|
|
|
|
!isFromUs(p) && mqtt)
|
2024-11-12 22:23:32 +01:00
|
|
|
mqtt->onSend(*p_encrypted, *p, p->channel);
|
2024-04-19 00:44:13 +02:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
packetPool.release(p_encrypted); // Release the encrypted packet
|
2020-05-23 09:24:22 -07:00
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:22:19 +01:00
|
|
|
void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
|
2020-05-23 09:24:22 -07:00
|
|
|
{
|
2024-07-28 19:49:10 -05:00
|
|
|
#if ENABLE_JSON_LOGGING
|
|
|
|
|
// Even ignored packets get logged in the trace
|
|
|
|
|
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_TRACE("%s", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
|
2024-07-28 19:49:10 -05:00
|
|
|
#elif ARCH_PORTDUINO
|
|
|
|
|
// Even ignored packets get logged in the trace
|
2025-09-03 17:50:26 -05:00
|
|
|
if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) {
|
2024-07-28 19:49:10 -05:00
|
|
|
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_TRACE("%s", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
|
2024-07-28 19:49:10 -05:00
|
|
|
}
|
|
|
|
|
#endif
|
2022-05-07 20:31:21 +10:00
|
|
|
// assert(radioConfig.has_preferences);
|
2024-08-14 05:51:32 -07:00
|
|
|
if (is_in_repeated(config.lora.ignore_incoming, p->from)) {
|
2024-11-04 12:16:25 -06:00
|
|
|
LOG_DEBUG("Ignore msg, 0x%x is in our ignore list", p->from);
|
2024-10-09 05:59:00 +02:00
|
|
|
packetPool.release(p);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-29 14:14:24 +01:00
|
|
|
meshtastic_NodeInfoLite const *node = nodeDB->getMeshNode(p->from);
|
2024-11-12 11:27:44 -08:00
|
|
|
if (node != NULL && node->is_ignored) {
|
|
|
|
|
LOG_DEBUG("Ignore msg, 0x%x is ignored", p->from);
|
|
|
|
|
packetPool.release(p);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-09 05:59:00 +02:00
|
|
|
if (p->from == NODENUM_BROADCAST) {
|
2024-11-04 12:16:25 -06:00
|
|
|
LOG_DEBUG("Ignore msg from broadcast address");
|
2024-08-14 05:51:32 -07:00
|
|
|
packetPool.release(p);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-05-23 10:01:36 -07:00
|
|
|
|
2024-08-14 05:51:32 -07:00
|
|
|
if (config.lora.ignore_mqtt && p->via_mqtt) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Msg came in via MQTT from 0x%x", p->from);
|
2024-08-14 05:51:32 -07:00
|
|
|
packetPool.release(p);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shouldFilterReceived(p)) {
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Incoming msg was filtered from 0x%x", p->from);
|
2024-08-14 05:51:32 -07:00
|
|
|
packetPool.release(p);
|
|
|
|
|
return;
|
2020-05-24 19:23:50 -07:00
|
|
|
}
|
2020-05-23 10:01:36 -07:00
|
|
|
|
|
|
|
|
// Note: we avoid calling shouldFilterReceived if we are supposed to ignore certain nodes - because some overrides might
|
|
|
|
|
// cache/learn of the existence of nodes (i.e. FloodRouter) that they should not
|
2024-08-14 05:51:32 -07:00
|
|
|
handleReceived(p);
|
2020-04-17 09:48:54 -07:00
|
|
|
packetPool.release(p);
|
2025-01-10 04:46:26 -06:00
|
|
|
}
|