EtherBus Class Reference

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 ()
void tokenize (const char *str, std::vector< double > &array)

Private Attributes

double propagationSpeed
BusTaptap
int taps
long numMessages


Constructor & Destructor Documentation

EtherBus::EtherBus (  ) 

00078 {
00079     tap = NULL;
00080 }

EtherBus::~EtherBus (  )  [virtual]

00083 {
00084     delete [] tap;
00085 }


Member Function Documentation

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

00245 {
00246     if (par("writeScalars").boolValue())
00247     {
00248         double t = simTime();
00249         recordScalar("simulated time", t);
00250         recordScalar("messages handled", numMessages);
00251         if (t>0)
00252             recordScalar("messages/sec", numMessages/t);
00253     }
00254 }

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

00168 {
00169     if (!msg->isSelfMessage())
00170     {
00171         // Handle frame sent down from the network entity
00172         int tapPoint = msg->arrivalGate()->index();
00173         EV << "Frame " << msg << " arrived on tap " << tapPoint << endl;
00174 
00175         // create upstream and downstream events
00176         if (tapPoint>0)
00177         {
00178             // start UPSTREAM travel
00179             cMessage *event = new cMessage("upstream", UPSTREAM);
00180             event->setContextPointer(&tap[tapPoint-1]);
00181             // if goes downstream too, we need to make a copy
00182             cMessage *msg2 = (tapPoint<taps-1) ? (cMessage *)msg->dup() : msg;
00183             event->encapsulate(msg2);
00184             scheduleAt(simTime()+tap[tapPoint].propagationDelay[UPSTREAM], event);
00185         }
00186         if (tapPoint<taps-1)
00187         {
00188             // start DOWNSTREAM travel
00189             cMessage *event = new cMessage("downstream", DOWNSTREAM);
00190             event->setContextPointer(&tap[tapPoint+1]);
00191             event->encapsulate(msg);
00192             scheduleAt(simTime()+tap[tapPoint].propagationDelay[DOWNSTREAM], event);
00193         }
00194         if (taps==1)
00195         {
00196             // if there's only one tap, there's nothing to do
00197             delete msg;
00198         }
00199     }
00200     else
00201     {
00202         // handle upstream and downstream events
00203         int direction = msg->kind();
00204         BusTap *thistap = (BusTap *) msg->contextPointer();
00205         int tapPoint = thistap->id;
00206 
00207         EV << "Event " << msg << " on tap " << tapPoint << ", sending out frame\n";
00208 
00209         // send out on gate
00210         bool isLast = (direction==UPSTREAM) ? (tapPoint==0) : (tapPoint==taps-1);
00211         cMessage *msg2 = isLast ? msg->decapsulate() : (cMessage *)msg->encapsulatedMsg()->dup();
00212         send(msg2, "out", tapPoint);
00213 
00214         // if not end of the bus, schedule for next tap
00215         if (isLast)
00216         {
00217             EV << "End of bus reached\n";
00218             delete msg;
00219         }
00220         else
00221         {
00222             EV << "Scheduling for next tap\n";
00223             int nextTap = (direction==UPSTREAM) ? (tapPoint-1) : (tapPoint+1);
00224             msg->setContextPointer(&tap[nextTap]);
00225             scheduleAt(simTime()+tap[tapPoint].propagationDelay[direction], msg);
00226         }
00227     }
00228 }

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

00088 {
00089     numMessages = 0;
00090     WATCH(numMessages);
00091 
00092     propagationSpeed = par("propagationSpeed").doubleValue();
00093 
00094     // initialize the positions where the hosts connects to the bus
00095     taps = gate("in",0)->size();
00096     if (gate("out",0)->size()!=taps)
00097         error("the sizes of the in[] and out[] gate vectors must be the same");
00098 
00099     // read positions and check if positions are defined in order (we're lazy to sort...)
00100     std::vector<double> pos;
00101     tokenize(par("positions").stringValue(), pos);
00102     int numPos = pos.size();
00103     if (numPos>taps)
00104         EV << "Note: `positions' parameter contains more values ("<< numPos << ") than "
00105               "the number of taps (" << taps << "), ignoring excess values.\n";
00106     else if (numPos<taps && numPos>=2)
00107         EV << "Note: `positions' parameter contains less values ("<< numPos << ") than "
00108               "the number of taps (" << taps << "), repeating distance between last 2 positions.\n";
00109     else if (numPos<taps && numPos<2)
00110         EV << "Note: `positions' parameter contains too few values, using 5m distances.\n";
00111 
00112     tap = new BusTap[taps];
00113 
00114     int i;
00115     double distance = numPos>=2 ? pos[numPos-1]-pos[numPos-2] : 5;
00116     for (i=0; i<taps; i++)
00117     {
00118         tap[i].id = i;
00119         tap[i].position = i<numPos ? pos[i] : i==0 ? 5 : tap[i-1].position+distance;
00120     }
00121     for (i=0; i<taps-1; i++)
00122     {
00123         if (tap[i].position > tap[i+1].position)
00124             error("Tap positions must be ordered in ascending fashion, modify 'positions' parameter and rerun\n");
00125     }
00126 
00127     // Calculate propagation of delays between tap points on the bus
00128     for (i=0; i<taps; i++)
00129     {
00130         // Propagation delay between adjacent tap points
00131         if (i == 0) {
00132             tap[i].propagationDelay[UPSTREAM] = 0;
00133             tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;
00134         }
00135         else if (i == taps-1) {
00136             tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
00137             tap[i].propagationDelay[DOWNSTREAM] = 0;
00138         }
00139         else {
00140             tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
00141             tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;;
00142         }
00143     }
00144 
00145     // Prints out data of parameters for parameter checking...
00146     EV << "Parameters of (" << className() << ") " << fullPath() << "\n";
00147     EV << "propagationSpeed: " << propagationSpeed << "\n";
00148     for (i=0; i<taps; i++)
00149     {
00150         EV << "tap[" << i << "] pos: " << tap[i].position <<
00151               "  upstream delay: " << tap[i].propagationDelay[UPSTREAM] <<
00152               "  downstream delay: " << tap[i].propagationDelay[DOWNSTREAM] << endl;
00153     }
00154     EV << "\n";
00155 
00156     // autoconfig: tell everyone that bus supports only 10Mb half-duplex
00157     EV << "Autoconfig: advertising that we only support 10Mb half-duplex operation\n";
00158     for (i=0; i<taps; i++)
00159     {
00160         EtherAutoconfig *autoconf = new EtherAutoconfig("autoconf-10Mb-halfduplex");
00161         autoconf->setHalfDuplex(true);
00162         autoconf->setTxrate(10000000); // 10Mb
00163         send(autoconf,"out",i);
00164     }
00165 }

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

00231 {
00232     char *str2 = opp_strdup(str);
00233     if (!str2) return;
00234         char *s = strtok(str2, " ");
00235     while (s)
00236     {
00237         array.push_back(atof(s));
00238         s = strtok(NULL, " ");
00239     }
00240     delete [] str2;
00241 }


Member Data Documentation

long EtherBus::numMessages [private]

double EtherBus::propagationSpeed [private]

BusTap* EtherBus::tap [private]

int EtherBus::taps [private]


The documentation for this class was generated from the following file:
Generated on Wed Apr 4 13:20:19 2007 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.7