Without ACK/NACK, message is lost?

I have look at the log several times but I will look at it again. That I think is that it’s overload because of the packages we send from the device (not the phone) I still got the warning about channel utilization percent. I will look at the tips you give me.
I’ll inform you if I find or get something, thank you!

I’ve been thinking about building a similar thing, using Python. Sounds like you may be building a reference implemention for streaming over Meshtastic?

I have wondered if it would be ideal to create a new module that would be dedicated to a UDP like packet so that a peer can reassemble the packets in an expected way. Also, having a dedicated module allows other radios to opt out of TCP like communication.

But I’m interrupting your technical troubleshooting… I’ll continue to watch. Happy to see how you make out.

Flood routing and tcp are not a great match, really only useful point to point and can’t use the mesh. Lora is really low bandwidth. If you have to turn off acks, keeping track of a file being assembled is not going to work. This winds up being what is essentially a DDOS attack on the mesh.

This is a valuable feature indeed!

@GUVWAF @mc-hamster How about including more than one ACK-message to one lora packet? In the case above, in the end, T-Beam 1 could include all four ACK’s to only one lora packet, avoiding transmitting separate ACK’s for all four messages. Moreover, also other messages (payloads) could be stacked within one lora transmission, for avoiding unnecessary airtime utilization…?

Looking at the waterfall, the channel utilization of the messages and ACK’s are almost the same, supposedly caused by very short messages?

1 Like

This change has been merged and will be in the next release.

Here I was sending broadcasts, so the ACKs are actually implicit ACKs, meaning a rebroadcast by another node, which have the same payload. Real ACKs are shorter.

While it would be possible to aggregate multiple ACKs, this would then only be helpful for real ACKs. Besides, it can only be done after you sense that the channel is busy and thus have to postpone sending the ACK directly, and while waiting you get another message. Then you have to discard the old ACK and generate an aggregated ACK. It would add quite some complexity for a very specific scenario, not sure if that is worth it.

Other payloads could maybe indeed be stacked, but I think the payload of messages from modules can already get quite big. For text messages, I would just recommend to send as much as possible in one message :slight_smile:

2 Likes

Hi, I have tested this with the newest firmware and Android code over the past few days, and now I’ve managed to fix it so there are never any lost and no errors such as a “core dump”. Next I tried using routers in between (for distance). What happens is sometimes packets are lost. Does anybody have any experience using routers in between or have any thoughts on what the problem may be or how to solve it?
So far I have loved this challenge. I would really love to take it to the next level. Any opinions would be really appreciated! :slightly_smiling_face:

1 Like

Nice to hear you got it working.

You mean now you have three devices (two clients and one router) where the two clients are out of range and the router forwards the packets? In this case you essentially cut the throughput in half, because the client cannot send when the router is forwarding. So maybe you need to decrease the rate at which you generate the packets.

1 Like

Yes, it is right like that. I want to add routers so I can use if I"m out of range.
The thing I’ll do is exactly that you said about decrease the rate but I don’t know really where to do this. If you could tell me that it would be very good.

Would I make the changes here? Is it different for client and router/-s?

/* If we have pending retransmissions, add the airtime of this packet to it, because during that time we cannot receive an
   (implicit) ACK. Otherwise, we might retransmit too early.
 */
for (auto i = pending.begin(); i != pending.end(); i++) {
    if (i->first.id != p->id) {
        i->second.nextTxMsec += iface->getPacketTime(p);
    }
}
/* At this point we have already deleted the pending retransmission if this packet was an (implicit) ACK to it.
   Now for all other pending retransmissions, we have to add the airtime of this received packet to the retransmission timer,
   because while receiving this packet, we could not have received an (implicit) ACK for it.
   If we don't add this, we will likely retransmit too early.
*/
for (auto i = pending.begin(); i != pending.end(); i++) {
    i->second.nextTxMsec += iface->getPacketTime(p);
}
1 Like

I see, that makes sense and it’s one of the benefits of Meshtastic :slight_smile:

I was actually referring to generating it on a lower rate at the Android side. If you’re generating the messages too fast already there, the device might not be able to deliver them. Depending on the payload size and LoRa settings you use, the airtime of a packet may even be multiple seconds. Since it needs to be send twice now, this time adds up pretty quickly.

The part you’re referring to in the firmware only handles the timing of retransmissions, not the actual sending rate of a new packet. It will already try to do this as fast as possible (but it will first listen if not somebody else is transmitting).

1 Like

I did a slow tranmission in the Android as I could. And I did this in the beginning but to slow down affects the program. Because of this I think it is better to make this slow down in the firmware.
Can you help me to where I can put delay() in front of send() if we have pending packets.

1 Like

Actually you don’t want it to wait longer if it can transmit already, because the packets will accumulate even more. If you’re generating packets too fast from the Android side, the device will eventually drop the packets.

What may help is setting the transmit delay of the router lower, because otherwise the client might eat up all bandwidth and the router is never able to send. You can do this by using only startTransmitTimer (and never startTransmitTimerSNR) here. However, this only works well if you have only one device that will be forwarding the messages.

Than you, I"ll try this and write to your about how it was

Ok I tried this ‘startTransmitTimer’ and decreased the delay here ‘getTxDelayMsec’. But it hasn’t worked like I wanted. This way that Android sends with delays works, but when I give it too much time, the error ‘Meshtastic is not responding’ is given. But I don’t think this is a problem because when I choose ‘Wait’ it then continues sending after the wait (usually of a few seconds or less). Do you think bypassing this by choosing ‘Wait’ is a problem in itself or cause other problems elsewhere?
I really think it could be more simple than this, since my only problem is that packets are being sent altogether, is there not anywhere where I can add an if statement to check if there are many packets at once, add a delay before sending.
How fast Android sends the packets, the device always receives them. But the problem is when the device sends. I think that the delay needs to be here. Am I crazy or just tired?! :sweat_smile: Seriously…

1 Like

The queues for both android and the firmware are new (maybe a month old) and have not been actually fully implemented anywhere yet, so you are pioneering here. It is going to be pretty difficult to implement all of this, and even trickier to get it working with the mesh.

Indeed, it’s new and you’re really pushing the limits here, so it’s very hard to get it work well. But if you’re up to the challenge, I wish you best of luck :slight_smile:

I don’t have any experience with the Android side, so I can’t really help with that.

Maybe you can get the amount of free slots in the transmit queue (txQueue.getFree() in RadioLibInterface) and based on that add your delay (less free means more packets in the queue). But this will need some trial and error and is even harder to make it work with all LoRa settings, packet lengths and regardless of how many nodes are in the mesh.

Me too, I don’t really know C++ but when I set my goal I can’t leave it alone! Since you know the feeling of not knowing something due to lack of experience… maybe you could explain a bit more about the txQueue.getFree() ? You mean I put the delay inside this script, like a simple if statement for how many free slots, if so-many then add a delay? Or would it need it be more than this, like inside the send function add things too? If much more is needed then I maybe I’ll be stuck for longer than I want to be…

Yes, you use that function to add the delay somewhere in the send methods. I’m not sure where to add it exactly, because I don’t know where the problem is now, so that’s something you’d have to try.

Ok great, I will try it. If something else comes to mind, let me know.
I 'll keep you updated! :slightly_smiling_face:

2 Likes

I tried what you said with the txQueue.getFree(). Like you said, it needs a lot of calculations considering all the different settings etc that need to be changed, but doesn’t always get the desired result.
Anyway, I have done it like we talked about earlier (the most recent update etc) and the result I got is enough for what I need.
Just wanted to say thanks for all your help! Good luck with the project and its future!

2 Likes