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 "ns3/attribute.h"
23 #include "ns3/double.h"
24 #include "ns3/log.h"
25 #include "ns3/nstime.h"
26 #include "ns3/trace-source-accessor.h"
27 #include "ns3/uan-header-common.h"
28 #include "ns3/uinteger.h"
29 
30 namespace ns3
31 {
32 
33 NS_LOG_COMPONENT_DEFINE("UanMacCw");
34 
36 
38  : UanMac(),
39  m_phy(nullptr),
40  m_pktTx(nullptr),
41  m_txOngoing(false),
42  m_state(IDLE),
43  m_cleared(false)
44 
45 {
46  m_rv = CreateObject<UniformRandomVariable>();
47 }
48 
50 {
51 }
52 
53 void
55 {
56  if (m_cleared)
57  {
58  return;
59  }
60  m_cleared = true;
61  m_pktTx = nullptr;
62  if (m_phy)
63  {
64  m_phy->Clear();
65  m_phy = nullptr;
66  }
68  m_txOngoing = false;
69 }
70 
71 void
73 {
74  Clear();
76 }
77 
78 TypeId
80 {
81  static TypeId tid = TypeId("ns3::UanMacCw")
82  .SetParent<UanMac>()
83  .SetGroupName("Uan")
84  .AddConstructor<UanMacCw>()
85  .AddAttribute("CW",
86  "The MAC parameter CW.",
87  UintegerValue(10),
89  MakeUintegerChecker<uint32_t>())
90  .AddAttribute("SlotTime",
91  "Time slot duration for MAC backoff.",
95  .AddTraceSource("Enqueue",
96  "A packet arrived at the MAC for transmission.",
98  "ns3::UanMacCw::QueueTracedCallback")
99  .AddTraceSource("Dequeue",
100  "A was passed down to the PHY from the MAC.",
102  "ns3::UanMacCw::QueueTracedCallback")
103  .AddTraceSource("RX",
104  "A packet was destined for this MAC and was received.",
106  "ns3::UanMac::PacketModeTracedCallback")
107 
108  ;
109  return tid;
110 }
111 
112 bool
113 UanMacCw::Enqueue(Ptr<Packet> packet, uint16_t protocolNumber, const Address& dest)
114 {
115  switch (m_state)
116  {
117  case CCABUSY:
118  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " MAC " << GetAddress()
119  << " Starting enqueue CCABUSY");
120  if (m_txOngoing == true)
121  {
122  NS_LOG_DEBUG("State is TX");
123  }
124  else
125  {
126  NS_LOG_DEBUG("State is not TX");
127  }
128 
129  NS_ASSERT(!m_phy->GetTransducer()->GetArrivalList().empty() || m_phy->IsStateTx());
130  return false;
131  case RUNNING:
132  NS_LOG_DEBUG("MAC " << GetAddress() << " Starting enqueue RUNNING");
133  NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().empty() && !m_phy->IsStateTx());
134  return false;
135  case TX:
136  case IDLE: {
137  NS_ASSERT(!m_pktTx);
138 
139  UanHeaderCommon header;
140  header.SetDest(Mac8Address::ConvertFrom(dest));
142  header.SetType(0);
143  header.SetProtocolNumber(0);
144  packet->AddHeader(header);
145 
146  m_enqueueLogger(packet, GetTxModeIndex());
147 
148  if (m_phy->IsStateBusy())
149  {
150  m_pktTx = packet;
152  m_state = CCABUSY;
153  uint32_t cw = (uint32_t)m_rv->GetValue(0, m_cw);
154  m_savedDelayS = cw * m_slotTime;
156  NS_LOG_DEBUG("Time " << Now().As(Time::S) << ": Addr " << GetAddress()
157  << ": Enqueuing new packet while busy: (Chose CW " << cw
158  << ", Sending at " << m_sendTime.As(Time::S)
159  << " Packet size: " << packet->GetSize());
160  NS_ASSERT(!m_phy->GetTransducer()->GetArrivalList().empty() || m_phy->IsStateTx());
161  }
162  else
163  {
164  NS_ASSERT(m_state != TX);
165  NS_LOG_DEBUG("Time " << Now().As(Time::S) << ": Addr " << GetAddress()
166  << ": Enqueuing new packet while idle (sending)");
167  NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().empty() && !m_phy->IsStateTx());
168  m_state = TX;
169  m_phy->SendPacket(packet, GetTxModeIndex());
170  }
171  break;
172  }
173  default:
174  NS_LOG_DEBUG("MAC " << GetAddress() << " Starting enqueue SOMETHING ELSE");
175  return false;
176  }
177 
178  return true;
179 }
180 
181 void
183 {
184  m_forwardUpCb = cb;
185 }
186 
187 void
189 {
190  m_phy = phy;
191  m_phy->SetReceiveOkCallback(MakeCallback(&UanMacCw::PhyRxPacketGood, this));
192  m_phy->SetReceiveErrorCallback(MakeCallback(&UanMacCw::PhyRxPacketError, this));
193  m_phy->RegisterListener(this);
194 }
195 
196 void
198 {
199  if (m_state == RUNNING)
200  {
201  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
202  << ": Switching to channel busy");
203  SaveTimer();
204  m_state = CCABUSY;
205  }
206 }
207 
208 void
210 {
211  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy())
212  {
213  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
214  << ": Switching to channel idle");
215  m_state = RUNNING;
216  StartTimer();
217  }
218 }
219 
220 void
222 {
223  if (m_state == CCABUSY && !m_phy->IsStateCcaBusy())
224  {
225  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
226  << ": Switching to channel idle");
227  m_state = RUNNING;
228  StartTimer();
229  }
230 }
231 
232 void
234 {
235  if (m_state == RUNNING)
236  {
237  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
238  << ": Switching to channel busy");
239  m_state = CCABUSY;
240  SaveTimer();
241  }
242 }
243 
244 void
246 {
247  if (m_state == CCABUSY)
248  {
249  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
250  << ": Switching to channel idle");
251  m_state = RUNNING;
252  StartTimer();
253  }
254 }
255 
256 void
258 {
259  m_txOngoing = true;
260 
261  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Tx Start Notified");
262 
263  if (m_state == RUNNING)
264  {
265  NS_ASSERT(0);
266  m_state = CCABUSY;
267  SaveTimer();
268  }
269 }
270 
271 void
273 {
274  m_txOngoing = false;
275 
276  EndTx();
277 }
278 
279 int64_t
280 UanMacCw::AssignStreams(int64_t stream)
281 {
282  NS_LOG_FUNCTION(this << stream);
283  m_rv->SetStream(stream);
284  return 1;
285 }
286 
287 void
289 {
290  NS_ASSERT(m_state == TX || m_state == CCABUSY);
291  if (m_state == TX)
292  {
293  m_state = IDLE;
294  }
295  else if (m_state == CCABUSY)
296  {
297  if (m_phy->IsStateIdle())
298  {
299  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
300  << ": Switching to channel idle (After TX!)");
301  m_state = RUNNING;
302  StartTimer();
303  }
304  }
305  else
306  {
307  NS_FATAL_ERROR("In strange state at UanMacCw EndTx");
308  }
309 }
310 
311 void
312 UanMacCw::SetCw(uint32_t cw)
313 {
314  m_cw = cw;
315 }
316 
317 void
319 {
320  m_slotTime = duration;
321 }
322 
323 uint32_t
325 {
326  return m_cw;
327 }
328 
329 Time
331 {
332  return m_slotTime;
333 }
334 
335 void
336 UanMacCw::PhyRxPacketGood(Ptr<Packet> packet, double /* sinr */, UanTxMode /* mode */)
337 {
338  UanHeaderCommon header;
339  packet->RemoveHeader(header);
340 
341  if (header.GetDest() == Mac8Address::ConvertFrom(GetAddress()) ||
342  header.GetDest() == Mac8Address::GetBroadcast())
343  {
344  m_forwardUpCb(packet, header.GetProtocolNumber(), header.GetSrc());
345  }
346 }
347 
348 void
349 UanMacCw::PhyRxPacketError(Ptr<Packet> /* packet */, double /* sinr */)
350 {
351 }
352 
353 void
355 {
356  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
357  << " Saving timer (Delay = "
358  << (m_savedDelayS = m_sendTime - Now()).As(Time::S) << ")");
363 }
364 
365 void
367 {
369  if (m_sendTime == Simulator::Now())
370  {
371  SendPacket();
372  }
373  else
374  {
376  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress()
377  << " Starting timer (New send time = " << this->m_sendTime.As(Time::S)
378  << ")");
379  }
380 }
381 
382 void
384 {
385  NS_LOG_DEBUG("Time " << Now().As(Time::S) << " Addr " << GetAddress() << " Transmitting ");
387  m_state = TX;
388  m_phy->SendPacket(m_pktTx, m_pktTxProt);
389  m_pktTx = nullptr;
390  m_sendTime = Seconds(0);
391  m_savedDelayS = Seconds(0);
392 }
393 
394 } // namespace ns3
a polymophic address class
Definition: address.h:100
Callback template class.
Definition: callback.h:443
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:93
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:61
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
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:863
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:568
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:276
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
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:417
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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:47
bool m_txOngoing
Tx is ongoing.
Definition: uan-mac-cw.h:145
Time m_sendTime
Time to send next packet.
Definition: uan-mac-cw.h:135
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet destined for this MAC was received.
Definition: uan-mac-cw.h:123
void NotifyCcaStart() override
Called when UanPhy begins sensing channel is busy.
Definition: uan-mac-cw.cc:233
void Clear() override
Clears all pointer references.
Definition: uan-mac-cw.cc:54
Ptr< Packet > m_pktTx
Next packet to send.
Definition: uan-mac-cw.h:139
void SaveTimer()
Cancel SendEvent and save remaining delay.
Definition: uan-mac-cw.cc:354
TracedCallback< Ptr< const Packet >, uint16_t > m_dequeueLogger
A packet was passed down to the PHY from the MAC.
Definition: uan-mac-cw.h:127
void NotifyRxEndError() override
Called when UanPhy finishes receiving packet in error.
Definition: uan-mac-cw.cc:221
bool m_cleared
Flag when we've been cleared.
Definition: uan-mac-cw.h:150
void EndTx()
End TX state.
Definition: uan-mac-cw.cc:288
void SendPacket()
Send packet on PHY.
Definition: uan-mac-cw.cc:383
void NotifyCcaEnd() override
Called when UanPhy stops sensing channel is busy.
Definition: uan-mac-cw.cc:245
virtual void SetSlotTime(Time duration)
Set the slot time duration.
Definition: uan-mac-cw.cc:318
virtual uint32_t GetCw()
Get the contention window size.
Definition: uan-mac-cw.cc:324
static TypeId GetTypeId()
Register this type.
Definition: uan-mac-cw.cc:79
UanMacCw()
Default constructor.
Definition: uan-mac-cw.cc:37
State m_state
Current state.
Definition: uan-mac-cw.h:147
Ptr< UniformRandomVariable > m_rv
Provides uniform random variable for contention window.
Definition: uan-mac-cw.h:153
bool Enqueue(Ptr< Packet > pkt, uint16_t protocolNumber, const Address &dest) override
Enqueue packet to be transmitted.
Definition: uan-mac-cw.cc:113
void NotifyRxEndOk() override
Called when UanPhy finishes receiving packet without error.
Definition: uan-mac-cw.cc:209
void DoDispose() override
Destructor implementation.
Definition: uan-mac-cw.cc:72
virtual void SetCw(uint32_t cw)
Set the contention window size.
Definition: uan-mac-cw.cc:312
Time m_slotTime
Slot time duration.
Definition: uan-mac-cw.h:131
~UanMacCw() override
Dummy destructor, DoDispose.
Definition: uan-mac-cw.cc:49
void NotifyTxStart(Time duration) override
Called when transmission starts from Phy object.
Definition: uan-mac-cw.cc:257
EventId m_sendEvent
Scheduled SendPacket event.
Definition: uan-mac-cw.h:143
void PhyRxPacketError(Ptr< Packet > packet, double sinr)
Packet received at lower layer in error.
Definition: uan-mac-cw.cc:349
Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > m_forwardUpCb
Forwarding up callback.
Definition: uan-mac-cw.h:119
void NotifyRxStart() override
Called when UanPhy begins receiving packet.
Definition: uan-mac-cw.cc:197
void PhyRxPacketGood(Ptr< Packet > packet, double sinr, UanTxMode mode)
Receive packet from lower layer (passed to PHY as callback).
Definition: uan-mac-cw.cc:336
@ IDLE
Idle state.
Definition: uan-mac-cw.h:112
@ RUNNING
Delay timer running.
Definition: uan-mac-cw.h:114
@ TX
Transmitting.
Definition: uan-mac-cw.h:115
@ CCABUSY
Channel busy.
Definition: uan-mac-cw.h:113
TracedCallback< Ptr< const Packet >, uint16_t > m_enqueueLogger
A packet arrived at the MAC for transmission.
Definition: uan-mac-cw.h:125
void NotifyTxEnd() override
Function called when Phy object finishes transmitting packet.
Definition: uan-mac-cw.cc:272
Time m_savedDelayS
Remaining delay until next send.
Definition: uan-mac-cw.h:137
virtual Time GetSlotTime()
Get the slot time duration.
Definition: uan-mac-cw.cc:330
void StartTimer()
Schedule SendPacket after delay.
Definition: uan-mac-cw.cc:366
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
Definition: uan-mac-cw.h:121
uint32_t m_cw
Contention window size.
Definition: uan-mac-cw.h:130
void AttachPhy(Ptr< UanPhy > phy) override
Attach PHY layer to this MAC.
Definition: uan-mac-cw.cc:188
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:182
uint16_t m_pktTxProt
Next packet protocol number (usage varies by MAC).
Definition: uan-mac-cw.h:141
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:280
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
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:1424
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:46
#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:296
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
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.
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:707
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
phy
Definition: third.py:82
@ IDLE
The PHY layer is IDLE.