Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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]
 

00325 {
00326     cMessage *msg = pppFrame->decapsulate();
00327     delete pppFrame;
00328     return msg;
00329 }

void PPP::displayBusy  )  [protected]
 

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 }

void PPP::displayIdle  )  [protected]
 

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 }

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

00317 {
00318     PPPFrame *pppFrame = new PPPFrame(msg->name());
00319     pppFrame->setByteLength(PPP_OVERHEAD_BYTES);
00320     pppFrame->encapsulate(msg);
00321     return pppFrame;
00322 }

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

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, &notifDetails);
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, &notifDetails);
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 }

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

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

00075 {return 4;}

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

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 }

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

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, &notifDetails);
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 }

void PPP::updateDisplayString  )  [protected]
 

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 }


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 Thu Oct 19 18:22:27 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0