/src/uan/model/uan-mac-rc.cc
C++ | 776 lines | 654 code | 99 blank | 23 comment | 81 complexity | 267b6e69d946e4df22715ae999ed4e0f MD5 | raw file
Possible License(s): GPL-2.0
- /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
- /*
- * Copyright (c) 2009 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Leonard Tracy <lentracy@gmail.com>
- */
- #include "uan-mac-rc.h"
- #include "uan-header-rc.h"
- #include "uan-tx-mode.h"
- #include "uan-phy.h"
- #include "uan-header-common.h"
- #include "uan-phy-dual.h"
- #include "ns3/log.h"
- #include "ns3/nstime.h"
- #include "ns3/simulator.h"
- #include "ns3/assert.h"
- #include "ns3/double.h"
- #include "ns3/uinteger.h"
- #include <list>
- #include <utility>
- NS_LOG_COMPONENT_DEFINE ("UanMacRc");
- namespace ns3 {
- NS_OBJECT_ENSURE_REGISTERED (UanMacRc);
- Reservation::Reservation ()
- : m_length (0),
- m_frameNo (0),
- m_retryNo (0),
- m_transmitted (false)
- {
- }
- Reservation::Reservation (std::list<std::pair <Ptr<Packet>, UanAddress > > &list, uint8_t frameNo, uint32_t maxPkts)
- : m_frameNo (frameNo),
- m_retryNo (0),
- m_transmitted (false)
- {
- uint32_t numPkts = (maxPkts) ? maxPkts : list.size ();
- uint32_t length = 0;
- UanHeaderRcData dh;
- UanHeaderCommon ch;
- for (uint32_t i = 0; i < numPkts; i++)
- {
- length += list.front ().first->GetSize () +
- ch.GetSerializedSize () +
- dh.GetSerializedSize ();
- m_pktList.push_back (list.front ());
- list.pop_front ();
- }
- m_length = length;
- }
- Reservation::~Reservation ()
- {
- std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
- for (it = m_pktList.begin (); it != m_pktList.end (); it++)
- {
- it->first = Ptr<Packet> ((Packet *) 0);
- }
- m_pktList.clear ();
- m_timestamp.clear ();
- }
- uint32_t
- Reservation::GetNoFrames () const
- {
- return m_pktList.size ();
- }
- uint32_t
- Reservation::GetLength () const
- {
- return m_length;
- }
- const std::list<std::pair <Ptr<Packet>, UanAddress > > &
- Reservation::GetPktList (void) const
- {
- return m_pktList;
- }
- uint8_t
- Reservation::GetFrameNo () const
- {
- return m_frameNo;
- }
- uint8_t
- Reservation::GetRetryNo () const
- {
- return m_retryNo;
- }
- Time
- Reservation::GetTimestamp (uint8_t n) const
- {
- return m_timestamp[n];
- }
- bool
- Reservation::IsTransmitted () const
- {
- return m_transmitted;
- }
- void
- Reservation::SetFrameNo (uint8_t fn)
- {
- m_frameNo = fn;
- }
- void
- Reservation::AddTimestamp (Time t)
- {
- m_timestamp.push_back (t);
- }
- void
- Reservation::IncrementRetry ()
- {
- m_retryNo++;
- }
- void
- Reservation::SetTransmitted (bool t)
- {
- m_transmitted = true;
- }
- uint32_t UanMacRc::m_cntrlSends = 0;
- UanMacRc::UanMacRc ()
- : UanMac (),
- m_state (UNASSOCIATED),
- m_rtsBlocked (false),
- m_currentRate (10),
- m_frameNo (0),
- m_cleared (false)
- {
- m_ev = CreateObject<ExponentialRandomVariable> ();
- UanHeaderCommon ch;
- UanHeaderRcCts ctsh;
- UanHeaderRcCtsGlobal ctsg;
- m_ctsSizeN = ctsh.GetSerializedSize ();
- m_ctsSizeG = ch.GetSerializedSize () + ctsg.GetSerializedSize ();
- }
- UanMacRc::~UanMacRc ()
- {
- }
- void
- UanMacRc::Clear ()
- {
- if (m_cleared)
- {
- return;
- }
- m_cleared = true;
- if (m_phy)
- {
- m_phy->Clear ();
- m_phy = 0;
- }
- std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
- for (it = m_pktQueue.begin (); it != m_pktQueue.end (); it++)
- {
- it->first = 0;
- }
- m_pktQueue.clear ();
- m_resList.clear ();
- m_startAgain.Cancel ();
- m_rtsEvent.Cancel ();
- }
- void
- UanMacRc::DoDispose ()
- {
- Clear ();
- UanMac::DoDispose ();
- }
- TypeId
- UanMacRc::GetTypeId (void)
- {
- static TypeId tid = TypeId ("ns3::UanMacRc")
- .SetParent<UanMac> ()
- .AddConstructor<UanMacRc> ()
- .AddAttribute ("RetryRate",
- "Number of retry attempts per second (of RTS/GWPING).",
- DoubleValue (1 / 5.0),
- MakeDoubleAccessor (&UanMacRc::m_retryRate),
- MakeDoubleChecker<double> ())
- .AddAttribute ("MaxFrames",
- "Maximum number of frames to include in a single RTS.",
- UintegerValue (1),
- MakeUintegerAccessor (&UanMacRc::m_maxFrames),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("QueueLimit",
- "Maximum packets to queue at MAC.",
- UintegerValue (10),
- MakeUintegerAccessor (&UanMacRc::m_queueLimit),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("SIFS",
- "Spacing to give between frames (this should match gateway).",
- TimeValue (Seconds (0.2)),
- MakeTimeAccessor (&UanMacRc::m_sifs),
- MakeTimeChecker ())
- .AddAttribute ("NumberOfRates",
- "Number of rate divisions supported by each PHY.",
- UintegerValue (0),
- MakeUintegerAccessor (&UanMacRc::m_numRates),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("MinRetryRate",
- "Smallest allowed RTS retry rate.",
- DoubleValue (0.01),
- MakeDoubleAccessor (&UanMacRc::m_minRetryRate),
- MakeDoubleChecker<double> ())
- .AddAttribute ("RetryStep",
- "Retry rate increment.",
- DoubleValue (0.01),
- MakeDoubleAccessor (&UanMacRc::m_retryStep),
- MakeDoubleChecker<double> ())
- .AddAttribute ("MaxPropDelay",
- "Maximum possible propagation delay to gateway.",
- TimeValue (Seconds (2)),
- MakeTimeAccessor (&UanMacRc::m_learnedProp),
- MakeTimeChecker ())
- .AddTraceSource ("Enqueue",
- "A (data) packet arrived at MAC for transmission.",
- MakeTraceSourceAccessor (&UanMacRc::m_enqueueLogger))
- .AddTraceSource ("Dequeue",
- "A (data) packet was passed down to PHY from MAC.",
- MakeTraceSourceAccessor (&UanMacRc::m_dequeueLogger))
- .AddTraceSource ("RX",
- "A packet was destined for and received at this MAC layer.",
- MakeTraceSourceAccessor (&UanMacRc::m_rxLogger))
- ;
- return tid;
- }
- int64_t
- UanMacRc::AssignStreams (int64_t stream)
- {
- NS_LOG_FUNCTION (this << stream);
- m_ev->SetStream (stream);
- return 1;
- }
- Address
- UanMacRc::GetAddress (void)
- {
- return m_address;
- }
- void
- UanMacRc::SetAddress (UanAddress addr)
- {
- m_address = addr;
- }
- bool
- UanMacRc::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
- {
- if (protocolNumber > 0)
- {
- NS_LOG_WARN ("Warning: UanMacRc does not support multiple protocols. protocolNumber argument to Enqueue is being ignored");
- }
- if (m_pktQueue.size () >= m_queueLimit)
- {
- return false;
- }
- m_pktQueue.push_back (std::make_pair (packet, UanAddress::ConvertFrom (dest)));
- switch (m_state)
- {
- case UNASSOCIATED:
- Associate ();
- return true;
- case IDLE:
- if (!m_rtsEvent.IsRunning ())
- {
- SendRts ();
- }
- return true;
- case GWPSENT:
- case RTSSENT:
- case DATATX:
- return true;
- }
- return true;
- }
- void
- UanMacRc::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
- {
- m_forwardUpCb = cb;
- }
- void
- UanMacRc::AttachPhy (Ptr<UanPhy> phy)
- {
- m_phy = phy;
- m_phy->SetReceiveOkCallback (MakeCallback (&UanMacRc::ReceiveOkFromPhy, this));
- }
- Address
- UanMacRc::GetBroadcast (void) const
- {
- return UanAddress::GetBroadcast ();
- }
- void
- UanMacRc::ReceiveOkFromPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode)
- {
- UanHeaderCommon ch;
- pkt->RemoveHeader (ch);
- if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
- {
- m_rxLogger (pkt, mode);
- }
- switch (ch.GetType ())
- {
- case TYPE_DATA:
- if (ch.GetDest () == m_address)
- {
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " UanMacRc Receiving DATA packet from PHY");
- UanHeaderRcData dh;
- pkt->RemoveHeader (dh);
- m_forwardUpCb (pkt, ch.GetSrc ());
- }
- break;
- case TYPE_RTS:
- // Currently don't respond to RTS packets at non-gateway nodes
- // (Code assumes single network neighberhood)
- break;
- case TYPE_CTS:
- {
- uint32_t ctsBytes = ch.GetSerializedSize () + pkt->GetSize ();
- m_assocAddr = ch.GetSrc ();
- UanHeaderRcCtsGlobal ctsg;
- pkt->RemoveHeader (ctsg);
- m_currentRate = ctsg.GetRateNum ();
- m_retryRate = m_minRetryRate + m_retryStep*ctsg.GetRetryRate ();
- UanHeaderRcRts rhtmp;
- Time winDelay = ctsg.GetWindowTime ();
- if (winDelay.GetSeconds () > 0)
- {
- m_rtsBlocked = false;
- Simulator::Schedule (winDelay, &UanMacRc::BlockRtsing, this);
- }
- else
- {
- NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received window period < 0");
- }
- UanHeaderRcCts ctsh;
- ctsh.SetAddress (UanAddress::GetBroadcast ());
- while (pkt->GetSize () > 0)
- {
- pkt->RemoveHeader (ctsh);
- if (ctsh.GetAddress () == m_address)
- {
- if (m_state == GWPSENT)
- {
- m_assocAddr = ch.GetSrc ();
- ScheduleData (ctsh, ctsg, ctsBytes);
- }
- else if (m_state == RTSSENT)
- {
- ScheduleData (ctsh, ctsg, ctsBytes);
- }
- else
- {
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS while state != RTSSENT or GWPING");
- }
- }
- }
- }
- break;
- case TYPE_GWPING:
- // Do not respond to GWPINGS at non-gateway nodes
- break;
- case TYPE_ACK:
- m_rtsBlocked = true;
- if (ch.GetDest () != m_address)
- {
- return;
- }
- ProcessAck (pkt);
- break;
- default:
- NS_FATAL_ERROR ("Unknown packet type " << ch.GetType () << " received at node " << GetAddress ());
- }
- }
- void
- UanMacRc::ScheduleData (const UanHeaderRcCts &ctsh, const UanHeaderRcCtsGlobal &ctsg, uint32_t ctsBytes)
- {
- NS_ASSERT (m_state == RTSSENT || m_state == GWPSENT);
- std::list<Reservation>::iterator it = m_resList.begin ();
- for (; it != m_resList.end (); it++)
- {
- if (it->GetFrameNo () == ctsh.GetFrameNo ())
- {
- break;
- }
- }
- if (it == m_resList.end ())
- {
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet with no corresponding reservation!");
- return;
- }
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet. Scheduling data");
- it->SetTransmitted ();
- double currentBps = m_phy->GetMode (m_currentRate).GetDataRateBps ();
- m_learnedProp = Simulator::Now () - ctsg.GetTxTimeStamp () - Seconds (ctsBytes * 8.0 / currentBps);
- Time arrTime = ctsg.GetTxTimeStamp () + ctsh.GetDelayToTx ();
- Time txTime = arrTime - m_learnedProp;
- Time startDelay = txTime - Simulator::Now ();
- Time frameDelay = Seconds (0);
- const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
- std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
- pit = l.begin ();
- for (uint32_t i = 0; i < it->GetNoFrames (); i++, pit++)
- {
- Ptr<Packet> pkt = (*pit).first->Copy ();
- UanHeaderRcData dh;
- dh.SetFrameNo (i);
- dh.SetPropDelay (m_learnedProp);
- pkt->AddHeader (dh);
- UanHeaderCommon ch;
- ch.SetType (TYPE_DATA);
- ch.SetDest (m_assocAddr);
- ch.SetSrc (m_address);
- pkt->AddHeader (ch);
- Time eventTime = startDelay + frameDelay;
- if (eventTime.GetSeconds () < 0)
- {
- if (eventTime.GetSeconds () > -0.001)
- {
- eventTime = Seconds (0);
- }
- else
- {
- NS_FATAL_ERROR ("Scheduling error resulted in very negative data transmission time! eventTime = " << eventTime.GetSeconds ());
- }
- }
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " scheduling with delay " << eventTime.GetSeconds () << " propDelay " << m_learnedProp.GetSeconds () << " start delay " << startDelay.GetSeconds () << " arrival time " << arrTime.GetSeconds ());
- Simulator::Schedule (eventTime, &UanMacRc::SendPacket, this, pkt, m_currentRate);
- frameDelay = frameDelay + m_sifs + Seconds (pkt->GetSize () / currentBps);
- }
- m_state = IDLE;
- if (!m_pktQueue.empty ())
- {
- if (m_rtsEvent.IsRunning ())
- {
- m_rtsEvent.Cancel ();
- }
- m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
- double timeout = m_ev->GetValue ();
- m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::SendRts, this);
- }
- }
- void
- UanMacRc::SendPacket (Ptr<Packet> pkt, uint32_t rate)
- {
- UanHeaderCommon ch;
- pkt->PeekHeader (ch);
- std::string type;
- switch (ch.GetType ())
- {
- case TYPE_DATA:
- type = "DATA";
- break;
- case TYPE_RTS:
- type = "RTS";
- break;
- case TYPE_CTS:
- type = "CTS";
- break;
- case TYPE_ACK:
- type = "ACK";
- break;
- case TYPE_GWPING:
- type = "GWPING";
- break;
- default:
- type = "UNKNOWN";
- break;
- }
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " transmitting " << pkt->GetSize () << " byte packet of type " << type << " with rate " << rate << "(" << m_phy->GetMode (rate).GetDataRateBps () << ") to " << ch.GetDest ());
- m_dequeueLogger (pkt, rate);
- m_phy->SendPacket (pkt, rate);
- }
- void
- UanMacRc::ProcessAck (Ptr<Packet> ack)
- {
- UanHeaderRcAck ah;
- ack->RemoveHeader (ah);
- std::list<Reservation>::iterator it = m_resList.begin ();
- for (; it != m_resList.end (); it++)
- {
- if (it->GetFrameNo () == ah.GetFrameNo ())
- {
- break;
- }
- }
- if (it == m_resList.end ())
- {
- NS_LOG_DEBUG ("In " << __func__ << " could not find reservation corresponding to received ACK");
- return;
- }
- if (!it->IsTransmitted ())
- {
- return;
- }
- if (ah.GetNoNacks () > 0)
- {
- const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
- std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
- pit = l.begin ();
- const std::set<uint8_t> &nacks = ah.GetNackedFrames ();
- std::set<uint8_t>::iterator nit = nacks.begin ();
- uint8_t pnum = 0;
- for (; nit != nacks.end (); nit++)
- {
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received NACK for " << (uint32_t) *nit);
- while (pnum < *nit)
- {
- pit++;
- pnum++;
- }
- UanHeaderRcData dh;
- UanHeaderCommon ch;
- m_pktQueue.push_front (*pit);
- }
- }
- else
- {
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received ACK for all frames");
- }
- m_resList.erase (it);
- }
- UanHeaderRcRts
- UanMacRc::CreateRtsHeader (const Reservation &res)
- {
- UanHeaderRcRts rh = UanHeaderRcRts ();
- rh.SetLength (res.GetLength ());
- rh.SetNoFrames (res.GetNoFrames ());
- rh.SetTimeStamp (res.GetTimestamp (res.GetRetryNo ()));
- rh.SetFrameNo (res.GetFrameNo ());
- rh.SetRetryNo (res.GetRetryNo ());
- return rh;
- }
- void
- UanMacRc::Associate (void)
- {
- m_cntrlSends++;
- Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
- res.AddTimestamp (Simulator::Now ());
- m_frameNo++;
- m_resList.push_back (res);
- Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
- bool phy1ok = IsPhy1Ok ();
- if (phy1ok && !phyDual->IsPhy2Tx () & !m_rtsBlocked)
- {
- Ptr<Packet> pkt = Create<Packet> (0);
- pkt->AddHeader (CreateRtsHeader (res));
- pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
- NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending first GWPING " << *pkt);
- SendPacket (pkt,m_currentRate + m_numRates);
- }
- m_state = GWPSENT;
- NS_ASSERT (!m_rtsEvent.IsRunning ());
- m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
- double timeout = m_ev->GetValue ();
- m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
- }
- void
- UanMacRc::AssociateTimeout ()
- {
- m_cntrlSends++;
- if (m_state != GWPSENT)
- {
- return;
- }
- Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
- bool phy1ok = IsPhy1Ok ();
- if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
- {
- Ptr<Packet> pkt = Create<Packet> ();
- Reservation res = m_resList.back ();
- m_resList.pop_back ();
- res.AddTimestamp (Simulator::Now ());
- res.IncrementRetry ();
- pkt->AddHeader (CreateRtsHeader (res));
- pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
- SendPacket (pkt,m_currentRate + m_numRates);
- m_resList.push_back (res);
- }
- NS_ASSERT (!m_rtsEvent.IsRunning ());
- m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
- double timeout = m_ev->GetValue ();
- m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
- }
- void
- UanMacRc::SendRts (void)
- {
- m_cntrlSends++;
- if (m_state == RTSSENT)
- {
- return;
- }
- NS_ASSERT (!m_pktQueue.empty ());
- Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
- res.AddTimestamp (Simulator::Now ());
- m_frameNo++;
- m_resList.push_back (res);
- Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
- bool phy1ok = IsPhy1Ok ();
- if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked )
- {
- Ptr<Packet> pkt = Create<Packet> (0);
- pkt->AddHeader (CreateRtsHeader (res));
- pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
- SendPacket (pkt,m_currentRate + m_numRates);
- }
- m_state = RTSSENT;
- NS_ASSERT (!m_rtsEvent.IsRunning ());
- m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
- double timeout = m_ev->GetValue ();
- m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
- }
- // We assume here that packet types are known at detection.
- bool
- UanMacRc::IsPhy1Ok ()
- {
- Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
- bool phy1ok = true;
- if (phyDual->IsPhy1Rx ())
- {
- Ptr<Packet> pkt = phyDual->GetPhy1PacketRx ();
- UanHeaderCommon ch;
- pkt->PeekHeader (ch);
- if (ch.GetType () == TYPE_CTS || ch.GetType () == TYPE_ACK)
- {
- phy1ok = false;
- }
- else if (ch.GetDest () == m_address)
- {
- phy1ok = false;
- }
- }
- return phy1ok;
- }
- void
- UanMacRc::RtsTimeout (void)
- {
- m_cntrlSends++;
- if (m_state != RTSSENT)
- {
- return;
- }
- Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
- bool phy1ok = IsPhy1Ok ();
- if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
- {
- if (m_resList.empty ())
- {
- NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " tried to retry RTS with empty reservation list");
- }
- Ptr<Packet> pkt = Create<Packet> (0);
- Reservation res = m_resList.back ();
- NS_ASSERT (!res.IsTransmitted ());
- m_resList.pop_back ();
- res.AddTimestamp (Simulator::Now ());
- res.IncrementRetry ();
- m_resList.push_back (res);
- pkt->AddHeader (CreateRtsHeader (res));
- pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
- SendPacket (pkt,m_currentRate + m_numRates);
- }
- m_state = RTSSENT;
- NS_ASSERT (!m_rtsEvent.IsRunning ());
- m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
- double timeout = m_ev->GetValue ();
- m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
- }
- void
- UanMacRc::BlockRtsing (void)
- {
- m_rtsBlocked = true;
- }
- } // namespace ns3