satellite-queue.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions Ltd.
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: Jani Puttonen <jani.puttonen@magister.fi>
19  */
20 
21 #include "satellite-queue.h"
22 
25 #include "satellite-log.h"
26 #include "satellite-utils.h"
27 
28 #include <ns3/enum.h>
29 #include <ns3/log.h>
30 #include <ns3/simulator.h>
31 #include <ns3/singleton.h>
32 #include <ns3/uinteger.h>
33 
34 NS_LOG_COMPONENT_DEFINE("SatQueue");
35 
36 namespace ns3
37 {
38 
39 NS_OBJECT_ENSURE_REGISTERED(SatQueue);
40 
41 TypeId
43 {
44  static TypeId tid =
45  TypeId("ns3::SatQueue")
46  .SetParent<Object>()
47  .AddConstructor<SatQueue>()
48  .AddAttribute("MaxPackets",
49  "The maximum number of packets accepted by this SatQueue.",
50  UintegerValue(1000),
51  MakeUintegerAccessor(&SatQueue::m_maxPackets),
52  MakeUintegerChecker<uint32_t>())
53  .AddTraceSource("Enqueue",
54  "Enqueue a packet in the queue.",
55  MakeTraceSourceAccessor(&SatQueue::m_traceEnqueue),
56  "ns3::Packet::TracedCallback")
57  .AddTraceSource("Dequeue",
58  "Dequeue a packet from the queue.",
59  MakeTraceSourceAccessor(&SatQueue::m_traceDequeue),
60  "ns3::Packet::TracedCallback")
61  .AddTraceSource("Drop",
62  "Drop a packet stored in the queue.",
63  MakeTraceSourceAccessor(&SatQueue::m_traceDrop),
64  "ns3::Packet::TracedCallback");
65 
66  return tid;
67 }
68 
70  : Object(),
71  m_packets(),
72  m_maxPackets(0),
73  m_flowId(0),
74  m_nBytes(0),
75  m_nTotalReceivedBytes(0),
76  m_nPackets(0),
77  m_nTotalReceivedPackets(0),
78  m_nTotalDroppedBytes(0),
79  m_nTotalDroppedPackets(),
80  m_nEnqueBytesSinceReset(0),
81  m_nDequeBytesSinceReset(0),
82  m_statResetTime(0)
83 {
84  NS_LOG_FUNCTION(this);
85 }
86 
87 SatQueue::SatQueue(uint8_t flowId)
88  : Object(),
89  m_packets(),
90  m_maxPackets(0),
91  m_flowId(flowId),
92  m_nBytes(0),
93  m_nTotalReceivedBytes(0),
94  m_nPackets(0),
95  m_nTotalReceivedPackets(0),
96  m_nTotalDroppedBytes(0),
97  m_nTotalDroppedPackets(),
98  m_nEnqueBytesSinceReset(0),
99  m_nDequeBytesSinceReset(0),
100  m_statResetTime(Seconds(0.0))
101 {
102  NS_LOG_FUNCTION(this);
103 }
104 
106 {
107  NS_LOG_FUNCTION(this);
108 }
109 
110 void
112 {
113  NS_LOG_FUNCTION(this);
114 
115  for (EventCallbackContainer_t::iterator it = m_queueEventCallbacks.begin();
116  it != m_queueEventCallbacks.end();
117  ++it)
118  {
119  (*it).Nullify();
120  }
121 
122  DequeueAll();
123  Object::DoDispose();
124 }
125 
126 void
127 SatQueue::SetFlowId(uint32_t flowId)
128 {
129  NS_LOG_FUNCTION(this << flowId);
130  m_flowId = flowId;
131 }
132 
133 bool
135 {
136  NS_LOG_FUNCTION(this);
137  return m_packets.empty();
138 }
139 
140 bool
141 SatQueue::Enqueue(Ptr<Packet> p)
142 {
143  NS_LOG_FUNCTION(this << p->GetSize());
144 
145  NS_LOG_INFO("Enque " << p->GetSize() << " bytes");
146 
147  if (m_packets.size() >= m_maxPackets)
148  {
149  NS_LOG_INFO("Queue full (at max packets) -- dropping pkt");
150 
151  std::stringstream msg;
152  msg << "SatQueue is full: packet dropped!";
153  msg << " at: " << Now().GetSeconds() << "s";
154  msg << " MaxPackets: " << m_maxPackets;
155  Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
156 
157  Drop(p);
158  return false;
159  }
160 
161  SatControlMsgTag tag;
162  if (p->PeekPacketTag(tag))
163  {
165  {
166  m_logonCallback(p);
167  return true;
168  }
169  }
170 
171  bool emptyBeforeEnque = m_packets.empty();
172 
173  m_nBytes += p->GetSize();
174  ++m_nPackets;
175 
176  m_nTotalReceivedBytes += p->GetSize();
178 
179  m_nEnqueBytesSinceReset += p->GetSize();
180 
181  m_packets.push_back(p);
182 
183  NS_LOG_INFO("Number packets " << m_packets.size());
184  NS_LOG_INFO("Number bytes " << m_nBytes);
185  m_traceEnqueue(p);
186 
187  if (emptyBeforeEnque == true)
188  {
190  }
191  else
192  {
194  }
195 
196  return true;
197 }
198 
199 Ptr<Packet>
201 {
202  NS_LOG_FUNCTION(this);
203 
204  if (IsEmpty())
205  {
206  NS_LOG_INFO("Queue empty");
207  return 0;
208  }
209 
210  Ptr<Packet> p = m_packets.front();
211  m_packets.pop_front();
212 
213  m_nBytes -= p->GetSize();
214  --m_nPackets;
215 
216  m_nDequeBytesSinceReset += p->GetSize();
217 
218  NS_LOG_INFO("Popped " << p);
219  NS_LOG_INFO("Number packets " << m_packets.size());
220  NS_LOG_INFO("Number bytes " << m_nBytes);
221  m_traceDequeue(p);
222 
223  return p;
224 }
225 
226 Ptr<const Packet>
227 SatQueue::Peek(void) const
228 {
229  NS_LOG_FUNCTION(this);
230 
231  if (IsEmpty())
232  {
233  NS_LOG_INFO("Queue empty");
234  return 0;
235  }
236 
237  Ptr<Packet> p = m_packets.front();
238 
239  NS_LOG_INFO("Number packets " << m_packets.size());
240  NS_LOG_INFO("Number bytes " << m_nBytes);
241 
242  return p;
243 }
244 
245 void
246 SatQueue::PushFront(Ptr<Packet> p)
247 {
248  NS_LOG_FUNCTION(this << p->GetSize());
249 
250  m_packets.push_front(p);
251 
252  ++m_nPackets;
253  m_nBytes += p->GetSize();
254 
255  m_nDequeBytesSinceReset -= p->GetSize();
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION(this);
262  while (!IsEmpty())
263  {
264  Dequeue();
265  }
266 }
267 
268 void
269 SatQueue::Drop(Ptr<Packet> p)
270 {
271  NS_LOG_FUNCTION(this << p->GetSize());
272 
274  m_nTotalDroppedBytes += p->GetSize();
275 
276  NS_LOG_INFO("m_traceDrop (p)");
277  m_traceDrop(p);
278 }
279 
280 void
282 {
283  NS_LOG_FUNCTION(this << &cb);
284  m_queueEventCallbacks.push_back(cb);
285 }
286 
287 void
289 {
290  NS_LOG_FUNCTION(this << &cb);
291  m_logonCallback = cb;
292 }
293 
294 void
296 {
297  NS_LOG_FUNCTION(this);
298 
299  for (EventCallbackContainer_t::const_iterator it = m_queueEventCallbacks.begin();
300  it != m_queueEventCallbacks.end();
301  ++it)
302  {
303  if (!(*it).IsNull())
304  {
305  (*it)(event, m_flowId);
306  }
307  }
308 }
309 
310 uint32_t
312 {
313  NS_LOG_FUNCTION(this);
314 
315  return m_nPackets;
316 }
317 
318 uint32_t
320 {
321  NS_LOG_FUNCTION(this);
322 
323  return m_nBytes;
324 }
325 
326 uint32_t
328 {
329  NS_LOG_FUNCTION(this);
330 
331  return m_nTotalReceivedBytes;
332 }
333 
334 uint32_t
336 {
337  NS_LOG_FUNCTION(this);
338 
340 }
341 
342 uint32_t
344 {
345  NS_LOG_FUNCTION(this);
346 
347  return m_nTotalDroppedBytes;
348 }
349 
350 uint32_t
352 {
353  NS_LOG_FUNCTION(this);
354 
355  return m_nTotalDroppedPackets;
356 }
357 
360 {
361  NS_LOG_FUNCTION(this << reset);
362 
363  QueueStats_t queueStats;
364  Time duration = Simulator::Now() - m_statResetTime;
365 
366  if (duration.IsStrictlyPositive())
367  {
370  duration.GetSeconds();
373  duration.GetSeconds();
376  queueStats.m_queueSizeBytes = GetNBytes();
377 
378  if (reset)
379  {
381  }
382  }
383  return queueStats;
384 }
385 
386 void
388 {
389  NS_LOG_FUNCTION(this);
390 
391  m_nBytes = 0;
393  m_nPackets = 0;
397 }
398 
399 void
401 {
402  NS_LOG_FUNCTION(this);
403 
406  m_statResetTime = Simulator::Now();
407 }
408 
409 uint32_t
410 SatQueue::GetNumSmallerPackets(uint32_t maxPacketSizeBytes) const
411 {
412  NS_LOG_FUNCTION(this << maxPacketSizeBytes);
413 
414  uint32_t packets(0);
415  for (PacketContainer_t::const_iterator it = m_packets.begin(); it != m_packets.end(); ++it)
416  {
417  if ((*it)->GetSize() <= maxPacketSizeBytes)
418  {
419  ++packets;
420  }
421  else
422  {
423  break;
424  }
425  }
426  return packets;
427 }
428 
429 } // namespace ns3
This class implements a tag that is used to identify control messages (packages).
@ SAT_LOGON_CTRL_MSG
SAT_LOGON_CTRL_MSG.
SatControlMsgType_t GetMsgType(void) const
Get type of the control message.
@ LOG_WARNING
LOG_WARNING.
Definition: satellite-log.h:64
uint32_t m_nTotalReceivedPackets
~SatQueue()
Destructor for SatQueue.
static TypeId GetTypeId(void)
Get the type ID.
virtual void DoDispose()
Dispose of this class instance.
virtual Ptr< const Packet > Peek(void) const
Get a copy of the item at the front of the queue without removing it.
virtual bool IsEmpty(void) const
Is the queue empty.
PacketContainer_t m_packets
Packet container.
void SetFlowId(uint32_t flowId)
Configured flow index for this queue.
void ResetShortTermStatistics()
Reset the short term statistics.
uint32_t m_nEnqueBytesSinceReset
EventCallbackContainer_t m_queueEventCallbacks
Container of callbacks for queue related events.
virtual void PushFront(Ptr< Packet > p)
PushFront pushes a fragmented packet back to the front of the packet container.
Callback< void, SatQueue::QueueEvent_t, uint8_t > QueueEventCallback
Callback to indicate queue related event.
uint32_t GetTotalReceivedBytes(void) const
Get total number of bytes received by this queue since the simulation began, or since ResetStatistics...
void Drop(Ptr< Packet > packet)
Drop a packet.
Callback< void, Ptr< Packet > > LogonCallback
logon msg sending callback
void DequeueAll(void)
Flush the queue.
uint32_t m_nTotalReceivedBytes
void AddLogonCallback(SatQueue::LogonCallback cb)
Add queue event callback.
virtual bool Enqueue(Ptr< Packet > p)
Enque pushes packet to the packet container (back)
LogonCallback m_logonCallback
Callback to send control messages.
TracedCallback< Ptr< const Packet > > m_traceDrop
uint8_t m_flowId
An unique id for each queue.
uint32_t GetNumSmallerPackets(uint32_t maxPacketSizeBytes) const
Method checks how many packets are smaller or equal in size than the maximum packets size threshold s...
uint32_t GetTotalDroppedBytes(void) const
Get total number of bytes dropped by this Queue since the simulation began, or since ResetStatistics ...
TracedCallback< Ptr< const Packet > > m_traceEnqueue
uint32_t GetNPackets(void) const
Get number of packets currently stored in the queue.
uint32_t m_nTotalDroppedPackets
uint32_t m_nPackets
uint32_t m_nTotalDroppedBytes
void SendEvent(SatQueue::QueueEvent_t event)
Send queue event to all registered callbacks.
virtual Ptr< Packet > Dequeue(void)
Deque takes packet from the packet container (front)
uint32_t m_nDequeBytesSinceReset
void ResetStatistics(void)
Resets the counts for dropped packets, dropped bytes, received packets, and received bytes.
void AddQueueEventCallback(SatQueue::QueueEventCallback cb)
Add queue event callback.
TracedCallback< Ptr< const Packet > > m_traceDequeue
uint32_t GetTotalReceivedPackets(void) const
Get total number of packets received by this Queue since the simulation began, or since ResetStatisti...
uint32_t GetTotalDroppedPackets(void) const
Get total number of bytes dropped by this Queue since the simulation began, or since ResetStatistics ...
uint32_t m_maxPackets
Maximum allowed packets within the packet container.
uint32_t GetNBytes(void) const
Get number of bytes currently stored in the queue.
SatQueue()
Default constructor.
QueueStats_t GetQueueStatistics(bool reset)
GetQueueStatistics returns a struct of KPIs.
constexpr uint32_t BITS_IN_KBIT
Number of bits consisting a kilobit.
constexpr uint32_t BITS_PER_BYTE
Number of bits in a byte.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
QueueStats_t definition for passing queue related statistics to any interested modules.