#include <EtherBus.h>
Classes | |
| struct | BusTap |
Public Member Functions | |
| EtherBus () | |
| virtual | ~EtherBus () |
Protected Member Functions | |
| virtual void | initialize () |
| virtual void | handleMessage (cMessage *) |
| virtual void | finish () |
| virtual void | tokenize (const char *str, std::vector< double > &array) |
Protected Attributes | |
| double | propagationSpeed |
| BusTap * | tap |
| int | taps |
| long | numMessages |
Implements the bus which connects hosts, switches and other LAN entities on an Ethernet LAN.
Definition at line 31 of file EtherBus.h.
| EtherBus::EtherBus | ( | ) |
Definition at line 29 of file EtherBus.cc.
{
tap = NULL;
}
| EtherBus::~EtherBus | ( | ) | [virtual] |
Definition at line 34 of file EtherBus.cc.
{
delete [] tap;
}
| void EtherBus::finish | ( | ) | [protected, virtual] |
Definition at line 191 of file EtherBus.cc.
{
simtime_t t = simTime();
recordScalar("simulated time", t);
recordScalar("messages handled", numMessages);
if (t>0)
recordScalar("messages/sec", numMessages/t);
}
| void EtherBus::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Definition at line 117 of file EtherBus.cc.
{
if (!msg->isSelfMessage())
{
// Handle frame sent down from the network entity
int tapPoint = msg->getArrivalGate()->getIndex();
EV << "Frame " << msg << " arrived on tap " << tapPoint << endl;
// create upstream and downstream events
if (tapPoint>0)
{
// start UPSTREAM travel
// if goes downstream too, we need to make a copy
cMessage *msg2 = (tapPoint<taps-1) ? (cMessage *)msg->dup() : msg;
msg2->setKind(UPSTREAM);
msg2->setContextPointer(&tap[tapPoint-1]);
scheduleAt(simTime()+tap[tapPoint].propagationDelay[UPSTREAM], msg2);
}
if (tapPoint<taps-1)
{
// start DOWNSTREAM travel
msg->setKind(DOWNSTREAM);
msg->setContextPointer(&tap[tapPoint+1]);
scheduleAt(simTime()+tap[tapPoint].propagationDelay[DOWNSTREAM], msg);
}
if (taps==1)
{
// if there's only one tap, there's nothing to do
delete msg;
}
}
else
{
// handle upstream and downstream events
int direction = msg->getKind();
BusTap *thistap = (BusTap *) msg->getContextPointer();
int tapPoint = thistap->id;
EV << "Event " << msg << " on tap " << tapPoint << ", sending out frame\n";
// send out on gate
bool isLast = (direction==UPSTREAM) ? (tapPoint==0) : (tapPoint==taps-1);
cPacket *msg2 = isLast ? PK(msg) : PK(msg->dup());
send(msg2, "ethg$o", tapPoint);
// if not end of the bus, schedule for next tap
if (isLast)
{
EV << "End of bus reached\n";
}
else
{
EV << "Scheduling for next tap\n";
int nextTap = (direction==UPSTREAM) ? (tapPoint-1) : (tapPoint+1);
msg->setContextPointer(&tap[nextTap]);
scheduleAt(simTime()+tap[tapPoint].propagationDelay[direction], msg);
}
}
}
| void EtherBus::initialize | ( | ) | [protected, virtual] |
Definition at line 39 of file EtherBus.cc.
{
numMessages = 0;
WATCH(numMessages);
propagationSpeed = par("propagationSpeed").doubleValue();
// initialize the positions where the hosts connects to the bus
taps = gateSize("ethg");
// read positions and check if positions are defined in order (we're lazy to sort...)
std::vector<double> pos;
tokenize(par("positions").stringValue(), pos);
int numPos = pos.size();
if (numPos>taps)
EV << "Note: `positions' parameter contains more values ("<< numPos << ") than "
"the number of taps (" << taps << "), ignoring excess values.\n";
else if (numPos<taps && numPos>=2)
EV << "Note: `positions' parameter contains less values ("<< numPos << ") than "
"the number of taps (" << taps << "), repeating distance between last 2 positions.\n";
else if (numPos<taps && numPos<2)
EV << "Note: `positions' parameter contains too few values, using 5m distances.\n";
tap = new BusTap[taps];
int i;
double distance = numPos>=2 ? pos[numPos-1]-pos[numPos-2] : 5;
for (i=0; i<taps; i++)
{
tap[i].id = i;
tap[i].position = i<numPos ? pos[i] : i==0 ? 5 : tap[i-1].position+distance;
}
for (i=0; i<taps-1; i++)
{
if (tap[i].position > tap[i+1].position)
error("Tap positions must be ordered in ascending fashion, modify 'positions' parameter and rerun\n");
}
// Calculate propagation of delays between tap points on the bus
for (i=0; i<taps; i++)
{
// Propagation delay between adjacent tap points
if (i == 0) {
tap[i].propagationDelay[UPSTREAM] = 0;
tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;
}
else if (i == taps-1) {
tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
tap[i].propagationDelay[DOWNSTREAM] = 0;
}
else {
tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;;
}
}
// Prints out data of parameters for parameter checking...
EV << "Parameters of (" << getClassName() << ") " << getFullPath() << "\n";
EV << "propagationSpeed: " << propagationSpeed << "\n";
for (i=0; i<taps; i++)
{
EV << "tap[" << i << "] pos: " << tap[i].position <<
" upstream delay: " << tap[i].propagationDelay[UPSTREAM] <<
" downstream delay: " << tap[i].propagationDelay[DOWNSTREAM] << endl;
}
EV << "\n";
// autoconfig: tell everyone that bus supports only 10Mb half-duplex
EV << "Autoconfig: advertising that we only support 10Mb half-duplex operation\n";
for (i=0; i<taps; i++)
{
EtherAutoconfig *autoconf = new EtherAutoconfig("autoconf-10Mb-halfduplex");
autoconf->setHalfDuplex(true);
autoconf->setTxrate(10000000); // 10Mb
send(autoconf,"ethg$o",i);
}
}
| void EtherBus::tokenize | ( | const char * | str, | |
| std::vector< double > & | array | |||
| ) | [protected, virtual] |
Definition at line 177 of file EtherBus.cc.
Referenced by initialize().
{
char *str2 = opp_strdup(str);
if (!str2) return;
char *s = strtok(str2, " ");
while (s)
{
array.push_back(atof(s));
s = strtok(NULL, " ");
}
delete [] str2;
}
long EtherBus::numMessages [protected] |
Definition at line 50 of file EtherBus.h.
Referenced by finish(), and initialize().
double EtherBus::propagationSpeed [protected] |
Definition at line 45 of file EtherBus.h.
Referenced by initialize().
BusTap* EtherBus::tap [protected] |
Definition at line 47 of file EtherBus.h.
Referenced by EtherBus(), handleMessage(), initialize(), and ~EtherBus().
int EtherBus::taps [protected] |
Definition at line 48 of file EtherBus.h.
Referenced by handleMessage(), and initialize().
1.7.1