Incorrect behaviour of Segmentation/Reassembly mechanism after dropped PDU

Bug #573631 reported by Boyan Lazarov on 2010-05-02
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
openWNS Library
Medium
Boyan Lazarov

Bug Description

Hello,
I'm trying to use the SegAndConcat FU (wns::ldk::sar::SegAndConcat) in combination with a SegmentingQueue in a setup similar to the one in wimac. I'm having some trouble during the reassembly procedure after a packet has been lost and the t-Reordering timer has expired. Below is is a description of the setup and the problem:

Setup:
A base station (BS) in a scenario with multiple cells and BSs is transmitting data to a subscriber station (SS). Data comes in the form of IP Packets from the constanze generators. Packet size is 1024 Bit data + 48 Bit overhead = 1072 Bit. The SegAndConcat FU is setup with isSegmenting = False as segmentation is performed by the SegmentingQueue in the scheduler. The FU thus only handles reassembly. There is also a CRC present bellow the SegAndConcat FU, which is set to "Dropping". Furthermore, there are no retransmissions in the system (no HARQ nor ARQ). The following situation arises:

After transmitting for some time, a PDU is discarded by the CRC because the ErrorModeling calculated a high error probability. The PDU has a SN = 189. As described in the protocol, the reordering timer is started. In the mean time, further transmissions occur, and PDUs with SN = 190 to 205 are transmitted and correctly received until the timer expires. The VR variables at the time the timer fires look the following way:

vrUH_ = 206
vrUR_=189
vrUX_ = 191

TS 36.322 5.1.2.2.4 defines the following actions when the timer expires:

- vrUR is set to the SN of the first not received PDU with SN > vrUX, in this case 206
- From the received PDUs with SN < this new vrUR ( SN < 206), SDUs are reassembled and passed to the FUs above.If an SDU cannot be reassembled due to missing PDUs, it should discarded.
- Finally, if vrUH is still larger than vrUR, the t-Reordering timer is restarted and vrUX is set equal to vrUH

The following happens in the simulator:

- Timer fires and ReorderingWindow::onTReorderingTimeout is called
- vrUR is correctly updated to 206
- updateReassemblyBuffer is called with the new vrUR as a parameter

- this function iterates over all PDUs in the reordering window (in this case, from SN 190 to 205) and attempts to pass them to the reassembly buffer
- this results in a call to onReorderedPDU() with the current PDU as a parameter
- this method first checks if this PDU is the nextExpectedPDU (which is not the case, the next expected is 189 which was lost)
- Because this is not the expected PDU, the reassembly buffer is emptied.
- It is then checked whether the current PDU can be accepted from the buffer - This is where the problem occurs:

- the function called is ReassemblyBuffer::accepts(PDU). This function returns "true" either if the buffer is empty _and_ the PDU's isBegin flag is set to true, or if the PDU is the next expected PDU (not the case). Since the buffer has been emptied, the only real factor is the isBegin flag. The transmitted PDUs are generated in the BS's scheduler by the SegmentingQueue. The actual function of interest is the retrieve() method of the InnerQueue (InnerQueue::retrieve()) after the getHeadOfLinePDUSegment function is called. In this retrieve function, one can see that the PDU's is begin flag is set to true only if a SDU begins right at the beginning of the PDU. However, this is not always the case (example - a PDU can contain the last bits of one SDU, and after that a new SDU could start; or a SDU can be split among multiple PDUs etc.). In fact, studying some of the simulation output it turns out that only a very small fraction of the PDUs begin with a new SDU an thus have their isBegin flag set. Back to the problem - from the PDUs with SNs from 190 to 205, none have their isBegin flag set. Therefore, all of them get rejected by the accepts() method, and are thus dropped by the reassembly buffer. As the BS transmitts with phymodes allowing ~330 to 550 bits per PDU, it is clear that the PDUs in the reordering window contain multiple SDUs that could have been reassembled. Furthermore, after the ReassemblyBuffer drops the first PDU (with SN = 190), the buffer is cleared and the nextExpectedPDU gets set to -1.
After this point, no more SDUs are reassemled by the SegAndConcat, even though there are multiple correct transmissions until the end of the simulation. Bellow is some output from the problem:

( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering onTReorderingExpired: (vrUR = 189 vrUX = 191)
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 191 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 192 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 193 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 194 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 195 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 196 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 197 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 198 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 199 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 200 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 201 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 202 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 203 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 204 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 205 is duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 206 is not duplicate
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering Moving segment 190 to reassembly Buffer
( 0.2559987) [ WNS] L2.SegAndConcat onReorderedPDU(sn=190):
( 0.2559987) [ WNS] L2.SegAndConcat onReorderedPDU: PDU 189 is missing. Clearing reassembly buffer.
( 0.2559987) [ WNS] L2.SegAndConcat onReorderedPDU: Dropping PDU 190. isBegin=False.
( 0.2559987) [ WNS] L2.SegAndConcat
( 0.2559987) [ WNS] L2.SegAndConcat reassemble: getReassembledSegments() sc.size()=0
( 0.2559987) [ WNS] L2.SegAndConcat.SegAndConcat.Reordering Moving segment 191 to reassembly Buffer
( 0.2559987) [ WNS] L2.SegAndConcat onReorderedPDU(sn=191):
( 0.2559987) [ WNS] L2.SegAndConcat onReorderedPDU: PDU -1 is missing. Clearing reassembly buffer.
( 0.2559987) [ WNS] L2.SegAndConcat onReorderedPDU: Dropping PDU 191. isBegin=False

... and so on up to PDU 205

I therefore have the following questions:
- Could this be a configuration issue which prevents the SegAndConcat unit from working correctly, or could this be a bug?
- In general, is it possible to use the combination of SegAndConcat and a Segmenting queue without any retransmission mechanism (HARQ), leaving aside the potentially higher packet loss?

Thank you for your time, any ideas would be greatly appreciated!

Best regards,

Boyan Lazarov, B.Sc
TU Muenchen

Related branches

Dear Boyan,

thank you for your good work. I also agree with you that you have found
a bug. Unfortunately, I do not have time at the moment to fix it myself,
but maybe you can contribute a fix if you like. I would propose the
following way forward:

1. Convert this question/answer thread to a bug report of openwns-library. (You have already done that, thanks!)

2. Extend the testcase src/ldk/sar/tests/SACSegmentingQueueIntegrationTest.cpp to actually provoke the error. It is quite easy to do. If you have a look at the source code you will find a test setup with the SegmentingQueue and the SegAndConcatFU. You can execute the test suite by:

cd tests/unit/unitTests
./openwns -t -v

or only execute the test above with:

cd tests/unit/unitTests
./openwns -t -v -T wns::ldk::sar::tests::SACSegmentingQueueIntegrationTest

3. Fix the bug ;) I think the following would be reasonable, but feel free to propose a better solution:

The starting point is void SegAndConcat::onReorderedPDU(). Probably you need to modify ReassemblyBuffer::isNextExpectedSegment() to accept a segment

  if (isEmpty() && (readCommand(c)->getBeginFlag() || readCommand(c)->peer.pdus_.size() > 1))

So, if the buffer is empty a new segment is accepted if the getBeginFlag
is set or if more than one sdu is contained within.

You will need to do the same with ReassemblyBuffer::accepts()

Furthermore, you will need to modify ReassemblyBuffer::insert(), such
that if the buffer is empty and the isBegin flag is not set:
  1) Assure that readCommand(c)->peer.pdus_.size() > 1
  2) Remove the head element of the pdus_ list,i.e. readCommand(c)->peer.pdus_.pop_front()
  3) Set the begin flag: readCommand(c)->setBeginFlag()
  4) Put the segment into the buffer

4. Check if this fixes the error and does not introduce new ones by executing the test suite.

5. Push your branch with the bugifx to launchpad and propose a merge. Me or Maciej will then merge it to the trunk.

Let me know if this is OK with you.

Thanks a lot,
  Daniel

Changed in openwns-library:
status: New → Confirmed
importance: Undecided → Medium
assignee: nobody → Boyan Lazarov (lazarov-b)
Changed in openwns-library:
status: Confirmed → In Progress
Jan (jan-ellenbeck) wrote :
Download full text (3.6 KiB)

