Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transmission disappearing when sent before second Rx window #163

Open
klementc opened this issue Apr 22, 2024 · 2 comments
Open

Transmission disappearing when sent before second Rx window #163

klementc opened this issue Apr 22, 2024 · 2 comments
Assignees

Comments

@klementc
Copy link

klementc commented Apr 22, 2024

Expected Behavior

Hello, if I send two uplink packets from the same node in a short time, I encounter 2 different behaviors for the second packet's transmission. The expected behavior is for the second packet to be scheduled after making sure the reception windows of the first packet are closed, and DC rules are respected.

Actual Behavior

I encounter 2 different behaviors depending on the timestamp of the Send() function:

  1. The second send() is made after the second reception window of the first packet is closed. In this case, the DC delay is computed, and the packet is delayed to later. In this case, the packet is sent after the delay expired.
  2. The second send() is made before the second reception window of the first packet is closed. In this case, the second packet is never sent, despite the logs notifying the scheduling of the send event after a delay.

Steps to Reproduce the Problem

I modify the simple-network-example to add a second transmission:

diff --git a/examples/simple-network-example.cc b/examples/simple-network-example.cc
index c1714e0..0787efd 100644
--- a/examples/simple-network-example.cc
+++ b/examples/simple-network-example.cc
@@ -150,7 +150,8 @@ main(int argc, char* argv[])
     oneShotSenderHelper.SetSendTime(Seconds(2));
 
     oneShotSenderHelper.Install(endDevices);
-
+    oneShotSenderHelper.SetSendTime(Seconds(4));
+    oneShotSenderHelper.Install(endDevices);
     /******************
      * Set Data Rates *
      ******************/

In this case, the (parsed) logs output:

#+BEGIN_SRC output
[FIRST PACKET RECEIVED WITH NO PROBLEM, FIRST RX WINDOW FINISHED, NOW SEND THE SECOND PACKET]
+4.000000000s 0 OneShotSender:SendPacket(0x582a2e609110)
+4.000000000s 0 EndDeviceLorawanMac:Send(0x582a2e607000, 0x582a2e6074c0)
+4.000000000s 0 EndDeviceLorawanMac:GetNextTransmissionDelay()
+4.000000000s 0 LogicalLoraChannelHelper:GetEnabledChannelList(0x582a2e607078)
+4.000000000s 0 LogicalLoraChannelHelper:GetWaitingTime(0x582a2e607078, 0x582a2e606970)
+4.000000000s 0 LogicalLoraChannelHelper:GetWaitingTime(): Waiting time: 3.09414
+4.000000000s 0 EndDeviceLorawanMac:GetNextTransmissionDelay(): Waiting time before the next transmission in channel with frequecy 868.1 is = 3.09414.
+4.000000000s 0 LogicalLoraChannelHelper:GetWaitingTime(0x582a2e607078, 0x582a2e606790)
+4.000000000s 0 LogicalLoraChannelHelper:GetWaitingTime(): Waiting time: 3.09414
+4.000000000s 0 EndDeviceLorawanMac:GetNextTransmissionDelay(): Waiting time before the next transmission in channel with frequecy 868.3 is = 3.09414.
+4.000000000s 0 LogicalLoraChannelHelper:GetWaitingTime(0x582a2e607078, 0x582a2e6067d0)
+4.000000000s 0 LogicalLoraChannelHelper:GetWaitingTime(): Waiting time: 3.09414
+4.000000000s 0 EndDeviceLorawanMac:GetNextTransmissionDelay(): Waiting time before the next transmission in channel with frequecy 868.5 is = 3.09414.
+4.000000000s 0 ClassAEndDeviceLorawanMac:GetNextClassTransmissionDelay()
+4.000000000s 0 ClassAEndDeviceLorawanMac:GetNextClassTransmissionDelay(): Attempting to send when there are receive windows: Transmission postponed.
+4.000000000s 0 LorawanMac:GetSfFromDataRate(0x582a2e607000, 0)
+4.000000000s 0 LorawanMac:GetBandwidthFromDataRate(0x582a2e607000, 0)
+4.000000000s 0 ClassAEndDeviceLorawanMac:GetNextClassTransmissionDelay(): Duration until endSecondRxWindow for new transmission:0.3136
+4.000000000s 0 EndDeviceLorawanMac:postponeTransmission(0x582a2e607000)
+4.000000000s 0 EndDeviceLorawanMac:postponeTransmission(): Attempting to send, but the aggregate duty cycle won't allow it. Scheduling a tx at a delay 3.09414.
+4.051456010s 0 ClassAEndDeviceLorawanMac:OpenSecondReceiveWindow()
+4.051456010s 0 EndDeviceLoraPhy:GetState()
+4.051456010s 0 EndDeviceLoraPhy:SwitchToStandby()
+4.051456010s 0 ClassAEndDeviceLorawanMac:OpenSecondReceiveWindow(): Using parameters: 869.525Hz, DR0
+4.051456010s 0 LorawanMac:GetSfFromDataRate(0x582a2e607000, 0)
+4.051456010s 0 LorawanMac:GetSfFromDataRate(0x582a2e607000, 0)
+4.051456010s 0 LorawanMac:GetBandwidthFromDataRate(0x582a2e607000, 0)
+4.313600010s 0 ClassAEndDeviceLorawanMac:CloseSecondReceiveWindow()
+4.313600010s 0 EndDeviceLoraPhy:GetState()
+4.313600010s 0 EndDeviceLoraPhy:SwitchToSleep()
+4.313600010s 0 ClassAEndDeviceLorawanMac:CloseSecondReceiveWindow(): We have 8 transmissions left. We were not transmitting confirmed messages.
OneShotSender:~OneShotSender()
OneShotSender:~OneShotSender()
#+END_SRC

