32 #include <ns3/mac48-address.h>
33 #include <ns3/simulator.h>
37 NS_LOG_COMPONENT_DEFINE(
"SatReturnLinkEncapsulatorArq");
42 NS_OBJECT_ENSURE_REGISTERED(SatReturnLinkEncapsulatorArq);
50 m_maxRtnArqSegmentSize(37),
51 m_maxNoOfRetransmissions(2),
52 m_retransmissionTimer(Seconds(0.6)),
55 m_nextExpectedSeqNo(0)
57 NS_LOG_FUNCTION(
this);
66 Mac48Address decapAddress,
67 Mac48Address sourceE2EAddress,
68 Mac48Address destE2EAddress,
70 uint32_t additionalHeaderSize)
76 additionalHeaderSize),
82 m_maxRtnArqSegmentSize(37),
83 m_maxNoOfRetransmissions(2),
84 m_retransmissionTimer(Seconds(0.6)),
87 m_nextExpectedSeqNo(0)
89 NS_LOG_FUNCTION(
this);
91 ObjectBase::ConstructSelf(AttributeConstructionList());
98 NS_LOG_FUNCTION(
this);
105 TypeId(
"ns3::SatReturnLinkEncapsulatorArq")
107 .AddConstructor<SatReturnLinkEncapsulatorArq>()
109 "MaxRtnArqSegmentSize",
110 "Maximum return link ARQ segment size in Bytes.",
113 MakeUintegerChecker<uint32_t>())
115 "MaxNoOfRetransmissions",
116 "Maximum number of retransmissions for a single RLE PDU.",
119 MakeUintegerChecker<uint32_t>())
121 "RetransmissionTimer",
122 "Retransmission time value, i.e. how long to wait for ACK before retransmission.",
123 TimeValue(Seconds(0.6)),
128 "Window size for ARQ, i.e. how many simultaneous packets are allowed in the air.",
131 MakeUintegerChecker<uint32_t>())
132 .AddAttribute(
"ArqHeaderSize",
133 "ARQ header size in Bytes.",
136 MakeUintegerChecker<uint32_t>())
137 .AddAttribute(
"RxWaitingTime",
138 "Time to wait for a packet at the reception (GW) before moving onwards "
139 "with the packet reception.",
140 TimeValue(Seconds(1.8)),
155 NS_LOG_FUNCTION(
this);
159 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.begin();
162 it->second->DoDispose();
172 it->second->DoDispose();
179 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
m_reorderingBuffer.begin();
182 it2->second->DoDispose();
194 uint32_t& nextMinTxO)
196 NS_LOG_FUNCTION(
this << bytes);
198 <<
" of " << bytes <<
" bytes");
211 Ptr<SatArqBufferContext> context =
m_retxBuffer.begin()->second;
214 if (context->m_pdu->GetSize() <= bytes)
220 context->m_retransmissionCount = context->m_retransmissionCount + 1;
226 m_txedBuffer.insert(std::make_pair(context->m_seqNo, context));
235 context->m_waitingTimer = t;
237 NS_LOG_INFO(
"UT: << " <<
m_encapAddress <<
" sent a retransmission packet of size: "
238 << context->m_pdu->GetSize()
239 <<
" with seqNo: " << (uint32_t)(context->m_seqNo)
240 <<
" flowId: " << (uint32_t)(
m_flowId));
242 Ptr<Packet> copy = context->m_pdu->Copy();
247 NS_LOG_INFO(
"Retransmission PDU: " << context->m_pdu->GetUid()
248 <<
" size: " << context->m_pdu->GetSize()
249 <<
" does not fit into TxO: " << bytes);
264 if (!packet->PeekPacketTag(mTag))
268 packet->AddPacketTag(mTag);
273 if (!packet->PeekPacketTag(addressE2ETag))
277 packet->AddPacketTag(addressE2ETag);
283 packet->AddPacketTag(flowIdTag);
286 uint8_t seqNo =
m_seqNo->NextSequenceNumber();
291 packet->AddHeader(arqHeader);
294 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
295 arqContext->m_retransmissionCount = 0;
296 Ptr<Packet> copy = packet->Copy();
297 arqContext->m_pdu = copy;
298 arqContext->m_seqNo = seqNo;
303 arqContext->m_waitingTimer =
313 if (packet->GetSize() > bytes)
315 NS_FATAL_ERROR(
"Created packet of size: " << packet->GetSize()
316 <<
" is larger than the tx opportunity: "
320 NS_LOG_INFO(
"UT: << " <<
m_encapAddress <<
" sent a packet of size: "
321 << packet->GetSize() <<
" with seqNo: " << (uint32_t)(seqNo)
322 <<
" flowId: " << (uint32_t)(
m_flowId));
323 NS_LOG_INFO(
"Queue size after TxOpportunity: " <<
m_txQueue->GetNBytes());
326 else if (!
m_seqNo->SeqNoAvailable())
344 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
347 <<
" ARQ retransmission timer expired for: " << (uint32_t)(seqNo));
349 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(seqNo);
353 NS_ASSERT(seqNo == it->second->m_seqNo);
354 NS_ASSERT(it->second->m_pdu);
359 NS_LOG_INFO(
"Moving the ARQ context to retransmission buffer");
361 Ptr<SatArqBufferContext> context = it->second;
372 NS_LOG_INFO(
"For UT: " <<
m_encapAddress <<
" max retransmissions reached for "
373 << (uint32_t)(seqNo));
381 NS_LOG_INFO(
"Element not found anymore in the m_txedBuffer, thus ACK has been received "
389 NS_LOG_FUNCTION(
this << (uint32_t)sequenceNumber);
392 m_seqNo->Release(sequenceNumber);
395 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(sequenceNumber);
398 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from txedBuffer!");
400 it->second->DoDispose();
409 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from retxBuffer!");
411 it->second->DoDispose();
420 NS_LOG_FUNCTION(
this);
428 <<
" received ACK with SN: " << (uint32_t)(ack->GetSequenceNumber()));
431 CleanUp(ack->GetSequenceNumber());
437 NS_LOG_FUNCTION(
this << p->GetSize());
441 p->RemovePacketTag(statusTag);
445 p->RemovePacketTag(flowIdTag);
449 bool mSuccess = p->RemovePacketTag(mTag);
452 NS_FATAL_ERROR(
"MAC tag not found in the packet!");
456 NS_FATAL_ERROR(
"Packet was not intended for this receiver!");
460 p->RemoveHeader(arqHeader);
461 uint8_t seqNo = arqHeader.
GetSeqNo();
463 NS_LOG_INFO(
"UT: " <<
m_encapAddress <<
" received a packet with SeqNo: " << (uint32_t)(seqNo));
471 NS_LOG_INFO(
"8bit SN: " << (uint32_t)(seqNo) <<
" 32bit SN: " << sn);
477 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(sn);
483 <<
" created a new ARQ buffer entry for SeqNo: " << sn);
484 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
485 arqContext->m_pdu = p;
486 arqContext->m_rxStatus =
true;
487 arqContext->m_seqNo = sn;
488 arqContext->m_retransmissionCount = 0;
495 <<
" reset an existing ARQ entry for SeqNo: " << sn);
496 it->second->m_waitingTimer.Cancel();
497 it->second->m_pdu = p;
498 it->second->m_rxStatus =
true;
501 NS_LOG_INFO(
"Received a packet with SeqNo: " << sn
510 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
513 NS_LOG_INFO(
"Finding context for " << i);
518 NS_LOG_INFO(
"Context NOT found for SeqNo: " << i);
520 Ptr<SatArqBufferContext> arqContext = CreateObject<SatArqBufferContext>();
521 arqContext->m_pdu = NULL;
522 arqContext->m_rxStatus =
false;
523 arqContext->m_seqNo = i;
524 arqContext->m_retransmissionCount = 0;
531 arqContext->m_waitingTimer = id;
543 NS_LOG_INFO(
"UT: " <<
m_encapAddress <<
" received a packet with SeqNo: " << sn
544 <<
" which is already received!");
551 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
553 uint32_t globalSeqNo(0);
559 NS_LOG_INFO(
"Input: " << (uint32_t)(seqNo) <<
" rounds: " << rounds <<
" rawSeqNo: " << rawSeqNo
564 if (seqNo >= rawSeqNo)
581 globalSeqNo = rounds * std::numeric_limits<uint8_t>::max() + seqNo;
589 NS_LOG_FUNCTION(
this);
592 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.begin();
595 <<
", status: " << it->second->m_rxStatus);
602 it->second->m_rxStatus ==
true)
605 <<
", status: " << it->second->m_rxStatus);
608 if (it->second->m_waitingTimer.IsRunning())
610 it->second->m_waitingTimer.Cancel();
615 if (it->second->m_pdu)
634 NS_LOG_FUNCTION(
this << seqNo);
636 NS_LOG_INFO(
"For UT: " <<
m_encapAddress <<
" max waiting time reached for SeqNo: " << seqNo);
637 NS_LOG_INFO(
"Mark the PDU received and move forward!");
640 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(seqNo);
643 it->second->m_waitingTimer.Cancel();
644 it->second->m_rxStatus =
true;
648 NS_FATAL_ERROR(
"Rx waiting timer is not running anymore even though it expired!");
657 NS_LOG_FUNCTION(
this);
665 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
668 <<
" with flowId: " << (uint32_t)(
m_flowId)
669 <<
" with SN: " << (uint32_t)(seqNo));
679 Ptr<SatArqAckMessage> ack = Create<SatArqAckMessage>();
680 ack->SetSequenceNumber(seqNo);
689 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.