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 " << Simulator::Now ().GetSeconds () << " 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));
140  header.SetSrc (m_address);
141  header.SetType (0);
142  packet->AddHeader (header);
143 
144  m_enqueueLogger (packet, GetTxModeIndex ());
145 
146  if (m_phy->IsStateBusy ())
147  {
148  m_pktTx = packet;
150  m_state = CCABUSY;
151  uint32_t cw = (uint32_t) m_rv->GetValue (0,m_cw);
152  m_savedDelayS = Seconds ((double)(cw) * m_slotTime.GetSeconds ());
154  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while busy: (Chose CW " << cw << ", Sending at " << m_sendTime.GetSeconds () << " Packet size: " << packet->GetSize ());
155  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
156  }
157  else
158  {
159  NS_ASSERT (m_state != TX);
160  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
161  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
162  m_state = TX;
163  m_phy->SendPacket (packet,GetTxModeIndex ());
164 
165  }
166  break;
167  }
168  default:
169  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
170  return false;
171  }
172 
173  return true;
174 
175 
176 }
177 
178 void
180 {
181  m_forwardUpCb = cb;
182 }
183 
184 void
186 {
187  m_phy = phy;
188  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
189  m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
190  m_phy->RegisterListener (this);
191 }
192 
193 void
195 {
196  if (m_state == RUNNING)
197  {
198 
199  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
200  SaveTimer ();
201  m_state = CCABUSY;
202  }
203 
204 }
205 void
207 {
208  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
209  {
210  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
211  m_state = RUNNING;
212  StartTimer ();
213 
214  }
215 
216 }
217 void
219 {
220  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
221  {
222  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
223  m_state = RUNNING;
224  StartTimer ();
225 
226  }
227 
228 }
229 void
231 {
232  if (m_state == RUNNING)
233  {
234  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
235  m_state = CCABUSY;
236  SaveTimer ();
237 
238  }
239 
240 }
241 void
243 {
244  if (m_state == CCABUSY)
245  {
246  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
247  m_state = RUNNING;
248  StartTimer ();
249 
250  }
251 
252 }
253 void
255 {
256 
257  if (m_txEndEvent.IsRunning ())
258  {
260  }
261 
262  m_txEndEvent = Simulator::Schedule (duration, &UanMacCw::EndTx, this);
263  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " scheduling TxEndEvent with delay " << duration.GetSeconds ());
264  if (m_state == RUNNING)
265  {
266  NS_ASSERT (0);
267  m_state = CCABUSY;
268  SaveTimer ();
269 
270  }
271 
272 }
273 
274 int64_t
275 UanMacCw::AssignStreams (int64_t stream)
276 {
277  NS_LOG_FUNCTION (this << stream);
278  m_rv->SetStream (stream);
279  return 1;
280 }
281 
282 void
284 {
285  NS_ASSERT (m_state == TX || m_state == CCABUSY);
286  if (m_state == TX)
287  {
288  m_state = IDLE;
289  }
290  else if (m_state == CCABUSY)
291  {
292  if (m_phy->IsStateIdle ())
293  {
294  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
295  m_state = RUNNING;
296  StartTimer ();
297  }
298  }
299  else
300  {
301  NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
302  }
303 }
304 void
305 UanMacCw::SetCw (uint32_t cw)
306 {
307  m_cw = cw;
308 }
309 void
311 {
312  m_slotTime = duration;
313 }
314 uint32_t
316 {
317  return m_cw;
318 }
319 Time
321 {
322  return m_slotTime;
323 }
324 void
326 {
327  NS_UNUSED (sinr);
328  UanHeaderCommon header;
329  packet->RemoveHeader (header);
330 
331  if (header.GetDest () == m_address || header.GetDest () == Mac8Address::GetBroadcast ())
332  {
333  m_forwardUpCb (packet, header.GetProtocolNumber (), header.GetSrc ());
334  }
335 }
336 void
338 {
339  NS_UNUSED (sinr);
340 }
341 void
343 {
344  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Simulator::Now ()).GetSeconds () << ")");
345  NS_ASSERT (m_pktTx);
349 
350 
351 }
352 void
354 {
355 
357  if (m_sendTime == Simulator::Now ())
358  {
359  SendPacket ();
360  }
361  else
362  {
364  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.GetSeconds () << ")");
365  }
366 }
367 
368 void
370 {
371  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Transmitting ");
373  m_state = TX;
374  m_phy->SendPacket (m_pktTx,m_pktTxProt);
375  m_pktTx = 0;
376  m_sendTime = Seconds (0);
377  m_savedDelayS = Seconds (0);
378 }
379 
380 } // namespace ns3
Transmitting.
Definition: uan-mac-cw.h:115
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
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:102
#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:1176
#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:149
void SendPacket(void)
Send packet on PHY.
Definition: uan-mac-cw.cc:369
void SetSrc(Mac8Address src)
Set the source address.
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:143
#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:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1015
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:821
#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:310
Mac8Address GetSrc(void) const
Get the source address.
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:185
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
A packet arrived at the MAC for transmission.
Definition: uan-mac-cw.h:127
bool m_cleared
Flag when we've been cleared.
Definition: uan-mac-cw.h:152
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
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's associated function will not be invoked when it expires...
Definition: simulator.cc:346
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Time m_savedDelayS
Remaining delay until next send.
Definition: uan-mac-cw.h:139
virtual void NotifyRxEndError(void)
Called when UanPhy finishes receiving packet in error.
Definition: uan-mac-cw.cc:218
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.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
Mac8Address m_address
The MAC address.
Definition: uan-mac-cw.h:121
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:49
tuple phy
Definition: third.py:86
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet destined for this MAC was received.
Definition: uan-mac-cw.h:125
AttributeValue implementation for Time.
Definition: nstime.h:1069
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:305
virtual void NotifyRxStart(void)
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:194
void EndTx(void)
End TX state.
Definition: uan-mac-cw.cc:283
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's.
Definition: mac8-address.h:42
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:179
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
Ptr< UniformRandomVariable > m_rv
Provides uniform random variable for contention window.
Definition: uan-mac-cw.h:155
virtual void NotifyRxEndOk(void)
Called when UanPhy finishes receiving packet without error.
Definition: uan-mac-cw.cc:206
void SaveTimer(void)
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:342
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:230
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:1070
virtual Time GetSlotTime(void)
Get the slot time duration.
Definition: uan-mac-cw.cc:320
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
Channel busy.
Definition: uan-mac-cw.h:113
virtual void NotifyTxStart(Time duration)
Called when transmission starts from Phy object.
Definition: uan-mac-cw.cc:254
virtual void DoDispose()
Destructor implementation.
Definition: uan-mac-cw.cc:70
EventId m_sendEvent
Scheduled SendPacket event.
Definition: uan-mac-cw.h:145
uint16_t GetProtocolNumber(void) const
Get the packet type value.
EventId m_txEndEvent
Scheduled EndTx event.
Definition: uan-mac-cw.h:147
virtual uint32_t GetCw(void)
Get the contention window size.
Definition: uan-mac-cw.cc:315
Time m_sendTime
Time to send next packet.
Definition: uan-mac-cw.h:137
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
Definition: uan-mac-cw.h:123
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:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1007
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:275
Time m_slotTime
Slot time duration.
Definition: uan-mac-cw.h:133
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:325
Ptr< Packet > m_pktTx
Next packet to send.
Definition: uan-mac-cw.h:141
void SetType(uint8_t type)
Set the header type.
uint32_t GetTxModeIndex()
Definition: uan-mac.cc:49
Mac8Address GetDest(void) const
Get the destination address.
void StartTimer(void)
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:353
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
A packet was passed down to the PHY from the MAC.
Definition: uan-mac-cw.h:129
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Packet received at lower layer in error.
Definition: uan-mac-cw.cc:337
Delay timer running.
Definition: uan-mac-cw.h:114
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:132
virtual void NotifyCcaEnd(void)
Called when UanPhy stops sensing channel is busy.
Definition: uan-mac-cw.cc:242
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:54
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
Idle state.
Definition: uan-mac-cw.h:112