#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().