PPP Class Reference

#include <PPP.h>

List of all members.


Detailed Description

PPP implementation. Derived from the p-to-p OMNeT++ sample simulation.


Public Member Functions

 PPP ()
virtual ~PPP ()

Protected Member Functions

InterfaceEntryregisterInterface (double datarate)
void startTransmitting (cMessage *msg)
PPPFrameencapsulate (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
IPassiveQueuequeueModule
InterfaceEntryinterfaceEntry
double datarate
NotificationBoardnb
TxNotifDetails notifDetails
std::string oldConnColor
long numSent
long numRcvdOK
long numBitErr
long numDroppedIfaceDown


Constructor & Destructor Documentation

PPP::PPP (  ) 

00034 {
00035     endTransmissionEvent = NULL;
00036 }

PPP::~PPP (  )  [virtual]

00039 {
00040     cancelAndDelete(endTransmissionEvent);
00041 }


Member Function Documentation

cMessage * PPP::decapsulate ( PPPFrame pppFrame  )  [protected]

00339 {
00340     cMessage *msg = pppFrame->decapsulate();
00341     delete pppFrame;
00342     return msg;
00343 }

void PPP::displayBusy (  )  [protected]

00279 {
00280     displayString().setTagArg("i",1, txQueue.length()>=3 ? "red" : "yellow");
00281     gateToWatch->displayString().setTagArg("o",0,"yellow");
00282     gateToWatch->displayString().setTagArg("o",1,"3");
00283     gate("physOut")->displayString().setTagArg("o",0,"yellow");
00284     gate("physOut")->displayString().setTagArg("o",1,"3");
00285 }

void PPP::displayIdle (  )  [protected]

00288 {
00289     displayString().setTagArg("i",1,"");
00290     gateToWatch->displayString().setTagArg("o",0,oldConnColor.c_str());
00291     gateToWatch->displayString().setTagArg("o",1,"1");
00292     gate("physOut")->displayString().setTagArg("o",0,"black");
00293     gate("physOut")->displayString().setTagArg("o",1,"1");
00294 }

PPPFrame * PPP::encapsulate ( cMessage *  msg  )  [protected]

00331 {
00332     PPPFrame *pppFrame = new PPPFrame(msg->name());
00333     pppFrame->setByteLength(PPP_OVERHEAD_BYTES);
00334     pppFrame->encapsulate(msg);
00335     return pppFrame;
00336 }

void PPP::handleMessage ( cMessage *  msg  )  [protected, virtual]

00193 {
00194     if (!connected)
00195     {
00196         EV << "Interface is not connected, dropping packet " << msg << endl;
00197         delete msg;
00198         numDroppedIfaceDown++;
00199     }
00200     else if (msg==endTransmissionEvent)
00201     {
00202         // Transmission finished, we can start next one.
00203         EV << "Transmission finished.\n";
00204         if (ev.isGUI()) displayIdle();
00205 
00206         // fire notification
00207         notifDetails.setMessage(NULL);
00208         nb->fireChangeNotification(NF_PP_TX_END, &notifDetails);
00209 
00210         if (!txQueue.empty())
00211         {
00212             msg = (cMessage *) txQueue.getTail();
00213             startTransmitting(msg);
00214             numSent++;
00215         }
00216         else if (queueModule)
00217         {
00218             // tell queue module that we've become idle
00219             queueModule->requestPacket();
00220         }
00221     }
00222     else if (msg->arrivedOn("physIn"))
00223     {
00224         // fire notification
00225         notifDetails.setMessage(msg);
00226         nb->fireChangeNotification(NF_PP_RX_END, &notifDetails);
00227 
00228         // check for bit errors
00229         if (msg->hasBitError())
00230         {
00231             EV << "Bit error in " << msg << endl;
00232             numBitErr++;
00233             delete msg;
00234         }
00235         else
00236         {
00237             // pass up payload
00238             cMessage *payload = decapsulate(check_and_cast<PPPFrame *>(msg));
00239             numRcvdOK++;
00240 
00241 #ifndef _MAX_SPEED
00242             send(payload,"netwOut");
00243 #else
00244             send(payload, gateIndexNetwOut);
00245 #endif
00246         }
00247     }
00248     else // arrived on gate "netwIn"
00249     {
00250         if (endTransmissionEvent->isScheduled())
00251         {
00252             // We are currently busy, so just queue up the packet.
00253             EV << "Received " << msg << " for transmission but transmitter busy, queueing.\n";
00254             if (ev.isGUI() && txQueue.length()>=3) displayString().setTagArg("i",1,"red");
00255 
00256             if (txQueueLimit && txQueue.length()>txQueueLimit)
00257                 error("txQueue length exceeds %d -- this is probably due to "
00258                       "a bogus app model generating excessive traffic "
00259                       "(or if this is normal, increase txQueueLimit!)",
00260                       txQueueLimit);
00261 
00262             txQueue.insert(msg);
00263         }
00264         else
00265         {
00266             // We are idle, so we can start transmitting right away.
00267             EV << "Received " << msg << " for transmission\n";
00268             startTransmitting(msg);
00269             numSent++;
00270         }
00271     }
00272 
00273     if (ev.isGUI())
00274         updateDisplayString();
00275 
00276 }

void PPP::initialize ( int  stage  )  [protected, virtual]

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 #ifdef _MAX_SPEED
00099         gateIndexPhysOut = gate("physOut")->id();
00100         gateIndexNetwOut = gate("netwOut")->id();
00101 #endif
00102     }
00103 
00104     // register our interface entry in InterfaceTable
00105     interfaceEntry = registerInterface(datarate);
00106 
00107     // prepare to fire notifications
00108     nb = NotificationBoardAccess().get();
00109     notifDetails.setInterfaceEntry(interfaceEntry);
00110 
00111     // if not connected, make it gray
00112     if (ev.isGUI())
00113     {
00114         if (!connected)
00115         {
00116             displayString().setTagArg("i",1,"#707070");
00117             displayString().setTagArg("i",2,"100");
00118         }
00119         oldConnColor = gateToWatch->displayString().getTagArg("o",0);
00120     }
00121 
00122     // request first frame to send
00123     if (queueModule)
00124     {
00125         EV << "Requesting first frame from queue module\n";
00126         queueModule->requestPacket();
00127     }
00128 }

