32#include "ns3/mac48-address.h"
33#include "ns3/simulator.h"
40NS_LOG_COMPONENT_DEFINE(
"SatReturnLinkEncapsulatorArq");
60 NS_LOG_FUNCTION(
this);
69 Mac48Address decapAddress,
70 Mac48Address sourceE2EAddress,
71 Mac48Address destE2EAddress,
73 uint32_t additionalHeaderSize)
79 additionalHeaderSize),
92 NS_LOG_FUNCTION(
this << encapAddress << decapAddress << sourceE2EAddress << destE2EAddress
93 << flowId << additionalHeaderSize);
99 NS_LOG_FUNCTION(
this);
101 SatReturnLinkEncapsulator::NotifyConstructionCompleted();
108 NS_LOG_FUNCTION(
this);
115 TypeId(
"ns3::SatReturnLinkEncapsulatorArq")
117 .AddConstructor<SatReturnLinkEncapsulatorArq>()
119 "MaxRtnArqSegmentSize",
120 "Maximum return link ARQ segment size in Bytes.",
123 MakeUintegerChecker<uint32_t>())
125 "MaxNoOfRetransmissions",
126 "Maximum number of retransmissions for a single RLE PDU.",
129 MakeUintegerChecker<uint32_t>())
131 "RetransmissionTimer",
132 "Retransmission time value, i.e. how long to wait for ACK before retransmission.",
133 TimeValue(Seconds(0.6)),
138 "Window size for ARQ, i.e. how many simultaneous packets are allowed in the air.",
141 MakeUintegerChecker<uint32_t>())
142 .AddAttribute(
"ArqHeaderSize",
143 "ARQ header size in Bytes.",
146 MakeUintegerChecker<uint32_t>())
147 .AddAttribute(
"RxWaitingTime",
148 "Time to wait for a packet at the reception (GW) before moving onwards "
149 "with the packet reception.",
150 TimeValue(Seconds(1.8)),
159 NS_LOG_FUNCTION(
this);
163 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.begin();
166 it->second->DoDispose();
176 it->second->DoDispose();
183 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
m_reorderingBuffer.begin();
186 it2->second->DoDispose();
198 uint32_t& nextMinTxO)
200 NS_LOG_FUNCTION(
this << bytes);
202 <<
" of " << bytes <<
" bytes");
215 Ptr<SatArqBufferContext> context =
m_retxBuffer.begin()->second;
218 if (context->m_pdu->GetSize() <= bytes)
224 context->m_retransmissionCount = context->m_retransmissionCount + 1;
230 m_txedBuffer.insert(std::make_pair(context->m_seqNo, context));
239 context->m_waitingTimer = t;
241 NS_LOG_INFO(
"UT: << " <<
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));
246 Ptr<Packet> copy = context->m_pdu->Copy();
251 NS_LOG_INFO(
"Retransmission PDU: " << context->m_pdu->GetUid()
252 <<
" size: " << context->m_pdu->GetSize()
253 <<
" does not fit into TxO: " << bytes);
268 if (!packet->PeekPacketTag(mTag))
272 packet->AddPacketTag(mTag);
277 if (!packet->PeekPacketTag(addressE2ETag))
281 packet->AddPacketTag(addressE2ETag);
287 packet->AddPacketTag(flowIdTag);
290 uint8_t seqNo =
m_seqNo->NextSequenceNumber();
295 packet->AddHeader(arqHeader);
298 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
299 arqContext->m_retransmissionCount = 0;
300 Ptr<Packet> copy = packet->Copy();
301 arqContext->m_pdu = copy;
302 arqContext->m_seqNo = seqNo;
307 arqContext->m_waitingTimer =
317 if (packet->GetSize() > bytes)
319 NS_FATAL_ERROR(
"Created packet of size: " << packet->GetSize()
320 <<
" is larger than the tx opportunity: "
324 NS_LOG_INFO(
"UT: << " <<
m_encapAddress <<
" sent a packet of size: "
325 << packet->GetSize() <<
" with seqNo: " << (uint32_t)(seqNo)
326 <<
" flowId: " << (uint32_t)(
m_flowId));
327 NS_LOG_INFO(
"Queue size after TxOpportunity: " <<
m_txQueue->GetNBytes());
330 else if (!
m_seqNo->SeqNoAvailable())
348 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
351 <<
" ARQ retransmission timer expired for: " << (uint32_t)(seqNo));
353 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(seqNo);
357 NS_ASSERT(seqNo == it->second->m_seqNo);
358 NS_ASSERT(it->second->m_pdu);
363 NS_LOG_INFO(
"Moving the ARQ context to retransmission buffer");
365 Ptr<SatArqBufferContext> context = it->second;
376 NS_LOG_INFO(
"For UT: " <<
m_encapAddress <<
" max retransmissions reached for "
377 << (uint32_t)(seqNo));
385 NS_LOG_INFO(
"Element not found anymore in the m_txedBuffer, thus ACK has been received "
393 NS_LOG_FUNCTION(
this << (uint32_t)sequenceNumber);
396 m_seqNo->Release(sequenceNumber);
399 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(sequenceNumber);
402 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from txedBuffer!");
404 it->second->DoDispose();
413 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from retxBuffer!");
415 it->second->DoDispose();
424 NS_LOG_FUNCTION(
this);
432 <<
" received ACK with SN: " << (uint32_t)(ack->GetSequenceNumber()));
435 CleanUp(ack->GetSequenceNumber());
441 NS_LOG_FUNCTION(
this << p->GetSize());
445 p->RemovePacketTag(statusTag);
449 p->RemovePacketTag(flowIdTag);
453 bool mSuccess = p->RemovePacketTag(mTag);
456 NS_FATAL_ERROR(
"MAC tag not found in the packet!");
460 NS_FATAL_ERROR(
"Packet was not intended for this receiver!");
464 p->RemoveHeader(arqHeader);
465 uint8_t seqNo = arqHeader.
GetSeqNo();
467 NS_LOG_INFO(
"UT: " <<
m_encapAddress <<
" received a packet with SeqNo: " << (uint32_t)(seqNo));
475 NS_LOG_INFO(
"8bit SN: " << (uint32_t)(seqNo) <<
" 32bit SN: " << sn);
481 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(sn);
487 <<
" created a new ARQ buffer entry for SeqNo: " << sn);
488 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
489 arqContext->m_pdu = p;
490 arqContext->m_rxStatus =
true;
491 arqContext->m_seqNo = sn;
492 arqContext->m_retransmissionCount = 0;
499 <<
" reset an existing ARQ entry for SeqNo: " << sn);
500 it->second->m_waitingTimer.Cancel();
501 it->second->m_pdu = p;
502 it->second->m_rxStatus =
true;
505 NS_LOG_INFO(
"Received a packet with SeqNo: " << sn
514 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
517 NS_LOG_INFO(
"Finding context for " << i);
522 NS_LOG_INFO(
"Context NOT found for SeqNo: " << i);
524 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
525 arqContext->m_pdu =
nullptr;
526 arqContext->m_rxStatus =
false;
527 arqContext->m_seqNo = i;
528 arqContext->m_retransmissionCount = 0;
535 arqContext->m_waitingTimer = id;
547 NS_LOG_INFO(
"UT: " <<
m_encapAddress <<
" received a packet with SeqNo: " << sn
548 <<
" which is already received!");
555 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
557 uint32_t globalSeqNo(0);
563 NS_LOG_INFO(
"Input: " << (uint32_t)(seqNo) <<
" rounds: " << rounds <<
" rawSeqNo: " << rawSeqNo
568 if (seqNo >= rawSeqNo)
585 globalSeqNo = rounds * std::numeric_limits<uint8_t>::max() + seqNo;
593 NS_LOG_FUNCTION(
this);
596 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.begin();
599 <<
", status: " << it->second->m_rxStatus);
606 it->second->m_rxStatus ==
true)
609 <<
", status: " << it->second->m_rxStatus);
612 if (it->second->m_waitingTimer.IsPending())
614 it->second->m_waitingTimer.Cancel();
619 if (it->second->m_pdu)
638 NS_LOG_FUNCTION(
this << seqNo);
640 NS_LOG_INFO(
"For UT: " <<
m_encapAddress <<
" max waiting time reached for SeqNo: " << seqNo);
641 NS_LOG_INFO(
"Mark the PDU received and move forward!");
644 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(seqNo);
647 it->second->m_waitingTimer.Cancel();
648 it->second->m_rxStatus =
true;
652 NS_FATAL_ERROR(
"Rx waiting timer is not running anymore even though it expired!");
661 NS_LOG_FUNCTION(
this);
669 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
672 <<
" with flowId: " << (uint32_t)(
m_flowId)
673 <<
" with SN: " << (uint32_t)(seqNo));
683 Ptr<SatArqAckMessage> ack = CreateObject<SatArqAckMessage>();
684 ack->SetSequenceNumber(seqNo);
693 NS_FATAL_ERROR(
"Unable to send ACK, since the Ctrl callback is NULL!");
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.
Mac48Address m_destE2EAddress
Mac48Address m_sourceE2EAddress
uint8_t m_flowId
Flow identifier.
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.
Mac48Address m_decapAddress
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.
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.
SatReturnLinkEncapsulatorArq class is inherited from the SatReturnLinkEncapsulator class,...
virtual uint32_t GetTxBufferSizeInBytes() const
Get the buffered packets for this encapsulator.
void ReassembleAndReceive()
Reassemble and receive the received PDUs if possible.
uint32_t m_arqWindowSize
ARQ window size, i.e.
virtual Ptr< Packet > NotifyTxOpportunity(uint32_t bytes, uint32_t &bytesLeft, uint32_t &nextMinTxO)
Notify a Tx opportunity to this encapsulator.
uint32_t m_txedBufferSize
Time m_retransmissionTimer
Retransmission timer, i.e.
Time m_rxWaitingTimer
Waiting time for waiting a certain SN to be received.
SatReturnLinkEncapsulatorArq()
Default constructor, not used.
uint32_t m_maxNoOfRetransmissions
Maximum number of retransmissions.
static TypeId GetTypeId(void)
Get the type ID.
virtual void ReceiveAck(Ptr< SatArqAckMessage > ack)
Receive a control message (ARQ ACK).
uint32_t m_nextExpectedSeqNo
Next expected sequence number at the packet reception.
void SendAck(uint8_t seqNo) const
Send ACK for a given sequence number.
std::map< uint8_t, Ptr< SatArqBufferContext > > m_txedBuffer
Transmitted and retransmission context buffer.
std::map< uint8_t, Ptr< SatArqBufferContext > > m_retxBuffer
uint32_t m_maxRtnArqSegmentSize
Max RTN link ARQ segment size.
void ArqReTxTimerExpired(uint8_t seqNo)
ARQ Tx timer has expired.
virtual void DoDispose()
Dispose of this class instance.
Ptr< SatArqSequenceNumber > m_seqNo
Sequence number handler.
uint32_t m_arqHeaderSize
ARQ header size in Bytes.
void CleanUp(uint8_t sequenceNumber)
Clean-up a certain sequence number.
virtual void NotifyConstructionCompleted() override
Notifier called once the ObjectBase is fully constructed.
virtual ~SatReturnLinkEncapsulatorArq()
Destructor for SatReturnLinkEncapsulatorArq.
void RxWaitingTimerExpired(uint32_t sn)
Rx waiting timer for a PDU has expired.
uint32_t ConvertSeqNo(uint8_t seqNo) const
Convert the 8-bit sequence number value from ARQ header into 32-bit continuous sequence number stream...
virtual void ReceivePdu(Ptr< Packet > p)
Receive a packet, thus decapsulate and defragment/deconcatenate if needed.
uint32_t m_retxBufferSize
std::map< uint32_t, Ptr< SatArqBufferContext > > m_reorderingBuffer
key = sequence number value = RLE packet
Ptr< Packet > GetNewRlePdu(uint32_t txOpportunityBytes, uint32_t maxRlePduSize, uint32_t additionalHeaderSize=0)
Get new packet performs the RLE fragmentation and encapsulation for a one single packet.
virtual void DoDispose()
Dispose of this class instance.
virtual uint32_t GetMinTxOpportunityInBytes() const
Get minimum Tx opportunity in bytes, which takes the assumed header sizes into account.
virtual void ProcessPdu(Ptr< Packet > p)
Process the reception of individual RLE PDUs.
SatReturnLinkEncapsulator()
Default constructor, not used.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.