GSoC 2012 NS-3 LTE MAC schedulers

This commit is contained in:
Dizhi Zhou
2012-10-21 21:47:17 -03:00
parent 8783c81710
commit 7e1fe7903e
42 changed files with 18199 additions and 0 deletions

View File

@@ -104,3 +104,4 @@ Mitch Watrous (watrous@u.washington.edu)
Florian Westphal (fw@strlen.de)
He Wu (mdzz@u.washington.edu)
Yoshihiko Yazawa (yoshiyaz@gmail.com)
Dizhi Zhou (dizhi.zhou@gmail.com)

View File

@@ -21,6 +21,8 @@ Supported platforms
New user-visible features
-------------------------
-Support several new LTE MAC schedulers developed in GSoC 2012 project. Those schedulers include FD-MT, TD-MT, TTA, FD-BET, TD-BET, FD-TBFQ, TD-TBFQ, PSS. Here, FD and TD mean frequency domain and time domain respectively.
Bugs fixed
----------

View File

@@ -1,6 +1,19 @@
The ns-3 LTE module is the result of the development effort carried out by different people/institutions/projects. The main contributors are listed below.
====================================================
Google Summer of Code (GSoC) (2012)
====================================================
Dizhi Zhou, University of New Brunswick, Canada <dizhi.zhou@gmail.com>
develop several LTE MAC schedulers
Nicola Baldo, CTTC <nbaldo@cttc.es>
Marco Miozzo, CTTC <mmiozzo@cttc.es>
supervision and GSoC project mentorship
====================================================
Google Summer of Code (GSoC) (2010)
====================================================

View File

@@ -652,6 +652,176 @@ where :math:`|\cdot|` indicates the cardinality of the set; finally,
\right)}{\tau}
Maximum Throughput (MT) Scheduler
----------------------------------
The Maximum Throughput (MT) scheduler [FCapo2012]_ aims to maximize the overall throughput of eNB.
It allocates each RB to the user that can achieve the maximum achievable rate in the current TTI.
Currently, MT scheduler in LENA has two versions: frequency domain (FDMT) and time domain (TDMT).
In FDMT, every TTI, MAC scheduler allocates RBGs to the UE who has highest achievable rate calculated
by subband CQI. In TDMT, every TTI, MAC scheduler selects one UE which has highest achievable rate
calculated by wideband CQI. Then MAC scheduler allocates all RBGs to this UE in current TTI.
The calculation of achievable rate in FDMT and TDMT is as same as the one in PF.
Let :math:`i,j` denote generic users; let :math:`t` be the
subframe index, and :math:`k` be the resource block index; let :math:`M_{i,k}(t)` be MCS
usable by user :math:`i` on resource block :math:`k` according to what reported by the AMC
model (see `Adaptive Modulation and Coding`_); finally, let :math:`S(M, B)` be the TB
size in bits as defined in [TS36.213]_ for the case where a number :math:`B` of
resource blocks is used. The achievable rate :math:`R_{i}(k,t)` in bit/s for user :math:`i`
on resource block :math:`k` at subframe :math:`t` is defined as
.. math::
R_{i}(k,t) = \frac{S\left( M_{i,k}(t), 1\right)}{\tau}
where :math:`\tau` is the TTI duration.
At the start of each subframe :math:`t`, each RB is assigned to a certain user.
In detail, the index :math:`\widehat{i}_{k}(t)` to which RB :math:`k` is assigned at time
:math:`t` is determined as
.. math::
\widehat{i}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
\left( { R_{j}(k,t) } \right)
When there are several UEs having the same achievable rate, current implementation always selects
the first UE created in script. Although MT can maximize cell throughput, it cannot provide
fairness to UEs in poor channel condition.
Throughput to Average (TTA) Scheduler
--------------------------------------
The Throughput to Average (TTA) scheduler [FCapo2012]_ can be considered as an intermediate between MT and PF.
The metric used in TTA is calculated as follows:
.. math::
\widehat{i}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
\left( \frac{ R_{j}(k,t) }{ R_{j}(t) } \right)
Here, :math:`R_{i}(k,t)` in bit/s represents the achievable rate for user :math:`i`
on resource block :math:`k` at subframe :math:`t`. The
calculation method already is shown in MT and PF. Meanwhile, :math:`R_{i}(t)` in bit/s stands
for the achievable rate for :math:`i` at subframe :math:`t`. The difference between those two
achievable rates is how to get MCS. For :math:`R_{i}(k,t)`, MCS is calculated by subband CQI while
:math:`R_{i}(t)` is calculated by wideband CQI. TTA scheduler can only be implemented in frequency domain (FD) because
the achievable rate of particular RBG is only related to FD scheduling.
Blind Average Throughput Scheduler
----------------------------------
The Blind Average Throughput scheduler [FCapo2012]_ aims to provide equal throughput to all UEs under eNB. The metric
used in TTA is calculated as follows:
.. math::
\widehat{i}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
\left( \frac{ 1 }{ T_\mathrm{j}(t) } \right)
where :math:`T_{j}(t)` is the past throughput performance perceived by the user :math:`j` and can be calculated by the
same method in PF scheduler. In the time domain blind average throughput (TD-BET), the scheduler selects the UE
with largest priority metric and allocates all RBGs to this UE. On the other hand, in the frequency domain blind
average throughput (FD-BET), every TTI, the scheduler first selects one UE with lowest pastAverageThroughput (largest
priority metric). Then scheduler assigns one RBG to this UE, it calculates expected throughput of this UE and uses it
to compare with past average throughput :math:`T_{j}(t)` of other UEs. The scheduler continues
to allocate RBG to this UE until its expected throughput is not the smallest one among past average throughput :math:`T_{j}(t)`
of all UE. Then the scheduler will use the same way to allocate RBG for a new UE which has the
lowest past average throughput :math:`T_{j}(t)` until all RBGs are allocated to UEs. The principle behind this is
that, in every TTI, the scheduler tries the best to achieve the equal throughput among all UEs.
Token Bank Fair Queue Scheduler
-------------------------------
Token Band Fair Queue (TBFQ) is a QoS aware scheduler which derives from the leaky-bucket mechanism. In TBFQ,
a traffic flow of user :math:`i` is characterized by following parameters:
* :math:`t_{i}`: packet arrival rate (byte/sec )
* :math:`r_{i}`: token generation rate (byte/sec)
* :math:`p_{i}`: token pool size (byte)
* :math:`E_{i}`: counter that records the number of token borrowed from or given to the token bank by flow :math:`i` ;
:math:`E_{i}` can be smaller than zero
Each K bytes data consumes k tokens. Also, TBFQ maintains a shared token bank (:math:`B`) so as to balance the traffic
between different flows. If token generation rate :math:`r_{i}` is bigger than packet arrival rate :math:`t_{i}`, then tokens
overflowing from token pool are added to the token bank, and :math:`E_{i}` is increased by the same amount. Otherwise,
flow :math:`i` needs to withdraw tokens from token bank based on a priority metric :math:`frac{E_{i}}{r_{i}}`, and :math:`E_{i}` is decreased.
Obviously, the user contributes more on token bank has higher priority to borrow tokens; on the other hand, the
user borrows more tokens from bank has lower priority to continue to withdraw tokens. Therefore, in case of several
users having the same token generation rate, traffic rate and token pool size, user suffers from higher interference
has more opportunity to borrow tokens from bank. In addition, TBFQ can police the traffic by setting the token
generation rate to limit the throughput. Additionally, TBFQ also maintains following three parameters for each flow:
* Debt limit :math:`d_{i}`: if :math:`E_{i}` belows this threshold, user i cannot further borrow tokens from bank. This is for
preventing malicious UE to borrow too much tokens.
* Credit limit :math:`c_{i}`: the maximum number of tokens UE i can borrow from the bank in one time.
* Credit threshold :math:`C`: once :math:`E_{i}` reaches debt limit, UE i must store :math:`C` tokens to bank in order to further
borrow token from bank.
LTE in NS-3 has two versions of TBFQ scheduler: frequency domain TBFQ (FD-TBFQ) and time domain TBFQ (TD-TBFQ).
In FD-TBFQ, the scheduler always select UE with highest metric and allocates RBG with highest subband CQI until
there are no packets within UE's RLC buffer or all RBGs are allocated [FABokhari2009]_. In TD-TBFQ, after selecting
UE with maximum metric, it allocates all RBGs to this UE by using wideband CQI [WKWong2004]_.
Priority Set Scheduler
----------------------
Priority set scheduler (PSS) is a QoS aware scheduler which combines time domain (TD) and frequency domain (FD)
packet scheduling operations into one scheduler [GMonghal2008]_. It controls the fairness among UEs by a specified
Target Bit Rate (TBR).
In TD scheduler part, PSS first selects UEs with non-empty RLC buffer and then divide them into two sets based
on the TBR:
* set 1: UE whose past average throughput is smaller than TBR; TD scheduler calculates their priority metric in
Blind Equal Throughput (BET) style:
.. math::
\widehat{i}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
\left( \frac{ 1 }{ T_\mathrm{j}(t) } \right)
* set 2: UE whose past average throughput is larger (or equal) than TBR; TD scheduler calculates their priority
metric in Proportional Fair (PF) style:
.. math::
\widehat{i}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
\left( \frac{ R_{j}(k,t) }{ T_\mathrm{j}(t) } \right)
UEs belonged to set 1 have higher priority than ones in set 2. Then PSS will select :math:`N_{mux}` UEs with
highest metric in two sets and forward those UE to FD scheduler. In PSS, FD scheduler allocates RBG k to UE n
that maximums the chosen metric. Two PF schedulers are used in PF scheduler:
* Proportional Fair scheduled (PFsch)
.. math::
\widehat{Msch}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
\left( \frac{ R_{j}(k,t) }{ Tsch_\mathrm{j}(t) } \right)
* Carrier over Interference to Average (CoIta)
.. math::
\widehat{Mcoi}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
\left( \frac{ CoI[j,k] }{ \sum_{k=0}^{N_{RBG}} CoI[j,k] } \right)
where :math:`Tsch_{j}(t)` is similar past throughput performance perceived by the user :math:`j`, with the
difference that it is updated only when the i-th user is actually served. :math:`CoI[j,k]` is an
estimation of the SINR on the RBG :math:`k` of UE :math:`j`. Both PFsch and CoIta is for decoupling
FD metric from TD scheduler. In addition, PSS FD scheduler also provide a weight metric W[n] for helping
controlling fairness in case of low number of UEs.
.. math::
W[n] = max (1, \frac{TBR}{ T_{j}(t) })
where :math:`T_{j}(t)` is the past throughput performance perceived by the user :math:`j` . Therefore, on
RBG k, the FD scheduler selects the UE :math:`j` that maximizes the product of the frequency domain
metric (:math:`Msch`, :math:`MCoI`) by weight :math:`W[n]`. This strategy will guarantee the throughput of lower
quality UE tend towards the TBR.
Transport Blocks
----------------

View File

@@ -86,5 +86,11 @@ References
.. [R4-081920] 3GPP R4-081920 `LTE PDCCH/PCFICH Demodulation Performance Results with Implementation Margin
<http://www.3gpp.org/ftp/tsg_ran/wg4_radio/TSGR4_48/Documents/R4-081920.zip>`_
.. [FCapo2012] F.Capozzi, G.Piro L.A.Grieco, G.Boggia, P.Camarda, "Downlink Packet Scheduling in LTE Cellular Networks: Key Design Issues and a Survey", IEEE Comm. Surveys and Tutorials, to appear
.. [FABokhari2009] F.A. Bokhari, H. Yanikomeroglu, W.K. Wong, M. Rahman, "Cross-Layer Resource Scheduling for Video Traffic in the Downlink of OFDMA-Based Wireless 4G Networks",EURASIP J. Wirel. Commun. Netw., vol.2009, no.3, pp. 1-10, Jan. 2009.
.. [WKWong2004] W.K. Wong, H.Y. Tang, V.C.M, Leung, "Token bank fair queuing: a new scheduling algorithm for wireless multimedia services", Int. J. Commun. Syst., vol.17, no.6, pp.591-614, Aug.2004.
.. [GMonghal2008] G.Mongha, K.I. Pedersen, I.Z. Kovacs, P.E. Mogensen, " QoS Oriented Time and Frequency Domain Packet Schedulers for The UTRAN Long Term Evolution", In Proc. IEEE VTC, 2008.

View File

