satellite-generic-stream-encapsulator-arq.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 
22 
24 #include "satellite-arq-header.h"
26 #include "satellite-llc.h"
27 #include "satellite-mac-tag.h"
28 #include "satellite-queue.h"
29 
30 #include <ns3/log.h>
31 #include <ns3/mac48-address.h>
32 #include <ns3/simulator.h>
33 
34 #include <algorithm>
35 
36 NS_LOG_COMPONENT_DEFINE("SatGenericStreamEncapsulatorArq");
37 
38 namespace ns3
39 {
40 
41 NS_OBJECT_ENSURE_REGISTERED(SatGenericStreamEncapsulatorArq);
42 
44  : m_seqNo(),
45  m_txedBuffer(),
46  m_retxBuffer(),
47  m_retxBufferSize(0),
48  m_txedBufferSize(0),
49  m_maxNoOfRetransmissions(2),
50  m_retransmissionTimer(Seconds(0.6)),
51  m_arqWindowSize(10),
52  m_arqHeaderSize(1),
53  m_nextExpectedSeqNo(0)
54 {
55  NS_LOG_FUNCTION(this);
56  NS_ASSERT(false);
57 
61 }
62 
64  Mac48Address decapAddress,
65  Mac48Address sourceE2EAddress,
66  Mac48Address destE2EAddress,
67  uint8_t flowId,
68  uint32_t additionalHeaderSize)
69  : SatGenericStreamEncapsulator(encapAddress,
70  decapAddress,
71  sourceE2EAddress,
72  destE2EAddress,
73  flowId,
74  additionalHeaderSize),
75  m_seqNo(),
76  m_txedBuffer(),
77  m_retxBuffer(),
78  m_retxBufferSize(0),
79  m_txedBufferSize(0),
80  m_maxNoOfRetransmissions(2),
81  m_retransmissionTimer(Seconds(0.6)),
82  m_arqWindowSize(10),
83  m_arqHeaderSize(1),
84  m_nextExpectedSeqNo(0)
85 {
86  NS_LOG_FUNCTION(this);
87 
88  ObjectBase::ConstructSelf(AttributeConstructionList());
89 
90  // ARQ sequence number generator
91  m_seqNo = Create<SatArqSequenceNumber>(m_arqWindowSize);
92 }
93 
95 {
96  NS_LOG_FUNCTION(this);
97  m_seqNo = 0;
98 }
99 
100 TypeId
102 {
103  static TypeId tid =
104  TypeId("ns3::SatGenericStreamEncapsulatorArq")
105  .SetParent<SatGenericStreamEncapsulator>()
106  .AddConstructor<SatGenericStreamEncapsulatorArq>()
107  .AddAttribute(
108  "MaxNoOfRetransmissions",
109  "Maximum number of retransmissions for a single GSE PDU.",
110  UintegerValue(2),
112  MakeUintegerChecker<uint32_t>())
113  .AddAttribute(
114  "RetransmissionTimer",
115  "Retransmission time value, i.e. how long to wait for ACK before retransmission.",
116  TimeValue(Seconds(0.6)),
118  MakeTimeChecker())
119  .AddAttribute(
120  "WindowSize",
121  "Window size for ARQ, i.e. how many simultaneous packets are allowed in the air.",
122  UintegerValue(10),
124  MakeUintegerChecker<uint32_t>())
125  .AddAttribute("ArqHeaderSize",
126  "ARQ header size in Bytes.",
127  UintegerValue(1),
129  MakeUintegerChecker<uint32_t>())
130  .AddAttribute("RxWaitingTime",
131  "Time to wait for a packet at the reception (GW) before moving onwards "
132  "with the packet reception.",
133  TimeValue(Seconds(1.8)),
135  MakeTimeChecker());
136  return tid;
137 }
138 
139 TypeId
141 {
142  return GetTypeId();
143 }
144 
145 void
147 {
148  NS_LOG_FUNCTION(this);
149  m_seqNo = 0;
150 
151  // Clean-up the Tx'ed buffer
152  std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it = m_txedBuffer.begin();
153  while (it != m_txedBuffer.end())
154  {
155  it->second->DoDispose();
156  it->second = 0;
157  ++it;
158  }
159  m_txedBuffer.clear();
160 
161  // Clean-up the reTx buffer
162  it = m_retxBuffer.begin();
163  while (it != m_retxBuffer.end())
164  {
165  it->second->DoDispose();
166  it->second = 0;
167  ++it;
168  }
169  m_retxBuffer.clear();
170 
171  // Clean-up the reordering buffer
172  std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 = m_reorderingBuffer.begin();
173  while (it2 != m_reorderingBuffer.end())
174  {
175  it2->second->DoDispose();
176  it2->second = 0;
177  ++it2;
178  }
179  m_reorderingBuffer.clear();
180 
182 }
183 
184 Ptr<Packet>
186  uint32_t& bytesLeft,
187  uint32_t& nextMinTxO)
188 {
189  NS_LOG_FUNCTION(this << bytes);
190  NS_LOG_INFO("TxOpportunity for UT: " << m_decapAddress << " flowId: " << (uint32_t)m_flowId
191  << " of " << bytes << " bytes");
192 
193  // Payload adapted PDU = NULL
194  Ptr<Packet> packet;
195 
201  if (!m_retxBuffer.empty())
202  {
203  // Oldest seqNo sent first
204  Ptr<SatArqBufferContext> context = m_retxBuffer.begin()->second;
205 
206  // If the packet fits into the transmission opportunity
207  if (context->m_pdu->GetSize() <= bytes)
208  {
209  // Pop the front
210  m_retxBuffer.erase(m_retxBuffer.begin());
211 
212  // Increase the retransmission counter
213  context->m_retransmissionCount = context->m_retransmissionCount + 1;
214 
215  m_retxBufferSize -= context->m_pdu->GetSize();
216  m_txedBufferSize += context->m_pdu->GetSize();
217 
218  std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
219  m_txedBuffer.find(context->m_seqNo);
220  if (it != m_txedBuffer.end())
221  {
222  NS_FATAL_ERROR("Trying to add retransmission packet to txedBuffer even though it "
223  "already exists there!");
224  }
225 
226  // Store it back to the transmitted packet container.
227  m_txedBuffer.insert(std::make_pair(context->m_seqNo, context));
228 
229  // Create the retransmission event and store it to the context. Event is cancelled if a
230  // ACK is received. However, if the event triggers, we shall send the packet again, if
231  // the packet still has retransmissions left.
232  EventId t = Simulator::Schedule(m_retransmissionTimer,
234  this,
235  context->m_seqNo);
236  context->m_waitingTimer = t;
237 
238  NS_LOG_INFO("GW: << " << m_encapAddress << " sent a retransmission packet of size: "
239  << context->m_pdu->GetSize()
240  << " with seqNo: " << (uint32_t)(context->m_seqNo)
241  << " flowId: " << (uint32_t)(m_flowId));
242 
243  Ptr<Packet> copy = context->m_pdu->Copy();
244  return copy;
245  }
246  else
247  {
248  NS_LOG_INFO("Retransmission PDU: " << context->m_pdu->GetUid()
249  << " size: " << context->m_pdu->GetSize()
250  << " does not fit into TxO: " << bytes);
251  }
252  }
253 
254  // Check the transmission buffer. Sequence number needs to be
255  // available for any new transmissions.
256  else if (!m_txQueue->IsEmpty() && m_seqNo->SeqNoAvailable())
257  {
258  // Crate new GSE PDU
259  packet = GetNewGsePdu(bytes, bytes, m_arqHeaderSize);
260 
261  if (packet)
262  {
263  // Add MAC tag to identify the packet in lower layers
264  SatMacTag mTag;
267  packet->AddPacketTag(mTag);
268 
269  // Add E2E address tag to identify the packet in lower layers
270  SatAddressE2ETag addressE2ETag;
271  if (!packet->PeekPacketTag(addressE2ETag))
272  {
273  addressE2ETag.SetE2EDestAddress(m_destE2EAddress);
275  packet->AddPacketTag(addressE2ETag);
276  }
277 
278  // Add flow id tag
279  SatFlowIdTag flowIdTag;
280  flowIdTag.SetFlowId(m_flowId);
281  packet->AddPacketTag(flowIdTag);
282 
283  // Get next available sequence number
284  uint8_t seqNo = m_seqNo->NextSequenceNumber();
285 
286  // Add ARQ header
287  SatArqHeader arqHeader;
288  arqHeader.SetSeqNo(seqNo);
289  packet->AddHeader(arqHeader);
290 
291  // Create ARQ context and store it to Tx'ed buffer
292  Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
293  arqContext->m_retransmissionCount = 0;
294  Ptr<Packet> copy = packet->Copy();
295  arqContext->m_pdu = copy;
296  arqContext->m_seqNo = seqNo;
297 
298  // Create the retransmission event and store it to the context. Event is cancelled if a
299  // ACK is received. However, if the event triggers, we shall send the packet again, if
300  // the packet still has retransmissions left.
301  arqContext->m_waitingTimer =
302  Simulator::Schedule(m_retransmissionTimer,
304  this,
305  seqNo);
306 
307  // Update the buffer status
308  m_txedBufferSize += packet->GetSize();
309  m_txedBuffer.insert(std::make_pair(seqNo, arqContext));
310 
311  if (packet->GetSize() > bytes)
312  {
313  NS_FATAL_ERROR("Created packet of size: " << packet->GetSize()
314  << " is larger than the tx opportunity: "
315  << bytes);
316  }
317 
318  NS_LOG_INFO("GW: << " << m_encapAddress << " sent a packet of size: "
319  << packet->GetSize() << " with seqNo: " << (uint32_t)(seqNo)
320  << " flowId: " << (uint32_t)(m_flowId));
321  NS_LOG_INFO("Queue size after TxOpportunity: " << m_txQueue->GetNBytes());
322  }
323  }
324  else if (!m_seqNo->SeqNoAvailable())
325  {
326  bytesLeft = 0;
327  return packet;
328  }
329 
330  // Update bytes lefts
331  bytesLeft = GetTxBufferSizeInBytes();
332 
333  // Update min TxO
334  nextMinTxO = GetMinTxOpportunityInBytes();
335 
336  return packet;
337 }
338 
339 void
341 {
342  NS_LOG_FUNCTION(this << (uint32_t)seqNo);
343 
344  NS_LOG_INFO("At GW: " << m_encapAddress
345  << " ARQ retransmission timer expired for: " << (uint32_t)(seqNo));
346 
347  std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it = m_txedBuffer.find(seqNo);
348 
349  if (it != m_txedBuffer.end())
350  {
351  NS_ASSERT(seqNo == it->second->m_seqNo);
352  NS_ASSERT(it->second->m_pdu);
353 
354  // Retransmission still possible
355  if (it->second->m_retransmissionCount < m_maxNoOfRetransmissions)
356  {
357  NS_LOG_INFO("Moving the ARQ context to retransmission buffer");
358 
359  Ptr<SatArqBufferContext> context = it->second;
360 
361  m_txedBuffer.erase(it);
362  m_retxBufferSize += context->m_pdu->GetSize();
363 
364  // Push to the retransmission buffer
365  m_retxBuffer.insert(std::make_pair(seqNo, context));
366  }
367  // Maximum retransmissions reached
368  else
369  {
370  NS_LOG_INFO("For GW: " << m_encapAddress << " max retransmissions reached for "
371  << (uint32_t)(seqNo));
372 
373  // Do clean-up
374  CleanUp(seqNo);
375  }
376  }
377  else
378  {
379  NS_LOG_INFO("Element not found anymore in the m_txedBuffer, thus ACK has been received "
380  "already earlier");
381  }
382 }
383 
384 void
386 {
387  NS_LOG_FUNCTION(this << (uint32_t)sequenceNumber);
388 
389  // Release sequence number
390  m_seqNo->Release(sequenceNumber);
391 
392  // Clean-up the Tx'ed buffer
393  std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it = m_txedBuffer.find(sequenceNumber);
394  if (it != m_txedBuffer.end())
395  {
396  NS_LOG_INFO("Sequence no: " << (uint32_t)sequenceNumber << " clean up from txedBuffer!");
397  m_txedBufferSize -= it->second->m_pdu->GetSize();
398  it->second->DoDispose();
399  it->second = 0;
400  m_txedBuffer.erase(it);
401  }
402 
403  // Clean-up the reTx buffer
404  it = m_retxBuffer.find(sequenceNumber);
405  if (it != m_retxBuffer.end())
406  {
407  NS_LOG_INFO("Sequence no: " << (uint32_t)sequenceNumber << " clean up from retxBuffer!");
408  m_retxBufferSize -= it->second->m_pdu->GetSize();
409  it->second->DoDispose();
410  it->second = 0;
411  m_retxBuffer.erase(it);
412  }
413 }
414 
415 void
417 {
418  NS_LOG_FUNCTION(this);
419 
425  NS_LOG_INFO("GW: " << m_encapAddress
426  << " received ACK with SN: " << (uint32_t)(ack->GetSequenceNumber()));
427 
428  // Do clean-up
429  CleanUp(ack->GetSequenceNumber());
430 }
431 
432 void
434 {
435  NS_LOG_FUNCTION(this << p->GetSize());
436 
437  // Remove encap PDU status tag
438  SatEncapPduStatusTag statusTag;
439  p->RemovePacketTag(statusTag);
440 
441  // Remove flow id tag
442  SatFlowIdTag flowIdTag;
443  p->RemovePacketTag(flowIdTag);
444 
445  // Sanity check
446  SatMacTag mTag;
447  bool mSuccess = p->RemovePacketTag(mTag);
448  if (!mSuccess)
449  {
450  NS_FATAL_ERROR("MAC tag not found in the packet!");
451  }
452  else if (mTag.GetDestAddress() != m_decapAddress)
453  {
454  NS_FATAL_ERROR("Packet was not intended for this receiver!");
455  }
456 
457  SatArqHeader arqHeader;
458  p->RemoveHeader(arqHeader);
459  uint8_t seqNo = arqHeader.GetSeqNo();
460 
461  NS_LOG_INFO("GW: " << m_encapAddress << " received a packet with SeqNo: " << (uint32_t)(seqNo));
462 
463  // Send ACK for the received GSE packet.
464  SendAck(seqNo);
465 
466  // Convert the 8-bit sequence number to continuous 32-bit sequence number
467  uint32_t sn = ConvertSeqNo(seqNo);
468 
469  NS_LOG_INFO("8bit SN: " << (uint32_t)(seqNo) << " 32bit SN: " << sn);
470 
471  // If the received SN is valid. If we receive a SN from the past
472  // nothing is needed to be done.
473  if (sn >= m_nextExpectedSeqNo)
474  {
475  std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it = m_reorderingBuffer.find(sn);
476 
477  // If the context is not found, then we create a new one.
478  if (it == m_reorderingBuffer.end())
479  {
480  NS_LOG_INFO("GW: " << m_encapAddress
481  << " created a new ARQ buffer entry for SeqNo: " << sn);
482  Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
483  arqContext->m_pdu = p;
484  arqContext->m_rxStatus = true;
485  arqContext->m_seqNo = sn;
486  arqContext->m_retransmissionCount = 0;
487  m_reorderingBuffer.insert(std::make_pair(sn, arqContext));
488  }
489  // If the context is found, update it.
490  else
491  {
492  NS_LOG_INFO("GW: " << m_encapAddress
493  << " reset an existing ARQ entry for SeqNo: " << sn);
494  it->second->m_waitingTimer.Cancel();
495  it->second->m_pdu = p;
496  it->second->m_rxStatus = true;
497  }
498 
499  NS_LOG_INFO("Received a packet with SeqNo: " << sn
500  << ", expecting: " << m_nextExpectedSeqNo);
501 
502  // If this is not the SN we expect
503  if (sn != m_nextExpectedSeqNo)
504  {
505  // Add context
506  for (uint32_t i = m_nextExpectedSeqNo; i < sn; ++i)
507  {
508  std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
509  m_reorderingBuffer.find(i);
510 
511  NS_LOG_INFO("Finding context for " << i);
512 
513  // If context not found
514  if (it2 == m_reorderingBuffer.end())
515  {
516  NS_LOG_INFO("Context NOT found for SeqNo: " << i);
517 
518  Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
519  arqContext->m_pdu = NULL;
520  arqContext->m_rxStatus = false;
521  arqContext->m_seqNo = i;
522  arqContext->m_retransmissionCount = 0;
523  m_reorderingBuffer.insert(std::make_pair(i, arqContext));
524  EventId id =
525  Simulator::Schedule(m_rxWaitingTimer,
527  this,
528  i);
529  arqContext->m_waitingTimer = id;
530  }
531  }
532  }
533  // An expected sequence number received, reassemble and receive.
534  else
535  {
537  }
538  }
539  else
540  {
541  NS_LOG_INFO("GW: " << m_encapAddress << " received a packet with SeqNo: " << sn
542  << " which is already received!");
543  }
544 }
545 
546 uint32_t
548 {
549  NS_LOG_FUNCTION(this << (uint32_t)seqNo);
550 
551  uint32_t globalSeqNo(0);
552 
553  // Calculate the rounds and current seq no from m_nextExpectedSeqNo
554  uint32_t rounds = (m_nextExpectedSeqNo / std::numeric_limits<uint8_t>::max());
555  uint32_t rawSeqNo = m_nextExpectedSeqNo % std::numeric_limits<uint8_t>::max();
556 
557  NS_LOG_INFO("Input: " << (uint32_t)(seqNo) << " rounds: " << rounds << " rawSeqNo: " << rawSeqNo
558  << " windowSize: " << m_arqWindowSize
559  << " next expected: " << m_nextExpectedSeqNo);
560 
561  // Received sequence number is higher than the expected one.
562  if (seqNo >= rawSeqNo)
563  {
564  // If seqNo is from previous round
565  if ((seqNo - rawSeqNo) > 2 * m_arqWindowSize)
566  {
567  rounds--;
568  }
569  }
570  // seqNo < rawSeqNo
571  else
572  {
573  if ((rawSeqNo - seqNo) > 2 * m_arqWindowSize)
574  {
575  rounds++;
576  }
577  }
578 
579  globalSeqNo = rounds * std::numeric_limits<uint8_t>::max() + seqNo;
580 
581  return globalSeqNo;
582 }
583 
584 void
586 {
587  NS_LOG_FUNCTION(this);
588 
589  // Start from the expected sequence number iterator
590  std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it = m_reorderingBuffer.begin();
591 
592  NS_LOG_INFO("Process SeqNo: " << it->first << ", expected: " << m_nextExpectedSeqNo
593  << ", status: " << it->second->m_rxStatus);
594 
599  while (it != m_reorderingBuffer.end() && it->first == m_nextExpectedSeqNo &&
600  it->second->m_rxStatus == true)
601  {
602  NS_LOG_INFO("Process SeqNo: " << it->first << ", expected: " << m_nextExpectedSeqNo
603  << ", status: " << it->second->m_rxStatus);
604 
605  // If PDU == NULL, it means that the RxWaitingTimer has expired
606  // without PDU being received
607  if (it->second->m_pdu)
608  {
609  // Process the PDU
610  ProcessPdu(it->second->m_pdu);
611  }
612 
613  it->second->DoDispose();
614  it->second = 0;
615  m_reorderingBuffer.erase(it);
616  it = m_reorderingBuffer.begin();
617 
618  // Increase the seq no
620 
621  NS_LOG_INFO("Increasing SeqNo to " << m_nextExpectedSeqNo);
622  }
623 }
624 
625 void
627 {
628  NS_LOG_FUNCTION(this << (uint32_t)seqNo);
629 
630  NS_LOG_INFO("For GW: " << m_encapAddress << " max waiting time reached for SeqNo: " << seqNo);
631  NS_LOG_INFO("Mark the PDU received and move forward!");
632 
633  // Find waiting timer, erase it and mark the packet received.
634  std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it = m_reorderingBuffer.find(seqNo);
635  if (it != m_reorderingBuffer.end())
636  {
637  it->second->m_waitingTimer.Cancel();
638  it->second->m_rxStatus = true;
639  }
640  else
641  {
642  NS_FATAL_ERROR("Rx waiting timer is not running anymore even though it expired!");
643  }
644 
646 }
647 
648 uint32_t
650 {
651  NS_LOG_FUNCTION(this);
652 
653  return m_txQueue->GetNBytes() + m_retxBufferSize;
654 }
655 
656 void
658 {
659  NS_LOG_FUNCTION(this << (uint32_t)seqNo);
660 
661  NS_LOG_INFO("GW: " << m_decapAddress << " send ACK to GW: " << m_encapAddress
662  << " with flowId: " << (uint32_t)(m_flowId)
663  << " with SN: " << (uint32_t)(seqNo));
664 
671  if (!m_ctrlCallback.IsNull())
672  {
673  Ptr<SatArqAckMessage> ack = Create<SatArqAckMessage>();
674  ack->SetSequenceNumber(seqNo);
675  ack->SetFlowId(m_flowId);
676 
677  // Source address (GW) is used here, since the in FWD link the UT is
678  // sending the ACK to the GW.
680  }
681  else
682  {
683  NS_FATAL_ERROR("Unable to send ACK, since the Ctrl callback is NULL!");
684  }
685 }
686 
687 } // namespace ns3
This class implements a tag that carries the satellite MAC of GW and UT.
void SetE2ESourceAddress(Mac48Address e2eSourceAddress)
Set E2E source MAC address.
void SetE2EDestAddress(Mac48Address e2eDestAddress)
Set E2E destination MAC address.
ARQ header implementation contains the sequence number related to the packet in question.
uint8_t GetSeqNo() const
Get sequence number.
void SetSeqNo(uint8_t seqNo)
Set sequence number.
Mac48Address m_encapAddress
Source and destination mac addresses.
Ptr< SatQueue > m_txQueue
Used queue in satellite encapsulator.
SendCtrlCallback m_ctrlCallback
Callback to send control messages.
SatEncapPduStatusTag is used temporarily to tag packets with the fragmentation status in the encapsul...
SatFlowIdTag implements a tag which carries the flow identifier of a packet.
void SetFlowId(uint8_t flowId)
Set flow id.
void ArqReTxTimerExpired(uint8_t seqNo)
ARQ Tx timer has expired.
Time m_rxWaitingTimer
Waiting time for waiting a certain SN to be received.
uint32_t m_maxNoOfRetransmissions
Maximum number of retransmissions.
virtual void ReceivePdu(Ptr< Packet > p)
Receive a packet, thus decapsulate and defragment/deconcatenate if needed.
uint32_t m_nextExpectedSeqNo
Next expected sequence number at the packet reception.
virtual void ReceiveAck(Ptr< SatArqAckMessage > ack)
Receive a control message (ARQ ACK)
virtual ~SatGenericStreamEncapsulatorArq()
Destructor for SatGenericStreamEncapsulatorArq.
void RxWaitingTimerExpired(uint32_t sn)
Rx waiting timer for a PDU has expired.
std::map< uint32_t, Ptr< SatArqBufferContext > > m_reorderingBuffer
key = sequence number value = GSE packet
std::map< uint8_t, Ptr< SatArqBufferContext > > m_txedBuffer
Transmitted and retransmission context buffer.
void ReassembleAndReceive()
Reassemble and receive the received PDUs if possible.
void CleanUp(uint8_t sequenceNumber)
Clean-up a certain sequence number.
uint32_t ConvertSeqNo(uint8_t seqNo) const
Convert the 8-bit sequence number value from ARQ header into 32-bit continuous sequence number stream...
void SendAck(uint8_t seqNo) const
Send ACK for a given sequence number.
virtual void DoDispose()
Dispose of this class instance.
virtual uint32_t GetTxBufferSizeInBytes() const
Get the buffered packets for this encapsulator.
std::map< uint8_t, Ptr< SatArqBufferContext > > m_retxBuffer
Ptr< SatArqSequenceNumber > m_seqNo
Sequence number handler.
virtual Ptr< Packet > NotifyTxOpportunity(uint32_t bytes, uint32_t &bytesLeft, uint32_t &nextMinTxO)
Notify a Tx opportunity to this encapsulator.
SatGenericStreamEncapsulator class is used in the FWD link for GSE encapsulation and fragmentation of...
virtual void DoDispose()
Dispose of this class instance.
Ptr< Packet > GetNewGsePdu(uint32_t txOpportunityBytes, uint32_t maxGsePduSize, uint32_t additionalHeaderSize=0)
Get new packet performs the GSE fragmentation and encapsulation for a one single packet.
virtual void ProcessPdu(Ptr< Packet > p)
Process the reception of individual GSE PDUs.
virtual uint32_t GetMinTxOpportunityInBytes() const
Get minimum Tx opportunity in bytes, which takes the assumed header sizes into account.
This class implements a tag that carries the satellite MAC specific information, such as source and d...
void SetDestAddress(Mac48Address dest)
Set destination MAC address.
Mac48Address GetDestAddress(void) const
Get destination MAC address.
void SetSourceAddress(Mac48Address source)
Set source MAC address.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.