EPONImplementationforOMNet++  0.8Beta
EPON_mac Class Reference

EPON_mac class is actually the EtherMAC2 class modified. More...

#include <EPON_mac.h>

List of all members.

Public Member Functions

 EPON_mac ()
virtual ~EPON_mac ()

Protected Member Functions

virtual void initialize ()
virtual void finalize ()
virtual void initializeTxrate ()
virtual void handleMessage (cMessage *msg)
virtual void startFrameTransmission ()
 When Tx starts we have already added Logical Link Identifier.
virtual void processFrameFromUpperLayer (EtherFrame *frame)
virtual void processMsgFromNetwork (cPacket *msg)
virtual void handleEndIFGPeriod ()
virtual void handleEndTxPeriod ()
virtual void updateHasSubcribers ()
void scheduleEndTxPeriod (cPacket *frame)

Protected Attributes

cOutVector TxRateVector

Detailed Description

EPON_mac class is actually the EtherMAC2 class modified.

From the INET framework documentation:

"A simplified version of EtherMAC. Since modern Ethernets typically operate over duplex links where's no contention, the original CSMA/CD algorithm is no longer needed. This simplified implementation doesn't contain CSMA/CD, frames are just simply queued and sent out one by one."

We use this class for some basic operations. The first one (and most important) is to change the way the frame is transmitted. On EPON network the Ethernet pre-amble includes the LLID (Logical Link ID). This LLID is carried, from the higher layers, inside the cMessage ControInfo. Thus what we do here is too remove the ControlInfo and use them in EtherFrameWithLLID. The original message is encapsulated inside this frame. Finally the preamble is added (-2 Bytes cause they are already in the EtherFrameWithLLID) and the SFD. For incoming frame from the network we do the opposite process (decapsulate the frame and add ControlInfo)

The second usage of this module is to handle the IFG times that, based on the drafts, should be there.

Finally note here that the basic control of the transmission times is located in the MacCtl modules (ONUMacCtl & OLTMacCtl), thus most of the times the queue this module has is not used at all.


Constructor & Destructor Documentation

EPON_mac::~EPON_mac ( ) [virtual]
                   {
      for (int i=0; i<txQueue.length(); i++)
            delete txQueue.pop();
}

Member Function Documentation

