Bug Summary

File:/tmp/asd-nat/home/nat/Work/ns-3-dev-git/build/../src/lte/model/lte-rlc-am.cc
Location:line 303, column 19
Description:Value stored to 'found' is never read

Annotated Source Code

1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Manuel Requena <manuel.requena@cttc.es>
19 * Nicola Baldo <nbaldo@cttc.es>
20 */
21
22#include "ns3/simulator.h"
23#include "ns3/log.h"
24
25#include "ns3/lte-rlc-am-header.h"
26#include "ns3/lte-rlc-am.h"
27#include "ns3/lte-rlc-sdu-status-tag.h"
28#include "ns3/lte-rlc-tag.h"
29
30
31namespace ns3 {
32
33NS_LOG_COMPONENT_DEFINE ("LteRlcAm")static ns3::LogComponent g_log = ns3::LogComponent ("LteRlcAm"
, "../src/lte/model/lte-rlc-am.cc")
;
34
35NS_OBJECT_ENSURE_REGISTERED (LteRlcAm)static struct ObjectLteRlcAmRegistrationClass { ObjectLteRlcAmRegistrationClass
() { ns3::TypeId tid = LteRlcAm::GetTypeId (); tid.SetSize (
sizeof (LteRlcAm)); tid.GetParent (); } } ObjectLteRlcAmRegistrationVariable
;
36
37
38LteRlcAm::LteRlcAm ()
39{
40 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
41
42 // Buffers
43 m_txonBufferSize = 0;
44 m_retxBuffer.resize (1024);
45 m_retxBufferSize = 0;
46 m_txedBuffer.resize (1024);
47 m_txedBufferSize = 0;
48
49 m_statusPduRequested = false;
50 m_statusPduBufferSize = 0;
51
52 // State variables: transmitting side
53 m_windowSize = 512;
54 m_vtA = 0;
55 m_vtMs = m_vtA + m_windowSize;
56 m_vtS = 0;
57 m_pollSn = 0;
58
59 // State variables: receiving side
60 m_vrR = 0;
61 m_vrMr = m_vrR + m_windowSize;
62 m_vrX = 0;
63 m_vrMs = 0;
64 m_vrH = 0;
65
66 // Counters
67 m_pduWithoutPoll = 0;
68 m_byteWithoutPoll = 0;
69
70 // Configurable parameters
71 m_maxRetxThreshold = 5;
72 m_pollPdu = 1;
73 m_pollByte = 50;
74
75 // SDU reassembling process
76 m_reassemblingState = WAITING_S0_FULL;
77 m_expectedSeqNumber = 0;
78
79 m_pollRetransmitTimerJustExpired = false;
80}
81
82LteRlcAm::~LteRlcAm ()
83{
84 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
85}
86
87TypeId
88LteRlcAm::GetTypeId (void)
89{
90 static TypeId tid = TypeId ("ns3::LteRlcAm")
91 .SetParent<LteRlc> ()
92 .SetGroupName("Lte")
93 .AddConstructor<LteRlcAm> ()
94 .AddAttribute ("PollRetransmitTimer",
95 "Value of the t-PollRetransmit timer (See section 7.3 of 3GPP TS 36.322)",
96 TimeValue (MilliSeconds (20)),
97 MakeTimeAccessor (&LteRlcAm::m_pollRetransmitTimerValue),
98 MakeTimeChecker ())
99 .AddAttribute ("ReorderingTimer",
100 "Value of the t-Reordering timer (See section 7.3 of 3GPP TS 36.322)",
101 TimeValue (MilliSeconds (10)),
102 MakeTimeAccessor (&LteRlcAm::m_reorderingTimerValue),
103 MakeTimeChecker ())
104 .AddAttribute ("StatusProhibitTimer",
105 "Value of the t-StatusProhibit timer (See section 7.3 of 3GPP TS 36.322)",
106 TimeValue (MilliSeconds (10)),
107 MakeTimeAccessor (&LteRlcAm::m_statusProhibitTimerValue),
108 MakeTimeChecker ())
109 .AddAttribute ("ReportBufferStatusTimer",
110 "How much to wait to issue a new Report Buffer Status since the last time "
111 "a new SDU was received",
112 TimeValue (MilliSeconds (20)),
113 MakeTimeAccessor (&LteRlcAm::m_rbsTimerValue),
114 MakeTimeChecker ())
115 .AddAttribute ("TxOpportunityForRetxAlwaysBigEnough",
116 "If true, always pretend that the size of a TxOpportunity is big enough "
117 "for retransmission. If false (default and realistic behavior), no retx "
118 "is performed unless the corresponding TxOpportunity is big enough.",
119 BooleanValue (false),
120 MakeBooleanAccessor (&LteRlcAm::m_txOpportunityForRetxAlwaysBigEnough),
121 MakeBooleanChecker ())
122
123 ;
124 return tid;
125}
126
127void
128LteRlcAm::DoDispose ()
129{
130 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
131 m_pollRetransmitTimer.Cancel ();
132 m_reorderingTimer.Cancel ();
133 m_statusProhibitTimer.Cancel ();
134 m_rbsTimer.Cancel ();
135
136 m_txonBuffer.clear ();
137 m_txonBufferSize = 0;
138 m_txedBuffer.clear ();
139 m_txedBufferSize = 0;
140 m_retxBuffer.clear ();
141 m_retxBufferSize = 0;
142 m_rxonBuffer.clear ();
143 m_sdusBuffer.clear ();
144 m_keepS0 = 0;
145 m_controlPduBuffer = 0;
146
147 LteRlc::DoDispose ();
148}
149
150
151/**
152 * RLC SAP
153 */
154
155void
156LteRlcAm::DoTransmitPdcpPdu (Ptr<Packet> p)
157{
158 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this << m_rnti << (uint32_t) m_lcid << p->
GetSize (); std::clog << ")" << std::endl; } } while
(false)
;
159
160 /** Store arrival time */
161 Time now = Simulator::Now ();
162 RlcTag timeTag (now);
163 p->AddPacketTag (timeTag);
164
165 /** Store PDCP PDU */
166
167 LteRlcSduStatusTag tag;
168 tag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
169 p->AddPacketTag (tag);
170
171 NS_LOG_LOGIC ("Txon Buffer: New packet added")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Txon Buffer: New packet added"
<< std::endl; } } while (false)
;
172 m_txonBuffer.push_back (p);
173 m_txonBufferSize += p->GetSize ();
174 NS_LOG_LOGIC ("NumOfBuffers = " << m_txonBuffer.size() )do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "NumOfBuffers = "
<< m_txonBuffer.size() << std::endl; } } while (
false)
;
175 NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txonBufferSize = "
<< m_txonBufferSize << std::endl; } } while (false
)
;
176
177 /** Report Buffer Status */
178 DoReportBufferStatus ();
179 m_rbsTimer.Cancel ();
180 m_rbsTimer = Simulator::Schedule (m_rbsTimerValue, &LteRlcAm::ExpireRbsTimer, this);
181}
182
183
184/**
185 * MAC SAP
186 */
187
188void
189LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId, uint8_t componentCarrierId, uint16_t rnti, uint8_t lcid)
190{
191 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this << m_rnti << (uint32_t) m_lcid << bytes
; std::clog << ")" << std::endl; } } while (false
)
;
192
193 if (bytes < 4)
194 {
195 // Stingy MAC: In general, we need more bytes.
196 // There are a more restrictive test for each particular case
197 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "TxOpportunity (size = "
<< bytes << ") too small" << std::endl; } }
while (false)
;
198 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small.\n"do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "TxOpportunity (size = " << bytes << ") too small.\n"
<< "Your MAC scheduler is assigned too few resource blocks."
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 199 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
199 << "Your MAC scheduler is assigned too few resource blocks.")do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "TxOpportunity (size = " << bytes << ") too small.\n"
<< "Your MAC scheduler is assigned too few resource blocks."
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 199 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
200 return;
201 }
202
203 if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
204 {
205 if (bytes < m_statusPduBufferSize)
206 {
207 // Stingy MAC: We need more bytes for the STATUS PDU
208 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "TxOpportunity (size = "
<< bytes << ") too small for the STATUS PDU (size = "
<< m_statusPduBufferSize << ")" << std::endl
; } } while (false)
;
209 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")\n"do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = "
<< m_statusPduBufferSize << ")\n" << "Your MAC scheduler is assigned too few resource blocks."
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 210 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
210 << "Your MAC scheduler is assigned too few resource blocks.")do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = "
<< m_statusPduBufferSize << ")\n" << "Your MAC scheduler is assigned too few resource blocks."
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 210 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
211 return;
212 }
213
214 NS_LOG_LOGIC ("Sending STATUS PDU")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Sending STATUS PDU"
<< std::endl; } } while (false)
;
215
216 Ptr<Packet> packet = Create<Packet> ();
217 LteRlcAmHeader rlcAmHeader;
218 rlcAmHeader.SetControlPdu (LteRlcAmHeader::STATUS_PDU);
219
220 NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to " << m_vrMs.GetValue())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Check for SNs to NACK from "
<< m_vrR.GetValue() << " to " << m_vrMs.GetValue
() << std::endl; } } while (false)
;
221 SequenceNumber10 sn;
222 sn.SetModulusBase (m_vrR);
223 std::map<uint16_t, PduBuffer>::iterator pduIt;
224 for (sn = m_vrR; sn < m_vrMs; sn++)
225 {
226 NS_LOG_LOGIC ("SN = " << sn)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "SN = " <<
sn << std::endl; } } while (false)
;
227 if (!rlcAmHeader.OneMoreNackWouldFitIn (bytes))
228 {
229 NS_LOG_LOGIC ("Can't fit more NACKs in STATUS PDU")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Can't fit more NACKs in STATUS PDU"
<< std::endl; } } while (false)
;
230 break;
231 }
232 pduIt = m_rxonBuffer.find (sn.GetValue ());
233 if (pduIt == m_rxonBuffer.end () || (!(pduIt->second.m_pduComplete)))
234 {
235 NS_LOG_LOGIC ("adding NACK_SN " << sn.GetValue ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "adding NACK_SN "
<< sn.GetValue () << std::endl; } } while (false
)
;
236 rlcAmHeader.PushNack (sn.GetValue ());
237 }
238 }
239 NS_LOG_LOGIC ("SN at end of NACK loop = " << sn)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "SN at end of NACK loop = "
<< sn << std::endl; } } while (false)
;
240 // 3GPP TS 36.322 section 6.2.2.1.4 ACK SN
241 // find the SN of the next not received RLC Data PDU
242 // which is not reported as missing in the STATUS PDU.
243 pduIt = m_rxonBuffer.find (sn.GetValue ());
244 while ((sn < m_vrMs) && (pduIt != m_rxonBuffer.end ()) && (pduIt->second.m_pduComplete))
245 {
246 NS_LOG_LOGIC ("SN = " << sn << " < " << m_vrMs << " = " << (sn < m_vrMs))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "SN = " <<
sn << " < " << m_vrMs << " = " <<
(sn < m_vrMs) << std::endl; } } while (false)
;
247 sn++;
248 NS_LOG_LOGIC ("SN = " << sn)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "SN = " <<
sn << std::endl; } } while (false)
;
249 pduIt = m_rxonBuffer.find (sn.GetValue ());
250 }
251
252 NS_ASSERT_MSG (sn <= m_vrMs, "first SN not reported as missing = " << sn << ", VR(MS) = " << m_vrMs)do { if (!(sn <= m_vrMs)) { std::cerr << "assert failed. cond=\""
<< "sn <= m_vrMs" << "\", "; do { std::cerr <<
"msg=\"" << "first SN not reported as missing = " <<
sn << ", VR(MS) = " << m_vrMs << "\", "; do
{ std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 252 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
253 rlcAmHeader.SetAckSn (sn);
254
255
256 NS_LOG_LOGIC ("RLC header: " << rlcAmHeader)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "RLC header: "
<< rlcAmHeader << std::endl; } } while (false)
;
257 packet->AddHeader (rlcAmHeader);
258
259 // Sender timestamp
260 RlcTag rlcTag (Simulator::Now ());
261 NS_ASSERT_MSG (!packet->PeekPacketTag (rlcTag), "RlcTag is already present")do { if (!(!packet->PeekPacketTag (rlcTag))) { std::cerr <<
"assert failed. cond=\"" << "!packet->PeekPacketTag (rlcTag)"
<< "\", "; do { std::cerr << "msg=\"" << "RlcTag is already present"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 261 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
262 packet->AddPacketTag (rlcTag);
263 m_txPdu (m_rnti, m_lcid, packet->GetSize ());
264
265 // Send RLC PDU to MAC layer
266 LteMacSapProvider::TransmitPduParameters params;
267 params.pdu = packet;
268 params.rnti = m_rnti;
269 params.lcid = m_lcid;
270 params.layer = layer;
271 params.harqProcessId = harqId;
272 params.componentCarrierId = componentCarrierId;
273
274 m_macSapProvider->TransmitPdu (params);
275
276 m_statusPduRequested = false;
277 m_statusPduBufferSize = 0;
278 m_statusProhibitTimer = Simulator::Schedule (m_statusProhibitTimerValue,
279 &LteRlcAm::ExpireStatusProhibitTimer, this);
280 return;
281 }
282 else if ( m_retxBufferSize > 0 )
283 {
284 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "retxBufferSize = "
<< m_retxBufferSize << std::endl; } } while (false
)
;
285 NS_LOG_LOGIC ("Sending data from Retransmission Buffer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Sending data from Retransmission Buffer"
<< std::endl; } } while (false)
;
286 NS_ASSERT (m_vtA < m_vtS)do { if (!(m_vtA < m_vtS)) { std::cerr << "assert failed. cond=\""
<< "m_vtA < m_vtS" << "\", "; do { std::cerr <<
"file=" << "../src/lte/model/lte-rlc-am.cc" << ", line="
<< 286 << std::endl; ::ns3::FatalImpl::FlushStreams
(); if (true) std::terminate (); } while (false); } } while (
false)
;
287 SequenceNumber10 sn;
288 sn.SetModulusBase (m_vtA);
289 bool found = false;
290 for (sn = m_vtA; sn < m_vtS; sn++)
291 {
292 uint16_t seqNumberValue = sn.GetValue ();
293 NS_LOG_LOGIC ("SN = " << seqNumberValue << " m_pdu " << m_retxBuffer.at (seqNumberValue).m_pdu)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "SN = " <<
seqNumberValue << " m_pdu " << m_retxBuffer.at (
seqNumberValue).m_pdu << std::endl; } } while (false)
;
294
295 if (m_retxBuffer.at (seqNumberValue).m_pdu != 0)
296 {
297
298 Ptr<Packet> packet = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
299
300 if (( packet->GetSize () <= bytes )
301 || m_txOpportunityForRetxAlwaysBigEnough)
302 {
303 found = true;
Value stored to 'found' is never read
304 // According to 5.2.1, the data field is left as is, but we rebuild the header
305 LteRlcAmHeader rlcAmHeader;
306 packet->RemoveHeader (rlcAmHeader);
307 NS_LOG_LOGIC ("old AM RLC header: " << rlcAmHeader)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "old AM RLC header: "
<< rlcAmHeader << std::endl; } } while (false)
;
308
309 // Calculate the Polling Bit (5.2.2.1)
310 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
311
312 NS_LOG_LOGIC ("polling conditions: m_txonBuffer.empty=" << m_txonBuffer.empty ()do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "polling conditions: m_txonBuffer.empty="
<< m_txonBuffer.empty () << " retxBufferSize=" <<
m_retxBufferSize << " packet->GetSize ()=" <<
packet->GetSize () << std::endl; } } while (false)
313 << " retxBufferSize=" << m_retxBufferSizedo { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "polling conditions: m_txonBuffer.empty="
<< m_txonBuffer.empty () << " retxBufferSize=" <<
m_retxBufferSize << " packet->GetSize ()=" <<
packet->GetSize () << std::endl; } } while (false)
314 << " packet->GetSize ()=" << packet->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "polling conditions: m_txonBuffer.empty="
<< m_txonBuffer.empty () << " retxBufferSize=" <<
m_retxBufferSize << " packet->GetSize ()=" <<
packet->GetSize () << std::endl; } } while (false)
;
315 if (((m_txonBuffer.empty ()) && (m_retxBufferSize == packet->GetSize () + rlcAmHeader.GetSerializedSize ()))
316 || (m_vtS >= m_vtMs)
317 || m_pollRetransmitTimerJustExpired)
318 {
319 m_pollRetransmitTimerJustExpired = false;
320 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
321 m_pduWithoutPoll = 0;
322 m_byteWithoutPoll = 0;
323
324 m_pollSn = m_vtS - 1;
325 NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New POLL_SN = "
<< m_pollSn << std::endl; } } while (false)
;
326
327 if (! m_pollRetransmitTimer.IsRunning () )
328 {
329 NS_LOG_LOGIC ("Start PollRetransmit timer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Start PollRetransmit timer"
<< std::endl; } } while (false)
;
330
331 m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
332 &LteRlcAm::ExpirePollRetransmitTimer, this);
333 }
334 else
335 {
336 NS_LOG_LOGIC ("Restart PollRetransmit timer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Restart PollRetransmit timer"
<< std::endl; } } while (false)
;
337
338 m_pollRetransmitTimer.Cancel ();
339 m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
340 &LteRlcAm::ExpirePollRetransmitTimer, this);
341 }
342 }
343
344 packet->AddHeader (rlcAmHeader);
345 NS_LOG_LOGIC ("new AM RLC header: " << rlcAmHeader)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "new AM RLC header: "
<< rlcAmHeader << std::endl; } } while (false)
;
346
347 // Sender timestamp
348 RlcTag rlcTag (Simulator::Now ());
349 NS_ASSERT_MSG (packet->PeekPacketTag (rlcTag), "RlcTag is missing")do { if (!(packet->PeekPacketTag (rlcTag))) { std::cerr <<
"assert failed. cond=\"" << "packet->PeekPacketTag (rlcTag)"
<< "\", "; do { std::cerr << "msg=\"" << "RlcTag is missing"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 349 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
350 packet->ReplacePacketTag (rlcTag);
351 m_txPdu (m_rnti, m_lcid, packet->GetSize ());
352
353 // Send RLC PDU to MAC layer
354 LteMacSapProvider::TransmitPduParameters params;
355 params.pdu = packet;
356 params.rnti = m_rnti;
357 params.lcid = m_lcid;
358 params.layer = layer;
359 params.harqProcessId = harqId;
360 params.componentCarrierId = componentCarrierId;
361
362 m_macSapProvider->TransmitPdu (params);
363
364 m_retxBuffer.at (seqNumberValue).m_retxCount++;
365 NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Incr RETX_COUNT for SN = "
<< seqNumberValue << std::endl; } } while (false
)
;
366 if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold)
367 {
368 NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Max RETX_COUNT for SN = "
<< seqNumberValue << std::endl; } } while (false
)
;
369 }
370
371 NS_LOG_INFO ("Move SN = " << seqNumberValue << " back to txedBuffer")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Move SN = "
<< seqNumberValue << " back to txedBuffer" <<
std::endl; } } while (false)
;
372 m_txedBuffer.at (seqNumberValue).m_pdu = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
373 m_txedBuffer.at (seqNumberValue).m_retxCount = m_retxBuffer.at (seqNumberValue).m_retxCount;
374 m_txedBufferSize += m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
375
376 m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
377 m_retxBuffer.at (seqNumberValue).m_pdu = 0;
378 m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
379
380 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "retxBufferSize = "
<< m_retxBufferSize << std::endl; } } while (false
)
;
381
382 return;
383 }
384 else
385 {
386 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for retransmission of the packet (size = " << packet->GetSize () << ")")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "TxOpportunity (size = "
<< bytes << ") too small for retransmission of the packet (size = "
<< packet->GetSize () << ")" << std::endl
; } } while (false)
;
387 NS_LOG_LOGIC ("Waiting for bigger TxOpportunity")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Waiting for bigger TxOpportunity"
<< std::endl; } } while (false)
;
388 return;
389 }
390 }
391 }
392 NS_ASSERT_MSG (found, "m_retxBufferSize > 0, but no PDU considered for retx found")do { if (!(found)) { std::cerr << "assert failed. cond=\""
<< "found" << "\", "; do { std::cerr << "msg=\""
<< "m_retxBufferSize > 0, but no PDU considered for retx found"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 392 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
393 }
394 else if ( m_txonBufferSize > 0 )
395 {
396 if (bytes < 7)
397 {
398 // Stingy MAC: We need more bytes for new DATA PDUs.
399 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for DATA PDU")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "TxOpportunity (size = "
<< bytes << ") too small for DATA PDU" << std
::endl; } } while (false)
;
400 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small for DATA PDU\n"do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "TxOpportunity (size = " << bytes << ") too small for DATA PDU\n"
<< "Your MAC scheduler is assigned too few resource blocks."
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 401 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
401 << "Your MAC scheduler is assigned too few resource blocks.")do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "TxOpportunity (size = " << bytes << ") too small for DATA PDU\n"
<< "Your MAC scheduler is assigned too few resource blocks."
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 401 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
402 return;
403 }
404
405 NS_ASSERT (m_vtS <= m_vtMs)do { if (!(m_vtS <= m_vtMs)) { std::cerr << "assert failed. cond=\""
<< "m_vtS <= m_vtMs" << "\", "; do { std::cerr
<< "file=" << "../src/lte/model/lte-rlc-am.cc" <<
", line=" << 405 << std::endl; ::ns3::FatalImpl::
FlushStreams (); if (true) std::terminate (); } while (false)
; } } while (false)
;
406 if (m_vtS == m_vtMs)
407 {
408 NS_LOG_INFO ("cannot transmit new RLC PDU due to window stalling")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "cannot transmit new RLC PDU due to window stalling"
<< std::endl; } } while (false)
;
409 return;
410 }
411
412 NS_LOG_LOGIC ("Sending data from Transmission Buffer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Sending data from Transmission Buffer"
<< std::endl; } } while (false)
;
413 }
414 else
415 {
416 NS_LOG_LOGIC ("No data pending")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "No data pending"
<< std::endl; } } while (false)
;
417 return;
418 }
419
420 //
421 //
422 // Build new PDU
423 //
424 //
425
426 Ptr<Packet> packet = Create<Packet> ();
427 LteRlcAmHeader rlcAmHeader;
428 rlcAmHeader.SetDataPdu ();
429
430 // Build Data field
431 uint32_t nextSegmentSize = bytes - 4;
432 uint32_t nextSegmentId = 1;
433 uint32_t dataFieldTotalSize = 0;
434 uint32_t dataFieldAddedSize = 0;
435 std::vector < Ptr<Packet> > dataField;
436
437 // Remove the first packet from the transmission buffer.
438 // If only a segment of the packet is taken, then the remaining is given back later
439 if ( m_txonBuffer.size () == 0 )
440 {
441 NS_LOG_LOGIC ("No data pending")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "No data pending"
<< std::endl; } } while (false)
;
442 return;
443 }
444
445 NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "SDUs in TxonBuffer = "
<< m_txonBuffer.size () << std::endl; } } while (
false)
;
446 NS_LOG_LOGIC ("First SDU buffer = " << *(m_txonBuffer.begin()))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "First SDU buffer = "
<< *(m_txonBuffer.begin()) << std::endl; } } while
(false)
;
447 NS_LOG_LOGIC ("First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "First SDU size = "
<< (*(m_txonBuffer.begin()))->GetSize () << std
::endl; } } while (false)
;
448 NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Next segment size = "
<< nextSegmentSize << std::endl; } } while (false
)
;
449 NS_LOG_LOGIC ("Remove SDU from TxBuffer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Remove SDU from TxBuffer"
<< std::endl; } } while (false)
;
450 Ptr<Packet> firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
451 m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
452 NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize )do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txBufferSize = "
<< m_txonBufferSize << std::endl; } } while (false
)
;
453 m_txonBuffer.erase (m_txonBuffer.begin ());
454
455 while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) )
456 {
457 NS_LOG_LOGIC ("WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )"
<< std::endl; } } while (false)
;
458 NS_LOG_LOGIC (" firstSegment size = " << firstSegment->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " firstSegment size = "
<< firstSegment->GetSize () << std::endl; } }
while (false)
;
459 NS_LOG_LOGIC (" nextSegmentSize = " << nextSegmentSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " nextSegmentSize = "
<< nextSegmentSize << std::endl; } } while (false
)
;
460 if ( (firstSegment->GetSize () > nextSegmentSize) ||
461 // Segment larger than 2047 octets can only be mapped to the end of the Data field
462 (firstSegment->GetSize () > 2047)
463 )
464 {
465 // Take the minimum size, due to the 2047-bytes 3GPP exception
466 // This exception is due to the length of the LI field (just 11 bits)
467 uint32_t currSegmentSize = std::min (firstSegment->GetSize (), nextSegmentSize);
468
469 NS_LOG_LOGIC (" IF ( firstSegment > nextSegmentSize ||")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " IF ( firstSegment > nextSegmentSize ||"
<< std::endl; } } while (false)
;
470 NS_LOG_LOGIC (" firstSegment > 2047 )")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " firstSegment > 2047 )"
<< std::endl; } } while (false)
;
471
472 // Segment txBuffer.FirstBuffer and
473 // Give back the remaining segment to the transmission buffer
474 Ptr<Packet> newSegment = firstSegment->CreateFragment (0, currSegmentSize);
475 NS_LOG_LOGIC (" newSegment size = " << newSegment->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " newSegment size = "
<< newSegment->GetSize () << std::endl; } } while
(false)
;
476
477 // Status tag of the new and remaining segments
478 // Note: This is the only place where a PDU is segmented and
479 // therefore its status can change
480 LteRlcSduStatusTag oldTag, newTag;
481 firstSegment->RemovePacketTag (oldTag);
482 newSegment->RemovePacketTag (newTag);
483 if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU)
484 {
485 newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT);
486 oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
487 }
488 else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT)
489 {
490 newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT);
491 //oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
492 }
493
494 // Give back the remaining segment to the transmission buffer
495 firstSegment->RemoveAtStart (currSegmentSize);
496 NS_LOG_LOGIC (" firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " firstSegment size (after RemoveAtStart) = "
<< firstSegment->GetSize () << std::endl; } }
while (false)
;
497 if (firstSegment->GetSize () > 0)
498 {
499 firstSegment->AddPacketTag (oldTag);
500
501 m_txonBuffer.insert (m_txonBuffer.begin (), firstSegment);
502 m_txonBufferSize += (*(m_txonBuffer.begin()))->GetSize ();
503
504 NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " Txon buffer: Give back the remaining segment"
<< std::endl; } } while (false)
;
505 NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " Txon buffers = "
<< m_txonBuffer.size () << std::endl; } } while (
false)
;
506 NS_LOG_LOGIC (" Front buffer size = " << (*(m_txonBuffer.begin()))->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " Front buffer size = "
<< (*(m_txonBuffer.begin()))->GetSize () << std
::endl; } } while (false)
;
507 NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize )do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " txonBufferSize = "
<< m_txonBufferSize << std::endl; } } while (false
)
;
508 }
509 else
510 {
511 // Whole segment was taken, so adjust tag
512 if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
513 {
514 newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
515 }
516 else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT)
517 {
518 newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
519 }
520 }
521 // Segment is completely taken or
522 // the remaining segment is given back to the transmission buffer
523 firstSegment = 0;
524
525 // Put status tag once it has been adjusted
526 newSegment->AddPacketTag (newTag);
527
528 // Add Segment to Data field
529 dataFieldAddedSize = newSegment->GetSize ();
530 dataFieldTotalSize += dataFieldAddedSize;
531 dataField.push_back (newSegment);
532 newSegment = 0;
533
534 // ExtensionBit (Next_Segment - 1) = 0
535 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
536
537 // no LengthIndicator for the last one
538
539 nextSegmentSize -= dataFieldAddedSize;
540 nextSegmentId++;
541
542 // nextSegmentSize MUST be zero (only if segment is smaller or equal to 2047)
543
544 // (NO more segments) ? exit
545 // break;
546 }
547 else if ( (nextSegmentSize - firstSegment->GetSize () <= 2) || (m_txonBuffer.size () == 0) )
548 {
549 NS_LOG_LOGIC (" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0"
<< std::endl; } } while (false)
;
550
551 // Add txBuffer.FirstBuffer to DataField
552 dataFieldAddedSize = firstSegment->GetSize ();
553 dataFieldTotalSize += dataFieldAddedSize;
554 dataField.push_back (firstSegment);
555 firstSegment = 0;
556
557 // ExtensionBit (Next_Segment - 1) = 0
558 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
559
560 // no LengthIndicator for the last one
561
562 nextSegmentSize -= dataFieldAddedSize;
563 nextSegmentId++;
564
565 NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " SDUs in TxBuffer = "
<< m_txonBuffer.size () << std::endl; } } while (
false)
;
566 if (m_txonBuffer.size () > 0)
567 {
568 NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " First SDU buffer = "
<< *(m_txonBuffer.begin()) << std::endl; } } while
(false)
;
569 NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " First SDU size = "
<< (*(m_txonBuffer.begin()))->GetSize () << std
::endl; } } while (false)
;
570 }
571 NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " Next segment size = "
<< nextSegmentSize << std::endl; } } while (false
)
;
572
573 // nextSegmentSize <= 2 (only if txBuffer is not empty)
574
575 // (NO more segments) ? exit
576 // break;
577 }
578 else // (firstSegment->GetSize () < m_nextSegmentSize) && (m_txBuffer.size () > 0)
579 {
580 NS_LOG_LOGIC (" IF firstSegment < NextSegmentSize && txonBuffer.size > 0")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " IF firstSegment < NextSegmentSize && txonBuffer.size > 0"
<< std::endl; } } while (false)
;
581 // Add txBuffer.FirstBuffer to DataField
582 dataFieldAddedSize = firstSegment->GetSize ();
583 dataFieldTotalSize += dataFieldAddedSize;
584 dataField.push_back (firstSegment);
585
586 // ExtensionBit (Next_Segment - 1) = 1
587 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS);
588
589 // LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length()
590 rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ());
591
592 nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
593 nextSegmentId++;
594
595 NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " SDUs in TxBuffer = "
<< m_txonBuffer.size () << std::endl; } } while (
false)
;
596 if (m_txonBuffer.size () > 0)
597 {
598 NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()))do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " First SDU buffer = "
<< *(m_txonBuffer.begin()) << std::endl; } } while
(false)
;
599 NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " First SDU size = "
<< (*(m_txonBuffer.begin()))->GetSize () << std
::endl; } } while (false)
;
600 }
601 NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " Next segment size = "
<< nextSegmentSize << std::endl; } } while (false
)
;
602 NS_LOG_LOGIC (" Remove SDU from TxBuffer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " Remove SDU from TxBuffer"
<< std::endl; } } while (false)
;
603
604 // (more segments)
605 firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
606 m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
607 m_txonBuffer.erase (m_txonBuffer.begin ());
608 NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize )do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << " txBufferSize = "
<< m_txonBufferSize << std::endl; } } while (false
)
;
609 }
610
611 }
612
613 //
614 // Build RLC header
615 //
616
617 rlcAmHeader.SetSequenceNumber ( m_vtS++ );
618 rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
619 rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
620 rlcAmHeader.SetSegmentOffset (0);
621
622 NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () < m_vtMs, "SN above TX window")do { if (!(rlcAmHeader.GetSequenceNumber () < m_vtMs)) { std
::cerr << "assert failed. cond=\"" << "rlcAmHeader.GetSequenceNumber () < m_vtMs"
<< "\", "; do { std::cerr << "msg=\"" << "SN above TX window"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 622 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
623 NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () >= m_vtA, "SN below TX window")do { if (!(rlcAmHeader.GetSequenceNumber () >= m_vtA)) { std
::cerr << "assert failed. cond=\"" << "rlcAmHeader.GetSequenceNumber () >= m_vtA"
<< "\", "; do { std::cerr << "msg=\"" << "SN below TX window"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 623 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
624
625 // Calculate FramingInfo flag according the status of the SDUs in the DataField
626 uint8_t framingInfo = 0;
627 std::vector< Ptr<Packet> >::iterator it;
628 it = dataField.begin ();
629
630 // FIRST SEGMENT
631 LteRlcSduStatusTag tag;
632 NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), "LteRlcSduStatusTag is missing")do { if (!((*it)->PeekPacketTag (tag))) { std::cerr <<
"assert failed. cond=\"" << "(*it)->PeekPacketTag (tag)"
<< "\", "; do { std::cerr << "msg=\"" << "LteRlcSduStatusTag is missing"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 632 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
633 (*it)->PeekPacketTag (tag);
634 if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
635 (tag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
636 )
637 {
638 framingInfo |= LteRlcAmHeader::FIRST_BYTE;
639 }
640 else
641 {
642 framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE;
643 }
644
645 // Add all SDUs (in DataField) to the Packet
646 while (it < dataField.end ())
647 {
648 NS_LOG_LOGIC ("Adding SDU/segment to packet, length = " << (*it)->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Adding SDU/segment to packet, length = "
<< (*it)->GetSize () << std::endl; } } while (
false)
;
649
650 NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), "LteRlcSduStatusTag is missing")do { if (!((*it)->PeekPacketTag (tag))) { std::cerr <<
"assert failed. cond=\"" << "(*it)->PeekPacketTag (tag)"
<< "\", "; do { std::cerr << "msg=\"" << "LteRlcSduStatusTag is missing"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 650 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
651 (*it)->RemovePacketTag (tag);
652 if (packet->GetSize () > 0)
653 {
654 packet->AddAtEnd (*it);
655 }
656 else
657 {
658 packet = (*it);
659 }
660 it++;
661 }
662
663 // LAST SEGMENT (Note: There could be only one and be the first one)
664 it--;
665 if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
666 (tag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT) )
667 {
668 framingInfo |= LteRlcAmHeader::LAST_BYTE;
669 }
670 else
671 {
672 framingInfo |= LteRlcAmHeader::NO_LAST_BYTE;
673 }
674
675 // Set the FramingInfo flag after the calculation
676 rlcAmHeader.SetFramingInfo (framingInfo);
677
678
679 // Calculate the Polling Bit (5.2.2.1)
680 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
681
682 m_pduWithoutPoll++;
683 NS_LOG_LOGIC ("PDU_WITHOUT_POLL = " << m_pduWithoutPoll)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "PDU_WITHOUT_POLL = "
<< m_pduWithoutPoll << std::endl; } } while (false
)
;
684 m_byteWithoutPoll += packet->GetSize ();
685 NS_LOG_LOGIC ("BYTE_WITHOUT_POLL = " << m_byteWithoutPoll)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "BYTE_WITHOUT_POLL = "
<< m_byteWithoutPoll << std::endl; } } while (false
)
;
686
687 if ( (m_pduWithoutPoll >= m_pollPdu) || (m_byteWithoutPoll >= m_pollByte) ||
688 ( (m_txonBuffer.empty ()) && (m_retxBufferSize == 0) ) ||
689 (m_vtS >= m_vtMs)
690 || m_pollRetransmitTimerJustExpired
691 )
692 {
693 m_pollRetransmitTimerJustExpired = false;
694 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
695 m_pduWithoutPoll = 0;
696 m_byteWithoutPoll = 0;
697
698 m_pollSn = m_vtS - 1;
699 NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New POLL_SN = "
<< m_pollSn << std::endl; } } while (false)
;
700
701 if (! m_pollRetransmitTimer.IsRunning () )
702 {
703 NS_LOG_LOGIC ("Start PollRetransmit timer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Start PollRetransmit timer"
<< std::endl; } } while (false)
;
704
705 m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
706 &LteRlcAm::ExpirePollRetransmitTimer, this);
707 }
708 else
709 {
710 NS_LOG_LOGIC ("Restart PollRetransmit timer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Restart PollRetransmit timer"
<< std::endl; } } while (false)
;
711
712 m_pollRetransmitTimer.Cancel ();
713 m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
714 &LteRlcAm::ExpirePollRetransmitTimer, this);
715 }
716 }
717
718
719 // Build RLC PDU with DataField and Header
720 NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "AM RLC header: "
<< rlcAmHeader << std::endl; } } while (false)
;
721 packet->AddHeader (rlcAmHeader);
722
723 // Store new PDU into the Transmitted PDU Buffer
724 NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Put transmitted PDU in the txedBuffer"
<< std::endl; } } while (false)
;
725 m_txedBufferSize += packet->GetSize ();
726 m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_pdu = packet->Copy ();
727 m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_retxCount = 0;
728
729 // Sender timestamp
730 RlcTag rlcTag (Simulator::Now ());
731 packet->ReplacePacketTag (rlcTag);
732 m_txPdu (m_rnti, m_lcid, packet->GetSize ());
733
734 // Send RLC PDU to MAC layer
735 LteMacSapProvider::TransmitPduParameters params;
736 params.pdu = packet;
737 params.rnti = m_rnti;
738 params.lcid = m_lcid;
739 params.layer = layer;
740 params.harqProcessId = harqId;
741 params.componentCarrierId = componentCarrierId;
742
743 m_macSapProvider->TransmitPdu (params);
744}
745
746void
747LteRlcAm::DoNotifyHarqDeliveryFailure ()
748{
749 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
750}
751
752
753void
754LteRlcAm::DoReceivePdu (Ptr<Packet> p, uint16_t rnti, uint8_t lcid)
755{
756 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ())do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this << m_rnti << (uint32_t) m_lcid << p->
GetSize (); std::clog << ")" << std::endl; } } while
(false)
;
757
758 // Receiver timestamp
759 RlcTag rlcTag;
760 Time delay;
761 NS_ASSERT_MSG (p->PeekPacketTag (rlcTag), "RlcTag is missing")do { if (!(p->PeekPacketTag (rlcTag))) { std::cerr <<
"assert failed. cond=\"" << "p->PeekPacketTag (rlcTag)"
<< "\", "; do { std::cerr << "msg=\"" << "RlcTag is missing"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 761 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
762 p->RemovePacketTag (rlcTag);
763 delay = Simulator::Now() - rlcTag.GetSenderTimestamp ();
764 m_rxPdu (m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds ());
765
766 // Get RLC header parameters
767 LteRlcAmHeader rlcAmHeader;
768 p->PeekHeader (rlcAmHeader);
769 NS_LOG_LOGIC ("RLC header: " << rlcAmHeader)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "RLC header: "
<< rlcAmHeader << std::endl; } } while (false)
;
770
771 if ( rlcAmHeader.IsDataPdu () )
772 {
773
774 // 5.1.3.1 Transmit operations
775
776 // 5.1.3.1.1 General
777 //
778 // The transmitting side of an AM RLC entity shall prioritize transmission of RLC control PDUs
779 // over RLC data PDUs. The transmitting side of an AM RLC entity shall prioritize retransmission
780 // of RLC data PDUs over transmission of new AMD PDUs.
781 //
782 // The transmitting side of an AM RLC entity shall maintain a transmitting window according to
783 // state variables VT(A) and VT(MS) as follows:
784 // - a SN falls within the transmitting window if VT(A) <= SN < VT(MS);
785 // - a SN falls outside of the transmitting window otherwise.
786 //
787 // The transmitting side of an AM RLC entity shall not deliver to lower layer any RLC data PDU
788 // whose SN falls outside of the transmitting window.
789 //
790 // When delivering a new AMD PDU to lower layer, the transmitting side of an AM RLC entity shall:
791 // - set the SN of the AMD PDU to VT(S), and then increment VT(S) by one.
792 //
793 // The transmitting side of an AM RLC entity can receive a positive acknowledgement (confirmation
794 // of successful reception by its peer AM RLC entity) for a RLC data PDU by the following:
795 // - STATUS PDU from its peer AM RLC entity.
796 //
797 // When receiving a positive acknowledgement for an AMD PDU with SN = VT(A), the transmitting
798 // side of an AM RLC entity shall:
799 // - set VT(A) equal to the SN of the AMD PDU with the smallest SN, whose SN falls within the
800 // range VT(A) <= SN <= VT(S) and for which a positive acknowledgment has not been received yet.
801 // - if positive acknowledgements have been received for all AMD PDUs associated with
802 // a transmitted RLC SDU:
803 // - send an indication to the upper layers of successful delivery of the RLC SDU.
804
805
806 // 5.1.3.2 Receive operations
807 //
808 // 5.1.3.2.1 General
809 //
810 // The receiving side of an AM RLC entity shall maintain a receiving window according to state
811 // variables VR(R) and VR(MR) as follows:
812 // - a SN falls within the receiving window if VR(R) <= SN < VR(MR);
813 // - a SN falls outside of the receiving window otherwise.
814 //
815 // When receiving a RLC data PDU from lower layer, the receiving side of an AM RLC entity shall:
816 // - either discard the received RLC data PDU or place it in the reception buffer (see sub clause 5.1.3.2.2);
817 // - if the received RLC data PDU was placed in the reception buffer:
818 // - update state variables, reassemble and deliver RLC SDUs to upper layer and start/stop t-Reordering as needed (see sub clause 5.1.3.2.3).
819 //
820 // When t-Reordering expires, the receiving side of an AM RLC entity shall:
821 // - update state variables and start t-Reordering as needed (see sub clause 5.1.3.2.4).
822
823
824 SequenceNumber10 seqNumber = rlcAmHeader.GetSequenceNumber ();
825 seqNumber.SetModulusBase (m_vrR);
826
827 if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::SEGMENT )
828 {
829 NS_LOG_LOGIC ("PDU segment received ( SN = " << seqNumber << " )")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "PDU segment received ( SN = "
<< seqNumber << " )" << std::endl; } } while
(false)
;
830 }
831 else if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::PDU )
832 {
833 NS_LOG_LOGIC ("PDU received ( SN = " << seqNumber << " )")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "PDU received ( SN = "
<< seqNumber << " )" << std::endl; } } while
(false)
;
834 }
835 else
836 {
837 NS_ASSERT_MSG (false, "Neither a PDU segment nor a PDU received")do { if (!(false)) { std::cerr << "assert failed. cond=\""
<< "false" << "\", "; do { std::cerr << "msg=\""
<< "Neither a PDU segment nor a PDU received" <<
"\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 837 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
838 return ;
839 }
840
841 // STATUS PDU is requested
842 if ( rlcAmHeader.GetPollingBit () == LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED )
843 {
844 m_statusPduRequested = true;
845 m_statusPduBufferSize = 4;
846
847 if (! m_statusProhibitTimer.IsRunning ())
848 {
849 DoReportBufferStatus ();
850 }
851 }
852
853 // 5.1.3.2.2 Actions when a RLC data PDU is received from lower layer
854 //
855 // When a RLC data PDU is received from lower layer, where the RLC data PDU contains
856 // byte segment numbers y to z of an AMD PDU with SN = x, the receiving side of an AM RLC entity shall:
857 // - if x falls outside of the receiving window; or
858 // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
859 // - discard the received RLC data PDU;
860 // - else:
861 // - place the received RLC data PDU in the reception buffer;
862 // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
863 // - discard the duplicate byte segments.
864
865 NS_LOG_LOGIC ("VR(R) = " << m_vrR)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "VR(R) = "
<< m_vrR << std::endl; } } while (false)
;
866 NS_LOG_LOGIC ("VR(MR) = " << m_vrMr)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "VR(MR) = "
<< m_vrMr << std::endl; } } while (false)
;
867 NS_LOG_LOGIC ("VR(X) = " << m_vrX)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "VR(X) = "
<< m_vrX << std::endl; } } while (false)
;
868 NS_LOG_LOGIC ("VR(MS) = " << m_vrMs)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "VR(MS) = "
<< m_vrMs << std::endl; } } while (false)
;
869 NS_LOG_LOGIC ("VR(H) = " << m_vrH)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "VR(H) = "
<< m_vrH << std::endl; } } while (false)
;
870
871 // - if x falls outside of the receiving window; or
872 // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
873 if ( ! IsInsideReceivingWindow (seqNumber) )
874 {
875 NS_LOG_LOGIC ("PDU discarded")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "PDU discarded"
<< std::endl; } } while (false)
;
876 return;
877 }
878 else
879 {
880 // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
881 // - discard the duplicate byte segments.
882 // note: re-segmentation of AMD PDU is currently not supported,
883 // so we just check that the segment was not received before
884 std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
885 if (it != m_rxonBuffer.end () )
886 {
887 NS_ASSERT (it->second.m_byteSegments.size () > 0)do { if (!(it->second.m_byteSegments.size () > 0)) { std
::cerr << "assert failed. cond=\"" << "it->second.m_byteSegments.size () > 0"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 887 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } } while (false)
;
888 NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1, "re-segmentation not supported")do { if (!(it->second.m_byteSegments.size () == 1)) { std::
cerr << "assert failed. cond=\"" << "it->second.m_byteSegments.size () == 1"
<< "\", "; do { std::cerr << "msg=\"" << "re-segmentation not supported"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 888 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
889 NS_LOG_LOGIC ("PDU segment already received, discarded")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "PDU segment already received, discarded"
<< std::endl; } } while (false)
;
890 }
891 else
892 {
893 NS_LOG_LOGIC ("Place PDU in the reception buffer ( SN = " << seqNumber << " )")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Place PDU in the reception buffer ( SN = "
<< seqNumber << " )" << std::endl; } } while
(false)
;
894 m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.push_back (p);
895 m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete = true;
896 }
897
898
899 }
900
901 // 5.1.3.2.3 Actions when a RLC data PDU is placed in the reception buffer
902 // When a RLC data PDU with SN = x is placed in the reception buffer,
903 // the receiving side of an AM RLC entity shall:
904
905 // - if x >= VR(H)
906 // - update VR(H) to x+ 1;
907
908 if ( seqNumber >= m_vrH )
909 {
910 m_vrH = seqNumber + 1;
911 NS_LOG_LOGIC ("New VR(H) = " << m_vrH)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New VR(H) = "
<< m_vrH << std::endl; } } while (false)
;
912 }
913
914 // - if all byte segments of the AMD PDU with SN = VR(MS) are received:
915 // - update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for
916 // which not all byte segments have been received;
917
918 std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
919 if ( it != m_rxonBuffer.end () &&
920 it->second.m_pduComplete )
921 {
922 int firstVrMs = m_vrMs.GetValue ();
923 while ( it != m_rxonBuffer.end () &&
924 it->second.m_pduComplete )
925 {
926 m_vrMs++;
927 it = m_rxonBuffer.find (m_vrMs.GetValue ());
928 NS_LOG_LOGIC ("Incr VR(MS) = " << m_vrMs)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Incr VR(MS) = "
<< m_vrMs << std::endl; } } while (false)
;
929
930 NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in RxonBuffer")do { if (!(firstVrMs != m_vrMs.GetValue ())) { std::cerr <<
"assert failed. cond=\"" << "firstVrMs != m_vrMs.GetValue ()"
<< "\", "; do { std::cerr << "msg=\"" << "Infinite loop in RxonBuffer"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 930 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
931 }
932 NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New VR(MS) = "
<< m_vrMs << std::endl; } } while (false)
;
933 }
934
935 // - if x = VR(R):
936 // - if all byte segments of the AMD PDU with SN = VR(R) are received:
937 // - update VR(R) to the SN of the first AMD PDU with SN > current VR(R) for which not all byte segments have been received;
938 // - update VR(MR) to the updated VR(R) + AM_Window_Size;
939 // - reassemble RLC SDUs from any byte segments of AMD PDUs with SN that falls outside of the receiving window and in-sequence byte segments of the AMD PDU with SN = VR(R), remove RLC headers when doing so and deliver the reassembled RLC SDUs to upper layer in sequence if not delivered before;
940
941 if ( seqNumber == m_vrR )
942 {
943 std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
944 if ( it != m_rxonBuffer.end () &&
945 it->second.m_pduComplete )
946 {
947 it = m_rxonBuffer.find (m_vrR.GetValue ());
948 int firstVrR = m_vrR.GetValue ();
949 while ( it != m_rxonBuffer.end () &&
950 it->second.m_pduComplete )
951 {
952 NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << m_vrR << " )")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Reassemble and Deliver ( SN = "
<< m_vrR << " )" << std::endl; } } while (
false)
;
953 NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1,do { if (!(it->second.m_byteSegments.size () == 1)) { std::
cerr << "assert failed. cond=\"" << "it->second.m_byteSegments.size () == 1"
<< "\", "; do { std::cerr << "msg=\"" << "Too many segments. PDU Reassembly process didn't work"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 954 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
954 "Too many segments. PDU Reassembly process didn't work")do { if (!(it->second.m_byteSegments.size () == 1)) { std::
cerr << "assert failed. cond=\"" << "it->second.m_byteSegments.size () == 1"
<< "\", "; do { std::cerr << "msg=\"" << "Too many segments. PDU Reassembly process didn't work"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 954 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
955 ReassembleAndDeliver (it->second.m_byteSegments.front ());
956 m_rxonBuffer.erase (m_vrR.GetValue ());
957
958 m_vrR++;
959 m_vrR.SetModulusBase (m_vrR);
960 m_vrX.SetModulusBase (m_vrR);
961 m_vrMs.SetModulusBase (m_vrR);
962 m_vrH.SetModulusBase (m_vrR);
963 it = m_rxonBuffer.find (m_vrR.GetValue ());
964
965 NS_ASSERT_MSG (firstVrR != m_vrR.GetValue (), "Infinite loop in RxonBuffer")do { if (!(firstVrR != m_vrR.GetValue ())) { std::cerr <<
"assert failed. cond=\"" << "firstVrR != m_vrR.GetValue ()"
<< "\", "; do { std::cerr << "msg=\"" << "Infinite loop in RxonBuffer"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 965 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
966 }
967 NS_LOG_LOGIC ("New VR(R) = " << m_vrR)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New VR(R) = "
<< m_vrR << std::endl; } } while (false)
;
968 m_vrMr = m_vrR + m_windowSize;
969
970 NS_LOG_LOGIC ("New VR(MR) = " << m_vrMr)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New VR(MR) = "
<< m_vrMr << std::endl; } } while (false)
;
971 }
972
973 }
974
975 // - if t-Reordering is running:
976 // - if VR(X) = VR(R); or
977 // - if VR(X) falls outside of the receiving window and VR(X) is not equal to VR(MR):
978 // - stop and reset t-Reordering;
979
980 if ( m_reorderingTimer.IsRunning () )
981 {
982 NS_LOG_LOGIC ("Reordering timer is running")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Reordering timer is running"
<< std::endl; } } while (false)
;
983 if ( (m_vrX == m_vrR) ||
984 ( (! IsInsideReceivingWindow (m_vrX)) && (m_vrX != m_vrMr) )
985 )
986 {
987 /// \todo stop and reset the t-Reordering
988 NS_LOG_LOGIC ("Stop reordering timer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Stop reordering timer"
<< std::endl; } } while (false)
;
989 m_reorderingTimer.Cancel ();
990 }
991 }
992
993 // - if t-Reordering is not running (includes the case t-Reordering is stopped due to actions above):
994 // - if VR (H) > VR(R):
995 // - start t-Reordering;
996 // - set VR(X) to VR(H).
997
998 if ( ! m_reorderingTimer.IsRunning () )
999 {
1000 NS_LOG_LOGIC ("Reordering timer is not running")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Reordering timer is not running"
<< std::endl; } } while (false)
;
1001 if ( m_vrH > m_vrR )
1002 {
1003 NS_LOG_LOGIC ("Start reordering timer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Start reordering timer"
<< std::endl; } } while (false)
;
1004 m_reorderingTimer = Simulator::Schedule (m_reorderingTimerValue,
1005 &LteRlcAm::ExpireReorderingTimer ,this);
1006 m_vrX = m_vrH;
1007 NS_LOG_LOGIC ("New VR(X) = " << m_vrX)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New VR(X) = "
<< m_vrX << std::endl; } } while (false)
;
1008 }
1009 }
1010 }
1011 else if ( rlcAmHeader.IsControlPdu () )
1012 {
1013 NS_LOG_INFO ("Control AM RLC PDU")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Control AM RLC PDU"
<< std::endl; } } while (false)
;
1014
1015 SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
1016 SequenceNumber10 sn;
1017
1018 NS_LOG_INFO ("ackSn = " << ackSn)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "ackSn = "
<< ackSn << std::endl; } } while (false)
;
1019 NS_LOG_INFO ("VT(A) = " << m_vtA)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "VT(A) = "
<< m_vtA << std::endl; } } while (false)
;
1020 NS_LOG_INFO ("VT(S) = " << m_vtS)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "VT(S) = "
<< m_vtS << std::endl; } } while (false)
;
1021 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "retxBufferSize = "
<< m_retxBufferSize << std::endl; } } while (false
)
;
1022 NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txedBufferSize = "
<< m_txedBufferSize << std::endl; } } while (false
)
;
1023
1024 m_vtA.SetModulusBase (m_vtA);
1025 m_vtS.SetModulusBase (m_vtA);
1026 m_vtMs.SetModulusBase (m_vtA);
1027 ackSn.SetModulusBase (m_vtA);
1028 sn.SetModulusBase (m_vtA);
1029
1030 bool incrementVtA = true;
1031
1032 for (sn = m_vtA; sn < ackSn && sn < m_vtS; sn++)
1033 {
1034 NS_LOG_LOGIC ("sn = " << sn)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "sn = " <<
sn << std::endl; } } while (false)
;
1035
1036 uint16_t seqNumberValue = sn.GetValue ();
1037
1038 if (m_pollRetransmitTimer.IsRunning ()
1039 && (seqNumberValue == m_pollSn.GetValue ()))
1040 {
1041 m_pollRetransmitTimer.Cancel ();
1042 }
1043
1044 if (rlcAmHeader.IsNackPresent (sn))
1045 {
1046 NS_LOG_LOGIC ("sn " << sn << " is NACKed")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "sn " <<
sn << " is NACKed" << std::endl; } } while (false
)
;
1047
1048 incrementVtA = false;
1049
1050 if (m_txedBuffer.at (seqNumberValue).m_pdu != 0)
1051 {
1052 NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Move SN = "
<< seqNumberValue << " to retxBuffer" << std
::endl; } } while (false)
;
1053 m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue).m_pdu->Copy ();
1054 m_retxBuffer.at (seqNumberValue).m_retxCount = m_txedBuffer.at (seqNumberValue).m_retxCount;
1055 m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1056
1057 m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
1058 m_txedBuffer.at (seqNumberValue).m_pdu = 0;
1059 m_txedBuffer.at (seqNumberValue).m_retxCount = 0;
1060 }
1061
1062 NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu != 0)do { if (!(m_retxBuffer.at (seqNumberValue).m_pdu != 0)) { std
::cerr << "assert failed. cond=\"" << "m_retxBuffer.at (seqNumberValue).m_pdu != 0"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 1062 << std::endl; ::ns3::
FatalImpl::FlushStreams (); if (true) std::terminate (); } while
(false); } } while (false)
;
1063
1064 }
1065 else
1066 {
1067 NS_LOG_LOGIC ("sn " << sn << " is ACKed")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "sn " <<
sn << " is ACKed" << std::endl; } } while (false
)
;
1068
1069 if (m_txedBuffer.at (seqNumberValue).m_pdu)
1070 {
1071 NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "ACKed SN = "
<< seqNumberValue << " from txedBuffer" <<
std::endl; } } while (false)
;
1072 // NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
1073 m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
1074 m_txedBuffer.at (seqNumberValue).m_pdu = 0;
1075 NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu == 0)do { if (!(m_retxBuffer.at (seqNumberValue).m_pdu == 0)) { std
::cerr << "assert failed. cond=\"" << "m_retxBuffer.at (seqNumberValue).m_pdu == 0"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 1075 << std::endl; ::ns3::
FatalImpl::FlushStreams (); if (true) std::terminate (); } while
(false); } } while (false)
;
1076 }
1077
1078 if (m_retxBuffer.at (seqNumberValue).m_pdu)
1079 {
1080 NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "ACKed SN = "
<< seqNumberValue << " from retxBuffer" <<
std::endl; } } while (false)
;
1081 m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1082 m_retxBuffer.at (seqNumberValue).m_pdu = 0;
1083 m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
1084 }
1085
1086 }
1087
1088 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "retxBufferSize = "
<< m_retxBufferSize << std::endl; } } while (false
)
;
1089 NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txedBufferSize = "
<< m_txedBufferSize << std::endl; } } while (false
)
;
1090
1091 if (incrementVtA)
1092 {
1093 m_vtA++;
1094 m_vtMs = m_vtA + m_windowSize;
1095 NS_LOG_INFO ("New VT(A) = " << m_vtA)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "New VT(A) = "
<< m_vtA << std::endl; } } while (false)
;
1096 m_vtA.SetModulusBase (m_vtA);
1097 m_vtMs.SetModulusBase (m_vtA);
1098 m_vtS.SetModulusBase (m_vtA);
1099 ackSn.SetModulusBase (m_vtA);
1100 sn.SetModulusBase (m_vtA);
1101 }
1102
1103 } // loop over SN : VT(A) <= SN < ACK SN
1104
1105 return;
1106
1107 }
1108 else
1109 {
1110 NS_LOG_WARN ("Wrong AM RLC PDU type")do { if (g_log.IsEnabled (ns3::LOG_WARN)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_WARN) << "] "; }; std::clog << "Wrong AM RLC PDU type"
<< std::endl; } } while (false)
;
1111 return;
1112 }
1113
1114}
1115
1116
1117bool
1118LteRlcAm::IsInsideReceivingWindow (SequenceNumber10 seqNumber)
1119{
1120 NS_LOG_FUNCTION (this << seqNumber)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this << seqNumber; std::clog << ")" << std
::endl; } } while (false)
;
1121 NS_LOG_LOGIC ("Receiving Window: " <<do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Receiving Window: "
<< m_vrR << " <= " << seqNumber <<
" <= " << m_vrMr << std::endl; } } while (false
)
1122 m_vrR << " <= " << seqNumber << " <= " << m_vrMr)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Receiving Window: "
<< m_vrR << " <= " << seqNumber <<
" <= " << m_vrMr << std::endl; } } while (false
)
;
1123
1124 m_vrR.SetModulusBase (m_vrR);
1125 m_vrMr.SetModulusBase (m_vrR);
1126 seqNumber.SetModulusBase (m_vrR);
1127
1128 if ( (m_vrR <= seqNumber) && (seqNumber < m_vrMr ) )
1129 {
1130 NS_LOG_LOGIC (seqNumber << " is INSIDE the receiving window")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << seqNumber <<
" is INSIDE the receiving window" << std::endl; } } while
(false)
;
1131 return true;
1132 }
1133 else
1134 {
1135 NS_LOG_LOGIC (seqNumber << " is OUTSIDE the receiving window")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << seqNumber <<
" is OUTSIDE the receiving window" << std::endl; } } while
(false)
;
1136 return false;
1137 }
1138}
1139
1140
1141void
1142LteRlcAm::ReassembleAndDeliver (Ptr<Packet> packet)
1143{
1144 LteRlcAmHeader rlcAmHeader;
1145 packet->RemoveHeader (rlcAmHeader);
1146 uint8_t framingInfo = rlcAmHeader.GetFramingInfo ();
1147 SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber ();
1148 bool expectedSnLost;
1149
1150 if ( currSeqNumber != m_expectedSeqNumber )
1151 {
1152 expectedSnLost = true;
1153 NS_LOG_LOGIC ("There are losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "There are losses. Expected SN = "
<< m_expectedSeqNumber << ". Current SN = " <<
currSeqNumber << std::endl; } } while (false)
;
1154 m_expectedSeqNumber = currSeqNumber + 1;
1155 }
1156 else
1157 {
1158 expectedSnLost = false;
1159 NS_LOG_LOGIC ("No losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "No losses. Expected SN = "
<< m_expectedSeqNumber << ". Current SN = " <<
currSeqNumber << std::endl; } } while (false)
;
1160 m_expectedSeqNumber = m_expectedSeqNumber + 1;
1161 }
1162
1163 // Build list of SDUs
1164 uint8_t extensionBit;
1165 uint16_t lengthIndicator;
1166 do
1167 {
1168 extensionBit = rlcAmHeader.PopExtensionBit ();
1169 NS_LOG_LOGIC ("E = " << (uint16_t)extensionBit)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "E = " <<
(uint16_t)extensionBit << std::endl; } } while (false)
;
1170
1171 if ( extensionBit == 0 )
1172 {
1173 m_sdusBuffer.push_back (packet);
1174 }
1175 else // extensionBit == 1
1176 {
1177 lengthIndicator = rlcAmHeader.PopLengthIndicator ();
1178 NS_LOG_LOGIC ("LI = " << lengthIndicator)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "LI = " <<
lengthIndicator << std::endl; } } while (false)
;
1179
1180 // Check if there is enough data in the packet
1181 if ( lengthIndicator >= packet->GetSize () )
1182 {
1183 NS_LOG_LOGIC ("INTERNAL ERROR: Not enough data in the packet (" << packet->GetSize () << "). Needed LI=" << lengthIndicator)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "INTERNAL ERROR: Not enough data in the packet ("
<< packet->GetSize () << "). Needed LI=" <<
lengthIndicator << std::endl; } } while (false)
;
1184 /// \todo What to do in this case? Discard packet and continue? Or Assert?
1185 }
1186
1187 // Split packet in two fragments
1188 Ptr<Packet> data_field = packet->CreateFragment (0, lengthIndicator);
1189 packet->RemoveAtStart (lengthIndicator);
1190
1191 m_sdusBuffer.push_back (data_field);
1192 }
1193 }
1194 while ( extensionBit == 1 );
1195
1196 std::list < Ptr<Packet> >::iterator it;
1197
1198 // Current reassembling state
1199 if (m_reassemblingState == WAITING_S0_FULL) NS_LOG_LOGIC ("Reassembling State = 'WAITING_S0_FULL'")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Reassembling State = 'WAITING_S0_FULL'"
<< std::endl; } } while (false)
;
1200 else if (m_reassemblingState == WAITING_SI_SF) NS_LOG_LOGIC ("Reassembling State = 'WAITING_SI_SF'")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Reassembling State = 'WAITING_SI_SF'"
<< std::endl; } } while (false)
;
1201 else NS_LOG_LOGIC ("Reassembling State = Unknown state")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Reassembling State = Unknown state"
<< std::endl; } } while (false)
;
1202
1203 // Received framing Info
1204 NS_LOG_LOGIC ("Framing Info = " << (uint16_t)framingInfo)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Framing Info = "
<< (uint16_t)framingInfo << std::endl; } } while
(false)
;
1205 NS_LOG_LOGIC ("m_sdusBuffer = " << m_sdusBuffer.size ())do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "m_sdusBuffer = "
<< m_sdusBuffer.size () << std::endl; } } while (
false)
;
1206
1207 // Reassemble the list of SDUs (when there is no losses)
1208 if (!expectedSnLost)
1209 {
1210 switch (m_reassemblingState)
1211 {
1212 case WAITING_S0_FULL:
1213 switch (framingInfo)
1214 {
1215 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1216 m_reassemblingState = WAITING_S0_FULL;
1217
1218 /**
1219 * Deliver one or multiple PDUs
1220 */
1221 for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1222 {
1223 m_rlcSapUser->ReceivePdcpPdu (*it);
1224 }
1225 m_sdusBuffer.clear ();
1226 break;
1227
1228 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1229 m_reassemblingState = WAITING_SI_SF;
1230
1231 /**
1232 * Deliver full PDUs
1233 */
1234 while ( m_sdusBuffer.size () > 1 )
1235 {
1236 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1237 m_sdusBuffer.pop_front ();
1238 }
1239
1240 /**
1241 * Keep S0
1242 */
1243 m_keepS0 = m_sdusBuffer.front ();
1244 m_sdusBuffer.pop_front ();
1245 break;
1246
1247 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1248 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1249 default:
1250 /**
1251 * ERROR: Transition not possible
1252 */
1253 NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "INTERNAL ERROR: Transition not possible. FI = "
<< (uint32_t) framingInfo << std::endl; } } while
(false)
;
1254 break;
1255 }
1256 break;
1257
1258 case WAITING_SI_SF:
1259 switch (framingInfo)
1260 {
1261 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1262 m_reassemblingState = WAITING_S0_FULL;
1263
1264 /**
1265 * Deliver (Kept)S0 + SN
1266 */
1267 m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1268 m_sdusBuffer.pop_front ();
1269 m_rlcSapUser->ReceivePdcpPdu (m_keepS0);
1270
1271 /**
1272 * Deliver zero, one or multiple PDUs
1273 */
1274 while ( ! m_sdusBuffer.empty () )
1275 {
1276 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1277 m_sdusBuffer.pop_front ();
1278 }
1279 break;
1280
1281 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1282 m_reassemblingState = WAITING_SI_SF;
1283
1284 /**
1285 * Keep SI
1286 */
1287 if ( m_sdusBuffer.size () == 1 )
1288 {
1289 m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1290 m_sdusBuffer.pop_front ();
1291 }
1292 else // m_sdusBuffer.size () > 1
1293 {
1294 /**
1295 * Deliver (Kept)S0 + SN
1296 */
1297 m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1298 m_sdusBuffer.pop_front ();
1299 m_rlcSapUser->ReceivePdcpPdu (m_keepS0);
1300
1301 /**
1302 * Deliver zero, one or multiple PDUs
1303 */
1304 while ( m_sdusBuffer.size () > 1 )
1305 {
1306 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1307 m_sdusBuffer.pop_front ();
1308 }
1309
1310 /**
1311 * Keep S0
1312 */
1313 m_keepS0 = m_sdusBuffer.front ();
1314 m_sdusBuffer.pop_front ();
1315 }
1316 break;
1317
1318 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1319 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1320 default:
1321 /**
1322 * ERROR: Transition not possible
1323 */
1324 NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "INTERNAL ERROR: Transition not possible. FI = "
<< (uint32_t) framingInfo << std::endl; } } while
(false)
;
1325 break;
1326 }
1327 break;
1328
1329 default:
1330 NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "INTERNAL ERROR: Wrong reassembling state = "
<< (uint32_t) m_reassemblingState << std::endl; }
} while (false)
;
1331 break;
1332 }
1333 }
1334 else // Reassemble the list of SDUs (when there are losses, i.e. the received SN is not the expected one)
1335 {
1336 switch (m_reassemblingState)
1337 {
1338 case WAITING_S0_FULL:
1339 switch (framingInfo)
1340 {
1341 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1342 m_reassemblingState = WAITING_S0_FULL;
1343
1344 /**
1345 * Deliver one or multiple PDUs
1346 */
1347 for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1348 {
1349 m_rlcSapUser->ReceivePdcpPdu (*it);
1350 }
1351 m_sdusBuffer.clear ();
1352 break;
1353
1354 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1355 m_reassemblingState = WAITING_SI_SF;
1356
1357 /**
1358 * Deliver full PDUs
1359 */
1360 while ( m_sdusBuffer.size () > 1 )
1361 {
1362 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1363 m_sdusBuffer.pop_front ();
1364 }
1365
1366 /**
1367 * Keep S0
1368 */
1369 m_keepS0 = m_sdusBuffer.front ();
1370 m_sdusBuffer.pop_front ();
1371 break;
1372
1373 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1374 m_reassemblingState = WAITING_S0_FULL;
1375
1376 /**
1377 * Discard SN
1378 */
1379 m_sdusBuffer.pop_front ();
1380
1381 /**
1382 * Deliver zero, one or multiple PDUs
1383 */
1384 while ( ! m_sdusBuffer.empty () )
1385 {
1386 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1387 m_sdusBuffer.pop_front ();
1388 }
1389 break;
1390
1391 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1392 if ( m_sdusBuffer.size () == 1 )
1393 {
1394 m_reassemblingState = WAITING_S0_FULL;
1395 }
1396 else
1397 {
1398 m_reassemblingState = WAITING_SI_SF;
1399 }
1400
1401 /**
1402 * Discard SI or SN
1403 */
1404 m_sdusBuffer.pop_front ();
1405
1406 if ( m_sdusBuffer.size () > 0 )
1407 {
1408 /**
1409 * Deliver zero, one or multiple PDUs
1410 */
1411 while ( m_sdusBuffer.size () > 1 )
1412 {
1413 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1414 m_sdusBuffer.pop_front ();
1415 }
1416
1417 /**
1418 * Keep S0
1419 */
1420 m_keepS0 = m_sdusBuffer.front ();
1421 m_sdusBuffer.pop_front ();
1422 }
1423 break;
1424
1425 default:
1426 /**
1427 * ERROR: Transition not possible
1428 */
1429 NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "INTERNAL ERROR: Transition not possible. FI = "
<< (uint32_t) framingInfo << std::endl; } } while
(false)
;
1430 break;
1431 }
1432 break;
1433
1434 case WAITING_SI_SF:
1435 switch (framingInfo)
1436 {
1437 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1438 m_reassemblingState = WAITING_S0_FULL;
1439
1440 /**
1441 * Discard S0
1442 */
1443 m_keepS0 = 0;
1444
1445 /**
1446 * Deliver one or multiple PDUs
1447 */
1448 while ( ! m_sdusBuffer.empty () )
1449 {
1450 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1451 m_sdusBuffer.pop_front ();
1452 }
1453 break;
1454
1455 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1456 m_reassemblingState = WAITING_SI_SF;
1457
1458 /**
1459 * Discard S0
1460 */
1461 m_keepS0 = 0;
1462
1463 /**
1464 * Deliver zero, one or multiple PDUs
1465 */
1466 while ( m_sdusBuffer.size () > 1 )
1467 {
1468 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1469 m_sdusBuffer.pop_front ();
1470 }
1471
1472 /**
1473 * Keep S0
1474 */
1475 m_keepS0 = m_sdusBuffer.front ();
1476 m_sdusBuffer.pop_front ();
1477
1478 break;
1479
1480 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1481 m_reassemblingState = WAITING_S0_FULL;
1482
1483 /**
1484 * Discard S0
1485 */
1486 m_keepS0 = 0;
1487
1488 /**
1489 * Discard SI or SN
1490 */
1491 m_sdusBuffer.pop_front ();
1492
1493 /**
1494 * Deliver zero, one or multiple PDUs
1495 */
1496 while ( ! m_sdusBuffer.empty () )
1497 {
1498 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1499 m_sdusBuffer.pop_front ();
1500 }
1501 break;
1502
1503 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1504 if ( m_sdusBuffer.size () == 1 )
1505 {
1506 m_reassemblingState = WAITING_S0_FULL;
1507 }
1508 else
1509 {
1510 m_reassemblingState = WAITING_SI_SF;
1511 }
1512
1513 /**
1514 * Discard S0
1515 */
1516 m_keepS0 = 0;
1517
1518 /**
1519 * Discard SI or SN
1520 */
1521 m_sdusBuffer.pop_front ();
1522
1523 if ( m_sdusBuffer.size () > 0 )
1524 {
1525 /**
1526 * Deliver zero, one or multiple PDUs
1527 */
1528 while ( m_sdusBuffer.size () > 1 )
1529 {
1530 m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1531 m_sdusBuffer.pop_front ();
1532 }
1533
1534 /**
1535 * Keep S0
1536 */
1537 m_keepS0 = m_sdusBuffer.front ();
1538 m_sdusBuffer.pop_front ();
1539 }
1540 break;
1541
1542 default:
1543 /**
1544 * ERROR: Transition not possible
1545 */
1546 NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "INTERNAL ERROR: Transition not possible. FI = "
<< (uint32_t) framingInfo << std::endl; } } while
(false)
;
1547 break;
1548 }
1549 break;
1550
1551 default:
1552 NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "INTERNAL ERROR: Wrong reassembling state = "
<< (uint32_t) m_reassemblingState << std::endl; }
} while (false)
;
1553 break;
1554 }
1555 }
1556
1557}
1558
1559void
1560LteRlcAm::DoReportBufferStatus (void)
1561{
1562 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
1563
1564 Time now = Simulator::Now ();
1565
1566 NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txonBufferSize = "
<< m_txonBufferSize << std::endl; } } while (false
)
;
1567 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "retxBufferSize = "
<< m_retxBufferSize << std::endl; } } while (false
)
;
1568 NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txedBufferSize = "
<< m_txedBufferSize << std::endl; } } while (false
)
;
1569 NS_LOG_LOGIC ("VT(A) = " << m_vtA)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "VT(A) = " <<
m_vtA << std::endl; } } while (false)
;
1570 NS_LOG_LOGIC ("VT(S) = " << m_vtS)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "VT(S) = " <<
m_vtS << std::endl; } } while (false)
;
1571
1572 // Transmission Queue HOL time
1573 Time txonQueueHolDelay (0);
1574 if ( m_txonBufferSize > 0 )
1575 {
1576 RlcTag txonQueueHolTimeTag;
1577 m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
1578 txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp ();
1579 }
1580
1581 // Retransmission Queue HOL time
1582 Time retxQueueHolDelay;
1583 RlcTag retxQueueHolTimeTag;
1584 if ( m_retxBufferSize > 0 )
1585 {
1586 if (m_retxBuffer.at (m_vtA.GetValue ()).m_pdu != 0)
1587 {
1588 m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->PeekPacketTag (retxQueueHolTimeTag);
1589 }
1590 else
1591 {
1592 m_txedBuffer.at (m_vtA.GetValue ()).m_pdu->PeekPacketTag (retxQueueHolTimeTag);
1593 }
1594 retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
1595 }
1596 else
1597 {
1598 retxQueueHolDelay = Seconds (0);
1599 }
1600
1601 LteMacSapProvider::ReportBufferStatusParameters r;
1602 r.rnti = m_rnti;
1603 r.lcid = m_lcid;
1604 r.txQueueSize = m_txonBufferSize;
1605 r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
1606 r.retxQueueSize = m_retxBufferSize + m_txedBufferSize;
1607 r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
1608
1609 if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
1610 {
1611 r.statusPduSize = m_statusPduBufferSize;
1612 }
1613 else
1614 {
1615 r.statusPduSize = 0;
1616 }
1617
1618 if ( r.txQueueSize != 0 || r.retxQueueSize != 0 || r.statusPduSize != 0 )
1619 {
1620 NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Send ReportBufferStatus: "
<< r.txQueueSize << ", " << r.txQueueHolDelay
<< ", " << r.retxQueueSize << ", " <<
r.retxQueueHolDelay << ", " << r.statusPduSize <<
std::endl; } } while (false)
1621 << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Send ReportBufferStatus: "
<< r.txQueueSize << ", " << r.txQueueHolDelay
<< ", " << r.retxQueueSize << ", " <<
r.retxQueueHolDelay << ", " << r.statusPduSize <<
std::endl; } } while (false)
1622 << r.statusPduSize)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Send ReportBufferStatus: "
<< r.txQueueSize << ", " << r.txQueueHolDelay
<< ", " << r.retxQueueSize << ", " <<
r.retxQueueHolDelay << ", " << r.statusPduSize <<
std::endl; } } while (false)
;
1623 m_macSapProvider->ReportBufferStatus (r);
1624 }
1625 else
1626 {
1627 NS_LOG_INFO ("ReportBufferStatus don't needed")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "ReportBufferStatus don't needed"
<< std::endl; } } while (false)
;
1628 }
1629}
1630
1631
1632void
1633LteRlcAm::ExpireReorderingTimer (void)
1634{
1635 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
1636 NS_LOG_LOGIC ("Reordering Timer has expired")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Reordering Timer has expired"
<< std::endl; } } while (false)
;
1637
1638 // 5.1.3.2.4 Actions when t-Reordering expires
1639 // When t-Reordering expires, the receiving side of an AM RLC entity shall:
1640 // - update VR(MS) to the SN of the first AMD PDU with SN >= VR(X) for which not all byte segments
1641 // have been received;
1642 // - if VR(H) > VR(MS):
1643 // - start t-Reordering;
1644 // - set VR(X) to VR(H).
1645
1646 m_vrMs = m_vrX;
1647 int firstVrMs = m_vrMs.GetValue ();
1648 std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
1649 while ( it != m_rxonBuffer.end () &&
1650 it->second.m_pduComplete )
1651 {
1652 m_vrMs++;
1653 it = m_rxonBuffer.find (m_vrMs.GetValue ());
1654
1655 NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in ExpireReorderingTimer")do { if (!(firstVrMs != m_vrMs.GetValue ())) { std::cerr <<
"assert failed. cond=\"" << "firstVrMs != m_vrMs.GetValue ()"
<< "\", "; do { std::cerr << "msg=\"" << "Infinite loop in ExpireReorderingTimer"
<< "\", "; do { std::cerr << "file=" << "../src/lte/model/lte-rlc-am.cc"
<< ", line=" << 1655 << std::endl; ::ns3::
FatalImpl::FlushStreams (); if (true) std::terminate (); } while
(false); } while (false); } } while (false)
;
1656 }
1657 NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New VR(MS) = "
<< m_vrMs << std::endl; } } while (false)
;
1658
1659 if ( m_vrH > m_vrMs )
1660 {
1661 NS_LOG_LOGIC ("Start reordering timer")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "Start reordering timer"
<< std::endl; } } while (false)
;
1662 m_reorderingTimer = Simulator::Schedule (m_reorderingTimerValue,
1663 &LteRlcAm::ExpireReorderingTimer ,this);
1664 m_vrX = m_vrH;
1665 NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "New VR(MS) = "
<< m_vrMs << std::endl; } } while (false)
;
1666 }
1667
1668 // Section 5.2.3 Status Reporting:
1669 // - The receiving side of an AM RLC entity shall trigger a
1670 // STATUS report when T_reordering expires.
1671 m_statusPduRequested = true;
1672}
1673
1674void
1675LteRlcAm::ExpirePollRetransmitTimer (void)
1676{
1677 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
1678 NS_LOG_LOGIC ("PollRetransmit Timer has expired")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "PollRetransmit Timer has expired"
<< std::endl; } } while (false)
;
1679
1680 NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txonBufferSize = "
<< m_txonBufferSize << std::endl; } } while (false
)
;
1681 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "retxBufferSize = "
<< m_retxBufferSize << std::endl; } } while (false
)
;
1682 NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "txedBufferSize = "
<< m_txedBufferSize << std::endl; } } while (false
)
;
1683 NS_LOG_LOGIC ("statusPduRequested = " << m_statusPduRequested)do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "statusPduRequested = "
<< m_statusPduRequested << std::endl; } } while (
false)
;
1684
1685 m_pollRetransmitTimerJustExpired = true;
1686
1687 // see section 5.2.2.3
1688 // note the difference between Rel 8 and Rel 11 specs; we follow Rel 11 here
1689 NS_ASSERT (m_vtS <= m_vtMs)do { if (!(m_vtS <= m_vtMs)) { std::cerr << "assert failed. cond=\""
<< "m_vtS <= m_vtMs" << "\", "; do { std::cerr
<< "file=" << "../src/lte/model/lte-rlc-am.cc" <<
", line=" << 1689 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } } while (false)
;
1690 if ((m_txonBufferSize == 0 && m_retxBufferSize == 0)
1691 || (m_vtS == m_vtMs))
1692 {
1693 NS_LOG_INFO ("txonBuffer and retxBuffer empty. Move PDUs up to = " << m_vtS.GetValue () - 1 << " to retxBuffer")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "txonBuffer and retxBuffer empty. Move PDUs up to = "
<< m_vtS.GetValue () - 1 << " to retxBuffer" <<
std::endl; } } while (false)
;
1694 uint16_t sn = 0;
1695 for ( sn = m_vtA.GetValue(); sn < m_vtS.GetValue (); sn++ )
1696 {
1697 bool pduAvailable = m_txedBuffer.at (sn).m_pdu != 0;
1698
1699 if ( pduAvailable )
1700 {
1701 NS_LOG_INFO ("Move PDU " << sn << " from txedBuffer to retxBuffer")do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "Move PDU " <<
sn << " from txedBuffer to retxBuffer" << std::endl
; } } while (false)
;
1702 m_retxBuffer.at (sn).m_pdu = m_txedBuffer.at (sn).m_pdu->Copy ();
1703 m_retxBuffer.at (sn).m_retxCount = m_txedBuffer.at (sn).m_retxCount;
1704 m_retxBufferSize += m_retxBuffer.at (sn).m_pdu->GetSize ();
1705
1706 m_txedBufferSize -= m_txedBuffer.at (sn).m_pdu->GetSize ();
1707 m_txedBuffer.at (sn).m_pdu = 0;
1708 m_txedBuffer.at (sn).m_retxCount = 0;
1709 }
1710 }
1711 }
1712
1713 DoReportBufferStatus ();
1714}
1715
1716
1717void
1718LteRlcAm::ExpireStatusProhibitTimer (void)
1719{
1720 NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this; std::clog << ")" << std::endl; } } while (
false)
;
1721}
1722
1723void
1724LteRlcAm::ExpireRbsTimer (void)
1725{
1726 NS_LOG_LOGIC ("RBS Timer expires")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_LOGIC) << "] "; }; std::clog << "RBS Timer expires"
<< std::endl; } } while (false)
;
1727
1728 if (m_txonBufferSize + m_txedBufferSize + m_retxBufferSize > 0)
1729 {
1730 DoReportBufferStatus ();
1731 m_rbsTimer = Simulator::Schedule (m_rbsTimerValue, &LteRlcAm::ExpireRbsTimer, this);
1732 }
1733}
1734
1735} // namespace ns3