inet-framework / simulte

SimuLTE - LTE System Level Simulation Model and Simulator for INET & OMNeT++ - deprecated, use Simu5G instead
https://simulte.omnetpp.org
Other
137 stars 110 forks source link

Empty buffer for cid XX while expected SDUs were YY runtime error in multiple D2D application usecase #65

Open stefanSchuhbaeck opened 3 years ago

stefanSchuhbaeck commented 3 years ago

In one of my simulations I encountered a problem where the above mentioned exception is triggered here about 30 minutes into my simulation. Setup:

The node in question is created out of range of any eNB and thus cannot transmit. This also needs PR #64 to work. During this time the applications create messages which will be queued in the RLC Layer, each within a dedicated connection.

In the Mac layer the MacBuffers accepts the LteRlcPduNewData as expected. When the node enters TX/RX range with a eNB scheduling grants are received and the Mac layer starts the scheduling (LcgScheduler) as expected. Due to the full Buffers only one of the connections is scheduled leading to scheduleList that looks something like this:

cid         numSDUs
73990145      0
73990146      0
73990147      1

All availableBytes are given to a single connection id. Note that the availableBytes must include the MAC_HEADER (once) and the RLC_HEADER (for each cid). After scheduling the Mac layer calls LteMacUe::macSduRequest() to create LteMacSduRequests for each connection currently available. This includes all connection even if the did not receive any available bytes. In line 183 the scheduleList is iterated, creating the LteMacSduRequests as mentioned. From the first Sdu the scheduled number of bytes is reduced by the MAC_HEADER (here). However, in my case the first item in the iterator didn't get allocated any bytes, leading to a negative number of bytes for this SDU. This does not create an error because the sduSize is of the type unsigned int (underflow) and the RLC layer code will cast it to and int later on and ignores the request (see here).

This however means that for cid 73990147 2 Bytes more are requested than actually needed. This will lead to difference between the RLC Buffer length and the MacBuffer length which should be synchronized. The RLC Buffer will run out of data but the MacBuffer still has data which will be scheduled but no data will be send down from the RLC layer, leading to the mentions exception. This error will only occur if multiple connections exist, only one of them is served and if the iterators in LteMacUe::macSduRequest() and in the LcgScheduler have different order allowing an empty LteMacSduRequest to be the first SDU.

To reproduce the error create a breakpoint here with an condition of sduSize <= 0. In this case the MAC_HEADER is not removed correctly and for some other connection to many bytes are requested from the RLC layer leading to an offset between the RLC and LteMacBuffer.

In the pull request I fixed the issue by directly specifying which connection provides the first SDU so the MAC_HEADER is removed from the correct connection. Another approach would be to give the scheduler the correct amount of availabeBytes where the MAC_HEADER is already removed. However I am not sure if this breaks something else I am not aware of.