![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WiMeMac * 00003 * This file is part of openWNS (open Wireless Network Simulator) 00004 * _____________________________________________________________________________ 00005 * 00006 * Copyright (C) 2004-2011 00007 * Chair of Communication Networks (ComNets) 00008 * Kopernikusstr. 5, D-52074 Aachen, Germany 00009 * phone: ++49-241-80-27910, 00010 * fax: ++49-241-80-22242 00011 * email: info@openwns.org 00012 * www: http://www.openwns.org 00013 * _____________________________________________________________________________ 00014 * 00015 * openWNS is free software; you can redistribute it and/or modify it under the 00016 * terms of the GNU Lesser General Public License version 2 as published by the 00017 * Free Software Foundation; 00018 * 00019 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00021 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00022 * details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public License 00025 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00026 * 00027 ******************************************************************************/ 00028 00029 #include <WIMEMAC/helper/Queues.hpp> 00030 #include <DLL/UpperConvergence.hpp> 00031 00032 using namespace wimemac::helper; 00033 00034 Queues::Queues(const wns::pyconfig::View& _config, wns::ldk::fun::FUN* fun): 00035 maxSize(_config.get<long int>("queuesize")), 00036 FrameDuration(_config.get<wns::simulator::Time>("frameduration")), 00037 logger(_config.get("logger")), 00038 config(_config) 00039 { 00040 friends.keyReader = fun->getProxy()->getCommandReader("upperConvergence"); 00041 00042 scheduler = wns::simulator::getEventScheduler(); 00043 deleteQueues = _config.get<bool>("deleteQueues"); 00044 nextPCAReceiver = wns::service::dll::UnicastAddress(); 00045 } 00046 00047 bool 00048 Queues::isAccepting(const wns::ldk::CompoundPtr& compound) const 00049 { 00050 int size = compound->getLengthInBits(); 00051 00052 wns::ldk::CommandPool* commandPool = compound->getCommandPool(); 00053 dll::UpperCommand* unicastcommand = 00054 friends.keyReader->readCommand<dll::UpperCommand>(commandPool); 00055 wns::service::dll::UnicastAddress rx = unicastcommand->peer.targetMACAddress; 00056 00057 if(queues.find(rx) == queues.end()) 00058 { 00059 MESSAGE_SINGLE(NORMAL, logger, "Compound with size " << size 00060 <<" is accepted, a new queue will be created for target "<<rx); 00061 00062 return true; 00063 } 00064 00065 if(size + queues.find(rx)->second.bits > maxSize) 00066 { 00067 MESSAGE_SINGLE(NORMAL, logger, "Compound with size " << size 00068 <<" is not accepted, because queue size is" 00069 << queues.find(rx)->second.bits << " for target " << rx); 00070 00071 return false; 00072 } 00073 00074 // MESSAGE_SINGLE(NORMAL, logger, "Compound with size " << size 00075 // <<" accepted, because queue size is" 00076 // << queues.find(rx)->second.bits << " for target " << rx); 00077 00078 return true; 00079 } 00080 00081 void 00082 Queues::put(const wns::ldk::CompoundPtr& compound) 00083 { 00084 assure(compound, "No valid PDU"); 00085 assure(compound != wns::ldk::CompoundPtr(), "No valid PDU"); 00086 assure(isAccepting(compound), "sendData() has been called without isAccepting()"); 00087 00088 wns::ldk::CommandPool* commandPool = compound->getCommandPool(); 00089 dll::UpperCommand* unicastcommand = 00090 friends.keyReader->readCommand<dll::UpperCommand>(commandPool); 00091 wns::service::dll::UnicastAddress rx = unicastcommand->peer.targetMACAddress; 00092 00093 00094 //MESSAGE_SINGLE(NORMAL, logger, "Compound for " << rx ); 00095 00096 // If this is a new queue initialize RemoveCompounds variable with config value 00097 if (queues.find(rx) == queues.end()) queues[rx].RemoveCompounds = deleteQueues; 00098 00099 (queues[rx].pduQueue).push_back(compound); 00100 queues[rx].bits += compound->getLengthInBits(); 00101 } 00102 00103 void 00104 Queues::putFront(const wns::ldk::CompoundPtr& compound, wns::service::dll::UnicastAddress rx) 00105 { 00106 MESSAGE_SINGLE(NORMAL, logger, "Compound for " << rx << " is being re-inserted to the front of the queue"); 00107 00108 (queues[rx].pduQueue).push_back(compound); 00109 queues[rx].bits += compound->getLengthInBits(); 00110 } 00111 00112 wns::ldk::CompoundPtr 00113 Queues::getHeadOfLinePDU(wns::service::dll::UnicastAddress rx) 00114 { 00115 assure(queueHasPDUs(rx), "getHeadOfLinePDU called for mac without PDUs or on existing mac"); 00116 00117 wns::ldk::CompoundPtr pdu = queues[rx].pduQueue.front(); 00118 queues[rx].pduQueue.pop_front(); 00119 queues[rx].bits -= pdu->getLengthInBits(); 00120 00121 return pdu; 00122 } 00123 00124 int 00125 Queues::getHeadOfLinePDUbits(wns::service::dll::UnicastAddress rx) 00126 { 00127 assure(queueHasPDUs(rx), "getHeadOfLinePDUbits called for mac without PDUs or non-existent mac " << rx); 00128 return queues[rx].pduQueue.front()->getLengthInBits(); 00129 } 00130 00131 bool 00132 Queues::hasQueue(wns::service::dll::UnicastAddress rx) 00133 { 00134 return queues.find(rx) != queues.end(); 00135 } 00136 00137 bool 00138 Queues::queueHasPDUs(wns::service::dll::UnicastAddress rx) 00139 { 00140 if (queues.find(rx) == queues.end()) 00141 return false; 00142 else 00143 { 00144 if(queues[rx].RemoveCompounds == true) 00145 { 00146 RemoveCompounds(rx); 00147 queues[rx].RemoveCompounds = false; 00148 MESSAGE_SINGLE(NORMAL, logger, "Deleting Queue on startUp"); 00149 return false; 00150 } 00151 return (queues[rx].pduQueue.size() != 0); 00152 } 00153 } 00154 00155 00156 std::string 00157 Queues::printAllQueues() 00158 { 00159 std::stringstream s; 00160 for (std::map<wns::service::dll::UnicastAddress, Queue>::iterator iter = queues.begin(); 00161 iter != queues.end(); ++iter) 00162 { 00163 wns::service::dll::UnicastAddress rx = iter->first; 00164 int bits = iter->second.bits; 00165 int compounds = iter->second.pduQueue.size(); 00166 s << rx << ":" << bits << "," << compounds << " "; 00167 } 00168 return s.str(); 00169 } 00170 00171 void 00172 Queues::RemoveCompounds(wns::service::dll::UnicastAddress rx) 00173 { 00174 while (!queues[rx].pduQueue.empty()) 00175 { 00176 queues[rx].pduQueue.pop_front(); 00177 } 00178 00179 queues[rx].bits = 0; 00180 MESSAGE_SINGLE(NORMAL, logger, "Clear queue for target: " << rx 00181 <<" Queue size now: " << queues[rx].pduQueue.size()); 00182 } 00183 00184 wns::service::dll::UnicastAddress 00185 Queues::getNextPCAReceiver() 00186 { 00187 // If nextPCAReceiver was not initialized yet, but there is a Queue, set it to the first Queue storing compounds 00188 if(nextPCAReceiver == wns::service::dll::UnicastAddress() && queues.size() > 0) 00189 { 00190 for (std::map<wns::service::dll::UnicastAddress, Queue>::iterator iter = queues.begin(); 00191 iter != queues.end(); ++iter) 00192 { 00193 if(iter->second.pduQueue.size() > 0) 00194 { 00195 nextPCAReceiver = iter->first; 00196 break; 00197 } 00198 } 00199 } 00200 00201 if(queues[nextPCAReceiver].pduQueue.size() == 0) 00202 { 00203 MESSAGE_SINGLE(NORMAL, logger, "The last set PCA Receiver has no compounds in Queue due to DRP transmissions"); 00204 changePCAreceiver(); 00205 } 00206 00207 return nextPCAReceiver; 00208 } 00209 00210 void 00211 Queues::changePCAreceiver() 00212 { 00213 bool foundNewPCAreceiver = false; 00214 wns::service::dll::UnicastAddress oldPCAreceiver = nextPCAReceiver; 00215 std::map<wns::service::dll::UnicastAddress, Queue>::iterator iter_oldPCArec; 00216 for (std::map<wns::service::dll::UnicastAddress, Queue>::iterator iter = queues.begin(); 00217 iter != queues.end(); ++iter) 00218 { 00219 if(iter->first == oldPCAreceiver) 00220 { 00221 iter_oldPCArec = iter; 00222 break; 00223 } 00224 } 00225 00226 for (std::map<wns::service::dll::UnicastAddress, Queue>::iterator iter = ++iter_oldPCArec; 00227 iter != queues.end(); ++iter) 00228 { 00229 if(iter->second.pduQueue.size() > 0) 00230 { 00231 nextPCAReceiver = iter->first; 00232 foundNewPCAreceiver = true; 00233 break; 00234 } 00235 } 00236 00237 if(!foundNewPCAreceiver) 00238 { 00239 for (std::map<wns::service::dll::UnicastAddress, Queue>::iterator iter = queues.begin(); 00240 iter != queues.end(); ++iter) 00241 { 00242 if(iter->second.pduQueue.size() > 0) 00243 { 00244 nextPCAReceiver = iter->first; 00245 foundNewPCAreceiver = true; 00246 break; 00247 } 00248 } 00249 } 00250 00251 if(!foundNewPCAreceiver) nextPCAReceiver = wns::service::dll::UnicastAddress(); 00252 MESSAGE_SINGLE(NORMAL, logger, "Next PCA Receiver will be " << nextPCAReceiver << " with " << queues[nextPCAReceiver].pduQueue.size() << " waiting compounds"); 00253 }
1.5.5