Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "SCTPReceiveStream.h"
00020 #include "SCTPAssociation.h"
00021
00022
00023 SCTPReceiveStream::SCTPReceiveStream()
00024 {
00025 streamId = 0;
00026 expectedStreamSeqNum = 0;
00027 deliveryQ = new SCTPQueue();
00028 orderedQ = new SCTPQueue();
00029 unorderedQ = new SCTPQueue();
00030 }
00031
00032 SCTPReceiveStream::~SCTPReceiveStream()
00033 {
00034 delete deliveryQ;
00035 delete orderedQ;
00036 delete unorderedQ;
00037 }
00038
00039 uint32 SCTPReceiveStream::reassemble(SCTPQueue* queue, uint32 tsn)
00040 {
00041 uint32 begintsn = tsn, endtsn = 0;
00042
00043 sctpEV3 << "Trying to reassemble message..." << endl;
00044
00045
00046 while (orderedQ->getChunk(begintsn) && !(orderedQ->getChunk(begintsn))->bbit)
00047 begintsn--;
00048
00049 if (orderedQ->getChunk(begintsn))
00050 {
00051 endtsn = begintsn;
00052
00053
00054 while (orderedQ->getChunk(endtsn) && !(orderedQ->getChunk(endtsn))->ebit)
00055 endtsn++;
00056
00057 if (orderedQ->getChunk(endtsn))
00058 {
00059 sctpEV3 << "All fragments found, now reassembling..." << endl;
00060
00061 SCTPDataVariables *firstVar = orderedQ->getChunk(begintsn), *processVar;
00062 SCTPSimpleMessage* firstSimple=check_and_cast<SCTPSimpleMessage*>(firstVar->userData);
00063
00064 sctpEV3 << "First fragment has " << firstVar->len / 8 << " bytes." << endl;
00065
00066 while (++begintsn <= endtsn)
00067 {
00068 processVar = orderedQ->getAndExtractChunk(begintsn);
00069 SCTPSimpleMessage* processSimple=check_and_cast<SCTPSimpleMessage*>(processVar->userData);
00070
00071 sctpEV3 << "Adding fragment with " << processVar->len / 8 << " bytes." << endl;
00072
00073 firstSimple->setDataArraySize(firstSimple->getDataArraySize() + processSimple->getDataArraySize());
00074 firstSimple->setDataLen(firstSimple->getDataLen() + processSimple->getDataLen());
00075 firstSimple->setByteLength(firstSimple->getByteLength() + processSimple->getByteLength());
00076
00077 for (uint32 i = 0; i < (processVar->len / 8); i++)
00078 firstSimple->setData(i + (firstVar->len / 8), processSimple->getData(i));
00079
00080 firstVar->len += processVar->len;
00081
00082 delete processVar->userData;
00083 delete processVar;
00084 }
00085
00086 firstVar->ebit = 1;
00087
00088 sctpEV3 << "Reassembly done. Length=" << firstVar->len<<"\n";
00089 return firstVar->tsn;
00090 }
00091 }
00092 return tsn;
00093 }
00094
00095
00096 uint32 SCTPReceiveStream::enqueueNewDataChunk(SCTPDataVariables* dchunk)
00097 {
00098 uint32 delivery = 0;
00099
00100 SCTPDataVariables* chunk;
00101
00102
00103 if (!dchunk->ordered)
00104 {
00105 if (dchunk->bbit && dchunk->ebit)
00106 {
00107
00108 if (deliveryQ->checkAndInsertChunk(dchunk->tsn, dchunk))
00109 {
00110 delivery = 2;
00111 }
00112 } else {
00113 unorderedQ->checkAndInsertChunk(dchunk->tsn, dchunk);
00114 delivery = 3;
00115
00116
00117 uint32 reassembled = reassemble(unorderedQ, dchunk->tsn);
00118
00119 if ((unorderedQ->getChunk(reassembled))->bbit && (unorderedQ->getChunk(reassembled))->bbit)
00120 {
00121
00122 if (deliveryQ->checkAndInsertChunk(reassembled, unorderedQ->getAndExtractChunk(reassembled)))
00123 {
00124 delivery = 2;
00125 }
00126 }
00127 }
00128 }
00129 else if (dchunk->ordered)
00130 {
00131
00132 if (orderedQ->checkAndInsertChunk(dchunk->tsn, dchunk))
00133 delivery = 1;
00134
00135 if (!dchunk->bbit || !dchunk->ebit)
00136 {
00137 delivery = 3;
00138
00139 reassemble(orderedQ, dchunk->tsn);
00140 }
00141
00142 if (orderedQ->getQueueSize()>0)
00143 {
00144
00145 chunk = orderedQ->dequeueChunkBySSN(expectedStreamSeqNum);
00146 if (chunk)
00147 {
00148 if (deliveryQ->checkAndInsertChunk(chunk->tsn, chunk))
00149 {
00150 ++expectedStreamSeqNum;
00151 if (expectedStreamSeqNum > 65535)
00152 expectedStreamSeqNum = 0;
00153 delivery = 2;
00154 }
00155 }
00156 }
00157 }
00158
00159 return delivery;
00160 }