31 #include <ns3/mac48-address.h>
32 #include <ns3/simulator.h>
39 NS_LOG_COMPONENT_DEFINE(
"SatGenericStreamEncapsulatorArq");
44 NS_OBJECT_ENSURE_REGISTERED(SatGenericStreamEncapsulatorArq);
52 m_maxNoOfRetransmissions(2),
53 m_retransmissionTimer(Seconds(0.6)),
56 m_nextExpectedSeqNo(0)
58 NS_LOG_FUNCTION(
this);
67 Mac48Address decapAddress,
68 Mac48Address sourceE2EAddress,
69 Mac48Address destE2EAddress,
71 uint32_t additionalHeaderSize)
77 additionalHeaderSize),
83 m_maxNoOfRetransmissions(2),
84 m_retransmissionTimer(Seconds(0.6)),
87 m_nextExpectedSeqNo(0)
89 NS_LOG_FUNCTION(
this);
91 ObjectBase::ConstructSelf(AttributeConstructionList());
99 NS_LOG_FUNCTION(
this);
107 TypeId(
"ns3::SatGenericStreamEncapsulatorArq")
109 .AddConstructor<SatGenericStreamEncapsulatorArq>()
111 "MaxNoOfRetransmissions",
112 "Maximum number of retransmissions for a single GSE PDU.",
115 MakeUintegerChecker<uint32_t>())
117 "RetransmissionTimer",
118 "Retransmission time value, i.e. how long to wait for ACK before retransmission.",
119 TimeValue(Seconds(0.6)),
124 "Window size for ARQ, i.e. how many simultaneous packets are allowed in the air.",
127 MakeUintegerChecker<uint32_t>())
128 .AddAttribute(
"ArqHeaderSize",
129 "ARQ header size in Bytes.",
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)),
151 NS_LOG_FUNCTION(
this);
155 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.begin();
158 it->second->DoDispose();
168 it->second->DoDispose();
175 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
m_reorderingBuffer.begin();
178 it2->second->DoDispose();
190 uint32_t& nextMinTxO)
192 NS_LOG_FUNCTION(
this << bytes);
194 <<
" of " << bytes <<
" bytes");
207 Ptr<SatArqBufferContext> context =
m_retxBuffer.begin()->second;
210 if (context->m_pdu->GetSize() <= bytes)
216 context->m_retransmissionCount = context->m_retransmissionCount + 1;
221 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
225 NS_FATAL_ERROR(
"Trying to add retransmission packet to txedBuffer even though it "
226 "already exists there!");
230 m_txedBuffer.insert(std::make_pair(context->m_seqNo, context));
239 context->m_waitingTimer = t;
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));
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);
270 packet->AddPacketTag(mTag);
274 if (!packet->PeekPacketTag(addressE2ETag))
278 packet->AddPacketTag(addressE2ETag);
284 packet->AddPacketTag(flowIdTag);
287 uint8_t seqNo =
m_seqNo->NextSequenceNumber();
292 packet->AddHeader(arqHeader);
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;
304 arqContext->m_waitingTimer =
314 if (packet->GetSize() > bytes)
316 NS_FATAL_ERROR(
"Created packet of size: " << packet->GetSize()
317 <<
" is larger than the tx opportunity: "
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());
327 else if (!
m_seqNo->SeqNoAvailable())
345 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
348 <<
" ARQ retransmission timer expired for: " << (uint32_t)(seqNo));
350 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(seqNo);
354 NS_ASSERT(seqNo == it->second->m_seqNo);
355 NS_ASSERT(it->second->m_pdu);
360 NS_LOG_INFO(
"Moving the ARQ context to retransmission buffer");
362 Ptr<SatArqBufferContext> context = it->second;
373 NS_LOG_INFO(
"For GW: " <<
m_encapAddress <<
" max retransmissions reached for "
374 << (uint32_t)(seqNo));
382 NS_LOG_INFO(
"Element not found anymore in the m_txedBuffer, thus ACK has been received "
390 NS_LOG_FUNCTION(
this << (uint32_t)sequenceNumber);
393 m_seqNo->Release(sequenceNumber);
396 std::map<uint8_t, Ptr<SatArqBufferContext>>::iterator it =
m_txedBuffer.find(sequenceNumber);
399 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from txedBuffer!");
401 it->second->DoDispose();
410 NS_LOG_INFO(
"Sequence no: " << (uint32_t)sequenceNumber <<
" clean up from retxBuffer!");
412 it->second->DoDispose();
421 NS_LOG_FUNCTION(
this);
429 <<
" received ACK with SN: " << (uint32_t)(ack->GetSequenceNumber()));
432 CleanUp(ack->GetSequenceNumber());
438 NS_LOG_FUNCTION(
this << p->GetSize());
442 p->RemovePacketTag(statusTag);
446 p->RemovePacketTag(flowIdTag);
450 bool mSuccess = p->RemovePacketTag(mTag);
453 NS_FATAL_ERROR(
"MAC tag not found in the packet!");
457 NS_FATAL_ERROR(
"Packet was not intended for this receiver!");
461 p->RemoveHeader(arqHeader);
462 uint8_t seqNo = arqHeader.
GetSeqNo();
464 NS_LOG_INFO(
"GW: " <<
m_encapAddress <<
" received a packet with SeqNo: " << (uint32_t)(seqNo));
472 NS_LOG_INFO(
"8bit SN: " << (uint32_t)(seqNo) <<
" 32bit SN: " << sn);
478 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(sn);
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;
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;
502 NS_LOG_INFO(
"Received a packet with SeqNo: " << sn
511 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it2 =
514 NS_LOG_INFO(
"Finding context for " << i);
519 NS_LOG_INFO(
"Context NOT found for SeqNo: " << i);
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;
532 arqContext->m_waitingTimer = id;
544 NS_LOG_INFO(
"GW: " <<
m_encapAddress <<
" received a packet with SeqNo: " << sn
545 <<
" which is already received!");
552 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
554 uint32_t globalSeqNo(0);
560 NS_LOG_INFO(
"Input: " << (uint32_t)(seqNo) <<
" rounds: " << rounds <<
" rawSeqNo: " << rawSeqNo
565 if (seqNo >= rawSeqNo)
582 globalSeqNo = rounds * std::numeric_limits<uint8_t>::max() + seqNo;
590 NS_LOG_FUNCTION(
this);
593 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.begin();
596 <<
", status: " << it->second->m_rxStatus);
603 it->second->m_rxStatus ==
true)
606 <<
", status: " << it->second->m_rxStatus);
610 if (it->second->m_pdu)
616 it->second->DoDispose();
631 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
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!");
637 std::map<uint32_t, Ptr<SatArqBufferContext>>::iterator it =
m_reorderingBuffer.find(seqNo);
640 it->second->m_waitingTimer.Cancel();
641 it->second->m_rxStatus =
true;
645 NS_FATAL_ERROR(
"Rx waiting timer is not running anymore even though it expired!");
654 NS_LOG_FUNCTION(
this);
662 NS_LOG_FUNCTION(
this << (uint32_t)seqNo);
665 <<
" with flowId: " << (uint32_t)(
m_flowId)
666 <<
" with SN: " << (uint32_t)(seqNo));
676 Ptr<SatArqAckMessage> ack = Create<SatArqAckMessage>();
677 ack->SetSequenceNumber(seqNo);
686 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.