meshtastic / firmware

Meshtastic device firmware
https://meshtastic.org
GNU General Public License v3.0
3.37k stars 825 forks source link

[Feature Request]: Remote radio driver #4228

Open danielkucera opened 3 months ago

danielkucera commented 3 months ago

Platform

Linux Native

Description

Hello, I have a conveniently located LoRaWAN gateway using packet forwarder protocol (see A in the picture).

lorawan-adapter

I would like to use this gateway as a radio for meshtastic native (see B). In the middle, there is a multiplexer which will forward packets to/from both TTN and ??? box. I am able to implement the ??? by myself. On the meshtastic side, I would need a simple "virtual radio" driver which can communicate via TCP/UDP. I was looking at SimRadio but that doesn't send the modulation parameters (freq, bw, sf, cr,...)

Do you think this can be easily implemented? Do you think it would be easier to extend the SimRadio or write a new radio driver?

Pigpog commented 2 weeks ago

I have the same need, for a different purpose. I am trying to make some buggy/unsupported hardware speak Meshtastic, and currently my plan is to tap into the simulated radio as you suggest. It was rather simple to make the firmware output the packets it is trying to send to a FIFO file, encoded as hexadecimal for portability. It was similarly easy to make the proof of concept driver for this hardware transmit the packets.

Where I'm stuck is making the simulated radio "receive" data from real radio hardware. My hardware driver is outputting hex-encoded packets to a FIFO, but I don't know how to make Meshtastic fw read it.

While my use-case is probably less of a priority for developers, we can now say there are at least two use-cases for this requested feature.

Here's the patch I made for exfiltrating packets from Meshtastic to a FIFO. (not necessarily good code but it works): ```diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index eacd4964..e824dfb0 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -1,4 +1,4 @@ -#include "RadioInterface.h" +#include "RadioInterface.h" #include "Channels.h" #include "DisplayFormatters.h" #include "MeshRadio.h" @@ -12,6 +12,14 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \ { \ meshtastic_Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ @@ -615,6 +623,38 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p) memcpy(radiobuf + sizeof(PacketHeader), p->encrypted.bytes, p->encrypted.size); + + // Name of the FIFO file + const char* fifoPath = "/dev/shm/meshtastic"; + + // Create the FIFO if it doesn't exist + mkfifo(fifoPath, 0666); + + // Open the FIFO for writing + int fifoFd = open(fifoPath, O_WRONLY); + if (fifoFd == -1) { + std::cerr << "Error opening FIFO: " << fifoPath << std::endl; + return 1; + } + + // Convert the byte to a zero-padded hexadecimal string + std::ostringstream formattedByte; + for (int i = 0; i < (16 + p->encrypted.size); i++) { + formattedByte << std::setw(2) << std::setfill('0') << std::hex << static_cast(radiobuf[i]); + } + formattedByte << std::endl; + // Get the formatted string + std::string hexString = formattedByte.str(); + + // Write the formatted byte to the FIFO + ssize_t bytesWritten = write(fifoFd, hexString.c_str(), hexString.length()); + if (bytesWritten == -1) { + std::cerr << "Error writing to FIFO." << std::endl; + } + + // Close the FIFO + close(fifoFd); + sendingPacket = p; return p->encrypted.size + sizeof(PacketHeader); } ```