@@ -347,6 +347,197 @@ more resources to the users that use a higher MCS index.
where the UEs have MCS index :math:`28, 24, 16, 12, 6`
Maximum Throughput scheduler performance
----------------------------------------
Test suites ``lte-fdmt-ff-mac-scheduler`` and ``lte-tdmt-ff-mac-scheduler``
create different test cases with a single eNB and several UEs, all having the same
Radio Bearer specification, using the Frequency Domain Maximum Throughput (FDMT)
scheduler and Time Domain Maximum Throughput (TDMT) scheduler respectively.
In other words, UEs are all placed at the
same distance from the eNB, and hence all placed in order to have the
same SNR. Different test cases are implemented by using a different
SNR values and a different number of UEs. The test consists on
checking that the obtained throughput performance matches with the
known reference throughput up to a given tolerance.The expected
behavior of both FDMT and TDMT scheduler when all UEs have the same SNR is that
scheduler allocates all RBGs to the first UE defined in script. This is because
the current FDMT and TDMT implementation always select the first UE to serve when there are
multiple UEs having the same SNR value. We calculate the reference
throughput value for first UE by the throughput achievable of a single UE
at the given SNR, while reference throughput value for other UEs by zero.
Let :math:`\tau` be the TTI duration, :math:`B` the transmission
bandwidth configuration in number of RBs, :math:`M` the modulation and
coding scheme in use at the given SNR and :math:`S(M, B)` be the
transport block size as defined in [TS36.213]_. The reference
throughput :math:`T` in bit/s achieved by each UE is calculated as
.. math::
T = \frac{S(M,B)}{\tau}
Throughput to Average scheduler performance
-------------------------------------------
Test suites ``lte-tta-ff-mac-scheduler``
create different test cases with a single eNB and several UEs, all having the same
Radio Bearer specification using TTA scheduler. Network topology and configurations in
TTA test case are as the same as the test for MT scheduler. More complex test case needs to be
developed to show the fairness feature of TTA scheduler.
Blind Average Throughput scheduler performance
----------------------------------------------
Test suites ``lte-tdbet-ff-mac-scheduler`` and ``lte-fdbet-ff-mac-scheduler`` create different
test cases with a single eNB and several UEs, all having the same Radio Bearer specification.
In the first test case of ``lte-tdbet-ff-mac-scheduler`` and ``lte-fdbet-ff-mac-scheduler``,
the UEs are all placed at the same distance from the eNB, and hence all placed in order to
have the same SNR. Different test cases are implemented by using a different SNR value and
a different number of UEs. The test consists on checking that the obtained throughput performance
matches with the known reference throughput up to a given tolerance. In long term, the expected
behavior of both TD-BET and FD-BET when all UEs have the same SNR is that each UE should get an
equal throughput. However, the exact throughput value of TD-BET and FD-BET in this test case is not
the same.
When all UEs have the same SNR, TD-BET can be seen as a specific case of PF where achievable rate equals
to 1. Therefore, the throughput obtained by TD-BET is equal to that of PF. On the other hand, FD-BET performs
very similar to the round robin (RR) scheduler in case of that all UEs have the same SNR and the number of UE( or RBG)
is an integer multiple of the number of RBG( or UE). In this case, FD-BET always allocate the same number of RBGs
to each UE. For example, if eNB has 12 RBGs and there are 6 UEs, then each UE will get 2 RBGs in each TTI.
Or if eNB has 12 RBGs and there are 24 UEs, then each UE will get 2 RBGs per two TTIs. When the number of
UE (RBG) is not an integer multiple of the number of RBG (UE), FD-BET will not follow the RR behavior because
it will assigned different number of RBGs to some UEs, while the throughput of each UE is still the same.
The second category of tests aims at verifying the fairness of the both TD-BET and FD-BET schedulers in a more realistic
simulation scenario where the UEs have a different SNR (constant for the whole simulation). In this case,
both scheduler should give the same amount of averaged throughput to each user.
Specifically, for TD-BET, let :math:`F_i` be the fraction of time allocated to user i in total simulation time,
:math:`R^{fb}_i` be the the full bandwidth achievable rate for user i and :math:`T_i` be the achieved throughput of
user i. Then we have:
.. math::
T_i = F_i R^{fb}_i
In TD-BET, the sum of :math:`F_i` for all user equals one. In long term, all UE has the same :math:`T_i` so that we replace
:math:`T_i` by :math:`T`. Then we have:
.. math::
T = \frac{1}{ \sum_{i=1}^{N} \frac{1}{R^{fb}_i} }
Token Band Fair Queue scheduler performance
-------------------------------------------
Test suites ``lte-fdtbfq-ff-mac-scheduler`` and ``lte-tdtbfq-ff-mac-scheduler`` create different
test cases for testing three key features of TBFQ scheduler: traffic policing, fairness and traffic
balance. Constant Bit Rate UDP traffic is used in both downlink and uplink in all test cases.
The packet interval is set to 1ms to keep the RLC buffer non-empty. Different traffic rate is
achieved by setting different packet size. Specifically, two classes of flows are created in the
testsuites:
* Homogeneous flow: flows with the same token generation rate and packet arrival rate
* Heterogeneous flow: flows with different packet arrival rate, but with the same token generation rate
In test case 1 verifies traffic policing and fairness features for the scenario that all UEs are
placed at the same distance from the eNB. In this case, all Ues have the same SNR value. Different
test cases are implemented by using a different SNR value and a different number of UEs. Because each
flow have the same traffic rate and token generation rate, TBFQ scheduler will guarantee the same
throughput among UEs without the constraint of token generation rate. In addition, the exact value
of UE throughput is depended on the total traffic rate:
* If total traffic rate <= maximum throughput, UE throughput = traffic rate
* If total traffic rate > maximum throughput, UE throughput = maximum throughput / N
Here, N is the number of UE connected to eNodeB. The maximum throughput in this case equals to the rate
that all RBGs are assigned to one UE(e.g., when distance equals 0, maximum throughput is 2196000 byte/sec).
When the traffic rate is smaller than max bandwidth, TBFQ can police the traffic by token generation rate
so that the UE throughput equals its actual traffic rate (token generation rate is set to traffic
generation rate); On the other hand, when total traffic rate is bigger than the max throughput, eNodeB
cannot forward all traffic to UEs. Therefore, in each TTI, TBFQ will allocate all RBGs to one UE due to
the large packets buffered in RLC buffer. When a UE is scheduled in current TTI, its token counter is decreased
so that it will not be scheduled in the next TTI. Because each UE has the same traffic generation rate,
TBFQ will serve each UE in turn and only serve one UE in each TTI (both in TD TBFQ and FD TBFQ).
Therefore, the UE throughput in the second condition equals to the evenly share of maximum throughput.
Test case 2 verifies traffic policing and fairness features for the scenario that each UE is placed at
the different distance from the eNB. In this case, each UE has the different SNR value. Similar to test
case 1, UE throughput in test case 2 is also depended on the total traffic rate but with a different
maximum throughput. Suppose all UEs have a high traffic load. Then the traffic will saturate the RLC buffer
in eNodeB. In each TTI, after selecting one UE with highest metric, TBFQ will allocate all RBGs to this
UE due to the large RLC buffer size. On the other hand, once RLC buffer is saturated, the total throughput
of all UEs cannot increase any more. In addition, as we discussed in test case 1, for homogeneous flows
which have the same t_i and r_i, each UE will achieve the same throughput in long term. Therefore, we
can use the same method in TD BET to calculate the maximum throughput:
.. math::
T = \frac{N}{ \sum_{i=1}^{N} \frac{1}{R^{fb}_i} }
Here, :math:`T` is the maximum throughput. :math:`R^{fb}_i` be the the full bandwidth achievable rate
for user i. :math:`N` is the number of UE.
When the totol traffic rate is bigger than :math:`T`, the UE throughput equals to :math:`\frac{T}{N}` . Otherwise, UE throughput
equals to its traffic generation rate.
In test case 3, three flows with different traffic rate are created. Token generation rate for each
flow is the same and equals to the average traffic rate of three flows. Because TBFQ use a shared token
bank, tokens contributed by UE with lower traffic load can be utilized by UE with higher traffic load.
In this way, TBFQ can guarantee the traffic rate for each flow. Although we use heterogeneous flow here,
the calculation of maximum throughput is as same as that in test case 2. In calculation max throughput
of test case 2, we assume that all UEs suffer high traffic load so that scheduler always assign all RBGs
to one UE in each TTI. This assumes is also true in heterogeneous flow case. In other words, whether
those flows have the same traffic rate and token generation rate, if their traffic rate is bigger enough,
TBFQ performs as same as it in test case 2. Therefore, the maximum bandwidth in test case 3 is as
same as it in test case 2.
In test case 3, in some flows, token generate rate does not equal to MBR, although all flows are CBR
traffic. This is not accorded with our parameter setting rules. Actually, the traffic balance feature
is used in VBR traffic. Because different UE's peak rate may occur in different time, TBFQ use shared
token bank to balance the traffic among those VBR traffics. Test case 3 use CBR traffic to verify this
feature. But in the real simulation, it is recommended to set token generation rate to MBR.
Priority Set scheduler performance
----------------------------------
Test suites ``lte-pss-ff-mac-scheduler`` create different test cases with a single eNB and several UEs.
In all test cases, we select PFsch in FD scheduler. Same testing results can also be obtained by using CoItA
scheduler. In addition, all test cases do not define nMux so that TD scheduler in PSS will always select half
of total UE.
In the first class test case of ``lte-pss-ff-mac-scheduler``, the UEs are all placed at the same distance from
the eNB, and hence all placed in order to have the same SNR. Different test cases are implemented
by using a different TBR for each UEs. In each test cases, all UEs have the same
Target Bit Rate configured by GBR in EPS bear setting. The expected behavior of PSS is to guarantee that
each UE's throughput at least equals its TBR if the total flow rate is blow maximum throughput. Similar
to TBFQ, the maximum throughput in this case equals to the rate that all RBGs are assigned to one UE.
When the traffic rate is smaller than max bandwidth, the UE throughput equals its actual traffic rate;
On the other hand, UE throughput equals to the evenly share of the maximum throughput.
In the first class of test cases, each UE has the same SNR. Therefore, the priority metric in PF scheduler will be
determined by past average throughput :math:`T_{j}(t)` because each UE has the same achievable throughput
:math:`R_{j}(k,t)` in PFsch or same :math:`CoI[k,n]` in CoItA. This means that PSS will performs like a
TD-BET which allocates all RBGs to one UE in each TTI. Then the maximum value of UE throughput equals to
the achievable rate that all RBGs are allocated to this UE.
In the second class of test case of ``lte-pss-ff-mac-scheduler``, the UEs are all placed at the same distance from
the eNB, and hence all placed in order to have the same SNR. Different TBR values are assigned to each UE.
There also exist an maximum throughput in this case. Once total traffic rate is bigger than this threshold,
there will be some UEs that cannot achieve their TBR. Because there is no fading, subband CQIs for each
RBGs frequency are the same. Therefore, in FD scheduler,in each TTI, priority metrics of UE for all RBGs
are the same. This means that FD scheduler will always allocate all RBGs to one user. Therefore, in the
maximum throughput case, PSS performs like a TD-BET. Then we have:
.. math::
T = \frac{N}{ \sum_{i=1}^N \frac{1}{R^{fb}_i} }
Here, :math:`T` is the maximum throughput. :math:`R^{fb}_i` be the the full bandwidth achievable rate
for user i. :math:`N` is the number of UE.
Building Propagation Loss Model
-------------------------------

View File

@@ -189,6 +189,61 @@ note that the above will put in the file ``input-defaults.txt`` *all*
the default values that are registered in your particular build of the
simulator, including lots of non-LTE attributes.
Configure LTE MAC Scheduler
---------------------------
There are several types of LTE MAC scheduler user can choose here. User can use following codes to define scheduler type::
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetSchedulerType ("ns3::FdMtFfMacScheduler"); // FD-MT scheduler
lteHelper->SetSchedulerType ("ns3::TdMtFfMacScheduler"); // TD-MT scheduler
lteHelper->SetSchedulerType ("ns3::TtaFfMacScheduler"); // TTA scheduler
lteHelper->SetSchedulerType ("ns3::FdBetFfMacScheduler"); // FD-BET scheduler
lteHelper->SetSchedulerType ("ns3::TdBetFfMacScheduler"); // TD-BET scheduler
lteHelper->SetSchedulerType ("ns3::FdTbfqFfMacScheduler"); // FD-TBFQ scheduler
lteHelper->SetSchedulerType ("ns3::TdTbfqFfMacScheduler"); // TD-TBFQ scheduler
lteHelper->SetSchedulerType ("ns3::PssFfMacScheduler"); //PSS scheduler
TBFQ and PSS have more parameters than other schedulers. Users can define those parameters in following way::
* TBFQ scheduler::
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetSchedulerAttribute("DebtLimit", IntegerValue(yourvalue)); // default value -625000 bytes (-5Mb)
lteHelper->SetSchedulerAttribute("CreditLimit", UintegerValue(yourvalue)); // default value 625000 bytes (5Mb)
lteHelper->SetSchedulerAttribute("TokenPoolSize", UintegerValue(yourvalue)); // default value 1 byte
lteHelper->SetSchedulerAttribute("CreditableThreshold", UintegerValue(yourvalue)); // default value 0
* PSS scheduler::
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetSchedulerAttribute("nMux", UIntegerValue(yourvalue)); // the maximum number of UE selected by TD scheduler
lteHelper->SetSchedulerAttribute("PssFdSchedulerType", StringValue("CoItA")); // PF scheduler type in PSS
In TBFQ, default values of debt limit and credit limit are set to -5Mb and 5Mb respectively based on paper [FABokhari2009]_.
Current implementation does not consider credit threshold (:math:`C` = 0). In PSS, if user does not define nMux,
PSS will set this value to half of total UE. The default FD scheduler is PFsch.
In addition, token generation rate in TBFQ and target bit rate in PSS need to be configured by Guarantee Bit Rate (GBR) or
Maximum Bit Rate (MBR) in epc bearer QoS parameters. Users can use following codes to define GBR and MBR in both downlink and uplink::
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
enum EpsBearer::Qci q = EpsBearer::yourvalue; // define Qci type
GbrQosInformation qos;
qos.gbrDl = yourvalue; // Downlink GBR
qos.gbrUl = yourvalue; // Uplink GBR
qos.mbrDl = yourvalue; // Downlink MBR
qos.mbrUl = yourvalue; // Uplink MBR
EpsBearer bearer (q, qos);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
In PSS, TBR is obtained from GBR in bearer level QoS parameters. In TBFQ, token generation rate is obtained from the MBR
setting in bearer level QoS parameters, which therefore needs to be configured consistently.
For constant bit rate (CBR) traffic, it is suggested to set MBR to GBR. For variance bit rate (VBR) traffic,
it is suggested to set MBR k times larger than GBR in order to cover the peak traffic rate. In current implementation, k is set to
three based on paper [FABokhari2009]_. In addition, current version of TBFQ does not consider RLC header and PDCP header length in
MBR and GBR. Another parameter in TBFQ is packet arrival rate. This parameter is calculated within scheduler and equals to the past
average throughput which is used in PF scheduler.
Simulation Output
-----------------

View File

