|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2004 Andras Varga 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public License 00015 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 00019 #include "TCPMsgBasedSendQueue.h" 00020 00021 Register_Class(TCPMsgBasedSendQueue); 00022 00023 TCPMsgBasedSendQueue::TCPMsgBasedSendQueue() : TCPSendQueue() 00024 { 00025 begin = end = 0; 00026 } 00027 00028 TCPMsgBasedSendQueue::~TCPMsgBasedSendQueue() 00029 { 00030 for (PayloadQueue::iterator it=payloadQueue.begin(); it!=payloadQueue.end(); ++it) 00031 delete it->msg; 00032 } 00033 00034 void TCPMsgBasedSendQueue::init(uint32 startSeq) 00035 { 00036 begin = startSeq; 00037 end = startSeq; 00038 } 00039 00040 std::string TCPMsgBasedSendQueue::info() const 00041 { 00042 std::stringstream out; 00043 out << "[" << begin << ".." << end << "), " << payloadQueue.size() << " packets"; 00044 return out.str(); 00045 } 00046 00047 void TCPMsgBasedSendQueue::enqueueAppData(cPacket *msg) 00048 { 00049 //tcpEV << "sendQ: " << info() << " enqueueAppData(bytes=" << msg->getByteLength() << ")\n"; 00050 end += msg->getByteLength(); 00051 00052 Payload payload; 00053 payload.endSequenceNo = end; 00054 payload.msg = msg; 00055 payloadQueue.push_back(payload); 00056 } 00057 00058 uint32 TCPMsgBasedSendQueue::getBufferStartSeq() 00059 { 00060 return begin; 00061 } 00062 00063 uint32 TCPMsgBasedSendQueue::getBufferEndSeq() 00064 { 00065 return end; 00066 } 00067 00068 TCPSegment *TCPMsgBasedSendQueue::createSegmentWithBytes(uint32 fromSeq, ulong numBytes) 00069 { 00070 //tcpEV << "sendQ: " << info() << " createSeg(seq=" << fromSeq << " len=" << numBytes << ")\n"; 00071 ASSERT(seqLE(begin,fromSeq) && seqLE(fromSeq+numBytes,end)); 00072 00073 TCPSegment *tcpseg = conn->createTCPSegment(NULL); 00074 tcpseg->setSequenceNo(fromSeq); 00075 tcpseg->setPayloadLength(numBytes); 00076 00077 // add payload messages whose endSequenceNo is between fromSeq and fromSeq+numBytes 00078 PayloadQueue::iterator i = payloadQueue.begin(); 00079 while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, fromSeq)) 00080 ++i; 00081 uint32 toSeq = fromSeq+numBytes; 00082 const char *payloadName = NULL; 00083 while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, toSeq)) 00084 { 00085 if (!payloadName) payloadName = i->msg->getName(); 00086 tcpseg->addPayloadMessage(i->msg->dup(), i->endSequenceNo); 00087 ++i; 00088 } 00089 00090 // give segment a name 00091 char msgname[80]; 00092 if (!payloadName) 00093 sprintf(msgname, "tcpseg(l=%lu,%dmsg)", numBytes, tcpseg->getPayloadArraySize()); 00094 else 00095 sprintf(msgname, "%.10s(l=%lu,%dmsg)", payloadName, numBytes, tcpseg->getPayloadArraySize()); 00096 tcpseg->setName(msgname); 00097 00098 return tcpseg; 00099 } 00100 00101 void TCPMsgBasedSendQueue::discardUpTo(uint32 seqNum) 00102 { 00103 //tcpEV << "sendQ: " << info() << " discardUpTo(seq=" << seqNum << ")\n"; 00104 ASSERT(seqLE(begin,seqNum) && seqLE(seqNum,end)); 00105 begin = seqNum; 00106 00107 // remove payload messages whose endSequenceNo is below seqNum 00108 while (!payloadQueue.empty() && seqLE(payloadQueue.front().endSequenceNo, seqNum)) 00109 { 00110 delete payloadQueue.front().msg; 00111 payloadQueue.pop_front(); 00112 } 00113 } 00114