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 |
BusTap * | tap |
int | taps |
long | numMessages |
EtherBus::EtherBus | ( | ) |
EtherBus::~EtherBus | ( | ) | [virtual] |
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] |
long EtherBus::numMessages [private] |
double EtherBus::propagationSpeed [private] |
BusTap* EtherBus::tap [private] |
int EtherBus::taps [private] |