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_=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 isWithinReorderingWindow: Segment 0 is in window > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: tReordering started (vrUX = 2) > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: finished (vrUH_ = 2 vrUR_=0 vrUX_ = 2) > segmentingQueue_->getHeadOfLinePDUbits: 110 > ( 0.0010000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=126): totalSize=110 bits, sn=2 > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: New segment 2 (vrUH_ = 2 vrUR_=0 vrUX_ = 2) > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isExpired: Segment 2 is not expired > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isConsideredForReordering: Segment 2 is not considered > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: New segment 2 > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: Inserting New segment 2 > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 2 is not in window > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUH_=3 > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 0 is in window > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 2 is in window > ( 0.0010000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: finished (vrUH_ = 3 vrUR_=0 vrUX_ = 2) > ( 0.0160000) [ WNS] SegAndConcat.SegAndConcat.Reordering onTReorderingExpired: (vrUR = 0 vrUX = 2) > ( 0.0160000) [ WNS] SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 2 is duplicate > ( 0.0160000) [ WNS] SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 3 is not duplicate > ( 0.0160000) [ WNS] SegAndConcat.SegAndConcat.Reordering Moving segment 1 to reassembly Buffer > ( 0.0160000) [ WNS] SegAndConcat onReorderedPDU(sn=1): > ( 0.0160000) [ WNS] SegAndConcat onReorderedPDU: Putting PDU 1 of size 126 bits into reassembly buffer > ( 0.0160000) [ WNS] SegAndConcat |(B)|1:( with id: 21,) > ( 0.0160000) [ WNS] SegAndConcat reassemble: getReassembledSegments() sc.size()=0 > ( 0.0160000) [ WNS] SegAndConcat.SegAndConcat.Reordering Moving segment 2 to reassembly Buffer > ( 0.0160000) [ WNS] SegAndConcat onReorderedPDU(sn=2): > ( 0.0160000) [ WNS] SegAndConcat onReorderedPDU: Putting PDU 2 of size 110 bits into reassembly buffer > ( 0.0160000) [ WNS] SegAndConcat |(B)|1:( with id: 21,) |(E)|2:( with id: 21, with id: 22,) > ( 0.0160000) [ WNS] SegAndConcat reassemble: getReassembledSegments() sc.size()=2 > ( 0.0160000) [ WNS] SegAndConcat reassemble: Passing 80 bits to upper FU. > ( 0.0160000) [ WNS] SegAndConcat reassemble: Passing 50 bits to upper FU. > > Another example (the > SACSegmentingQueueIntegrationTest::testIncomingFourSegments() test with > some debug printout) where you can see that 24 bits become 40 gross bits > in the queue. When 4 times 22 bits are taken out, the first 3 segments > contain 6 bits each and the last segment contains 22 bits: > > [TST] N3wns3ldk3sar5tests33SACSegmentingQueueIntegrationTestE::testIncomingFourSegments ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering ReorderingWindow (snFieldLength=10, windowSize_ = 512) > ( 0.0000000) [ WNS] SegAndConcat SegAndConcat::onFUNCreated() > ( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::setFUN(): segmentHeaderCommandName=testee > ( 0.0000000) [ WNS] SegmentingQueue SegmentingQueue::put(cid=1): after: bits=24/40, PDUs=1 > segmentingQueue_->getHeadOfLinePDUbits: 40 > ( 0.0000000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=22): totalSize=22 bits, sn=0 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: New segment 0 (vrUH_ = 0 vrUR_=0 vrUX_ = 0) > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isExpired: Segment 0 is not expired > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isConsideredForReordering: Segment 0 is not considered > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: New segment 0 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: Inserting New segment 0 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 0 is not in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUH_=1 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 0 is in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 1 is not duplicate > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUR_=1 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering Moving segment 0 to reassembly Buffer > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU(sn=0): > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU: Putting PDU 0 of size 22 bits into reassembly buffer > ( 0.0000000) [ WNS] SegAndConcat |(B)|1:( with id: 10,) > ( 0.0000000) [ WNS] SegAndConcat reassemble: getReassembledSegments() sc.size()=0 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: finished (vrUH_ = 1 vrUR_=1 vrUX_ = 0) > segmentingQueue_->getHeadOfLinePDUbits: 34 > ( 0.0000000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=22): totalSize=22 bits, sn=1 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: New segment 1 (vrUH_ = 1 vrUR_=1 vrUX_ = 0) > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isExpired: Segment 1 is not expired > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isConsideredForReordering: Segment 1 is not considered > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: New segment 1 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: Inserting New segment 1 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 1 is not in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUH_=2 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 1 is in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 2 is not duplicate > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUR_=2 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering Moving segment 1 to reassembly Buffer > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU(sn=1): > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU: Putting PDU 1 of size 22 bits into reassembly buffer > ( 0.0000000) [ WNS] SegAndConcat |(B)|1:( with id: 10,) |()|1:( with id: 10,) > ( 0.0000000) [ WNS] SegAndConcat reassemble: getReassembledSegments() sc.size()=0 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: finished (vrUH_ = 2 vrUR_=2 vrUX_ = 0) > segmentingQueue_->getHeadOfLinePDUbits: 28 > ( 0.0000000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=22): totalSize=22 bits, sn=2 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: New segment 2 (vrUH_ = 2 vrUR_=2 vrUX_ = 0) > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isExpired: Segment 2 is not expired > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isConsideredForReordering: Segment 2 is not considered > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: New segment 2 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: Inserting New segment 2 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 2 is not in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUH_=3 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 2 is in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 3 is not duplicate > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUR_=3 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering Moving segment 2 to reassembly Buffer > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU(sn=2): > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU: Putting PDU 2 of size 22 bits into reassembly buffer > ( 0.0000000) [ WNS] SegAndConcat |(B)|1:( with id: 10,) |()|1:( with id: 10,) |()|1:( with id: 10,) > ( 0.0000000) [ WNS] SegAndConcat reassemble: getReassembledSegments() sc.size()=0 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: finished (vrUH_ = 3 vrUR_=3 vrUX_ = 0) > segmentingQueue_->getHeadOfLinePDUbits: 22 > ( 0.0000000) [ WNS] SegmentingQueue getHeadOfLinePDUSegment(cid=1,to=n/a,bits=22): totalSize=22 bits, sn=3 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: New segment 3 (vrUH_ = 3 vrUR_=3 vrUX_ = 0) > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isExpired: Segment 3 is not expired > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isConsideredForReordering: Segment 3 is not considered > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: New segment 3 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering insert: Inserting New segment 3 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 3 is not in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUH_=4 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isWithinReorderingWindow: Segment 3 is in window > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering isDuplicate: Segment 4 is not duplicate > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: Updated vrUR_=4 > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering Moving segment 3 to reassembly Buffer > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU(sn=3): > ( 0.0000000) [ WNS] SegAndConcat onReorderedPDU: Putting PDU 3 of size 22 bits into reassembly buffer > ( 0.0000000) [ WNS] SegAndConcat |(B)|1:( with id: 10,) |()|1:( with id: 10,) |()|1:( with id: 10,) |(E)|1:( with id: 10,) > ( 0.0000000) [ WNS] SegAndConcat reassemble: getReassembledSegments() sc.size()=1 > ( 0.0000000) [ WNS] SegAndConcat reassemble: Passing 24 bits to upper FU. > ( 0.0000000) [ WNS] SegAndConcat.SegAndConcat.Reordering onSegment: finished (vrUH_ = 4 vrUR_=4 vrUX_ = 0) > no more bits for this CID in segmentingQueue > >