INET Framework for OMNeT++/OMNEST
AnsaPPP Class Reference

#include <AnsaPPP.h>

Inheritance diagram for AnsaPPP:
INotifiable

List of all members.

Public Member Functions

 AnsaPPP ()
virtual ~AnsaPPP ()
virtual InterfaceEntrygetInterfaceEntry (void)
virtual void setDisabled (bool b)
virtual bool isDisabled (void)

Protected Member Functions

virtual InterfaceEntryregisterInterface (double datarate)
virtual void startTransmitting (cPacket *msg)
virtual PPPFrameencapsulate (cPacket *msg)
virtual cPacket * decapsulate (PPPFrame *pppFrame)
virtual void displayBusy ()
virtual void displayIdle ()
virtual void updateDisplayString ()
virtual void updateHasSubcribers ()
virtual void receiveChangeNotification (int category, const cPolymorphic *details)
virtual int numInitStages () const
virtual void initialize (int stage)
virtual void handleMessage (cMessage *msg)

Protected Attributes

long txQueueLimit
cGate * physOutGate
cChannel * datarateChannel
bool disabled
cQueue txQueue
cMessage * endTransmissionEvent
IPassiveQueuequeueModule
InterfaceEntryinterfaceEntry
NotificationBoardnb
TxNotifDetails notifDetails
bool hasSubscribers
std::string oldConnColor
long numSent
long numRcvdOK
long numBitErr
long numDroppedIfaceDown

Detailed Description

PPP implementation.

Definition at line 36 of file AnsaPPP.h.


Constructor & Destructor Documentation

Definition at line 33 of file AnsaPPP.cc.

AnsaPPP::~AnsaPPP ( ) [virtual]

Definition at line 38 of file AnsaPPP.cc.

{
    cancelAndDelete(endTransmissionEvent);
}

Member Function Documentation

cPacket * AnsaPPP::decapsulate ( PPPFrame pppFrame) [protected, virtual]

Definition at line 372 of file AnsaPPP.cc.

Referenced by handleMessage().

{
    cPacket *msg = pppFrame->decapsulate();
    delete pppFrame;
    return msg;
}
void AnsaPPP::displayBusy ( ) [protected, virtual]

Definition at line 274 of file AnsaPPP.cc.

Referenced by startTransmitting().

{
    getDisplayString().setTagArg("i",1, txQueue.length()>=3 ? "red" : "yellow");
    datarateChannel->getDisplayString().setTagArg("o",0,"yellow");
    datarateChannel->getDisplayString().setTagArg("o",1,"3");
}
void AnsaPPP::displayIdle ( ) [protected, virtual]

Definition at line 281 of file AnsaPPP.cc.

Referenced by handleMessage().

{
    getDisplayString().setTagArg("i",1,"");
    datarateChannel->getDisplayString().setTagArg("o",0,oldConnColor.c_str());
    datarateChannel->getDisplayString().setTagArg("o",1,"1");
}
PPPFrame * AnsaPPP::encapsulate ( cPacket *  msg) [protected, virtual]

Definition at line 364 of file AnsaPPP.cc.

Referenced by startTransmitting().

{
    PPPFrame *pppFrame = new PPPFrame(msg->getName());
    pppFrame->setByteLength(PPP_OVERHEAD_BYTES);
    pppFrame->encapsulate(msg);
    return pppFrame;
}
virtual InterfaceEntry* AnsaPPP::getInterfaceEntry ( void  ) [inline, virtual]

Definition at line 78 of file AnsaPPP.h.

Referenced by receiveChangeNotification().

{ return interfaceEntry; }
void AnsaPPP::handleMessage ( cMessage *  msg) [protected, virtual]

Definition at line 181 of file AnsaPPP.cc.

