Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion protobufs
2 changes: 2 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ bool eink_found = true;

uint32_t serialSinceMsec;
bool pauseBluetoothLogging = false;
// Global control flag for encrypted-only promiscuous forwarding to FromRadio
bool serialPromiscuousEnabled = false;

bool pmu_found;

Expand Down
4 changes: 4 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ extern bool runASAP;

extern bool pauseBluetoothLogging;

// When true, forward all received LoRa packets to FromRadio as encrypted MeshPacket payloads
// and avoid sending decrypted duplicates to FromRadio. Reset to false on serial connect/disconnect.
extern bool serialPromiscuousEnabled;

void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(), rp2040Setup(), clearBonds(), enterDfuMode();

meshtastic_DeviceMetadata getDeviceMetadata();
Expand Down
20 changes: 15 additions & 5 deletions src/mesh/MeshService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
}

printPacket("Forwarding to phone", mp);
sendToPhone(packetPool.allocCopy(*mp));
// If promiscuous mode is enabled, suppress duplicate to phone.
if (!serialPromiscuousEnabled) {
sendToPhone(packetPool.allocCopy(*mp));
}

return 0;
}
Expand Down Expand Up @@ -184,7 +187,10 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
return;
}
#endif
p.from = 0; // We don't let clients assign nodenums to their sent messages
// Allow any encrypted packet as-is in promiscuous mode
if (!(serialPromiscuousEnabled && p.which_payload_variant == meshtastic_MeshPacket_encrypted_tag)) {
p.from = 0; // We don't let clients assign nodenums to their sent messages
}
p.next_hop = NO_NEXT_HOP_PREFERENCE; // We don't let clients assign next_hop to their sent messages
p.relay_node = NO_RELAY_NODE; // We don't let clients assign relay_node to their sent messages

Expand Down Expand Up @@ -292,7 +298,10 @@ bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)

void MeshService::sendToPhone(meshtastic_MeshPacket *p)
{
perhapsDecode(p);
// In promiscuous mode, prefer to forward encrypted packets as-is and avoid decoding duplicates
if (!serialPromiscuousEnabled) {
perhapsDecode(p);
}

#ifdef ARCH_ESP32
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
Expand All @@ -306,8 +315,9 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
#endif

if (toPhoneQueue.numFree() == 0) {
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
(p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP)) {
LOG_WARN("ToPhone queue is full, discard oldest");
meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
if (d)
Expand Down
5 changes: 5 additions & 0 deletions src/mesh/PhoneAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ void PhoneAPI::close()
config_state = 0;
pauseBluetoothLogging = false;
heartbeatReceived = false;
serialPromiscuousEnabled = false;
}
}

Expand Down Expand Up @@ -165,6 +166,10 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
LOG_INFO("Disconnect from phone");
close();
break;
case meshtastic_ToRadio_set_promiscuous_tag:
LOG_INFO("Set serial promiscuous: %s", toRadioScratch.set_promiscuous ? "true" : "false");
serialPromiscuousEnabled = toRadioScratch.set_promiscuous;
break;
case meshtastic_ToRadio_xmodemPacket_tag:
LOG_INFO("Got xmodem packet");
#ifdef FSCom
Expand Down
7 changes: 7 additions & 0 deletions src/mesh/Router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,13 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)

void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
{
if (serialPromiscuousEnabled) {
// If serial promiscuous mode is enabled, forward the encrypted form to the phone now
service->sendToPhone(packetPool.allocCopy(*p));
}
LOG_DEBUG("serialPromiscuousEnabled: %d Encrypted: %d", serialPromiscuousEnabled,
p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag);

#if ENABLE_JSON_LOGGING
// Even ignored packets get logged in the trace
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
Expand Down
5 changes: 5 additions & 0 deletions src/mesh/StreamAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "RTC.h"
#include "Throttle.h"
#include "configuration.h"
#include "main.h"

#define START1 0x94
#define START2 0xc3
Expand Down Expand Up @@ -219,9 +220,13 @@ void StreamAPI::onConnectionChanged(bool connected)

if (connected) { // To prevent user confusion, turn off bluetooth while using the serial port api
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
// Reset promiscuous mode on connect
serialPromiscuousEnabled = false;
} else {
// FIXME, we get no notice of serial going away, we should instead automatically generate this event if we haven't
// received a packet in a while
powerFSM.trigger(EVENT_SERIAL_DISCONNECTED);
// Reset promiscuous mode on disconnect
serialPromiscuousEnabled = false;
}
}
8 changes: 7 additions & 1 deletion src/mesh/generated/meshtastic/mesh.pb.h
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,10 @@ typedef struct _meshtastic_ToRadio {
meshtastic_MqttClientProxyMessage mqttClientProxyMessage;
/* Heartbeat message (used to keep the device connection awake on serial) */
meshtastic_Heartbeat heartbeat;
/* Set or clear promiscuous capture mode for LoRa RX.
If true, the device will forward all received LoRa packets to FromRadio as encrypted MeshPacket payloads,
and will avoid additionally sending the decrypted copies. This is primarily intended for serial sniffing. */
bool set_promiscuous;
};
} meshtastic_ToRadio;

Expand Down Expand Up @@ -1605,6 +1609,7 @@ extern "C" {
#define meshtastic_ToRadio_xmodemPacket_tag 5
#define meshtastic_ToRadio_mqttClientProxyMessage_tag 6
#define meshtastic_ToRadio_heartbeat_tag 7
#define meshtastic_ToRadio_set_promiscuous_tag 8
#define meshtastic_NodeRemoteHardwarePin_node_num_tag 1
#define meshtastic_NodeRemoteHardwarePin_pin_tag 2
#define meshtastic_ChunkedPayload_payload_id_tag 1
Expand Down Expand Up @@ -1883,7 +1888,8 @@ X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_i
X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 5) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqttClientProxyMessage,mqttClientProxyMessage), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,heartbeat,heartbeat), 7)
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,heartbeat,heartbeat), 7) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,set_promiscuous,set_promiscuous), 8)
#define meshtastic_ToRadio_CALLBACK NULL
#define meshtastic_ToRadio_DEFAULT NULL
#define meshtastic_ToRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket
Expand Down
Loading