📄 integrated_agent.cc
字号:
/* Copyright (c) University of Maryland, Baltimore County, 2003.
* Original Authors: Ramakrishna Shenai, Sunil Gowda and Krishna Sivalingam.
*
* This software is developed at the University of Maryland, Baltimore County under
* grants from Cisco Systems Inc and the University of Maryland, Baltimore County.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation in source and binary forms for non-commercial purposes
* and without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both the copyright notice and
* this permission notice appear in supporting documentation. and that
* any documentation, advertising materials, and other materials related
* to such distribution and use acknowledge that the software was
* developed by the University of Maryland, Baltimore County. The name of
* the University may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Copyright (C) 2000-2003 Washington State University. All rights reserved.
* This software was originally developed at Alcatel USA and subsequently modified
* at Washington State University, Pullman, WA through research work which was
* supported by Alcatel USA, Inc and Cisco Systems Inc.
* The following notice is in adherence to the Washington State University
* copyright policy follows.
*
* License is granted to copy, to use, and to make and to use derivative
* works for research and evaluation purposes, provided that Washington
* State University is acknowledged in all documentation pertaining to any such
* copy or derivative work. Washington State University grants no other
* licenses expressed or implied. The Washington State University name
* should not be used in any advertising without its written permission.
*
* WASHINGTON STATE UNIVERSITY MAKES NO REPRESENTATIONS CONCERNING EITHER
* THE MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
* FOR ANY PARTICULAR PURPOSE. The software is provided "as is"
* without express or implied warranty of any kind. These notices must
* be retained in any copies of any part of this software.
*/
#include "integrated_agent.h"
#include "./debug.h"
/* Default initial values for static variables */
int hdr_IPKT::offset_ipkt_;
unsigned long BurstManager::burstid__ = 0;
int BurstManager::maxburstsize__ = 1000; // 1000
int BurstManager::pcntguard__ = 0;
//GMG -- changed initialization of offsettime__ to array initialization; note that must change this
// if #QoS classes (nqos_classes) is changed
double BurstManager::offsettime__[] = { 0.000010, 0.000010, 0.000010, 0.000010, 0.000010 };
double BurstManager::burst_timeout__ = 0.01; // 0.1
double BurstManager::delta__ = 0.00001;
/*=====================================================================*
* *
* Implementation of the Burst-manager class *
* *
*=====================================================================*/
/* Constructs a new BurstManager */
BurstManager::BurstManager() : bt_(this),
currburstsize_(0), npkts_(0), a_(NULL), destnodeid_(-1)
{
for ( int i = 0 ; i < MAXBURSTSIZE ; i++ )
BurstBuffer_[i] = NULL;
}
/* Init method, intended to be called by the parent IPKT Agent.
* parent - reference to the initializing IPKT Agent
* destnodeid - the default destination node identifier
*/
void BurstManager::init( IPKTAgent* parent,int destnodeid, int priority )
{
a_ = parent;
destnodeid_ = destnodeid;
prio_ = priority;
}
/* Support - method 1 - Calculates the number of hops between the source
* and destination.
* src - the source address
* des - the destination address
* returns the number of hops in the burst manager */
int BurstManager::nhops(nsaddr_t src,nsaddr_t des)
{
Tcl& tcl = Tcl::instance();
sprintf(tcl.buffer(),"[Simulator instance] nhops %d %d",src,des);
tcl.eval();
char *ni = tcl.result();
return atoi(ni);
}
/* Recv method. */
void BurstManager::recv( Packet *pkt, Handler *h )
{
hdr_cmn *ch = hdr_cmn::access( pkt );
int pktsize = ch->size();
if (ch->ptype() == PT_TCP) //GMG -- added TCPSND, ACKSND, and UDPSND
// statistics collection
{
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "TCPSND", sc.getValue( "TCPSND" ) + 1.0 );
sc.updateEntry( "TCPBYTESSND", sc.getValue( "TCPBYTESSND" ) + pktsize );
}
else if (ch->ptype() == PT_ACK)
{
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "ACKSND", sc.getValue( "ACKSND" ) + 1.0 );
}
else if (ch->ptype() == PT_UDP)
{
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "UDPSND", sc.getValue( "UDPSND" ) + 1.0 );
sc.updateEntry( "UDPBYTESSND", sc.getValue( "UDPBYTESSND" ) + pktsize );
}
else if (ch->ptype() == PT_CBR)
{
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "CBRSND", sc.getValue( "CBRSND" ) + 1.0 );
sc.updateEntry( "CBRBYTESSND", sc.getValue( "CBRBYTESSND" ) + pktsize );
}
else if (ch->ptype() == PT_EXP)
{
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "EXPSND", sc.getValue( "EXPSND" ) + 1.0 );
sc.updateEntry( "EXPBYTESSND", sc.getValue( "EXPBYTESSND" ) + pktsize );
}
else if (ch->ptype() == PT_PARETO)
{
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "PARSND", sc.getValue( "PARSND" ) + 1.0 );
sc.updateEntry( "PARBYTESSND", sc.getValue( "PARBYTESSND" ) + pktsize );
}
else if (ch->ptype() == PT_SELFSIM)
{
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "SSIMSND", sc.getValue( "SSIMSND" ) + 1.0 );
sc.updateEntry( "SSIMBYTESSND", sc.getValue( "SSIMBYTESSND" ) + pktsize );
}
if ( ( currburstsize_ + pktsize ) > maxburstsize__ )
sendBurst();
if ( npkts_ == 0 )
bt_.resched( burst_timeout() );
BurstBuffer_[npkts_++] = pkt;
currburstsize_ += pktsize;
if ( currburstsize_ >= maxburstsize__ )
sendBurst();
// Debug::debug( "BurstManager: added the TCP/UDP packet successfully" );
}
void BurstManager::timeout()
{
if( currburstsize_ > 0 ) {
sendBurst();
}
//GMG -- commented out the line below after discussion in presentation on 03/09/2004.
// If send burst due to burst timer expiring, should not reset timer until a new packet
// arrives.
// bt_.resched( burst_timeout() );
}
void BurstManager::sendBurst()
{
if( currburstsize_ > 0 ) {
a_->sendBurst( BurstBuffer_, getburstid(), npkts_,
currburstsize_, destnodeid_, offsettime__[prio_], pcntguard__,
delta__, prio_ );
}
resetBurstParams();
}
void BurstManager::resetBurstParams()
{
int i = 0;
while(BurstBuffer_[i]!= NULL && i<MAXBURSTSIZE )
BurstBuffer_[i++] = NULL;
currburstsize_ = 0;
npkts_ = 0;
}
int BurstManager::command( int argc, const char*const* argv) {
return NsObject::command( argc, argv );
}
double& BurstManager::offsettime(int j)
{
char s[200];
if (j < 0 || j >= nqos_classes)
{
sprintf(s, "Invalid QoS class %d in obtaining offsettime", j);
Debug::debug(s);
exit(1);
}
return offsettime__[j];
}
void BurstManager::setOffsettime( int j, double offsettime )
{
char s[200];
if (j < 0 || j >= nqos_classes)
{
sprintf(s, "Invalid QoS class %d in obtaining offsettime", j);
Debug::debug(s);
exit(1);
}
offsettime__[j] = offsettime;
}
/*=====================================================================*
* *
* Implementation of the Integrated-Agent class *
* *
*=====================================================================*/
// default constructor //
IPKTAgent::IPKTAgent() : Agent(PT_IPKT) , maxindx_( -1 ),
seqno_(0)
{
int j;
for ( j = 0; j < nqos_classes; j++)
BM_[j] = (BurstManager*)NULL;
bind("packetSize_", &size_);
bind( "address_", &address_ );
}
// handle the recv of a packet
void IPKTAgent::recv( Packet *pkt, Handler *h )
{
hdr_ip* hdrip = hdr_ip::access(pkt);
hdr_cmn* ch = hdr_cmn::access(pkt);
hdr_IPKT* hdr = hdr_IPKT::access( pkt );
int priority; //GMG -- added priority variable
char s[200];
// if ( ( ch->ptype() == PT_TCP || ch->ptype() == PT_ACK )
if ( (ch->ptype() != PT_IPKT) //GMG -- changed this to
&& ( hdrip->saddr()== addr() ) ) { // correspond to the
// receipt of any data packet (not
//just TCP, ACK, or UDP)
//GMG -- added calculation of packet priority; print error message and terminate if out of range.
priority = hdrip->prio();
if (priority < 0 || priority >= nqos_classes)
{
sprintf (s, "Priority = %d is out of bounds", priority);
Debug::debug(s);
char *src_nodeaddr = Address::instance().print_nodeaddr(hdrip->saddr());
char *src_portaddr = Address::instance().print_portaddr(hdrip->sport());
char *dst_nodeaddr = Address::instance().print_nodeaddr(hdrip->daddr());
char *dst_portaddr = Address::instance().print_portaddr(hdrip->dport());
sprintf (s, "Source node.port = %s.%s Dest node.port = %s.%s",
src_nodeaddr, src_portaddr, dst_nodeaddr, dst_portaddr);
Debug::debug(s);
exit(1);
}
BM_[priority][hdrip->daddr()].recv( pkt, h );
return;
}
else if( ( ch->ptype() == PT_IPKT ) && ( hdrip->daddr() == addr() ) ) {
if ( hdrip->prio_== 2 ) {
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "BURSTRCV", sc.getValue( "BURSTRCV" ) + 1.0 );
/* record the end to end delay for the data-burst */
sc.updateEntry( "BURSTDLY", sc.getValue( "BURSTDLY" ) + Scheduler::instance().clock() - hdr->end_end_delay() );
if( ch->size() <= 0 ) {
Debug::debug( __FILE__, __LINE__, "Critical error occurred: Burst of size=0 found" );
exit (-1);
}
deBurst( pkt );
return;
}
else if ( hdrip->prio_==1 ) {
StatCollector &sc = StatCollector::instance();
sc.updateEntry( "BHPRCV", sc.getValue( "BHPRCV" ) + 1.0 );
sc.updateEntry( "BHPDLY", sc.getValue( "BHPDLY" ) + Scheduler::instance().clock() - hdr->end_end_delay() );
}
}
else {
}
if( pkt != NULL ) {
Packet::free( pkt );
}
}
// deburstify
void IPKTAgent::deBurst(Packet *pkt)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -