In one of my simulations I encountered a problem where the above mentioned exception is
triggered here about 30 minutes into my simulation. Setup:
Coupled simulation with Sumo over TraCI
Multiple eNBs (6)
120 nodes (Pedestrians, manged by Sumo)
Each pedestrian has 3 D2D applications sending broadcast messages (link local)
*.lteNic.phy.dynamicCellAssociation = true
**.lteNic.phy.enableHandover = true
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.
In one of my simulations I encountered a problem where the above mentioned exception is triggered here about 30 minutes into my simulation. Setup:
*.lteNic.phy.dynamicCellAssociation = true
**.lteNic.phy.enableHandover = true
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:All
availableBytes
are given to a single connection id. Note that theavailableBytes
must include theMAC_HEADER
(once) and theRLC_HEADER
(for each cid). After scheduling the Mac layer calls LteMacUe::macSduRequest() to createLteMacSduRequests
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 theLteMacSduRequests
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 inLteMacUe::macSduRequest()
and in theLcgScheduler
have different order allowing an emptyLteMacSduRequest
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.