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 NS_LOG_COMPONENT_DEFINE ("UanMacCw");
31 
32 namespace ns3 {
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),
85  MakeUintegerAccessor (&UanMacCw::m_cw),
86  MakeUintegerChecker<uint32_t> ())
87  .AddAttribute ("SlotTime",
88  "Time slot duration for MAC backoff.",
89  TimeValue (MilliSeconds (20)),
90  MakeTimeAccessor (&UanMacCw::m_slotTime),
91  MakeTimeChecker ())
92  .AddTraceSource ("Enqueue",
93  "A packet arrived at the MAC for transmission.",
95  .AddTraceSource ("Dequeue",
96  "A was passed down to the PHY from the MAC.",
98  .AddTraceSource ("RX",
99  "A packet was destined for this MAC and was received.",
101 
102  ;
103  return tid;
104 }
105 
106 Address
108 {
109  return this->m_address;
110 }
111 
112 void
114 {
115  m_address = addr;
116 }
117 
118 bool
119 UanMacCw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
120 {
121 
122  switch (m_state)
123  {
124  case CCABUSY:
125  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
126  if (m_txEndEvent.IsRunning ())
127  {
128  NS_LOG_DEBUG ("State is TX");
129  }
130  else
131  {
132  NS_LOG_DEBUG ("State is not TX");
133  }
134 
135  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
136  return false;
137  case RUNNING:
138  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue RUNNING");
139  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
140  return false;
141  case TX:
142  case IDLE:
143  {
144  NS_ASSERT (!m_pktTx);
145 
146  UanHeaderCommon header;
147  header.SetDest (UanAddress::ConvertFrom (dest));
148  header.SetSrc (m_address);
149  header.SetType (0);
150  packet->AddHeader (header);
151 
152  m_enqueueLogger (packet, protocolNumber);
153 
154  if (m_phy->IsStateBusy ())
155  {
156  m_pktTx = packet;
157  m_pktTxProt = protocolNumber;
158  m_state = CCABUSY;
159  uint32_t cw = (uint32_t) m_rv->GetValue (0,m_cw);
160  m_savedDelayS = Seconds ((double)(cw) * m_slotTime.GetSeconds ());
162  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 ());
163  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
164  }
165  else
166  {
167  NS_ASSERT (m_state != TX);
168  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
169  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
170  m_state = TX;
171  m_phy->SendPacket (packet,protocolNumber);
172 
173  }
174  break;
175  }
176  default:
177  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
178  return false;
179  }
180 
181  return true;
182 
183 
184 }
185 
186 void
188 {
189  m_forwardUpCb = cb;
190 }
191 
192 void
194 {
195  m_phy = phy;
196  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
197  m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
198  m_phy->RegisterListener (this);
199 }
200 
201 Address
203 {
204  return UanAddress::GetBroadcast ();
205 }
206 
207 
208 void
210 {
211  if (m_state == RUNNING)
212  {
213 
214  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
215  SaveTimer ();
216  m_state = CCABUSY;
217  }
218 
219 }
220 void
222 {
223  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
224  {
225  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
226  m_state = RUNNING;
227  StartTimer ();
228 
229  }
230 
231 }
232 void
234 {
235  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
236  {
237  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
238  m_state = RUNNING;
239  StartTimer ();
240 
241  }
242 
243 }
244 void
246 {
247  if (m_state == RUNNING)
248  {
249  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
250  m_state = CCABUSY;
251  SaveTimer ();
252 
253  }
254 
255 }
256 void
258 {
259  if (m_state == CCABUSY)
260  {
261  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
262  m_state = RUNNING;
263  StartTimer ();
264 
265  }
266 
267 }
268 void
270 {
271 
272  if (m_txEndEvent.IsRunning ())
273  {
275  }
276 
277  m_txEndEvent = Simulator::Schedule (duration, &UanMacCw::EndTx, this);
278  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " scheduling TxEndEvent with delay " << duration.GetSeconds ());
279  if (m_state == RUNNING)
280  {
281  NS_ASSERT (0);
282  m_state = CCABUSY;
283  SaveTimer ();
284 
285  }
286 
287 }
288 
289 int64_t
290 UanMacCw::AssignStreams (int64_t stream)
291 {
292  NS_LOG_FUNCTION (this << stream);
293  m_rv->SetStream (stream);
294  return 1;
295 }
296 
297 void
299 {
300  NS_ASSERT (m_state == TX || m_state == CCABUSY);
301  if (m_state == TX)
302  {
303  m_state = IDLE;
304  }
305  else if (m_state == CCABUSY)
306  {
307  if (m_phy->IsStateIdle ())
308  {
309  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
310  m_state = RUNNING;
311  StartTimer ();
312  }
313  }
314  else
315  {
316  NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
317  }
318 }
319 void
320 UanMacCw::SetCw (uint32_t cw)
321 {
322  m_cw = cw;
323 }
324 void
326 {
327  m_slotTime = duration;
328 }
329 uint32_t
331 {
332  return m_cw;
333 }
334 Time
336 {
337  return m_slotTime;
338 }
339 void
341 {
342  UanHeaderCommon header;
343  packet->RemoveHeader (header);
344 
345  if (header.GetDest () == m_address || header.GetDest () == UanAddress::GetBroadcast ())
346  {
347  m_forwardUpCb (packet, header.GetSrc ());
348  }
349 }
350 void
352 {
353 
354 }
355 void
357 {
358  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Simulator::Now ()).GetSeconds () << ")");
359  NS_ASSERT (m_pktTx);
363 
364 
365 }
366 void
368 {
369 
371  if (m_sendTime == Simulator::Now ())
372  {
373  SendPacket ();
374  }
375  else
376  {
378  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.GetSeconds () << ")");
379  }
380 }
381 
382 void
384 {
385  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Transmitting ");
387  m_state = TX;
388  m_phy->SendPacket (m_pktTx,m_pktTxProt);
389  m_pktTx = 0;
390  m_sendTime = Seconds (0);
391  m_savedDelayS = Seconds (0);
392 }
393 
394 } // namespace ns3
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:79
virtual Address GetAddress()
Get the MAC Address.
Definition: uan-mac-cw.cc:107
#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:924
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
State m_state
Current state.
Definition: uan-mac-cw.h:144
void SendPacket(void)
Send packet on PHY.
Definition: uan-mac-cw.cc:383
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:138
#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:170
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:325
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:193
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
A packet arrived at the MAC for transmission.
Definition: uan-mac-cw.h:122
bool m_cleared
Flag when we've been cleared.
Definition: uan-mac-cw.h:147
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
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:268
bool IsRunning(void) const
This method is syntactic sugar for the ns3::Simulator::isExpired method.
Definition: event-id.cc:59
Idle state.
Definition: uan-mac-cw.h:107
virtual Address GetBroadcast(void) const
Get the broadcast address.
Definition: uan-mac-cw.cc:202
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:825
Time m_savedDelayS
Remaining delay until next send.
Definition: uan-mac-cw.h:134
virtual void NotifyRxEndError(void)
Called when UanPhy finishes receiving packet in error.
Definition: uan-mac-cw.cc:233
a polymophic address class
Definition: address.h:86
virtual void SetAddress(UanAddress addr)
Set the address.
Definition: uan-mac-cw.cc:113
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:119
double GetSeconds(void) const
Definition: nstime.h:272
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:47
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet destined for this MAC was received.
Definition: uan-mac-cw.h:120
hold objects of type ns3::Time
Definition: nstime.h:1008
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:46
void SetSrc(UanAddress src)
Set the source address.
virtual void SetCw(uint32_t cw)
Set the contention window size.
Definition: uan-mac-cw.cc:320
virtual void NotifyRxStart(void)
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:209
void EndTx(void)
End TX state.
Definition: uan-mac-cw.cc:298
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:1242
Ptr< UniformRandomVariable > m_rv
Provides uniform random variable for contention window.
Definition: uan-mac-cw.h:150
void SetDest(UanAddress dest)
Set the destination address.
Callback< void, Ptr< Packet >, const UanAddress & > m_forwardUpCb
Forwarding up callback.
Definition: uan-mac-cw.h:114
virtual void NotifyRxEndOk(void)
Called when UanPhy finishes receiving packet without error.
Definition: uan-mac-cw.cc:221
void SaveTimer(void)
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:356
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:245
Common packet header fields.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
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.
virtual Time GetSlotTime(void)
Get the slot time duration.
Definition: uan-mac-cw.cc:335
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
virtual void NotifyTxStart(Time duration)
Called when transmission starts from Phy object.
Definition: uan-mac-cw.cc:269
virtual void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: uan-mac-cw.cc:70
Channel busy.
Definition: uan-mac-cw.h:108
EventId m_sendEvent
Scheduled SendPacket event.
Definition: uan-mac-cw.h:140
EventId m_txEndEvent
Scheduled EndTx event.
Definition: uan-mac-cw.h:142
virtual uint32_t GetCw(void)
Get the contention window size.
Definition: uan-mac-cw.cc:330
Time m_sendTime
Time to send next packet.
Definition: uan-mac-cw.h:132
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
Definition: uan-mac-cw.h:118
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
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:290
Time m_slotTime
Slot time duration.
Definition: uan-mac-cw.h:128
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:187
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::cancel method.
Definition: event-id.cc:47
void PhyRxPacketGood(Ptr< Packet > packet, double sinr, UanTxMode mode)
Receive packet from lower layer (passed to PHY as callback).
Definition: uan-mac-cw.cc:340
Ptr< Packet > m_pktTx
Next packet to send.
Definition: uan-mac-cw.h:136
void SetType(uint8_t type)
Set the header type.
UanAddress GetSrc(void) const
Get the source address.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
UanAddress m_address
The MAC address.
Definition: uan-mac-cw.h:116
Delay timer running.
Definition: uan-mac-cw.h:109
a base class which provides memory management and object aggregation
Definition: object.h:64
void StartTimer(void)
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:367
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
A packet was passed down to the PHY from the MAC.
Definition: uan-mac-cw.h:124
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Packet received at lower layer in error.
Definition: uan-mac-cw.cc:351
a unique identifier for an interface.
Definition: type-id.h:49
uint32_t m_cw
Contention window size.
Definition: uan-mac-cw.h:127
Transmitting.
Definition: uan-mac-cw.h:110
virtual void NotifyCcaEnd(void)
Called when UanPhy stops sensing channel is busy.
Definition: uan-mac-cw.cc:257
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253