User Manual, Developers Guide and API Documentation

ARQ.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/arq/ARQ.hpp>
00030 #include <DLL/Layer2.hpp>
00031 
00032 
00033 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00034     wimemac::arq::ARQ,
00035     wns::ldk::FunctionalUnit,
00036     "wimemac.arq.ARQ",
00037     wns::ldk::FUNConfigCreator );
00038 
00039 using namespace wimemac::arq;
00040 
00041 ARQ::ARQ( wns::ldk::fun::FUN* _fun, const wns::pyconfig::View& config_ ) :
00042         wns::ldk::fu::Plain<ARQ, ARQCommand>(_fun),
00043         logger(config_.get("logger")),
00044         managerName(config_.get<std::string>("managerName")),
00045         fun(_fun),
00046         retrans(0),
00047         SIFS(10E-6),
00048         AckDuration(13.125E-6)
00049 {
00050     scheduler = wns::simulator::getEventScheduler();
00051 }
00052 
00053 void 
00054 ARQ::doOnData( const wns::ldk::CompoundPtr& compound )
00055 {
00056     dll::UpperCommand* command = fun->getCommandReader("upperConvergence")
00057         ->readCommand<dll::UpperCommand>(compound->getCommandPool());
00058 
00059     if(command->peer.targetMACAddress != ownaddress)
00060     {
00061         MESSAGE_SINGLE(NORMAL, this->logger, "Received compound that is not for me -> drop");
00062     }
00063 
00064     else
00065     {
00066         wns::service::dll::UnicastAddress rx = command->peer.sourceMACAddress;
00067         wns::service::dll::UnicastAddress currentPartner = friends.manager->getCurrentTransmissionTarget();
00068 
00069         // only process compound if it's from the currently active transmission partner or if no transmission is active
00070         if((currentPartner == rx) || (currentPartner == wns::service::dll::UnicastAddress()))
00071         {
00072             if(hasCommandOf(compound) && getCommand(compound->getCommandPool())->peer.Frametype == ARQCommand::Ack)
00073             {
00074             MESSAGE_SINGLE(NORMAL, logger, "ARQ: received an ACK compound ");
00075 
00076                 if(getCommand(compound->getCommandPool())->peer.ACKpolicy == ARQCommand::ImmACK)
00077                 {
00078                     MESSAGE_SINGLE(NORMAL, logger, "ARQ: an immediate ack is received from station : " << rx
00079                         <<"  inform the drp buffer about the acknowledged compound ");
00080                     friends.manager->Acknowledgment(rx);
00081 
00082                 }
00083             }
00084             else
00085             {
00086                 MESSAGE_SINGLE(NORMAL, logger, "ARQ: receive a data frame from " << rx << ", create an ACK and forward data frame ");
00087                 getDeliverer()->getAcceptor( compound )->onData( compound );
00088                 CreateACK(compound);
00089             }
00090         }
00091         else MESSAGE_SINGLE(NORMAL, logger, "ARQ: Received a compound from " << rx << ", but the current partner is " << currentPartner << ". Dropping the compound.");
00092     }
00093 }
00094 
00095 bool 
00096 ARQ::doIsAccepting( const wns::ldk::CompoundPtr& ) const
00097 {
00098     return true;
00099 }
00100 
00101 void 
00102 ARQ::doSendData( const wns::ldk::CompoundPtr& compound )
00103 {
00104     if(!hasCommandOf(compound))
00105     {
00106         ARQCommand* ac = activateCommand(compound->getCommandPool());
00107         ac->peer.ACKpolicy  = ARQCommand::ImmACK;
00108     }
00109     else
00110     {
00111         MESSAGE_SINGLE(NORMAL, logger, "ARQ: Command is already activated, ACKPolicy is set to: "
00112         <<getCommand(compound->getCommandPool())->peer.ACKpolicy
00113         <<" Target is : "<< (fun->getCommandReader("upperConvergence")
00114         ->readCommand<dll::UpperCommand>(compound->getCommandPool()))->peer.targetMACAddress);
00115     }
00116 
00117     if(!getConnector()->hasAcceptor(compound)){
00118         if(getCommand(compound->getCommandPool())->peer.Frametype == ARQCommand::Ack)
00119         {
00120             MESSAGE_SINGLE(NORMAL, logger, "ARQ: can't send ACK");
00121         }
00122         else
00123         {
00124             MESSAGE_SINGLE(NORMAL, logger, "ARQ: can't send Data");
00125         }
00126     }
00127     else{
00128 
00129         if(getCommand(compound->getCommandPool())->peer.Frametype == ARQCommand::Ack)
00130         {
00131             MESSAGE_SINGLE(NORMAL, logger, "ARQ: send ACK");
00132         }
00133         else
00134         {
00135             MESSAGE_SINGLE(NORMAL, logger, "ARQ: send Data");
00136         }
00137         getConnector()->getAcceptor(compound)->sendData(compound);
00138     }
00139 }
00140 
00141 
00142 void 
00143 ARQ::onFUNCreated()
00144 {
00145     ownaddress = getFUN()->findFriend<dll::UpperConvergence*>("upperConvergence")->getMACAddress();
00146     friends.manager = getFUN()->findFriend<wimemac::lowerMAC::IManagerServices*>(managerName);
00147 }
00148 
00149 void 
00150 ARQ::doWakeup()
00151 {
00152 }
00153 
00154 bool
00155 ARQ::hasCommandOf(const wns::ldk::CompoundPtr& compound) const
00156 {
00157     return (getFUN()->getProxy()->commandIsActivated( compound->getCommandPool(), this ));
00158 }
00159 
00160 void
00161 ARQ::CreateACK( const wns::ldk::CompoundPtr& compound)
00162 {
00163     wns::ldk::CommandPool* AckCommand = friends.manager->createReply(compound->getCommandPool(), ACK);
00164     wns::ldk::CompoundPtr AckCompound(new wns::ldk::Compound(AckCommand));
00165 
00166     wns::simulator::Time fxDur = friends.manager->getFrameExchangeDuration(compound->getCommandPool()) - SIFS - AckDuration;
00167     if (fxDur < SIFS)
00168     {
00169         fxDur = 0;
00170     }
00171     friends.manager->setFrameExchangeDuration(AckCommand, fxDur);
00172     MESSAGE_SINGLE(NORMAL, logger, "ARQ: FrameExchangeDuration set to : " << fxDur);
00173 
00174     ARQCommand* ac = activateCommand(AckCompound->getCommandPool());
00175     ac->peer.Frametype = ARQCommand::Ack;
00176     ac->peer.ACKpolicy = ARQCommand::ImmACK;
00177 
00178     wns::events::scheduler::Callable call = boost::bind(&ARQ::TransmitAck, this, AckCompound);
00179     scheduler->scheduleDelay(call, SIFS);
00180 }
00181 
00182 
00183 void 
00184 ARQ::calculateSizes(const wns::ldk::CommandPool* commandPool, Bit& commandPoolSize, Bit& sduSize) const
00185 {
00186     getFUN()->getProxy()->calculateSizes(commandPool, commandPoolSize, sduSize,this);
00187 }
00188 void
00189 ARQ::TransmitAck(const wns::ldk::CompoundPtr& compound)
00190 {
00191     MESSAGE_SINGLE(NORMAL, logger, "ARQ: send Ack after SIFS");
00192     doSendData(compound);
00193 }
00194 

Generated on Mon May 21 03:32:17 2012 for openWNS by  doxygen 1.5.5