A Discrete-Event Network Simulator
API
uan-mac-cw.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 University of Washington
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Leonard Tracy <lentracy@gmail.com>
18  */
19 
20 #include "uan-mac-cw.h"
21 
22 #include "uan-header-common.h"
23 
24 #include "ns3/attribute.h"
25 #include "ns3/double.h"
26 #include "ns3/log.h"
27 #include "ns3/nstime.h"
28 #include "ns3/trace-source-accessor.h"
29 #include "ns3/uinteger.h"
30 
31 namespace ns3
32 {
33 
34 NS_LOG_COMPONENT_DEFINE("UanMacCw");
35 
37 
39  : UanMac(),
40  m_phy(nullptr),
41  m_pktTx(nullptr),
42  m_txOngoing(false),
43  m_state(IDLE),
44  m_cleared(false)
45 
46 {
47  m_rv = CreateObject<UniformRandomVariable>();
48 }
49 
51 {
52 }
53 
54 void
56 {
57  if (m_cleared)
58  {
59  return;
60  }
61  m_cleared = true;
62  m_pktTx = nullptr;
63  if (m_phy)
64  {
65  m_phy->Clear();
66  m_phy = nullptr;
67  }
69  m_txOngoing = false;
70 }
71 
72 void
74 {
75  Clear();
77 }
78 
79 TypeId
81 {
82  static TypeId tid = TypeId("ns3::UanMacCw")
83  .SetParent<UanMac>()
84  .SetGroupName("Uan")
85  .AddConstructor<UanMacCw>()
86  .AddAttribute("CW",
87  "The MAC parameter CW.",
88  UintegerValue(10),
90  MakeUintegerChecker<uint32_t>())
91  .AddAttribute("SlotTime",
92  "Time slot duration for MAC backoff.",
96  .AddTraceSource("Enqueue",
97  "A packet arrived at the MAC for transmission.",
99  "ns3::UanMacCw::QueueTracedCallback")
100  .AddTraceSource("Dequeue",
101  "A was passed down to the PHY from the MAC.",
103  "ns3::UanMacCw::QueueTracedCallback")
104  .AddTraceSource("RX",
105  "A packet was destined for this MAC and was received.",
107  "ns3::UanMac::PacketModeTracedCallback")
108 
109  ;
110  return tid;
111 }
112 
113 bool
114 UanMacCw::Enqueue(Ptr<Packet> packet, uint16_t protocolNumber, const Address& dest)
115 {
116  switch (m_state)
117  {
118  case CCABUSY:
119  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " MAC " << GetAddress()
120  << " Starting enqueue CCABUSY");
121  if (m_txOngoing)
122  {
123  NS_LOG_DEBUG("State is TX");
124  }
125  else
126  {
127  NS_LOG_DEBUG("State is not TX");
128  }
129 
130  NS_ASSERT(!m_phy->GetTransducer()->GetArrivalList().empty() || m_phy->IsStateTx());
131  return false;
132  case RUNNING:
133  NS_LOG_DEBUG("MAC " << GetAddress() << " Starting enqueue RUNNING");
134  NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().empty() && !m_phy->IsStateTx());
135  return false;
136  case TX:
137  case IDLE: {
138  NS_ASSERT(!m_pktTx);
139 
140  UanHeaderCommon header;
141  header.SetDest(Mac8Address::ConvertFrom(dest));
143  header.SetType(0);
144  header.SetProtocolNumber(0);
145  packet->AddHeader(header);
146 
147  m_enqueueLogger(packet, GetTxModeIndex());
148 
149  if (m_phy->IsStateBusy())
150  {
151  m_pktTx = packet;
153  m_state = CCABUSY;
154  auto cw = (uint32_t)m_rv->GetValue(0, m_cw);
155  m_savedDelayS = cw * m_slotTime;
157  NS_LOG_DEBUG("Time " << Now().As(Time::S) << ": Addr " << GetAddress()
158  << ": Enqueuing new packet while busy: (Chose CW " << cw
159  << ", Sending at " << m_sendTime.As(Time::S)
160  << " Packet size: " << packet->GetSize());
161  NS_ASSERT(!m_phy->GetTransducer()->GetArrivalList().empty() || m_phy->IsStateTx());
162  }
163  else
164  {
165  NS_ASSERT(m_state != TX);
166  NS_LOG_DEBUG("Time " << Now().As(Time::S) << ": Addr " << GetAddress()
167  << ": Enqueuing new packet while idle (sending)");
168  NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().empty() && !m_phy->IsStateTx());
169  m_state = TX;
170  m_phy->SendPacket(packet, GetTxModeIndex());
171  }
172  break;
173  }
174  default:
175  NS_LOG_DEBUG("MAC " << GetAddress() << " Starting enqueue SOMETHING ELSE");
176  return false;
177  }
178 
179  return true;
180 }
181 
182 void
184 {
185  m_forwardUpCb = cb;
186 }
187 
188 void
190 {
191  m_phy = phy;
192  m_phy->SetReceiveOkCallback(MakeCallback(&UanMacCw::PhyRxPacketGood, this));
193  m_phy->SetReceiveErrorCallback(MakeCallback(&UanMacCw::PhyRxPacketError, this));
194  m_phy->RegisterListener(this);
195 }
196 
197 void
199 {
200  if (m_state == RUNNING)
201  {
202  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
203  << ": Switching to channel busy");
204  SaveTimer();
205  m_state = CCABUSY;
206  }
207 }
208 
209 void
211 {
212  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy())
213  {
214  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
215  << ": Switching to channel idle");
216  m_state = RUNNING;
217  StartTimer();
218  }
219 }
220 
221 void
223 {
224  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy())
225  {
226  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
227  << ": Switching to channel idle");
228  m_state = RUNNING;
229  StartTimer();
230  }
231 }
232 
233 void
235 {
236  if (m_state == RUNNING)
237  {
238  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
239  << ": Switching to channel busy");
240  m_state = CCABUSY;
241  SaveTimer();
242  }
243 }
244 
245 void
247 {
248  if (m_state == CCABUSY)
249  {
250  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
251  << ": Switching to channel idle");
252  m_state = RUNNING;
253  StartTimer();
254  }
255 }
256 
257 void
259 {
260  m_txOngoing = true;
261 
262  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Tx Start Notified");
263 
264  if (m_state == RUNNING)
265  {
266  NS_ASSERT(0);
267  m_state = CCABUSY;
268  SaveTimer();
269  }
270 }
271 
272 void
274 {
275  m_txOngoing = false;
276 
277  EndTx();
278 }
279 
280 int64_t
281 UanMacCw::AssignStreams(int64_t stream)
282 {
283  NS_LOG_FUNCTION(this << stream);
284  m_rv->SetStream(stream);
285  return 1;
286 }
287 
288 void
290 {
291  NS_ASSERT(m_state == TX || m_state == CCABUSY);
292  if (m_state == TX)
293  {
294  m_state = IDLE;
295  }
296  else if (m_state == CCABUSY)
297  {
298  if (m_phy->IsStateIdle())
299  {
300  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
301  << ": Switching to channel idle (After TX!)");
302  m_state = RUNNING;
303  StartTimer();
304  }
305  }
306  else
307  {
308  NS_FATAL_ERROR("In strange state at UanMacCw EndTx");
309  }
310 }
311 
312 void
313 UanMacCw::SetCw(uint32_t cw)
314 {
315  m_cw = cw;
316 }
317 
318 void
320 {
321  m_slotTime = duration;
322 }
323 
324 uint32_t
326 {
327  return m_cw;
328 }
329 
330 Time
332 {
333  return m_slotTime;
334 }
335 
336 void
337 UanMacCw::PhyRxPacketGood(Ptr<Packet> packet, double /* sinr */, UanTxMode /* mode */)
338 {
339  UanHeaderCommon header;
340  packet->RemoveHeader(header);
341 
342  if (header.GetDest() == Mac8Address::ConvertFrom(GetAddress()) ||
343  header.GetDest() == Mac8Address::GetBroadcast())
344  {
345  m_forwardUpCb(packet, header.GetProtocolNumber(), header.GetSrc());
346  }
347 }
348 
349 void
350 UanMacCw::PhyRxPacketError(Ptr<Packet> /* packet */, double /* sinr */)
351 {
352 }
353 
354 void
356 {
357  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
358  << " Saving timer (Delay = "
359  << (m_savedDelayS = m_sendTime - Now()).As(Time::S) << ")");
364 }
365 
366 void
368 {
370  if (m_sendTime == Simulator::Now())
371  {
372  SendPacket();
373  }
374  else
375  {
377  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
378  << " Starting timer (New send time = " << this->m_sendTime.As(Time::S)
379  << ")");
380  }
381 }
382 
383 void
385 {
386  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress() << " Transmitting ");
388  m_state = TX;
389  m_phy->SendPacket(m_pktTx, m_pktTxProt);
390  m_pktTx = nullptr;
391  m_sendTime = Seconds(0);
392  m_savedDelayS = Seconds(0);
393 }
394 
395 } // namespace ns3
a polymophic address class
Definition: address.h:101
Callback template class.
Definition: callback.h:438
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
A class used for addressing MAC8 MAC's.
Definition: mac8-address.h:44
static Mac8Address GetBroadcast()
Get the broadcast address (255).
Definition: mac8-address.cc:88
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:56
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:285
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Common packet header fields.
void SetSrc(Mac8Address src)
Set the source address.
Mac8Address GetDest() const
Get the destination address.
void SetProtocolNumber(uint16_t protocolNumber)
Set the packet type.
Mac8Address GetSrc() const
Get the source address.
void SetDest(Mac8Address dest)
Set the destination address.
void SetType(uint8_t type)
Set the header type.
uint16_t GetProtocolNumber() const
Get the packet type value.
CW-MAC protocol, similar in idea to the 802.11 DCF with constant backoff window.
Definition: uan-mac-cw.h:48
bool m_txOngoing
Tx is ongoing.
Definition: uan-mac-cw.h:146
Time m_sendTime
Time to send next packet.
Definition: uan-mac-cw.h:136
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet destined for this MAC was received.
Definition: uan-mac-cw.h:124
void NotifyCcaStart() override
Called when UanPhy begins sensing channel is busy.
Definition: uan-mac-cw.cc:234
void Clear() override
Clears all pointer references.
Definition: uan-mac-cw.cc:55
Ptr< Packet > m_pktTx
Next packet to send.
Definition: uan-mac-cw.h:140
void SaveTimer()
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:355
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
A packet was passed down to the PHY from the MAC.
Definition: uan-mac-cw.h:128
void NotifyRxEndError() override
Called when UanPhy finishes receiving packet in error.
Definition: uan-mac-cw.cc:222
bool m_cleared
Flag when we've been cleared.
Definition: uan-mac-cw.h:151
void EndTx()
End TX state.
Definition: uan-mac-cw.cc:289
void SendPacket()
Send packet on PHY.
Definition: uan-mac-cw.cc:384
void NotifyCcaEnd() override
Called when UanPhy stops sensing channel is busy.
Definition: uan-mac-cw.cc:246
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:319
virtual uint32_t GetCw()
Get the contention window size.
Definition: uan-mac-cw.cc:325
static TypeId GetTypeId()
Register this type.
Definition: uan-mac-cw.cc:80
UanMacCw()
Default constructor.
Definition: uan-mac-cw.cc:38
State m_state
Current state.
Definition: uan-mac-cw.h:148
Ptr< UniformRandomVariable > m_rv
Provides uniform random variable for contention window.
Definition: uan-mac-cw.h:154
bool Enqueue(Ptr< Packet > pkt, uint16_t protocolNumber, const Address &dest) override
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:114
void NotifyRxEndOk() override
Called when UanPhy finishes receiving packet without error.
Definition: uan-mac-cw.cc:210
void DoDispose() override
Destructor implementation.
Definition: uan-mac-cw.cc:73
virtual void SetCw(uint32_t cw)
Set the contention window size.
Definition: uan-mac-cw.cc:313
Time m_slotTime
Slot time duration.
Definition: uan-mac-cw.h:132
~UanMacCw() override
Dummy destructor, DoDispose.
Definition: uan-mac-cw.cc:50
void NotifyTxStart(Time duration) override
Called when transmission starts from Phy object.
Definition: uan-mac-cw.cc:258
EventId m_sendEvent
Scheduled SendPacket event.
Definition: uan-mac-cw.h:144
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Packet received at lower layer in error.
Definition: uan-mac-cw.cc:350
Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > m_forwardUpCb
Forwarding up callback.
Definition: uan-mac-cw.h:120
void NotifyRxStart() override
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:198
void PhyRxPacketGood(Ptr< Packet > packet, double sinr, UanTxMode mode)
Receive packet from lower layer (passed to PHY as callback).
Definition: uan-mac-cw.cc:337
@ IDLE
Idle state.
Definition: uan-mac-cw.h:113
@ RUNNING
Delay timer running.
Definition: uan-mac-cw.h:115
@ TX
Transmitting.
Definition: uan-mac-cw.h:116
@ CCABUSY
Channel busy.
Definition: uan-mac-cw.h:114
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
A packet arrived at the MAC for transmission.
Definition: uan-mac-cw.h:126
void NotifyTxEnd() override
Function called when Phy object finishes transmitting packet.
Definition: uan-mac-cw.cc:273
Time m_savedDelayS
Remaining delay until next send.
Definition: uan-mac-cw.h:138
virtual Time GetSlotTime()
Get the slot time duration.
Definition: uan-mac-cw.cc:331
void StartTimer()
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:367
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
Definition: uan-mac-cw.h:122
uint32_t m_cw
Contention window size.
Definition: uan-mac-cw.h:131
void AttachPhy(Ptr< UanPhy > phy) override
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:189
void SetForwardUpCb(Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > cb) override
Set the callback to forward packets up to higher layers.
Definition: uan-mac-cw.cc:183
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:142
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
Definition: uan-mac-cw.cc:281
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:46
uint32_t GetTxModeIndex() const
Get the Tx mode index (Modulation type).
Definition: uan-mac.cc:46
virtual Address GetAddress()
Get the MAC Address.
Definition: uan-mac.cc:52
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:43
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76
phy
Definition: third.py:89