5#include "ns3/beam-id.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"
32class TestNotchingPhySapProvider :
public NrPhySapProvider
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,
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);
55 uint32_t m_sapNumOfUesPerBeam = 0;
56 uint32_t m_sapNumOfBeams = 0;
59TestNotchingPhySapProvider::TestNotchingPhySapProvider()
63TestNotchingPhySapProvider::~TestNotchingPhySapProvider()
68TestNotchingPhySapProvider::SetParams(uint32_t numOfUesPerBeam, uint32_t numOfBeams)
70 m_sapNumOfUesPerBeam = numOfUesPerBeam;
71 m_sapNumOfBeams = numOfBeams;
75TestNotchingPhySapProvider::GetSymbolsPerSlot()
const
81Ptr<const SpectrumModel>
82TestNotchingPhySapProvider::GetSpectrumModel()
88TestNotchingPhySapProvider::GetBwpId()
const
94TestNotchingPhySapProvider::GetCellId()
const
100TestNotchingPhySapProvider::GetSlotPeriod()
const
102 return MilliSeconds(1);
106TestNotchingPhySapProvider::SendMacPdu(
const Ptr<Packet>& p,
114TestNotchingPhySapProvider::SendControlMessage(Ptr<NrControlMessage> msg)
119TestNotchingPhySapProvider::SendRachPreamble(uint8_t PreambleId, uint8_t Rnti)
124TestNotchingPhySapProvider::SetSlotAllocInfo(
const SlotAllocInfo& slotAllocInfo)
129TestNotchingPhySapProvider::NotifyConnectionSuccessful()
134TestNotchingPhySapProvider::GetRbNum()
const
137 NS_FATAL_ERROR(
"GetRbNum should not be called");
142TestNotchingPhySapProvider::GetBeamId(uint8_t rnti)
const
144 BeamId beamId = BeamId(0, 0.0);
146 for (uint32_t beam = 0; beam < m_sapNumOfUesPerBeam; beam++)
148 for (uint32_t u = 0; u < m_sapNumOfBeams; u++)
150 if (rnti == 0 || (rntiCnt == rnti && beam == 0))
152 beamId = BeamId(0, 0.0);
154 else if (rntiCnt == rnti && beam == 1)
156 beamId = BeamId(1, 120.0);
164class TestNotchingGnbMac :
public NrGnbMac
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);
174 std::vector<bool> m_inputMask;
175 bool m_verboseMac =
false;
178NS_OBJECT_ENSURE_REGISTERED(TestNotchingGnbMac);
181TestNotchingGnbMac::GetTypeId()
183 static TypeId tid = TypeId(
"ns3::TestNotchingGnbMac").SetParent<NrGnbMac>()
189TestNotchingGnbMac::TestNotchingGnbMac(
const std::vector<bool>& inputMask)
191 m_inputMask = inputMask;
194TestNotchingGnbMac::~TestNotchingGnbMac()
199TestNotchingGnbMac::SetVerbose(
bool verbose)
201 m_verboseMac = verbose;
205TestNotchingGnbMac::DoSchedConfigIndication(NrMacSchedSapUser::SchedConfigIndParameters ind)
211 for (
auto& varTtiAllocInfo : ind.m_slotAllocInfo.m_varTtiAllocInfo)
213 if (varTtiAllocInfo.m_dci->m_rnti == 0)
220 std::ostringstream oss;
221 for (
auto x : varTtiAllocInfo.m_dci->m_rbgBitmask)
223 oss << std::to_string(x) <<
" ";
226 std::cout <<
"UE " << varTtiAllocInfo.m_dci->m_rnti <<
" assigned RBG"
227 <<
" with mask: " << oss.str() << std::endl;
230 NS_ASSERT_MSG(varTtiAllocInfo.m_dci->m_rbgBitmask.size() == m_inputMask.size(),
231 "dci bitmask is not of same size as the mask");
233 unsigned zeroes = std::count(varTtiAllocInfo.m_dci->m_rbgBitmask.begin(),
234 varTtiAllocInfo.m_dci->m_rbgBitmask.end(),
237 NS_ASSERT_MSG(zeroes != m_inputMask.size(),
"dci rbgBitmask is filled with zeros");
239 for (
unsigned index = 0; index < varTtiAllocInfo.m_dci->m_rbgBitmask.size(); index++)
241 if (m_inputMask[index] == 0)
243 NS_ASSERT_MSG(varTtiAllocInfo.m_dci->m_rbgBitmask[index] == 0,
244 "dci is diff from mask");
253class NrNotchingTestCase :
public TestCase
264 NrNotchingTestCase(
const std::string& name,
265 const std::vector<bool>& mask,
266 const std::string& schedulerType,
267 uint32_t numOfUesPerBeam,
271 m_schedulerType(schedulerType),
272 m_numOfUesPerBeam(numOfUesPerBeam),
277 ~NrNotchingTestCase()
override;
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;
286 bool m_verbose =
false;
287 const std::vector<bool> m_mask;
288 const std::string m_schedulerType;
289 uint32_t m_numOfUesPerBeam;
291 TestNotchingPhySapProvider* m_phySapProvider;
294NrNotchingTestCase::~NrNotchingTestCase()
298Ptr<NrMacSchedulerNs3>
299NrNotchingTestCase::CreateScheduler(
const std::string& schedulerType)
const
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);
310Ptr<TestNotchingGnbMac>
311NrNotchingTestCase::CreateMac(Ptr<NrMacSchedulerNs3>& scheduler,
312 NrMacCschedSapProvider::CschedCellConfigReqParameters& params)
const
314 Ptr<TestNotchingGnbMac> mac = CreateObject<TestNotchingGnbMac>(m_mask);
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);
323 scheduler->DoCschedCellConfigReq(params);
329NrNotchingTestCase::DoRun()
331 NrMacCschedSapProvider::CschedCellConfigReqParameters params;
332 params.m_ulBandwidth = m_mask.size();
333 params.m_dlBandwidth = m_mask.size();
335 auto sched = CreateScheduler(m_schedulerType);
336 auto mac = CreateMac(sched, params);
338 m_phySapProvider =
new TestNotchingPhySapProvider();
339 m_phySapProvider->SetParams(m_beamsNum, m_numOfUesPerBeam);
341 mac->SetPhySapProvider(m_phySapProvider);
342 mac->SetVerbose(m_verbose);
344 Ptr<NrAmc> amc = CreateObject<NrAmc>();
345 sched->InstallDlAmc(amc);
350 uint16_t rntiCnt = 1;
351 for (uint32_t beam = 0; beam < m_beamsNum; beam++)
353 for (uint32_t u = 0; u < m_numOfUesPerBeam; u++)
355 NrMacCschedSapProvider::CschedUeConfigReqParameters paramsUe;
356 paramsUe.m_rnti = rntiCnt;
357 paramsUe.m_beamId = m_phySapProvider->GetBeamId(rntiCnt);
361 std::cout <<
"beam: " << beam <<
" ue: " << u <<
" rnti: " << paramsUe.m_rnti
362 <<
" beam Id: " << paramsUe.m_beamId <<
" scheduler: " << m_schedulerType
364 if (beam == (m_beamsNum - 1) && u == (m_numOfUesPerBeam - 1))
366 std::ostringstream ss;
367 for (
auto x : m_mask)
369 ss << std::to_string(x) <<
" ";
372 std::cout <<
"The defined mask is: " << ss.str() << std::endl;
377 sched->DoCschedUeConfigReq(paramsUe);
380 NrMacCschedSapProvider::CschedLcConfigReqParameters paramsLc;
381 paramsLc.m_rnti = rntiCnt;
382 paramsLc.m_reconfigureFlag =
false;
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;
390 paramsLc.m_logicalChannelConfigList.emplace_back(lc);
392 sched->DoCschedLcConfigReq(paramsLc);
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;
404 sched->DoSchedDlRlcBufferReq(paramsDlRlc);
411 NrMacSchedSapProvider::SchedDlTriggerReqParameters paramsDlTrigger;
412 paramsDlTrigger.m_snfSf = SfnSf(0, 0, 0, 0);
414 sched->DoSchedDlTriggerReq(paramsDlTrigger);
416 delete m_phySapProvider;
419class NrNotchingTestSuite :
public TestSuite
422 NrNotchingTestSuite()
423 : TestSuite(
"nr-test-notching", Type::UNIT)
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};
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};
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};
441 for (
const auto& subType : subdivision)
443 for (
const auto& sched : scheds)
445 for (
const auto& uesPerBeam : uesPerBeamList)
447 for (
const auto& beam : beams)
449 std::stringstream ss;
450 std::stringstream schedName;
451 ss <<
", " << subType <<
" " << sched <<
", " << uesPerBeam
452 <<
" UE per beam, " << beam <<
" beam";
454 schedName <<
"ns3::NrMacScheduler" << subType << sched;
456 AddTestCase(
new NrNotchingTestCase(ss.str(),
462 AddTestCase(
new NrNotchingTestCase(ss.str(),
static NrNotchingTestSuite nrNotchingTestSuite
Nr Notching test suite.