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<Object> ()
81  .AddConstructor<UanMacCw> ()
82  .AddAttribute ("CW",
83  "The MAC parameter CW.",
84  UintegerValue (10),
86  MakeUintegerChecker<uint32_t> ())
87  .AddAttribute ("SlotTime",
88  "Time slot duration for MAC backoff.",
89  TimeValue (MilliSeconds (20)),
91  MakeTimeChecker ())
92  .AddTraceSource ("Enqueue",
93  "A packet arrived at the MAC for transmission.",
95  "ns3::UanMacCw::QueueTracedCallback")
96  .AddTraceSource ("Dequeue",
97  "A was passed down to the PHY from the MAC.",
99  "ns3::UanMacCw::QueueTracedCallback")
100  .AddTraceSource ("RX",
101  "A packet was destined for this MAC and was received.",
103  "ns3::UanMac::PacketModeTracedCallback")
104 
105  ;
106  return tid;
107 }
108 
109 Address
111 {
112  return this->m_address;
113 }
114 
115 void
117 {
118  m_address = addr;
119 }
120 
121 bool
122 UanMacCw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
123 {
124 
125  switch (m_state)
126  {
127  case CCABUSY:
128  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
129  if (m_txEndEvent.IsRunning ())
130  {
131  NS_LOG_DEBUG ("State is TX");
132  }
133  else
134  {
135  NS_LOG_DEBUG ("State is not TX");
136  }
137 
138  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
139  return false;
140  case RUNNING:
141  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue RUNNING");
142  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
143  return false;
144  case TX:
145  case IDLE:
146  {
147  NS_ASSERT (!m_pktTx);
148 
149  UanHeaderCommon header;
150  header.SetDest (UanAddress::ConvertFrom (dest));
151  header.SetSrc (m_address);
152  header.SetType (0);
153  packet->AddHeader (header);
154 
155  m_enqueueLogger (packet, protocolNumber);
156 
157  if (m_phy->IsStateBusy ())
158  {
159  m_pktTx = packet;
160  m_pktTxProt = protocolNumber;
161  m_state = CCABUSY;
162  uint32_t cw = (uint32_t) m_rv->GetValue (0,m_cw);
163  m_savedDelayS = Seconds ((double)(cw) * m_slotTime.GetSeconds ());
165  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 ());
166  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
167  }
168  else
169  {
170  NS_ASSERT (m_state != TX);
171  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
172  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
173  m_state = TX;
174  m_phy->SendPacket (packet,protocolNumber);
175 
176  }
177  break;
178  }
179  default:
180  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
181  return false;
182  }
183 
184  return true;
185 
186 
187 }
188 
189 void
191 {
192  m_forwardUpCb = cb;
193 }
194 
195 void
197 {
198  m_phy = phy;
199  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
200  m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
201  m_phy->RegisterListener (this);
202 }
203 
204 Address
206 {
207  return UanAddress::GetBroadcast ();
208 }
209 
210 
211 void
213 {
214  if (m_state == RUNNING)
215  {
216 
217  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
218  SaveTimer ();
219  m_state = CCABUSY;
220  }
221 
222 }
223 void
225 {
226  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
227  {
228  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
229  m_state = RUNNING;
230  StartTimer ();
231 
232  }
233 
234 }
235 void
237 {
238  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
239  {
240  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
241  m_state = RUNNING;
242  StartTimer ();
243 
244  }
245 
246 }
247 void
249 {
250  if (m_state == RUNNING)
251  {
252  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
253  m_state = CCABUSY;
254  SaveTimer ();
255 
256  }
257 
258 }
259 void
261 {
262  if (m_state == CCABUSY)
263  {
264  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
265  m_state = RUNNING;
266  StartTimer ();
267 
268  }
269 
270 }
271 void
273 {
274 
275  if (m_txEndEvent.IsRunning ())
276  {
278  }
279 
280  m_txEndEvent = Simulator::Schedule (duration, &UanMacCw::EndTx, this);
281  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " scheduling TxEndEvent with delay " << duration.GetSeconds ());
282  if (m_state == RUNNING)
283  {
284  NS_ASSERT (0);
285  m_state = CCABUSY;
286  SaveTimer ();
287 
288  }
289 
290 }
291 
292 int64_t
293 UanMacCw::AssignStreams (int64_t stream)
294 {
295  NS_LOG_FUNCTION (this << stream);
296  m_rv->SetStream (stream);
297  return 1;
298 }
299 
300 void
302 {
303  NS_ASSERT (m_state == TX || m_state == CCABUSY);
304  if (m_state == TX)
305  {
306  m_state = IDLE;
307  }
308  else if (m_state == CCABUSY)
309  {
310  if (m_phy->IsStateIdle ())
311  {
312  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
313  m_state = RUNNING;
314  StartTimer ();
315  }
316  }
317  else
318  {
319  NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
320  }
321 }
322 void
323 UanMacCw::SetCw (uint32_t cw)
324 {
325  m_cw = cw;
326 }
327 void
329 {
330  m_slotTime = duration;
331 }
332 uint32_t
334 {
335  return m_cw;
336 }
337 Time
339 {
340  return m_slotTime;
341 }
342 void
344 {
345  UanHeaderCommon header;
346  packet->RemoveHeader (header);
347 
348  if (header.GetDest () == m_address || header.GetDest () == UanAddress::GetBroadcast ())
349  {
350  m_forwardUpCb (packet, header.GetSrc ());
351  }
352 }
353 void
355 {
356 
357 }
358 void
360 {
361  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Simulator::Now ()).GetSeconds () << ")");
362  NS_ASSERT (m_pktTx);
366 
367 
368 }
369 void
371 {
372 
374  if (m_sendTime == Simulator::Now ())
375  {
376  SendPacket ();
377  }
378  else
379  {
381  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.GetSeconds () << ")");
382  }
383 }
384 
385 void
387 {
388  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Transmitting ");
390  m_state = TX;
391  m_phy->SendPacket (m_pktTx,m_pktTxProt);
392  m_pktTx = 0;
393  m_sendTime = Seconds (0);
394  m_savedDelayS = Seconds (0);
395 }
396 
397 } // namespace ns3
Transmitting.
Definition: uan-mac-cw.h:118
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
virtual Address GetAddress()
Get the MAC Address.
Definition: uan-mac-cw.cc:110
#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 this RNG stream.
Callback template class.
Definition: callback.h:978
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
State m_state
Current state.
Definition: uan-mac-cw.h:152
void SendPacket(void)
Send packet on PHY.
Definition: uan-mac-cw.cc:386
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:146
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
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:62
#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:867
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:328
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:338
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:196
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
A packet arrived at the MAC for transmission.
Definition: uan-mac-cw.h:130
bool m_cleared
Flag when we've been cleared.
Definition: uan-mac-cw.h:155
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
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:311
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
virtual Address GetBroadcast(void) const
Get the broadcast address.
Definition: uan-mac-cw.cc:205
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
Time m_savedDelayS
Remaining delay until next send.
Definition: uan-mac-cw.h:142
virtual void NotifyRxEndError(void)
Called when UanPhy finishes receiving packet in error.
Definition: uan-mac-cw.cc:236
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.
virtual void SetAddress(UanAddress addr)
Set the address.
Definition: uan-mac-cw.cc:116
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:122
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:327
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:48
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet destined for this MAC was received.
Definition: uan-mac-cw.h:128
AttributeValue implementation for Time.
Definition: nstime.h:921
A class used for addressing UAN MAC's.
Definition: uan-address.h:40
static UanAddress ConvertFrom(const Address &address)
Convert a generic address to a UanAddress.
Definition: uan-address.cc:54
Hold an unsigned integer type.
Definition: uinteger.h:44
void SetSrc(UanAddress src)
Set the source address.
virtual void SetCw(uint32_t cw)
Set the contention window size.
Definition: uan-mac-cw.cc:323
virtual void NotifyRxStart(void)
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:212
void EndTx(void)
End TX state.
Definition: uan-mac-cw.cc:301
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:41
UanMacCw()
Default constructor.
Definition: uan-mac-cw.cc:36
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
Ptr< UniformRandomVariable > m_rv
Provides uniform random variable for contention window.
Definition: uan-mac-cw.h:158
void SetDest(UanAddress dest)
Set the destination address.
Callback< void, Ptr< Packet >, const UanAddress & > m_forwardUpCb
Forwarding up callback.
Definition: uan-mac-cw.h:122
virtual void NotifyRxEndOk(void)
Called when UanPhy finishes receiving packet without error.
Definition: uan-mac-cw.cc:224
void SaveTimer(void)
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:359
static UanAddress GetBroadcast(void)
Get the broadcast address (255).
Definition: uan-address.cc:92
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:248
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Common packet header fields.
UanAddress GetDest(void) const
Get the destination address.
double GetValue(double min, double max)
Returns a random double from the uniform distribution with 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:922
virtual Time GetSlotTime(void)
Get the slot time duration.
Definition: uan-mac-cw.cc:338
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
Channel busy.
Definition: uan-mac-cw.h:116
virtual void NotifyTxStart(Time duration)
Called when transmission starts from Phy object.
Definition: uan-mac-cw.cc:272
virtual void DoDispose()
Destructor implementation.
Definition: uan-mac-cw.cc:70
EventId m_sendEvent
Scheduled SendPacket event.
Definition: uan-mac-cw.h:148
EventId m_txEndEvent
Scheduled EndTx event.
Definition: uan-mac-cw.h:150
virtual uint32_t GetCw(void)
Get the contention window size.
Definition: uan-mac-cw.cc:333
Time m_sendTime
Time to send next packet.
Definition: uan-mac-cw.h:140
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
Definition: uan-mac-cw.h:126
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
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:293
Time m_slotTime
Slot time duration.
Definition: uan-mac-cw.h:136
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, const UanAddress & > cb)
Set the callback to forward packets up to higher layers.
Definition: uan-mac-cw.cc:190
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:343
Ptr< Packet > m_pktTx
Next packet to send.
Definition: uan-mac-cw.h:144
void SetType(uint8_t type)
Set the header type.
UanAddress GetSrc(void) const
Get the source address.
UanAddress m_address
The MAC address.
Definition: uan-mac-cw.h:124
A base class which provides memory management and object aggregation.
Definition: object.h:87
void StartTimer(void)
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:370
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
A packet was passed down to the PHY from the MAC.
Definition: uan-mac-cw.h:132
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Packet received at lower layer in error.
Definition: uan-mac-cw.cc:354
Delay timer running.
Definition: uan-mac-cw.h:117
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:51
uint32_t m_cw
Contention window size.
Definition: uan-mac-cw.h:135
virtual void NotifyCcaEnd(void)
Called when UanPhy stops sensing channel is busy.
Definition: uan-mac-cw.cc:260
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Idle state.
Definition: uan-mac-cw.h:115