We observe the delayed scheduling of the second packet transmission 3.09414 seconds after its supposed emission time. However, the transmission never starts. If using a Tx time later than the second receive window (i.e. 4.3136), the second packet is delayed in a similar way, and sent successfully after this delay.

I think this behavior shouldn't happen and the postponed transmission should take place after considering DC rules.

The reason for this to happen is the resetRetransmissionParameters() function called in CloseSecondReceiveWindow() that cancels the future transmission. Simulator::Cancel(m_nextTx); deletes the future Tx, causing this issue.

If this is the expected behavior, how should I schedule the tx of multiple packets from the application

Specifications

  • ns-3 version: 3.41
  • lorawan module version: commit b866c0b
klementc added a commit to klementc/lorawan that referenced this issue Apr 22, 2024
@non-det-alle non-det-alle self-assigned this Apr 27, 2024
@non-det-alle
Copy link
Collaborator

Hello Clément,

Yes, we are aware of this problem (among others!) in the current implementation of the MAC layer. In general, real LoRaWAN applications would not request two uplink transmission in such a short time span (2 seconds). As you noted, the responsibility not to schedule a second uplink transmission in such a short time frame is currently left to the user. I agree that in the future it should be prevented to avoid unexpected behavior; it is already on the list of planned changes to this module in the dedicated issue.

I'll take this chance to write down how - in my opinion - the intended behavior should be; then we can see whether to take the time to implement it, or just patch your issue for now.

If we look at an actual implementation of the LoRaWAN MAC layer, we see that you should not be able to transmit a new packet neither while the device is still busy with the reception procedure (i.e., the 2 reception windows), nor if there are further retransmission scheduled for a previous packet. The way they prevent you from doing that is by having an internal task scheduler, acting as a size-1 buffer for send events. The send task is only launched if the MAC layer is IDLE, i.e., not planning to open a reception window, not planning to retransmit a packet, etc.

Interestingly, this implementation seems to interrupt the retransmission procedure if no channel with available duty-cycle is found after closing the 2nd reception window. Note that here the duty-cycle is managed in 1 hour periods (i.e., with a 1% DC you'd have 36 cumulative seconds to use for TX in the band for the current hour), providing more time management flexibility than our implementation.

For now, you may want to avoid scheduling a second call to Send while the device is still in the process of opening reception windows. I'll leave this issue open for further discussion and updates.

@klementc
Copy link
Author

Hello, thank you for your answer.
I know that it is uncommon to have applications sending messages within such short delays, but I am interested in simulating what would happen in such situations.
I guess for now the best is to rely on callbacks to wait for the finish of the second window before sending new packets, thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants