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