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)
Definition: packet.cc:268
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
virtual Address GetAddress()
Definition: uan-mac-cw.cc:107
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
Callback template class.
Definition: callback.h:920
void SendPacket(void)
Definition: uan-mac-cw.cc:383
uint16_t m_pktTxProt
Definition: uan-mac-cw.h:121
#define NS_ASSERT(condition)
Definition: assert.h:64
static TypeId GetTypeId(void)
Definition: uan-mac-cw.cc:77
uint32_t GetSize(void) const
Definition: packet.h:650
virtual void SetSlotTime(Time duration)
Definition: uan-mac-cw.cc:325
virtual void DoDispose(void)
Definition: object.cc:335
virtual void AttachPhy(Ptr< UanPhy > phy)
Definition: uan-mac-cw.cc:193
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
Definition: uan-mac-cw.h:110
virtual void Clear(void)
Definition: uan-mac-cw.cc:52
static void Cancel(const EventId &id)
Definition: simulator.cc:268
bool IsRunning(void) const
Definition: event-id.cc:59
virtual Address GetBroadcast(void) const
Definition: uan-mac-cw.cc:202
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
Time m_savedDelayS
Definition: uan-mac-cw.h:119
virtual void NotifyRxEndError(void)
Function called by UanPhy object to notify of packet received in error.
Definition: uan-mac-cw.cc:233
#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)
Definition: uan-mac-cw.cc:113
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
Definition: uan-mac-cw.cc:119
double GetSeconds(void) const
Definition: nstime.h:266
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:47
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
Definition: uan-mac-cw.h:109
hold objects of type ns3::Time
Definition: nstime.h:828
static UanAddress ConvertFrom(const Address &address)
Definition: uan-address.cc:54
Hold an unsigned integer type.
Definition: uinteger.h:46
void SetSrc(UanAddress src)
virtual void SetCw(uint32_t cw)
Definition: uan-mac-cw.cc:320
virtual void NotifyRxStart(void)
Function called by UanPhy object to notify of packet reception.
Definition: uan-mac-cw.cc:209
void EndTx(void)
Definition: uan-mac-cw.cc:298
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:36
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
Ptr< UniformRandomVariable > m_rv
Provides uniform random variables.
Definition: uan-mac-cw.h:129
void SetDest(UanAddress dest)
Callback< void, Ptr< Packet >, const UanAddress & > m_forwardUpCb
Definition: uan-mac-cw.h:106
virtual void NotifyRxEndOk(void)
Function called by UanPhy object to notify of packet received successfully.
Definition: uan-mac-cw.cc:221
void SaveTimer(void)
Definition: uan-mac-cw.cc:356
static UanAddress GetBroadcast(void)
Definition: uan-address.cc:92
virtual ~UanMacCw()
Definition: uan-mac-cw.cc:47
virtual void NotifyCcaStart(void)
Function called by UanPhy object to notify of channel sensed busy.
Definition: uan-mac-cw.cc:245
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
UanAddress GetDest(void) const
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)
Definition: uan-mac-cw.cc:335
static Time Now(void)
Definition: simulator.cc:180
virtual void NotifyTxStart(Time duration)
Function called by UanPhy object to notify of outgoing transmission start.
Definition: uan-mac-cw.cc:269
virtual void DoDispose()
Definition: uan-mac-cw.cc:70
EventId m_sendEvent
Definition: uan-mac-cw.h:122
EventId m_txEndEvent
Definition: uan-mac-cw.h:123
virtual uint32_t GetCw(void)
Definition: uan-mac-cw.cc:330
Ptr< UanPhy > m_phy
Definition: uan-mac-cw.h:108
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
int64_t AssignStreams(int64_t stream)
Definition: uan-mac-cw.cc:290
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, const UanAddress & > cb)
Definition: uan-mac-cw.cc:187
void Cancel(void)
Definition: event-id.cc:47
void PhyRxPacketGood(Ptr< Packet > packet, double sinr, UanTxMode mode)
Definition: uan-mac-cw.cc:340
Ptr< Packet > m_pktTx
Definition: uan-mac-cw.h:120
void SetType(uint8_t type)
UanAddress GetSrc(void) const
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
Definition: time.cc:404
UanAddress m_address
Definition: uan-mac-cw.h:107
a base class which provides memory management and object aggregation
Definition: object.h:63
void StartTimer(void)
Definition: uan-mac-cw.cc:367
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
Definition: uan-mac-cw.h:111
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Definition: uan-mac-cw.cc:351
a unique identifier for an interface.
Definition: type-id.h:49
uint32_t m_cw
Definition: uan-mac-cw.h:114
virtual void NotifyCcaEnd(void)
Function called by UanPhy object to notify of channel no longer sensed busy.
Definition: uan-mac-cw.cc:257
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void AddHeader(const Header &header)
Definition: packet.cc:253