#include <PPP.h>
Public Member Functions | |
PPP () | |
virtual | ~PPP () |
Protected Member Functions | |
InterfaceEntry * | registerInterface (double datarate) |
void | startTransmitting (cMessage *msg) |
PPPFrame * | encapsulate (cMessage *msg) |
cMessage * | decapsulate (PPPFrame *pppFrame) |
void | displayBusy () |
void | displayIdle () |
void | updateDisplayString () |
virtual int | numInitStages () const |
virtual void | initialize (int stage) |
virtual void | handleMessage (cMessage *msg) |
Protected Attributes | |
bool | connected |
long | txQueueLimit |
cGate * | gateToWatch |
cQueue | txQueue |
cMessage * | endTransmissionEvent |
IPassiveQueue * | queueModule |
InterfaceEntry * | interfaceEntry |
double | datarate |
NotificationBoard * | nb |
TxNotifDetails | notifDetails |
std::string | oldConnColor |
long | numSent |
long | numRcvdOK |
long | numBitErr |
long | numDroppedIfaceDown |
|
00034 { 00035 endTransmissionEvent = NULL; 00036 }
|
|
00039 { 00040 cancelAndDelete(endTransmissionEvent); 00041 }
|
|
00325 { 00326 cMessage *msg = pppFrame->decapsulate(); 00327 delete pppFrame; 00328 return msg; 00329 }
|
|
00265 { 00266 displayString().setTagArg("i",1, txQueue.length()>=3 ? "red" : "yellow"); 00267 gateToWatch->displayString().setTagArg("o",0,"yellow"); 00268 gateToWatch->displayString().setTagArg("o",1,"3"); 00269 gate("physOut")->displayString().setTagArg("o",0,"yellow"); 00270 gate("physOut")->displayString().setTagArg("o",1,"3"); 00271 }
|
|
00274 { 00275 displayString().setTagArg("i",1,""); 00276 gateToWatch->displayString().setTagArg("o",0,oldConnColor.c_str()); 00277 gateToWatch->displayString().setTagArg("o",1,"1"); 00278 gate("physOut")->displayString().setTagArg("o",0,"black"); 00279 gate("physOut")->displayString().setTagArg("o",1,"1"); 00280 }
|
|
00317 { 00318 PPPFrame *pppFrame = new PPPFrame(msg->name()); 00319 pppFrame->setByteLength(PPP_OVERHEAD_BYTES); 00320 pppFrame->encapsulate(msg); 00321 return pppFrame; 00322 }
|
|
00184 { 00185 if (!connected) 00186 { 00187 EV << "Interface is not connected, dropping packet " << msg << endl; 00188 delete msg; 00189 numDroppedIfaceDown++; 00190 } 00191 else if (msg==endTransmissionEvent) 00192 { 00193 // Transmission finished, we can start next one. 00194 EV << "Transmission finished.\n"; 00195 if (ev.isGUI()) displayIdle(); 00196 00197 // fire notification 00198 notifDetails.setMessage(NULL); 00199 nb->fireChangeNotification(NF_PP_TX_END, ¬ifDetails); 00200 00201 if (!txQueue.empty()) 00202 { 00203 msg = (cMessage *) txQueue.getTail(); 00204 startTransmitting(msg); 00205 numSent++; 00206 } 00207 else if (queueModule) 00208 { 00209 // tell queue module that we've become idle 00210 queueModule->requestPacket(); 00211 } 00212 } 00213 else if (msg->arrivedOn("physIn")) 00214 { 00215 // fire notification 00216 notifDetails.setMessage(msg); 00217 nb->fireChangeNotification(NF_PP_RX_END, ¬ifDetails); 00218 00219 // check for bit errors 00220 if (msg->hasBitError()) 00221 { 00222 EV << "Bit error in " << msg << endl; 00223 numBitErr++; 00224 delete msg; 00225 } 00226 else 00227 { 00228 // pass up payload 00229 cMessage *payload = decapsulate(check_and_cast<PPPFrame *>(msg)); 00230 numRcvdOK++; 00231 send(payload,"netwOut"); 00232 } 00233 } 00234 else // arrived on gate "netwIn" 00235 { 00236 if (endTransmissionEvent->isScheduled()) 00237 { 00238 // We are currently busy, so just queue up the packet. 00239 EV << "Received " << msg << " for transmission but transmitter busy, queueing.\n"; 00240 if (ev.isGUI() && txQueue.length()>=3) displayString().setTagArg("i",1,"red"); 00241 00242 if (txQueueLimit && txQueue.length()>txQueueLimit) 00243 error("txQueue length exceeds %d -- this is probably due to " 00244 "a bogus app model generating excessive traffic " 00245 "(or if this is normal, increase txQueueLimit!)", 00246 txQueueLimit); 00247 00248 txQueue.insert(msg); 00249 } 00250 else 00251 { 00252 // We are idle, so we can start transmitting right away. 00253 EV << "Received " << msg << " for transmission\n"; 00254 startTransmitting(msg); 00255 numSent++; 00256 } 00257 } 00258 00259 if (ev.isGUI()) 00260 updateDisplayString(); 00261 00262 }
|
|
00044 { 00045 if (stage==3) 00046 { 00047 // update display string when addresses have been autoconfigured etc. 00048 updateDisplayString(); 00049 return; 00050 } 00051 00052 // all initialization is done in the first stage 00053 if (stage!=0) 00054 return; 00055 00056 txQueue.setName("txQueue"); 00057 endTransmissionEvent = new cMessage("pppEndTxEvent"); 00058 00059 txQueueLimit = par("txQueueLimit"); 00060 00061 interfaceEntry = NULL; 00062 00063 numSent = numRcvdOK = numBitErr = numDroppedIfaceDown = 0; 00064 WATCH(numSent); 00065 WATCH(numRcvdOK); 00066 WATCH(numBitErr); 00067 WATCH(numDroppedIfaceDown); 00068 00069 // find queueModule 00070 queueModule = NULL; 00071 if (par("queueModule").stringValue()[0]) 00072 { 00073 cModule *mod = parentModule()->submodule(par("queueModule").stringValue()); 00074 queueModule = check_and_cast<IPassiveQueue *>(mod); 00075 } 00076 00077 // we're connected if other end of connection path is an input gate 00078 cGate *physOut = gate("physOut"); 00079 connected = physOut->destinationGate()->type()=='I'; 00080 00081 // if we're connected, get the gate with transmission rate 00082 gateToWatch = physOut; 00083 datarate = 0; 00084 if (connected) 00085 { 00086 while (gateToWatch) 00087 { 00088 // does this gate have data rate? 00089 cSimpleChannel *chan = dynamic_cast<cSimpleChannel*>(gateToWatch->channel()); 00090 if (chan && (datarate=chan->datarate())>0) 00091 break; 00092 // otherwise just check next connection in path 00093 gateToWatch = gateToWatch->toGate(); 00094 } 00095 if (!gateToWatch) 00096 error("gate physOut must be connected (directly or indirectly) to a link with data rate"); 00097 } 00098 00099 // register our interface entry in InterfaceTable 00100 interfaceEntry = registerInterface(datarate); 00101 00102 // prepare to fire notifications 00103 nb = NotificationBoardAccess().get(); 00104 notifDetails.setInterfaceEntry(interfaceEntry); 00105 00106 // if not connected, make it gray 00107 if (ev.isGUI()) 00108 { 00109 if (!connected) 00110 { 00111 displayString().setTagArg("i",1,"#707070"); 00112 displayString().setTagArg("i",2,"100"); 00113 } 00114 oldConnColor = gateToWatch->displayString().getTagArg("o",0); 00115 } 00116 00117 // request first frame to send 00118 if (queueModule) 00119 { 00120 EV << "Requesting first frame from queue module\n"; 00121 queueModule->requestPacket(); 00122 } 00123 }
|
|
00075 {return 4;}
|
|
00126 { 00127 InterfaceEntry *e = new InterfaceEntry(); 00128 00129 // interface name: our module name without special characters ([]) 00130 char *interfaceName = new char[strlen(parentModule()->fullName())+1]; 00131 char *d=interfaceName; 00132 for (const char *s=parentModule()->fullName(); *s; s++) 00133 if (isalnum(*s)) 00134 *d++ = *s; 00135 *d = '\0'; 00136 00137 e->setName(interfaceName); 00138 delete [] interfaceName; 00139 00140 // data rate 00141 e->setDatarate(datarate); 00142 00143 // generate a link-layer address to be used as interface token for IPv6 00144 InterfaceToken token(0, simulation.getUniqueNumber(), 64); 00145 e->setInterfaceToken(token); 00146 00147 // MTU: typical values are 576 (Internet de facto), 1500 (Ethernet-friendly), 00148 // 4000 (on some point-to-point links), 4470 (Cisco routers default, FDDI compatible) 00149 e->setMtu(4470); 00150 00151 // capabilities 00152 e->setMulticast(true); 00153 e->setPointToPoint(true); 00154 00155 // add 00156 InterfaceTable *ift = InterfaceTableAccess().get(); 00157 ift->addInterface(e, this); 00158 00159 return e; 00160 }
|
|
00164 { 00165 // if there's any control info, remove it; then encapsulate the packet 00166 delete msg->removeControlInfo(); 00167 PPPFrame *pppFrame = encapsulate(msg); 00168 if (ev.isGUI()) displayBusy(); 00169 00170 // fire notification 00171 notifDetails.setMessage(pppFrame); 00172 nb->fireChangeNotification(NF_PP_TX_BEGIN, ¬ifDetails); 00173 00174 // send 00175 EV << "Starting transmission of " << pppFrame << endl; 00176 send(pppFrame, "physOut"); 00177 00178 // schedule an event for the time when last bit will leave the gate. 00179 simtime_t endTransmission = gateToWatch->transmissionFinishes(); 00180 scheduleAt(endTransmission, endTransmissionEvent); 00181 }
|
|
00283 { 00284 char buf[80]; 00285 if (ev.disabled()) 00286 { 00287 // speed up things 00288 displayString().setTagArg("t",0,""); 00289 } 00290 else if (connected) 00291 { 00292 char drate[40]; 00293 if (datarate>=1e9) sprintf(drate,"%gG", datarate/1e9); 00294 else if (datarate>=1e6) sprintf(drate,"%gM", datarate/1e6); 00295 else if (datarate>=1e3) sprintf(drate,"%gK", datarate/1e3); 00296 else sprintf(drate,"%gbps", datarate); 00297 00298 /* TBD FIXME find solution for displaying IP address without dependence on IPv6 or IPv6 00299 IPAddress addr = interfaceEntry->ipv4()->inetAddress(); 00300 sprintf(buf, "%s / %s\nrcv:%ld snt:%ld", addr.isUnspecified()?"-":addr.str().c_str(), drate, numRcvdOK, numSent); 00301 */ 00302 sprintf(buf, "%s\nrcv:%ld snt:%ld", drate, numRcvdOK, numSent); 00303 00304 if (numBitErr>0) 00305 sprintf(buf+strlen(buf), "\nerr:%ld", numBitErr); 00306 00307 displayString().setTagArg("t",0,buf); 00308 } 00309 else 00310 { 00311 sprintf(buf, "not connected\ndropped:%ld", numDroppedIfaceDown); 00312 displayString().setTagArg("t",0,buf); 00313 } 00314 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|