INET Framework for OMNeT++/OMNEST
inet::sctp::SctpReceiveStream Class Reference

#include <SctpReceiveStream.h>

Inheritance diagram for inet::sctp::SctpReceiveStream:

Public Member Functions

uint32_t enqueueNewDataChunk (SctpDataVariables *dchunk)
 
 SctpReceiveStream (SctpAssociation *assoc)
 Ctor. More...
 
int32_t getExpectedStreamSeqNum ()
 
void setExpectedStreamSeqNum (int32_t num)
 
 ~SctpReceiveStream ()
 Virtual dtor. More...
 
SctpQueuegetDeliveryQ () const
 
SctpQueuegetOrderedQ () const
 
SctpQueuegetUnorderedQ () const
 
int32_t getStreamId () const
 
void setStreamId (const uint16_t id)
 

Protected Member Functions

uint32_t reassemble (SctpQueue *queue, uint32_t tsn)
 

Protected Attributes

SctpAssociationassoc
 
uint16_t streamId
 
int32_t expectedStreamSeqNum
 
SctpQueuedeliveryQ
 
SctpQueueorderedQ
 
SctpQueueunorderedQ
 

Constructor & Destructor Documentation

◆ SctpReceiveStream()

inet::sctp::SctpReceiveStream::SctpReceiveStream ( SctpAssociation assoc)

Ctor.

18 {
19  streamId = 0;
21  deliveryQ = new SctpQueue();
22  orderedQ = new SctpQueue();
23  unorderedQ = new SctpQueue();
24  assoc = assoc_;
25 }

◆ ~SctpReceiveStream()

inet::sctp::SctpReceiveStream::~SctpReceiveStream ( )

Virtual dtor.

28 {
29  delete deliveryQ;
30  delete orderedQ;
31  delete unorderedQ;
32 }

Member Function Documentation

◆ enqueueNewDataChunk()

uint32_t inet::sctp::SctpReceiveStream::enqueueNewDataChunk ( SctpDataVariables dchunk)
90 {
91  uint32_t delivery = 0; // 0:orderedQ=false && deliveryQ=false; 1:orderedQ=true && deliveryQ=false; 2:oderedQ=true && deliveryQ=true; 3:fragment
92 
93  SctpDataVariables *chunk;
94  /* Enqueueing NEW data chunk. Append it to the respective queue */
95 
96  // ====== Unordered delivery =============================================
97  if (!dchunk->ordered) {
98  if (dchunk->bbit && dchunk->ebit) {
99  /* put message into deliveryQ */
100  if (deliveryQ->checkAndInsertChunk(dchunk->tsn, dchunk)) {
101  delivery = 2;
102  }
103  }
104  else {
105  if (unorderedQ->checkAndInsertChunk(dchunk->tsn, dchunk)) {
106  delivery = 3;
107  }
108 
109  /* try to reassemble here */
110  uint32_t reassembled = reassemble(unorderedQ, dchunk->tsn);
111 
112  if ((unorderedQ->getChunk(reassembled))->bbit && (unorderedQ->getChunk(reassembled))->bbit) { // FIXME There are identical sub-expressions '(unorderedQ->getChunk(reassembled))->bbit' to the left and to the right of the '&&' operator.
113  /* put message into deliveryQ */
114  if (deliveryQ->checkAndInsertChunk(reassembled, unorderedQ->getAndExtractChunk(reassembled))) {
115  delivery = 2;
116  }
117  }
118  }
119  }
120  // ====== Ordered delivery ===============================================
121  else if (dchunk->ordered) {
122  /* put message into orderedQ */
123  if (orderedQ->checkAndInsertChunk(dchunk->tsn, dchunk))
124  delivery = 1;
125 
126  if (!dchunk->bbit || !dchunk->ebit) {
127  delivery = 3;
128  /* try to reassemble */
129  reassemble(orderedQ, dchunk->tsn);
130  }
131 
132  if (orderedQ->getQueueSize() > 0) {
133  /* dequeue first from orderedQ */
135  if (chunk) {
136  if (deliveryQ->checkAndInsertChunk(chunk->tsn, chunk)) {
138  if (expectedStreamSeqNum > 65535)
140  delivery = 2;
141  }
142  }
143  }
144  }
145 
146  return delivery;
147 }

◆ getDeliveryQ()

◆ getExpectedStreamSeqNum()

int32_t inet::sctp::SctpReceiveStream::getExpectedStreamSeqNum ( )

◆ getOrderedQ()

◆ getStreamId()

int32_t inet::sctp::SctpReceiveStream::getStreamId ( ) const
inline

◆ getUnorderedQ()

SctpQueue* inet::sctp::SctpReceiveStream::getUnorderedQ ( ) const
inline

◆ reassemble()

