|
INET Framework for OMNeT++/OMNEST
|
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