EtherMAC2.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Levente Meszaros
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <omnetpp.h>
00021 #include "EtherMAC2.h"
00022 #include "IPassiveQueue.h"
00023 #include "NotificationBoard.h"
00024 #include "NotifierConsts.h"
00025 
00026 Define_Module(EtherMAC2);
00027 
00028 EtherMAC2::EtherMAC2()
00029 {
00030 }
00031 
00032 void EtherMAC2::initialize()
00033 {
00034     EtherMACBase::initialize();
00035 
00036     duplexMode = true;
00037     calculateParameters();
00038 
00039     beginSendFrames();
00040 }
00041 
00042 void EtherMAC2::initializeTxrate()
00043 {
00044     // if we're connected, find the gate with transmission rate
00045     txrate = 0;
00046 
00047     if (connected)
00048     {
00049         // obtain txrate from channel. As a side effect, this also asserts
00050         // that the other end is an EtherMAC2, since normal EtherMAC
00051         // insists that the connection has *no* datarate set.
00052         // if we're connected, get the gate with transmission rate
00053         cChannel *datarateChannel = physOutGate->getTransmissionChannel();
00054         txrate = datarateChannel->par("datarate").doubleValue();
00055     }
00056 }
00057 
00058 void EtherMAC2::handleMessage(cMessage *msg)
00059 {
00060     if (!connected)
00061         processMessageWhenNotConnected(msg);
00062     else if (disabled)
00063         processMessageWhenDisabled(msg);
00064     else if (msg->isSelfMessage())
00065     {
00066         EV << "Self-message " << msg << " received\n";
00067 
00068         if (msg == endTxMsg)
00069             handleEndTxPeriod();
00070         else if (msg == endIFGMsg)
00071             handleEndIFGPeriod();
00072         else if (msg == endPauseMsg)
00073             handleEndPausePeriod();
00074         else
00075             error("Unknown self message received!");
00076     }
00077     else
00078     {
00079         if (msg->getArrivalGate() == gate("upperLayerIn"))
00080             processFrameFromUpperLayer(check_and_cast<EtherFrame *>(msg));
00081         else if (msg->getArrivalGate() == gate("phys$i"))
00082             processMsgFromNetwork(check_and_cast<EtherFrame *>(msg));
00083         else
00084             error("Message received from unknown gate!");
00085     }
00086 
00087     if (ev.isGUI())  updateDisplayString();
00088 }
00089 
00090 void EtherMAC2::startFrameTransmission()
00091 {
00092     EtherFrame *origFrame = (EtherFrame *)txQueue.front();
00093     EV << "Transmitting a copy of frame " << origFrame << endl;
00094 
00095     EtherFrame *frame = (EtherFrame *) origFrame->dup();
00096     frame->addByteLength(PREAMBLE_BYTES+SFD_BYTES);
00097 
00098     if (hasSubscribers)
00099     {
00100         // fire notification
00101         notifDetails.setPacket(frame);
00102         nb->fireChangeNotification(NF_PP_TX_BEGIN, &notifDetails);
00103     }
00104 
00105     // fill in src address if not set
00106     if (frame->getSrc().isUnspecified())
00107         frame->setSrc(address);
00108 
00109     // send
00110     EV << "Starting transmission of " << frame << endl;
00111     send(frame, physOutGate);
00112     scheduleEndTxPeriod(frame);
00113 
00114     // update burst variables
00115     if (frameBursting)
00116     {
00117         bytesSentInBurst = frame->getByteLength();
00118         framesSentInBurst++;
00119     }
00120 }
00121 
00122 void EtherMAC2::processFrameFromUpperLayer(EtherFrame *frame)
00123 {
00124     EtherMACBase::processFrameFromUpperLayer(frame);
00125 
00126     if (transmitState == TX_IDLE_STATE)
00127         startFrameTransmission();
00128 }
00129 
00130 void EtherMAC2::processMsgFromNetwork(cPacket *msg)
00131 {
00132     EtherMACBase::processMsgFromNetwork(msg);
00133     EtherFrame *frame = check_and_cast<EtherFrame *>(msg);
00134 
00135     if (hasSubscribers)
00136     {
00137         // fire notification
00138         notifDetails.setPacket(frame);
00139         nb->fireChangeNotification(NF_PP_RX_END, &notifDetails);
00140     }
00141 
00142     if (checkDestinationAddress(frame))
00143         frameReceptionComplete(frame);
00144 }
00145 
00146 void EtherMAC2::handleEndIFGPeriod()
00147 {
00148     EtherMACBase::handleEndIFGPeriod();
00149 
00150     startFrameTransmission();
00151 }
00152 
00153 void EtherMAC2::handleEndTxPeriod()
00154 {
00155     if (hasSubscribers)
00156     {
00157         // fire notification
00158         notifDetails.setPacket((cPacket *)txQueue.front());
00159         nb->fireChangeNotification(NF_PP_TX_END, &notifDetails);
00160     }
00161 
00162     if (checkAndScheduleEndPausePeriod())
00163         return;
00164 
00165     EtherMACBase::handleEndTxPeriod();
00166 
00167     beginSendFrames();
00168 }
00169 
00170 void EtherMAC2::updateHasSubcribers()
00171 {
00172     hasSubscribers = nb->hasSubscribers(NF_PP_TX_BEGIN) ||
00173                      nb->hasSubscribers(NF_PP_TX_END) ||
00174                      nb->hasSubscribers(NF_PP_RX_END);
00175 }
00176