{
    if (datarateChannel==NULL)
    {
        EV << "Interface is not connected, dropping packet " << msg << endl;
        delete msg;
        numDroppedIfaceDown++;
    }
    else if (disabled == true)
    {
        EV << "Interface is disabled, dropping packet " << msg << endl;
        delete msg;
        numDroppedIfaceDown++;
    }
    else if (msg==endTransmissionEvent)
    {
        // Transmission finished, we can start next one.
        EV << "Transmission finished.\n";
        if (ev.isGUI()) displayIdle();

        if (hasSubscribers)
        {
            // fire notification
            notifDetails.setPacket(NULL);
            nb->fireChangeNotification(NF_PP_TX_END, &notifDetails);
        }

        if (!txQueue.empty())
        {
            cPacket *pk = (cPacket *) txQueue.pop();
            startTransmitting(pk);
            numSent++;
        }
        else if (queueModule)
        {
            // tell queue module that we've become idle
            queueModule->requestPacket();
        }
    }
    else if (msg->arrivedOn("phys$i"))
    {
        if (hasSubscribers)
        {
            // fire notification
            notifDetails.setPacket(PK(msg));
            nb->fireChangeNotification(NF_PP_RX_END, &notifDetails);
        }

        // check for bit errors
        if (PK(msg)->hasBitError())
        {
            EV << "Bit error in " << msg << endl;
            numBitErr++;
            delete msg;
        }
        else
        {
            // pass up payload
            cPacket *payload = decapsulate(check_and_cast<PPPFrame *>(msg));
            numRcvdOK++;
            send(payload,"netwOut");
        }
    }
    else // arrived on gate "netwIn"
    {
        if (endTransmissionEvent->isScheduled())
        {
            // We are currently busy, so just queue up the packet.
            EV << "Received " << msg << " for transmission but transmitter busy, queueing.\n";
            if (ev.isGUI() && txQueue.length()>=3) getDisplayString().setTagArg("i",1,"red");

            if (txQueueLimit && txQueue.length()>txQueueLimit)
                error("txQueue length exceeds %d -- this is probably due to "
                      "a bogus app model generating excessive traffic "
                      "(or if this is normal, increase txQueueLimit!)",
                      txQueueLimit);

            txQueue.insert(msg);
        }
        else
        {
            // We are idle, so we can start transmitting right away.
            EV << "Received " << msg << " for transmission\n";
            startTransmitting(PK(msg));
            numSent++;
        }
    }

    if (ev.isGUI())
        updateDisplayString();

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

Definition at line 43 of file AnsaPPP.cc.

{
    // all initialization is done in the first stage
    if (stage==0)
    {
        txQueue.setName("txQueue");
        endTransmissionEvent = new cMessage("pppEndTxEvent");

        txQueueLimit = par("txQueueLimit");
        
        disabled = false;
        WATCH(disabled);

        interfaceEntry = NULL;

        numSent = numRcvdOK = numBitErr = numDroppedIfaceDown = 0;
        WATCH(numSent);
        WATCH(numRcvdOK);
        WATCH(numBitErr);
        WATCH(numDroppedIfaceDown);

        // find queueModule
        queueModule = NULL;
        if (par("queueModule").stringValue()[0])
        {
            cModule *mod = getParentModule()->getSubmodule(par("queueModule").stringValue());
            queueModule = check_and_cast<IPassiveQueue *>(mod);
        }

        // remember the output gate now, to speed up send()
        physOutGate = gate("phys$o");

        // we're connected if other end of connection path is an input gate
        bool connected = physOutGate->getPathEndGate()->getType()==cGate::INPUT;

        // if we're connected, get the gate with transmission rate
        datarateChannel = connected ? physOutGate->getTransmissionChannel() : NULL;
        double datarate = connected ? datarateChannel->par("datarate").doubleValue() : 0;

        // register our interface entry in IInterfaceTable
        interfaceEntry = registerInterface(datarate);

        // prepare to fire notifications
        nb = NotificationBoardAccess().get();
        nb->subscribe(this, NF_INTERFACE_STATE_CHANGED);
        notifDetails.setInterfaceEntry(interfaceEntry);
        nb->subscribe(this, NF_SUBSCRIBERLIST_CHANGED);
        updateHasSubcribers();

        // display string stuff
        if (ev.isGUI())
        {
            if (connected) {
                oldConnColor = datarateChannel->getDisplayString().getTagArg("o",0);
            }
            else {
                // we are not connected: gray out our icon
                getDisplayString().setTagArg("i",1,"#707070");
                getDisplayString().setTagArg("i",2,"100");
            }
        }

        // request first frame to send
        if (queueModule)
        {
            EV << "Requesting first frame from queue module\n";
            queueModule->requestPacket();
        }
    }

    // update display string when addresses have been autoconfigured etc.
    if (stage==3)
    {
        updateDisplayString();
    }
}
virtual bool AnsaPPP::isDisabled ( void  ) [inline, virtual]

Definition at line 80 of file AnsaPPP.h.

Referenced by receiveChangeNotification().

{ return disabled; }
virtual int AnsaPPP::numInitStages ( ) const [inline, protected, virtual]

Definition at line 83 of file AnsaPPP.h.

{return 4;}
void AnsaPPP::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [protected, virtual]

Called by the NotificationBoard whenever a change of a category occurs to which this client has subscribed.

Implements INotifiable.

Definition at line 332 of file AnsaPPP.cc.

{
    if (category==NF_SUBSCRIBERLIST_CHANGED)
        updateHasSubcribers();

    else if (category==NF_INTERFACE_STATE_CHANGED) // change state of notified interface
    {
        InterfaceEntry *entry = check_and_cast<InterfaceEntry*>(details);

        if(interfaceEntry == entry && entry->isDown() != isDisabled())
        {
          setDisabled(entry->isDown());

          if(datarateChannel!=NULL)
          {
           AnsaPPP *neighInt = dynamic_cast<AnsaPPP*>(physOutGate->getPathEndGate()->getOwnerModule());

           if((neighInt != NULL) && (neighInt->isDisabled() != isDisabled()))
           {
              InterfaceStateManager *stMng = check_and_cast<InterfaceStateManager*>(neighInt->getParentModule()->getParentModule()->getSubmodule("interfaceStateManager"));

              if(stMng != NULL)
              {
                EV << "Changing state of the interface on the other site of link" << endl;
                stMng->changeInterfaceState(neighInt->getInterfaceEntry(), isDisabled());
              }
           }
          }
        }
    }
}
InterfaceEntry * AnsaPPP::registerInterface ( double  datarate) [protected, virtual]

Definition at line 120 of file AnsaPPP.cc.

Referenced by initialize().

{
    InterfaceEntry *e = new InterfaceEntry();

    // interface name: our module name without special characters ([])
    char *interfaceName = new char[strlen(getParentModule()->getFullName())+1];
    char *d=interfaceName;
    for (const char *s=getParentModule()->getFullName(); *s; s++)
        if (isalnum(*s))
            *d++ = *s;
    *d = '\0';

    e->setName(interfaceName);
    delete [] interfaceName;

    // data rate
    e->setDatarate(datarate);

    // generate a link-layer address to be used as interface token for IPv6
    InterfaceToken token(0, simulation.getUniqueNumber(), 64);
    e->setInterfaceToken(token);

    // MTU: typical values are 576 (Internet de facto), 1500 (Ethernet-friendly),
    // 4000 (on some point-to-point links), 4470 (Cisco routers default, FDDI compatible)
    e->setMtu(4470);

    // capabilities
    e->setMulticast(true);
    e->setPointToPoint(true);

    // add
    IInterfaceTable *ift = InterfaceTableAccess().get();
    ift->addInterface(e, this);

    return e;
}
virtual void AnsaPPP::setDisabled ( bool  b) [inline, virtual]

Definition at line 79 of file AnsaPPP.h.

Referenced by receiveChangeNotification().

{ disabled = b; }
void AnsaPPP::startTransmitting ( cPacket *  msg) [protected, virtual]

Definition at line 158 of file AnsaPPP.cc.

Referenced by handleMessage().

{
    // if there's any control info, remove it; then encapsulate the packet
    delete msg->removeControlInfo();
    PPPFrame *pppFrame = encapsulate(msg);
    if (ev.isGUI()) displayBusy();

    if (hasSubscribers)
    {
        // fire notification
        notifDetails.setPacket(pppFrame);
        nb->fireChangeNotification(NF_PP_TX_BEGIN, &notifDetails);
    }

    // send
    EV << "Starting transmission of " << pppFrame << endl;
    send(pppFrame, physOutGate);

    // schedule an event for the time when last bit will leave the gate.
    simtime_t endTransmissionTime = datarateChannel->getTransmissionFinishTime();
    scheduleAt(endTransmissionTime, endTransmissionEvent);
}
void AnsaPPP::updateDisplayString ( ) [protected, virtual]

Definition at line 288 of file AnsaPPP.cc.

Referenced by handleMessage(), and initialize().

{
    if (ev.isDisabled())
    {
        // speed up things
        getDisplayString().setTagArg("t",0,"");
    }
    else if (datarateChannel!=NULL)
    {
        double datarate = datarateChannel->par("datarate").doubleValue();
        char datarateText[40];
        if (datarate>=1e9) sprintf(datarateText,"%gG", datarate/1e9);
        else if (datarate>=1e6) sprintf(datarateText,"%gM", datarate/1e6);
        else if (datarate>=1e3) sprintf(datarateText,"%gK", datarate/1e3);
        else sprintf(datarateText,"%gbps", datarate);

/* TBD find solution for displaying IP address without dependence on IPv6 or IPv6
        IPAddress addr = interfaceEntry->ipv4Data()->getIPAddress();
        sprintf(buf, "%s / %s\nrcv:%ld snt:%ld", addr.isUnspecified()?"-":addr.str().c_str(), datarateText, numRcvdOK, numSent);
*/

        char buf[80];
        sprintf(buf, "%s\nrcv:%ld snt:%ld", datarateText, numRcvdOK, numSent);

        if (numBitErr>0)
            sprintf(buf+strlen(buf), "\nerr:%ld", numBitErr);

        getDisplayString().setTagArg("t",0,buf);
    }
    else
    {
        char buf[80];
        sprintf(buf, "not connected\ndropped:%ld", numDroppedIfaceDown);
        getDisplayString().setTagArg("t",0,buf);
    }
}

Member Data Documentation

bool AnsaPPP::disabled [protected]

Definition at line 43 of file AnsaPPP.h.

Referenced by handleMessage(), and initialize().

cMessage* AnsaPPP::endTransmissionEvent [protected]

Definition at line 46 of file AnsaPPP.h.

Referenced by AnsaPPP(), handleMessage(), initialize(), startTransmitting(), and ~AnsaPPP().

bool AnsaPPP::hasSubscribers [protected]

Definition at line 53 of file AnsaPPP.h.

Referenced by handleMessage(), startTransmitting(), and updateHasSubcribers().

Definition at line 49 of file AnsaPPP.h.

Referenced by initialize(), and receiveChangeNotification().

Definition at line 51 of file AnsaPPP.h.

Referenced by handleMessage(), initialize(), startTransmitting(), and updateHasSubcribers().

Definition at line 52 of file AnsaPPP.h.

Referenced by handleMessage(), initialize(), and startTransmitting().

long AnsaPPP::numBitErr [protected]

Definition at line 60 of file AnsaPPP.h.

Referenced by handleMessage(), initialize(), and updateDisplayString().

long AnsaPPP::numDroppedIfaceDown [protected]

Definition at line 61 of file AnsaPPP.h.

Referenced by handleMessage(), initialize(), and updateDisplayString().

long AnsaPPP::numRcvdOK [protected]

Definition at line 59 of file AnsaPPP.h.

Referenced by handleMessage(), initialize(), and updateDisplayString().

long AnsaPPP::numSent [protected]

Definition at line 58 of file AnsaPPP.h.

Referenced by handleMessage(), initialize(), and updateDisplayString().

std::string AnsaPPP::oldConnColor [protected]

Definition at line 55 of file AnsaPPP.h.

Referenced by displayIdle(), and initialize().

cGate* AnsaPPP::physOutGate [protected]

Definition at line 40 of file AnsaPPP.h.

Referenced by initialize(), receiveChangeNotification(), and startTransmitting().

Definition at line 47 of file AnsaPPP.h.

Referenced by handleMessage(), and initialize().

cQueue AnsaPPP::txQueue [protected]

Definition at line 45 of file AnsaPPP.h.

Referenced by displayBusy(), handleMessage(), and initialize().

long AnsaPPP::txQueueLimit [protected]

Definition at line 39 of file AnsaPPP.h.

Referenced by handleMessage(), and initialize().


The documentation for this class was generated from the following files: