#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 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1.4.1