31 #include <ns3/mac48-address.h>
32 #include <ns3/simulator.h>
36 NS_LOG_COMPONENT_DEFINE(
"SatGenericStreamEncapsulatorArq");
41 NS_OBJECT_ENSURE_REGISTERED(SatGenericStreamEncapsulatorArq);
49 m_maxNoOfRetransmissions(2),
50 m_retransmissionTimer(Seconds(0.6)),
53 m_nextExpectedSeqNo(0)
55 NS_LOG_FUNCTION(
this);
64 Mac48Address decapAddress,
65 Mac48Address sourceE2EAddress,
66 Mac48Address destE2EAddress,
68 uint32_t additionalHeaderSize)
74 additionalHeaderSize),
80 m_maxNoOfRetransmissions(2),
81 m_retransmissionTimer(Seconds(0.6)),
84 m_nextExpectedSeqNo(0)
86 NS_LOG_FUNCTION(
this);
88 ObjectBase::ConstructSelf(AttributeConstructionList());
96 NS_LOG_FUNCTION(
this);
104 TypeId(
"ns3::SatGenericStreamEncapsulatorArq")
106 .AddConstructor<SatGenericStreamEncapsulatorArq>()
108 "MaxNoOfRetransmissions",
109 "Maximum number of retransmissions for a single GSE PDU.",
112 MakeUintegerChecker<uint32_t>())
114 "RetransmissionTimer",
115 "Retransmission time value, i.e. how long to wait for ACK before retransmission.",
116 TimeValue(Seconds(0.6)),
121 "Window size for ARQ, i.e. how many simultaneous packets are allowed in the air.",
124 MakeUintegerChecker<uint32_t>())
125 .AddAttribute(
"ArqHeaderSize",
126 "ARQ header size in Bytes.",
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)),
148 NS_LOG_FUNCTION(
this);
152 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.begin();
155 it->second->DoDispose();
165 it->second->DoDispose();
172 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
m_reorderingBuffer.begin();
175 it2->second->DoDispose();
187 uint32_t& nextMinTxO)
189 NS_LOG_FUNCTION(
this << bytes);
191 <<
" of " << bytes <<
" bytes");
204 Ptr<SatArqBufferContext> context =
m_retxBuffer.begin()->second;
207 if (context->m_pdu->GetSize() <= bytes)
213 context->m_retransmissionCount = context->m_retransmissionCount + 1;
218 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
222 NS_FATAL_ERROR(
"Trying to add retransmission packet to txedBuffer even though it "
223 "already exists there!");
227 m_txedBuffer.insert(std::make_pair(context->m_seqNo, context));
236 context->m_waitingTimer = t;
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));
243 Ptr<Packet> copy = context->m_pdu->Copy();
248 NS_LOG_INFO(
"Retransmission PDU: " << context->m_pdu->GetUid()
249 <<
" size: " << context->m_pdu->GetSize()
250 <<
" does not fit into TxO: " << bytes);
267 packet->AddPacketTag(mTag);
271 if (!packet->PeekPacketTag(addressE2ETag))
275 packet->AddPacketTag(addressE2ETag);
281 packet->AddPacketTag(flowIdTag);
284 uint8_t seqNo =
m_seqNo->NextSequenceNumber();
289 packet->AddHeader(arqHeader);
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;
301 arqContext->m_waitingTimer =
311 if (packet->GetSize() > bytes)
313 NS_FATAL_ERROR(
"Created packet of size: " << packet->GetSize()
314 <<
" is larger than the tx opportunity: "
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());
324 else if (!
m_seqNo->SeqNoAvailable())
342 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
345 <<
" ARQ retransmission timer expired for: " << (uint32_t)(seqNo));
347 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(seqNo);
351 NS_ASSERT(seqNo == it->second->m_seqNo);
352 NS_ASSERT(it->second->m_pdu);
357 NS_LOG_INFO(
"Moving the ARQ context to retransmission buffer");
359 Ptr<SatArqBufferContext> context = it->second;
370 NS_LOG_INFO(
"For GW: " <<
m_encapAddress <<
" max retransmissions reached for "
371 << (uint32_t)(seqNo));
379 NS_LOG_INFO(
"Element not found anymore in the m_txedBuffer, thus ACK has been received "
387 NS_LOG_FUNCTION(
this << (uint32_t)sequenceNumber);
390 m_seqNo->Release(sequenceNumber);
393 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(sequenceNumber);
396 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from txedBuffer!");
398 it->second->DoDispose();
407 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from retxBuffer!");
409 it->second->DoDispose();
418 NS_LOG_FUNCTION(
this);
426 <<
" received ACK with SN: " << (uint32_t)(ack->GetSequenceNumber()));
429 CleanUp(ack->GetSequenceNumber());
435 NS_LOG_FUNCTION(
this << p->GetSize());
439 p->RemovePacketTag(statusTag);
443 p->RemovePacketTag(flowIdTag);
447 bool mSuccess = p->RemovePacketTag(mTag);
450 NS_FATAL_ERROR(
"MAC tag not found in the packet!");
454 NS_FATAL_ERROR(
"Packet was not intended for this receiver!");
458 p->RemoveHeader(arqHeader);
459 uint8_t seqNo = arqHeader.
GetSeqNo();
461 NS_LOG_INFO(
"GW: " <<
m_encapAddress <<
" received a packet with SeqNo: " << (uint32_t)(seqNo));
469 NS_LOG_INFO(
"8bit SN: " << (uint32_t)(seqNo) <<
" 32bit SN: " << sn);
475 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(sn);
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;
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;
499 NS_LOG_INFO(
"Received a packet with SeqNo: " << sn
508 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
511 NS_LOG_INFO(
"Finding context for " << i);
516 NS_LOG_INFO(
"Context NOT found for SeqNo: " << i);
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;
529 arqContext->m_waitingTimer = id;
541 NS_LOG_INFO(
"GW: " <<
m_encapAddress <<
" received a packet with SeqNo: " << sn
542 <<
" which is already received!");
549 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
551 uint32_t globalSeqNo(0);
557 NS_LOG_INFO(
"Input: " << (uint32_t)(seqNo) <<
" rounds: " << rounds <<
" rawSeqNo: " << rawSeqNo
562 if (seqNo >= rawSeqNo)
579 globalSeqNo = rounds * std::numeric_limits<uint8_t>::max() + seqNo;
587 NS_LOG_FUNCTION(
this);
590 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.begin();
593 <<
", status: " << it->second->m_rxStatus);
600 it->second->m_rxStatus ==
true)
603 <<
", status: " << it->second->m_rxStatus);
607 if (it->second->m_pdu)
613 it->second->DoDispose();
628 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
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!");
634 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(seqNo);
637 it->second->m_waitingTimer.Cancel();
638 it->second->m_rxStatus =
true;
642 NS_FATAL_ERROR(
"Rx waiting timer is not running anymore even though it expired!");
651 NS_LOG_FUNCTION(
this);
659 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
662 <<
" with flowId: " << (uint32_t)(
m_flowId)
663 <<
" with SN: " << (uint32_t)(seqNo));
673 Ptr<SatArqAckMessage> ack = Create<SatArqAckMessage>();
674 ack->SetSequenceNumber(seqNo);
683 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.
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.
SatGenericStreamEncapsulatorArq()
Default constructor, not used.
Time m_retransmissionTimer
Retransmission timer, i.e.
virtual void ReceivePdu(Ptr< Packet > p)
Receive a packet, thus decapsulate and defragment/deconcatenate if needed.
uint32_t m_arqWindowSize
ARQ window size, i.e.
uint32_t m_txedBufferSize
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.
uint32_t m_arqHeaderSize
ARQ header size in Bytes.
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
TypeId GetInstanceTypeId(void) const
Ptr< SatArqSequenceNumber > m_seqNo
Sequence number handler.
uint32_t m_retxBufferSize
virtual Ptr< Packet > NotifyTxOpportunity(uint32_t bytes, uint32_t &bytesLeft, uint32_t &nextMinTxO)
Notify a Tx opportunity to this encapsulator.
static TypeId GetTypeId(void)
Get the type ID.
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.