liberatedsystems / RNode_Firmware_CE

RNode is an open, free and flexible digital radio interface with many uses
https://unsigned.io/rnode
GNU General Public License v3.0
40 stars 9 forks source link

Interface support #3

Closed jacobeva closed 3 months ago

jacobeva commented 4 months ago

The thing I've been going on about for so long...

How should we handle this in the firmware?

My first thought is to have a type assigned to every modem object, primary or secondary. Then, when a packet is received, the modem it was received on can be indicated to the host (just like RSSI and SNR). Then, when the host adds packets to be transmitted in reply, it can also specify the modem before writing the packet. This is how I'd imagine interacting with the two working. This also means that both can still generate interrupts and things don't get muddled also.

I also had the idea in my mind of having a connection "upgrade". Imagine 2 boards with a SX1262 and a SX1280 each. When the transmitter sends out a link request, and it's received on the receiver, there could be some kind of config parameter for the interface in reticulum, which specifies that it tries to do this "upgrade" (if it has a second modem with higher data rate of course). So, it responds using the SX1280. If it doesn't hear a reply after a certain timeout, it responds using the SX1262, and carries on as normal. A note should probably be made so it doesn't try the "upgrade" for the same peer again for a certain period. This way, if the link is too poor for the SX1280, or the transmitter doesn't have an SX1280, things still work okay. This should probably be disabled by default and the timeout tuned so as to not create too much disruption. However, it will slow things down. Maybe we could transmit on both at the same time? Of course, you could also send some kind of info in the advertising packet about whether a higher speed link is available, but this would mean adding unnecessary information and I imagine you probably wouldn't like it that way ;)

Please let me know what you think Mark!

Edit: Issue transferred from original at https://github.com/markqvist/RNode_Firmware/issues/65

jacobeva commented 4 months ago

"I think the best approach is for the RNodes with multiple modems to be handled as multiple interfaces by Reticulum. In that case, the "upgrade" functionality is already there, and Reticulum will use faster links when available, but fall back to the SX1262 when the SX1280 is no longer in range. This greatly simplifies the transceiver firmware logic, and keeps routing decisions within Reticulum, in accordance with the overall philosophy of the system.

Should also be the most straightforward to implement. But needs a way for both the firmware and Reticulum to handle single devices presenting multiple interfaces. Not really complicated though, we could just have separate virtual interfaces that are addressable with an index byte or something on the host interface protocol.

I've had these features planned for a long time too, but have so far opted not to add them to the current branch of the firmware, since it's already pretty convoluted. I think it may be worth considering moving advanced stuff like this to a clean slate, and focus on creating a more clean structure, and removing legacy stuff." @markqvist

jacobeva commented 4 months ago

I see, I apologise for the poor suggestion. That makes much more sense indeed.

Yep, addressing is somewhat like what I suggested initially, albeit you put it in a much clearer way!

What do you mean by a clean slate? Are you intending to revamp this firmware repo at some point? I remember you mentioning something of the sort in the Matrix channel, I don't recall much of it.

jacobeva commented 4 months ago

"Don't apologise, I'm just suggesting stuff :) Depending on how many different transceivers would be needed per device, we could add an extra byte to the DATA command, so instead of C0 00 [DATA] C0, you could have C0 00 [TRANSCEIVER_CHANNEL] [DATA] C0 that would also allow all kinds of funky stuff such as virtual "channels" running on the same modem, in addition to having multiple modems.

The only thing slightly hairy about this approach is that it might be better to move modem/channel configuration parameters to the device itself, instead of having that stored in the Reticulum config. That way, Reticulum could poll the device for available sub-devices, and just create interfaces accordingly. Not sure I like the idea of leaving that much up to the device though.

Another way would simply be to allow specifying "sub-devices" for a particular device in the Reticulum configuration, so for example adding an interface on a given serial/bt port would always default to the primary modem on that device, but by specifying a sub-device in the config, other modems can be used. This can get convoluted pretty quickly though.

Really not sure what the best approach is yet, and it's worth thinking it through really well.

And yes, I meant a complete revamp / cleanup of the repo. The current state of it goes all the way back to when RNodes were only made on the AVR platform, and even ESP32 support was added in as a sort of compiler hack. Today, by far the primary use is on modern devices like ESP (and now soon nRF, hopefully), and having the full 8-bit AVR legacy is a bit silly. There's a lot that could be cleaned up, structured better and generally improved in all sorts of ways, but I just haven't had the time to do this yet." @markqvist

jacobeva commented 4 months ago

Interesting suggestions. Why would you want to add tranceiver channels? Is this related to something else?

In terms of multiple interfaces, something akin to this?

  [[freeNode]]
     type = RNodeInterface

     # Enable interface if you want use it!
     interface_enabled = False

     # Serial port for the device
     port = /dev/ttyACM0

     [[modem0]]
         # Set frequency to 867.2 MHz
         frequency = 867200000

         bandwidth = 500000

         txpower = 0

         spreadingfactor = 7

         codingrate = 5

    [[modem1]]
        frequency = 2400000000

        bandwidth = 500000
        txpower = 5

        spreadingfactor = 6

        codingrate = 7

I think it makes more sense to have the config done in reticulum than on device for now, keeping in line with your philosophy as you stated prior. The user will have to be given instructions on how to configure their device, as is currently expected anyway :)

jacobeva commented 4 months ago

As seen on Wikipedia, the KISS protocol already supports multiple TNC ports. The 00 in C0 00 [DATA] C0 can be incremented to address different TNC ports. For example, C0 10 [DATA] C0 would address TNC port 1. Only the high nibble can be used for this, which restricts us to 16 possible subinterfaces on the RNode, but I think that's plenty. Someone's got to have a pretty mental setup to get beyond that!

markqvist commented 4 months ago

I was going to say this wouldn't work, since RNode doesn't restrict commands to only using the low nibble components of the KISS command byte, since there's a lot of commands.

But looking at the code, it seems I somehow had the foresight to reserve all the 0x?0 commands for this purpose when I mapped out the command codes initially. Surprise from the past.

You'll need to modify the code that removes the port nibble from the command byte in the serial read loop, and deal with it accordingly, but other than that, it seems like a valid approach.

markqvist commented 4 months ago

Err, wait, no. Not at all. There will be collisions with CMD_BLINK, CMD_RANDOM, CMD_FW_VERSION and CMD_HASHES.

But you could map around that and still get 10 ports, which I guess should be more than enough.

jacobeva commented 4 months ago

Sounds good, thanks for the feedback. You just saved me a lot of troubleshooting lol.

jacobeva commented 4 months ago

Correction, 11 total interfaces are possible ;)

Edit: 12 actually it seems...

jacobeva commented 3 months ago

Merged.