|
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_old.h" 00020 00021 using namespace tcp_old; 00022 00023 Register_Class(TCPMsgBasedSendQueue); 00024 00025 TCPMsgBasedSendQueue::TCPMsgBasedSendQueue() : TCPSendQueue() 00026 { 00027 begin = end = 0; 00028 } 00029 00030 TCPMsgBasedSendQueue::~TCPMsgBasedSendQueue() 00031 { 00032 for (PayloadQueue::iterator it=payloadQueue.begin(); it!=payloadQueue.end(); ++it) 00033 delete it->msg; 00034 } 00035 00036 void TCPMsgBasedSendQueue::init(uint32 startSeq) 00037 { 00038 begin = startSeq; 00039 end = startSeq; 00040 } 00041 00042 std::string TCPMsgBasedSendQueue::info() const 00043 { 00044 std::stringstream out; 00045 out << "[" << begin << ".." << end << "), " << payloadQueue.size() << " packets"; 00046 return out.str(); 00047 } 00048 00049 void TCPMsgBasedSendQueue::enqueueAppData(cPacket *msg) 00050 { 00051 //tcpEV << "sendQ: " << info() << " enqueueAppData(bytes=" << msg->getByteLength() << ")\n"; 00052 end += msg->getByteLength(); 00053 00054 Payload payload; 00055 payload.endSequenceNo = end; 00056 payload.msg = msg; 00057 payloadQueue.push_back(payload); 00058 } 00059 00060 uint32 TCPMsgBasedSendQueue::getBufferStartSeq() 00061 { 00062 return begin; 00063 } 00064 00065 uint32 TCPMsgBasedSendQueue::getBufferEndSeq() 00066 { 00067 return end; 00068 } 00069 00070 TCPSegment *TCPMsgBasedSendQueue::createSegmentWithBytes(uint32 fromSeq, ulong numBytes) 00071 { 00072 //tcpEV << "sendQ: " << info() << " createSeg(seq=" << fromSeq << " len=" << numBytes << ")\n"; 00073 ASSERT(seqLE(begin,fromSeq) && seqLE(fromSeq+numBytes,end)); 00074 00075 TCPSegment *tcpseg = conn->createTCPSegment(NULL); 00076 tcpseg->setSequenceNo(fromSeq); 00077 tcpseg->setPayloadLength(numBytes); 00078 00079 // add payload messages whose endSequenceNo is between fromSeq and fromSeq+numBytes 00080 PayloadQueue::iterator i = payloadQueue.begin(); 00081 while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, fromSeq)) 00082 ++i; 00083 uint32 toSeq = fromSeq+numBytes; 00084 const char *payloadName = NULL; 00085 while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, toSeq)) 00086 { 00087 if (!payloadName) payloadName = i->msg->getName(); 00088 tcpseg->addPayloadMessage(i->msg->dup(), i->endSequenceNo); 00089 ++i; 00090 } 00091 00092 // give segment a name 00093 char msgname[80]; 00094 if (!payloadName) 00095 sprintf(msgname, "tcpseg(l=%lu,%dmsg)", numBytes, tcpseg->getPayloadArraySize()); 00096 else 00097 sprintf(msgname, "%.10s(l=%lu,%dmsg)", payloadName, numBytes, tcpseg->getPayloadArraySize()); 00098 tcpseg->setName(msgname); 00099 00100 return tcpseg; 00101 } 00102 00103 void TCPMsgBasedSendQueue::discardUpTo(uint32 seqNum) 00104 { 00105 //tcpEV << "sendQ: " << info() << " discardUpTo(seq=" << seqNum << ")\n"; 00106 ASSERT(seqLE(begin,seqNum) && seqLE(seqNum,end)); 00107 begin = seqNum; 00108 00109 // remove payload messages whose endSequenceNo is below seqNum 00110 while (!payloadQueue.empty() && seqLE(payloadQueue.front().endSequenceNo, seqNum)) 00111 { 00112 delete payloadQueue.front().msg; 00113 payloadQueue.pop_front(); 00114 } 00115 } 00116