5G-LENA nr-v3.3-161-gad18933f
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-test-notching.cc
Go to the documentation of this file.
1// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "ns3/beam-id.h"
6#include "ns3/node.h"
7#include "ns3/nr-control-messages.h"
8#include "ns3/nr-gnb-mac.h"
9#include "ns3/nr-mac-sched-sap.h"
10#include "ns3/nr-mac-scheduler-ns3.h"
11#include "ns3/nr-phy-sap.h"
12#include "ns3/object-factory.h"
13#include "ns3/test.h"
14
15#include <algorithm>
16
29namespace ns3
30{
31
32class TestNotchingPhySapProvider : public NrPhySapProvider
33{
34 public:
35 TestNotchingPhySapProvider();
36 ~TestNotchingPhySapProvider() override;
37 uint32_t GetSymbolsPerSlot() const override;
38 Ptr<const SpectrumModel> GetSpectrumModel() override;
39 uint16_t GetBwpId() const override;
40 uint16_t GetCellId() const override;
41 Time GetSlotPeriod() const override;
42 void SendMacPdu(const Ptr<Packet>& p,
43 const SfnSf& sfn,
44 uint8_t symStart,
45 uint16_t rnti) override;
46 void SendControlMessage(Ptr<NrControlMessage> msg) override;
47 void SendRachPreamble(uint8_t PreambleId, uint8_t Rnti) override;
48 void SetSlotAllocInfo(const SlotAllocInfo& slotAllocInfo) override;
49 void NotifyConnectionSuccessful() override;
50 uint32_t GetRbNum() const override;
51 BeamId GetBeamId(uint8_t rnti) const override;
52 void SetParams(uint32_t numOfUesPerBeam, uint32_t numOfBeams);
53
54 private:
55 uint32_t m_sapNumOfUesPerBeam = 0;
56 uint32_t m_sapNumOfBeams = 0;
57};
58
59TestNotchingPhySapProvider::TestNotchingPhySapProvider()
60{
61}
62
63TestNotchingPhySapProvider::~TestNotchingPhySapProvider()
64{
65}
66
67void
68TestNotchingPhySapProvider::SetParams(uint32_t numOfUesPerBeam, uint32_t numOfBeams)
69{
70 m_sapNumOfUesPerBeam = numOfUesPerBeam;
71 m_sapNumOfBeams = numOfBeams;
72}
73
74uint32_t
75TestNotchingPhySapProvider::GetSymbolsPerSlot() const
76{
77 // Fixed 14 symbols per slot.
78 return 14;
79}
80
81Ptr<const SpectrumModel>
82TestNotchingPhySapProvider::GetSpectrumModel()
83{
84 return nullptr;
85}
86
87uint16_t
88TestNotchingPhySapProvider::GetBwpId() const
89{
90 return 0;
91}
92
93uint16_t
94TestNotchingPhySapProvider::GetCellId() const
95{
96 return 0;
97}
98
99Time
100TestNotchingPhySapProvider::GetSlotPeriod() const
101{
102 return MilliSeconds(1);
103}
104
105void
106TestNotchingPhySapProvider::SendMacPdu(const Ptr<Packet>& p,
107 const SfnSf& sfn,
108 uint8_t symStart,
109 uint16_t rnti)
110{
111}
112
113void
114TestNotchingPhySapProvider::SendControlMessage(Ptr<NrControlMessage> msg)
115{
116}
117
118void
119TestNotchingPhySapProvider::SendRachPreamble(uint8_t PreambleId, uint8_t Rnti)
120{
121}
122
123void
124TestNotchingPhySapProvider::SetSlotAllocInfo(const SlotAllocInfo& slotAllocInfo)
125{
126}
127
128void
129TestNotchingPhySapProvider::NotifyConnectionSuccessful()
130{
131}
132
133uint32_t
134TestNotchingPhySapProvider::GetRbNum() const
135{
136 // If in the future the scheduler calls this method, remove this assert"
137 NS_FATAL_ERROR("GetRbNum should not be called");
138 return 53;
139}
140
141BeamId
142TestNotchingPhySapProvider::GetBeamId(uint8_t rnti) const
143{
144 BeamId beamId = BeamId(0, 0.0);
145 uint8_t rntiCnt = 1;
146 for (uint32_t beam = 0; beam < m_sapNumOfUesPerBeam; beam++)
147 {
148 for (uint32_t u = 0; u < m_sapNumOfBeams; u++)
149 {
150 if (rnti == 0 || (rntiCnt == rnti && beam == 0))
151 {
152 beamId = BeamId(0, 0.0);
153 }
154 else if (rntiCnt == rnti && beam == 1)
155 {
156 beamId = BeamId(1, 120.0);
157 }
158 rntiCnt++;
159 }
160 }
161 return beamId;
162}
163
164class TestNotchingGnbMac : public NrGnbMac
165{
166 public:
167 static TypeId GetTypeId();
168 TestNotchingGnbMac(const std::vector<bool>& inputMask);
169 ~TestNotchingGnbMac() override;
170 void DoSchedConfigIndication(NrMacSchedSapUser::SchedConfigIndParameters ind) override;
171 void SetVerbose(bool verbose);
172
173 private:
174 std::vector<bool> m_inputMask;
175 bool m_verboseMac = false;
176};
177
178NS_OBJECT_ENSURE_REGISTERED(TestNotchingGnbMac);
179
180TypeId
181TestNotchingGnbMac::GetTypeId()
182{
183 static TypeId tid = TypeId("ns3::TestNotchingGnbMac").SetParent<NrGnbMac>()
184 //.AddConstructor<TestNotchingGnbMac> ()
185 ;
186 return tid;
187}
188
189TestNotchingGnbMac::TestNotchingGnbMac(const std::vector<bool>& inputMask)
190{
191 m_inputMask = inputMask;
192}
193
194TestNotchingGnbMac::~TestNotchingGnbMac()
195{
196}
197
198void
199TestNotchingGnbMac::SetVerbose(bool verbose)
200{
201 m_verboseMac = verbose;
202}
203
204void
205TestNotchingGnbMac::DoSchedConfigIndication(NrMacSchedSapUser::SchedConfigIndParameters ind)
206{
207 // Check that the allocations in `ind` have the correct RBG mask
208 // Will be called after SchedDlTriggerReq is called
209 // test that ind.m_slotAllocInfo is ok: the sfnf, and the varAlloc deque
210
211 for (auto& varTtiAllocInfo : ind.m_slotAllocInfo.m_varTtiAllocInfo)
212 {
213 if (varTtiAllocInfo.m_dci->m_rnti == 0)
214 {
215 continue;
216 }
217
218 if (m_verboseMac)
219 {
220 std::ostringstream oss;
221 for (auto x : varTtiAllocInfo.m_dci->m_rbgBitmask)
222 {
223 oss << std::to_string(x) << " ";
224 }
225
226 std::cout << "UE " << varTtiAllocInfo.m_dci->m_rnti << " assigned RBG"
227 << " with mask: " << oss.str() << std::endl;
228 }
229
230 NS_ASSERT_MSG(varTtiAllocInfo.m_dci->m_rbgBitmask.size() == m_inputMask.size(),
231 "dci bitmask is not of same size as the mask");
232
233 unsigned zeroes = std::count(varTtiAllocInfo.m_dci->m_rbgBitmask.begin(),
234 varTtiAllocInfo.m_dci->m_rbgBitmask.end(),
235 0);
236
237 NS_ASSERT_MSG(zeroes != m_inputMask.size(), "dci rbgBitmask is filled with zeros");
238
239 for (unsigned index = 0; index < varTtiAllocInfo.m_dci->m_rbgBitmask.size(); index++)
240 {
241 if (m_inputMask[index] == 0)
242 {
243 NS_ASSERT_MSG(varTtiAllocInfo.m_dci->m_rbgBitmask[index] == 0,
244 "dci is diff from mask");
245 }
246 }
247 }
248}
249
253class NrNotchingTestCase : public TestCase
254{
255 public:
264 NrNotchingTestCase(const std::string& name,
265 const std::vector<bool>& mask,
266 const std::string& schedulerType,
267 uint32_t numOfUesPerBeam,
268 uint32_t beamsNum)
269 : TestCase(name),
270 m_mask(mask),
271 m_schedulerType(schedulerType),
272 m_numOfUesPerBeam(numOfUesPerBeam),
273 m_beamsNum(beamsNum)
274 {
275 }
276
277 ~NrNotchingTestCase() override;
278
279 private:
280 void DoRun() override;
281 Ptr<NrMacSchedulerNs3> CreateScheduler(const std::string& schedulerType) const;
282 Ptr<TestNotchingGnbMac> CreateMac(
283 Ptr<NrMacSchedulerNs3>& scheduler,
284 NrMacCschedSapProvider::CschedCellConfigReqParameters& params) const;
285
286 bool m_verbose = false;
287 const std::vector<bool> m_mask;
288 const std::string m_schedulerType;
289 uint32_t m_numOfUesPerBeam;
290 uint32_t m_beamsNum;
291 TestNotchingPhySapProvider* m_phySapProvider;
292};
293
294NrNotchingTestCase::~NrNotchingTestCase()
295{
296}
297
298Ptr<NrMacSchedulerNs3>
299NrNotchingTestCase::CreateScheduler(const std::string& schedulerType) const
300{
301 ObjectFactory schedFactory;
302 schedFactory.SetTypeId(schedulerType);
303 Ptr<NrMacSchedulerNs3> sched = DynamicCast<NrMacSchedulerNs3>(schedFactory.Create());
304 NS_ABORT_MSG_IF(sched == nullptr,
305 "Can't create a NrMacSchedulerNs3 from type " + schedulerType);
306
307 return sched;
308}
309
310Ptr<TestNotchingGnbMac>
311NrNotchingTestCase::CreateMac(Ptr<NrMacSchedulerNs3>& scheduler,
312 NrMacCschedSapProvider::CschedCellConfigReqParameters& params) const
313{
314 Ptr<TestNotchingGnbMac> mac = CreateObject<TestNotchingGnbMac>(m_mask);
315
316 mac->SetNrMacSchedSapProvider(scheduler->GetMacSchedSapProvider());
317 mac->SetNrMacCschedSapProvider(scheduler->GetMacCschedSapProvider());
318 scheduler->SetMacSchedSapUser(mac->GetNrMacSchedSapUser());
319 scheduler->SetMacCschedSapUser(mac->GetNrMacCschedSapUser());
320 scheduler->SetDlNotchedRbgMask(m_mask);
321 scheduler->SetUlNotchedRbgMask(m_mask);
322 // Config sched
323 scheduler->DoCschedCellConfigReq(params);
324
325 return mac;
326}
327
328void
329NrNotchingTestCase::DoRun()
330{
331 NrMacCschedSapProvider::CschedCellConfigReqParameters params;
332 params.m_ulBandwidth = m_mask.size();
333 params.m_dlBandwidth = m_mask.size();
334
335 auto sched = CreateScheduler(m_schedulerType);
336 auto mac = CreateMac(sched, params);
337
338 m_phySapProvider = new TestNotchingPhySapProvider();
339 m_phySapProvider->SetParams(m_beamsNum, m_numOfUesPerBeam);
340
341 mac->SetPhySapProvider(m_phySapProvider);
342 mac->SetVerbose(m_verbose);
343
344 Ptr<NrAmc> amc = CreateObject<NrAmc>();
345 sched->InstallDlAmc(amc);
346
347 // uint32_t rbPerRbg = mac->GetNumRbPerRbg ();
348 // std::cout << "numRbPerRbg: " << rbPerRbg << std::endl;
349
350 uint16_t rntiCnt = 1;
351 for (uint32_t beam = 0; beam < m_beamsNum; beam++)
352 {
353 for (uint32_t u = 0; u < m_numOfUesPerBeam; u++)
354 {
355 NrMacCschedSapProvider::CschedUeConfigReqParameters paramsUe;
356 paramsUe.m_rnti = rntiCnt;
357 paramsUe.m_beamId = m_phySapProvider->GetBeamId(rntiCnt);
358
359 if (m_verbose)
360 {
361 std::cout << "beam: " << beam << " ue: " << u << " rnti: " << paramsUe.m_rnti
362 << " beam Id: " << paramsUe.m_beamId << " scheduler: " << m_schedulerType
363 << std::endl;
364 if (beam == (m_beamsNum - 1) && u == (m_numOfUesPerBeam - 1))
365 {
366 std::ostringstream ss;
367 for (auto x : m_mask)
368 {
369 ss << std::to_string(x) << " ";
370 }
371
372 std::cout << "The defined mask is: " << ss.str() << std::endl;
373 }
374 }
375
376 // Add Users
377 sched->DoCschedUeConfigReq(paramsUe); // Repeat for the number of UEs
378
379 // Create LC
380 NrMacCschedSapProvider::CschedLcConfigReqParameters paramsLc;
381 paramsLc.m_rnti = rntiCnt;
382 paramsLc.m_reconfigureFlag = false;
383
384 nr::LogicalChannelConfigListElement_s lc;
385 lc.m_logicalChannelIdentity = 1;
386 lc.m_logicalChannelGroup = 2;
387 lc.m_direction = nr::LogicalChannelConfigListElement_s::DIR_DL;
388 lc.m_qosBearerType = nr::LogicalChannelConfigListElement_s::QBT_NON_GBR;
389 lc.m_qci = 9;
390 paramsLc.m_logicalChannelConfigList.emplace_back(lc);
391
392 sched->DoCschedLcConfigReq(paramsLc);
393
394 // Update queue
395 NrMacSchedSapProvider::SchedDlRlcBufferReqParameters paramsDlRlc;
396 paramsDlRlc.m_rnti = rntiCnt;
397 paramsDlRlc.m_logicalChannelIdentity = 1;
398 paramsDlRlc.m_rlcRetransmissionHolDelay = 0;
399 paramsDlRlc.m_rlcRetransmissionQueueSize = 0;
400 paramsDlRlc.m_rlcStatusPduSize = 0;
401 paramsDlRlc.m_rlcTransmissionQueueHolDelay = 0;
402 paramsDlRlc.m_rlcTransmissionQueueSize = 1284;
403
404 sched->DoSchedDlRlcBufferReq(paramsDlRlc);
405
406 rntiCnt++;
407 }
408 }
409
410 // Call scheduling
411 NrMacSchedSapProvider::SchedDlTriggerReqParameters paramsDlTrigger;
412 paramsDlTrigger.m_snfSf = SfnSf(0, 0, 0, 0);
413 paramsDlTrigger.m_slotType = LteNrTddSlotType::DL;
414 sched->DoSchedDlTriggerReq(paramsDlTrigger);
415
416 delete m_phySapProvider;
417}
418
419class NrNotchingTestSuite : public TestSuite
420{
421 public:
422 NrNotchingTestSuite()
423 : TestSuite("nr-test-notching", Type::UNIT)
424 {
425 // We simulate BW of 10 MHz so the size of the mask is 53 RBGs
426 // considering that 1 RBG contains 1 RB
427 // NOLINTBEGIN
428 std::vector<bool> notchedMask1{0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
429 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,
430 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
431
432 std::vector<bool> notchedMask2{0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
433 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
434 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0};
435 // NOLINTEND
436 std::list<std::string> subdivision = {"Tdma", "Ofdma"};
437 std::list<std::string> scheds = {"RR"};
438 std::list<uint32_t> uesPerBeamList = {1, 2, 4, 6};
439 std::list<uint32_t> beams = {1, 2};
440
441 for (const auto& subType : subdivision)
442 {
443 for (const auto& sched : scheds)
444 {
445 for (const auto& uesPerBeam : uesPerBeamList)
446 {
447 for (const auto& beam : beams)
448 {
449 std::stringstream ss;
450 std::stringstream schedName;
451 ss << ", " << subType << " " << sched << ", " << uesPerBeam
452 << " UE per beam, " << beam << " beam";
453
454 schedName << "ns3::NrMacScheduler" << subType << sched;
455
456 AddTestCase(new NrNotchingTestCase(ss.str(),
457 notchedMask1,
458 schedName.str(),
459 uesPerBeam,
460 beam),
461 Duration::QUICK);
462 AddTestCase(new NrNotchingTestCase(ss.str(),
463 notchedMask2,
464 schedName.str(),
465 uesPerBeam,
466 beam),
467 Duration::QUICK);
468 }
469 }
470 }
471 }
472 }
473};
474
475static NrNotchingTestSuite nrNotchingTestSuite;
476
478
479} // namespace ns3
@ DL
DL CTRL + DL DATA.
static NrNotchingTestSuite nrNotchingTestSuite
Nr Notching test suite.