In addition to the previously documented bug, we have identified another potential problem related to the t-Reordering timer.

In our simulations we observe that after the first expiration of the t-Reordering timer it won't be set again when another segment loss occurs.

Here, segment 0 is lost, segment 1 is received and triggers the t-Reordering timer for the first time.

 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering ReorderingWindow (snFieldLength=20, windowSize_ = 524288)
( 0.0519950) [ WNS] L2.SegAndConcat.SS18 SegAndConcat::onFUNCreated()
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: New segment 1 (vrUH_ = 0 vrUR_=0 vrUX_ = 0)
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isExpired: Segment 1 is not expired
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isConsideredForReordering: Segment 1 is not considered
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: New segment 1
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: Inserting New segment 1
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 1 is not in window
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: Updated vrUH_=2
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 0 is in window
( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: tReordering started (vrUX = 2)
[...]
later the t-Reordering timer expires and segments from 1 to 15, in this case, are moved to the reassembly buffer:
( 0.0659950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: finished (vrUH_ = 16 vrUR_=0 vrUX_ = 2)
( 0.0669950) [ WNS] L2.SegAndConcat.SS18.Reordering onTReorderingExpired: (vrUR = 0 vrUX = 2)

Now, if we lose another segment (number 16), the timer should be started again after segment 17 is received. However, this does not happen:

( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: New segment 17 (vrUH_ = 16 vrUR_=16 vrUX_ = 2)
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering isExpired: Segment 17 is not expired
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering isConsideredForReordering: Segment 17 is not considered
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: New segment 17
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: Inserting New segment 17
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 17 is not in window
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: Updated vrUH_=18
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 16 is in window
( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: finished (vrUH_ = 18 vrUR_=16 vrUX_ = 2)

We believe t...

Read more...

Download full text (4.6 KiB)

Dear Jan

I think I already had that issue fixed. I think the problem was that we
did store a handle to the queued event.
Check if you have the following, especially the line marked with -------->
void
ReorderingWindow::onTReorderingExpired()
{
    // 3GPP TS 36.322 Section 5.1.2.2.4 (V8.5.0 2009-03)
    MESSAGE_SINGLE(NORMAL, logger_, "onTReorderingExpired: (vrUR = " <<
vrUR_ << " vrUX = " << vrUX_ << ")");

    vrUR_ = nextMissingSegment(Segment(vrUX_ - 1,
wns::ldk::CompoundPtr())).sn();

    updateReassemblyBuffer(vrUR_);

    if (vrUH_ > vrUR_)
    {

--------> reorderingTimer_ =
wns::simulator::getEventScheduler()->scheduleDelay(boost::lambda::bind(&ReorderingWindow::onTReorderingExpired,
this), tReordering_);

        vrUX_ = vrUH_;

        MESSAGE_SINGLE(NORMAL, logger_, "onTReorderingExpired:
tReordering started (vrUX = " << vrUX_ << ")");

    }

}

Regards,
  Daniel

Jan wrote:
> In addition to the previously documented bug, we have identified another
> potential problem related to the t-Reordering timer.
>
> In our simulations we observe that after the first expiration of the
> t-Reordering timer it won't be set again when another segment loss
> occurs.
>
> Here, segment 0 is lost, segment 1 is received and triggers the
> t-Reordering timer for the first time.
>
> 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering ReorderingWindow (snFieldLength=20, windowSize_ = 524288)
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18 SegAndConcat::onFUNCreated()
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: New segment 1 (vrUH_ = 0 vrUR_=0 vrUX_ = 0)
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isExpired: Segment 1 is not expired
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isConsideredForReordering: Segment 1 is not considered
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: New segment 1
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: Inserting New segment 1
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 1 is not in window
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: Updated vrUH_=2
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 0 is in window
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: tReordering started (vrUX = 2)
> [...]
> later the t-Reordering timer expires and segments from 1 to 15, in this case, are moved to the reassembly buffer:
> ( 0.0659950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: finished (vrUH_ = 16 vrUR_=0 vrUX_ = 2)
> ( 0.0669950) [ WNS] L2.SegAndConcat.SS18.Reordering onTReorderingExpired: (vrUR = 0 vrUX = 2)
>
> Now, if we lose another segment (number 16), the timer should be started
> again after segment 17 is received. However, this does not happen:
>
> ( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: New segment 17...

Read more...

Jan (jan-ellenbeck) wrote :

Hi,

no, that part (reorderingTimer_ = wns::simulator::getEventScheduler()->scheduleDelay(...) is not yet included in the public branch at

http://bazaar.launchpad.net/%7Ecomnets/openwns-library/library--main--1.0/annotate/head%3A/src/ldk/sar/reassembly/ReorderingWindow.cpp

I currently don't think that this line alone makes a difference because you would still never reach the part where a new timer is set in line 170 in that file because reorderingTimer_ != wns::events::scheduler::IEventPtr() However, I guess it is needed for our patch to work properly. Did you already fix that as well?

Cheers
Jan

Jan (jan-ellenbeck) wrote :
Download full text (14.8 KiB)

While working on a unit test and a corresponding patch, we noticed a strange behavior of the SegmentingQueue and we are not sure if it is a bug or just a very advanced and undocumented feature ;-)

In the SACSegmentingQueueIntegrationTest with fixedHeaderSize = 16 and extensionHeaderSize = 8 we observe the following behavior:

1) Inserting PDUs into the queue: For every inserted PDU the gross ("brutto") bits are increased by an additional 16 bits for the first and 8 bits for every subsequent PDU. Is this supposed to be the fixedHeaderSize and the extensionHeader size, respectively?

2) When retrieving segments from the queue, the retrieved segment size is 16 bits bigger than the bits by which the gross queue size is decreased. E.g., if segmentingQueue_->getHeadOfLinePDUbits gives 330 bits, getHeadOfLinePDUSegment(cid=1,to=n/a,bits=126): totalSize=126 decreases this to 220, taking 110 (= 126 - 16?) bits out of the queue. This is always the case except for the situation when all (or more than available) bits are requested. In this case no additional 16 bits are added to the segment. See below for an example.

So the question would be: Is it a feature that for the last segment no header is added? Is it for a good reason that the fixed header size is used both for storing and retrieving and the extionsion header size is used only for storing subsequent PDUs?

( 0.0000000) [ WNS] SegAndConcat SegAndConcat::onFUNCreated()
( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::setFUN(): segmentHeaderCommandName=testee
( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=80/96, PDUs=1
( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=160/184, PDUs=2
( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=240/272, PDUs=3
( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=290/330, PDUs=4
segmentingQueue_->getHeadOfLinePDUbits: 330
( 0.0000000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=126): totalSize=126 bits, sn=0
segmentingQueue_->getHeadOfLinePDUbits: 220
( 0.0010000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=126): totalSize=126 bits, sn=1
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: New segment 1 (vrUH_ = 0 vrUR_=0 vrUX_ = 0)
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isExpired: Segment 1 is not expired
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isConsideredForReordering: Segment 1 is not considered
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: New segment 1
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: Inserting New segment 1
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 1 is not in window
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUH_=2
( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering i...

Download full text (15.7 KiB)

Dear Jan,

the idea is that if the scheduler asks for the number of queued bits,
the segmenting queue makes the assumption that the scheduler would
retrieve all the PDUs. So the headers that are added are
1x16 fixed part
(N-1)x8 extension if the number N of queued SDUs in larger than 1

If you request a certain number of bits the "actual" header sizes do
apply. The scheduler asks you for brutto bits, i.e. the segmenting
queue must include the headers.
1x16 always
(N-1)x8 if there fit more parts of an SDU (including the 8bit additional
header that would be needed)

Regards,
  Daniel

Jan wrote:
> While working on a unit test and a corresponding patch, we noticed a
> strange behavior of the SegmentingQueue and we are not sure if it is a
> bug or just a very advanced and undocumented feature ;-)
>
> In the SACSegmentingQueueIntegrationTest with fixedHeaderSize = 16 and
> extensionHeaderSize = 8 we observe the following behavior:
>
> 1) Inserting PDUs into the queue: For every inserted PDU the gross
> ("brutto") bits are increased by an additional 16 bits for the first and
> 8 bits for every subsequent PDU. Is this supposed to be the
> fixedHeaderSize and the extensionHeader size, respectively?
>
> 2) When retrieving segments from the queue, the retrieved segment size
> is 16 bits bigger than the bits by which the gross queue size is
> decreased. E.g., if segmentingQueue_->getHeadOfLinePDUbits gives 330
> bits, getHeadOfLinePDUSegment(cid=1,to=n/a,bits=126): totalSize=126
> decreases this to 220, taking 110 (= 126 - 16?) bits out of the queue.
> This is always the case except for the situation when all (or more than
> available) bits are requested. In this case no additional 16 bits are
> added to the segment. See below for an example.
>
> So the question would be: Is it a feature that for the last segment no
> header is added? Is it for a good reason that the fixed header size is
> used both for storing and retrieving and the extionsion header size is
> used only for storing subsequent PDUs?
>
>
> ( 0.0000000) [ WNS] SegAndConcat SegAndConcat::onFUNCreated()
> ( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::setFUN(): segmentHeaderCommandName=testee
> ( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=80/96, PDUs=1
> ( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=160/184, PDUs=2
> ( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=240/272, PDUs=3
> ( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=290/330, PDUs=4
> segmentingQueue_->getHeadOfLinePDUbits: 330
> ( 0.0000000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=126): totalSize=126 bits, sn=0
> segmentingQueue_->getHeadOfLinePDUbits: 220
> ( 0.0010000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=126): totalSize=126 bits, sn=1
> ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: New segment 1 (vrUH_ = 0 vrUR_=...

Download full text (4.1 KiB)

It seems that you are correct.

I think it would be best to include
....
    else
    {
        MESSAGE_SINGLE(VERBOSE, logger_, "onTReorderingExpired: Clearing
reorderingTimer handle");
        reorderingTimer_ = wns::events::scheduler::IEventPtr();
    }

in

void
ReorderingWindow::onTReorderingExpired()

What do you think?

Regards,
  Daniel

Jan wrote:
> In addition to the previously documented bug, we have identified another
> potential problem related to the t-Reordering timer.
>
> In our simulations we observe that after the first expiration of the
> t-Reordering timer it won't be set again when another segment loss
> occurs.
>
> Here, segment 0 is lost, segment 1 is received and triggers the
> t-Reordering timer for the first time.
>
> 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering ReorderingWindow (snFieldLength=20, windowSize_ = 524288)
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18 SegAndConcat::onFUNCreated()
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: New segment 1 (vrUH_ = 0 vrUR_=0 vrUX_ = 0)
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isExpired: Segment 1 is not expired
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isConsideredForReordering: Segment 1 is not considered
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: New segment 1
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: Inserting New segment 1
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 1 is not in window
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: Updated vrUH_=2
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering isWithinReorderingWindow: Segment 0 is in window
> ( 0.0519950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: tReordering started (vrUX = 2)
> [...]
> later the t-Reordering timer expires and segments from 1 to 15, in this case, are moved to the reassembly buffer:
> ( 0.0659950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: finished (vrUH_ = 16 vrUR_=0 vrUX_ = 2)
> ( 0.0669950) [ WNS] L2.SegAndConcat.SS18.Reordering onTReorderingExpired: (vrUR = 0 vrUX = 2)
>
> Now, if we lose another segment (number 16), the timer should be started
> again after segment 17 is received. However, this does not happen:
>
> ( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering onSegment: New segment 17 (vrUH_ = 16 vrUR_=16 vrUX_ = 2)
> ( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering isExpired: Segment 17 is not expired
> ( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering isConsideredForReordering: Segment 17 is not considered
> ( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: New segment 17
> ( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering insert: Inserting New segment 17
> ( 0.0679950) [ WNS] L2.SegAndConcat.SS18.Reordering ...

Read more...

Jan (jan-ellenbeck) wrote :

Daniel,

thanks for the explanation regarding the queue sizes and headers. Now it all makes sense :-)

Let's have a look at our example:

We add 4 PDUs A (80 bits), B (80 bits), C (80 bits), D (50 bits) to the queue and set the fixed header size to 16 and the extension header size to 8 bits.

What the queue shows is the "brutto" bits and they are computed taking one full header and 3 extension headers: (16 + 80) + (8 + 80) + (8 + 80) + (8 + 50) = 330 bits

So far so good.

When we take segments out, the first SDU is supposed to have a 16bit header and subsequent SDUs (fragments) in the same segment take an additional 8 bits.

Now we ask for the first 126 bits so we get (16 + 80) + (8 + 22) = 126 which
is the complete 80 bits of PDU A and 22 bits of PDU B with a fixed header and an extension header.

Now we ask for the next 126 bits and get (16 + 58) + (8 + 44) = 126
which is the remaining 58 bits of PDU B and the first 44 bits of PDU C again with a fixed header and an extension header.

Now we ask for the next 126 bits and get (16 + 36) + (8 + 50) = 110 bits
which is the rest of PDU C and the complete PDU D of only 50 bits again with a fixed header and an extension header.

Thanks
Jan

Jan,

your welcome. So behaviour is correct I suppose ;)

Regards,
  Daniel

Jan wrote:
> Daniel,
>
> thanks for the explanation regarding the queue sizes and headers. Now it
> all makes sense :-)
>
> Let's have a look at our example:
>
> We add 4 PDUs A (80 bits), B (80 bits), C (80 bits), D (50 bits) to the
> queue and set the fixed header size to 16 and the extension header size
> to 8 bits.
>
> What the queue shows is the "brutto" bits and they are computed taking
> one full header and 3 extension headers: (16 + 80) + (8 + 80) + (8 + 80)
> + (8 + 50) = 330 bits
>
> So far so good.
>
> When we take segments out, the first SDU is supposed to have a 16bit
> header and subsequent SDUs (fragments) in the same segment take an
> additional 8 bits.
>
> Now we ask for the first 126 bits so we get (16 + 80) + (8 + 22) = 126 which
> is the complete 80 bits of PDU A and 22 bits of PDU B with a fixed header and an extension header.
>
> Now we ask for the next 126 bits and get (16 + 58) + (8 + 44) = 126
> which is the remaining 58 bits of PDU B and the first 44 bits of PDU C again with a fixed header and an extension header.
>
> Now we ask for the next 126 bits and get (16 + 36) + (8 + 50) = 110 bits
> which is the rest of PDU C and the complete PDU D of only 50 bits again with a fixed header and an extension header.
>
> Thanks
> Jan
>
>

correction:

you're welcome....

Daniel Bültmann wrote:
> Jan,
>
> your welcome. So behaviour is correct I suppose ;)
>
> Regards,
> Daniel
>
> Jan wrote:
>
>> Daniel,
>>
>> thanks for the explanation regarding the queue sizes and headers. Now it
>> all makes sense :-)
>>
>> Let's have a look at our example:
>>
>> We add 4 PDUs A (80 bits), B (80 bits), C (80 bits), D (50 bits) to the
>> queue and set the fixed header size to 16 and the extension header size
>> to 8 bits.
>>
>> What the queue shows is the "brutto" bits and they are computed taking
>> one full header and 3 extension headers: (16 + 80) + (8 + 80) + (8 + 80)
>> + (8 + 50) = 330 bits
>>
>> So far so good.
>>
>> When we take segments out, the first SDU is supposed to have a 16bit
>> header and subsequent SDUs (fragments) in the same segment take an
>> additional 8 bits.
>>
>> Now we ask for the first 126 bits so we get (16 + 80) + (8 + 22) = 126 which
>> is the complete 80 bits of PDU A and 22 bits of PDU B with a fixed header and an extension header.
>>
>> Now we ask for the next 126 bits and get (16 + 58) + (8 + 44) = 126
>> which is the remaining 58 bits of PDU B and the first 44 bits of PDU C again with a fixed header and an extension header.
>>
>> Now we ask for the next 126 bits and get (16 + 36) + (8 + 50) = 110 bits
>> which is the rest of PDU C and the complete PDU D of only 50 bits again with a fixed header and an extension header.
>>
>> Thanks
>> Jan
>>
>>
>>
>
>

Changed in openwns-library:
status: In Progress → Fix Committed
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Related questions