uint32_t inet::sctp::SctpReceiveStream::reassemble ( SctpQueue queue,
uint32_t  tsn 
)
protected
35 {
36  uint32_t begintsn = tsn, endtsn = 0;
37 
38  EV_INFO << "Trying to reassemble message..." << endl;
39 
40  /* test if we have all fragments down to the first */
41  while (queue->getChunk(begintsn) && !(queue->getChunk(begintsn))->bbit)
42  begintsn--;
43 
44  if (queue->getChunk(begintsn)) {
45  endtsn = begintsn;
46 
47  /* test if we have all fragments up to the end */
48  while (queue->getChunk(endtsn) && !(queue->getChunk(endtsn))->ebit)
49  endtsn++;
50 
51  if (queue->getChunk(endtsn)) {
52  EV_INFO << "All fragments found, now reassembling..." << endl;
53 
54  SctpDataVariables *firstVar = queue->getChunk(begintsn), *processVar;
55  SctpSimpleMessage *firstSimple = check_and_cast<SctpSimpleMessage *>(firstVar->userData);
56 
57  EV_INFO << "First fragment has " << firstVar->len / 8 << " bytes." << endl;
58 
59  while (++begintsn <= endtsn) {
60  processVar = queue->getAndExtractChunk(begintsn);
61  SctpSimpleMessage *processSimple = check_and_cast<SctpSimpleMessage *>(processVar->userData);
62 
63  EV_INFO << "Adding fragment with " << processVar->len / 8 << " bytes." << endl;
64 
65  if ((firstSimple->getDataArraySize() > 0) && (processSimple->getDataArraySize() > 0)) {
66  firstSimple->setDataArraySize(firstSimple->getDataArraySize() + processSimple->getDataArraySize());
67  firstSimple->setDataLen(firstSimple->getDataLen() + processSimple->getDataLen());
68  firstSimple->setByteLength(firstSimple->getByteLength() + processSimple->getByteLength());
69  /* copy data */
70  for (uint32_t i = 0; i < (processVar->len / 8); i++)
71  firstSimple->setData(i + (firstVar->len / 8), processSimple->getData(i));
72  }
73 
74  firstVar->len += processVar->len;
75 
76  delete processVar->userData;
77  delete processVar;
78  }
79 
80  firstVar->ebit = 1;
81 
82  EV_INFO << "Reassembly done. Length=" << firstVar->len << "\n";
83  return firstVar->tsn;
84  }
85  }
86  return tsn;
87 }

Referenced by enqueueNewDataChunk().

◆ setExpectedStreamSeqNum()

void inet::sctp::SctpReceiveStream::setExpectedStreamSeqNum ( int32_t  num)

◆ setStreamId()

void inet::sctp::SctpReceiveStream::setStreamId ( const uint16_t  id)
inline

Member Data Documentation

◆ assoc

SctpAssociation* inet::sctp::SctpReceiveStream::assoc
protected

Referenced by SctpReceiveStream().

◆ deliveryQ

SctpQueue* inet::sctp::SctpReceiveStream::deliveryQ
protected

◆ expectedStreamSeqNum

int32_t inet::sctp::SctpReceiveStream::expectedStreamSeqNum
protected

◆ orderedQ

SctpQueue* inet::sctp::SctpReceiveStream::orderedQ
protected

◆ streamId

uint16_t inet::sctp::SctpReceiveStream::streamId
protected

Referenced by SctpReceiveStream().

◆ unorderedQ

SctpQueue* inet::sctp::SctpReceiveStream::unorderedQ
protected

The documentation for this class was generated from the following files:
inet::sctp::SctpQueue::getChunk
SctpDataVariables * getChunk(const uint32_t key) const
Definition: SctpQueue.cc:111
inet::sctp::SctpReceiveStream::assoc
SctpAssociation * assoc
Definition: SctpReceiveStream.h:20
inet::sctp::SctpQueue::getAndExtractChunk
SctpDataVariables * getAndExtractChunk(const uint32_t tsn)
Definition: SctpQueue.cc:65
inet::sctp::SctpReceiveStream::streamId
uint16_t streamId
Definition: SctpReceiveStream.h:21
inet::sctp::SctpReceiveStream::deliveryQ
SctpQueue * deliveryQ
Definition: SctpReceiveStream.h:23
inet::sctp::SctpReceiveStream::orderedQ
SctpQueue * orderedQ
Definition: SctpReceiveStream.h:24
inet::sctp::SctpQueue::checkAndInsertChunk
bool checkAndInsertChunk(const uint32_t key, SctpDataVariables *chunk)
Definition: SctpQueue.cc:39
inet::sctp::SctpQueue::dequeueChunkBySSN
SctpDataVariables * dequeueChunkBySSN(const uint16_t ssn)
Definition: SctpQueue.cc:173
inet::sctp::SctpReceiveStream::expectedStreamSeqNum
int32_t expectedStreamSeqNum
Definition: SctpReceiveStream.h:22
inet::sctp::SctpReceiveStream::reassemble
uint32_t reassemble(SctpQueue *queue, uint32_t tsn)
Definition: SctpReceiveStream.cc:34
inet::sctp::SctpQueue::getQueueSize
uint32_t getQueueSize() const
Definition: SctpQueue.cc:49
inet::sctp::SctpReceiveStream::unorderedQ
SctpQueue * unorderedQ
Definition: SctpReceiveStream.h:25