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