@@ -38,6 +38,11 @@ EpsBearer::EpsBearer (Qci x)
{
}
EpsBearer::EpsBearer (Qci x, struct GbrQosInformation y)
: qci (x), gbrQosInfo (y)
{
}
bool
EpsBearer::IsGbr () const
{

View File

@@ -88,6 +88,8 @@ struct EpsBearer
*/
EpsBearer (Qci x);
EpsBearer (Qci x, GbrQosInformation y);
/**
*
* @return true if the EPS Bearer is a Guaranteed Bit Rate bearer, false otherwise

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,216 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef FDBET_FF_MAC_SCHEDULER_H
#define FDBET_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
struct fdbetsFlowPerf_t
{
Time flowStart;
unsigned long totalBytesTransmitted;
unsigned int lastTtiBytesTransmitted;
double lastAveragedThroughput;
};
/**
* \ingroup lte
* \brief Implements the SCHED SAP and CSCHED SAP for a Frequency Domain Blind Equal Throughput scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class FdBetFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
FdBetFfMacScheduler ();
/**
* Destructor
*/
virtual ~FdBetFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class FdBetSchedulerMemberCschedSapProvider;
friend class FdBetSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Map of UE statistics (per RNTI basis) in downlink
*/
std::map <uint16_t, fdbetsFlowPerf_t> m_flowStatsDl;
/*
* Map of UE statistics (per RNTI basis)
*/
std::map <uint16_t, fdbetsFlowPerf_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
double m_timeWindow;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
};
} // namespace ns3
#endif /* FDBET_FF_MAC_SCHEDULER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef FDMT_FF_MAC_SCHEDULER_H
#define FDMT_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <set>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
/**
* \ingroup lte
*
* \brief Implements the SCHED SAP and CSCHED SAP for a Frequency Domain Maximum Throughput scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class FdMtFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
FdMtFfMacScheduler ();
/**
* Destructor
*/
virtual ~FdMtFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class FdMtSchedulerMemberCschedSapProvider;
friend class FdMtSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Set of UE's RNTI in downlink
*/
std::set <uint16_t> m_flowStatsDl;
/*
* Set of UE's RNTI in uplink
*/
std::set <uint16_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
};
} // namespace ns3
#endif /* FDMT_FF_MAC_SCHEDULER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef FDTBFQ_FF_MAC_SCHEDULER_H
#define FDTBFQ_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <set>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
/**
* Flow information
*/
struct fdtbfqsFlowPerf_t
{
Time flowStart;
uint64_t packetArrivalRate; /// packet arrival rate( byte/s)
uint64_t tokenGenerationRate; /// token generation rate ( byte/s )
uint32_t tokenPoolSize; /// current size of token pool (byte)
uint32_t maxTokenPoolSize; /// maximum size of token pool (byte)
int counter; /// the number of token borrow or given to token bank
uint32_t burstCredit; /// the maximum number of tokens connection i can borrow from the bank each time
int debtLimit; /// counter threshold that the flow cannot further borrow tokens from bank
uint32_t creditableThreshold; /// the flow cannot borrow token from bank until the number of token it has deposited to bank reaches this threshold
};
/**
* \ingroup lte
* \brief Implements the SCHED SAP and CSCHED SAP for a Frequency Domain Token Bank Fair Queue scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class FdTbfqFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
FdTbfqFfMacScheduler ();
/**
* Destructor
*/
virtual ~FdTbfqFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class FdTbfqSchedulerMemberCschedSapProvider;
friend class FdTbfqSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Map of UE statistics (per RNTI basis) in downlink
*/
std::map <uint16_t, fdtbfqsFlowPerf_t> m_flowStatsDl;
/*
* Map of UE statistics (per RNTI basis)
*/
std::map <uint16_t, fdtbfqsFlowPerf_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
double m_timeWindow;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
uint64_t bankSize; // the number of bytes in token bank
int m_debtLimit; // flow debt limit (byte)
uint32_t m_creditLimit; // flow credit limit (byte)
uint32_t m_tokenPoolSize; // maximum size of token pool (byte)
uint32_t m_creditableThreshold; // threshold of flow credit
};
} // namespace ns3
#endif /* FDTBFQ_FF_MAC_SCHEDULER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,225 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef PSS_FF_MAC_SCHEDULER_H
#define PSS_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <algorithm>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
/**
* Flow information
*/
struct pssFlowPerf_t
{
Time flowStart;
unsigned long totalBytesTransmitted; /// Total bytes send by eNb for this UE
unsigned int lastTtiBytesTransmitted; /// Total bytes send by eNB in last tti for this UE
double lastAveragedThroughput; /// Past average throughput
double secondLastAveragedThroughput;
double targetThroughput; /// Target throughput
};
/**
* \ingroup lte
* \brief Implements the SCHED SAP and CSCHED SAP for a Priority Set scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class PssFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
PssFfMacScheduler ();
/**
* Destructor
*/
virtual ~PssFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class PssSchedulerMemberCschedSapProvider;
friend class PssSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Map of UE statistics (per RNTI basis) in downlink
*/
std::map <uint16_t, pssFlowPerf_t> m_flowStatsDl;
/*
* Map of UE statistics (per RNTI basis)
*/
std::map <uint16_t, pssFlowPerf_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
double m_timeWindow;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
std::string m_fdSchedulerType;
uint32_t m_nMux; // TD scheduler selects nMux UEs and transfer them to FD scheduler
};
} // namespace ns3
#endif /* PSS_FF_MAC_SCHEDULER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,216 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef TDBET_FF_MAC_SCHEDULER_H
#define TDBET_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
struct tdbetsFlowPerf_t
{
Time flowStart;
unsigned long totalBytesTransmitted;
unsigned int lastTtiBytesTransmitted;
double lastAveragedThroughput;
};
/**
* \ingroup lte
* \brief Implements the SCHED SAP and CSCHED SAP for a Time Domain Blind Equal Throughput scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class TdBetFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
TdBetFfMacScheduler ();
/**
* Destructor
*/
virtual ~TdBetFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class TdBetSchedulerMemberCschedSapProvider;
friend class TdBetSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Map of UE statistics (per RNTI basis) in downlink
*/
std::map <uint16_t, tdbetsFlowPerf_t> m_flowStatsDl;
/*
* Map of UE statistics (per RNTI basis)
*/
std::map <uint16_t, tdbetsFlowPerf_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
double m_timeWindow;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
};
} // namespace ns3
#endif /* TDBET_FF_MAC_SCHEDULER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef TDMT_FF_MAC_SCHEDULER_H
#define TDMT_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <set>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
/**
* \ingroup lte
*
* \brief Implements the SCHED SAP and CSCHED SAP for a Time Domain Maximum Throughput scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class TdMtFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
TdMtFfMacScheduler ();
/**
* Destructor
*/
virtual ~TdMtFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class TdMtSchedulerMemberCschedSapProvider;
friend class TdMtSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Set of UE's RNTI in downlink
*/
std::set <uint16_t> m_flowStatsDl;
/*
* Set of UE's RNTI in uplink
*/
std::set <uint16_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
};
} // namespace ns3
#endif /* TDMT_FF_MAC_SCHEDULER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef TDTBFQ_FF_MAC_SCHEDULER_H
#define TDTBFQ_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <set>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
/**
* Flow information
*/
struct tdtbfqsFlowPerf_t
{
Time flowStart;
uint64_t packetArrivalRate; /// packet arrival rate( byte/s)
uint64_t tokenGenerationRate; /// token generation rate ( byte/s )
uint32_t tokenPoolSize; /// current size of token pool (byte)
uint32_t maxTokenPoolSize; /// maximum size of token pool (byte)
int counter; /// the number of token borrow or given to token bank
uint32_t burstCredit; /// the maximum number of tokens connection i can borrow from the bank each time
int debtLimit; /// counter threshold that the flow cannot further borrow tokens from bank
uint32_t creditableThreshold; /// the flow cannot borrow token from bank until the number of token it has deposited to bank reaches this threshold
};
/**
* \ingroup lte
* \brief Implements the SCHED SAP and CSCHED SAP for a Frequency Domain Token Bank Fair Queue scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class TdTbfqFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
TdTbfqFfMacScheduler ();
/**
* Destructor
*/
virtual ~TdTbfqFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class TdTbfqSchedulerMemberCschedSapProvider;
friend class TdTbfqSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Map of UE statistics (per RNTI basis) in downlink
*/
std::map <uint16_t, tdtbfqsFlowPerf_t> m_flowStatsDl;
/*
* Map of UE statistics (per RNTI basis)
*/
std::map <uint16_t, tdtbfqsFlowPerf_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
double m_timeWindow;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
uint64_t bankSize; // the number of bytes in token bank
int m_debtLimit; // flow debt limit (byte)
uint32_t m_creditLimit; // flow credit limit (byte)
uint32_t m_tokenPoolSize; // maximum size of token pool (byte)
uint32_t m_creditableThreshold; // threshold of flow credit
};
} // namespace ns3
#endif /* TDTBFQ_FF_MAC_SCHEDULER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es> // original version
* Modification: Dizhi Zhou <dizhi.zhou@gmail.com> // modify codes related to downlink scheduler
*/
#ifndef TTA_FF_MAC_SCHEDULER_H
#define TTA_FF_MAC_SCHEDULER_H
#include <ns3/lte-common.h>
#include <ns3/ff-mac-csched-sap.h>
#include <ns3/ff-mac-sched-sap.h>
#include <ns3/ff-mac-scheduler.h>
#include <vector>
#include <map>
#include <set>
#include <ns3/nstime.h>
#include <ns3/lte-amc.h>
namespace ns3 {
/**
* \ingroup lte
*
* \brief Implements the SCHED SAP and CSCHED SAP for a Throughput to Average scheduler
*
* This class implements the interface defined by the FfMacScheduler abstract class
*/
class TtaFfMacScheduler : public FfMacScheduler
{
public:
/**
* \brief Constructor
*
* Creates the MAC Scheduler interface implementation
*/
TtaFfMacScheduler ();
/**
* Destructor
*/
virtual ~TtaFfMacScheduler ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
// inherited from FfMacScheduler
virtual void SetFfMacCschedSapUser (FfMacCschedSapUser* s);
virtual void SetFfMacSchedSapUser (FfMacSchedSapUser* s);
virtual FfMacCschedSapProvider* GetFfMacCschedSapProvider ();
virtual FfMacSchedSapProvider* GetFfMacSchedSapProvider ();
friend class TtaSchedulerMemberCschedSapProvider;
friend class TtaSchedulerMemberSchedSapProvider;
void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
// Implementation of the CSCHED API primitives
// (See 4.1 for description of the primitives)
//
void DoCschedCellConfigReq (const struct FfMacCschedSapProvider::CschedCellConfigReqParameters& params);
void DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params);
void DoCschedLcConfigReq (const struct FfMacCschedSapProvider::CschedLcConfigReqParameters& params);
void DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params);
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
//
void DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params);
void DoSchedDlPagingBufferReq (const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters& params);
void DoSchedDlMacBufferReq (const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters& params);
void DoSchedDlTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
void DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params);
void DoSchedDlCqiInfoReq (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params);
void DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params);
void DoSchedUlNoiseInterferenceReq (const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters& params);
void DoSchedUlSrInfoReq (const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters& params);
void DoSchedUlMacCtrlInfoReq (const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters& params);
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
int GetRbgSize (int dlbandwidth);
int LcActivePerFlow (uint16_t rnti);
double EstimateUlSinr (uint16_t rnti, uint16_t rb);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
Ptr<LteAmc> m_amc;
/*
* Vectors of UE's LC info
*/
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
/*
* Set of UE's RNTI in downlink
*/
std::set <uint16_t> m_flowStatsDl;
/*
* Set of UE's RNTI in uplink
*/
std::set <uint16_t> m_flowStatsUl;
/*
* Map of UE's DL CQI P01 received
*/
std::map <uint16_t,uint8_t> m_p10CqiRxed;
/*
* Map of UE's timers on DL CQI P01 received
*/
std::map <uint16_t,uint32_t> m_p10CqiTimers;
/*
* Map of UE's DL CQI A30 received
*/
std::map <uint16_t,SbMeasResult_s> m_a30CqiRxed;
/*
* Map of UE's timers on DL CQI A30 received
*/
std::map <uint16_t,uint32_t> m_a30CqiTimers;
/*
* Map of previous allocated UE per RBG
* (used to retrieve info from UL-CQI)
*/
std::map <uint16_t, std::vector <uint16_t> > m_allocationMaps;
/*
* Map of UEs' UL-CQI per RBG
*/
std::map <uint16_t, std::vector <double> > m_ueCqi;
/*
* Map of UEs' timers on UL-CQI per RBG
*/
std::map <uint16_t, uint32_t> m_ueCqiTimers;
/*
* Map of UE's buffer status reports received
*/
std::map <uint16_t,uint32_t> m_ceBsrRxed;
// MAC SAPs
FfMacCschedSapUser* m_cschedSapUser;
FfMacSchedSapUser* m_schedSapUser;
FfMacCschedSapProvider* m_cschedSapProvider;
FfMacSchedSapProvider* m_schedSapProvider;
// Internal parameters
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig;
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
};
} // namespace ns3
#endif /* TTA_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,530 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
#include "lte-test-fdbet-ff-mac-scheduler.h"
NS_LOG_COMPONENT_DEFINE ("LenaTestFdBetFfMacCheduler");
namespace ns3 {
LenaTestFdBetFfMacSchedulerSuite::LenaTestFdBetFfMacSchedulerSuite ()
: TestSuite ("lte-fdbet-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestFdBetFfMacSchedulerSuite");
//Test Case 1: AMC works in FDBET
// DOWNLINK- DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec
// UPLINK- DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (1,0,0,2196000,2292000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (3,0,0,749000,749000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (6,0,0,373000,373000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (12,0,0,185000,185000));
// DOWNLINK - DISTANCE 3000 -> MCS 22 -> Itbs 20 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 20 -> 1383 -> 1383000 bytes/sec
// 3 users -> 8 PRB at Itbs 20 -> 469 -> 469000 bytes/sec
// 6 users -> 4 PRB at Itbs 20 -> 233 -> 233000 bytes/sec
// 12 users -> 2 PRB at Itbs 20 -> 113 -> 113000 bytes/sec
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 bytes/sec
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (1,0,3000,1383000,1239000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (3,0,3000,469000,389000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (6,0,3000,233500,193000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (12,0,3000,113000,97000));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 15 -> 903 -> 903000 bytes/sec
// 3 users -> 8 PRB at Itbs 15 -> 309 -> 309000 bytes/sec
// 6 users -> 4 PRB at Itbs 15 -> 153 -> 153000 bytes/sec
// 12 users -> 2 PRB at Itbs 15 -> 75 -> 75000 bytes/sec
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (1,0,6000,903000,621000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (3,0,6000,309000,201000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (6,0,6000,153000,97000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (12,0,6000,75000,47000));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 11 -> 597 -> 597000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 bytes/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 bytes/sec
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (1,0,9000,597000,437000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (3,0,9000,201000,137000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (6,0,9000,97000,67000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (12,0,9000,47000,32000));
// DOWNLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 6 -> 309 -> 309000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 101 -> 101000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 49 -> 49000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 22 -> 22000 bytes/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (1,0,15000,309000,233000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (3,0,15000,101000,69000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (6,0,15000,49000,32000));
AddTestCase (new LenaFdBetFfMacSchedulerTestCase1 (12,0,15000,22000,15000));
// Test Case 2: fairness check
std::vector<uint16_t> dist;
dist.push_back (0); // User 0 distance --> MCS 28
dist.push_back (3000); // User 1 distance --> MCS 24
dist.push_back (6000); // User 2 distance --> MCS 16
dist.push_back (9000); // User 3 distance --> MCS 12
std::vector<uint32_t> estAchievableRateDl;
estAchievableRateDl.push_back (2196000);
estAchievableRateDl.push_back (1383000);
estAchievableRateDl.push_back (903000);
estAchievableRateDl.push_back (597000);
std::vector<uint32_t> estThrFdBetUl;
estThrFdBetUl.push_back (549000); // User 0 estimated TTI throughput from FDBET
estThrFdBetUl.push_back (293000); // User 1 estimated TTI throughput from FDBET
estThrFdBetUl.push_back (149000); // User 2 estimated TTI throughput from FDBET
estThrFdBetUl.push_back (101000); // User 3 estimated TTI throughput from FDBET
AddTestCase (new LenaFdBetFfMacSchedulerTestCase2 (dist, estAchievableRateDl, estThrFdBetUl));
}
static LenaTestFdBetFfMacSchedulerSuite lenaTestFdBetFfMacSchedulerSuite;
// --------------- T E S T - C A S E # 1 ------------------------------
std::string
LenaFdBetFfMacSchedulerTestCase1::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaFdBetFfMacSchedulerTestCase1::LenaFdBetFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaFdBetFfMacSchedulerTestCase1::~LenaFdBetFfMacSchedulerTestCase1 ()
{
}
void
LenaFdBetFfMacSchedulerTestCase1::DoRun (void)
{
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbFdBetc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeFdBetc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("FdBetFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestFdBetFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::FdBetFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
lteHelper->EnableRlcTraces ();
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "FD blind equal throughput" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
/**
* Check that the assignation is done in a "FD blind equal throughput" manner among users
* with equal SINRs: the bandwidth should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*/
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Unfair Throughput!");
}
/**
* Check that the uplink assignation is done in a "FD blind equal throughput" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
/**
* Check that the assignation is done in a "FD blind equal throughput" manner among users
* with equal SINRs: the bandwidht should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*/
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
// --------------- T E S T - C A S E # 2 ------------------------------
std::string
LenaFdBetFfMacSchedulerTestCase2::BuildNameString (uint16_t nUser, std::vector<uint16_t> dist)
{
std::ostringstream oss;
oss << "distances (m) = [ " ;
for (std::vector<uint16_t>::iterator it = dist.begin (); it != dist.end (); ++it)
{
oss << *it << " ";
}
oss << "]";
return oss.str ();
}
LenaFdBetFfMacSchedulerTestCase2::LenaFdBetFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estAchievableRateDl, std::vector<uint32_t> estThrFdBetUl)
: TestCase (BuildNameString (dist.size (), dist)),
m_nUser (dist.size ()),
m_dist (dist),
m_achievableRateDl (estAchievableRateDl),
m_estThrFdBetUl (estThrFdBetUl)
{
}
LenaFdBetFfMacSchedulerTestCase2::~LenaFdBetFfMacSchedulerTestCase2 ()
{
}
void
LenaFdBetFfMacSchedulerTestCase2::DoRun (void)
{
// LogComponentEnable ("LteEnbFdBetc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeFdBetc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("FdBetFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestFdBetFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::FdBetFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
lteHelper->EnableRlcTraces ();
double simulationTime = 1;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s)");
std::vector <uint64_t> dlDataRxed;
double totalData = 0;
double estTotalThr = 0;
double estUeThr = 0;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
totalData += (double)dlDataRxed.at (i);
estTotalThr += 1 / m_achievableRateDl.at (i);
//NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_nUser);
}
estTotalThr = m_nUser * (1 / estTotalThr);
estUeThr = estTotalThr / m_nUser;
/**
* Check that the assignation is done in a "FD blind equal throughput" manner among users
* with different SINRs: the bandwidth should be distributed equally in long term
*/
for (int i = 0; i < m_nUser; i++)
{
double thrRatio = (double) 1 / m_nUser;
double estThrRatio = (double)dlDataRxed.at (i) / totalData;
NS_LOG_INFO ("\tUser " << i << " thrRatio " << thrRatio << " estThrRatio " << estThrRatio);
NS_TEST_ASSERT_MSG_EQ_TOL (estThrRatio, thrRatio, tolerance, " Unfair Throughput!");
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, estUeThr, estUeThr * tolerance, " Unfair Throughput!");
}
/**
* Check that the assignation in uplink is done in a round robin manner.
*/
NS_LOG_INFO ("UL - Test with " << m_nUser);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << (double)m_estThrFdBetUl.at (i));
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, (double)m_estThrFdBetUl.at (i), (double)m_estThrFdBetUl.at (i) * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
} // namespace ns3

View File

@@ -0,0 +1,89 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_TDBET_FF_MAC_SCHEDULER_H
#define LENA_TEST_TDBET_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
namespace ns3 {
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is equal among users is consistent with the definition of blind equal throughput
* scheduling
*/
class LenaFdBetFfMacSchedulerTestCase1 : public TestCase
{
public:
LenaFdBetFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl);
virtual ~LenaFdBetFfMacSchedulerTestCase1 ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
double m_thrRefDl;
double m_thrRefUl;
};
class LenaFdBetFfMacSchedulerTestCase2 : public TestCase
{
public:
LenaFdBetFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> m_achievableRateDl, std::vector<uint32_t> estThrFdBetUl);
virtual ~LenaFdBetFfMacSchedulerTestCase2 ();
private:
static std::string BuildNameString (uint16_t nUser, std::vector<uint16_t> dist);
virtual void DoRun (void);
uint16_t m_nUser;
std::vector<uint16_t> m_dist;
std::vector<uint32_t> m_achievableRateDl;
std::vector<uint32_t> m_estThrFdBetUl;
};
class LenaTestFdBetFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestFdBetFfMacSchedulerSuite ();
};
} // namespace ns3
#endif /* LENA_TEST_TDBET_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,347 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include "lte-test-fdmt-ff-mac-scheduler.h"
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
NS_LOG_COMPONENT_DEFINE ("LenaTestFdMtFfMacCheduler");
using namespace ns3;
LenaTestFdMtFfMacSchedulerSuite::LenaTestFdMtFfMacSchedulerSuite ()
: TestSuite ("lte-fdmt-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestFdMtFfMacSchedulerSuite");
//Test Case : AMC works in FDMT
// DOWNLINK - DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 2196000 among 3 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 2196000 among 6 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 2196000 among 12 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 2196000 among 15 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK- DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec
// 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (1,0,0,2196000,2292000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (3,0,0,2196000,749000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (6,0,0,2196000,373000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (12,0,0,2196000,185000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (15,0,0,2196000,89000));
// DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 30 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 20 -> 1383 -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 1383000 among 3 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 1383000 among 6 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 1383000 among 12 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 1383000 among 15 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 bytes/sec
// 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (1,0,3000,1383000,1239000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (3,0,3000,1383000,389000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (6,0,3000,1383000,193000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (12,0,3000,1383000,97000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (15,0,3000,1383000,47000));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 15 -> 903 -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 903000 among 3 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 903000 among 6 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 903000 among 12 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 903000 among 15 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 bytes/sec
// 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (1,0,6000,903000,621000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (3,0,6000,903000,201000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (6,0,6000,903000,97000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (12,0,6000,903000,47000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (15,0,6000,903000,22000));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 11 -> 597 -> 597000 bytes/sec
// 3 users -> 597000 among 3 users -> 199000 bytes/sec
// 6 users -> 597000 among 6 users -> 99500 bytes/sec
// 12 users -> 597000 among 12 users -> 49750 bytes/sec
// 15 users -> 597000 among 15 users -> 39800 bytes/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 bytes/sec
// 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (1,0,9000,597000,437000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (3,0,9000,597000,137000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (6,0,9000,597000,67000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (12,0,9000,597000,32000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (15,0,9000,597000,15000));
// DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 6 -> 309 -> 309000 bytes/sec
// 3 users -> 309000 among 3 users -> 103000 bytes/sec
// 6 users -> 309000 among 6 users -> 51500 bytes/sec
// 12 users -> 309000 among 12 users -> 25750 bytes/sec
// 15 users -> 309000 among 15 users -> 20600 bytes/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 bytes/sec
// 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (1,0,15000,309000,233000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (3,0,15000,309000,69000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (6,0,15000,309000,32000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (12,0,15000,309000,15000));
AddTestCase (new LenaFdMtFfMacSchedulerTestCase (15,0,15000,309000,7000));
}
static LenaTestFdMtFfMacSchedulerSuite lenaTestFdMtFfMacSchedulerSuite;
// --------------- T E S T - C A S E ------------------------------
std::string
LenaFdMtFfMacSchedulerTestCase::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaFdMtFfMacSchedulerTestCase::LenaFdMtFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaFdMtFfMacSchedulerTestCase::~LenaFdMtFfMacSchedulerTestCase ()
{
}
void
LenaFdMtFfMacSchedulerTestCase::DoRun (void)
{
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("FdMtFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestFdMtFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::FdMtFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
lteHelper->EnableRlcTraces ();
lteHelper->EnableMacTraces ();
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "maximum throughput" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
/**
* Check that the assignation is done in a "maximum throughput" manner among users
* with equal SINRs: all bandwidth should be allocated to the first UE in script
*/
for (int i = 0; i < 1; i++)
{
if (i == 0)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Invalid Throughput!");
}
else
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, 0, tolerance, " Invalid Throughput!");
}
}
/**
* Check that the uplink assignation is done in a "maximum throughput" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
/**
* Check that the assignation is done in a "maximum throughput" manner among users
* with equal SINRs: the bandwidht should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*
*/
for (int i = 0; i < 1; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}

