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_state (IDLE),
41  m_cleared (false)
42 
43 {
44  m_rv = CreateObject<UniformRandomVariable> ();
45 }
46 
48 {
49 }
50 
51 void
53 {
54  if (m_cleared)
55  {
56  return;
57  }
58  m_cleared = true;
59  m_pktTx = 0;
60  if (m_phy)
61  {
62  m_phy->Clear ();
63  m_phy = 0;
64  }
67 }
68 
69 void
71 {
72  Clear ();
74 }
75 
76 TypeId
78 {
79  static TypeId tid = TypeId ("ns3::UanMacCw")
80  .SetParent<UanMac> ()
81  .SetGroupName ("Uan")
82  .AddConstructor<UanMacCw> ()
83  .AddAttribute ("CW",
84  "The MAC parameter CW.",
85  UintegerValue (10),
87  MakeUintegerChecker<uint32_t> ())
88  .AddAttribute ("SlotTime",
89  "Time slot duration for MAC backoff.",
90  TimeValue (MilliSeconds (20)),
92  MakeTimeChecker ())
93  .AddTraceSource ("Enqueue",
94  "A packet arrived at the MAC for transmission.",
96  "ns3::UanMacCw::QueueTracedCallback")
97  .AddTraceSource ("Dequeue",
98  "A was passed down to the PHY from the MAC.",
100  "ns3::UanMacCw::QueueTracedCallback")
101  .AddTraceSource ("RX",
102  "A packet was destined for this MAC and was received.",
104  "ns3::UanMac::PacketModeTracedCallback")
105 
106  ;
107  return tid;
108 }
109 
110 bool
111 UanMacCw::Enqueue (Ptr<Packet> packet, uint16_t protocolNumber, const Address &dest)
112 {
113 
114  switch (m_state)
115  {
116  case CCABUSY:
117  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
118  if (m_txEndEvent.IsRunning ())
119  {
120  NS_LOG_DEBUG ("State is TX");
121  }
122  else
123  {
124  NS_LOG_DEBUG ("State is not TX");
125  }
126 
127  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
128  return false;
129  case RUNNING:
130  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue RUNNING");
131  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
132  return false;
133  case TX:
134  case IDLE:
135  {
136  NS_ASSERT (!m_pktTx);
137 
138  UanHeaderCommon header;
139  header.SetDest (Mac8Address::ConvertFrom (dest));
141  header.SetType (0);
142  header.SetProtocolNumber (0);
143  packet->AddHeader (header);
144 
145  m_enqueueLogger (packet, GetTxModeIndex ());
146 
147  if (m_phy->IsStateBusy ())
148  {
149  m_pktTx = packet;
151  m_state = CCABUSY;
152  uint32_t cw = (uint32_t) m_rv->GetValue (0,m_cw);
153  m_savedDelayS = cw * m_slotTime;
155  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 ());
156  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
157  }
158  else
159  {
160  NS_ASSERT (m_state != TX);
161  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
162  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
163  m_state = TX;
164  m_phy->SendPacket (packet,GetTxModeIndex ());
165 
166  }
167  break;
168  }
169  default:
170  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
171  return false;
172  }
173 
174  return true;
175 
176 
177 }
178 
179 void
181 {
182  m_forwardUpCb = cb;
183 }
184 
185 void
187 {
188  m_phy = phy;
189  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
190  m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
191  m_phy->RegisterListener (this);
192 }
193 
194 void
196 {
197  if (m_state == RUNNING)
198  {
199 
200  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel busy");
201  SaveTimer ();
202  m_state = CCABUSY;
203  }
204 
205 }
206 void
208 {
209  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
210  {
211  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle");
212  m_state = RUNNING;
213  StartTimer ();
214 
215  }
216 
217 }
218 void
220 {
221  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
222  {
223  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle");
224  m_state = RUNNING;
225  StartTimer ();
226 
227  }
228 
229 }
230 void
232 {
233  if (m_state == RUNNING)
234  {
235  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel busy");
236  m_state = CCABUSY;
237  SaveTimer ();
238 
239  }
240 
241 }
242 void
244 {
245  if (m_state == CCABUSY)
246  {
247  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle");
248  m_state = RUNNING;
249  StartTimer ();
250 
251  }
252 
253 }
254 void
256 {
257 
258  if (m_txEndEvent.IsRunning ())
259  {
261  }
262 
263  m_txEndEvent = Simulator::Schedule (duration, &UanMacCw::EndTx, this);
264  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " scheduling TxEndEvent with delay " << duration.As (Time::S));
265  if (m_state == RUNNING)
266  {
267  NS_ASSERT (0);
268  m_state = CCABUSY;
269  SaveTimer ();
270 
271  }
272 
273 }
274 
275 int64_t
276 UanMacCw::AssignStreams (int64_t stream)
277 {
278  NS_LOG_FUNCTION (this << stream);
279  m_rv->SetStream (stream);
280  return 1;
281 }
282 
283 void
285 {
286  NS_ASSERT (m_state == TX || m_state == CCABUSY);
287  if (m_state == TX)
288  {
289  m_state = IDLE;
290  }
291  else if (m_state == CCABUSY)
292  {
293  if (m_phy->IsStateIdle ())
294  {
295  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
296  m_state = RUNNING;
297  StartTimer ();
298  }
299  }
300  else
301  {
302  NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
303  }
304 }
305 void
306 UanMacCw::SetCw (uint32_t cw)
307 {
308  m_cw = cw;
309 }
310 void
312 {
313  m_slotTime = duration;
314 }
315 uint32_t
317 {
318  return m_cw;
319 }
320 Time
322 {
323  return m_slotTime;
324 }
325 void
327 {
328  NS_UNUSED (sinr);
329  UanHeaderCommon header;
330  packet->RemoveHeader (header);
331 
332  if (header.GetDest () == Mac8Address::ConvertFrom (GetAddress ()) || header.GetDest () == Mac8Address::GetBroadcast ())
333  {
334  m_forwardUpCb (packet, header.GetProtocolNumber (), header.GetSrc ());
335  }
336 }
337 void
339 {
340  NS_UNUSED (sinr);
341 }
342 void
344 {
345  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Now ()).As (Time::S) << ")");
346  NS_ASSERT (m_pktTx);
350 
351 
352 }
353 void
355 {
356 
358  if (m_sendTime == Simulator::Now ())
359  {
360  SendPacket ();
361  }
362  else
363  {
365  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.As (Time::S) << ")");
366  }
367 }
368 
369 void
371 {
372  NS_LOG_DEBUG ("Time " << Now ().As (Time::S) << " Addr " << GetAddress () << " Transmitting ");
374  m_state = TX;
375  m_phy->SendPacket (m_pktTx,m_pktTxProt);
376  m_pktTx = 0;
377  m_sendTime = Seconds (0);
378  m_savedDelayS = Seconds (0);
379 }
380 
381 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
CW-MAC protocol, similar in idea to the 802.11 DCF with constant backoff window.
Definition: uan-mac-cw.h:46
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
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:180
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
Callback template class.
Definition: callback.h:1278
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
State m_state
Current state.
Definition: uan-mac-cw.h:147
void SendPacket(void)
Send packet on PHY.
Definition: uan-mac-cw.cc:370
void SetSrc(Mac8Address src)
Set the source address.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:141
#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
static TypeId GetTypeId(void)
Register this type.
Definition: uan-mac-cw.cc:77
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:75
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
static Mac8Address GetBroadcast(void)
Get the broadcast address (255).
Definition: mac8-address.cc:87
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:311
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:186
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
A packet arrived at the MAC for transmission.
Definition: uan-mac-cw.h:125
bool m_cleared
Flag when we&#39;ve been cleared.
Definition: uan-mac-cw.h:150
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
virtual void Clear(void)
Clears all pointer references.
Definition: uan-mac-cw.cc:52
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event&#39;s associated function will not be invoked when it expires...
Definition: simulator.cc:268
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Idle state.
Definition: uan-mac-cw.h:112
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
Time m_savedDelayS
Remaining delay until next send.
Definition: uan-mac-cw.h:137
virtual void NotifyRxEndError(void)
Called when UanPhy finishes receiving packet in error.
Definition: uan-mac-cw.cc:219
a polymophic address class
Definition: address.h:90
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
phy
Definition: third.py:93
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:49
void SetProtocolNumber(uint16_t protocolNumber)
Set the packet type.
Mac8Address GetDest(void) const
Get the destination address.
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet destined for this MAC was received.
Definition: uan-mac-cw.h:123
AttributeValue implementation for Time.
Definition: nstime.h:1342
virtual Address GetAddress(void)
Get the MAC Address.
Definition: uan-mac.cc:55
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual void SetCw(uint32_t cw)
Set the contention window size.
Definition: uan-mac-cw.cc:306
virtual void NotifyRxStart(void)
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:195
void EndTx(void)
End TX state.
Definition: uan-mac-cw.cc:284
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:41
UanMacCw()
Default constructor.
Definition: uan-mac-cw.cc:36
A class used for addressing MAC8 MAC&#39;s.
Definition: mac8-address.h:42
Ptr< UniformRandomVariable > m_rv
Provides uniform random variable for contention window.
Definition: uan-mac-cw.h:153
virtual void NotifyRxEndOk(void)
Called when UanPhy finishes receiving packet without error.
Definition: uan-mac-cw.cc:207
Mac8Address GetSrc(void) const
Get the source address.
void SaveTimer(void)
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:343
virtual ~UanMacCw()
Dummy destructor, DoDispose.
Definition: uan-mac-cw.cc:47
virtual void NotifyCcaStart(void)
Called when UanPhy begins sensing channel is busy.
Definition: uan-mac-cw.cc:231
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Common packet header fields.
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
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:1343
virtual Time GetSlotTime(void)
Get the slot time duration.
Definition: uan-mac-cw.cc:321
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
virtual void NotifyTxStart(Time duration)
Called when transmission starts from Phy object.
Definition: uan-mac-cw.cc:255
virtual void DoDispose()
Destructor implementation.
Definition: uan-mac-cw.cc:70
Channel busy.
Definition: uan-mac-cw.h:113
EventId m_sendEvent
Scheduled SendPacket event.
Definition: uan-mac-cw.h:143
EventId m_txEndEvent
Scheduled EndTx event.
Definition: uan-mac-cw.h:145
virtual uint32_t GetCw(void)
Get the contention window size.
Definition: uan-mac-cw.cc:316
Time m_sendTime
Time to send next packet.
Definition: uan-mac-cw.h:135
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
Definition: uan-mac-cw.h:121
Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > m_forwardUpCb
Forwarding up callback.
Definition: uan-mac-cw.h:119
void SetDest(Mac8Address dest)
Set the destination address.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
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:276
Time m_slotTime
Slot time duration.
Definition: uan-mac-cw.h:131
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
uint16_t GetProtocolNumber(void) const
Get the packet type value.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
void PhyRxPacketGood(Ptr< Packet > packet, double sinr, UanTxMode mode)
Receive packet from lower layer (passed to PHY as callback).
Definition: uan-mac-cw.cc:326
Ptr< Packet > m_pktTx
Next packet to send.
Definition: uan-mac-cw.h:139
void SetType(uint8_t type)
Set the header type.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:472
uint32_t GetTxModeIndex()
Definition: uan-mac.cc:49
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
second
Definition: nstime.h:115
Delay timer running.
Definition: uan-mac-cw.h:114
void StartTimer(void)
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:354
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
A packet was passed down to the PHY from the MAC.
Definition: uan-mac-cw.h:127
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Packet received at lower layer in error.
Definition: uan-mac-cw.cc:338
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
a unique identifier for an interface.
Definition: type-id.h:58
uint32_t m_cw
Contention window size.
Definition: uan-mac-cw.h:130
Transmitting.
Definition: uan-mac-cw.h:115
virtual void NotifyCcaEnd(void)
Called when UanPhy stops sensing channel is busy.
Definition: uan-mac-cw.cc:243
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:54
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:1642
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
virtual bool Enqueue(Ptr< Packet > pkt, uint16_t protocolNumber, const Address &dest)
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:111