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 Address
112 {
113  return this->m_address;
114 }
115 
116 void
118 {
119  m_address = addr;
120 }
121 
122 bool
123 UanMacCw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
124 {
125 
126  switch (m_state)
127  {
128  case CCABUSY:
129  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
130  if (m_txEndEvent.IsRunning ())
131  {
132  NS_LOG_DEBUG ("State is TX");
133  }
134  else
135  {
136  NS_LOG_DEBUG ("State is not TX");
137  }
138 
139  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
140  return false;
141  case RUNNING:
142  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue RUNNING");
143  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
144  return false;
145  case TX:
146  case IDLE:
147  {
148  NS_ASSERT (!m_pktTx);
149 
150  UanHeaderCommon header;
151  header.SetDest (UanAddress::ConvertFrom (dest));
152  header.SetSrc (m_address);
153  header.SetType (0);
154  packet->AddHeader (header);
155 
156  m_enqueueLogger (packet, protocolNumber);
157 
158  if (m_phy->IsStateBusy ())
159  {
160  m_pktTx = packet;
161  m_pktTxProt = protocolNumber;
162  m_state = CCABUSY;
163  uint32_t cw = (uint32_t) m_rv->GetValue (0,m_cw);
164  m_savedDelayS = Seconds ((double)(cw) * m_slotTime.GetSeconds ());
166  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 ());
167  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
168  }
169  else
170  {
171  NS_ASSERT (m_state != TX);
172  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
173  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
174  m_state = TX;
175  m_phy->SendPacket (packet,protocolNumber);
176 
177  }
178  break;
179  }
180  default:
181  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
182  return false;
183  }
184 
185  return true;
186 
187 
188 }
189 
190 void
192 {
193  m_forwardUpCb = cb;
194 }
195 
196 void
198 {
199  m_phy = phy;
200  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
201  m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
202  m_phy->RegisterListener (this);
203 }
204 
205 Address
207 {
208  return UanAddress::GetBroadcast ();
209 }
210 
211 
212 void
214 {
215  if (m_state == RUNNING)
216  {
217 
218  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
219  SaveTimer ();
220  m_state = CCABUSY;
221  }
222 
223 }
224 void
226 {
227  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
228  {
229  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
230  m_state = RUNNING;
231  StartTimer ();
232 
233  }
234 
235 }
236 void
238 {
239  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
240  {
241  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
242  m_state = RUNNING;
243  StartTimer ();
244 
245  }
246 
247 }
248 void
250 {
251  if (m_state == RUNNING)
252  {
253  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
254  m_state = CCABUSY;
255  SaveTimer ();
256 
257  }
258 
259 }
260 void
262 {
263  if (m_state == CCABUSY)
264  {
265  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
266  m_state = RUNNING;
267  StartTimer ();
268 
269  }
270 
271 }
272 void
274 {
275 
276  if (m_txEndEvent.IsRunning ())
277  {
279  }
280 
281  m_txEndEvent = Simulator::Schedule (duration, &UanMacCw::EndTx, this);
282  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " scheduling TxEndEvent with delay " << duration.GetSeconds ());
283  if (m_state == RUNNING)
284  {
285  NS_ASSERT (0);
286  m_state = CCABUSY;
287  SaveTimer ();
288 
289  }
290 
291 }
292 
293 int64_t
294 UanMacCw::AssignStreams (int64_t stream)
295 {
296  NS_LOG_FUNCTION (this << stream);
297  m_rv->SetStream (stream);
298  return 1;
299 }
300 
301 void
303 {
304  NS_ASSERT (m_state == TX || m_state == CCABUSY);
305  if (m_state == TX)
306  {
307  m_state = IDLE;
308  }
309  else if (m_state == CCABUSY)
310  {
311  if (m_phy->IsStateIdle ())
312  {
313  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
314  m_state = RUNNING;
315  StartTimer ();
316  }
317  }
318  else
319  {
320  NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
321  }
322 }
323 void
324 UanMacCw::SetCw (uint32_t cw)
325 {
326  m_cw = cw;
327 }
328 void
330 {
331  m_slotTime = duration;
332 }
333 uint32_t
335 {
336  return m_cw;
337 }
338 Time
340 {
341  return m_slotTime;
342 }
343 void
345 {
346  UanHeaderCommon header;
347  packet->RemoveHeader (header);
348 
349  if (header.GetDest () == m_address || header.GetDest () == UanAddress::GetBroadcast ())
350  {
351  m_forwardUpCb (packet, header.GetSrc ());
352  }
353 }
354 void
356 {
357 
358 }
359 void
361 {
362  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Simulator::Now ()).GetSeconds () << ")");
363  NS_ASSERT (m_pktTx);
367 
368 
369 }
370 void
372 {
373 
375  if (m_sendTime == Simulator::Now ())
376  {
377  SendPacket ();
378  }
379  else
380  {
382  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.GetSeconds () << ")");
383  }
384 }
385 
386 void
388 {
389  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Transmitting ");
391  m_state = TX;
392  m_phy->SendPacket (m_pktTx,m_pktTxProt);
393  m_pktTx = 0;
394  m_sendTime = Seconds (0);
395  m_savedDelayS = Seconds (0);
396 }
397 
398 } // 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
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
virtual Address GetAddress()
Get the MAC Address.
Definition: uan-mac-cw.cc:111
#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:1176
#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:387
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: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:903
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:329
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:197
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)
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:321
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
virtual Address GetBroadcast(void) const
Get the broadcast address.
Definition: uan-mac-cw.cc:206
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:237
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:117
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:123
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:48
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:1238
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:957
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:324
virtual void NotifyRxStart(void)
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:213
void EndTx(void)
End TX state.
Definition: uan-mac-cw.cc:302
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:1489
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:225
void SaveTimer(void)
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:360
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:249
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)
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:958
virtual Time GetSlotTime(void)
Get the slot time duration.
Definition: uan-mac-cw.cc:339
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
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:273
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:334
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:895
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:294
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:191
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:344
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
void StartTimer(void)
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:371
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:355
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:58
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:261
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
Idle state.
Definition: uan-mac-cw.h:115