A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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
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:311
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:340
Idle state.
Definition: uan-mac-cw.h:115
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:1221
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
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:223
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
Channel busy.
Definition: uan-mac-cw.h:116
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
Delay timer running.
Definition: uan-mac-cw.h:117
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
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
Transmitting.
Definition: uan-mac-cw.h:118
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:827
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257