User Manual, Developers Guide and API Documentation

Queues.cpp

Go to the documentation of this file.
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 }

Generated on Fri May 25 03:32:15 2012 for openWNS by  doxygen 1.5.5