virtual int PPP::numInitStages (  )  const [inline, protected, virtual]

00080 {return 4;}

InterfaceEntry * PPP::registerInterface ( double  datarate  )  [protected]

00131 {
00132     InterfaceEntry *e = new InterfaceEntry();
00133 
00134     // interface name: our module name without special characters ([])
00135     char *interfaceName = new char[strlen(parentModule()->fullName())+1];
00136     char *d=interfaceName;
00137     for (const char *s=parentModule()->fullName(); *s; s++)
00138         if (isalnum(*s))
00139             *d++ = *s;
00140     *d = '\0';
00141 
00142     e->setName(interfaceName);
00143     delete [] interfaceName;
00144 
00145     // data rate
00146     e->setDatarate(datarate);
00147 
00148     // generate a link-layer address to be used as interface token for IPv6
00149     InterfaceToken token(0, simulation.getUniqueNumber(), 64);
00150     e->setInterfaceToken(token);
00151 
00152     // MTU: typical values are 576 (Internet de facto), 1500 (Ethernet-friendly),
00153     // 4000 (on some point-to-point links), 4470 (Cisco routers default, FDDI compatible)
00154     e->setMtu(4470);
00155 
00156     // capabilities
00157     e->setMulticast(true);
00158     e->setPointToPoint(true);
00159 
00160     // add
00161     InterfaceTable *ift = InterfaceTableAccess().get();
00162     ift->addInterface(e, this);
00163 
00164     return e;
00165 }

void PPP::startTransmitting ( cMessage *  msg  )  [protected]

00169 {
00170     // if there's any control info, remove it; then encapsulate the packet
00171     delete msg->removeControlInfo();
00172     PPPFrame *pppFrame = encapsulate(msg);
00173     if (ev.isGUI()) displayBusy();
00174 
00175     // fire notification
00176     notifDetails.setMessage(pppFrame);
00177     nb->fireChangeNotification(NF_PP_TX_BEGIN, &notifDetails);
00178 
00179     // send
00180 #ifndef _MAX_SPEED
00181     EV << "Starting transmission of " << pppFrame << endl;
00182     send(pppFrame, "physOut");
00183 #else
00184     send(pppFrame, gateIndexPhysOut);
00185 #endif
00186 
00187     // schedule an event for the time when last bit will leave the gate.
00188     simtime_t endTransmission = gateToWatch->transmissionFinishes();
00189     scheduleAt(endTransmission, endTransmissionEvent);
00190 }

void PPP::updateDisplayString (  )  [protected]

00297 {
00298     char buf[80];
00299     if (ev.disabled())
00300     {
00301         // speed up things
00302         displayString().setTagArg("t",0,"");
00303     }
00304     else if (connected)
00305     {
00306         char drate[40];
00307         if (datarate>=1e9) sprintf(drate,"%gG", datarate/1e9);
00308         else if (datarate>=1e6) sprintf(drate,"%gM", datarate/1e6);
00309         else if (datarate>=1e3) sprintf(drate,"%gK", datarate/1e3);
00310         else sprintf(drate,"%gbps", datarate);
00311 
00312 /* TBD FIXME find solution for displaying IP address without dependence on IPv6 or IPv6
00313         IPAddress addr = interfaceEntry->ipv4()->inetAddress();
00314         sprintf(buf, "%s / %s\nrcv:%ld snt:%ld", addr.isUnspecified()?"-":addr.str().c_str(), drate, numRcvdOK, numSent);
00315 */
00316         sprintf(buf, "%s\nrcv:%ld snt:%ld", drate, numRcvdOK, numSent);
00317 
00318         if (numBitErr>0)
00319             sprintf(buf+strlen(buf), "\nerr:%ld", numBitErr);
00320 
00321         displayString().setTagArg("t",0,buf);
00322     }
00323     else
00324     {
00325         sprintf(buf, "not connected\ndropped:%ld", numDroppedIfaceDown);
00326         displayString().setTagArg("t",0,buf);
00327     }
00328 }


Member Data Documentation

bool PPP::connected [protected]

double PPP::datarate [protected]

cMessage* PPP::endTransmissionEvent [protected]

cGate* PPP::gateToWatch [protected]

InterfaceEntry* PPP::interfaceEntry [protected]

NotificationBoard* PPP::nb [protected]

TxNotifDetails PPP::notifDetails [protected]

long PPP::numBitErr [protected]

long PPP::numDroppedIfaceDown [protected]

long PPP::numRcvdOK [protected]

long PPP::numSent [protected]

std::string PPP::oldConnColor [protected]

IPassiveQueue* PPP::queueModule [protected]

cQueue PPP::txQueue [protected]

long PPP::txQueueLimit [protected]


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:20:22 2007 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.7