void EPON_mac::finalize ( ) [protected, virtual]
                       {
      // Do logging
      if (!disabled)
      {
            simtime_t t = simTime();
            if (t>0)
            {
//                recordScalar("frames/sec sent", TxRateVector);
            }
      }
}
void EPON_mac::handleEndTxPeriod ( ) [protected, virtual]
{
    if (hasSubscribers)
    {
        // fire notification
        notifDetails.setPacket((cPacket *)txQueue.front());
        nb->fireChangeNotification(NF_PP_TX_END, &notifDetails);
    }

    if (checkAndScheduleEndPausePeriod())
        return;


    // Deletes the frame... and log stats
    EtherMACBase::handleEndTxPeriod();


    beginSendFrames();
}
void EPON_mac::handleMessage ( cMessage *  msg) [protected, virtual]
{
    if (!connected)
        processMessageWhenNotConnected(msg);
    else if (disabled)
        processMessageWhenDisabled(msg);
    else if (msg->isSelfMessage())
    {
        EV << "Self-message " << msg << " received\n";

        if (msg == endTxMsg)
            handleEndTxPeriod();
        else if (msg == endIFGMsg)
            handleEndIFGPeriod();
        else if (msg == endPauseMsg)
            handleEndPausePeriod();
        else
            error("Unknown self message received!");
    }
    else
    {
        if (msg->getArrivalGate() == gate("upperLayerIn"))
            processFrameFromUpperLayer(check_and_cast<EtherFrame *>(msg));
        else if (msg->getArrivalGate() == gate("phys$i") ||
                  msg->getArrivalGate() == gate("direct")) {
            processMsgFromNetwork(check_and_cast<cPacket *>(msg));
        }else
            error("Message received from unknown gate!");
    }

    if (ev.isGUI())  updateDisplayString();
}
void EPON_mac::initialize ( ) [protected, virtual]
{
    EtherMACBase::initialize();

    duplexMode = true;
    calculateParameters();

    beginSendFrames();
}
void EPON_mac::initializeTxrate ( ) [protected, virtual]
{
    // if we're connected, find the gate with transmission rate
    txrate = 0;

    if (connected)
    {
        // obtain txrate from channel. As a side effect, this also asserts
        // that the other end is an EPON_mac, since normal EtherMAC
        // insists that the connection has *no* datarate set.
        // if we're connected, get the gate with transmission rate
        cChannel *datarateChannel = physOutGate->getTransmissionChannel();
        txrate = datarateChannel->par("datarate").doubleValue();
    }
}
void EPON_mac::processFrameFromUpperLayer ( EtherFrame *  frame) [protected, virtual]
{
      EV << "Received frame from upper layer: " << frame << endl;

      if (frame->getDest().equals(address))
      {
            error("logic error: frame %s from higher layer has local MAC address as dest (%s)",
                    frame->getFullName(), frame->getDest().str().c_str());
      }

      if (frame->getByteLength() > MAX_ETHERNET_FRAME_D1Q)
            error("packet from higher layer (%d bytes) exceeds maximum Ethernet frame size (%d)", frame->getByteLength(), MAX_ETHERNET_FRAME_D1Q);

      // must be EtherFrame (or EtherPauseFrame) from upper layer
      bool isPauseFrame = (dynamic_cast<EtherPauseFrame*>(frame)!=NULL);
      if (!isPauseFrame)
      {
            numFramesFromHL++;

            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);

            // fill in src address if not set
            if (frame->getSrc().isUnspecified())
                  frame->setSrc(address);


             // Note: take the control from the origial frame. Dup() does not clone it.
            EPON_LLidCtrlInfo *nfo=dynamic_cast<EPON_LLidCtrlInfo *>(frame->getControlInfo());
            EtherFrameWithLLID * llid_eth = new EtherFrameWithLLID();
            llid_eth->setName(frame->getName());

            if (nfo != NULL){
                  EV << "Control Info FOUND"<<endl;
                  // Convert to EtherFrameWithLLID

                  uint16_t tmpLlid = nfo->llid;
                  // Relay didn't knew the llid...
                  if (tmpLlid == -1)
                        tmpLlid=LLID_EPON_BC;
                  llid_eth->setLlid(tmpLlid);
            }else{
            // MPCP Frames may not have LLIDs
            // Encapsulate BC
                  uint16_t tmpLlid = LLID_EPON_BC;
                  llid_eth->setLlid(tmpLlid);
          }


            /*
             * YOU HAVE TO MANUALLY SET THE BYTE LENGTH...
             */
            llid_eth->addByteLength(2);   // add for the 2 bytes in the preamble
            frame->addByteLength(EPON_PREAMBLE_BYTES+SFD_BYTES); // add the rest
            llid_eth->encapsulate(frame);
            //frame=NULL;

            // store frame and possibly begin transmitting
            EV << "Packet " << llid_eth << " arrived from higher layers, enqueueing\n";
            EV << "After enc Size " << llid_eth->getByteLength()<< " \n";
            EV << "Orig. Size " << frame->getByteLength()<< " \n";

            txQueue.insert(llid_eth);

      }
      else
      {
            EV << "PAUSE received from higher layer\n";

            // PAUSE frames enjoy priority -- they're transmitted before all other frames queued up
            if (!txQueue.empty())
                  txQueue.insertBefore(txQueue.front(), frame);  // front() frame is probably being transmitted
            else
                  txQueue.insert(frame);
      }


      // In any case, wait for IFG before transmitting
    if (transmitState == TX_IDLE_STATE)
      scheduleEndIFGPeriod();
}
void EPON_mac::processMsgFromNetwork ( cPacket *  msg) [protected, virtual]
{
    //EtherMACBase::processMsgFromNetwork(msg);
      // the original ^ checks for frame type and for cable length...
      // both not applicable here...

       EtherFrame *ethframe = dynamic_cast<EtherFrame *>(msg);
       EtherFrameWithLLID * ethllid= dynamic_cast<EtherFrameWithLLID *>(msg);

      if ( ethframe== NULL && ethllid== NULL){
            error("EPON_mac: Unrecognized Frame... Shit happens");
      }

      // IF we have EPON frame with LLID de-capsulate
      if (ethllid){
            ethframe = check_and_cast<EtherFrame *>(ethllid->decapsulate());
            delete ethllid->decapsulate();
            // Add Control Information to it
            EV << "IT HAD LLID INFO ... : "<<ethllid->getLlid()<<endl;
            if (ethframe->getControlInfo()==NULL)
            ethframe->setControlInfo(new EPON_LLidCtrlInfo(ethllid->getLlid()) );
            // Add original pre-amble.. to be used from the base class...
            ethframe->addByteLength(-EPON_PREAMBLE_BYTES);
            ethframe->addByteLength(PREAMBLE_BYTES);
            // Get rid of the original
            delete msg;
      }



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

    if (checkDestinationAddress(ethframe))
        frameReceptionComplete(ethframe);
}
void EPON_mac::scheduleEndTxPeriod ( cPacket *  frame) [protected]
void EPON_mac::startFrameTransmission ( ) [protected, virtual]

When Tx starts we have already added Logical Link Identifier.

{
      EtherFrameWithLLID *origFrame = (EtherFrameWithLLID *)txQueue.front();
    EV << "Transmitting a copy of frame " << origFrame << endl;

    EtherFrameWithLLID *frame = (EtherFrameWithLLID *) origFrame->dup();

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

    // fill in src address if not set
//    if (frame->getSrc().isUnspecified())
//        frame->setSrc(address);

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

    // update burst variables
    if (frameBursting)
    {
        bytesSentInBurst = frame->getByteLength();
        framesSentInBurst++;
    }

}
void EPON_mac::updateHasSubcribers ( ) [protected, virtual]
{
    hasSubscribers = nb->hasSubscribers(NF_PP_TX_BEGIN) ||
                     nb->hasSubscribers(NF_PP_TX_END) ||
                     nb->hasSubscribers(NF_PP_RX_END);
}

Member Data Documentation

cOutVector EPON_mac::TxRateVector [protected]

The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Typedefs Friends Defines