A Discrete-Event Network Simulator
API
uan-mac-cw.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Leonard Tracy <lentracy@gmail.com>
19  */
20 
21 #include "uan-mac-cw.h"
22 #include "ns3/attribute.h"
23 #include "ns3/uinteger.h"
24 #include "ns3/double.h"
25 #include "ns3/nstime.h"
26 #include "ns3/uan-header-common.h"
27 #include "ns3/trace-source-accessor.h"
28 #include "ns3/log.h"
29 
30 namespace ns3 {
31 
32 NS_LOG_COMPONENT_DEFINE ("UanMacCw");
33 
35 
37  : UanMac (),
38  m_phy (0),
39  m_pktTx (0),
40  m_txOngoing (false),
41  m_state (IDLE),
42  m_cleared (false)
43 
44 {
45  m_rv = CreateObject<UniformRandomVariable> ();
46 }
47 
49 {
50 }
51 
52 void
54 {
55  if (m_cleared)
56  {
57  return;
58  }
59  m_cleared = true;
60  m_pktTx = 0;
61  if (m_phy)
62  {
63  m_phy->Clear ();
64  m_phy = 0;
65  }
67  m_txOngoing = false;
68 }
69 
70 void
72 {
73  Clear ();
75 }
76 
77 TypeId
79 {
80  static TypeId tid = TypeId ("ns3::UanMacCw")
81  .SetParent<UanMac> ()
82  .SetGroupName ("Uan")
83  .AddConstructor<UanMacCw> ()
84  .AddAttribute ("CW",
85  "The MAC parameter CW.",
86  UintegerValue (10),
88  MakeUintegerChecker<uint32_t> ())
89  .AddAttribute ("SlotTime",
90  "Time slot duration for MAC backoff.",
91  TimeValue (MilliSeconds (20)),
93  MakeTimeChecker ())
94  .AddTraceSource ("Enqueue",
95  "A packet arrived at the MAC for transmission.",
97  "ns3::UanMacCw::QueueTracedCallback")
98  .AddTraceSource ("Dequeue",
99  "A was passed down to the PHY from the MAC.",
101  "ns3::UanMacCw::QueueTracedCallback")
102  .AddTraceSource ("RX",
103  "A packet was destined for this MAC and was received.",
105  "ns3::UanMac::PacketModeTracedCallback")
106 
107  ;
108  return tid;
109 }
110 
111 bool
112 UanMacCw::Enqueue (Ptr<Packet> packet, uint16_t protocolNumber, const Address &dest)
113 {
114 
115  switch (m_state)
116  {
117  case CCABUSY:
118  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
119  if (m_txOngoing == true)
120  {
121  NS_LOG_DEBUG ("State is TX");
122  }
123  else
124  {
125  NS_LOG_DEBUG ("State is not TX");
126  }
127 
128  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
129  return false;
130  case RUNNING:
131  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue RUNNING");
132  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
133  return false;
134  case TX:
135  case IDLE:
136  {
137  NS_ASSERT (!m_pktTx);
138 
139  UanHeaderCommon header;
140  header.SetDest (Mac8Address::ConvertFrom (dest));
142  header.SetType (0);
143  header.SetProtocolNumber (0);
144  packet->AddHeader (header);
145 
146  m_enqueueLogger (packet, GetTxModeIndex ());
147 
148  if (m_phy->IsStateBusy ())
149  {
150  m_pktTx = packet;
152  m_state = CCABUSY;
153  uint32_t cw = (uint32_t) m_rv->GetValue (0,m_cw);
154  m_savedDelayS = cw * m_slotTime;
156  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << ": Addr " << GetAddress () << ": Enqueuing new packet while busy: (Chose CW " << cw << ", Sending at " << m_sendTime.As (Time::S) << " Packet size: " << packet->GetSize ());
157  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
158  }
159  else
160  {
161  NS_ASSERT (m_state != TX);
162  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
163  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
164  m_state = TX;
165  m_phy->SendPacket (packet,GetTxModeIndex ());
166 
167  }
168  break;
169  }
170  default:
171  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
172  return false;
173  }
174 
175  return true;
176 
177 
178 }
179 
180 void
182 {
183  m_forwardUpCb = cb;
184 }
185 
186 void
188 {
189  m_phy = phy;
190  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
191  m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
192  m_phy->RegisterListener (this);
193 }
194 
195 void
197 {
198  if (m_state == RUNNING)
199  {
200 
201  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel busy");
202  SaveTimer ();
203  m_state = CCABUSY;
204  }
205 
206 }
207 void
209 {
210  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
211  {
212  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle");
213  m_state = RUNNING;
214  StartTimer ();
215 
216  }
217 
218 }
219 void
221 {
222  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
223  {
224  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle");
225  m_state = RUNNING;
226  StartTimer ();
227 
228  }
229 
230 }
231 void
233 {
234  if (m_state == RUNNING)
235  {
236  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel busy");
237  m_state = CCABUSY;
238  SaveTimer ();
239 
240  }
241 
242 }
243 void
245 {
246  if (m_state == CCABUSY)
247  {
248  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle");
249  m_state = RUNNING;
250  StartTimer ();
251 
252  }
253 
254 }
255 void
257 {
258  m_txOngoing = true;
259 
260  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Tx Start Notified");
261 
262  if (m_state == RUNNING)
263  {
264  NS_ASSERT (0);
265  m_state = CCABUSY;
266  SaveTimer ();
267  }
268 }
269 
270 void
272 {
273  m_txOngoing = false;
274 
275  EndTx ();
276 }
277 
278 int64_t
279 UanMacCw::AssignStreams (int64_t stream)
280 {
281  NS_LOG_FUNCTION (this << stream);
282  m_rv->SetStream (stream);
283  return 1;
284 }
285 
286 void
288 {
289  NS_ASSERT (m_state == TX || m_state == CCABUSY);
290  if (m_state == TX)
291  {
292  m_state = IDLE;
293  }
294  else if (m_state == CCABUSY)
295  {
296  if (m_phy->IsStateIdle ())
297  {
298  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
299  m_state = RUNNING;
300  StartTimer ();
301  }
302  }
303  else
304  {
305  NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
306  }
307 }
308 void
309 UanMacCw::SetCw (uint32_t cw)
310 {
311  m_cw = cw;
312 }
313 void
315 {
316  m_slotTime = duration;
317 }
318 uint32_t
320 {
321  return m_cw;
322 }
323 Time
325 {
326  return m_slotTime;
327 }
328 void
329 UanMacCw::PhyRxPacketGood (Ptr<Packet> packet, [[maybe_unused]] double sinr, UanTxMode mode)
330 {
331  UanHeaderCommon header;
332  packet->RemoveHeader (header);
333 
334  if (header.GetDest () == Mac8Address::ConvertFrom (GetAddress ()) || header.GetDest () == Mac8Address::GetBroadcast ())
335  {
336  m_forwardUpCb (packet, header.GetProtocolNumber (), header.GetSrc ());
337  }
338 }
339 void
340 UanMacCw::PhyRxPacketError (Ptr<Packet> packet, [[maybe_unused]] double sinr)
341 {
342 }
343 void
345 {
346  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Now ()).As (Time::S) << ")");
347  NS_ASSERT (m_pktTx);
351 
352 
353 }
354 void
356 {
357 
359  if (m_sendTime == Simulator::Now ())
360  {
361  SendPacket ();
362  }
363  else
364  {
366  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.As (Time::S) << ")");
367  }
368 }
369 
370 void
372 {
373  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << " Transmitting ");
375  m_state = TX;
376  m_phy->SendPacket (m_pktTx,m_pktTxProt);
377  m_pktTx = 0;
378  m_sendTime = Seconds (0);
379  m_savedDelayS = Seconds (0);
380 }
381 
382 } // namespace ns3
a polymophic address class
Definition: address.h:91
Callback template class.
Definition: callback.h:1279
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
A class used for addressing MAC8 MAC's.
Definition: mac8-address.h:43
static Mac8Address GetBroadcast(void)
Get the broadcast address (255).
Definition: mac8-address.cc:87
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:54
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ S
second
Definition: nstime.h:114
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Common packet header fields.
void SetSrc(Mac8Address src)
Set the source address.
Mac8Address GetSrc(void) const
Get the source address.
Mac8Address GetDest(void) const
Get the destination address.
void SetProtocolNumber(uint16_t protocolNumber)
Set the packet type.
void SetDest(Mac8Address dest)
Set the destination address.
void SetType(uint8_t type)
Set the header type.
uint16_t GetProtocolNumber(void) const
Get the packet type value.
CW-MAC protocol, similar in idea to the 802.11 DCF with constant backoff window.
Definition: uan-mac-cw.h:48
bool m_txOngoing
Tx is ongoing.
Definition: uan-mac-cw.h:146
virtual void NotifyRxStart(void)
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:196
Time m_sendTime
Time to send next packet.
Definition: uan-mac-cw.h:136
virtual void NotifyTxEnd(void)
Function called when Phy object finishes transmitting packet.
Definition: uan-mac-cw.cc:271
virtual void NotifyRxEndError(void)
Called when UanPhy finishes receiving packet in error.
Definition: uan-mac-cw.cc:220
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
A packet arrived at the MAC for transmission.
Definition: uan-mac-cw.h:126
Ptr< Packet > m_pktTx
Next packet to send.
Definition: uan-mac-cw.h:140
virtual void NotifyRxEndOk(void)
Called when UanPhy finishes receiving packet without error.
Definition: uan-mac-cw.cc:208
virtual void NotifyTxStart(Time duration)
Called when transmission starts from Phy object.
Definition: uan-mac-cw.cc:256
void EndTx(void)
End TX state.
Definition: uan-mac-cw.cc:287
bool m_cleared
Flag when we've been cleared.
Definition: uan-mac-cw.h:151
static TypeId GetTypeId(void)
Register this type.
Definition: uan-mac-cw.cc:78
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet destined for this MAC was received.
Definition: uan-mac-cw.h:124
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:314
virtual void NotifyCcaEnd(void)
Called when UanPhy stops sensing channel is busy.
Definition: uan-mac-cw.cc:244
UanMacCw()
Default constructor.
Definition: uan-mac-cw.cc:36
State m_state
Current state.
Definition: uan-mac-cw.h:148
Ptr< UniformRandomVariable > m_rv
Provides uniform random variable for contention window.
Definition: uan-mac-cw.h:154
virtual bool Enqueue(Ptr< Packet > pkt, uint16_t protocolNumber, const Address &dest)
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:112
virtual void DoDispose()
Destructor implementation.
Definition: uan-mac-cw.cc:71
virtual void Clear(void)
Clears all pointer references.
Definition: uan-mac-cw.cc:53
void SendPacket(void)
Send packet on PHY.
Definition: uan-mac-cw.cc:371
virtual void SetCw(uint32_t cw)
Set the contention window size.
Definition: uan-mac-cw.cc:309
virtual void NotifyCcaStart(void)
Called when UanPhy begins sensing channel is busy.
Definition: uan-mac-cw.cc:232
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > cb)
Set the callback to forward packets up to higher layers.
Definition: uan-mac-cw.cc:181
virtual ~UanMacCw()
Dummy destructor, DoDispose.
Definition: uan-mac-cw.cc:48
Time m_slotTime
Slot time duration.
Definition: uan-mac-cw.h:132
virtual uint32_t GetCw(void)
Get the contention window size.
Definition: uan-mac-cw.cc:319
EventId m_sendEvent
Scheduled SendPacket event.
Definition: uan-mac-cw.h:144
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Packet received at lower layer in error.
Definition: uan-mac-cw.cc:340
Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > m_forwardUpCb
Forwarding up callback.
Definition: uan-mac-cw.h:120
void PhyRxPacketGood(Ptr< Packet > packet, double sinr, UanTxMode mode)
Receive packet from lower layer (passed to PHY as callback).
Definition: uan-mac-cw.cc:329
void StartTimer(void)
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:355
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:187
@ IDLE
Idle state.
Definition: uan-mac-cw.h:113
@ RUNNING
Delay timer running.
Definition: uan-mac-cw.h:115
@ TX
Transmitting.
Definition: uan-mac-cw.h:116
@ CCABUSY
Channel busy.
Definition: uan-mac-cw.h:114
virtual Time GetSlotTime(void)
Get the slot time duration.
Definition: uan-mac-cw.cc:324
Time m_savedDelayS
Remaining delay until next send.
Definition: uan-mac-cw.h:138
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
Definition: uan-mac-cw.h:122
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: uan-mac-cw.cc:279
uint32_t m_cw
Contention window size.
Definition: uan-mac-cw.h:131
void SaveTimer(void)
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:344
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
A packet was passed down to the PHY from the MAC.
Definition: uan-mac-cw.h:128
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:142
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:50
virtual Address GetAddress(void)
Get the MAC Address.
Definition: uan-mac.cc:55
uint32_t GetTxModeIndex()
Get the Tx mode index (Modulation type).
Definition: uan-mac.cc:49
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:42
Hold an unsigned integer type.
Definition: uinteger.h:44
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1309
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:75
phy
Definition: third.py:93