View File

@@ -0,0 +1,67 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_FDMT_FF_MAC_SCHEDULER_H
#define LENA_TEST_FDMT_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
using namespace ns3;
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is consistent with the definition of maximum throughput
* scheduling
*/
class LenaFdMtFfMacSchedulerTestCase : public TestCase
{
public:
LenaFdMtFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl);
virtual ~LenaFdMtFfMacSchedulerTestCase ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
double m_thrRefDl;
double m_thrRefUl;
};
class LenaTestFdMtFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestFdMtFfMacSchedulerSuite ();
};
#endif /* LENA_TEST_FDMT_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,764 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
#include "ns3/epc-helper.h"
#include "ns3/network-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-helper.h"
#include "lte-test-fdtbfq-ff-mac-scheduler.h"
NS_LOG_COMPONENT_DEFINE ("LenaTestFdTbfqFfMacCheduler");
namespace ns3 {
LenaTestFdTbfqFfMacSchedulerSuite::LenaTestFdTbfqFfMacSchedulerSuite ()
: TestSuite ("lte-fdtbfq-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestFdTbfqFfMacSchedulerSuite");
// General config
// Traffic: UDP traffic with fixed rate
// Token generation rate = traffic rate
// RLC header length = 2 bytes, PDCP header = 2 bytes
// Simulation time = 1.0 sec
// Throughput in this file is calculated in RLC layer
//Test Case 1: homogeneous flow test in FDTBFQ (same distance)
// DOWNLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 26 -> 2196 -> 2196000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 2196000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 2196000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 < 2196000 -> throughput = 232000 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 2196000 -> throughput = 2196000 / 12 = 183000 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 2196000 -> throughput = 2196000 / 15 = 146400 byte/sec
// UPLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 > 232000 -> throughput = 232000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 > 232000 -> throughput = 232000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 < 232000 -> throughput = 185000 bytes/sec
// 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (1,0,0,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (3,0,0,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (6,0,0,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (12,0,0,183000,185000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (15,0,0,146400,89000,200,1));
// DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 20 (from table 7.1.7.2.1-1 of 36.213)
// DOWNLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 20 -> 1383 -> 1383000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 1383000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 1383000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 > 1383000 -> throughput = 1383000 / 6 = 230500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 1383000 -> throughput = 1383000 / 12 = 115250 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 1383000 -> throughput = 1383000 / 15 = 92200 byte/sec
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 > 232000 -> throughput = 232000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 < 232000 -> throughput = 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 < 232000 -> throughput = 97000 bytes/sec
// 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (1,0,3000,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (3,0,3000,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (6,0,3000,230500,193000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (12,0,3000,115250,97000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (15,0,3000,92200,47000,200,1));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 15 -> 903 -> 903000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 903000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 903000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 > 903000 -> throughput = 903000 / 6 = 150500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 903000 -> throughput = 903000 / 12 = 75250 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 903000 -> throughput = 903000 / 15 = 60200 byte/sec
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 < 232000 -> throughput = 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 < 232000 -> throughput = 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 < 232000 -> throughput = 47000 bytes/sec
// 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (1,0,6000,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (3,0,6000,232000,201000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (6,0,6000,150500,97000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (12,0,6000,75250,47000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (15,0,6000,60200,22000,200,1));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 11 -> 597 -> 597000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 597000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 > 597000 -> througphut = 597000 / 3 = 199000byte/sec
// 6 user -> 232000 * 6 = 139200 > 597000 -> throughput = 597000 / 6 = 99500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 597000 -> throughput = 597000 / 12 = 49750 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 597000 -> throughput = 597000 / 15 = 39800 byte/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 < 232000 -> throughput = 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 < 232000 -> throughput = 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 < 232000 -> throughput = 32000 bytes/sec
// 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (1,0,9000,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (3,0,9000,199000,137000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (6,0,9000,99500,67000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (12,0,9000,49750,32000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (15,0,9000,39800,15000,200,1));
// DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 6 -> 309 -> 309000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 309000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 > 309000 -> througphut = 309000 / 3 = 103000byte/sec
// 6 user -> 232000 * 6 = 139200 > 309000 -> throughput = 309000 / 6 = 51500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 309000 -> throughput = 309000 / 12 = 25750 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 309000 -> throughput = 309000 / 15 = 20600 byte/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 < 232000 -> throughput = 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 < 232000 -> throughput = 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 < 232000 -> throughput = 15000 bytes/sec
// 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (1,0,15000,232000,232000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (3,0,15000,103000,69000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (6,0,15000,51500,32000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (12,0,15000,25750,15000,200,1));
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase1 (15,0,15000,20600,7000,200,1));
// Test Case 2: homogeneous flow test in FDTBFQ (different distance)
// Traffic1 info
// UDP traffic: payload size = 100 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 132000 byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 + 1/597000 + 1/309000) = 694720 byte/s
// 132000 * 5 = 660000 < 694720 -> estimated throughput in downlink = 132000 byte/sec
std::vector<uint16_t> dist1;
dist1.push_back (0); // User 0 distance --> MCS 28
dist1.push_back (3000); // User 1 distance --> MCS 24
dist1.push_back (6000); // User 2 distance --> MCS 16
dist1.push_back (9000); // User 3 distance --> MCS 12
dist1.push_back (15000); // User 4 distance --> MCS 6
std::vector<uint16_t> packetSize1;
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
std::vector<uint32_t> estThrFdTbfqDl1;
estThrFdTbfqDl1.push_back (132000); // User 0 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl1.push_back (132000); // User 1 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl1.push_back (132000); // User 2 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl1.push_back (132000); // User 3 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl1.push_back (132000); // User 4 estimated TTI throughput from FDTBFQ
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase2 (dist1,estThrFdTbfqDl1,packetSize1,1));
// Traffic2 info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 + 1/597000 + 1/309000) = 694720 byte/s
// 232000 * 5 = 1160000 > 694720 -> estimated throughput in downlink = 694720 / 5 = 138944 byte/sec
std::vector<uint16_t> dist2;
dist2.push_back (0); // User 0 distance --> MCS 28
dist2.push_back (3000); // User 1 distance --> MCS 24
dist2.push_back (6000); // User 2 distance --> MCS 16
dist2.push_back (9000); // User 3 distance --> MCS 12
dist2.push_back (15000); // User 4 distance --> MCS 6
std::vector<uint16_t> packetSize2;
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
std::vector<uint32_t> estThrFdTbfqDl2;
estThrFdTbfqDl2.push_back (138944); // User 0 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl2.push_back (138944); // User 1 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl2.push_back (138944); // User 2 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl2.push_back (138944); // User 3 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl2.push_back (138944); // User 4 estimated TTI throughput from FDTBFQ
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase2 (dist2,estThrFdTbfqDl2,packetSize2,1));
// Test Case 3: heterogeneous flow test in FDTBFQ
// UDP traffic: payload size = [100,200,300] bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> [132000, 232000, 332000] byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 ) = 1312417 byte/s
// 132000 + 232000 + 332000 = 696000 < 1312417 -> estimated throughput in downlink = [132000, 232000, 332000] byte/sec
std::vector<uint16_t> dist3;
dist3.push_back (0); // User 0 distance --> MCS 28
dist3.push_back (3000); // User 1 distance --> MCS 24
dist3.push_back (6000); // User 2 distance --> MCS 16
std::vector<uint16_t> packetSize3;
packetSize3.push_back (100);
packetSize3.push_back (200);
packetSize3.push_back (300);
std::vector<uint32_t> estThrFdTbfqDl3;
estThrFdTbfqDl3.push_back (132000); // User 0 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl3.push_back (232000); // User 1 estimated TTI throughput from FDTBFQ
estThrFdTbfqDl3.push_back (332000); // User 2 estimated TTI throughput from FDTBFQ
AddTestCase (new LenaFdTbfqFfMacSchedulerTestCase2 (dist3,estThrFdTbfqDl3,packetSize3,1));
}
static LenaTestFdTbfqFfMacSchedulerSuite lenaTestFdTbfqFfMacSchedulerSuite;
// --------------- T E S T - C A S E # 1 ------------------------------
std::string
LenaFdTbfqFfMacSchedulerTestCase1::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaFdTbfqFfMacSchedulerTestCase1::LenaFdTbfqFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl, uint16_t packetSize, uint16_t interval)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_packetSize (packetSize),
m_interval (interval),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaFdTbfqFfMacSchedulerTestCase1::~LenaFdTbfqFfMacSchedulerTestCase1 ()
{
}
void
LenaFdTbfqFfMacSchedulerTestCase1::DoRun (void)
{
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
lteHelper->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteHelper::RLC_UM_ALWAYS));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("FdTbfqFfMacScheduler", LOG_LEVEL_AlL);
LogComponentEnable ("LenaTestFdTbfqFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::FdTbfqFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
}
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
GbrQosInformation qos;
qos.gbrDl = (m_packetSize + 32) * (1000 / m_interval) * 8; // bit/s, considering IP, UDP, RLC, PDCP header size
qos.gbrUl = 0;
qos.mbrDl = qos.gbrDl;
qos.mbrUl = 0;
EpsBearer bearer (q, qos);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
lteHelper->EnableMacTraces ();
lteHelper->EnableRlcTraces ();
lteHelper->EnablePdcpTraces ();
// Install downlind and uplink applications
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); // receive packets from UEs
UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
UdpClientHelper ulClient (remoteHostAddr, ulPort); // downlink packets generator
ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
clientApps.Add (dlClient.Install (remoteHost));
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
serverApps.Start (Seconds (0.001));
clientApps.Start (Seconds (0.001));
double simulationTime = 2.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "token bank fair queue" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
uint64_t data = rlcStats->GetDlRxData (imsi, lcId);
dlDataRxed.push_back (data);
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Unfair Throughput!");
}
/**
* Check that the uplink assignation is done in a "round robin" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
// --------------- T E S T - C A S E # 2 ------------------------------
std::string
LenaFdTbfqFfMacSchedulerTestCase2::BuildNameString (uint16_t nUser, std::vector<uint16_t> dist)
{
std::ostringstream oss;
oss << "distances (m) = [ " ;
for (std::vector<uint16_t>::iterator it = dist.begin (); it != dist.end (); ++it)
{
oss << *it << " ";
}
oss << "]";
return oss.str ();
}
LenaFdTbfqFfMacSchedulerTestCase2::LenaFdTbfqFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estThrFdTbfqDl, std::vector<uint16_t> packetSize, uint16_t interval)
: TestCase (BuildNameString (dist.size (), dist)),
m_nUser (dist.size ()),
m_dist (dist),
m_packetSize (packetSize),
m_interval (interval),
m_estThrFdTbfqDl (estThrFdTbfqDl)
{
}
LenaFdTbfqFfMacSchedulerTestCase2::~LenaFdTbfqFfMacSchedulerTestCase2 ()
{
}
void
LenaFdTbfqFfMacSchedulerTestCase2::DoRun (void)
{
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
lteHelper->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteHelper::RLC_UM_ALWAYS));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("FdTbfqFfMacScheduler", LOG_LEVEL_AlL);
LogComponentEnable ("LenaTestFdTbfqFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::FdTbfqFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
}
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
GbrQosInformation qos;
uint16_t mbrDl = 0;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
mbrDl = mbrDl + m_packetSize.at (u);
}
mbrDl = mbrDl / ueNodes.GetN ();
qos.gbrDl = (mbrDl + 32) * (1000 / m_interval) * 8; // bit/s, considering IP, UDP, RLC, PDCP header size
qos.gbrUl = 0;
qos.mbrDl = qos.gbrDl;
qos.mbrUl = 0;
EpsBearer bearer (q, qos);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
lteHelper->EnableMacTraces ();
lteHelper->EnableRlcTraces ();
lteHelper->EnablePdcpTraces ();
// Install downlind and uplink applications
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); // receive packets from UEs
UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
UdpClientHelper ulClient (remoteHostAddr, ulPort); // downlink packets generator
ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
clientApps.Add (dlClient.Install (remoteHost));
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
serverApps.Start (Seconds (0.001));
clientApps.Start (Seconds (0.001));
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "token bank fair queue" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s)");
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_nUser);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_estThrFdTbfqDl.at (i), m_estThrFdTbfqDl.at (i) * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
} // namespace ns3

View File

@@ -0,0 +1,90 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_FDTBFQ_FF_MAC_SCHEDULER_H
#define LENA_TEST_FDTBFQ_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
namespace ns3 {
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is equal among users is consistent with the definition of token bank fair
* queue scheduling
*/
class LenaFdTbfqFfMacSchedulerTestCase1 : public TestCase
{
public:
LenaFdTbfqFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl, uint16_t packetSize, uint16_t interval);
virtual ~LenaFdTbfqFfMacSchedulerTestCase1 ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
uint16_t m_packetSize; // byte
uint16_t m_interval; // ms
double m_thrRefDl;
double m_thrRefUl;
};
class LenaFdTbfqFfMacSchedulerTestCase2 : public TestCase
{
public:
LenaFdTbfqFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estThrFdTbfqDl, std::vector<uint16_t> packetSize, uint16_t interval);
virtual ~LenaFdTbfqFfMacSchedulerTestCase2 ();
private:
static std::string BuildNameString (uint16_t nUser, std::vector<uint16_t> dist);
virtual void DoRun (void);
uint16_t m_nUser;
std::vector<uint16_t> m_dist;
std::vector<uint16_t> m_packetSize; // byte
uint16_t m_interval; // ms
std::vector<uint32_t> m_estThrFdTbfqDl;
};
class LenaTestFdTbfqFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestFdTbfqFfMacSchedulerSuite ();
};
} // namespace ns3
#endif /* LENA_TEST_FDTBFQ_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,791 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
#include "ns3/epc-helper.h"
#include "ns3/network-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-helper.h"
#include "lte-test-pss-ff-mac-scheduler.h"
NS_LOG_COMPONENT_DEFINE ("LenaTestPssFfMacCheduler");
namespace ns3 {
LenaTestPssFfMacSchedulerSuite::LenaTestPssFfMacSchedulerSuite ()
: TestSuite ("lte-pss-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestPssFfMacSchedulerSuite");
// General config
// Traffic: UDP traffic with fixed rate
// Token generation rate = traffic rate
// RLC header length = 2 bytes, PDCP header = 2 bytes
// Simulation time = 1.0 sec
// Throughput in this file is calculated in RLC layer
//Test Case 1: homogeneous flow test in PSS (same distance)
// DOWNLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 26 -> 2196 -> 2196000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 2196000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 2196000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 < 2196000 -> throughput = 232000 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 2196000 -> throughput = 2196000 / 12 = 183000 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 2196000 -> throughput = 2196000 / 15 = 146400 byte/sec
// UPLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 > 232000 -> throughput = 232000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 > 232000 -> throughput = 232000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 < 232000 -> throughput = 185000 bytes/sec
// 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (1,0,0,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (3,0,0,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (6,0,0,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (12,0,0,183000,185000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (15,0,0,146400,89000,200,1));
// DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 20 (from table 7.1.7.2.1-1 of 36.213)
// DOWNLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 20 -> 1383 -> 1383000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 1383000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 1383000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 > 1383000 -> throughput = 1383000 / 6 = 230500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 1383000 -> throughput = 1383000 / 12 = 115250 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 1383000 -> throughput = 1383000 / 15 = 92200 byte/sec
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 > 232000 -> throughput = 232000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 < 232000 -> throughput = 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 < 232000 -> throughput = 97000 bytes/sec
// 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (1,0,3000,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (3,0,3000,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (6,0,3000,230500,193000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (12,0,3000,115250,97000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (15,0,3000,92200,47000,200,1));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 15 -> 903 -> 903000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 903000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 903000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 > 903000 -> throughput = 903000 / 6 = 150500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 903000 -> throughput = 903000 / 12 = 75250 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 903000 -> throughput = 903000 / 15 = 60200 byte/sec
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 < 232000 -> throughput = 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 < 232000 -> throughput = 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 < 232000 -> throughput = 47000 bytes/sec
// 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (1,0,6000,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (3,0,6000,232000,201000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (6,0,6000,150500,97000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (12,0,6000,75250,47000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (15,0,6000,60200,22000,200,1));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 11 -> 597 -> 597000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 597000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 > 597000 -> througphut = 597000 / 3 = 199000byte/sec
// 6 user -> 232000 * 6 = 139200 > 597000 -> throughput = 597000 / 6 = 99500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 597000 -> throughput = 597000 / 12 = 49750 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 597000 -> throughput = 597000 / 15 = 39800 byte/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 < 232000 -> throughput = 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 < 232000 -> throughput = 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 < 232000 -> throughput = 32000 bytes/sec
// 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (1,0,9000,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (3,0,9000,199000,137000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (6,0,9000,99500,67000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (12,0,9000,49750,32000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (15,0,9000,39800,15000,200,1));
// DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 6 -> 309 -> 309000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 309000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 > 309000 -> througphut = 309000 / 3 = 103000byte/sec
// 6 user -> 232000 * 6 = 139200 > 309000 -> throughput = 309000 / 6 = 51500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 309000 -> throughput = 309000 / 12 = 25750 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 309000 -> throughput = 309000 / 15 = 20600 byte/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 < 232000 -> throughput = 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 < 232000 -> throughput = 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 < 232000 -> throughput = 15000 bytes/sec
// 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (1,0,15000,232000,232000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (3,0,15000,103000,69000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (6,0,15000,51500,32000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (12,0,15000,25750,15000,200,1));
AddTestCase (new LenaPssFfMacSchedulerTestCase1 (15,0,15000,20600,7000,200,1));
// Test Case 2: homogeneous flow test in PSS (different distance)
// Traffic1 info
// UDP traffic: payload size = 100 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 132000 byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 + 1/597000 + 1/309000) = 694720 byte/s
// 132000 * 5 = 660000 < 694720 -> estimated throughput in downlink = 694720/5 = 132000 bytes/sec
std::vector<uint16_t> dist1;
dist1.push_back (0); // User 0 distance --> MCS 28
dist1.push_back (3000); // User 1 distance --> MCS 24
dist1.push_back (6000); // User 2 distance --> MCS 16
dist1.push_back (9000); // User 3 distance --> MCS 12
dist1.push_back (15000); // User 4 distance --> MCS 6
std::vector<uint16_t> packetSize1;
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
std::vector<uint32_t> estThrPssDl1;
estThrPssDl1.push_back (132000);
estThrPssDl1.push_back (132000);
estThrPssDl1.push_back (132000);
estThrPssDl1.push_back (132000);
estThrPssDl1.push_back (132000);
AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist1,estThrPssDl1,packetSize1,1));
// Traffic2 info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 132000 byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 + 1/597000 + 1/309000) = 694720 byte/s
// 232000 * 5 = 1160000 > 694720 -> estimated throughput in downlink = 694720/5 = 138944 bytes/sec
std::vector<uint16_t> dist2;
dist2.push_back (0); // User 0 distance --> MCS 28
dist2.push_back (3000); // User 1 distance --> MCS 24
dist2.push_back (6000); // User 2 distance --> MCS 16
dist2.push_back (9000); // User 3 distance --> MCS 12
dist2.push_back (15000); // User 4 distance --> MCS 6
std::vector<uint16_t> packetSize2;
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
std::vector<uint32_t> estThrPssDl2;
estThrPssDl2.push_back (138944);
estThrPssDl2.push_back (138944);
estThrPssDl2.push_back (138944);
estThrPssDl2.push_back (138944);
estThrPssDl2.push_back (138944);
AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist2,estThrPssDl2,packetSize2,1));
// Test Case 3: : heterogeneous flow test in PSS (same distance)
// Traffic3 info:
// UDP traffic: payload size = [100, 200,300,400,500] bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Maximum throughput = 2196000 byte/sec
// 132000 + 232000 + 332000 + 432000 + 532000 = 1660000 < 2196000 -> estimated throughput in downlink = [132000, 232000,332000, 432000, 53200] bytes/sec
std::vector<uint16_t> dist3;
dist3.push_back (0); // User 0 distance --> MCS 28
dist3.push_back (0); // User 1 distance --> MCS 24
dist3.push_back (0); // User 2 distance --> MCS 16
dist3.push_back (0); // User 3 distance --> MCS 12
dist3.push_back (0); // User 4 distance --> MCS 6
std::vector<uint16_t> packetSize3;
packetSize3.push_back (100);
packetSize3.push_back (200);
packetSize3.push_back (300);
packetSize3.push_back (400);
packetSize3.push_back (500);
std::vector<uint32_t> estThrPssDl3;
estThrPssDl3.push_back (132000);
estThrPssDl3.push_back (232000);
estThrPssDl3.push_back (332000);
estThrPssDl3.push_back (432000);
estThrPssDl3.push_back (532000);
AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist3,estThrPssDl3,packetSize3,1));
// Test Case 4: heterogeneous flow test in PSS (different distance)
// Traffic4 info
// UDP traffic: payload size = [100,200,300] bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> [132000, 232000, 332000] byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 ) = 1312417 byte/s
// 132000 + 232000 + 332000 = 696000 < 1312417 -> estimated throughput in downlink = [132000, 232000, 332000] byte/sec
std::vector<uint16_t> dist4;
dist4.push_back (0); // User 0 distance --> MCS 28
dist4.push_back (3000); // User 1 distance --> MCS 24
dist4.push_back (6000); // User 2 distance --> MCS 16
std::vector<uint16_t> packetSize4;
packetSize4.push_back (100);
packetSize4.push_back (200);
packetSize4.push_back (300);
std::vector<uint32_t> estThrPssDl4;
estThrPssDl4.push_back (132000); // User 0 estimated TTI throughput from PSS
estThrPssDl4.push_back (232000); // User 1 estimated TTI throughput from PSS
estThrPssDl4.push_back (332000); // User 2 estimated TTI throughput from PSS
AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist4,estThrPssDl4,packetSize4,1));
}
static LenaTestPssFfMacSchedulerSuite lenaTestPssFfMacSchedulerSuite;
// --------------- T E S T - C A S E # 1 ------------------------------
std::string
LenaPssFfMacSchedulerTestCase1::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaPssFfMacSchedulerTestCase1::LenaPssFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl, uint16_t packetSize, uint16_t interval)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_packetSize (packetSize),
m_interval (interval),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaPssFfMacSchedulerTestCase1::~LenaPssFfMacSchedulerTestCase1 ()
{
}
void
LenaPssFfMacSchedulerTestCase1::DoRun (void)
{
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
lteHelper->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteHelper::RLC_UM_ALWAYS));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("PssFfMacScheduler", LOG_LEVEL_AlL);
LogComponentEnable ("LenaTestPssFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::PssFfMacScheduler");
lteHelper->SetSchedulerAttribute("PssFdSchedulerType", StringValue("PFsch"));
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
// Activate an EPS bearer
Ptr<NetDevice> ueDevice = ueDevs.Get (u);
GbrQosInformation qos;
qos.gbrDl = (m_packetSize + 32) * (1000 / m_interval) * 8 * 1; // bit/
qos.gbrUl = (m_packetSize + 32) * (1000 / m_interval) * 8 * 1;
qos.mbrDl = 0;
qos.mbrUl = 0;
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q, qos);
lteHelper->ActivateEpsBearer (ueDevice, bearer, EpcTft::Default ());
}
lteHelper->EnableMacTraces ();
lteHelper->EnableRlcTraces ();
lteHelper->EnablePdcpTraces ();
// Install downlind and uplink applications
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); // receive packets from UEs
UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
UdpClientHelper ulClient (remoteHostAddr, ulPort); // downlink packets generator
ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
clientApps.Add (dlClient.Install (remoteHost));
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
serverApps.Start (Seconds (0.001));
clientApps.Start (Seconds (0.001));
double simulationTime = 2.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "priority set scheduler" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
uint64_t data = rlcStats->GetDlRxData (imsi, lcId);
dlDataRxed.push_back (data);
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Unfair Throughput!");
}
/**
* Check that the uplink assignation is done in a "round robin" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
// --------------- T E S T - C A S E # 2 ------------------------------
std::string
LenaPssFfMacSchedulerTestCase2::BuildNameString (uint16_t nUser, std::vector<uint16_t> dist)
{
std::ostringstream oss;
oss << "distances (m) = [ " ;
for (std::vector<uint16_t>::iterator it = dist.begin (); it != dist.end (); ++it)
{
oss << *it << " ";
}
oss << "]";
return oss.str ();
}
LenaPssFfMacSchedulerTestCase2::LenaPssFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estThrPssDl, std::vector<uint16_t> packetSize, uint16_t interval)
: TestCase (BuildNameString (dist.size (), dist)),
m_nUser (dist.size ()),
m_dist (dist),
m_packetSize (packetSize),
m_interval (interval),
m_estThrPssDl (estThrPssDl)
{
}
LenaPssFfMacSchedulerTestCase2::~LenaPssFfMacSchedulerTestCase2 ()
{
}
void
LenaPssFfMacSchedulerTestCase2::DoRun (void)
{
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
lteHelper->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteHelper::RLC_UM_ALWAYS));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("PssFfMacScheduler", LOG_LEVEL_AlL);
LogComponentEnable ("LenaTestPssFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::PssFfMacScheduler");
lteHelper->SetSchedulerAttribute ("PssFdSchedulerType", StringValue ("PFsch"));
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
// Activate an EPS bearer
Ptr<NetDevice> ueDevice = ueDevs.Get (u);
GbrQosInformation qos;
qos.gbrDl = (m_packetSize.at (u) + 32) * (1000 / m_interval) * 8 * 1; // bit/s, = Target Bit Rate(TBR)
qos.gbrUl = (m_packetSize.at (u) + 32) * (1000 / m_interval) * 8 * 1;
qos.mbrDl = qos.gbrDl;
qos.mbrUl = qos.gbrUl;
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q, qos);
lteHelper->ActivateEpsBearer (ueDevice, bearer, EpcTft::Default ());
}
lteHelper->EnableMacTraces ();
lteHelper->EnableRlcTraces ();
lteHelper->EnablePdcpTraces ();
// Install downlind and uplink applications
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); // receive packets from UEs
UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
UdpClientHelper ulClient (remoteHostAddr, ulPort); // downlink packets generator
ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
clientApps.Add (dlClient.Install (remoteHost));
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
serverApps.Start (Seconds (0.001));
clientApps.Start (Seconds (0.001));
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "priority set scheduler" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s)");
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_nUser);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_estThrPssDl.at (i), m_estThrPssDl.at (i) * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
} // namespace ns3

View File

@@ -0,0 +1,89 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_PSS_FF_MAC_SCHEDULER_H
#define LENA_TEST_PSS_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
namespace ns3 {
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is equal among users is consistent with the definition of priority set scheduling
*/
class LenaPssFfMacSchedulerTestCase1 : public TestCase
{
public:
LenaPssFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl, uint16_t packetSize, uint16_t interval);
virtual ~LenaPssFfMacSchedulerTestCase1 ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
uint16_t m_packetSize; // byte
uint16_t m_interval; // ms
double m_thrRefDl;
double m_thrRefUl;
};
class LenaPssFfMacSchedulerTestCase2 : public TestCase
{
public:
LenaPssFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estThrPssDl, std::vector<uint16_t> packetSize, uint16_t interval);
virtual ~LenaPssFfMacSchedulerTestCase2 ();
private:
static std::string BuildNameString (uint16_t nUser, std::vector<uint16_t> dist);
virtual void DoRun (void);
uint16_t m_nUser;
std::vector<uint16_t> m_dist;
std::vector<uint16_t> m_packetSize; // byte
uint16_t m_interval; // ms
std::vector<uint32_t> m_estThrPssDl;
};
class LenaTestPssFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestPssFfMacSchedulerSuite ();
};
} // namespace ns3
#endif /* LENA_TEST_PSS_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,548 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
#include "lte-test-tdbet-ff-mac-scheduler.h"
NS_LOG_COMPONENT_DEFINE ("LenaTestTdBetFfMacCheduler");
namespace ns3 {
LenaTestTdBetFfMacSchedulerSuite::LenaTestTdBetFfMacSchedulerSuite ()
: TestSuite ("lte-tdbet-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestTdBetFfMacSchedulerSuite");
//Test Case 1: AMC works in TDBET
// DOWNLINK - DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec
// 3 users -> 2196000 among 3 users -> 732000 bytes/sec
// 6 users -> 2196000 among 6 users -> 366000 bytes/sec
// 12 users -> 2196000 among 12 users -> 183000 bytes/sec
// 15 users -> 2196000 among 15 users -> 146400 bytes/sec
// UPLINK- DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec
// 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (1,0,0,2196000,2292000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (3,0,0,732000,749000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (6,0,0,366000,373000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (12,0,0,183000,185000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (15,0,0,146400,89000));
// DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 30 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 20 -> 1383 -> 1383000 bytes/sec
// 3 users -> 1383000 among 3 users -> 461000 bytes/sec
// 6 users -> 1383000 among 6 users -> 230500 bytes/sec
// 12 users -> 1383000 among 12 users -> 115250 bytes/sec
// 15 users -> 1383000 among 15 users -> 92200 bytes/sec
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 bytes/sec
// 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (1,0,3000,1383000,1239000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (3,0,3000,461000,389000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (6,0,3000,230500,193000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (12,0,3000,115250,97000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (15,0,3000,92200,47000));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 15 -> 903 -> 903000 bytes/sec
// 3 users -> 903000 among 3 users -> 301000 bytes/sec
// 6 users -> 903000 among 6 users -> 150500 bytes/sec
// 12 users -> 903000 among 12 users -> 75250 bytes/sec
// 15 users -> 903000 among 15 users -> 60200 bytes/sec
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 bytes/sec
// 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (1,0,6000,903000,621000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (3,0,6000,301000,201000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (6,0,6000,150500,97000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (12,0,6000,75250,47000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (15,0,6000,60200,22000));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 11 -> 597 -> 597000 bytes/sec
// 3 users -> 597000 among 3 users -> 199000 bytes/sec
// 6 users -> 597000 among 6 users -> 99500 bytes/sec
// 12 users -> 597000 among 12 users -> 49750 bytes/sec
// 15 users -> 597000 among 15 users -> 39800 bytes/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 bytes/sec
// 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (1,0,9000,597000,437000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (3,0,9000,199000,137000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (6,0,9000,99500,67000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (12,0,9000,49750,32000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (15,0,9000,39800,15000));
// DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 6 -> 309 -> 309000 bytes/sec
// 3 users -> 309000 among 3 users -> 103000 bytes/sec
// 6 users -> 309000 among 6 users -> 51500 bytes/sec
// 12 users -> 309000 among 12 users -> 25750 bytes/sec
// 15 users -> 309000 among 15 users -> 20600 bytes/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 bytes/sec
// 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (1,0,15000,309000,233000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (3,0,15000,103000,69000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (6,0,15000,51500,32000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (12,0,15000,25750,15000));
AddTestCase (new LenaTdBetFfMacSchedulerTestCase1 (15,0,15000,20600,7000));
// Test Case 2: fairness check
std::vector<uint16_t> dist;
dist.push_back (0); // User 0 distance --> MCS 28
dist.push_back (3000); // User 1 distance --> MCS 24
dist.push_back (6000); // User 2 distance --> MCS 16
dist.push_back (9000); // User 3 distance --> MCS 12
dist.push_back (15000); // User 4 distance --> MCS 6
std::vector<uint32_t> estAchievableRateDl;
estAchievableRateDl.push_back (2196000);
estAchievableRateDl.push_back (1383000);
estAchievableRateDl.push_back (903000);
estAchievableRateDl.push_back (597000);
estAchievableRateDl.push_back (309000);
std::vector<uint32_t> estThrTdBetUl;
estThrTdBetUl.push_back (469000); // User 0 estimated TTI throughput from TDBET
estThrTdBetUl.push_back (249000); // User 1 estimated TTI throughput from TDBET
estThrTdBetUl.push_back (125000); // User 2 estimated TTI throughput from TDBET
estThrTdBetUl.push_back (85000); // User 3 estimated TTI throughput from TDBET
estThrTdBetUl.push_back (41000); // User 4 estimated TTI throughput from TDBET
AddTestCase (new LenaTdBetFfMacSchedulerTestCase2 (dist, estAchievableRateDl, estThrTdBetUl));
}
static LenaTestTdBetFfMacSchedulerSuite lenaTestTdBetFfMacSchedulerSuite;
// --------------- T E S T - C A S E # 1 ------------------------------
std::string
LenaTdBetFfMacSchedulerTestCase1::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaTdBetFfMacSchedulerTestCase1::LenaTdBetFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaTdBetFfMacSchedulerTestCase1::~LenaTdBetFfMacSchedulerTestCase1 ()
{
}
void
LenaTdBetFfMacSchedulerTestCase1::DoRun (void)
{
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("TdBetFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestTdBetFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::TdBetFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
lteHelper->EnableRlcTraces ();
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "TD blind equal throughput" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
/**
* Check that the assignation is done in a "TD blind equal throughput" manner among users
* with equal SINRs: the bandwidth should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*/
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Unfair Throughput!");
}
/**
* Check that the uplink assignation is done in a "TD blind equal throughput" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
/**
* Check that the assignation is done in a "TD blind equal throughput" manner among users
* with equal SINRs: the bandwidht should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*/
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
// --------------- T E S T - C A S E # 2 ------------------------------
std::string
LenaTdBetFfMacSchedulerTestCase2::BuildNameString (uint16_t nUser, std::vector<uint16_t> dist)
{
std::ostringstream oss;
oss << "distances (m) = [ " ;
for (std::vector<uint16_t>::iterator it = dist.begin (); it != dist.end (); ++it)
{
oss << *it << " ";
}
oss << "]";
return oss.str ();
}
LenaTdBetFfMacSchedulerTestCase2::LenaTdBetFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estAchievableRateDl, std::vector<uint32_t> estThrTdBetUl)
: TestCase (BuildNameString (dist.size (), dist)),
m_nUser (dist.size ()),
m_dist (dist),
m_achievableRateDl (estAchievableRateDl),
m_estThrTdBetUl (estThrTdBetUl)
{
}
LenaTdBetFfMacSchedulerTestCase2::~LenaTdBetFfMacSchedulerTestCase2 ()
{
}
void
LenaTdBetFfMacSchedulerTestCase2::DoRun (void)
{
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("TdBetFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestTdBetFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::TdBetFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
lteHelper->EnableRlcTraces ();
double simulationTime = 1;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s)");
std::vector <uint64_t> dlDataRxed;
double totalData = 0;
double estTotalThr = 0;
double estUeThr = 0;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
totalData += (double)dlDataRxed.at (i);
estTotalThr += 1 / m_achievableRateDl.at (i);
//NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_nUser);
}
estTotalThr = m_nUser * (1 / estTotalThr);
estUeThr = estTotalThr / m_nUser;
/**
* Check that the assignation is done in a "TD blind equal throughput" manner among users
* with different SINRs: the bandwidth should be distributed equally in long term
*/
for (int i = 0; i < m_nUser; i++)
{
double thrRatio = (double) 1 / m_nUser;
double estThrRatio = (double)dlDataRxed.at (i) / totalData;
NS_LOG_INFO ("\tUser " << i << " thrRatio " << thrRatio << " estThrRatio " << estThrRatio);
NS_TEST_ASSERT_MSG_EQ_TOL (estThrRatio, thrRatio, tolerance, " Unfair Throughput!");
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, estUeThr, estUeThr * tolerance, " Unfair Throughput!");
}
/**
* Check that the assignation in uplink is done in a round robin manner.
*/
NS_LOG_INFO ("UL - Test with " << m_nUser);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << (double)m_estThrTdBetUl.at (i));
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, (double)m_estThrTdBetUl.at (i), (double)m_estThrTdBetUl.at (i) * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
} // namespace ns3

