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 #include <sstream>
35 
36 NS_LOG_COMPONENT_DEFINE("SatQueue");
37 
38 namespace ns3
39 {
40 
41 NS_OBJECT_ENSURE_REGISTERED(SatQueue);
42 
43 TypeId
45 {
46  static TypeId tid =
47  TypeId("ns3::SatQueue")
48  .SetParent<Object>()
49  .AddConstructor<SatQueue>()
50  .AddAttribute("MaxPackets",
51  "The maximum number of packets accepted by this SatQueue.",
52  UintegerValue(1000),
53  MakeUintegerAccessor(&SatQueue::m_maxPackets),
54  MakeUintegerChecker<uint32_t>())
55  .AddTraceSource("Enqueue",
56  "Enqueue a packet in the queue.",
57  MakeTraceSourceAccessor(&SatQueue::m_traceEnqueue),
58  "ns3::Packet::TracedCallback")
59  .AddTraceSource("Dequeue",
60  "Dequeue a packet from the queue.",
61  MakeTraceSourceAccessor(&SatQueue::m_traceDequeue),
62  "ns3::Packet::TracedCallback")
63  .AddTraceSource("Drop",
64  "Drop a packet stored in the queue.",
65  MakeTraceSourceAccessor(&SatQueue::m_traceDrop),
66  "ns3::Packet::TracedCallback");
67 
68  return tid;
69 }
70 
72  : Object(),
73  m_packets(),
74  m_maxPackets(0),
75  m_flowId(0),
76  m_nBytes(0),
77  m_nTotalReceivedBytes(0),
78  m_nPackets(0),
79  m_nTotalReceivedPackets(0),
80  m_nTotalDroppedBytes(0),
81  m_nTotalDroppedPackets(),
82  m_nEnqueBytesSinceReset(0),
83  m_nDequeBytesSinceReset(0),
84  m_statResetTime(0)
85 {
86  NS_LOG_FUNCTION(this);
87 }
88 
89 SatQueue::SatQueue(uint8_t flowId)
90  : Object(),
91  m_packets(),
92  m_maxPackets(0),
93  m_flowId(flowId),
94  m_nBytes(0),
95  m_nTotalReceivedBytes(0),
96  m_nPackets(0),
97  m_nTotalReceivedPackets(0),
98  m_nTotalDroppedBytes(0),
99  m_nTotalDroppedPackets(),
100  m_nEnqueBytesSinceReset(0),
101  m_nDequeBytesSinceReset(0),
102  m_statResetTime(Seconds(0.0))
103 {
104  NS_LOG_FUNCTION(this);
105 }
106 
108 {
109  NS_LOG_FUNCTION(this);
110 }
111 
112 void
114 {
115  NS_LOG_FUNCTION(this);
116 
117  for (EventCallbackContainer_t::iterator it = m_queueEventCallbacks.begin();
118  it != m_queueEventCallbacks.end();
119  ++it)
120  {
121  (*it).Nullify();
122  }
123 
124  DequeueAll();
125  Object::DoDispose();
126 }
127 
128 void
129 SatQueue::SetFlowId(uint32_t flowId)
130 {
131  NS_LOG_FUNCTION(this << flowId);
132  m_flowId = flowId;
133 }
134 
135 bool
137 {
138  NS_LOG_FUNCTION(this);
139  return m_packets.empty();
140 }
141 
142 bool
143 SatQueue::Enqueue(Ptr<Packet> p)
144 {
145  NS_LOG_FUNCTION(this << p->GetSize());
146 
147  NS_LOG_INFO("Enque " << p->GetSize() << " bytes");
148 
149  if (m_packets.size() >= m_maxPackets)
150  {
151  NS_LOG_INFO("Queue full (at max packets) -- dropping pkt");
152 
153  std::stringstream msg;
154  msg << "SatQueue is full: packet dropped!";
155  msg << " at: " << Now().GetSeconds() << "s";
156  msg << " MaxPackets: " << m_maxPackets;
157  Singleton<SatLog>::Get()->AddToLog(SatLog::LOG_WARNING, "", msg.str());
158 
159  Drop(p);
160  return false;
161  }
162 
163  SatControlMsgTag tag;
164  if (p->PeekPacketTag(tag))
165  {
167  {
168  m_logonCallback(p);
169  return true;
170  }
171  }
172 
173  bool emptyBeforeEnque = m_packets.empty();
174 
175  m_nBytes += p->GetSize();
176  ++m_nPackets;
177 
178  m_nTotalReceivedBytes += p->GetSize();
180 
181  m_nEnqueBytesSinceReset += p->GetSize();
182 
183  m_packets.push_back(p);
184 
185  NS_LOG_INFO("Number packets " << m_packets.size());
186  NS_LOG_INFO("Number bytes " << m_nBytes);
187  m_traceEnqueue(p);
188 
189  if (emptyBeforeEnque == true)
190  {
192  }
193  else
194  {
196  }
197 
198  return true;
199 }
200 
201 Ptr<Packet>
203 {
204  NS_LOG_FUNCTION(this);
205 
206  if (IsEmpty())
207  {
208  NS_LOG_INFO("Queue empty");
209  return 0;
210  }
211 
212  Ptr<Packet> p = m_packets.front();
213  m_packets.pop_front();
214 
215  m_nBytes -= p->GetSize();
216  --m_nPackets;
217 
218  m_nDequeBytesSinceReset += p->GetSize();
219 
220  NS_LOG_INFO("Popped " << p);
221  NS_LOG_INFO("Number packets " << m_packets.size());
222  NS_LOG_INFO("Number bytes " << m_nBytes);
223  m_traceDequeue(p);
224 
225  return p;
226 }
227 
228 Ptr<const Packet>
229 SatQueue::Peek(void) const
230 {
231  NS_LOG_FUNCTION(this);
232 
233  if (IsEmpty())
234  {
235  NS_LOG_INFO("Queue empty");
236  return 0;
237  }
238 
239  Ptr<Packet> p = m_packets.front();
240 
241  NS_LOG_INFO("Number packets " << m_packets.size());
242  NS_LOG_INFO("Number bytes " << m_nBytes);
243 
244  return p;
245 }
246 
247 void
248 SatQueue::PushFront(Ptr<Packet> p)
249 {
250  NS_LOG_FUNCTION(this << p->GetSize());
251 
252  m_packets.push_front(p);
253 
254  ++m_nPackets;
255  m_nBytes += p->GetSize();
256 
257  m_nDequeBytesSinceReset -= p->GetSize();
258 }
259 
260 void
262 {
263  NS_LOG_FUNCTION(this);
264  while (!IsEmpty())
265  {
266  Dequeue();
267  }
268 }
269 
270 void
271 SatQueue::Drop(Ptr<Packet> p)
272 {
273  NS_LOG_FUNCTION(this << p->GetSize());
274 
276  m_nTotalDroppedBytes += p->GetSize();
277 
278  NS_LOG_INFO("m_traceDrop (p)");
279  m_traceDrop(p);
280 }
281 
282 void
284 {
285  NS_LOG_FUNCTION(this << &cb);
286  m_queueEventCallbacks.push_back(cb);
287 }
288 
289 void
291 {
292  NS_LOG_FUNCTION(this << &cb);
293  m_logonCallback = cb;
294 }
295 
296 void
298 {
299  NS_LOG_FUNCTION(this);
300 
301  for (EventCallbackContainer_t::const_iterator it = m_queueEventCallbacks.begin();
302  it != m_queueEventCallbacks.end();
303  ++it)
304  {
305  if (!(*it).IsNull())
306  {
307  (*it)(event, m_flowId);
308  }
309  }
310 }
311 
312 uint32_t
314 {
315  NS_LOG_FUNCTION(this);
316 
317  return m_nPackets;
318 }
319 
320 uint32_t
322 {
323  NS_LOG_FUNCTION(this);
324 
325  return m_nBytes;
326 }
327 
328 uint32_t
330 {
331  NS_LOG_FUNCTION(this);
332 
333  return m_nTotalReceivedBytes;
334 }
335 
336 uint32_t
338 {
339  NS_LOG_FUNCTION(this);
340 
342 }
343 
344 uint32_t
346 {
347  NS_LOG_FUNCTION(this);
348 
349  return m_nTotalDroppedBytes;
350 }
351 
352 uint32_t
354 {
355  NS_LOG_FUNCTION(this);
356 
357  return m_nTotalDroppedPackets;
358 }
359 
362 {
363  NS_LOG_FUNCTION(this << reset);
364 
365  QueueStats_t queueStats;
366  Time duration = Simulator::Now() - m_statResetTime;
367 
368  if (duration.IsStrictlyPositive())
369  {
372  duration.GetSeconds();
375  duration.GetSeconds();
378  queueStats.m_queueSizeBytes = GetNBytes();
379 
380  if (reset)
381  {
383  }
384  }
385  return queueStats;
386 }
387 
388 void
390 {
391  NS_LOG_FUNCTION(this);
392 
393  m_nBytes = 0;
395  m_nPackets = 0;
399 }
400 
401 void
403 {
404  NS_LOG_FUNCTION(this);
405 
408  m_statResetTime = Simulator::Now();
409 }
410 
411 uint32_t
412 SatQueue::GetNumSmallerPackets(uint32_t maxPacketSizeBytes) const
413 {
414  NS_LOG_FUNCTION(this << maxPacketSizeBytes);
415 
416  uint32_t packets(0);
417  for (PacketContainer_t::const_iterator it = m_packets.begin(); it != m_packets.end(); ++it)
418  {
419  if ((*it)->GetSize() <= maxPacketSizeBytes)
420  {
421  ++packets;
422  }
423  else
424  {
425  break;
426  }
427  }
428  return packets;
429 }
430 
431 } // 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:66
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.