32 #include <ns3/mac48-address.h>
33 #include <ns3/simulator.h>
40 NS_LOG_COMPONENT_DEFINE(
"SatReturnLinkEncapsulatorArq");
45 NS_OBJECT_ENSURE_REGISTERED(SatReturnLinkEncapsulatorArq);
53 m_maxRtnArqSegmentSize(37),
54 m_maxNoOfRetransmissions(2),
55 m_retransmissionTimer(Seconds(0.6)),
58 m_nextExpectedSeqNo(0)
60 NS_LOG_FUNCTION(
this);
69 Mac48Address decapAddress,
70 Mac48Address sourceE2EAddress,
71 Mac48Address destE2EAddress,
73 uint32_t additionalHeaderSize)
79 additionalHeaderSize),
85 m_maxRtnArqSegmentSize(37),
86 m_maxNoOfRetransmissions(2),
87 m_retransmissionTimer(Seconds(0.6)),
90 m_nextExpectedSeqNo(0)
92 NS_LOG_FUNCTION(
this);
94 ObjectBase::ConstructSelf(AttributeConstructionList());
101 NS_LOG_FUNCTION(
this);
108 TypeId(
"ns3::SatReturnLinkEncapsulatorArq")
110 .AddConstructor<SatReturnLinkEncapsulatorArq>()
112 "MaxRtnArqSegmentSize",
113 "Maximum return link ARQ segment size in Bytes.",
116 MakeUintegerChecker<uint32_t>())
118 "MaxNoOfRetransmissions",
119 "Maximum number of retransmissions for a single RLE PDU.",
122 MakeUintegerChecker<uint32_t>())
124 "RetransmissionTimer",
125 "Retransmission time value, i.e. how long to wait for ACK before retransmission.",
126 TimeValue(Seconds(0.6)),
131 "Window size for ARQ, i.e. how many simultaneous packets are allowed in the air.",
134 MakeUintegerChecker<uint32_t>())
135 .AddAttribute(
"ArqHeaderSize",
136 "ARQ header size in Bytes.",
139 MakeUintegerChecker<uint32_t>())
140 .AddAttribute(
"RxWaitingTime",
141 "Time to wait for a packet at the reception (GW) before moving onwards "
142 "with the packet reception.",
143 TimeValue(Seconds(1.8)),
158 NS_LOG_FUNCTION(
this);
162 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.begin();
165 it->second->DoDispose();
175 it->second->DoDispose();
182 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
m_reorderingBuffer.begin();
185 it2->second->DoDispose();
197 uint32_t& nextMinTxO)
199 NS_LOG_FUNCTION(
this << bytes);
201 <<
" of " << bytes <<
" bytes");
214 Ptr<SatArqBufferContext> context =
m_retxBuffer.begin()->second;
217 if (context->m_pdu->GetSize() <= bytes)
223 context->m_retransmissionCount = context->m_retransmissionCount + 1;
229 m_txedBuffer.insert(std::make_pair(context->m_seqNo, context));
238 context->m_waitingTimer = t;
240 NS_LOG_INFO(
"UT: << " <<
m_encapAddress <<
" sent a retransmission packet of size: "
241 << context->m_pdu->GetSize()
242 <<
" with seqNo: " << (uint32_t)(context->m_seqNo)
243 <<
" flowId: " << (uint32_t)(
m_flowId));
245 Ptr<Packet> copy = context->m_pdu->Copy();
250 NS_LOG_INFO(
"Retransmission PDU: " << context->m_pdu->GetUid()
251 <<
" size: " << context->m_pdu->GetSize()
252 <<
" does not fit into TxO: " << bytes);
267 if (!packet->PeekPacketTag(mTag))
271 packet->AddPacketTag(mTag);
276 if (!packet->PeekPacketTag(addressE2ETag))
280 packet->AddPacketTag(addressE2ETag);
286 packet->AddPacketTag(flowIdTag);
289 uint8_t seqNo =
m_seqNo->NextSequenceNumber();
294 packet->AddHeader(arqHeader);
297 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
298 arqContext->m_retransmissionCount = 0;
299 Ptr<Packet> copy = packet->Copy();
300 arqContext->m_pdu = copy;
301 arqContext->m_seqNo = seqNo;
306 arqContext->m_waitingTimer =
316 if (packet->GetSize() > bytes)
318 NS_FATAL_ERROR(
"Created packet of size: " << packet->GetSize()
319 <<
" is larger than the tx opportunity: "
323 NS_LOG_INFO(
"UT: << " <<
m_encapAddress <<
" sent a packet of size: "
324 << packet->GetSize() <<
" with seqNo: " << (uint32_t)(seqNo)
325 <<
" flowId: " << (uint32_t)(
m_flowId));
326 NS_LOG_INFO(
"Queue size after TxOpportunity: " <<
m_txQueue->GetNBytes());
329 else if (!
m_seqNo->SeqNoAvailable())
347 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
350 <<
" ARQ retransmission timer expired for: " << (uint32_t)(seqNo));
352 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(seqNo);
356 NS_ASSERT(seqNo == it->second->m_seqNo);
357 NS_ASSERT(it->second->m_pdu);
362 NS_LOG_INFO(
"Moving the ARQ context to retransmission buffer");
364 Ptr<SatArqBufferContext> context = it->second;
375 NS_LOG_INFO(
"For UT: " <<
m_encapAddress <<
" max retransmissions reached for "
376 << (uint32_t)(seqNo));
384 NS_LOG_INFO(
"Element not found anymore in the m_txedBuffer, thus ACK has been received "
392 NS_LOG_FUNCTION(
this << (uint32_t)sequenceNumber);
395 m_seqNo->Release(sequenceNumber);
398 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(sequenceNumber);
401 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from txedBuffer!");
403 it->second->DoDispose();
412 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from retxBuffer!");
414 it->second->DoDispose();
423 NS_LOG_FUNCTION(
this);
431 <<
" received ACK with SN: " << (uint32_t)(ack->GetSequenceNumber()));
434 CleanUp(ack->GetSequenceNumber());
440 NS_LOG_FUNCTION(
this << p->GetSize());
444 p->RemovePacketTag(statusTag);
448 p->RemovePacketTag(flowIdTag);
452 bool mSuccess = p->RemovePacketTag(mTag);
455 NS_FATAL_ERROR(
"MAC tag not found in the packet!");
459 NS_FATAL_ERROR(
"Packet was not intended for this receiver!");
463 p->RemoveHeader(arqHeader);
464 uint8_t seqNo = arqHeader.
GetSeqNo();
466 NS_LOG_INFO(
"UT: " <<
m_encapAddress <<
" received a packet with SeqNo: " << (uint32_t)(seqNo));
474 NS_LOG_INFO(
"8bit SN: " << (uint32_t)(seqNo) <<
" 32bit SN: " << sn);
480 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(sn);
486 <<
" created a new ARQ buffer entry for SeqNo: " << sn);
487 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
488 arqContext->m_pdu = p;
489 arqContext->m_rxStatus =
true;
490 arqContext->m_seqNo = sn;
491 arqContext->m_retransmissionCount = 0;
498 <<
" reset an existing ARQ entry for SeqNo: " << sn);
499 it->second->m_waitingTimer.Cancel();
500 it->second->m_pdu = p;
501 it->second->m_rxStatus =
true;
504 NS_LOG_INFO(
"Received a packet with SeqNo: " << sn
513 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
516 NS_LOG_INFO(
"Finding context for " << i);
521 NS_LOG_INFO(
"Context NOT found for SeqNo: " << i);
523 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
524 arqContext->m_pdu =
nullptr;
525 arqContext->m_rxStatus =
false;
526 arqContext->m_seqNo = i;
527 arqContext->m_retransmissionCount = 0;
534 arqContext->m_waitingTimer = id;
546 NS_LOG_INFO(
"UT: " <<
m_encapAddress <<
" received a packet with SeqNo: " << sn
547 <<
" which is already received!");
554 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
556 uint32_t globalSeqNo(0);
562 NS_LOG_INFO(
"Input: " << (uint32_t)(seqNo) <<
" rounds: " << rounds <<
" rawSeqNo: " << rawSeqNo
567 if (seqNo >= rawSeqNo)
584 globalSeqNo = rounds * std::numeric_limits<uint8_t>::max() + seqNo;
592 NS_LOG_FUNCTION(
this);
595 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.begin();
598 <<
", status: " << it->second->m_rxStatus);
605 it->second->m_rxStatus ==
true)
608 <<
", status: " << it->second->m_rxStatus);
611 if (it->second->m_waitingTimer.IsPending())
613 it->second->m_waitingTimer.Cancel();
618 if (it->second->m_pdu)
637 NS_LOG_FUNCTION(
this << seqNo);
639 NS_LOG_INFO(
"For UT: " <<
m_encapAddress <<
" max waiting time reached for SeqNo: " << seqNo);
640 NS_LOG_INFO(
"Mark the PDU received and move forward!");
643 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(seqNo);
646 it->second->m_waitingTimer.Cancel();
647 it->second->m_rxStatus =
true;
651 NS_FATAL_ERROR(
"Rx waiting timer is not running anymore even though it expired!");
660 NS_LOG_FUNCTION(
this);
668 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
671 <<
" with flowId: " << (uint32_t)(
m_flowId)
672 <<
" with SN: " << (uint32_t)(seqNo));
682 Ptr<SatArqAckMessage> ack = Create<SatArqAckMessage>();
683 ack->SetSequenceNumber(seqNo);
692 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.
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 ~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
TypeId GetInstanceTypeId(void) const
SatReturnLinkEncapsulator class is used in the RTN link for RLE encapsulation and fragmentation of hi...
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.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.