A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lte-enb-phy.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Giuseppe Piro <g.piro@poliba.it>
7 * Marco Miozzo <mmiozzo@cttc.es>
8 */
9
10#include "lte-enb-phy.h"
11
12#include "lte-common.h"
14#include "lte-net-device.h"
17
18#include <ns3/attribute-accessor-helper.h>
19#include <ns3/double.h>
20#include <ns3/log.h>
21#include <ns3/object-factory.h>
22#include <ns3/simulator.h>
23
24#include <cfloat>
25#include <cmath>
26
27// WILD HACK for the initialization of direct eNB-UE ctrl messaging
28#include <ns3/node-list.h>
29#include <ns3/node.h>
30#include <ns3/pointer.h>
31
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("LteEnbPhy");
36
38
39/**
40 * Duration of the data portion of a DL subframe.
41 * Equals to "TTI length * (11/14) - margin".
42 * Data portion is fixed to 11 symbols out of the available 14 symbols.
43 * 1 nanosecond margin is added to avoid overlapping simulator events.
44 */
45static const Time DL_DATA_DURATION = NanoSeconds(785714 - 1);
46
47/**
48 * Delay from the start of a DL subframe to transmission of the data portion.
49 * Equals to "TTI length * (3/14)".
50 * Control portion is fixed to 3 symbols out of the available 14 symbols.
51 */
53
54////////////////////////////////////////
55// member SAP forwarders
56////////////////////////////////////////
57
58/// @todo SetBandwidth() and SetCellId() can be removed.
60{
61 public:
62 /**
63 * Constructor
64 *
65 * @param phy the ENB Phy
66 */
68
69 // inherited from LteEnbPhySapProvider
70 void SendMacPdu(Ptr<Packet> p) override;
72 uint8_t GetMacChTtiDelay() override;
73 /**
74 * Set bandwidth function
75 *
76 * @param ulBandwidth the UL bandwidth
77 * @param dlBandwidth the DL bandwidth
78 */
79 virtual void SetBandwidth(uint16_t ulBandwidth, uint16_t dlBandwidth);
80 /**
81 * Set Cell ID function
82 *
83 * @param cellId the cell ID
84 */
85 virtual void SetCellId(uint16_t cellId);
86
87 private:
88 LteEnbPhy* m_phy; ///< the ENB Phy
89};
90
95
96void
101
102void
103EnbMemberLteEnbPhySapProvider::SetBandwidth(uint16_t ulBandwidth, uint16_t dlBandwidth)
104{
105 m_phy->DoSetBandwidth(ulBandwidth, dlBandwidth);
106}
107
108void
110{
111 m_phy->DoSetCellId(cellId);
112}
113
114void
119
120uint8_t
125
126////////////////////////////////////////
127// generic LteEnbPhy methods
128////////////////////////////////////////
129
131{
132 NS_LOG_FUNCTION(this);
133 NS_FATAL_ERROR("This constructor should not be called");
134}
135
137 : LtePhy(dlPhy, ulPhy),
138 m_enbPhySapUser(nullptr),
139 m_enbCphySapUser(nullptr),
140 m_nrFrames(0),
141 m_nrSubFrames(0),
142 m_srsPeriodicity(0),
143 m_srsStartTime(),
144 m_currentSrsOffset(0),
145 m_interferenceSampleCounter(0)
146{
150 m_downlinkSpectrumPhy->SetHarqPhyModule(m_harqPhyModule);
151 m_uplinkSpectrumPhy->SetHarqPhyModule(m_harqPhyModule);
152}
153
154TypeId
156{
157 static TypeId tid =
158 TypeId("ns3::LteEnbPhy")
159 .SetParent<LtePhy>()
160 .SetGroupName("Lte")
161 .AddConstructor<LteEnbPhy>()
162 .AddAttribute("TxPower",
163 "Transmission power in dBm",
164 DoubleValue(30.0),
167 .AddAttribute(
168 "NoiseFigure",
169 "Loss (dB) in the Signal-to-Noise-Ratio due to "
170 "non-idealities in the receiver. According to Wikipedia "
171 "(http://en.wikipedia.org/wiki/Noise_figure), this is "
172 "\"the difference in decibels (dB) between"
173 " the noise output of the actual receiver to "
174 "the noise output of an ideal receiver with "
175 "the same overall gain and bandwidth when the receivers "
176 "are connected to sources at the standard noise "
177 "temperature T0.\" In this model, we consider T0 = 290K.",
178 DoubleValue(5.0),
181 .AddAttribute(
182 "MacToChannelDelay",
183 "The delay in TTI units that occurs between "
184 "a scheduling decision in the MAC and the actual "
185 "start of the transmission by the PHY. This is "
186 "intended to be used to model the latency of real PHY "
187 "and MAC implementations.",
188 UintegerValue(2),
191 .AddTraceSource("ReportUeSinr",
192 "Report UEs' averaged linear SINR",
194 "ns3::LteEnbPhy::ReportUeSinrTracedCallback")
195 .AddAttribute("UeSinrSamplePeriod",
196 "The sampling period for reporting UEs' SINR stats.",
197 UintegerValue(1), /// \todo In what unit is this?
200 .AddTraceSource("ReportInterference",
201 "Report linear interference power per PHY RB",
203 "ns3::LteEnbPhy::ReportInterferenceTracedCallback")
204 .AddAttribute("InterferenceSamplePeriod",
205 "The sampling period for reporting interference stats",
206 UintegerValue(1), /// \todo In what unit is this?
209 .AddTraceSource("DlPhyTransmission",
210 "DL transmission PHY layer statistics.",
212 "ns3::PhyTransmissionStatParameters::TracedCallback")
213 .AddAttribute("DlSpectrumPhy",
214 "The downlink LteSpectrumPhy associated to this LtePhy",
216 PointerValue(),
219 .AddAttribute("UlSpectrumPhy",
220 "The uplink LteSpectrumPhy associated to this LtePhy",
222 PointerValue(),
225 return tid;
226}
227
231
232void
234{
235 NS_LOG_FUNCTION(this);
236 m_ueAttached.clear();
237 m_srsUeOffset.clear();
238 delete m_enbPhySapProvider;
241}
242
243void
245{
246 NS_LOG_FUNCTION(this);
247
248 NS_ABORT_MSG_IF(!m_netDevice, "LteEnbDevice is not available in LteEnbPhy");
249 Ptr<Node> node = m_netDevice->GetNode();
250 NS_ABORT_MSG_IF(!node, "Node is not available in the LteNetDevice of LteEnbPhy");
251 uint32_t nodeId = node->GetId();
252
253 // ScheduleWithContext() is needed here to set context for logs,
254 // because Initialize() is called outside of Node::AddDevice().
255
257
258 Ptr<SpectrumValue> noisePsd =
262 m_uplinkSpectrumPhy->SetNoisePowerSpectralDensity(noisePsd);
264}
265
266void
271
277
278void
284
291
292void
294{
295 NS_LOG_FUNCTION(this << pow);
296 m_txPower = pow;
297}
298
299double
301{
302 NS_LOG_FUNCTION(this);
303 return m_txPower;
304}
305
306int8_t
308{
309 NS_LOG_FUNCTION(this);
310 return m_txPower;
311}
312
313void
315{
316 NS_LOG_FUNCTION(this << nf);
317 m_noiseFigure = nf;
318}
319
320double
322{
323 NS_LOG_FUNCTION(this);
324 return m_noiseFigure;
325}
326
327void
329{
330 NS_LOG_FUNCTION(this);
331 m_macChTtiDelay = delay;
332 for (int i = 0; i < m_macChTtiDelay; i++)
333 {
335 m_packetBurstQueue.push_back(pb);
336 std::list<Ptr<LteControlMessage>> l;
337 m_controlMessagesQueue.push_back(l);
338 std::list<UlDciLteControlMessage> l1;
339 m_ulDciQueue.push_back(l1);
340 }
341 for (int i = 0; i < UL_PUSCH_TTIS_DELAY; i++)
342 {
343 std::list<UlDciLteControlMessage> l1;
344 m_ulDciQueue.push_back(l1);
345 }
346}
347
348uint8_t
350{
351 return m_macChTtiDelay;
352}
353
359
365
366bool
368{
369 NS_LOG_FUNCTION(this << rnti);
370 auto it = m_ueAttached.find(rnti);
371 if (it == m_ueAttached.end())
372 {
373 m_ueAttached.insert(rnti);
374 return true;
375 }
376 else
377 {
378 NS_LOG_ERROR("UE already attached");
379 return false;
380 }
381}
382
383bool
385{
386 NS_LOG_FUNCTION(this << rnti);
387 auto it = m_ueAttached.find(rnti);
388 if (it == m_ueAttached.end())
389 {
390 NS_LOG_ERROR("UE not attached");
391 return false;
392 }
393 else
394 {
395 m_ueAttached.erase(it);
396 return true;
397 }
398}
399
400void
406
407uint8_t
412
413void
419
420void
422{
423 NS_LOG_FUNCTION(this);
426 m_downlinkSpectrumPhy->SetTxPowerSpectralDensity(txPsd);
427}
428
429void
437
438std::vector<int>
444
445void
447{
448 NS_LOG_FUNCTION(this);
449 double rbgTxPower = m_txPower;
450
451 auto it = m_paMap.find(rnti);
452 if (it != m_paMap.end())
453 {
454 rbgTxPower = m_txPower + it->second;
455 }
456
457 m_dlPowerAllocationMap.insert(std::pair<int, double>(rbId, rbgTxPower));
458}
459
473
488
489void
491{
492 NS_LOG_FUNCTION(this);
493}
494
495void
497{
498 NS_LOG_FUNCTION(this << msg);
499 // queues the message (wait for MAC-PHY delay)
501}
502
503void
510
511void
513{
514 NS_LOG_FUNCTION(this);
515 for (auto it = msgList.begin(); it != msgList.end(); it++)
516 {
517 switch ((*it)->GetMessageType())
518 {
522 m_enbPhySapUser->ReceiveRachPreamble(rachPreamble->GetRapId());
523 }
524 break;
527 CqiListElement_s dlcqi = dlcqiMsg->GetDlCqi();
528 // check whether the UE is connected
529 if (m_ueAttached.find(dlcqi.m_rnti) != m_ueAttached.end())
530 {
532 }
533 }
534 break;
537 MacCeListElement_s bsr = bsrMsg->GetBsr();
538 // check whether the UE is connected
539 if (m_ueAttached.find(bsr.m_rnti) != m_ueAttached.end())
540 {
542 }
543 }
544 break;
548 DlInfoListElement_s dlharq = dlharqMsg->GetDlHarqFeedback();
549 // check whether the UE is connected
550 if (m_ueAttached.find(dlharq.m_rnti) != m_ueAttached.end())
551 {
553 }
554 }
555 break;
556 default:
557 NS_FATAL_ERROR("Unexpected LteControlMessage type");
558 break;
559 }
560 }
561}
562
563void
565{
566 NS_LOG_FUNCTION(this);
567
568 ++m_nrFrames;
569 NS_LOG_INFO("-----frame " << m_nrFrames << "-----");
570 m_nrSubFrames = 0;
571
572 // send MIB at beginning of every frame
575 mibMsg->SetMib(m_mib);
576 m_controlMessagesQueue.at(0).emplace_back(mibMsg);
577
579}
580
581void
583{
584 NS_LOG_FUNCTION(this);
585
587
588 /*
589 * Send SIB1 at 6th subframe of every odd-numbered radio frame. This is
590 * equivalent with Section 5.2.1.2 of 3GPP TS 36.331, where it is specified
591 * "repetitions are scheduled in subframe #5 of all other radio frames for
592 * which SFN mod 2 = 0," except that 3GPP counts frames and subframes starting
593 * from 0, while ns-3 counts starting from 1.
594 */
595 if ((m_nrSubFrames == 6) && ((m_nrFrames % 2) == 1))
596 {
598 msg->SetSib1(m_sib1);
599 m_controlMessagesQueue.at(0).emplace_back(msg);
600 }
601
602 if (m_srsPeriodicity > 0)
603 {
604 // might be 0 in case the eNB has no UEs attached
605 NS_ASSERT_MSG(m_nrFrames > 1, "the SRS index check code assumes that frameNo starts at 1");
607 "the SRS index check code assumes that subframeNo starts at 1");
609 }
610 NS_LOG_INFO("-----sub frame " << m_nrSubFrames << "-----");
611 m_harqPhyModule->SubframeIndication(m_nrFrames, m_nrSubFrames);
612
613 // update info on TB to be received
614 std::list<UlDciLteControlMessage> uldcilist = DequeueUlDci();
615 NS_LOG_DEBUG(this << " eNB Expected TBs " << uldcilist.size());
616 for (auto dciIt = uldcilist.begin(); dciIt != uldcilist.end(); dciIt++)
617 {
618 auto it2 = m_ueAttached.find((*dciIt).GetDci().m_rnti);
619
620 if (it2 == m_ueAttached.end())
621 {
622 NS_LOG_ERROR("UE not attached");
623 }
624 else
625 {
626 // send info of TB to LteSpectrumPhy
627 // translate to allocation map
628 std::vector<int> rbMap;
629 for (int i = (*dciIt).GetDci().m_rbStart;
630 i < (*dciIt).GetDci().m_rbStart + (*dciIt).GetDci().m_rbLen;
631 i++)
632 {
633 rbMap.push_back(i);
634 }
635 m_uplinkSpectrumPhy->AddExpectedTb((*dciIt).GetDci().m_rnti,
636 (*dciIt).GetDci().m_ndi,
637 (*dciIt).GetDci().m_tbSize,
638 (*dciIt).GetDci().m_mcs,
639 rbMap,
640 0 /* always SISO*/,
641 0 /* no HARQ proc id in UL*/,
642 0 /*evaluated by LteSpectrumPhy*/,
643 false /* UL*/);
644 if ((*dciIt).GetDci().m_ndi == 1)
645 {
646 NS_LOG_DEBUG(this << " RNTI " << (*dciIt).GetDci().m_rnti << " NEW TB");
647 }
648 else
649 {
650 NS_LOG_DEBUG(this << " RNTI " << (*dciIt).GetDci().m_rnti << " HARQ RETX");
651 }
652 }
653 }
654
655 // process the current burst of control messages
656 std::list<Ptr<LteControlMessage>> ctrlMsg = GetControlMessages();
657 m_dlDataRbMap.clear();
659 if (!ctrlMsg.empty())
660 {
661 auto it = ctrlMsg.begin();
662 while (it != ctrlMsg.end())
663 {
664 Ptr<LteControlMessage> msg = (*it);
665 if (msg->GetMessageType() == LteControlMessage::DL_DCI)
666 {
668 // get the tx power spectral density according to DL-DCI(s)
669 // translate the DCI to Spectrum framework
670 uint32_t mask = 0x1;
671 for (int i = 0; i < 32; i++)
672 {
673 if (((dci->GetDci().m_rbBitmap & mask) >> i) == 1)
674 {
675 for (int k = 0; k < GetRbgSize(); k++)
676 {
677 m_dlDataRbMap.push_back((i * GetRbgSize()) + k);
678 // NS_LOG_DEBUG(this << " [enb]DL-DCI allocated PRB " <<
679 // (i*GetRbgSize()) + k);
680 GeneratePowerAllocationMap(dci->GetDci().m_rnti,
681 (i * GetRbgSize()) + k);
682 }
683 }
684 mask = (mask << 1);
685 }
686 // fire trace of DL Tx PHY stats
687 for (std::size_t i = 0; i < dci->GetDci().m_mcs.size(); i++)
688 {
690 params.m_cellId = m_cellId;
691 params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
692 params.m_timestamp = Simulator::Now().GetMilliSeconds();
693 params.m_rnti = dci->GetDci().m_rnti;
694 params.m_txMode = 0; // TBD
695 params.m_layer = i;
696 params.m_mcs = dci->GetDci().m_mcs.at(i);
697 params.m_size = dci->GetDci().m_tbsSize.at(i);
698 params.m_rv = dci->GetDci().m_rv.at(i);
699 params.m_ndi = dci->GetDci().m_ndi.at(i);
700 params.m_ccId = m_componentCarrierId;
701 m_dlPhyTransmission(params);
702 }
703 }
704 else if (msg->GetMessageType() == LteControlMessage::UL_DCI)
705 {
707 QueueUlDci(*dci);
708 }
709 else if (msg->GetMessageType() == LteControlMessage::RAR)
710 {
712 for (auto it = rarMsg->RarListBegin(); it != rarMsg->RarListEnd(); ++it)
713 {
714 if (it->rarPayload.m_grant.m_ulDelay)
715 {
716 NS_FATAL_ERROR(" RAR delay is not yet implemented");
717 }
718 UlGrant_s ulGrant = it->rarPayload.m_grant;
719 // translate the UL grant in a standard UL-DCI and queue it
721 dci.m_rnti = ulGrant.m_rnti;
722 dci.m_rbStart = ulGrant.m_rbStart;
723 dci.m_rbLen = ulGrant.m_rbLen;
724 dci.m_tbSize = ulGrant.m_tbSize;
725 dci.m_mcs = ulGrant.m_mcs;
726 dci.m_hopping = ulGrant.m_hopping;
727 dci.m_tpc = ulGrant.m_tpc;
728 dci.m_cqiRequest = ulGrant.m_cqiRequest;
729 dci.m_ndi = 1;
731 msg.SetDci(dci);
732 QueueUlDci(msg);
733 }
734 }
735 it++;
736 }
737 }
738
739 SendControlChannels(ctrlMsg);
740
741 // send data frame
743 if (pb)
744 {
745 Simulator::Schedule(DL_CTRL_DELAY_FROM_SUBFRAME_START, // ctrl frame fixed to 3 symbols
747 this,
748 pb);
749 }
750
751 // trigger the MAC
753
755}
756
757void
759{
760 NS_LOG_FUNCTION(this << " eNB " << m_cellId << " start tx ctrl frame");
761 // set the current tx power spectral density (full bandwidth)
762 std::vector<int> dlRb;
763 for (uint16_t i = 0; i < m_dlBandwidth; i++)
764 {
765 dlRb.push_back(i);
766 }
768 NS_LOG_LOGIC(this << " eNB start TX CTRL");
769 bool pss = false;
770 if ((m_nrSubFrames == 1) || (m_nrSubFrames == 6))
771 {
772 pss = true;
773 }
774 m_downlinkSpectrumPhy->StartTxDlCtrlFrame(ctrlMsgList, pss);
775}
776
777void
779{
780 // set the current tx power spectral density
782 // send the current burts of packets
783 NS_LOG_LOGIC(this << " eNB start TX DATA");
784 std::list<Ptr<LteControlMessage>> ctrlMsgList;
785 ctrlMsgList.clear();
786 m_downlinkSpectrumPhy->StartTxDataFrame(pb, ctrlMsgList, DL_DATA_DURATION);
787}
788
789void
791{
793 if (m_nrSubFrames == 10)
794 {
796 }
797 else
798 {
800 }
801}
802
803void
809
810void
812{
813 NS_LOG_FUNCTION(this << sinr << Simulator::Now() << m_srsStartTime);
814 // avoid processing SRSs sent with an old SRS configuration index
816 {
819 }
820}
821
822void
829
830void
842
843void
845{
846 // not used by eNB
847}
848
851{
852 NS_LOG_FUNCTION(this << sinr);
854 ulcqi.m_ulCqi.m_type = UlCqi_s::PUSCH;
855 for (auto it = sinr.ConstValuesBegin(); it != sinr.ConstValuesEnd(); it++)
856 {
857 double sinrdb = 10 * std::log10(*it);
858 // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb);
859 // convert from double to fixed point notation Sxxxxxxxxxxx.xxx
860 int16_t sinrFp = LteFfConverter::double2fpS11dot3(sinrdb);
861 ulcqi.m_ulCqi.m_sinr.push_back(sinrFp);
862 }
863 return ulcqi;
864}
865
866void
867LteEnbPhy::DoSetBandwidth(uint16_t ulBandwidth, uint16_t dlBandwidth)
868{
869 NS_LOG_FUNCTION(this << (uint32_t)ulBandwidth << (uint32_t)dlBandwidth);
870 m_ulBandwidth = ulBandwidth;
871 m_dlBandwidth = dlBandwidth;
872
873 static const int Type0AllocationRbg[4] = {
874 10, // RBG size 1
875 26, // RBG size 2
876 63, // RBG size 3
877 110, // RBG size 4
878 }; // see table 7.1.6.1-1 of 36.213
879 for (int i = 0; i < 4; i++)
880 {
881 if (dlBandwidth < Type0AllocationRbg[i])
882 {
883 m_rbgSize = i + 1;
884 break;
885 }
886 }
887}
888
889void
891{
892 NS_LOG_FUNCTION(this << ulEarfcn << dlEarfcn);
893 m_ulEarfcn = ulEarfcn;
894 m_dlEarfcn = dlEarfcn;
895}
896
897void
898LteEnbPhy::DoAddUe(uint16_t rnti)
899{
900 NS_LOG_FUNCTION(this << rnti);
901
902 bool success = AddUePhy(rnti);
903 NS_ASSERT_MSG(success, "AddUePhy() failed");
904
905 // add default P_A value
906 DoSetPa(rnti, 0);
907}
908
909void
911{
912 NS_LOG_FUNCTION(this << rnti);
913
914 bool success = DeleteUePhy(rnti);
915 NS_ASSERT_MSG(success, "DeleteUePhy() failed");
916
917 // remove also P_A value
918 auto it = m_paMap.find(rnti);
919 if (it != m_paMap.end())
920 {
921 m_paMap.erase(it);
922 }
923
924 // additional data to be removed
925 m_uplinkSpectrumPhy->RemoveExpectedTb(rnti);
926 // remove srs info to avoid trace errors
927 auto sit = m_srsSampleCounterMap.find(rnti);
928 if (sit != m_srsSampleCounterMap.end())
929 {
930 m_srsSampleCounterMap.erase(rnti);
931 }
932 // remove DL_DCI message otherwise errors occur for m_dlPhyTransmission trace
933 // remove also any UL_DCI message for the UE to be removed
934
935 for (auto& ctrlMessageList : m_controlMessagesQueue)
936 {
937 auto ctrlMsgListIt = ctrlMessageList.begin();
938 while (ctrlMsgListIt != ctrlMessageList.end())
939 {
940 Ptr<LteControlMessage> msg = (*ctrlMsgListIt);
941 if (msg->GetMessageType() == LteControlMessage::DL_DCI)
942 {
944 if (dci->GetDci().m_rnti == rnti)
945 {
946 NS_LOG_INFO("DL_DCI to be sent from cell id : " << m_cellId << " to RNTI : "
947 << rnti << " is deleted");
948 ctrlMsgListIt = ctrlMessageList.erase(ctrlMsgListIt);
949 }
950 else
951 {
952 ++ctrlMsgListIt;
953 }
954 }
955 else if (msg->GetMessageType() == LteControlMessage::UL_DCI)
956 {
958 if (dci->GetDci().m_rnti == rnti)
959 {
960 NS_LOG_INFO("UL_DCI to be sent from cell id : " << m_cellId << " to RNTI : "
961 << rnti << " is deleted");
962 ctrlMsgListIt = ctrlMessageList.erase(ctrlMsgListIt);
963 }
964 else
965 {
966 ++ctrlMsgListIt;
967 }
968 }
969 else
970 {
971 ++ctrlMsgListIt;
972 }
973 }
974 }
975}
976
977void
978LteEnbPhy::DoSetPa(uint16_t rnti, double pa)
979{
980 NS_LOG_FUNCTION(this << rnti);
981
982 auto it = m_paMap.find(rnti);
983
984 if (it == m_paMap.end())
985 {
986 m_paMap.insert(std::pair<uint16_t, double>(rnti, pa));
987 }
988 else
989 {
990 it->second = pa;
991 }
992}
993
996{
997 NS_LOG_FUNCTION(this << sinr);
999 ulcqi.m_ulCqi.m_type = UlCqi_s::SRS;
1000 int i = 0;
1001 double srsSum = 0.0;
1002 for (auto it = sinr.ConstValuesBegin(); it != sinr.ConstValuesEnd(); it++)
1003 {
1004 double sinrdb = 10 * log10(*it);
1005 // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb);
1006 // convert from double to fixed point notation Sxxxxxxxxxxx.xxx
1007 int16_t sinrFp = LteFfConverter::double2fpS11dot3(sinrdb);
1008 srsSum += (*it);
1009 ulcqi.m_ulCqi.m_sinr.push_back(sinrFp);
1010 i++;
1011 }
1012 // Insert the user generated the srs as a vendor specific parameter
1013 NS_LOG_DEBUG(this << " ENB RX UL-CQI of " << m_srsUeOffset.at(m_currentSrsOffset));
1016 vsp.m_length = sizeof(SrsCqiRntiVsp);
1018 vsp.m_value = rnti;
1019 ulcqi.m_vendorSpecificList.push_back(vsp);
1020 // call SRS tracing method
1021 CreateSrsReport(m_srsUeOffset.at(m_currentSrsOffset), (i > 0) ? (srsSum / i) : DBL_MAX);
1022 return ulcqi;
1023}
1024
1025void
1026LteEnbPhy::CreateSrsReport(uint16_t rnti, double srs)
1027{
1028 NS_LOG_FUNCTION(this << rnti << srs);
1029 auto it = m_srsSampleCounterMap.find(rnti);
1030 if (it == m_srsSampleCounterMap.end())
1031 {
1032 // create new entry
1033 m_srsSampleCounterMap.insert(std::pair<uint16_t, uint16_t>(rnti, 0));
1034 it = m_srsSampleCounterMap.find(rnti);
1035 }
1036 (*it).second++;
1037 if ((*it).second == m_srsSamplePeriod)
1038 {
1039 m_reportUeSinr(m_cellId, rnti, srs, (uint16_t)m_componentCarrierId);
1040 (*it).second = 0;
1041 }
1042}
1043
1044void
1045LteEnbPhy::DoSetTransmissionMode(uint16_t rnti, uint8_t txMode)
1046{
1047 NS_LOG_FUNCTION(this << rnti << (uint16_t)txMode);
1048 // UL supports only SISO MODE
1049}
1050
1051void
1057
1058std::list<UlDciLteControlMessage>
1060{
1061 NS_LOG_FUNCTION(this);
1062 if (!m_ulDciQueue.at(0).empty())
1063 {
1064 std::list<UlDciLteControlMessage> ret = m_ulDciQueue.at(0);
1065 m_ulDciQueue.erase(m_ulDciQueue.begin());
1066 std::list<UlDciLteControlMessage> l;
1067 m_ulDciQueue.push_back(l);
1068 return ret;
1069 }
1070 else
1071 {
1072 m_ulDciQueue.erase(m_ulDciQueue.begin());
1073 std::list<UlDciLteControlMessage> l;
1074 m_ulDciQueue.push_back(l);
1075 std::list<UlDciLteControlMessage> emptylist;
1076 return emptylist;
1077 }
1078}
1079
1080void
1081LteEnbPhy::DoSetSrsConfigurationIndex(uint16_t rnti, uint16_t srcCi)
1082{
1083 NS_LOG_FUNCTION(this);
1084 uint16_t p = GetSrsPeriodicity(srcCi);
1085 if (p != m_srsPeriodicity)
1086 {
1087 // resize the array of offset -> re-initialize variables
1088 m_srsUeOffset.clear();
1089 m_srsUeOffset.resize(p, 0);
1090 m_srsPeriodicity = p;
1091 // inhibit SRS until RRC Connection Reconfiguration propagates
1092 // to UEs, otherwise we might be wrong in determining the UE who
1093 // actually sent the SRS (if the UE was using a stale SRS config)
1094 // if we use a static SRS configuration index, we can have a 0ms guard time
1096 }
1097
1098 NS_LOG_DEBUG(this << " ENB SRS P " << m_srsPeriodicity << " RNTI " << rnti << " offset "
1099 << GetSrsSubframeOffset(srcCi) << " CI " << srcCi);
1100 auto it = m_srsCounter.find(rnti);
1101 if (it != m_srsCounter.end())
1102 {
1103 (*it).second = GetSrsSubframeOffset(srcCi) + 1;
1104 }
1105 else
1106 {
1107 m_srsCounter.insert(std::pair<uint16_t, uint16_t>(rnti, GetSrsSubframeOffset(srcCi) + 1));
1108 }
1109 m_srsUeOffset.at(GetSrsSubframeOffset(srcCi)) = rnti;
1110}
1111
1112void
1118
1119void
1125
1126void
1131
1132void
1139
1140} // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
void SendMacPdu(Ptr< Packet > p) override
Send the MAC PDU to the channel.
EnbMemberLteEnbPhySapProvider(LteEnbPhy *phy)
Constructor.
virtual void SetBandwidth(uint16_t ulBandwidth, uint16_t dlBandwidth)
Set bandwidth function.
uint8_t GetMacChTtiDelay() override
Get the delay from MAC to Channel expressed in TTIs.
LteEnbPhy * m_phy
the ENB Phy
virtual void SetCellId(uint16_t cellId)
Set Cell ID function.
void SendLteControlMessage(Ptr< LteControlMessage > msg) override
Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
LteEnbPhy models the physical layer for the eNodeB.
Definition lte-enb-phy.h:34
uint16_t m_srsPeriodicity
SRS periodicity.
double GetTxPower() const
Time m_srsStartTime
SRS start time.
int8_t DoGetReferenceSignalPower() const
void StartSubFrame()
Start a LTE sub frame.
void CreateSrsReport(uint16_t rnti, double srs)
Create SRS report function.
uint16_t m_interferenceSamplePeriod
The InterferenceSamplePeriod attribute.
virtual void ReportUlHarqFeedback(UlInfoListElement_s mes)
Report the uplink HARQ feedback generated by LteSpectrumPhy to MAC.
std::list< UlDciLteControlMessage > DequeueUlDci()
uint16_t m_srsSamplePeriod
The UeSinrSamplePeriod trace source.
void SetLteEnbCphySapUser(LteEnbCphySapUser *s)
Set the CPHY SAP User.
FfMacSchedSapProvider::SchedUlCqiInfoReqParameters CreatePuschCqiReport(const SpectrumValue &sinr)
Create the UL CQI feedback from SINR values perceived at the physical layer with the PUSCH signal rec...
uint32_t m_nrSubFrames
The subframe number currently served.
std::set< uint16_t > m_ueAttached
List of RNTI of attached UEs.
LteEnbPhySapProvider * GetLteEnbPhySapProvider()
Get the PHY SAP provider.
void SetLteEnbPhySapUser(LteEnbPhySapUser *s)
Set the PHY SAP User.
void DoSetMasterInformationBlock(LteRrcSap::MasterInformationBlock mib)
Set master information block.
bool DeleteUePhy(uint16_t rnti)
Remove the given RNTI from the list of attached UE m_ueAttached.
std::vector< std::list< UlDciLteControlMessage > > m_ulDciQueue
For storing info on future receptions.
double GetNoiseFigure() const
void SetTxPower(double pow)
std::vector< int > m_dlDataRbMap
DL data RB map.
TracedCallback< uint16_t, uint16_t, double, uint8_t > m_reportUeSinr
The ReportUeSinr trace source.
~LteEnbPhy() override
Ptr< LteSpectrumPhy > GetDlSpectrumPhy() const
void DoDispose() override
Destructor implementation.
void GenerateCtrlCqiReport(const SpectrumValue &sinr) override
generate a CQI report based on the given SINR of Ctrl frame
void GenerateDataCqiReport(const SpectrumValue &sinr) override
generate a CQI report based on the given SINR of Data frame (used for PUSCH CQIs)
void SendDataChannels(Ptr< PacketBurst > pb)
Send the PDSCH.
std::map< uint16_t, uint16_t > m_srsSampleCounterMap
SRS sample counter map.
void DoSetSrsConfigurationIndex(uint16_t rnti, uint16_t srcCi)
Set source configuration index.
void PhyPduReceived(Ptr< Packet > p)
PhySpectrum received a new PHY-PDU.
FfMacSchedSapProvider::SchedUlCqiInfoReqParameters CreateSrsCqiReport(const SpectrumValue &sinr)
Create the UL CQI feedback from SINR values perceived at the physical layer with the SRS signal recei...
LteEnbPhySapUser * m_enbPhySapUser
ENB Phy SAP user.
void EndFrame()
End a LTE frame.
void CalcChannelQualityForUe(std::vector< double > sinr, Ptr< LteSpectrumPhy > ue)
Calculate the channel quality for a given UE.
void DoSetPa(uint16_t rnti, double pa)
Set PA.
uint8_t GetMacChDelay() const
uint16_t m_currentSrsOffset
current SRS offset
void DoSetEarfcn(uint32_t dlEarfcn, uint32_t ulEarfcn)
Set EARFCN.
Ptr< SpectrumValue > CreateTxPowerSpectralDensity() override
Create the PSD for TX.
void DoSetTransmissionMode(uint16_t rnti, uint8_t txMode)
Set transmission mode.
LteEnbPhySapProvider * m_enbPhySapProvider
ENB Phy SAP provider.
uint8_t DoGetMacChTtiDelay()
Get MAC ch TTI delay function.
std::map< int, double > m_dlPowerAllocationMap
DL power allocation map.
std::vector< int > m_listOfDownlinkSubchannel
A vector of integers, if the i-th value is j it means that the j-th resource block is used for transm...
void GeneratePowerAllocationMap(uint16_t rnti, int rbId)
Generate power allocation map (i.e.
void QueueUlDci(UlDciLteControlMessage m)
void SetNoiseFigure(double pow)
std::map< uint16_t, uint16_t > m_srsCounter
SRS counter.
void SetMacChDelay(uint8_t delay)
void SetHarqPhyModule(Ptr< LteHarqPhy > harq)
Set the HARQ Phy module.
virtual void ReceiveLteControlMessageList(std::list< Ptr< LteControlMessage > > msgList)
PhySpectrum received a new list of LteControlMessage.
void SendControlChannels(std::list< Ptr< LteControlMessage > > ctrlMsgList)
Send the PDCCH and PCFICH in the first 3 symbols.
void DoRemoveUe(uint16_t rnti)
Remove UE.
void SetDownlinkSubChannelsWithPowerAllocation(std::vector< int > mask)
set the resource blocks (a.k.a.
void ReportRsReceivedPower(const SpectrumValue &power) override
generate a report based on the linear RS power perceived during CTRL frame NOTE: used only by UE for ...
LteRrcSap::MasterInformationBlock m_mib
The Master Information Block message to be broadcasted every frame.
void DoSendMacPdu(Ptr< Packet > p) override
Queue the MAC PDU to be sent (according to m_macChTtiDelay)
void ReportInterference(const SpectrumValue &interf) override
generate a report based on the linear interference and noise power perceived during DATA frame NOTE: ...
TracedCallback< uint16_t, Ptr< SpectrumValue > > m_reportInterferenceTrace
The ReportInterference trace source.
Ptr< LteSpectrumPhy > GetUlSpectrumPhy() const
void DoAddUe(uint16_t rnti)
Add UE.
friend class EnbMemberLteEnbPhySapProvider
allow EnbMemberLteEnbPhySapProvider class friend access
Definition lte-enb-phy.h:36
void DoSetSystemInformationBlockType1(LteRrcSap::SystemInformationBlockType1 sib1)
Set system information block.
void DoSendLteControlMessage(Ptr< LteControlMessage > msg)
Send LTE Control Message function.
virtual Ptr< SpectrumValue > CreateTxPowerSpectralDensityWithPowerAllocation()
Create the PSD for TX with power allocation for each RB.
bool AddUePhy(uint16_t rnti)
Add the given RNTI to the list of attached UE m_ueAttached.
void DoInitialize() override
Initialize() implementation.
LteRrcSap::SystemInformationBlockType1 m_sib1
The System Information Block Type 1 message to be broadcasted.
std::map< uint16_t, double > m_paMap
P_A per UE RNTI.
void DoSetBandwidth(uint16_t ulBandwidth, uint16_t dlBandwidth)
Set bandwidth function.
void EndSubFrame()
End a LTE sub frame.
LteEnbCphySapUser * m_enbCphySapUser
ENB CPhy SAP user.
uint16_t m_interferenceSampleCounter
interference sample counter
void SetDownlinkSubChannels(std::vector< int > mask)
set the resource blocks (a.k.a.
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive the control message.
void StartFrame()
Start a LTE frame.
uint32_t m_nrFrames
The frame number currently served.
LteEnbCphySapProvider * m_enbCphySapProvider
ENB CPhy SAP provider.
std::vector< uint16_t > m_srsUeOffset
SRS UE offset.
LteEnbCphySapProvider * GetLteEnbCphySapProvider()
Get the CPHY SAP provider.
TracedCallback< PhyTransmissionStatParameters > m_dlPhyTransmission
The DlPhyTransmission trace source.
std::vector< int > GetDownlinkSubChannels()
Ptr< LteHarqPhy > m_harqPhyModule
HARQ Phy module.
friend class MemberLteEnbCphySapProvider< LteEnbPhy >
allow MemberLteEnbCphySapProvider<LteEnbPhy> class friend access
Definition lte-enb-phy.h:38
static TypeId GetTypeId()
Get the type ID.
Service Access Point (SAP) offered by the eNB-PHY to the eNB-MAC.
Service Access Point (SAP) offered by the eNB-PHY to the eNB-MAC.
virtual void ReceivePhyPdu(Ptr< Packet > p)=0
Called by the Phy to notify the MAC of the reception of a new PHY-PDU.
virtual void UlCqiReport(FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)=0
Returns to MAC level the UL-CQI evaluated.
virtual void UlInfoListElementHarqFeedback(UlInfoListElement_s params)=0
Notify the HARQ on the UL transmission status.
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)=0
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
virtual void ReceiveRachPreamble(uint32_t prachId)=0
notify the reception of a RACH preamble on the PRACH
virtual void SubframeIndication(uint32_t frameNo, uint32_t subframeNo)=0
Trigger the start from a new frame (input from Phy layer)
static uint16_t double2fpS11dot3(double val)
Convert from double to fixed point S11.3 notation.
The LtePhy models the physical layer of LTE.
Definition lte-phy.h:40
void DoSetCellId(uint16_t cellId)
Definition lte-phy.cc:229
double m_txPower
Transmission power in dBm.
Definition lte-phy.h:230
uint8_t GetRbgSize() const
Definition lte-phy.cc:169
void DoDispose() override
Destructor implementation.
Definition lte-phy.cc:65
uint16_t GetSrsPeriodicity(uint16_t srcCi) const
Definition lte-phy.cc:133
std::vector< Ptr< PacketBurst > > m_packetBurstQueue
A queue of packet bursts to be sent.
Definition lte-phy.h:270
uint16_t m_ulBandwidth
The UL bandwidth in number of PRBs.
Definition lte-phy.h:250
Ptr< PacketBurst > GetPacketBurst()
Definition lte-phy.cc:181
uint8_t m_componentCarrierId
component carrier Id used to address sap
Definition lte-phy.h:292
double m_noiseFigure
Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver.
Definition lte-phy.h:242
uint32_t m_ulEarfcn
The uplink carrier frequency.
Definition lte-phy.h:267
uint16_t m_dlBandwidth
The DL bandwidth in number of PRBs.
Definition lte-phy.h:255
Ptr< LteSpectrumPhy > m_downlinkSpectrumPhy
The downlink LteSpectrumPhy associated to this LtePhy.
Definition lte-phy.h:219
void SetMacPdu(Ptr< Packet > p)
Definition lte-phy.cc:175
std::list< Ptr< LteControlMessage > > GetControlMessages()
Definition lte-phy.cc:207
uint16_t GetSrsSubframeOffset(uint16_t srcCi) const
Definition lte-phy.cc:151
Ptr< LteNetDevice > m_netDevice
Pointer to the NetDevice where this PHY layer is attached.
Definition lte-phy.h:213
uint16_t m_cellId
Cell identifier.
Definition lte-phy.h:289
void SetControlMessages(Ptr< LteControlMessage > m)
Definition lte-phy.cc:199
uint32_t m_dlEarfcn
The downlink carrier frequency.
Definition lte-phy.h:262
Ptr< LteSpectrumPhy > m_uplinkSpectrumPhy
The uplink LteSpectrumPhy associated to this LtePhy.
Definition lte-phy.h:224
double GetTti() const
Definition lte-phy.cc:126
std::vector< std::list< Ptr< LteControlMessage > > > m_controlMessagesQueue
A queue of control messages to be sent.
Definition lte-phy.h:272
uint8_t m_rbgSize
The RB group size according to the bandwidth.
Definition lte-phy.h:257
uint8_t m_macChTtiDelay
Delay between MAC and channel layer in terms of TTIs.
Definition lte-phy.h:282
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double powerTx, std::vector< int > activeRbs)
create a spectrum value representing the power spectral density of a signal to be transmitted.
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:440
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:577
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
Set of values corresponding to a given SpectrumModel.
Values::const_iterator ConstValuesBegin() const
Values::const_iterator ConstValuesEnd() const
Define the RNTI that has generated the.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:397
@ S
second
Definition nstime.h:105
a unique identifier for an interface.
Definition type-id.h:48
@ ATTR_GET
The attribute can be read.
Definition type-id.h:53
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
The Uplink Data Control Indicator messages defines the RB allocation for the users in the uplink.
void SetDci(UlDciListElement_s dci)
add a DCI into the message
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition double.h:32
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1380
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1356
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
#define UL_PUSCH_TTIS_DELAY
Definition lte-common.h:17
#define SRS_CQI_RNTI_VSP
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const Time DL_CTRL_DELAY_FROM_SUBFRAME_START
Delay from the start of a DL subframe to transmission of the data portion.
static const Time DL_DATA_DURATION
Duration of the data portion of a DL subframe.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
static const int Type0AllocationRbg[4]
Type 0 RBG allocation.
See section 4.3.24 cqiListElement.
See section 4.3.23 dlInfoListElement.
Parameters of the SCHED_UL_CQI_INFO_REQ primitive.
std::vector< VendorSpecificListElement_s > m_vendorSpecificList
vendor specific list
MasterInformationBlock structure.
uint16_t systemFrameNumber
system frame number
SystemInformationBlockType1 structure.
See section 4.3.14 macCEListElement.
PhyTransmissionStatParameters structure.
Definition lte-common.h:177
std::vector< uint16_t > m_sinr
SINR.
See section 4.3.2 ulDciListElement.
int8_t m_tpc
Tx power control command.
bool m_cqiRequest
CQI request.
Substitutive structure for specifying BuildRarListElement_s::m_grant field.
int8_t m_tpc
Tx power control command.
bool m_cqiRequest
CQI request?
bool m_hopping
hopping?
uint16_t m_tbSize
size
uint8_t m_rbLen
length
uint8_t m_mcs
MCS.
uint8_t m_rbStart
start
uint16_t m_rnti
RNTI.
See section 4.3.12 ulInfoListElement.
See section 4.3.3 vendorSpecificListElement.
Ptr< VendorSpecificValue > m_value
value