SCTPQueue.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2005-2009 Irene Ruengeler
00003 // Copyright (C) 2009-2010 Thomas Dreibholz
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00017 //
00018 
00019 
00020 #include "SCTPQueue.h"
00021 #include "SCTPAssociation.h"
00022 
00023 Register_Class(SCTPQueue);
00024 
00025 
00026 SCTPQueue::SCTPQueue()
00027 {
00028     assoc = NULL;
00029 }
00030 
00031 SCTPQueue::~SCTPQueue()
00032 {
00033     for (PayloadQueue::iterator iterator = payloadQueue.begin();
00034           iterator != payloadQueue.end(); iterator++) {
00035         SCTPDataVariables* chunk = iterator->second;
00036         delete chunk->userData;
00037     }
00038     if (!payloadQueue.empty()) {
00039         payloadQueue.clear();
00040     }
00041 }
00042 
00043 bool SCTPQueue::checkAndInsertChunk(const uint32 key, SCTPDataVariables* chunk)
00044 {
00045     PayloadQueue::iterator found = payloadQueue.find(key);
00046     if (found != payloadQueue.end()) {
00047         return false;
00048     }
00049     payloadQueue[key] = chunk;
00050     return true;
00051 }
00052 
00053 uint32 SCTPQueue::getQueueSize() const
00054 {
00055     return payloadQueue.size();
00056 }
00057 
00058 SCTPDataVariables* SCTPQueue::extractMessage()
00059 {
00060     if (!payloadQueue.empty()) {
00061         PayloadQueue::iterator iterator = payloadQueue.begin();
00062         SCTPDataVariables*    chunk   = iterator->second;
00063         payloadQueue.erase(iterator);
00064         return chunk;
00065     }
00066     return NULL;
00067 }
00068 
00069 SCTPDataVariables* SCTPQueue::getAndExtractChunk(const uint32 tsn)
00070 {
00071     if (!payloadQueue.empty()) {
00072         PayloadQueue::iterator iterator = payloadQueue.find(tsn);
00073         SCTPDataVariables*    chunk   = iterator->second;
00074         payloadQueue.erase(iterator);
00075         return chunk;
00076     }
00077     return NULL;
00078 }
00079 
00080 void SCTPQueue::printQueue() const
00081 {
00082     sctpEV3 << "Queue contents:\n";
00083     for (PayloadQueue::const_iterator iterator = payloadQueue.begin();
00084           iterator != payloadQueue.end(); ++iterator) {
00085         const uint32                 key     = iterator->first;
00086         const SCTPDataVariables* chunk = iterator->second;
00087         sctpEV3 << key << ":\t"
00088                   << "lastDestination="             << chunk->getLastDestination()
00089                   << " nextDestination="            << chunk->getNextDestination()
00090                   << " hasBeenAcked="               << chunk->hasBeenAcked
00091                   << " countsAsOutstanding="        << chunk->countsAsOutstanding
00092                   << " numberOfRetransmissions=" << chunk->numberOfRetransmissions
00093                   << endl;
00094     }
00095     sctpEV3 << endl;
00096 }
00097 
00098 SCTPDataVariables* SCTPQueue::getFirstChunk() const
00099 {
00100     PayloadQueue::const_iterator iterator = payloadQueue.begin();
00101     SCTPDataVariables* chunk                  = iterator->second;
00102     return chunk;
00103 }
00104 
00105 cMessage* SCTPQueue::getMsg(const uint32 tsn) const
00106 {
00107     PayloadQueue::const_iterator iterator = payloadQueue.find(tsn);
00108     if (iterator != payloadQueue.end()) {
00109         SCTPDataVariables* chunk = iterator->second;
00110         cMessage* msg = check_and_cast<cMessage*>(chunk->userData);
00111         return msg;
00112     }
00113     return NULL;
00114 }
00115 
00116 SCTPDataVariables* SCTPQueue::getChunk(const uint32 tsn) const
00117 {
00118     PayloadQueue::const_iterator iterator = payloadQueue.find(tsn);
00119     if (iterator != payloadQueue.end()) {
00120         SCTPDataVariables* chunk = iterator->second;
00121         return chunk;
00122     }
00123     return NULL;
00124 }
00125 
00126 SCTPDataVariables* SCTPQueue::getChunkFast(const uint32 tsn, bool& firstTime)
00127 {
00128     if(!firstTime) {
00129         if(GetChunkFastIterator != payloadQueue.end()) {
00130             SCTPDataVariables* chunk = GetChunkFastIterator->second;
00131             if(chunk->tsn == tsn) {
00132                 GetChunkFastIterator++;
00133                 return(chunk);    // Found the right TSN!
00134             }
00135         }
00136         // TSN not found -> needs regular TSN lookup.
00137     }
00138 
00139     GetChunkFastIterator = payloadQueue.find(tsn);
00140     if(GetChunkFastIterator != payloadQueue.end()) {
00141         SCTPDataVariables* chunk = GetChunkFastIterator->second;
00142         GetChunkFastIterator++;
00143         firstTime = false;
00144         return(chunk);
00145     }
00146 
00147     return(NULL);
00148 }
00149 
00150 
00151 void SCTPQueue::removeMsg(const uint32 tsn)
00152 {
00153     PayloadQueue::iterator iterator = payloadQueue.find(tsn);
00154     payloadQueue.erase(iterator);
00155 }
00156 
00157 bool SCTPQueue::deleteMsg(const uint32 tsn)
00158 {
00159     PayloadQueue::iterator iterator = payloadQueue.find(tsn);
00160     if (iterator != payloadQueue.end())
00161     {
00162         SCTPDataVariables* chunk = iterator->second;
00163         cMessage* msg = check_and_cast<cMessage*>(chunk->userData);
00164         delete msg;
00165         payloadQueue.erase(iterator);
00166         return true;
00167     }
00168     return false;
00169 }
00170 
00171 int32 SCTPQueue::getNumBytes() const
00172 {
00173     int32 qb = 0;
00174     for (PayloadQueue::const_iterator iterator = payloadQueue.begin();
00175           iterator != payloadQueue.end(); iterator++) {
00176         qb += (iterator->second->len / 8);
00177     }
00178     return qb;
00179 }
00180 
00181 SCTPDataVariables* SCTPQueue::dequeueChunkBySSN(const uint16 ssn)
00182 {
00183     for (PayloadQueue::iterator iterator = payloadQueue.begin();
00184           iterator != payloadQueue.end(); iterator++) {
00185         SCTPDataVariables* chunk = iterator->second;
00186         if ((iterator->second->ssn == ssn) &&
00187              (iterator->second->bbit) &&
00188              (iterator->second->ebit) ) {
00189             payloadQueue.erase(iterator);
00190             return chunk;
00191         }
00192     }
00193     return NULL;
00194 }
00195 
00196