View File

@@ -0,0 +1,89 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_TDBET_FF_MAC_SCHEDULER_H
#define LENA_TEST_TDBET_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
namespace ns3 {
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is equal among users is consistent with the definition of blind equal throughput
* scheduling
*/
class LenaTdBetFfMacSchedulerTestCase1 : public TestCase
{
public:
LenaTdBetFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl);
virtual ~LenaTdBetFfMacSchedulerTestCase1 ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
double m_thrRefDl;
double m_thrRefUl;
};
class LenaTdBetFfMacSchedulerTestCase2 : public TestCase
{
public:
LenaTdBetFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> m_achievableRateDl, std::vector<uint32_t> estThrTdBetUl);
virtual ~LenaTdBetFfMacSchedulerTestCase2 ();
private:
static std::string BuildNameString (uint16_t nUser, std::vector<uint16_t> dist);
virtual void DoRun (void);
uint16_t m_nUser;
std::vector<uint16_t> m_dist;
std::vector<uint32_t> m_achievableRateDl;
std::vector<uint32_t> m_estThrTdBetUl;
};
class LenaTestTdBetFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestTdBetFfMacSchedulerSuite ();
};
} // namespace ns3
#endif /* LENA_TEST_TDBET_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,347 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include "lte-test-tdmt-ff-mac-scheduler.h"
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
NS_LOG_COMPONENT_DEFINE ("LenaTestTdMtFfMacCheduler");
using namespace ns3;
LenaTestTdMtFfMacSchedulerSuite::LenaTestTdMtFfMacSchedulerSuite ()
: TestSuite ("lte-tdmt-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestTdMtFfMacSchedulerSuite");
//Test Case : AMC works in TDMT
// DOWNLINK - DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 2196000 among 3 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 2196000 among 6 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 2196000 among 12 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 2196000 among 15 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK- DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec
// 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (1,0,0,2196000,2292000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (3,0,0,2196000,749000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (6,0,0,2196000,373000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (12,0,0,2196000,185000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (15,0,0,2196000,89000));
// DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 30 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 20 -> 1383 -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 1383000 among 3 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 1383000 among 6 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 1383000 among 12 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 1383000 among 15 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 bytes/sec
// 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (1,0,3000,1383000,1239000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (3,0,3000,1383000,389000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (6,0,3000,1383000,193000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (12,0,3000,1383000,97000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (15,0,3000,1383000,47000));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 15 -> 903 -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 903000 among 3 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 903000 among 6 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 903000 among 12 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 903000 among 15 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 bytes/sec
// 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (1,0,6000,903000,621000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (3,0,6000,903000,201000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (6,0,6000,903000,97000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (12,0,6000,903000,47000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (15,0,6000,903000,22000));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 11 -> 597 -> 597000 bytes/sec
// 3 users -> 597000 among 3 users -> 199000 bytes/sec
// 6 users -> 597000 among 6 users -> 99500 bytes/sec
// 12 users -> 597000 among 12 users -> 49750 bytes/sec
// 15 users -> 597000 among 15 users -> 39800 bytes/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 bytes/sec
// 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (1,0,9000,597000,437000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (3,0,9000,597000,137000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (6,0,9000,597000,67000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (12,0,9000,597000,32000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (15,0,9000,597000,15000));
// DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 6 -> 309 -> 309000 bytes/sec
// 3 users -> 309000 among 3 users -> 103000 bytes/sec
// 6 users -> 309000 among 6 users -> 51500 bytes/sec
// 12 users -> 309000 among 12 users -> 25750 bytes/sec
// 15 users -> 309000 among 15 users -> 20600 bytes/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 bytes/sec
// 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (1,0,15000,309000,233000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (3,0,15000,309000,69000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (6,0,15000,309000,32000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (12,0,15000,309000,15000));
AddTestCase (new LenaTdMtFfMacSchedulerTestCase (15,0,15000,309000,7000));
}
static LenaTestTdMtFfMacSchedulerSuite lenaTestTdMtFfMacSchedulerSuite;
// --------------- T E S T - C A S E ------------------------------
std::string
LenaTdMtFfMacSchedulerTestCase::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaTdMtFfMacSchedulerTestCase::LenaTdMtFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaTdMtFfMacSchedulerTestCase::~LenaTdMtFfMacSchedulerTestCase ()
{
}
void
LenaTdMtFfMacSchedulerTestCase::DoRun (void)
{
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("TdMtFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestTdMtFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::TdMtFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
lteHelper->EnableRlcTraces ();
lteHelper->EnableMacTraces ();
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "maximum throughput" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
/**
* Check that the assignation is done in a "maximum throughput" manner among users
* with equal SINRs: all bandwidth should be allocated to the first UE in script
*/
for (int i = 0; i < 1; i++)
{
if (i == 0)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Invalid Throughput!");
}
else
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, 0, tolerance, " Invalid Throughput!");
}
}
/**
* Check that the uplink assignation is done in a "maximum throughput" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
/**
* Check that the assignation is done in a "maximum throughput" manner among users
* with equal SINRs: the bandwidht should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*
*/
for (int i = 0; i < 1; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}

