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  ;
36 
38  : UanMac (),
39  m_phy (0),
40  m_pktTx (0),
41  m_state (IDLE),
42  m_cleared (false)
43 
44 {
45  m_rv = CreateObject<UniformRandomVariable> ();
46 }
47 
49 {
50 }
51 
52 void
54 {
55  if (m_cleared)
56  {
57  return;
58  }
59  m_cleared = true;
60  m_pktTx = 0;
61  if (m_phy)
62  {
63  m_phy->Clear ();
64  m_phy = 0;
65  }
68 }
69 
70 void
72 {
73  Clear ();
75 }
76 
77 TypeId
79 {
80  static TypeId tid = TypeId ("ns3::UanMacCw")
81  .SetParent<Object> ()
82  .AddConstructor<UanMacCw> ()
83  .AddAttribute ("CW",
84  "The MAC parameter CW.",
85  UintegerValue (10),
86  MakeUintegerAccessor (&UanMacCw::m_cw),
87  MakeUintegerChecker<uint32_t> ())
88  .AddAttribute ("SlotTime",
89  "Time slot duration for MAC backoff.",
90  TimeValue (MilliSeconds (20)),
91  MakeTimeAccessor (&UanMacCw::m_slotTime),
92  MakeTimeChecker ())
93  .AddTraceSource ("Enqueue",
94  "A packet arrived at the MAC for transmission.",
96  .AddTraceSource ("Dequeue",
97  "A was passed down to the PHY from the MAC.",
99  .AddTraceSource ("RX",
100  "A packet was destined for this MAC and was received.",
102 
103  ;
104  return tid;
105 }
106 
107 Address
109 {
110  return this->m_address;
111 }
112 
113 void
115 {
116  m_address = addr;
117 }
118 
119 bool
120 UanMacCw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
121 {
122 
123  switch (m_state)
124  {
125  case CCABUSY:
126  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
127  if (m_txEndEvent.IsRunning ())
128  {
129  NS_LOG_DEBUG ("State is TX");
130  }
131  else
132  {
133  NS_LOG_DEBUG ("State is not TX");
134  }
135 
136  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
137  return false;
138  case RUNNING:
139  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue RUNNING");
140  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
141  return false;
142  case TX:
143  case IDLE:
144  {
145  NS_ASSERT (!m_pktTx);
146 
147  UanHeaderCommon header;
148  header.SetDest (UanAddress::ConvertFrom (dest));
149  header.SetSrc (m_address);
150  header.SetType (0);
151  packet->AddHeader (header);
152 
153  m_enqueueLogger (packet, protocolNumber);
154 
155  if (m_phy->IsStateBusy ())
156  {
157  m_pktTx = packet;
158  m_pktTxProt = protocolNumber;
159  m_state = CCABUSY;
160  uint32_t cw = (uint32_t) m_rv->GetValue (0,m_cw);
161  m_savedDelayS = Seconds ((double)(cw) * m_slotTime.GetSeconds ());
163  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 ());
164  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
165  }
166  else
167  {
168  NS_ASSERT (m_state != TX);
169  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
170  NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
171  m_state = TX;
172  m_phy->SendPacket (packet,protocolNumber);
173 
174  }
175  break;
176  }
177  default:
178  NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
179  return false;
180  }
181 
182  return true;
183 
184 
185 }
186 
187 void
189 {
190  m_forwardUpCb = cb;
191 }
192 
193 void
195 {
196  m_phy = phy;
197  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
198  m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
199  m_phy->RegisterListener (this);
200 }
201 
202 Address
204 {
205  return UanAddress::GetBroadcast ();
206 }
207 
208 
209 void
211 {
212  if (m_state == RUNNING)
213  {
214 
215  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
216  SaveTimer ();
217  m_state = CCABUSY;
218  }
219 
220 }
221 void
223 {
224  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
225  {
226  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
227  m_state = RUNNING;
228  StartTimer ();
229 
230  }
231 
232 }
233 void
235 {
236  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
237  {
238  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
239  m_state = RUNNING;
240  StartTimer ();
241 
242  }
243 
244 }
245 void
247 {
248  if (m_state == RUNNING)
249  {
250  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
251  m_state = CCABUSY;
252  SaveTimer ();
253 
254  }
255 
256 }
257 void
259 {
260  if (m_state == CCABUSY)
261  {
262  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
263  m_state = RUNNING;
264  StartTimer ();
265 
266  }
267 
268 }
269 void
271 {
272 
273  if (m_txEndEvent.IsRunning ())
274  {
276  }
277 
278  m_txEndEvent = Simulator::Schedule (duration, &UanMacCw::EndTx, this);
279  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " scheduling TxEndEvent with delay " << duration.GetSeconds ());
280  if (m_state == RUNNING)
281  {
282  NS_ASSERT (0);
283  m_state = CCABUSY;
284  SaveTimer ();
285 
286  }
287 
288 }
289 
290 int64_t
291 UanMacCw::AssignStreams (int64_t stream)
292 {
293  NS_LOG_FUNCTION (this << stream);
294  m_rv->SetStream (stream);
295  return 1;
296 }
297 
298 void
300 {
301  NS_ASSERT (m_state == TX || m_state == CCABUSY);
302  if (m_state == TX)
303  {
304  m_state = IDLE;
305  }
306  else if (m_state == CCABUSY)
307  {
308  if (m_phy->IsStateIdle ())
309  {
310  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
311  m_state = RUNNING;
312  StartTimer ();
313  }
314  }
315  else
316  {
317  NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
318  }
319 }
320 void
321 UanMacCw::SetCw (uint32_t cw)
322 {
323  m_cw = cw;
324 }
325 void
327 {
328  m_slotTime = duration;
329 }
330 uint32_t
332 {
333  return m_cw;
334 }
335 Time
337 {
338  return m_slotTime;
339 }
340 void
342 {
343  UanHeaderCommon header;
344  packet->RemoveHeader (header);
345 
346  if (header.GetDest () == m_address || header.GetDest () == UanAddress::GetBroadcast ())
347  {
348  m_forwardUpCb (packet, header.GetSrc ());
349  }
350 }
351 void
353 {
354 
355 }
356 void
358 {
359  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Simulator::Now ()).GetSeconds () << ")");
360  NS_ASSERT (m_pktTx);
364 
365 
366 }
367 void
369 {
370 
372  if (m_sendTime == Simulator::Now ())
373  {
374  SendPacket ();
375  }
376  else
377  {
379  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.GetSeconds () << ")");
380  }
381 }
382 
383 void
385 {
386  NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Transmitting ");
388  m_state = TX;
389  m_phy->SendPacket (m_pktTx,m_pktTxProt);
390  m_pktTx = 0;
391  m_sendTime = Seconds (0);
392  m_savedDelayS = Seconds (0);
393 }
394 
395 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
virtual Address GetAddress()
Get the MAC Address.
Definition: uan-mac-cw.cc:108
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
Callback template class.
Definition: callback.h:920
State m_state
Current state.
Definition: uan-mac-cw.h:144
void SendPacket(void)
Send packet on PHY.
Definition: uan-mac-cw.cc:384
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:138
#define NS_ASSERT(condition)
Definition: assert.h:64
static TypeId GetTypeId(void)
Register this type.
Definition: uan-mac-cw.cc:78
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:62
uint32_t GetSize(void) const
Definition: packet.h:650
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:326
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:194
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
virtual void Clear(void)
Clears all pointer references.
Definition: uan-mac-cw.cc:53
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:203
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:824
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:234
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
a polymophic address class
Definition: address.h:86
virtual void SetAddress(UanAddress addr)
Set the address.
Definition: uan-mac-cw.cc:114
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:120
double GetSeconds(void) const
Definition: nstime.h:274
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:961
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:321
virtual void NotifyRxStart(void)
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:210
void EndTx(void)
End TX state.
Definition: uan-mac-cw.cc:299
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:41
UanMacCw()
Default constructor.
Definition: uan-mac-cw.cc:37
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
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:222
void SaveTimer(void)
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:357
static UanAddress GetBroadcast(void)
Get the broadcast address (255).
Definition: uan-address.cc:92
virtual ~UanMacCw()
Dummy destructor, DoDispose.
Definition: uan-mac-cw.cc:48
virtual void NotifyCcaStart(void)
Called when UanPhy begins sensing channel is busy.
Definition: uan-mac-cw.cc:246
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.
NS_LOG_COMPONENT_DEFINE("UanMacCw")
virtual Time GetSlotTime(void)
Get the slot time duration.
Definition: uan-mac-cw.cc:336
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:270
virtual void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: uan-mac-cw.cc:71
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:331
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)
Definition: log.h:289
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:291
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:188
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:341
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:452
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:63
void StartTimer(void)
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:368
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:352
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:258
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253