INET Framework for OMNeT++/OMNEST
Ieee80211MgmtBase.cc
Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Andras Varga
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 
00019 #include "Ieee80211MgmtBase.h"
00020 #include "Ieee802Ctrl_m.h"
00021 
00022 
00023 static std::ostream& operator<< (std::ostream& out, cMessage *msg)
00024 {
00025     out << "(" << msg->getClassName() << ")" << msg->getFullName();
00026     return out;
00027 }
00028 
00029 void Ieee80211MgmtBase::initialize(int stage)
00030 {
00031     if (stage==0)
00032     {
00033         PassiveQueueBase::initialize();
00034 
00035         dataQueue.setName("wlanDataQueue");
00036         mgmtQueue.setName("wlanMgmtQueue");
00037         dataQueueLenVec.setName("queue length");
00038         dataQueueDropVec.setName("queue drop count");
00039 
00040         numDataFramesReceived = 0;
00041         numMgmtFramesReceived = 0;
00042         numMgmtFramesDropped = 0;
00043         WATCH(numDataFramesReceived);
00044         WATCH(numMgmtFramesReceived);
00045         WATCH(numMgmtFramesDropped);
00046 
00047         // configuration
00048         frameCapacity = par("frameCapacity");
00049 
00050 
00051     }
00052     else if (stage==1)
00053     {
00054         // obtain our address from MAC
00055         cModule *mac = getParentModule()->getSubmodule("mac");
00056         if (!mac)
00057             error("MAC module not found; it is expected to be next to this submodule and called 'mac'");
00058         myAddress.setAddress(mac->par("address").stringValue());
00059     }
00060 }
00061 
00062 
00063 void Ieee80211MgmtBase::handleMessage(cMessage *msg)
00064 {
00065     if (msg->isSelfMessage())
00066     {
00067         // process timers
00068         EV << "Timer expired: " << msg << "\n";
00069         handleTimer(msg);
00070     }
00071     else if (msg->arrivedOn("macIn"))
00072     {
00073         // process incoming frame
00074         EV << "Frame arrived from MAC: " << msg << "\n";
00075         Ieee80211DataOrMgmtFrame *frame = check_and_cast<Ieee80211DataOrMgmtFrame *>(msg);
00076         processFrame(frame);
00077     }
00078     else if (msg->arrivedOn("agentIn"))
00079     {
00080         // process command from agent
00081         EV << "Command arrived from agent: " << msg << "\n";
00082         int msgkind = msg->getKind();
00083         cPolymorphic *ctrl = msg->removeControlInfo();
00084         delete msg;
00085 
00086         handleCommand(msgkind, ctrl);
00087     }
00088     else
00089     {
00090         // packet from upper layers, to be sent out
00091         cPacket *pk = PK(msg);
00092         EV << "Packet arrived from upper layers: " << pk << "\n";
00093         if (pk->getByteLength() > 2312)
00094             error("message from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)",
00095                   pk->getClassName(), pk->getName(), (int)(pk->getByteLength()));
00096 
00097         handleUpperMessage(pk);
00098     }
00099 }
00100 
00101 void Ieee80211MgmtBase::sendOrEnqueue(cPacket *frame)
00102 {
00103     PassiveQueueBase::handleMessage(frame);
00104 }
00105 
00106 bool Ieee80211MgmtBase::enqueue(cMessage *msg)
00107 {
00108     ASSERT(dynamic_cast<Ieee80211DataOrMgmtFrame *>(msg)!=NULL);
00109     bool isDataFrame = dynamic_cast<Ieee80211DataFrame *>(msg)!=NULL;
00110 
00111     if (!isDataFrame)
00112     {
00113         // management frames are inserted into mgmtQueue
00114         mgmtQueue.insert(msg);
00115         return false;
00116     }
00117     else if (frameCapacity && dataQueue.length() >= frameCapacity)
00118     {
00119         EV << "Queue full, dropping packet.\n";
00120         delete msg;
00121         dataQueueDropVec.record(1);
00122         return true;
00123     }
00124     else
00125     {
00126         dataQueue.insert(msg);
00127         dataQueueLenVec.record(dataQueue.length());
00128         return false;
00129     }
00130 }
00131 
00132 cMessage *Ieee80211MgmtBase::dequeue()
00133 {
00134     // management frames have priority
00135     if (!mgmtQueue.empty())
00136         return (cMessage *)mgmtQueue.pop();
00137 
00138     // return a data frame if we have one
00139     if (dataQueue.empty())
00140         return NULL;
00141 
00142     cMessage *pk = (cMessage *)dataQueue.pop();
00143 
00144     // statistics
00145     dataQueueLenVec.record(dataQueue.length());
00146     return pk;
00147 }
00148 
00149 void Ieee80211MgmtBase::sendOut(cMessage *msg)
00150 {
00151     send(msg, "macOut");
00152 }
00153 
00154 void Ieee80211MgmtBase::dropManagementFrame(Ieee80211ManagementFrame *frame)
00155 {
00156     EV << "ignoring management frame: " << (cMessage *)frame << "\n";
00157     delete frame;
00158     numMgmtFramesDropped++;
00159 }
00160 
00161 cPacket *Ieee80211MgmtBase::decapsulate(Ieee80211DataFrame *frame)
00162 {
00163     cPacket *payload = frame->decapsulate();
00164 
00165     Ieee802Ctrl *ctrl = new Ieee802Ctrl();
00166     ctrl->setSrc(frame->getAddress3());
00167     ctrl->setDest(frame->getReceiverAddress());
00168     payload->setControlInfo(ctrl);
00169 
00170     delete frame;
00171     return payload;
00172 }
00173 
00174 void Ieee80211MgmtBase::sendUp(cMessage *msg)
00175 {
00176     send(msg, "uppergateOut");
00177 }
00178 
00179 void Ieee80211MgmtBase::processFrame(Ieee80211DataOrMgmtFrame *frame)
00180 {
00181     switch(frame->getType())
00182     {
00183       case ST_DATA:
00184         numDataFramesReceived++;
00185         handleDataFrame(check_and_cast<Ieee80211DataFrame *>(frame));
00186         break;
00187       case ST_AUTHENTICATION:
00188         numMgmtFramesReceived++;
00189         handleAuthenticationFrame(check_and_cast<Ieee80211AuthenticationFrame *>(frame));
00190         break;
00191       case ST_DEAUTHENTICATION:
00192         numMgmtFramesReceived++;
00193         handleDeauthenticationFrame(check_and_cast<Ieee80211DeauthenticationFrame *>(frame));
00194         break;
00195       case ST_ASSOCIATIONREQUEST:
00196         numMgmtFramesReceived++;
00197         handleAssociationRequestFrame(check_and_cast<Ieee80211AssociationRequestFrame *>(frame));
00198         break;
00199       case ST_ASSOCIATIONRESPONSE:
00200         numMgmtFramesReceived++;
00201         handleAssociationResponseFrame(check_and_cast<Ieee80211AssociationResponseFrame *>(frame));
00202         break;
00203       case ST_REASSOCIATIONREQUEST:
00204         numMgmtFramesReceived++;
00205         handleReassociationRequestFrame(check_and_cast<Ieee80211ReassociationRequestFrame *>(frame));
00206         break;
00207       case ST_REASSOCIATIONRESPONSE:
00208         numMgmtFramesReceived++;
00209         handleReassociationResponseFrame(check_and_cast<Ieee80211ReassociationResponseFrame *>(frame)); break;
00210       case ST_DISASSOCIATION:
00211         numMgmtFramesReceived++;
00212         handleDisassociationFrame(check_and_cast<Ieee80211DisassociationFrame *>(frame));
00213         break;
00214       case ST_BEACON:
00215         numMgmtFramesReceived++;
00216         handleBeaconFrame(check_and_cast<Ieee80211BeaconFrame *>(frame));
00217         break;
00218       case ST_PROBEREQUEST:
00219         numMgmtFramesReceived++;
00220         handleProbeRequestFrame(check_and_cast<Ieee80211ProbeRequestFrame *>(frame));
00221         break;
00222       case ST_PROBERESPONSE:
00223         numMgmtFramesReceived++;
00224         handleProbeResponseFrame(check_and_cast<Ieee80211ProbeResponseFrame *>(frame));
00225         break;
00226       default:
00227         error("unexpected frame type (%s)%s", frame->getClassName(), frame->getName());
00228     }
00229 }
00230