View File

@@ -0,0 +1,67 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_TDMT_FF_MAC_SCHEDULER_H
#define LENA_TEST_TDMT_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
using namespace ns3;
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is consistent with the definition of maximum throughput
* scheduling
*/
class LenaTdMtFfMacSchedulerTestCase : public TestCase
{
public:
LenaTdMtFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl);
virtual ~LenaTdMtFfMacSchedulerTestCase ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
double m_thrRefDl;
double m_thrRefUl;
};
class LenaTestTdMtFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestTdMtFfMacSchedulerSuite ();
};
#endif /* LENA_TEST_TDMT_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,760 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>,
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
#include "ns3/epc-helper.h"
#include "ns3/network-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-helper.h"
#include "lte-test-tdtbfq-ff-mac-scheduler.h"
NS_LOG_COMPONENT_DEFINE ("LenaTestTdTbfqFfMacCheduler");
namespace ns3 {
LenaTestTdTbfqFfMacSchedulerSuite::LenaTestTdTbfqFfMacSchedulerSuite ()
: TestSuite ("lte-tdtbfq-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestTdTbfqFfMacSchedulerSuite");
// General config
// Traffic: UDP traffic with fixed rate
// Token generation rate = traffic rate
// RLC header length = 2 bytes, PDCP header = 2 bytes
// Simulation time = 1.0 sec
// Throughput in this file is calculated in RLC layer
//Test Case 1: homogeneous flow test in TDTBFQ (same distance)
// DOWNLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 26 -> 2196 -> 2196000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 2196000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 2196000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 < 2196000 -> throughput = 232000 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 2196000 -> throughput = 2196000 / 12 = 183000 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 2196000 -> throughput = 2196000 / 15 = 146400 byte/sec
// UPLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 > 232000 -> throughput = 232000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 > 232000 -> throughput = 232000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 < 232000 -> throughput = 185000 bytes/sec
// 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (1,0,0,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (3,0,0,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (6,0,0,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (12,0,0,183000,185000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (15,0,0,146400,89000,200,1));
// DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 20 (from table 7.1.7.2.1-1 of 36.213)
// DOWNLINK -> DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.2 13)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 20 -> 1383 -> 1383000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 1383000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 1383000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 > 1383000 -> throughput = 1383000 / 6 = 230500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 1383000 -> throughput = 1383000 / 12 = 115250 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 1383000 -> throughput = 1383000 / 15 = 92200 byte/sec
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 > 232000 -> throughput = 232000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 < 232000 -> throughput = 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 < 232000 -> throughput = 97000 bytes/sec
// 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (1,0,3000,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (3,0,3000,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (6,0,3000,230500,193000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (12,0,3000,115250,97000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (15,0,3000,92200,47000,200,1));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 15 -> 903 -> 903000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 903000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 < 903000 -> througphut = 232000 byte/sec
// 6 user -> 232000 * 6 = 139200 > 903000 -> throughput = 903000 / 6 = 150500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 903000 -> throughput = 903000 / 12 = 75250 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 903000 -> throughput = 903000 / 15 = 60200 byte/sec
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 < 232000 -> throughput = 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 < 232000 -> throughput = 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 < 232000 -> throughput = 47000 bytes/sec
// 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (1,0,6000,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (3,0,6000,232000,201000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (6,0,6000,150500,97000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (12,0,6000,75250,47000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (15,0,6000,60200,22000,200,1));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 11 -> 597 -> 597000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 597000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 > 597000 -> througphut = 597000 / 3 = 199000byte/sec
// 6 user -> 232000 * 6 = 139200 > 597000 -> throughput = 597000 / 6 = 99500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 597000 -> throughput = 597000 / 12 = 49750 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 597000 -> throughput = 597000 / 15 = 39800 byte/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 < 232000 -> throughput = 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 < 232000 -> throughput = 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 < 232000 -> throughput = 32000 bytes/sec
// 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (1,0,9000,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (3,0,9000,199000,137000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (6,0,9000,99500,67000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (12,0,9000,49750,32000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (15,0,9000,39800,15000,200,1));
// DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// Traffic info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Totol bandwidth: 24 PRB at Itbs 6 -> 309 -> 309000 byte/sec
// 1 user -> 232000 * 1 = 232000 < 309000 -> throughput = 232000 byte/sec
// 3 user -> 232000 * 3 = 696000 > 309000 -> througphut = 309000 / 3 = 103000byte/sec
// 6 user -> 232000 * 6 = 139200 > 309000 -> throughput = 309000 / 6 = 51500 byte/sec
// 12 user -> 232000 * 12 = 2784000 > 309000 -> throughput = 309000 / 12 = 25750 byte/sec
// 15 user -> 232000 * 15 = 3480000 > 309000 -> throughput = 309000 / 15 = 20600 byte/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 > 232000 -> throughput = 232000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 < 232000 -> throughput = 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 < 232000 -> throughput = 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 < 232000 -> throughput = 15000 bytes/sec
// 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (1,0,15000,232000,232000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (3,0,15000,103000,69000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (6,0,15000,51500,32000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (12,0,15000,25750,15000,200,1));
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase1 (15,0,15000,20600,7000,200,1));
// Test Case 2: homogeneous flow test in TDTBFQ (different distance)
// Traffic1 info
// UDP traffic: payload size = 100 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 132000 byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 + 1/597000 + 1/309000) = 694720 byte/s
// 132000 * 5 = 660000 < 694720 -> estimated throughput in downlink = 132000 byte/sec
std::vector<uint16_t> dist1;
dist1.push_back (0); // User 0 distance --> MCS 28
dist1.push_back (3000); // User 1 distance --> MCS 24
dist1.push_back (6000); // User 2 distance --> MCS 16
dist1.push_back (9000); // User 3 distance --> MCS 12
dist1.push_back (15000); // User 4 distance --> MCS 6
std::vector<uint16_t> packetSize1;
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
packetSize1.push_back (100);
std::vector<uint32_t> estThrTdTbfqDl1;
estThrTdTbfqDl1.push_back (132000); // User 0 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl1.push_back (132000); // User 1 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl1.push_back (132000); // User 2 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl1.push_back (132000); // User 3 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl1.push_back (132000); // User 4 estimated TTI throughput from TDTBFQ
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase2 (dist1,estThrTdTbfqDl1,packetSize1,1));
// Traffic2 info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 + 1/597000 + 1/309000) = 694720 byte/s
// 232000 * 5 = 1160000 > 694720 -> estimated throughput in downlink = 694720 / 5 = 138944 byte/sec
std::vector<uint16_t> dist2;
dist2.push_back (0); // User 0 distance --> MCS 28
dist2.push_back (3000); // User 1 distance --> MCS 24
dist2.push_back (6000); // User 2 distance --> MCS 16
dist2.push_back (9000); // User 3 distance --> MCS 12
dist2.push_back (15000); // User 4 distance --> MCS 6
std::vector<uint16_t> packetSize2;
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
packetSize2.push_back (200);
std::vector<uint32_t> estThrTdTbfqDl2;
estThrTdTbfqDl2.push_back (138944); // User 0 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl2.push_back (138944); // User 1 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl2.push_back (138944); // User 2 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl2.push_back (138944); // User 3 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl2.push_back (138944); // User 4 estimated TTI throughput from TDTBFQ
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase2 (dist2,estThrTdTbfqDl2,packetSize2,1));
// Test Case 3: heterogeneous flow test in TDTBFQ
// UDP traffic: payload size = [100,200,300] bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> [132000, 232000, 332000] byte/rate
// Maximum throughput = 5 / ( 1/2196000 + 1/1383000 + 1/903000 ) = 1312417 byte/s
// 132000 + 232000 + 332000 = 696000 < 1312417 -> estimated throughput in downlink = [132000, 232000, 332000] byte/sec
std::vector<uint16_t> dist3;
dist3.push_back (0); // User 0 distance --> MCS 28
dist3.push_back (3000); // User 1 distance --> MCS 24
dist3.push_back (6000); // User 2 distance --> MCS 16
std::vector<uint16_t> packetSize3;
packetSize3.push_back (100);
packetSize3.push_back (200);
packetSize3.push_back (300);
std::vector<uint32_t> estThrTdTbfqDl3;
estThrTdTbfqDl3.push_back (132000); // User 0 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl3.push_back (232000); // User 1 estimated TTI throughput from TDTBFQ
estThrTdTbfqDl3.push_back (332000); // User 2 estimated TTI throughput from TDTBFQ
AddTestCase (new LenaTdTbfqFfMacSchedulerTestCase2 (dist3,estThrTdTbfqDl3,packetSize3,1));
}
static LenaTestTdTbfqFfMacSchedulerSuite lenaTestTdTbfqFfMacSchedulerSuite;
// --------------- T E S T - C A S E # 1 ------------------------------
std::string
LenaTdTbfqFfMacSchedulerTestCase1::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaTdTbfqFfMacSchedulerTestCase1::LenaTdTbfqFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl, uint16_t packetSize, uint16_t interval)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_packetSize (packetSize),
m_interval (interval),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaTdTbfqFfMacSchedulerTestCase1::~LenaTdTbfqFfMacSchedulerTestCase1 ()
{
}
void
LenaTdTbfqFfMacSchedulerTestCase1::DoRun (void)
{
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
lteHelper->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteHelper::RLC_UM_ALWAYS));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("TdTbfqFfMacScheduler", LOG_LEVEL_AlL);
LogComponentEnable ("LenaTestTdTbfqFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::TdTbfqFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
}
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
GbrQosInformation qos;
qos.gbrDl = (m_packetSize + 32) * (1000 / m_interval) * 8; // bit/s, considering IP, UDP, RLC, PDCP header size
qos.gbrUl = 0;
qos.mbrDl = qos.gbrDl;
qos.mbrUl = 0;
EpsBearer bearer (q, qos);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
lteHelper->EnableMacTraces ();
lteHelper->EnableRlcTraces ();
lteHelper->EnablePdcpTraces ();
// Install downlind and uplink applications
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); // receive packets from UEs
UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
UdpClientHelper ulClient (remoteHostAddr, ulPort); // downlink packets generator
ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
clientApps.Add (dlClient.Install (remoteHost));
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
serverApps.Start (Seconds (0.001));
clientApps.Start (Seconds (0.001));
double simulationTime = 2.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "token bank fair queue" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
uint64_t data = rlcStats->GetDlRxData (imsi, lcId);
dlDataRxed.push_back (data);
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Unfair Throughput!");
}
/**
* Check that the uplink assignation is done in a "round robin" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
// --------------- T E S T - C A S E # 2 ------------------------------
std::string
LenaTdTbfqFfMacSchedulerTestCase2::BuildNameString (uint16_t nUser, std::vector<uint16_t> dist)
{
std::ostringstream oss;
oss << "distances (m) = [ " ;
for (std::vector<uint16_t>::iterator it = dist.begin (); it != dist.end (); ++it)
{
oss << *it << " ";
}
oss << "]";
return oss.str ();
}
LenaTdTbfqFfMacSchedulerTestCase2::LenaTdTbfqFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estThrTdTbfqDl, std::vector<uint16_t> packetSize, uint16_t interval)
: TestCase (BuildNameString (dist.size (), dist)),
m_nUser (dist.size ()),
m_dist (dist),
m_packetSize (packetSize),
m_interval (interval),
m_estThrTdTbfqDl (estThrTdTbfqDl)
{
}
LenaTdTbfqFfMacSchedulerTestCase2::~LenaTdTbfqFfMacSchedulerTestCase2 ()
{
}
void
LenaTdTbfqFfMacSchedulerTestCase2::DoRun (void)
{
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
lteHelper->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteHelper::RLC_UM_ALWAYS));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("TdTbfqFfMacScheduler", LOG_LEVEL_AlL);
LogComponentEnable ("LenaTestTdTbfqFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::TdTbfqFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
}
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
GbrQosInformation qos;
uint16_t mbrDl = 0;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
mbrDl = mbrDl + m_packetSize.at (u);
}
mbrDl = mbrDl / ueNodes.GetN ();
qos.gbrDl = (mbrDl + 32) * (1000 / m_interval) * 8; // bit/s, considering IP, UDP, RLC, PDCP header size
qos.gbrUl = 0;
qos.mbrDl = qos.gbrDl;
qos.mbrUl = 0;
EpsBearer bearer (q, qos);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
lteHelper->EnableMacTraces ();
lteHelper->EnableRlcTraces ();
lteHelper->EnablePdcpTraces ();
// Install downlind and uplink applications
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); // receive packets from UEs
UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
UdpClientHelper ulClient (remoteHostAddr, ulPort); // downlink packets generator
ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
clientApps.Add (dlClient.Install (remoteHost));
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
serverApps.Start (Seconds (0.001));
clientApps.Start (Seconds (0.001));
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the assignation is done in a "token bank fair queue" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s)");
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_nUser);
}
for (int i = 0; i < m_nUser; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_estThrTdTbfqDl.at (i), m_estThrTdTbfqDl.at (i) * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}
} // namespace ns3

View File

@@ -0,0 +1,90 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_TDTBFQ_FF_MAC_SCHEDULER_H
#define LENA_TEST_TDTBFQ_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
namespace ns3 {
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is equal among users is consistent with the definition of token bank fair
* queue scheduling
*/
class LenaTdTbfqFfMacSchedulerTestCase1 : public TestCase
{
public:
LenaTdTbfqFfMacSchedulerTestCase1 (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl, uint16_t packetSize, uint16_t interval);
virtual ~LenaTdTbfqFfMacSchedulerTestCase1 ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
uint16_t m_packetSize; // byte
uint16_t m_interval; // ms
double m_thrRefDl;
double m_thrRefUl;
};
class LenaTdTbfqFfMacSchedulerTestCase2 : public TestCase
{
public:
LenaTdTbfqFfMacSchedulerTestCase2 (std::vector<uint16_t> dist, std::vector<uint32_t> estThrTdTbfqDl, std::vector<uint16_t> packetSize, uint16_t interval);
virtual ~LenaTdTbfqFfMacSchedulerTestCase2 ();
private:
static std::string BuildNameString (uint16_t nUser, std::vector<uint16_t> dist);
virtual void DoRun (void);
uint16_t m_nUser;
std::vector<uint16_t> m_dist;
std::vector<uint16_t> m_packetSize; // byte
uint16_t m_interval; // ms
std::vector<uint32_t> m_estThrTdTbfqDl;
};
class LenaTestTdTbfqFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestTdTbfqFfMacSchedulerSuite ();
};
} // namespace ns3
#endif /* LENA_TEST_TDTBFQ_FF_MAC_SCHEDULER_H */

