EtherBus Class Reference

#include <EtherBus.h>

List of all members.


Detailed Description

Implements the bus which connects hosts, switches and other LAN entities on an Ethernet LAN.

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
BusTaptap
int taps
long numMessages

Classes

struct  BusTap

Constructor & Destructor Documentation

EtherBus::EtherBus (  ) 

00030 {
00031     tap = NULL;
00032 }

EtherBus::~EtherBus (  )  [virtual]

00035 {
00036     delete [] tap;
00037 }


Member Function Documentation

void EtherBus::initialize (  )  [protected, virtual]

00040 {
00041     numMessages = 0;
00042     WATCH(numMessages);
00043 
00044     propagationSpeed = par("propagationSpeed").doubleValue();
00045 
00046     // initialize the positions where the hosts connects to the bus
00047     taps = gateSize("ethg");
00048 
00049     // read positions and check if positions are defined in order (we're lazy to sort...)
00050     std::vector<double> pos;
00051     tokenize(par("positions").stringValue(), pos);
00052     int numPos = pos.size();
00053     if (numPos>taps)
00054         EV << "Note: `positions' parameter contains more values ("<< numPos << ") than "
00055               "the number of taps (" << taps << "), ignoring excess values.\n";
00056     else if (numPos<taps && numPos>=2)
00057         EV << "Note: `positions' parameter contains less values ("<< numPos << ") than "
00058               "the number of taps (" << taps << "), repeating distance between last 2 positions.\n";
00059     else if (numPos<taps && numPos<2)
00060         EV << "Note: `positions' parameter contains too few values, using 5m distances.\n";
00061 
00062     tap = new BusTap[taps];
00063 
00064     int i;
00065     double distance = numPos>=2 ? pos[numPos-1]-pos[numPos-2] : 5;
00066     for (i=0; i<taps; i++)
00067     {
00068         tap[i].id = i;
00069         tap[i].position = i<numPos ? pos[i] : i==0 ? 5 : tap[i-1].position+distance;
00070     }
00071     for (i=0; i<taps-1; i++)
00072     {
00073         if (tap[i].position > tap[i+1].position)
00074             error("Tap positions must be ordered in ascending fashion, modify 'positions' parameter and rerun\n");
00075     }
00076 
00077     // Calculate propagation of delays between tap points on the bus
00078     for (i=0; i<taps; i++)
00079     {
00080         // Propagation delay between adjacent tap points
00081         if (i == 0) {
00082             tap[i].propagationDelay[UPSTREAM] = 0;
00083             tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;
00084         }
00085         else if (i == taps-1) {
00086             tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
00087             tap[i].propagationDelay[DOWNSTREAM] = 0;
00088         }
00089         else {
00090             tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
00091             tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;;
00092         }
00093     }
00094 
00095     // Prints out data of parameters for parameter checking...
00096     EV << "Parameters of (" << getClassName() << ") " << getFullPath() << "\n";
00097     EV << "propagationSpeed: " << propagationSpeed << "\n";
00098     for (i=0; i<taps; i++)
00099     {
00100         EV << "tap[" << i << "] pos: " << tap[i].position <<
00101               "  upstream delay: " << tap[i].propagationDelay[UPSTREAM] <<
00102               "  downstream delay: " << tap[i].propagationDelay[DOWNSTREAM] << endl;
00103     }
00104     EV << "\n";
00105 
00106     // autoconfig: tell everyone that bus supports only 10Mb half-duplex
00107     EV << "Autoconfig: advertising that we only support 10Mb half-duplex operation\n";
00108     for (i=0; i<taps; i++)
00109     {
00110         EtherAutoconfig *autoconf = new EtherAutoconfig("autoconf-10Mb-halfduplex");
00111         autoconf->setHalfDuplex(true);
00112         autoconf->setTxrate(10000000); // 10Mb
00113         send(autoconf,"ethg$o",i);
00114     }
00115 }

void EtherBus::handleMessage ( cMessage *  msg  )  [protected, virtual]

00118 {
00119     if (!msg->isSelfMessage())
00120     {
00121         // Handle frame sent down from the network entity
00122         int tapPoint = msg->getArrivalGate()->getIndex();
00123         EV << "Frame " << msg << " arrived on tap " << tapPoint << endl;
00124 
00125         // create upstream and downstream events
00126         if (tapPoint>0)
00127         {
00128             // start UPSTREAM travel
00129             // if goes downstream too, we need to make a copy
00130             cMessage *msg2 = (tapPoint<taps-1) ? (cMessage *)msg->dup() : msg;
00131             msg2->setKind(UPSTREAM);
00132             msg2->setContextPointer(&tap[tapPoint-1]);
00133             scheduleAt(simTime()+tap[tapPoint].propagationDelay[UPSTREAM], msg2);
00134         }
00135         if (tapPoint<taps-1)
00136         {
00137             // start DOWNSTREAM travel
00138             msg->setKind(DOWNSTREAM);
00139             msg->setContextPointer(&tap[tapPoint+1]);
00140             scheduleAt(simTime()+tap[tapPoint].propagationDelay[DOWNSTREAM], msg);
00141         }
00142         if (taps==1)
00143         {
00144             // if there's only one tap, there's nothing to do
00145             delete msg;
00146         }
00147     }
00148     else
00149     {
00150         // handle upstream and downstream events
00151         int direction = msg->getKind();
00152         BusTap *thistap = (BusTap *) msg->getContextPointer();
00153         int tapPoint = thistap->id;
00154 
00155         EV << "Event " << msg << " on tap " << tapPoint << ", sending out frame\n";
00156 
00157         // send out on gate
00158         bool isLast = (direction==UPSTREAM) ? (tapPoint==0) : (tapPoint==taps-1);
00159         cPacket *msg2 = isLast ? PK(msg) : PK(msg->dup());
00160         send(msg2, "ethg$o", tapPoint);
00161 
00162         // if not end of the bus, schedule for next tap
00163         if (isLast)
00164         {
00165             EV << "End of bus reached\n";
00166         }
00167         else
00168         {
00169             EV << "Scheduling for next tap\n";
00170             int nextTap = (direction==UPSTREAM) ? (tapPoint-1) : (tapPoint+1);
00171             msg->setContextPointer(&tap[nextTap]);
00172             scheduleAt(simTime()+tap[tapPoint].propagationDelay[direction], msg);
00173         }
00174     }
00175 }

void EtherBus::finish (  )  [protected, virtual]

00192 {
00193     simtime_t t = simTime();
00194     recordScalar("simulated time", t);
00195     recordScalar("messages handled", numMessages);
00196     if (t>0)
00197         recordScalar("messages/sec", numMessages/t);
00198 }

void EtherBus::tokenize ( const char *  str,
std::vector< double > &  array 
) [protected, virtual]

Referenced by initialize().

00178 {
00179     char *str2 = opp_strdup(str);
00180     if (!str2) return;
00181         char *s = strtok(str2, " ");
00182     while (s)
00183     {
00184         array.push_back(atof(s));
00185         s = strtok(NULL, " ");
00186     }
00187     delete [] str2;
00188 }


Member Data Documentation

double EtherBus::propagationSpeed [protected]

Referenced by initialize().

BusTap* EtherBus::tap [protected]

int EtherBus::taps [protected]

Referenced by handleMessage(), and initialize().

long EtherBus::numMessages [protected]

Referenced by finish(), and initialize().


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:18 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5