Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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 Thu Oct 19 18:22:21 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0