View File

@@ -0,0 +1,347 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#include <iostream>
#include <sstream>
#include <string>
#include <ns3/object.h>
#include <ns3/spectrum-interference.h>
#include <ns3/spectrum-error-model.h>
#include <ns3/log.h>
#include <ns3/test.h>
#include <ns3/simulator.h>
#include <ns3/packet.h>
#include <ns3/ptr.h>
#include "ns3/radio-bearer-stats-calculator.h"
#include <ns3/constant-position-mobility-model.h>
#include "lte-test-tta-ff-mac-scheduler.h"
#include <ns3/eps-bearer.h>
#include <ns3/node-container.h>
#include <ns3/mobility-helper.h>
#include <ns3/net-device-container.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-helper.h>
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/lte-enb-phy.h>
#include <ns3/lte-ue-phy.h>
#include <ns3/boolean.h>
#include <ns3/enum.h>
NS_LOG_COMPONENT_DEFINE ("LenaTestTtaFfMacCheduler");
using namespace ns3;
LenaTestTtaFfMacSchedulerSuite::LenaTestTtaFfMacSchedulerSuite ()
: TestSuite ("lte-tta-ff-mac-scheduler", SYSTEM)
{
NS_LOG_INFO ("creating LenaTestTtaFfMacSchedulerSuite");
//Test Case : AMC works in TTA
// DOWNLINK - DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 26 -> 2196 -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 2196000 among 3 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 2196000 among 6 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 2196000 among 12 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 2196000 among 15 users -> 2196000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK- DISTANCE 0 -> MCS 28 -> Itbs 26 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 bytes/sec
// 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec
// 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 bytes/sec
// 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec
// 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
AddTestCase (new LenaTtaFfMacSchedulerTestCase (1,0,0,2196000,2292000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (3,0,0,2196000,749000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (6,0,0,2196000,373000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (12,0,0,2196000,185000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (15,0,0,2196000,89000));
// DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 30 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 20 -> 1383 -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 1383000 among 3 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 1383000 among 6 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 1383000 among 12 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 1383000 among 15 users -> 1383000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK - DISTANCE 3000 -> MCS 20 -> Itbs 18 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 bytes/sec
// 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 bytes/sec
// 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 bytes/sec
// 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 bytes/sec
// 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec
AddTestCase (new LenaTtaFfMacSchedulerTestCase (1,0,3000,1383000,1239000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (3,0,3000,1383000,389000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (6,0,3000,1383000,193000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (12,0,3000,1383000,97000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (15,0,3000,1383000,47000));
// DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 15 -> 903 -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 3 users -> 903000 among 3 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 6 users -> 903000 among 6 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 12 users -> 903000 among 12 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// 15 users -> 903000 among 15 users -> 903000 bytes/sec for first UE; 0 bytes/sec for other UEs
// UPLINK - DISTANCE 6000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 bytes/sec
// 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 bytes/sec
// 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 bytes/sec
// 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 bytes/sec
// 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
AddTestCase (new LenaTtaFfMacSchedulerTestCase (1,0,6000,903000,621000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (3,0,6000,903000,201000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (6,0,6000,903000,97000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (12,0,6000,903000,47000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (15,0,6000,903000,22000));
// DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 11 -> 597 -> 597000 bytes/sec
// 3 users -> 597000 among 3 users -> 199000 bytes/sec
// 6 users -> 597000 among 6 users -> 99500 bytes/sec
// 12 users -> 597000 among 12 users -> 49750 bytes/sec
// 15 users -> 597000 among 15 users -> 39800 bytes/sec
// UPLINK - DISTANCE 9000 -> MCS 8 -> Itbs 8 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 bytes/sec
// 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 bytes/sec
// 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 bytes/sec
// 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 bytes/sec
// 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec
AddTestCase (new LenaTtaFfMacSchedulerTestCase (1,0,9000,597000,437000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (3,0,9000,597000,137000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (6,0,9000,597000,67000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (12,0,9000,597000,32000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (15,0,9000,597000,15000));
// DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 24 PRB at Itbs 6 -> 309 -> 309000 bytes/sec
// 3 users -> 309000 among 3 users -> 103000 bytes/sec
// 6 users -> 309000 among 6 users -> 51500 bytes/sec
// 12 users -> 309000 among 12 users -> 25750 bytes/sec
// 15 users -> 309000 among 15 users -> 20600 bytes/sec
// UPLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
// 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 bytes/sec
// 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 bytes/sec
// 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 bytes/sec
// 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 bytes/sec
// 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
AddTestCase (new LenaTtaFfMacSchedulerTestCase (1,0,15000,309000,233000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (3,0,15000,309000,69000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (6,0,15000,309000,32000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (12,0,15000,309000,15000));
AddTestCase (new LenaTtaFfMacSchedulerTestCase (15,0,15000,309000,7000));
}
static LenaTestTtaFfMacSchedulerSuite lenaTestTtaFfMacSchedulerSuite;
// --------------- T E S T - C A S E ------------------------------
std::string
LenaTtaFfMacSchedulerTestCase::BuildNameString (uint16_t nUser, uint16_t dist)
{
std::ostringstream oss;
oss << nUser << " UEs, distance " << dist << " m";
return oss.str ();
}
LenaTtaFfMacSchedulerTestCase::LenaTtaFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl)
: TestCase (BuildNameString (nUser, dist)),
m_nUser (nUser),
m_nLc (nLc),
m_dist (dist),
m_thrRefDl (thrRefDl),
m_thrRefUl (thrRefUl)
{
}
LenaTtaFfMacSchedulerTestCase::~LenaTtaFfMacSchedulerTestCase ()
{
}
void
LenaTtaFfMacSchedulerTestCase::DoRun (void)
{
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
//
// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable ("TtaFfMacScheduler", LOG_LEVEL_ALL);
LogComponentEnable ("LenaTestTtaFfMacCheduler", LOG_LEVEL_ALL);
// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
// LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
/**
* Initialize Simulation Scenario: 1 eNB and m_nUser UEs
*/
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
// Create Nodes: eNodeB and UE
NodeContainer enbNodes;
NodeContainer ueNodes;
enbNodes.Create (1);
ueNodes.Create (m_nUser);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ueNodes);
// Create Devices and install them in the Nodes (eNB and UE)
NetDeviceContainer enbDevs;
NetDeviceContainer ueDevs;
lteHelper->SetSchedulerType ("ns3::TtaFfMacScheduler");
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Attach a UE to a eNB
lteHelper->Attach (ueDevs, enbDevs.Get (0));
// Activate an EPS bearer
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
// Set UEs' position and power
for (int i = 0; i < m_nUser; i++)
{
Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
mm->SetPosition (Vector (m_dist, 0.0, 0.0));
Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
lteHelper->EnableRlcTraces ();
lteHelper->EnableMacTraces ();
double simulationTime = 1.0;
double tolerance = 0.1;
Simulator::Stop (Seconds (simulationTime));
Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (simulationTime)));
Simulator::Run ();
/**
* Check that the downlink assignation is done in a "throughput to average" manner
*/
NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> dlDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRefDl);
}
/**
* Check that the assignation is done in a "throughput to average" manner among users
* with equal SINRs: all bandwidth should be allocated to the first UE in script
*/
for (int i = 0; i < 1; i++)
{
if (i == 0)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRefDl, m_thrRefDl * tolerance, " Invalid Throughput!");
}
else
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, 0, tolerance, " Invalid Throughput!");
}
}
/**
* Check that the uplink assignation is done in a "throughput to average" manner
*/
NS_LOG_INFO ("UL - Test with " << m_nUser << " user(s) at distance " << m_dist);
std::vector <uint64_t> ulDataRxed;
for (int i = 0; i < m_nUser; i++)
{
// get the imsi
uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
// get the lcId
uint8_t lcId = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
ulDataRxed.push_back (rlcStats->GetUlRxData (imsi, lcId));
NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)ulDataRxed.at (i) << " thr " << (double)ulDataRxed.at (i) / simulationTime << " ref " << m_thrRefUl);
}
/**
* Check that the assignation is done in a "throughput to average" manner among users
* with equal SINRs: the bandwidht should be distributed according to the
* ratio of the estimated throughput per TTI of each user; therefore equally
* partitioning the whole bandwidth achievable from a single users in a TTI
*
*/
for (int i = 0; i < 1; i++)
{
NS_TEST_ASSERT_MSG_EQ_TOL ((double)ulDataRxed.at (i) / simulationTime, m_thrRefUl, m_thrRefUl * tolerance, " Unfair Throughput!");
}
Simulator::Destroy ();
}

View File

@@ -0,0 +1,66 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Marco Miozzo <marco.miozzo@cttc.es>,
* Nicola Baldo <nbaldo@cttc.es>
* Dizhi Zhou <dizhi.zhou@gmail.com>
*/
#ifndef LENA_TEST_TTA_FF_MAC_SCHEDULER_H
#define LENA_TEST_TTA_FF_MAC_SCHEDULER_H
#include "ns3/simulator.h"
#include "ns3/test.h"
using namespace ns3;
/**
* This system test program creates different test cases with a single eNB and
* several UEs, all having the same Radio Bearer specification. In each test
* case, the UEs see the same SINR from the eNB; different test cases are
* implemented obtained by using different SINR values and different numbers of
* UEs. The test consists on checking that the obtained throughput performance
* is consistent with the definition of throughput to average scheduling
*/
class LenaTtaFfMacSchedulerTestCase : public TestCase
{
public:
LenaTtaFfMacSchedulerTestCase (uint16_t nUser, uint16_t nLc, uint16_t dist, double thrRefDl, double thrRefUl);
virtual ~LenaTtaFfMacSchedulerTestCase ();
private:
static std::string BuildNameString (uint16_t nUser, uint16_t dist);
virtual void DoRun (void);
uint16_t m_nUser;
uint16_t m_nLc;
uint16_t m_dist;
double m_thrRefDl;
double m_thrRefUl;
};
class LenaTestTtaFfMacSchedulerSuite : public TestSuite
{
public:
LenaTestTtaFfMacSchedulerSuite ();
};
#endif /* LENA_TEST_TTA_FF_MAC_SCHEDULER_H */

View File

@@ -58,6 +58,14 @@ def build(bld):
'model/lte-interference.cc',
'model/lte-sinr-chunk-processor.cc',
'model/pf-ff-mac-scheduler.cc',
'model/fdmt-ff-mac-scheduler.cc',
'model/tdmt-ff-mac-scheduler.cc',
'model/tta-ff-mac-scheduler.cc',
'model/fdbet-ff-mac-scheduler.cc',
'model/tdbet-ff-mac-scheduler.cc',
'model/fdtbfq-ff-mac-scheduler.cc',
'model/tdtbfq-ff-mac-scheduler.cc',
'model/pss-ff-mac-scheduler.cc',
'model/epc-gtpu-header.cc',
'model/trace-fading-loss-model.cc',
'model/epc-enb-application.cc',
@@ -78,6 +86,14 @@ def build(bld):
'test/lte-test-ue-phy.cc',
'test/lte-test-rr-ff-mac-scheduler.cc',
'test/lte-test-pf-ff-mac-scheduler.cc',
'test/lte-test-fdmt-ff-mac-scheduler.cc',
'test/lte-test-tdmt-ff-mac-scheduler.cc',
'test/lte-test-tta-ff-mac-scheduler.cc',
'test/lte-test-fdbet-ff-mac-scheduler.cc',
'test/lte-test-tdbet-ff-mac-scheduler.cc',
'test/lte-test-fdtbfq-ff-mac-scheduler.cc',
'test/lte-test-tdtbfq-ff-mac-scheduler.cc',
'test/lte-test-pss-ff-mac-scheduler.cc',
'test/lte-test-earfcn.cc',
'test/lte-test-spectrum-value-helper.cc',
'test/lte-test-pathloss-model.cc',
@@ -155,6 +171,14 @@ def build(bld):
'model/lte-interference.h',
'model/lte-sinr-chunk-processor.h',
'model/pf-ff-mac-scheduler.h',
'model/fdmt-ff-mac-scheduler.h',
'model/tdmt-ff-mac-scheduler.h',
'model/tta-ff-mac-scheduler.h',
'model/fdbet-ff-mac-scheduler.h',
'model/tdbet-ff-mac-scheduler.h',
'model/fdtbfq-ff-mac-scheduler.h',
'model/tdtbfq-ff-mac-scheduler.h',
'model/pss-ff-mac-scheduler.h',
'model/trace-fading-loss-model.h',
'model/epc-gtpu-header.h',
'model/epc-enb-application.h',
@@ -163,6 +187,14 @@ def build(bld):
'model/epc-tft.h',
'model/epc-tft-classifier.h',
'model/lte-mi-error-model.h',
'test/lte-test-fdmt-ff-mac-scheduler.h',
'test/lte-test-tdmt-ff-mac-scheduler.h',
'test/lte-test-tta-ff-mac-scheduler.h',
'test/lte-test-fdbet-ff-mac-scheduler.h',
'test/lte-test-tdbet-ff-mac-scheduler.h',
'test/lte-test-fdtbfq-ff-mac-scheduler.h',
'test/lte-test-tdtbfq-ff-mac-scheduler.h',
'test/lte-test-pss-ff-mac-scheduler.h',
]
if (bld.env['ENABLE_EXAMPLES']):