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 |
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 | |
31 | namespace ns3 { |
32 | |
33 | NS_LOG_COMPONENT_DEFINE ("LteRlcAm")static ns3::LogComponent g_log = ns3::LogComponent ("LteRlcAm" , "../src/lte/model/lte-rlc-am.cc"); |
34 | |
35 | NS_OBJECT_ENSURE_REGISTERED (LteRlcAm)static struct ObjectLteRlcAmRegistrationClass { ObjectLteRlcAmRegistrationClass () { ns3::TypeId tid = LteRlcAm::GetTypeId (); tid.SetSize ( sizeof (LteRlcAm)); tid.GetParent (); } } ObjectLteRlcAmRegistrationVariable; |
36 | |
37 | |
38 | LteRlcAm::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 | |
82 | LteRlcAm::~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 | |
87 | TypeId |
88 | LteRlcAm::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 | |
127 | void |
128 | LteRlcAm::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 | |
155 | void |
156 | LteRlcAm::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 | |
188 | void |
189 | LteRlcAm::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 | |
746 | void |
747 | LteRlcAm::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 | |
753 | void |
754 | LteRlcAm::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 | |
1117 | bool |
1118 | LteRlcAm::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 | |
1141 | void |
1142 | LteRlcAm::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 | |
1559 | void |
1560 | LteRlcAm::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 | |
1632 | void |
1633 | LteRlcAm::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 | |
1674 | void |
1675 | LteRlcAm::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 | |
1717 | void |
1718 | LteRlcAm::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 | |
1723 | void |
1724 | LteRlcAm::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 |