#include <EtherBus.h>
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 |
Classes | |
struct | BusTap |
EtherBus::EtherBus | ( | ) |
EtherBus::~EtherBus | ( | ) | [virtual] |
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 }
double EtherBus::propagationSpeed [protected] |
Referenced by initialize().
BusTap* EtherBus::tap [protected] |
Referenced by EtherBus(), handleMessage(), initialize(), and ~EtherBus().
int EtherBus::taps [protected] |
Referenced by handleMessage(), and initialize().
long EtherBus::numMessages [protected] |
Referenced by finish(), and initialize().