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