--- a/src/lte/helper/epc-helper.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/helper/epc-helper.cc Thu Jun 13 11:32:13 2013 +0200
@@ -32,6 +32,7 @@
#include <ns3/packet-socket-address.h>
#include <ns3/epc-enb-application.h>
#include <ns3/epc-sgw-pgw-application.h>
+#include <ns3/epc-mbmsgw-application.h>
#include <ns3/lte-enb-rrc.h>
#include <ns3/epc-x2.h>
@@ -47,13 +48,16 @@
NS_OBJECT_ENSURE_REGISTERED (EpcHelper);
-EpcHelper::EpcHelper ()
- : m_gtpuUdpPort (2152) // fixed by the standard
+EpcHelper::EpcHelper ()
+ : m_gtpuUdpPort (2152),
+ // fixed by the standard
+ m_udpPortM1Socket (2153),
+ m_udpPortSgimbSocket (2154)
{
NS_LOG_FUNCTION (this);
- // since we use point-to-point links for all S1-U links,
- // we use a /30 subnet which can hold exactly two addresses
+ // since we use point-to-point links for all S1-U links,
+ // we use a /30 subnet which can hold exactly two addresses
// (remember that net broadcast and null address are not valid)
m_s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.252");
@@ -61,38 +65,45 @@
// we use a /8 net for all UEs
m_ueAddressHelper.SetBase ("7.0.0.0", "255.0.0.0");
-
+
// create SgwPgwNode
m_sgwPgw = CreateObject<Node> ();
InternetStackHelper internet;
internet.Install (m_sgwPgw);
-
+
// create S1-U socket
Ptr<Socket> sgwPgwS1uSocket = Socket::CreateSocket (m_sgwPgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
int retval = sgwPgwS1uSocket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_gtpuUdpPort));
NS_ASSERT (retval == 0);
- // create TUN device implementing tunneling of user data over GTP-U/UDP/IP
+ // create SGimb socket
+ Ptr<Socket> pgwSgimbSocket = Socket::CreateSocket (m_sgwPgw,
+ TypeId::LookupByName ("ns3::UdpSocketFactory"));
+ int retvalSgimb = pgwSgimbSocket->Bind (
+ InetSocketAddress (Ipv4Address::GetAny (), m_udpPortSgimbSocket));
+ NS_ASSERT (retvalSgimb == 0);
+
+ // create TUN device implementing tunneling of user data over GTP-U/UDP/IP
m_tunDevice = CreateObject<VirtualNetDevice> ();
// allow jumbo packets
m_tunDevice->SetAttribute ("Mtu", UintegerValue (30000));
// yes we need this
- m_tunDevice->SetAddress (Mac48Address::Allocate ());
+ m_tunDevice->SetAddress (Mac48Address::Allocate ());
m_sgwPgw->AddDevice (m_tunDevice);
NetDeviceContainer tunDeviceContainer;
tunDeviceContainer.Add (m_tunDevice);
-
+
// the TUN device is on the same subnet as the UEs, so when a packet
// addressed to an UE arrives at the intenet to the WAN interface of
- // the PGW it will be forwarded to the TUN device.
- Ipv4InterfaceContainer tunDeviceIpv4IfContainer = m_ueAddressHelper.Assign (tunDeviceContainer);
+ // the PGW it will be forwarded to the TUN device.
+ Ipv4InterfaceContainer tunDeviceIpv4IfContainer = m_ueAddressHelper.Assign (tunDeviceContainer);
// create EpcSgwPgwApplication
- m_sgwPgwApp = CreateObject<EpcSgwPgwApplication> (m_tunDevice, sgwPgwS1uSocket);
+ m_sgwPgwApp = CreateObject<EpcSgwPgwApplication> (m_tunDevice, sgwPgwS1uSocket, pgwSgimbSocket);
m_sgwPgw->AddApplication (m_sgwPgwApp);
-
+
// connect SgwPgwApplication and virtual net device for tunneling
m_tunDevice->SetSendCallback (MakeCallback (&EpcSgwPgwApplication::RecvFromTunDevice, m_sgwPgwApp));
@@ -100,6 +111,31 @@
m_mme = CreateObject<EpcMme> ();
m_mme->SetS11SapSgw (m_sgwPgwApp->GetS11SapSgw ());
m_sgwPgwApp->SetS11SapMme (m_mme->GetS11SapMme ());
+
+
+ //Create MBMS-GW node
+ m_mbmsGw = CreateObject<Node> ();
+ InternetStackHelper internetMbmsgw;
+ internetMbmsgw.Install (m_mbmsGw);
+
+
+
+ //Create M1 socket
+ Ptr<Socket> m1Socket = Socket::CreateSocket (m_mbmsGw,
+ TypeId::LookupByName ("ns3::UdpSocketFactory"));
+ int retvalm1 = m1Socket->Bind (
+ InetSocketAddress (Ipv4Address::GetAny (), m_udpPortM1Socket));
+ NS_ASSERT (retvalm1 == 0);
+
+ //Create MbmsGwApplication - connect with PGW
+ m_mbmsgwApp = CreateObject<EpcMbmsgwApplication> (pgwSgimbSocket, m1Socket);
+ m_mbmsGw->AddApplication (m_mbmsgwApp);
+
+ m_sgwPgwApp->SetMbmsGw (m_mbmsgwApp); //Temporary solution
+
+ //Create MCE and connect with MME via M3 interface
+
+
}
EpcHelper::~EpcHelper ()
@@ -113,17 +149,17 @@
static TypeId tid = TypeId ("ns3::EpcHelper")
.SetParent<Object> ()
.AddConstructor<EpcHelper> ()
- .AddAttribute ("S1uLinkDataRate",
+ .AddAttribute ("S1uLinkDataRate",
"The data rate to be used for the next S1-U link to be created",
DataRateValue (DataRate ("10Gb/s")),
MakeDataRateAccessor (&EpcHelper::m_s1uLinkDataRate),
MakeDataRateChecker ())
- .AddAttribute ("S1uLinkDelay",
+ .AddAttribute ("S1uLinkDelay",
"The delay to be used for the next S1-U link to be created",
TimeValue (Seconds (0)),
MakeTimeAccessor (&EpcHelper::m_s1uLinkDelay),
MakeTimeChecker ())
- .AddAttribute ("S1uLinkMtu",
+ .AddAttribute ("S1uLinkMtu",
"The MTU of the next S1-U link to be created. Note that, because of the additional GTP/UDP/IP tunneling overhead, you need a MTU larger than the end-to-end MTU that you want to support.",
UintegerValue (2000),
MakeUintegerAccessor (&EpcHelper::m_s1uLinkMtu),
@@ -153,7 +189,7 @@
NS_LOG_FUNCTION (this);
m_tunDevice->SetSendCallback (MakeNullCallback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> ());
m_tunDevice = 0;
- m_sgwPgwApp = 0;
+ m_sgwPgwApp = 0;
m_sgwPgw->Dispose ();
}
@@ -171,22 +207,22 @@
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after node creation: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
// create a point to point link between the new eNB and the SGW with
- // the corresponding new NetDevices on each side
+ // the corresponding new NetDevices on each side
NodeContainer enbSgwNodes;
enbSgwNodes.Add (m_sgwPgw);
enbSgwNodes.Add (enb);
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (m_s1uLinkDataRate));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (m_s1uLinkMtu));
- p2ph.SetChannelAttribute ("Delay", TimeValue (m_s1uLinkDelay));
+ p2ph.SetChannelAttribute ("Delay", TimeValue (m_s1uLinkDelay));
NetDeviceContainer enbSgwDevices = p2ph.Install (enb, m_sgwPgw);
- NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after installing p2p dev: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
+ NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after installing p2p dev: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
Ptr<NetDevice> enbDev = enbSgwDevices.Get (0);
Ptr<NetDevice> sgwDev = enbSgwDevices.Get (1);
m_s1uIpv4AddressHelper.NewNetwork ();
Ipv4InterfaceContainer enbSgwIpIfaces = m_s1uIpv4AddressHelper.Assign (enbSgwDevices);
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after assigning Ipv4 addr to S1 dev: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
-
+
Ipv4Address enbAddress = enbSgwIpIfaces.GetAddress (0);
Ipv4Address sgwAddress = enbSgwIpIfaces.GetAddress (1);
@@ -194,35 +230,39 @@
Ptr<Socket> enbS1uSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
int retval = enbS1uSocket->Bind (InetSocketAddress (enbAddress, m_gtpuUdpPort));
NS_ASSERT (retval == 0);
-
+
+ //Create M1 socket for the ENB
+ Ptr<Socket> enbM1Socket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
+ int retvalMbms = enbM1Socket->Bind (InetSocketAddress (enbAddress, m_udpPortM1Socket));
+ NS_ASSERT (retvalMbms == 0);
// give PacketSocket powers to the eNB
//PacketSocketHelper packetSocket;
- //packetSocket.Install (enb);
-
- // create LTE socket for the ENB
+ //packetSocket.Install (enb);
+
+ // create LTE socket for the ENB
Ptr<Socket> enbLteSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::PacketSocketFactory"));
PacketSocketAddress enbLteSocketBindAddress;
enbLteSocketBindAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
enbLteSocketBindAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
retval = enbLteSocket->Bind (enbLteSocketBindAddress);
- NS_ASSERT (retval == 0);
+ NS_ASSERT (retval == 0);
PacketSocketAddress enbLteSocketConnectAddress;
enbLteSocketConnectAddress.SetPhysicalAddress (Mac48Address::GetBroadcast ());
enbLteSocketConnectAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
enbLteSocketConnectAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
retval = enbLteSocket->Connect (enbLteSocketConnectAddress);
- NS_ASSERT (retval == 0);
-
+ NS_ASSERT (retval == 0);
+
NS_LOG_INFO ("create EpcEnbApplication");
- Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, enbAddress, sgwAddress, cellId);
+ Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, enbM1Socket, enbAddress, sgwAddress, cellId);
enb->AddApplication (enbApp);
NS_ASSERT (enb->GetNApplications () == 1);
NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
NS_LOG_LOGIC ("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication (0));
-
+
NS_LOG_INFO ("Create EpcX2 entity");
Ptr<EpcX2> x2 = CreateObject<EpcX2> ();
enb->AggregateObject (x2);
@@ -281,14 +321,14 @@
}
-void
+void
EpcHelper::AddUe (Ptr<NetDevice> ueDevice, uint64_t imsi)
{
NS_LOG_FUNCTION (this << imsi << ueDevice );
-
+
m_mme->AddUe (imsi);
m_sgwPgwApp->AddUe (imsi);
-
+
}
@@ -299,16 +339,17 @@
// we now retrieve the IPv4 address of the UE and notify it to the SGW;
// we couldn't do it before since address assignment is triggered by
- // the user simulation program, rather than done by the EPC
- Ptr<Node> ueNode = ueDevice->GetNode ();
+ // the user simulation program, rather than done by the EPC
+ Ptr<Node> ueNode = ueDevice->GetNode ();
Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4> ();
NS_ASSERT_MSG (ueIpv4 != 0, "UEs need to have IPv4 installed before EPS bearers can be activated");
int32_t interface = ueIpv4->GetInterfaceForDevice (ueDevice);
NS_ASSERT (interface >= 0);
NS_ASSERT (ueIpv4->GetNAddresses (interface) == 1);
Ipv4Address ueAddr = ueIpv4->GetAddress (interface, 0).GetLocal ();
- NS_LOG_LOGIC (" UE IP address: " << ueAddr); m_sgwPgwApp->SetUeAddress (imsi, ueAddr);
-
+ NS_LOG_LOGIC (" UE IP address: " << ueAddr);
+ m_sgwPgwApp->SetUeAddress (imsi, ueAddr);
+
m_mme->AddBearer (imsi, tft, bearer);
Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
if (ueLteDevice)
@@ -317,6 +358,11 @@
}
}
+void
+EpcHelper::ActivateBearerMbms (NetDeviceContainer enbDevices, NetDeviceContainer ueDevices, Ptr<EpcTft> tft, EpsBearer bearer, Ipv4Address mbmsAddress)
+{
+ m_mbmsgwApp->SetMbmsInfoMap (mbmsAddress, enbDevices, ueDevices, tft, bearer, m_mme);
+}
Ptr<Node>
EpcHelper::GetPgwNode ()
@@ -325,7 +371,7 @@
}
-Ipv4InterfaceContainer
+Ipv4InterfaceContainer
EpcHelper::AssignUeIpv4Address (NetDeviceContainer ueDevices)
{
return m_ueAddressHelper.Assign (ueDevices);
--- a/src/lte/helper/epc-helper.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/helper/epc-helper.h Thu Jun 13 11:32:13 2013 +0200
@@ -37,6 +37,7 @@
class EpcSgwPgwApplication;
class EpcX2;
class EpcMme;
+class EpcMbmsgwApplication;
/**
* \brief Helper class to handle the creation of the EPC entities and protocols.
@@ -104,6 +105,10 @@
*/
void ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer);
+ /**
+ * Activate MBMS Bearer
+ */
+ void ActivateBearerMbms (NetDeviceContainer enbDevices, NetDeviceContainer ueDevices, Ptr<EpcTft> tft, EpsBearer bearer, Ipv4Address mbmsAddress);
/**
*
@@ -168,12 +173,34 @@
uint16_t m_gtpuUdpPort;
/**
+ * UDP port of M1 Socket -> port 2153
+ */
+ uint16_t m_udpPortM1Socket;
+
+ /**
+ * UDP port of SG-iMB
+ */
+ uint16_t m_udpPortSgimbSocket;
+ /**
* Map storing for each IMSI the corresponding eNB NetDevice
*
*/
std::map<uint64_t, Ptr<NetDevice> > m_imsiEnbDeviceMap;
+
+ /**
+ * BM-SC MBMS-GW Network element
+ */
+ Ptr<Node> m_mbmsGw;
+ Ptr<EpcMbmsgwApplication> m_mbmsgwApp;
/**
+ * helper to assign addresses to M1 NetDevices
+ */
+
+
+
+
+ /**
* helper to assign addresses to X2 NetDevices
*/
Ipv4AddressHelper m_x2Ipv4AddressHelper;
--- a/src/lte/helper/lte-helper.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/helper/lte-helper.cc Thu Jun 13 11:32:13 2013 +0200
@@ -658,6 +658,17 @@
m_epcHelper->ActivateEpsBearer (ueDevice, imsi, tft, bearer);
}
+void
+LteHelper::ActivateEpsBearerMbms (NetDeviceContainer eNB, NetDeviceContainer ueDevices, EpsBearer bearer, Ptr<EpcTft> tft, Ipv4Address mbmsAddress)
+{
+ NS_LOG_FUNCTION (this);
+
+ NS_ASSERT_MSG (m_epcHelper != 0, "dedicated EPS bearers cannot be set up when EPC is not used");
+
+ //Attiva bearer EPC - " " +
+ m_epcHelper->ActivateBearerMbms (eNB, ueDevices, tft, bearer, mbmsAddress);
+}
+
class DrbActivator : public SimpleRefCount<DrbActivator>
{
public:
@@ -1062,6 +1073,7 @@
uint64_t imsi = 0;
std::ostringstream pathAndRnti;
pathAndRnti << path << "/" << params.m_rnti;
+ if (params.m_rnti != 0){
if (phyTxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
{
imsi = phyTxStats->GetImsiPath (pathAndRnti.str ());
@@ -1074,6 +1086,7 @@
params.m_imsi = imsi;
phyTxStats->DlPhyTransmission (params);
+ }
}
void
@@ -1084,6 +1097,7 @@
uint64_t imsi = 0;
std::ostringstream pathAndRnti;
pathAndRnti << path << "/" << params.m_rnti;
+ if (params.m_rnti){
if (phyTxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
{
imsi = phyTxStats->GetImsiPath (pathAndRnti.str ());
@@ -1096,6 +1110,7 @@
params.m_imsi = imsi;
phyTxStats->UlPhyTransmission (params);
+ }
}
@@ -1107,6 +1122,7 @@
uint64_t imsi = 0;
std::ostringstream pathAndRnti;
pathAndRnti << path << "/" << params.m_rnti;
+ if (params.m_rnti != 0){
if (phyRxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
{
imsi = phyRxStats->GetImsiPath (pathAndRnti.str ());
@@ -1119,6 +1135,7 @@
params.m_imsi = imsi;
phyRxStats->DlPhyReception (params);
+ }
}
void
@@ -1129,6 +1146,7 @@
uint64_t imsi = 0;
std::ostringstream pathAndRnti;
pathAndRnti << path << "/" << params.m_rnti;
+ if (params.m_rnti != 0){
if (phyRxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
{
imsi = phyRxStats->GetImsiPath (pathAndRnti.str ());
@@ -1141,6 +1159,7 @@
params.m_imsi = imsi;
phyRxStats->UlPhyReception (params);
+ }
}
void
@@ -1191,6 +1210,9 @@
uint8_t mcsTb2, uint16_t sizeTb2)
{
NS_LOG_FUNCTION (macStats << path);
+
+ if (rnti != 0)
+ {
uint64_t imsi = 0;
std::ostringstream pathAndRnti;
pathAndRnti << path << "/" << rnti;
@@ -1216,6 +1238,7 @@
}
macStats->DlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2);
+ }
}
@@ -1242,7 +1265,8 @@
uint8_t mcs, uint16_t size)
{
NS_LOG_FUNCTION (macStats << path);
-
+if (rnti != 0)
+ {
uint64_t imsi = 0;
std::ostringstream pathAndRnti;
pathAndRnti << path << "/" << rnti;
@@ -1268,6 +1292,7 @@
macStats->UlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcs, size);
}
+}
void
LteHelper::EnableUlMacTraces (void)
@@ -1311,7 +1336,8 @@
uint16_t cellId, uint16_t rnti, double sinrLinear)
{
NS_LOG_FUNCTION (phyStats << path);
-
+ if (rnti != 0)
+ {
uint64_t imsi = 0;
std::ostringstream pathAndRnti;
pathAndRnti << path << "/" << rnti;
@@ -1329,6 +1355,7 @@
phyStats->ReportUeSinr (cellId, imsi, rnti, sinrLinear);
}
+}
void
ReportInterference (Ptr<PhyStatsCalculator> phyStats, std::string path,
--- a/src/lte/helper/lte-helper.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/helper/lte-helper.h Thu Jun 13 11:32:13 2013 +0200
@@ -229,6 +229,15 @@
*/
void ActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft);
+ /**
+ * Activate MBMS bearer on a given set of eNBs e UEs
+ *
+ * \param eNB
+ * \param ueDevices
+ * \param bearer the characteristics of the bearer to be activated
+ * \param tft the Traffic Flow Template that identifies the traffic to go on this bearer
+ */
+ void ActivateEpsBearerMbms (NetDeviceContainer eNbDevices, NetDeviceContainer ueDevices, EpsBearer bearer, Ptr<EpcTft> tft, Ipv4Address mbmsAddress);
/**
* Create an X2 interface between all the eNBs in a given set
@@ -437,6 +446,7 @@
uint64_t m_imsiCounter;
uint16_t m_cellIdCounter;
+ uint64_t m_mrntiCounter;
bool m_useIdealRrc;
};
--- a/src/lte/model/epc-enb-application.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/epc-enb-application.cc Thu Jun 13 11:32:13 2013 +0200
@@ -29,6 +29,7 @@
#include "epc-gtpu-header.h"
#include "eps-bearer-tag.h"
+#include "eps-bearer-mbms-tag.h"
namespace ns3 {
@@ -73,23 +74,27 @@
NS_LOG_FUNCTION (this);
m_lteSocket = 0;
m_s1uSocket = 0;
+ m_m1Socket = 0;
delete m_s1SapProvider;
delete m_s1apSapEnb;
}
-EpcEnbApplication::EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId)
+EpcEnbApplication::EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ptr<Socket> m1Socket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId)
: m_lteSocket (lteSocket),
- m_s1uSocket (s1uSocket),
+ m_s1uSocket (s1uSocket),
+ m_m1Socket (m1Socket),
m_enbS1uAddress (enbS1uAddress),
m_sgwS1uAddress (sgwS1uAddress),
m_gtpuUdpPort (2152), // fixed by the standard
+ m_udpPortM1 (2153),
m_s1SapUser (0),
m_s1apSapMme (0),
m_cellId (cellId)
{
- NS_LOG_FUNCTION (this << lteSocket << s1uSocket << sgwS1uAddress);
+ NS_LOG_FUNCTION (this << lteSocket << s1uSocket << m1Socket << sgwS1uAddress);
m_s1uSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromS1uSocket, this));
+ m_m1Socket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromM1Socket, this));
m_lteSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromLteSocket, this));
m_s1SapProvider = new MemberEpcEnbS1SapProvider<EpcEnbApplication> (this);
m_s1apSapEnb = new MemberEpcS1apSapEnb<EpcEnbApplication> (this);
@@ -282,18 +287,50 @@
// workaround for bug 231 https://www.nsnam.org/bugzilla/show_bug.cgi?id=231
SocketAddressTag tag;
packet->RemovePacketTag (tag);
-
- SendToLteSocket (packet, it->second.m_rnti, it->second.m_bid);
+ uint16_t mrnti = 0;
+ SendToLteSocket (packet, it->second.m_rnti, mrnti, it->second.m_bid);
+}
+
+void
+EpcEnbApplication::RecvFromM1Socket (Ptr<Socket> socket)
+{
+ //Send to LTE Socket
+}
+
+//Temporary method
+void
+EpcEnbApplication::RecvMbmsPacket(Ptr<Packet> packet, uint16_t mrnti, uint8_t bid)
+{
+ SocketAddressTag tag;
+ packet->RemovePacketTag (tag);
+ uint16_t rnti = 0;
+ SendToLteSocket(packet, rnti, mrnti, bid);
}
void
-EpcEnbApplication::SendToLteSocket (Ptr<Packet> packet, uint16_t rnti, uint8_t bid)
+EpcEnbApplication::SendToLteSocket (Ptr<Packet> packet, uint16_t rnti, uint16_t mrnti, uint8_t bid)
{
- NS_LOG_FUNCTION (this << packet << rnti << (uint16_t) bid << packet->GetSize ());
- EpsBearerTag tag (rnti, bid);
- packet->AddPacketTag (tag);
- int sentBytes = m_lteSocket->Send (packet);
- NS_ASSERT (sentBytes > 0);
+ NS_LOG_FUNCTION (this << packet << rnti << mrnti << (uint16_t) bid << packet->GetSize ());
+
+ if(rnti!=0){
+ EpsBearerTag tag (rnti, bid);
+ packet->AddPacketTag (tag);
+ int sentBytes = m_lteSocket->Send (packet);
+ NS_ASSERT (sentBytes > 0);
+ }
+ else if (mrnti !=0)
+ {
+ EpsBearerMbmsTag tag (mrnti, bid);
+ packet->AddPacketTag(tag);
+ int sentBytes = m_lteSocket->Send (packet);
+ NS_ASSERT (sentBytes > 0);
+ }
+ else
+ {
+ NS_LOG_WARN("RNTI = 0, MRNTI = 0");
+ }
+
+
}
--- a/src/lte/model/epc-enb-application.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/epc-enb-application.h Thu Jun 13 11:32:13 2013 +0200
@@ -73,7 +73,7 @@
* \param sgwS1uAddress the IPv4 address at which this eNB will be able to reach its SGW for S1-U communications
* \param cellId the identifier of the enb
*/
- EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId);
+ EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ptr<Socket> m1Socket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId);
/**
* Destructor
@@ -123,6 +123,18 @@
*/
void RecvFromS1uSocket (Ptr<Socket> socket);
+ /**
+ * TEMPORARY SOLUTION
+ */
+ void RecvMbmsPacket (Ptr<Packet> packet, uint16_t mrnti, uint8_t bid);
+
+ /**
+ * Method to be assigned to the recv callback of the S1-U socket. It is called when the eNB receives a data packet from the SGW that is to be forwarded to the UE.
+ *
+ * \param socket pointer to the S1-U socket
+ */
+ void RecvFromM1Socket (Ptr<Socket> socket);
+
struct EpsFlowId_t
{
@@ -155,7 +167,7 @@
* \param packet t
* \param bid the EPS Bearer IDentifier
*/
- void SendToLteSocket (Ptr<Packet> packet, uint16_t rnti, uint8_t bid);
+ void SendToLteSocket (Ptr<Packet> packet, uint16_t rnti, uint16_t mrnti, uint8_t bid);
/**
@@ -188,6 +200,11 @@
Ptr<Socket> m_s1uSocket;
/**
+ * UDP socket to send and receive GTP-U the packets to and from the M1 interface
+ */
+ Ptr<Socket> m_m1Socket;
+
+ /**
* address of the eNB for S1-U communications
*/
Ipv4Address m_enbS1uAddress;
@@ -214,6 +231,12 @@
*/
uint16_t m_gtpuUdpPort;
+
+ /**
+ * UDP port where the GTP-U Socket is bound -> posto a 2153
+ */
+ uint16_t m_udpPortM1;
+
/**
* Provider for the S1 SAP
*/
@@ -244,6 +267,7 @@
uint16_t m_cellId;
+
};
} //namespace ns3
--- a/src/lte/model/epc-mme.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/epc-mme.cc Thu Jun 13 11:32:13 2013 +0200
@@ -121,6 +121,11 @@
it->second->bearersToBeActivated.push_back (bearerInfo);
}
+void
+EpcMme::AddbearerMbms (Ptr<EpcTft> tft, EpsBearer bearer)
+{
+
+}
// S1-AP SAP MME forwarded methods
--- a/src/lte/model/epc-mme.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/epc-mme.h Thu Jun 13 11:32:13 2013 +0200
@@ -108,8 +108,19 @@
*/
void AddBearer (uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer);
+ /**
+ * Add a MBMS EPS Bearer to the list of MBMS bearers active in
+ * the MBMS Area (Actually 1 MBMS Area = 1 cell)
+ *
+ *
+ * \param tft traffic flow template of the bearer
+ * \param bearer QoS characteristics of the bearer
+ */
+ void AddbearerMbms (Ptr<EpcTft> tft, EpsBearer bearer);
-private:
+
+
+public:
// S1-AP SAP MME forwarded methods
void DoInitialUeMessage (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, uint64_t imsi, uint16_t ecgi);
--- a/src/lte/model/epc-sgw-pgw-application.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/epc-sgw-pgw-application.cc Thu Jun 13 11:32:13 2013 +0200
@@ -57,11 +57,11 @@
NS_LOG_FUNCTION (this << p);
// we hardcode DOWNLINK direction since the PGW is espected to
// classify only downlink packets (uplink packets will go to the
- // internet without any classification).
+ // internet without any classification).
return m_tftClassifier.Classify (p, EpcTft::DOWNLINK);
}
-Ipv4Address
+Ipv4Address
EpcSgwPgwApplication::UeInfo::GetEnbAddr ()
{
return m_enbAddr;
@@ -73,7 +73,7 @@
m_enbAddr = enbAddr;
}
-Ipv4Address
+Ipv4Address
EpcSgwPgwApplication::UeInfo::GetUeAddr ()
{
return m_ueAddr;
@@ -86,6 +86,40 @@
}
/////////////////////////
+// MbmsInfo
+/////////////////////////
+EpcSgwPgwApplication::MbmsInfo::MbmsInfo ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void EpcSgwPgwApplication::MbmsInfo::AddBearer (Ptr<EpcTft> tft, uint32_t teid)
+{
+ NS_LOG_FUNCTION (this << tft << teid);
+ return m_tftClassifierMbms.Add (tft, teid);
+}
+
+void EpcSgwPgwApplication::MbmsInfo::SetEnbAddr (Ipv4Address enbAddr)
+{
+ m_enbAddrMbms = enbAddr;
+}
+
+uint32_t EpcSgwPgwApplication::MbmsInfo::Classify (Ptr<Packet> p)
+{
+ NS_LOG_FUNCTION (this << p);
+ // we hardcode DOWNLINK direction since the PGW is espected to
+ // classify only downlink packets (uplink packets will go to the
+ // internet without any classification).
+ return m_tftClassifierMbms.Classify (p, EpcTft::DOWNLINK);
+}
+
+Ipv4Address EpcSgwPgwApplication::MbmsInfo::GetEnbAddr ()
+{
+ return m_enbAddrMbms;
+}
+
+
+/////////////////////////
// EpcSgwPgwApplication
/////////////////////////
@@ -107,12 +141,16 @@
delete (m_s11SapSgw);
}
-
+
+
-EpcSgwPgwApplication::EpcSgwPgwApplication (const Ptr<VirtualNetDevice> tunDevice, const Ptr<Socket> s1uSocket)
+EpcSgwPgwApplication::EpcSgwPgwApplication (const Ptr<VirtualNetDevice> tunDevice, const Ptr<Socket> s1uSocket, const Ptr<Socket> sgimbSocket)
: m_s1uSocket (s1uSocket),
+ m_sgimbSocket (sgimbSocket),
m_tunDevice (tunDevice),
- m_gtpuUdpPort (2152), // fixed by the standard
+ m_gtpuUdpPort (2152),
+ m_udpPortSgimbSocket (2153),
+ // fixed by the standard
m_teidCount (0),
m_s11SapMme (0)
{
@@ -121,7 +159,7 @@
m_s11SapSgw = new MemberEpcS11SapSgw<EpcSgwPgwApplication> (this);
}
-
+
EpcSgwPgwApplication::~EpcSgwPgwApplication ()
{
NS_LOG_FUNCTION (this);
@@ -140,23 +178,34 @@
Ipv4Address ueAddr = ipv4Header.GetDestination ();
NS_LOG_LOGIC ("packet addressed to UE " << ueAddr);
- // find corresponding UeInfo address
- std::map<Ipv4Address, Ptr<UeInfo> >::iterator it = m_ueInfoByAddrMap.find (ueAddr);
- if (it == m_ueInfoByAddrMap.end ())
- {
- NS_LOG_WARN ("unknown UE address " << ueAddr) ;
+ if (ipv4Header.GetDestination ().IsMulticast ())
+ {
+
+ //Invio pacchetto alla classe MBMS-GW
+ //Si suppone che PGW e BM-SC siano nello stesso modulo
+ //Trasmissione pacchetto su interfaccia SG-iMB
+ SendToSgiMbSocket (packet);
}
else
{
- Ipv4Address enbAddr = it->second->GetEnbAddr ();
- uint32_t teid = it->second->Classify (packet);
- if (teid == 0)
+ // find corresponding UeInfo address
+ std::map<Ipv4Address, Ptr<UeInfo> >::iterator it = m_ueInfoByAddrMap.find (ueAddr);
+ if (it == m_ueInfoByAddrMap.end ())
{
- NS_LOG_WARN ("no matching bearer for this packet");
+ NS_LOG_WARN ("unknown UE address " << ueAddr);
}
else
{
- SendToS1uSocket (packet, enbAddr, teid);
+ Ipv4Address enbAddr = it->second->GetEnbAddr ();
+ uint32_t teid = it->second->Classify (packet);
+ if (teid == 0)
+ {
+ NS_LOG_WARN ("no matching bearer for this packet");
+ }
+ else
+ {
+ SendToS1uSocket (packet, enbAddr, teid);
+ }
}
}
// there is no reason why we should notify the TUN
@@ -166,10 +215,10 @@
return succeeded;
}
-void
+void
EpcSgwPgwApplication::RecvFromS1uSocket (Ptr<Socket> socket)
{
- NS_LOG_FUNCTION (this << socket);
+ NS_LOG_FUNCTION (this << socket);
NS_ASSERT (socket == m_s1uSocket);
Ptr<Packet> packet = socket->Recv ();
GtpuHeader gtpu;
@@ -183,7 +232,7 @@
SendToTunDevice (packet, teid);
}
-void
+void
EpcSgwPgwApplication::SendToTunDevice (Ptr<Packet> packet, uint32_t teid)
{
NS_LOG_FUNCTION (this << packet << teid);
@@ -191,7 +240,7 @@
m_tunDevice->Receive (packet, 0x0800, m_tunDevice->GetAddress (), m_tunDevice->GetAddress (), NetDevice::PACKET_HOST);
}
-void
+void
EpcSgwPgwApplication::SendToS1uSocket (Ptr<Packet> packet, Ipv4Address enbAddr, uint32_t teid)
{
NS_LOG_FUNCTION (this << packet << enbAddr << teid);
@@ -200,26 +249,58 @@
gtpu.SetTeid (teid);
// From 3GPP TS 29.281 v10.0.0 Section 5.1
// Length of the payload + the non obligatory GTP-U header
- gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
+ gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
packet->AddHeader (gtpu);
uint32_t flags = 0;
- m_s1uSocket->SendTo (packet, flags, InetSocketAddress(enbAddr, m_gtpuUdpPort));
+ m_s1uSocket->SendTo (packet, flags, InetSocketAddress (enbAddr, m_gtpuUdpPort));
}
+void
+EpcSgwPgwApplication::SendToSgiMbSocket (Ptr<Packet> packet)
+{
+ NS_LOG_FUNCTION (this << packet);
-void
+ //Temporary solution
+ m_mbmsGw->ReceiveMbmsData (packet);
+
+ /*
+ //Invio a EpcMbmsgwApplication
+ GtpuHeader gtpu;
+ gtpu.SetTeid (teid);
+ // From 3GPP TS 29.281 v10.0.0 Section 5.1
+ // Length of the payload + the non obligatory GTP-U header
+ gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
+ packet->AddHeader (gtpu);
+ uint32_t flags = 0;
+ m_sgimbSocket->SendTo (packet, flags, InetSocketAddress (mbmsgwAddress, m_gtpuUdpPortMbms));
+*/
+}
+
+void
+EpcSgwPgwApplication::setMbmsGwAddress (Ipv4Address mbmsGwAddress)
+{
+ m_mbmsGwAddress = mbmsGwAddress;
+}
+
+void
+EpcSgwPgwApplication::SetMbmsGw (Ptr<EpcMbmsgwApplication> mbmsGwApp)
+{
+ m_mbmsGw = mbmsGwApp;
+}
+
+void
EpcSgwPgwApplication::SetS11SapMme (EpcS11SapMme * s)
{
m_s11SapMme = s;
}
-EpcS11SapSgw*
+EpcS11SapSgw*
EpcSgwPgwApplication::GetS11SapSgw ()
{
return m_s11SapSgw;
}
-void
+void
EpcSgwPgwApplication::AddEnb (uint16_t cellId, Ipv4Address enbAddr, Ipv4Address sgwAddr)
{
NS_LOG_FUNCTION (this << cellId << enbAddr << sgwAddr);
@@ -229,7 +310,7 @@
m_enbInfoByCellId[cellId] = enbInfo;
}
-void
+void
EpcSgwPgwApplication::AddUe (uint64_t imsi)
{
NS_LOG_FUNCTION (this << imsi);
@@ -237,25 +318,25 @@
m_ueInfoByImsiMap[imsi] = ueInfo;
}
-void
+void
EpcSgwPgwApplication::SetUeAddress (uint64_t imsi, Ipv4Address ueAddr)
{
NS_LOG_FUNCTION (this << imsi << ueAddr);
std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
- NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
+ NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
m_ueInfoByAddrMap[ueAddr] = ueit->second;
ueit->second->SetUeAddr (ueAddr);
}
-void
+void
EpcSgwPgwApplication::DoCreateSessionRequest (EpcS11SapSgw::CreateSessionRequestMessage req)
{
NS_LOG_FUNCTION (this << req.imsi);
std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (req.imsi);
- NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << req.imsi);
+ NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << req.imsi);
uint16_t cellId = req.uli.gci;
std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
- NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
+ NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
Ipv4Address enbAddr = enbit->second.enbAddr;
ueit->second->SetEnbAddr (enbAddr);
@@ -268,33 +349,33 @@
{
// simple sanity check. If you ever need more than 4M teids
// throughout your simulation, you'll need to implement a smarter teid
- // management algorithm.
+ // management algorithm.
NS_ABORT_IF (m_teidCount == 0xFFFFFFFF);
- uint32_t teid = ++m_teidCount;
+ uint32_t teid = ++m_teidCount;
ueit->second->AddBearer (bit->tft, bit->epsBearerId, teid);
EpcS11SapMme::BearerContextCreated bearerContext;
bearerContext.sgwFteid.teid = teid;
bearerContext.sgwFteid.address = enbit->second.sgwAddr;
- bearerContext.epsBearerId = bit->epsBearerId;
- bearerContext.bearerLevelQos = bit->bearerLevelQos;
+ bearerContext.epsBearerId = bit->epsBearerId;
+ bearerContext.bearerLevelQos = bit->bearerLevelQos;
bearerContext.tft = bit->tft;
res.bearerContextsCreated.push_back (bearerContext);
}
m_s11SapMme->CreateSessionResponse (res);
-
+
}
-void
+void
EpcSgwPgwApplication::DoModifyBearerRequest (EpcS11SapSgw::ModifyBearerRequestMessage req)
{
NS_LOG_FUNCTION (this << req.teid);
uint64_t imsi = req.teid; // trick to avoid the need for allocating TEIDs on the S11 interface
std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
- NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
+ NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
uint16_t cellId = req.uli.gci;
std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
- NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
+ NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
Ipv4Address enbAddr = enbit->second.enbAddr;
ueit->second->SetEnbAddr (enbAddr);
// no actual bearer modification: for now we just support the minimum needed for path switch request (handover)
@@ -303,5 +384,5 @@
res.cause = EpcS11SapMme::ModifyBearerResponseMessage::REQUEST_ACCEPTED;
m_s11SapMme->ModifyBearerResponse (res);
}
-
+
}; // namespace ns3
--- a/src/lte/model/epc-sgw-pgw-application.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/epc-sgw-pgw-application.h Thu Jun 13 11:32:13 2013 +0200
@@ -37,6 +37,7 @@
#include <ns3/epc-s1ap-sap.h>
#include <ns3/epc-s11-sap.h>
#include <map>
+#include <ns3/epc-mbmsgw-application.h>
namespace ns3 {
@@ -63,12 +64,28 @@
* internet over GTP-U/UDP/IP on the S1-U interface
* \param s1uSocket socket used to send GTP-U packets to the eNBs
*/
- EpcSgwPgwApplication (const Ptr<VirtualNetDevice> tunDevice, const Ptr<Socket> s1uSocket);
+ EpcSgwPgwApplication (const Ptr<VirtualNetDevice> tunDevice, const Ptr<Socket> s1uSocket, const Ptr<Socket> sgimbSocket);
/**
* Destructor
*/
virtual ~EpcSgwPgwApplication (void);
+
+
+ /**
+ * Simulates the reception by the PGW of a GTP-C message of type
+ * CreateSessionRequest or BearerResourceCommand coming from the
+ * MME. This triggers the creation of a new EPS Bearer.
+ *
+ * \param bearer the specification of the EPS Bearer to be created
+ * \param enbS1uAddress the IPv4 address at which the SGW can reach
+ * the eNB via the S1-U interface
+ * \param tft the Traffic Flow Template related to this bearer
+ *
+ * \return the TunnelEndpointIdentifier of this EPS bearer
+ */
+ uint32_t ActivateS1Bearer (Ipv4Address ueAddr, Ipv4Address enbAddr, Ptr<EpcTft> tft);
+
/**
* Method to be assigned to the callback of the Gi TUN VirtualNetDevice. It
@@ -111,6 +128,15 @@
*/
void SendToS1uSocket (Ptr<Packet> packet, Ipv4Address enbS1uAddress, uint32_t teid);
+ /**
+ * Send a packet to the MBMS-GW via the SG-iMB interface
+ *
+ * \param packet packet to be sent
+ * \param mbmsgwAddress the address of the MBMS-GW
+ * \param teid the Tunnel Enpoint IDentifier
+ */
+
+ void SendToSgiMbSocket (Ptr<Packet> packet);
/**
* Set the MME side of the S11 SAP
@@ -149,6 +175,21 @@
*/
void SetUeAddress (uint64_t imsi, Ipv4Address ueAddr);
+ /**
+ * set the address of MBMS-GW
+ *
+ * \param mbmsGwAddress the IPv4 address of MBMS-GW
+ *
+ */
+ void setMbmsGwAddress (Ipv4Address mbmsGwAddress);
+
+ /**
+ * Pointer to MBMS-GW
+ *
+ */
+ void SetMbmsGw (Ptr<EpcMbmsgwApplication> mbmsGwApp);
+
+
private:
// S11 SAP SGW methods
@@ -214,6 +255,46 @@
std::map<uint8_t, uint32_t> m_teidByBearerIdMap;
};
+ class MbmsInfo
+ {
+public:
+ MbmsInfo ();
+
+ /**
+ *
+ * \param tft the Traffic Flow Template of the new bearer to be added
+ * \param teid the TEID of the new bearer
+ */
+ void AddBearer (Ptr<EpcTft> tft, uint32_t teid);
+
+ /**
+ *
+ *
+ * \param p the IP packet from the internet to be classified
+ *
+ * \return the corresponding bearer ID > 0 identifying the bearer
+ * among all the bearers of this UE; returns 0 if no bearers
+ * matches with the previously declared TFTs
+ */
+ uint32_t Classify (Ptr<Packet> p);
+
+ /**
+ * \return the address of the eNB to which the UE is connected
+ */
+ Ipv4Address GetEnbAddr ();
+
+ /**
+ * set the address of the eNB to which the UE is connected
+ *
+ * \param addr the address of the eNB
+ */
+ void SetEnbAddr (Ipv4Address addr);
+private:
+ EpcTftClassifier m_tftClassifierMbms;
+ Ipv4Address m_enbAddrMbms;
+ uint32_t mbmsInfoTeid;
+ };
+
/**
* UDP socket to send and receive GTP-U packets to and from the S1-U interface
@@ -221,6 +302,22 @@
Ptr<Socket> m_s1uSocket;
/**
+ * UDP socket to send MBMS packets to SG-iMB interface
+ */
+ Ptr<Socket> m_sgimbSocket;
+
+ /**
+ * MBMS-GW IPv4 address
+ */
+
+ Ipv4Address m_mbmsGwAddress;
+
+ /**
+ * Ptr to MBMS-GW
+ */
+ Ptr<EpcMbmsgwApplication> m_mbmsGw;
+
+ /**
* TUN VirtualNetDevice used for tunneling/detunneling IP packets
* from/to the internet over GTP-U/UDP/IP on the S1 interface
*/
@@ -241,6 +338,11 @@
*/
uint16_t m_gtpuUdpPort;
+ /**
+ * UDP port to be used for SG-imb interface
+ */
+ uint16_t m_udpPortSgimbSocket;
+
uint32_t m_teidCount;
/**
--- a/src/lte/model/eps-bearer.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/eps-bearer.cc Thu Jun 13 11:32:13 2013 +0200
@@ -48,16 +48,24 @@
}
EpsBearer::EpsBearer (Qci x)
- : qci (x)
+ : qci (x),
+ m_multicast (false)
{
}
-EpsBearer::EpsBearer (Qci x, struct GbrQosInformation y)
- : qci (x), gbrQosInfo (y)
+EpsBearer::EpsBearer (Qci x, bool multicast)
+ : qci (x),
+ m_multicast (multicast)
{
}
bool
+EpsBearer::isMulticast ()
+{
+ return m_multicast;
+}
+
+bool
EpsBearer::IsGbr () const
{
// 3GPP 23.203 Section 6.1.7.2
--- a/src/lte/model/eps-bearer.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/eps-bearer.h Thu Jun 13 11:32:13 2013 +0200
@@ -32,7 +32,7 @@
*/
struct GbrQosInformation
{
- /**
+ /**
* Default constructor, inizializes member variables to zero or equivalent
*/
GbrQosInformation ();
@@ -50,7 +50,7 @@
*/
struct AllocationRetentionPriority
{
- /**
+ /**
* Default constructor, inizializes member variables to zero or equivalent
*/
AllocationRetentionPriority ();
@@ -90,9 +90,12 @@
GbrQosInformation gbrQosInfo;
AllocationRetentionPriority arp;
+ bool m_multicast;
+
+
/**
* Deault constructor. QCI will be initialized to NGBR_VIDEO_TCP_DEFAULT
- *
+ *
*/
EpsBearer ();
@@ -103,7 +106,18 @@
*/
EpsBearer (Qci x);
- EpsBearer (Qci x, GbrQosInformation y);
+ /*
+ *
+ * @param x the Qos Class indicator
+ * @param multicast true if MBMS bearer
+ */
+ EpsBearer (Qci x, bool multicast);
+
+ /**
+ * @return true if MBMS bearer
+ */
+ bool isMulticast ();
+
/**
*
--- a/src/lte/model/ff-mac-common.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/ff-mac-common.h Thu Jun 13 11:32:13 2013 +0200
@@ -88,6 +88,7 @@
struct DlDciListElement_s
{
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint32_t m_rbBitmap;
uint8_t m_rbShift;
uint8_t m_resAlloc;
@@ -231,6 +232,15 @@
struct BuildDataListElement_s
{
uint16_t m_rnti;
+ uint16_t m_mrnti;
+ struct DlDciListElement_s m_dci;
+ std::vector <enum CeBitmap_e> m_ceBitmap;
+ std::vector < std::vector <struct RlcPduListElement_s> > m_rlcPduList;
+};
+
+struct BuildDataListElementMbms_s
+{
+ uint16_t m_mrnti;
struct DlDciListElement_s m_dci;
std::vector <enum CeBitmap_e> m_ceBitmap;
std::vector < std::vector <struct RlcPduListElement_s> > m_rlcPduList;
--- a/src/lte/model/ff-mac-csched-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/ff-mac-csched-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -191,6 +191,69 @@
};
/**
+ * Parameters of the CSCHED_UE_CONFIG_REQ primitive.
+ * See section 4.1.3 for a detailed description of the parameters.
+ */
+ struct CschedMbmsConfigReqParameters
+ {
+ uint16_t m_mrnti;
+ bool m_reconfigureFlag;
+ bool m_drxConfigPresent;
+ struct DrxConfig_s m_drxConfig;
+ uint16_t m_timeAlignmentTimer;
+
+ enum MeasGapConfigPattern_e
+ {
+ MGP_GP1,
+ MGP_GP2,
+ OFF
+ } m_measGapConfigPattern;
+
+ uint8_t m_measGapConfigSubframeOffset;
+ bool m_spsConfigPresent;
+ struct SpsConfig_s m_spsConfig;
+ bool m_srConfigPresent;
+ struct SrConfig_s m_srConfig;
+ bool m_cqiConfigPresent;
+ struct CqiConfig_s m_cqiConfig;
+ uint8_t m_transmissionMode;
+ uint64_t m_mbmsAggregatedMaximumBitrateUl;
+ uint64_t m_mbmsAggregatedMaximumBitrateDl;
+ struct UeCapabilities_s m_mbmsCapabilities;
+
+ enum OpenClosedLoop_e
+ {
+ noneloop,
+ openloop,
+ closedloop
+ } m_ueTransmitAntennaSelection;
+
+ bool m_ttiBundling;
+ uint8_t m_maxHarqTx;
+ uint8_t m_betaOffsetAckIndex;
+ uint8_t m_betaOffsetRiIndex;
+ uint8_t m_betaOffsetCqiIndex;
+ bool m_ackNackSrsSimultaneousTransmission;
+ bool m_simultaneousAckNackAndCqi;
+
+ enum RepMode_e
+ {
+ rm12, rm20, rm22, rm30, rm31, nonemode
+ } m_aperiodicCqiRepMode;
+
+ enum FeedbackMode_e
+ {
+ bundling,
+ multiplexing
+ } m_tddAckNackFeedbackMode;
+
+ uint8_t m_ackNackRepetitionFactor;
+
+ std::vector <struct VendorSpecificListElement_s> m_vendorSpecificList;
+ };
+
+
+ /**
* Parameters of the CSCHED_LC_CONFIG_REQ primitive.
* See section 4.1.5 for a detailed description of the parameters.
*/
@@ -240,6 +303,8 @@
virtual void CschedUeConfigReq (const struct CschedUeConfigReqParameters& params) = 0;
+ virtual void CschedMbmsConfigReq (const struct CschedMbmsConfigReqParameters& params) = 0;
+
virtual void CschedLcConfigReq (const struct CschedLcConfigReqParameters& params) = 0;
virtual void CschedLcReleaseReq (const struct CschedLcReleaseReqParameters& params) = 0;
--- a/src/lte/model/ff-mac-sched-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/ff-mac-sched-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -63,6 +63,7 @@
struct SchedDlRlcBufferReqParameters
{
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint8_t m_logicalChannelIdentity;
uint32_t m_rlcTransmissionQueueSize;
uint16_t m_rlcTransmissionQueueHolDelay;
@@ -221,6 +222,8 @@
virtual void SchedUlCqiInfoReq (const struct SchedUlCqiInfoReqParameters& params) = 0;
+ virtual void SchedMbmsTriggerReq (const struct SchedDlTriggerReqParameters& params) = 0;
+
private:
};
@@ -243,6 +246,7 @@
std::vector <struct BuildDataListElement_s> m_buildDataList;
std::vector <struct BuildRarListElement_s> m_buildRarList;
std::vector <struct BuildBroadcastListElement_s> m_buildBroadcastList;
+ std::vector <struct BuildDataListElementMbms_s> m_buildDataListMbms;
uint8_t m_nrOfPdcchOfdmSymbols;
@@ -270,6 +274,8 @@
virtual void SchedUlConfigInd (const struct SchedUlConfigIndParameters& params) = 0;
+ virtual void SchedDlConfigIndMbms (const struct SchedDlConfigIndParameters& params) = 0;
+
private:
};
--- a/src/lte/model/lte-enb-cmac-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-cmac-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -54,6 +54,7 @@
virtual void AddUe (uint16_t rnti) = 0;
+ virtual void AddMbms (uint16_t mrnti) = 0;
/**
* remove the UE, e.g., after handover or termination of the RRC connection
*
--- a/src/lte/model/lte-enb-cphy-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-cphy-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -72,6 +72,13 @@
*/
virtual void AddUe (uint16_t rnti) = 0;
+ /**
+ * Add a new MBMS to the cell
+ *
+ * \param mrnti the MBMS id relative to this cell
+ */
+ virtual void AddMbms (uint16_t mrnti) = 0;
+
/**
* Remove an UE from the the cell
*
@@ -133,6 +140,7 @@
virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
virtual void SetEarfcn (uint16_t ulEarfcn, uint16_t dlEarfcn);
virtual void AddUe (uint16_t rnti);
+ virtual void AddMbms (uint16_t mrnti);
virtual void RemoveUe (uint16_t rnti);
virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode);
virtual void SetSrsConfigurationIndex (uint16_t rnti, uint16_t srsCi);
@@ -184,6 +192,13 @@
}
template <class C>
+void
+MemberLteEnbCphySapProvider<C>::AddMbms (uint16_t mrnti)
+{
+ m_owner->DoAddMbms (mrnti);
+}
+
+template <class C>
void
MemberLteEnbCphySapProvider<C>::RemoveUe (uint16_t rnti)
{
--- a/src/lte/model/lte-enb-mac.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-mac.cc Thu Jun 13 11:32:13 2013 +0200
@@ -60,6 +60,7 @@
// inherited from LteEnbCmacSapProvider
virtual void ConfigureMac (uint8_t ulBandwidth, uint8_t dlBandwidth);
virtual void AddUe (uint16_t rnti);
+ virtual void AddMbms (uint16_t mrnti);
virtual void RemoveUe (uint16_t rnti);
virtual void AddLc (LcInfo lcinfo, LteMacSapUser* msu);
virtual void ReconfigureLc (LcInfo lcinfo);
@@ -67,7 +68,7 @@
virtual void UeUpdateConfigurationReq (UeConfig params);
virtual RachConfig GetRachConfig ();
virtual AllocateNcRaPreambleReturnValue AllocateNcRaPreamble (uint16_t rnti);
-
+
private:
LteEnbMac* m_mac;
@@ -92,6 +93,12 @@
}
void
+EnbMacMemberLteEnbCmacSapProvider::AddMbms (uint16_t mrnti)
+{
+ m_mac->DoAddMbms (mrnti);
+}
+
+void
EnbMacMemberLteEnbCmacSapProvider::RemoveUe (uint16_t rnti)
{
m_mac->DoRemoveUe (rnti);
@@ -121,13 +128,13 @@
m_mac->DoUeUpdateConfigurationReq (params);
}
-LteEnbCmacSapProvider::RachConfig
+LteEnbCmacSapProvider::RachConfig
EnbMacMemberLteEnbCmacSapProvider::GetRachConfig ()
{
return m_mac->DoGetRachConfig ();
}
-
-LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
+
+LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
EnbMacMemberLteEnbCmacSapProvider::AllocateNcRaPreamble (uint16_t rnti)
{
return m_mac->DoAllocateNcRaPreamble (rnti);
@@ -142,6 +149,7 @@
virtual void SchedDlConfigInd (const struct SchedDlConfigIndParameters& params);
virtual void SchedUlConfigInd (const struct SchedUlConfigIndParameters& params);
+ virtual void SchedDlConfigIndMbms (const struct SchedDlConfigIndParameters& params);
private:
LteEnbMac* m_mac;
};
@@ -168,6 +176,12 @@
}
+void
+EnbMacMemberFfMacSchedSapUser::SchedDlConfigIndMbms (const struct SchedDlConfigIndParameters& params)
+{
+ m_mac->DoSchedDlConfigIndMbms (params);
+}
+
class EnbMacMemberFfMacCschedSapUser : public FfMacCschedSapUser
{
@@ -331,6 +345,11 @@
UintegerValue (3),
MakeUintegerAccessor (&LteEnbMac::m_raResponseWindowSize),
MakeUintegerChecker<uint8_t> (2, 10))
+ .AddAttribute ("MbmsSubframe",
+ "The number of MBMS subframe per frame (max 6)",
+ UintegerValue (3),
+ MakeUintegerAccessor (&LteEnbMac::m_mbmsSubframe),
+ MakeUintegerChecker<uint16_t> ())
.AddTraceSource ("DlScheduling",
"Information regarding DL scheduling.",
MakeTraceSourceAccessor (&LteEnbMac::m_dlScheduling))
@@ -440,6 +459,31 @@
return m_enbPhySapUser;
}
+bool
+LteEnbMac::CheckSubframeMbms (uint16_t subframeNumber)
+{
+ if ((subframeNumber == 1 || subframeNumber == 5
+ || subframeNumber == 6 || subframeNumber == 10))
+ {
+ if (m_counterSubframe != m_mbmsSubframe)
+ {
+ m_counterSubframe++;
+ return (true);
+ }
+ else
+ {
+ m_counterSubframe = 0;
+ return (false);
+ }
+
+ }
+ else
+ {
+ return (false);
+ }
+
+}
+
void
@@ -484,7 +528,7 @@
{
NS_LOG_INFO ("preambleId " << (uint32_t) it->first << ": collision");
// in case of collision we assume that no preamble is
- // successfully received, hence no RAR is sent
+ // successfully received, hence no RAR is sent
}
else
{
@@ -494,7 +538,7 @@
{
rnti = jt->second.rnti;
NS_LOG_INFO ("preambleId previously allocated for NC based RA, RNTI =" << (uint32_t) rnti << ", sending RAR");
-
+
}
else
{
@@ -528,34 +572,45 @@
FfMacSchedSapProvider::SchedDlTriggerReqParameters dlparams;
dlparams.m_sfnSf = ((0x3FF & dlSchedFrameNo) << 4) | (0xF & dlSchedSubframeNo);
- // Forward DL HARQ feebacks collected during last TTI
- if (m_dlInfoListReceived.size () > 0)
+
+ //Check if subframe MBMS
+ uint16_t subframeNumber = 0xF & dlparams.m_sfnSf;
+ if (CheckSubframeMbms (subframeNumber))
+ {
+ m_schedSapProvider->SchedMbmsTriggerReq (dlparams);
+ }
+ else
{
- dlparams.m_dlInfoList = m_dlInfoListReceived;
- // empty local buffer
- m_dlInfoListReceived.clear ();
+ // Forward DL HARQ feebacks collected during last TTI
+ if (m_dlInfoListReceived.size () > 0)
+ {
+ dlparams.m_dlInfoList = m_dlInfoListReceived;
+ // empty local buffer
+ m_dlInfoListReceived.clear ();
+ }
+
+ m_schedSapProvider->SchedDlTriggerReq (dlparams);
+
}
- m_schedSapProvider->SchedDlTriggerReq (dlparams);
-
// --- UPLINK ---
// Send UL-CQI info to the scheduler
std::vector <FfMacSchedSapProvider::SchedUlCqiInfoReqParameters>::iterator itCqi;
for (uint16_t i = 0; i < m_ulCqiReceived.size (); i++)
{
- if (subframeNo>1)
- {
+ if (subframeNo > 1)
+ {
m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & (subframeNo - 1));
}
else
{
- m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & (frameNo-1)) << 4) | (0xF & 10);
+ m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & (frameNo - 1)) << 4) | (0xF & 10);
}
m_schedSapProvider->SchedUlCqiInfoReq (m_ulCqiReceived.at (i));
}
- m_ulCqiReceived.clear ();
-
+ m_ulCqiReceived.clear ();
+
// Send BSR reports to the scheduler
if (m_ulCeReceived.size () > 0)
{
@@ -571,14 +626,14 @@
uint32_t ulSchedFrameNo = m_frameNo;
uint32_t ulSchedSubframeNo = m_subframeNo;
// NS_LOG_DEBUG (this << " sfn " << frameNo << " sbfn " << subframeNo);
- if (ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY) > 10)
+ if (ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY) > 10)
{
ulSchedFrameNo++;
- ulSchedSubframeNo = (ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY)) % 10;
+ ulSchedSubframeNo = (ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY)) % 10;
}
else
{
- ulSchedSubframeNo = ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY);
+ ulSchedSubframeNo = ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY);
}
FfMacSchedSapProvider::SchedUlTriggerReqParameters ulparams;
ulparams.m_sfnSf = ((0x3FF & ulSchedFrameNo) << 4) | (0xF & ulSchedSubframeNo);
@@ -586,7 +641,7 @@
// Forward DL HARQ feebacks collected during last TTI
if (m_ulInfoListReceived.size () > 0)
{
- ulparams.m_ulInfoList = m_ulInfoListReceived;
+ ulparams.m_ulInfoList = m_ulInfoListReceived;
// empty local buffer
m_ulInfoListReceived.clear ();
}
@@ -631,7 +686,7 @@
void
LteEnbMac::DoUlCqiReport (FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)
-{
+{
if (ulcqi.m_ulCqi.m_type == UlCqi_s::PUSCH)
{
NS_LOG_DEBUG (this << " eNB rxed an PUSCH UL-CQI");
@@ -691,7 +746,7 @@
// ulinfonew.m_receptionStatus = UlInfoListElement_s::Ok;
// ulinfonew.m_tpc = 0; // Tx power control not implemented at this stage
// m_ulInfoListElements.insert (std::pair<uint16_t, UlInfoListElement_s > (tag.GetRnti (), ulinfonew));
-//
+//
// }
// else
// {
@@ -741,8 +796,8 @@
{
NS_LOG_FUNCTION (this << " rnti=" << rnti);
std::map<uint8_t, LteMacSapUser*> empty;
- std::pair <std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator, bool>
- ret = m_rlcAttached.insert (std::pair <uint16_t, std::map<uint8_t, LteMacSapUser*> >
+ std::pair <std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator, bool>
+ ret = m_rlcAttached.insert (std::pair <uint16_t, std::map<uint8_t, LteMacSapUser*> >
(rnti, empty));
NS_ASSERT_MSG (ret.second, "element already present, RNTI already existed");
@@ -774,6 +829,23 @@
}
void
+LteEnbMac::DoAddMbms (uint16_t mrnti)
+{
+ NS_LOG_FUNCTION (this << " mrnti=" << mrnti);
+ std::map<uint8_t, LteMacSapUser*> empty;
+ std::pair <std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator, bool>
+ ret = m_rlcAttached.insert (std::pair <uint16_t, std::map<uint8_t, LteMacSapUser*> >
+ (mrnti, empty));
+ NS_ASSERT_MSG (ret.second, "element already present, MRNTI already existed");
+
+ FfMacCschedSapProvider::CschedMbmsConfigReqParameters params;
+ params.m_mrnti = mrnti;
+ params.m_transmissionMode = 0; // set to default value (SISO) for avoiding random initialization (valgrind error)
+
+ m_cschedSapProvider->CschedMbmsConfigReq (params);
+}
+
+void
LteEnbMac::DoRemoveUe (uint16_t rnti)
{
NS_LOG_FUNCTION (this << " rnti=" << rnti);
@@ -790,9 +862,9 @@
NS_LOG_FUNCTION (this);
std::map <LteFlowId_t, LteMacSapUser* >::iterator it;
-
+
LteFlowId_t flow (lcinfo.rnti, lcinfo.lcId);
-
+
std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator rntiIt = m_rlcAttached.find (lcinfo.rnti);
NS_ASSERT_MSG (rntiIt != m_rlcAttached.end (), "RNTI not found");
std::map<uint8_t, LteMacSapUser*>::iterator lcidIt = rntiIt->second.find (lcinfo.lcId);
@@ -805,9 +877,9 @@
NS_LOG_ERROR ("LC already exists");
}
- // CCCH (LCID 0) is pre-configured
+ // CCCH (LCID 0) is pre-configured
// see FF LTE MAC Scheduler
- // Interface Specification v1.11,
+ // Interface Specification v1.11,
// 4.3.4 logicalChannelConfigListElement
if (lcinfo.lcId != 0)
{
@@ -856,7 +928,7 @@
m_cschedSapProvider->CschedUeConfigReq (req);
}
-LteEnbCmacSapProvider::RachConfig
+LteEnbCmacSapProvider::RachConfig
LteEnbMac::DoGetRachConfig ()
{
struct LteEnbCmacSapProvider::RachConfig rc;
@@ -865,8 +937,8 @@
rc.raResponseWindowSize = m_raResponseWindowSize;
return rc;
}
-
-LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
+
+LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
LteEnbMac::DoAllocateNcRaPreamble (uint16_t rnti)
{
bool found = false;
@@ -879,8 +951,8 @@
{
found = true;
NcRaPreambleInfo preambleInfo;
- uint32_t expiryIntervalMs = (uint32_t) m_preambleTransMax * ((uint32_t) m_raResponseWindowSize + 5);
-
+ uint32_t expiryIntervalMs = (uint32_t) m_preambleTransMax * ((uint32_t) m_raResponseWindowSize + 5);
+
preambleInfo.expiryTime = Simulator::Now () + MilliSeconds (expiryIntervalMs);
preambleInfo.rnti = rnti;
NS_LOG_INFO ("allocated preamble for NC based RA: preamble " << preambleId << ", RNTI " << preambleInfo.rnti << ", exiryTime " << preambleInfo.expiryTime);
@@ -915,15 +987,18 @@
LteEnbMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
{
NS_LOG_FUNCTION (this);
- LteRadioBearerTag tag (params.rnti, params.lcid, params.layer);
+ LteRadioBearerTag tag (params.rnti, params.mrnti, params.lcid, params.layer);
params.pdu->AddPacketTag (tag);
- // Store pkt in HARQ buffer
- std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (params.rnti);
- NS_ASSERT (it!=m_miDlHarqProcessesPackets.end ());
- NS_LOG_DEBUG (this << " LAYER " <<(uint16_t)tag.GetLayer () << " HARQ ID " << (uint16_t)params.harqProcessId);
-
- //(*it).second.at (params.layer).at (params.harqProcessId) = params.pdu;//->Copy ();
- (*it).second.at (params.layer).at (params.harqProcessId)->AddPacket (params.pdu);
+ // Store pkt in HARQ buffer - only for unicast traffic
+ if (params.rnti != 0)
+ {
+ std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (params.rnti);
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
+ NS_LOG_DEBUG (this << " LAYER " << (uint16_t)tag.GetLayer () << " HARQ ID " << (uint16_t)params.harqProcessId);
+
+ //(*it).second.at (params.layer).at (params.harqProcessId) = params.pdu;//->Copy ();
+ (*it).second.at (params.layer).at (params.harqProcessId)->AddPacket (params.pdu);
+ }
m_enbPhySapProvider->SendMacPdu (params.pdu);
}
@@ -933,6 +1008,7 @@
NS_LOG_FUNCTION (this);
FfMacSchedSapProvider::SchedDlRlcBufferReqParameters req;
req.m_rnti = params.rnti;
+ req.m_mrnti = params.mrnti;
req.m_logicalChannelIdentity = params.lcid;
req.m_rlcTransmissionQueueSize = params.txQueueSize;
req.m_rlcTransmissionQueueHolDelay = params.txQueueHolDelay;
@@ -966,8 +1042,8 @@
{
// new data -> force emptying correspondent harq pkt buffer
std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (ind.m_buildDataList.at (i).m_rnti);
- NS_ASSERT(it!=m_miDlHarqProcessesPackets.end());
- for (uint16_t lcId = 0; lcId < (*it).second.size (); lcId ++)
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
+ for (uint16_t lcId = 0; lcId < (*it).second.size (); lcId++)
{
Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
(*it).second.at (lcId).at (ind.m_buildDataList.at (i).m_dci.m_harqProcess) = pb;
@@ -992,11 +1068,11 @@
}
else
{
- if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (k)>0)
+ if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (k) > 0)
{
// HARQ retransmission -> retrieve TB from HARQ buffer
std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (ind.m_buildDataList.at (i).m_rnti);
- NS_ASSERT(it!=m_miDlHarqProcessesPackets.end());
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
Ptr<PacketBurst> pb = (*it).second.at (k).at ( ind.m_buildDataList.at (i).m_dci.m_harqProcess);
for (std::list<Ptr<Packet> >::const_iterator j = pb->Begin (); j != pb->End (); ++j)
{
@@ -1101,7 +1177,67 @@
}
+void
+LteEnbMac::DoSchedDlConfigIndMbms (FfMacSchedSapUser::SchedDlConfigIndParameters ind)
+{
+ NS_LOG_FUNCTION (this);
+ // Create DL PHY PDU
+ Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
+ std::map <LteFlowId_t, LteMacSapUser* >::iterator it;
+ for (unsigned int i = 0; i < ind.m_buildDataList.size (); i++)
+ {
+
+ for (unsigned int j = 0; j < ind.m_buildDataList.at (i).m_rlcPduList.size (); j++)
+ {
+ for (uint16_t k = 0; k < ind.m_buildDataList.at (i).m_rlcPduList.at (j).size (); k++)
+ {
+ // New Data -> retrieve it from RLC
+ uint16_t mrnti = ind.m_buildDataList.at (i).m_mrnti;
+ uint8_t lcid = ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_logicalChannelIdentity;
+ std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator mrntiIt = m_rlcAttached.find (mrnti);
+ NS_ASSERT_MSG (mrntiIt != m_rlcAttached.end (), "could not find M-RNTI" << mrnti);
+ std::map<uint8_t, LteMacSapUser*>::iterator lcidIt = mrntiIt->second.find (lcid);
+ NS_ASSERT_MSG (lcidIt != mrntiIt->second.end (), "could not find LCID" << lcid);
+ NS_LOG_DEBUG (this << " mrnti= " << mrnti << " lcid= " << (uint32_t) lcid << " layer= " << k);
+ (*lcidIt).second->NotifyTxOpportunity (ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_size, k, 0);
+ }
+ }
+ // send the relative DCI
+ Ptr<DlDciLteControlMessage> msg = Create<DlDciLteControlMessage> ();
+ msg->SetDci (ind.m_buildDataList.at (i).m_dci);
+ m_enbPhySapProvider->SendLteControlMessage (msg);
+ }
+
+ // Fire the trace with the DL information
+ for ( uint32_t i = 0; i < ind.m_buildDataList.size (); i++ )
+ {
+ // Only one TB used
+ if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.size () == 1)
+ {
+ m_dlScheduling (m_frameNo, m_subframeNo, ind.m_buildDataList.at (i).m_dci.m_rnti,
+ ind.m_buildDataList.at (i).m_dci.m_mcs.at (0),
+ ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (0),
+ 0, 0
+ );
+
+ }
+ // Two TBs used
+ else if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.size () == 2)
+ {
+ m_dlScheduling (m_frameNo, m_subframeNo, ind.m_buildDataList.at (i).m_dci.m_rnti,
+ ind.m_buildDataList.at (i).m_dci.m_mcs.at (0),
+ ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (0),
+ ind.m_buildDataList.at (i).m_dci.m_mcs.at (1),
+ ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (1)
+ );
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Found element with more than two transport blocks");
+ }
+ }
+}
// ////////////////////////////////////////////
@@ -1171,17 +1307,17 @@
NS_LOG_FUNCTION (this);
// Update HARQ buffer
std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (params.m_rnti);
- NS_ASSERT (it!=m_miDlHarqProcessesPackets.end ());
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
for (uint8_t layer = 0; layer < params.m_harqStatus.size (); layer++)
{
- if (params.m_harqStatus.at (layer)==DlInfoListElement_s::ACK)
+ if (params.m_harqStatus.at (layer) == DlInfoListElement_s::ACK)
{
// discard buffer
Ptr<PacketBurst> emptyBuf = CreateObject <PacketBurst> ();
(*it).second.at (layer).at (params.m_harqProcessId) = emptyBuf;
NS_LOG_DEBUG (this << " HARQ-ACK UE " << params.m_rnti << " harqId " << (uint16_t)params.m_harqProcessId << " layer " << (uint16_t)layer);
}
- else if (params.m_harqStatus.at (layer)==DlInfoListElement_s::NACK)
+ else if (params.m_harqStatus.at (layer) == DlInfoListElement_s::NACK)
{
NS_LOG_DEBUG (this << " HARQ-NACK UE " << params.m_rnti << " harqId " << (uint16_t)params.m_harqProcessId << " layer " << (uint16_t)layer);
}
--- a/src/lte/model/lte-enb-mac.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-mac.h Thu Jun 13 11:32:13 2013 +0200
@@ -120,6 +120,11 @@
*/
void SetLteEnbPhySapProvider (LteEnbPhySapProvider* s);
+ /**
+ * Check if subframe MBMS
+ */
+ bool CheckSubframeMbms (uint16_t subframeNumber);
+
private:
@@ -145,6 +150,7 @@
// forwarded from LteEnbCmacSapProvider
void DoConfigureMac (uint8_t ulBandwidth, uint8_t dlBandwidth);
void DoAddUe (uint16_t rnti);
+ void DoAddMbms (uint16_t mrnti);
void DoRemoveUe (uint16_t rnti);
void DoAddLc (LteEnbCmacSapProvider::LcInfo lcinfo, LteMacSapUser* msu);
void DoReconfigureLc (LteEnbCmacSapProvider::LcInfo lcinfo);
@@ -170,6 +176,7 @@
// forwarded from FfMacSchedSapUser
void DoSchedDlConfigInd (FfMacSchedSapUser::SchedDlConfigIndParameters ind);
void DoSchedUlConfigInd (FfMacSchedSapUser::SchedUlConfigIndParameters params);
+ void DoSchedDlConfigIndMbms (FfMacSchedSapUser::SchedDlConfigIndParameters ind);
// forwarded from LteEnbPhySapUser
void DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo);
@@ -240,6 +247,10 @@
uint8_t m_preambleTransMax;
uint8_t m_raResponseWindowSize;
+ //MBMS attributes
+ uint16_t m_mbmsSubframe;
+ uint8_t m_counterSubframe;
+
/**
* info associated with a preamble allocated for non-contention based RA
*
--- a/src/lte/model/lte-enb-phy.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-phy.cc Thu Jun 13 11:32:13 2013 +0200
@@ -351,6 +351,24 @@
}
bool
+LteEnbPhy::AddMbmsPhy (uint16_t mrnti)
+{
+ NS_LOG_FUNCTION (this << mrnti);
+ std::set <uint16_t>::iterator it;
+ it = m_mbmsAttached.find (mrnti);
+ if(it == m_mbmsAttached.end())
+ {
+ m_mbmsAttached.insert (mrnti);
+ return (true);
+ }
+ else
+ {
+ NS_LOG_ERROR ("MRNTI already attached");
+ return (false);
+ }
+}
+
+bool
LteEnbPhy::DeleteUePhy (uint16_t rnti)
{
NS_LOG_FUNCTION (this << rnti);
@@ -557,7 +575,7 @@
{
rbMap.push_back (i);
}
- m_uplinkSpectrumPhy->AddExpectedTb ((*dciIt).GetDci ().m_rnti, (*dciIt).GetDci ().m_ndi, (*dciIt).GetDci ().m_tbSize, (*dciIt).GetDci ().m_mcs, rbMap, 0 /* always SISO*/, 0 /* no HARQ proc id in UL*/, 0 /*evaluated by LteSpectrumPhy*/, false /* UL*/);
+ m_uplinkSpectrumPhy->AddExpectedTb ((*dciIt).GetDci ().m_rnti, 0, (*dciIt).GetDci ().m_ndi, (*dciIt).GetDci ().m_tbSize, (*dciIt).GetDci ().m_mcs, rbMap, 0 /* always SISO*/, 0 /* no HARQ proc id in UL*/, 0 /*evaluated by LteSpectrumPhy*/, false /* UL*/);
if ((*dciIt).GetDci ().m_ndi==1)
{
NS_LOG_DEBUG (this << " RNTI " << (*dciIt).GetDci ().m_rnti << " NEW TB");
@@ -832,6 +850,15 @@
NS_ASSERT_MSG (success, "AddUePhy() failed");
}
+void
+LteEnbPhy::DoAddMbms (uint16_t mrnti)
+{
+ NS_LOG_FUNCTION (this << mrnti);
+
+ bool success = AddMbmsPhy (mrnti);
+ NS_ASSERT_MSG (success, "AddMbmsPhy() failed");
+}
+
void
LteEnbPhy::DoRemoveUe (uint16_t rnti)
{
--- a/src/lte/model/lte-enb-phy.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-phy.h Thu Jun 13 11:32:13 2013 +0200
@@ -260,6 +260,7 @@
void DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
void DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn);
void DoAddUe (uint16_t rnti);
+ void DoAddMbms (uint16_t mrnti);
void DoRemoveUe (uint16_t rnti);
void DoSetTransmissionMode (uint16_t rnti, uint8_t txMode);
void DoSetSrsConfigurationIndex (uint16_t rnti, uint16_t srcCi);
@@ -272,12 +273,15 @@
bool AddUePhy (uint16_t rnti);
+ bool AddMbmsPhy (uint16_t mrnti);
+
bool DeleteUePhy (uint16_t rnti);
void CreateSrsReport(uint16_t rnti, double srs);
std::set <uint16_t> m_ueAttached;
+ std::set <uint16_t> m_mbmsAttached;
std::vector <int> m_listOfDownlinkSubchannel;
--- a/src/lte/model/lte-enb-rrc.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-rrc.cc Thu Jun 13 11:32:13 2013 +0200
@@ -33,6 +33,7 @@
#include "lte-enb-net-device.h"
#include "lte-radio-bearer-info.h"
#include "eps-bearer-tag.h"
+#include "eps-bearer-mbms-tag.h"
#include "ff-mac-csched-sap.h"
#include "epc-enb-s1-sap.h"
@@ -95,19 +96,19 @@
}
-const char* g_ueManagerStateName[UeManager::NUM_STATES] =
- {
- "INITIAL_RANDOM_ACCESS",
- "CONNECTION_SETUP",
- "CONNECTION_REJECTED",
- "CONNECTED_NORMALLY",
- "CONNECTION_RECONFIGURATION",
- "CONNECTION_REESTABLISHMENT",
- "HANDOVER_PREPARATION",
- "HANDOVER_JOINING",
- "HANDOVER_PATH_SWITCH",
- "HANDOVER_LEAVING",
- };
+const char* g_ueManagerStateName[UeManager::NUM_STATES] =
+{
+ "INITIAL_RANDOM_ACCESS",
+ "CONNECTION_SETUP",
+ "CONNECTION_REJECTED",
+ "CONNECTED_NORMALLY",
+ "CONNECTION_RECONFIGURATION",
+ "CONNECTION_REESTABLISHMENT",
+ "HANDOVER_PREPARATION",
+ "HANDOVER_JOINING",
+ "HANDOVER_PATH_SWITCH",
+ "HANDOVER_LEAVING",
+};
std::string ToString (UeManager::State s)
{
@@ -117,7 +118,7 @@
///////////////////////////////////////////
-// UeManager
+// UeManager
///////////////////////////////////////////
@@ -133,6 +134,7 @@
UeManager::UeManager (Ptr<LteEnbRrc> rrc, uint16_t rnti, State s)
: m_lastAllocatedDrbid (0),
m_rnti (rnti),
+ m_mrnti (0),
m_imsi (0),
m_lastRrcTransactionIdentifier (0),
m_rrc (rrc),
@@ -141,7 +143,7 @@
m_sourceX2apId (0),
m_sourceCellId (0),
m_needTransmissionModeConfiguration (false)
-{
+{
NS_LOG_FUNCTION (this);
}
@@ -168,9 +170,10 @@
Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
rlc->SetLteMacSapProvider (m_rrc->m_macSapProvider);
rlc->SetRnti (m_rnti);
+ rlc->SetMrnti(0);
rlc->SetLcId (lcid);
- m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
+ m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
m_srb0->m_rlc = rlc;
m_srb0->m_srbIdentity = 0;
// no need to store logicalChannelConfig as SRB0 is pre-configured
@@ -180,7 +183,7 @@
lcinfo.lcId = lcid;
// leave the rest of lcinfo empty as CCCH (LCID 0) is pre-configured
m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
-
+
}
// setup the eNB side of SRB1; the UE side will be set up upon RRC connection establishment
@@ -190,16 +193,18 @@
Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ()->GetObject<LteRlc> ();
rlc->SetLteMacSapProvider (m_rrc->m_macSapProvider);
rlc->SetRnti (m_rnti);
+ rlc->SetMrnti(0);
rlc->SetLcId (lcid);
Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
pdcp->SetRnti (m_rnti);
+ pdcp->SetMrnti(0);
pdcp->SetLcId (lcid);
pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
- m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
+ m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
m_srb1->m_rlc = rlc;
m_srb1->m_pdcp = pdcp;
m_srb1->m_srbIdentity = 1;
@@ -207,7 +212,7 @@
m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = 100;
m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = 100;
m_srb1->m_logicalChannelConfig.logicalChannelGroup = 0;
-
+
LteEnbCmacSapProvider::LcInfo lcinfo;
lcinfo.rnti = m_rnti;
lcinfo.lcId = lcid;
@@ -231,7 +236,7 @@
req.m_rnti = m_rnti;
req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
m_rrc->m_cmacSapProvider->UeUpdateConfigurationReq (req);
-
+
// configure PHY
m_rrc->m_cphySapProvider->SetTransmissionMode (m_rnti, m_physicalConfigDedicated.antennaInfo.transmissionMode);
m_rrc->m_cphySapProvider->SetSrsConfigurationIndex (m_rnti, m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex);
@@ -241,21 +246,21 @@
switch (m_state)
{
case INITIAL_RANDOM_ACCESS:
- m_connectionTimeout = Simulator::Schedule (m_rrc->m_connectionTimeoutDuration,
- &LteEnbRrc::ConnectionTimeout,
+ m_connectionTimeout = Simulator::Schedule (m_rrc->m_connectionTimeoutDuration,
+ &LteEnbRrc::ConnectionTimeout,
m_rrc, m_rnti);
break;
case HANDOVER_JOINING:
- m_handoverJoiningTimeout = Simulator::Schedule (m_rrc->m_handoverJoiningTimeoutDuration,
- &LteEnbRrc::HandoverJoiningTimeout,
- m_rrc, m_rnti);
- break;
+ m_handoverJoiningTimeout = Simulator::Schedule (m_rrc->m_handoverJoiningTimeoutDuration,
+ &LteEnbRrc::HandoverJoiningTimeout,
+ m_rrc, m_rnti);
+ break;
default:
NS_FATAL_ERROR ("unexpected state " << ToString (m_state));
- break;
- }
+ break;
+ }
m_servingCellMeasures = CreateObject<UeMeasure> ();
m_servingCellMeasures->m_cellId = m_rrc->m_cellId;
@@ -310,18 +315,18 @@
.AddTraceSource ("StateTransition",
"fired upon every UE state transition seen by the UeManager at the eNB RRC",
MakeTraceSourceAccessor (&UeManager::m_stateTransitionTrace))
- ;
+ ;
return tid;
}
-void
+void
UeManager::SetSource (uint16_t sourceCellId, uint16_t sourceX2apId)
{
m_sourceX2apId = sourceX2apId;
m_sourceCellId = sourceCellId;
}
-void
+void
UeManager::SetImsi (uint64_t imsi)
{
m_imsi = imsi;
@@ -334,8 +339,8 @@
Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
uint8_t drbid = AddDataRadioBearerInfo (drbInfo);
- uint8_t lcid = Drbid2Lcid (drbid);
- uint8_t bid = Drbid2Bid (drbid);
+ uint8_t lcid = Drbid2Lcid (drbid);
+ uint8_t bid = Drbid2Bid (drbid);
NS_ASSERT_MSG ( bearerId == 0 || bid == bearerId, "bearer ID mismatch (" << (uint32_t) bid << " != " << (uint32_t) bearerId << ", the assumption that ID are allocated in the same way by MME and RRC is not valid any more");
drbInfo->m_epsBearerIdentity = bid;
drbInfo->m_drbIdentity = drbid;
@@ -345,12 +350,12 @@
if (m_state == HANDOVER_JOINING)
{
- // setup TEIDs for receiving data eventually forwarded over X2-U
+ // setup TEIDs for receiving data eventually forwarded over X2-U
LteEnbRrc::X2uTeidInfo x2uTeidInfo;
x2uTeidInfo.rnti = m_rnti;
x2uTeidInfo.drbid = drbid;
std::pair<std::map<uint32_t, LteEnbRrc::X2uTeidInfo>::iterator, bool>
- ret = m_rrc->m_x2uTeidInfoMap.insert (std::pair<uint32_t, LteEnbRrc::X2uTeidInfo> (gtpTeid, x2uTeidInfo));
+ ret = m_rrc->m_x2uTeidInfoMap.insert (std::pair<uint32_t, LteEnbRrc::X2uTeidInfo> (gtpTeid, x2uTeidInfo));
NS_ASSERT_MSG (ret.second == true, "overwriting a pre-existing entry in m_x2uTeidInfoMap");
}
@@ -361,6 +366,7 @@
Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
rlc->SetLteMacSapProvider (m_rrc->m_macSapProvider);
rlc->SetRnti (m_rnti);
+ rlc->SetMrnti(0);
drbInfo->m_rlc = rlc;
@@ -372,13 +378,14 @@
{
Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
pdcp->SetRnti (m_rnti);
+ pdcp->SetMrnti(0);
pdcp->SetLcId (lcid);
pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
drbInfo->m_pdcp = pdcp;
}
-
+
LteEnbCmacSapProvider::LcInfo lcinfo;
lcinfo.rnti = m_rnti;
lcinfo.lcId = lcid;
@@ -390,7 +397,7 @@
lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
-
+
if (rlcTypeId == LteRlcAm::GetTypeId ())
{
drbInfo->m_rlcConfig.choice = LteRrcSap::RlcConfig::AM;
@@ -405,7 +412,7 @@
drbInfo->m_logicalChannelConfig.logicalChannelGroup = m_rrc->GetLogicalChannelGroup (bearer);
if (bearer.IsGbr ())
{
- drbInfo->m_logicalChannelConfig.prioritizedBitRateKbps = bearer.gbrQosInfo.gbrUl;
+ drbInfo->m_logicalChannelConfig.prioritizedBitRateKbps = bearer.gbrQosInfo.gbrUl;
}
else
{
@@ -425,7 +432,7 @@
++it)
{
m_drbsToBeStarted.push_back (it->first);
- }
+ }
}
void
@@ -465,16 +472,16 @@
LteRrcSap::RadioResourceConfigDedicated rrcd;
rrcd.havePhysicalConfigDedicated = false;
rrcd.drbToReleaseList.push_back (drbid);
-
+
LteRrcSap::RrcConnectionReconfiguration msg;
msg.haveMeasConfig = false;
msg.haveMobilityControlInfo = false;
-
+
m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration (m_rnti, msg);
}
-void
+void
UeManager::ScheduleRrcConnectionReconfiguration ()
{
NS_LOG_FUNCTION (this);
@@ -490,8 +497,8 @@
// a previous reconfiguration still ongoing, we need to wait for it to be finished
m_pendingRrcConnectionReconfiguration = true;
break;
-
- case CONNECTED_NORMALLY:
+
+ case CONNECTED_NORMALLY:
{
m_pendingRrcConnectionReconfiguration = false;
LteRrcSap::RrcConnectionReconfiguration msg = BuildRrcConnectionReconfiguration ();
@@ -499,21 +506,21 @@
RecordDataRadioBearersToBeStarted ();
SwitchToState (CONNECTION_RECONFIGURATION);
}
- break;
-
+ break;
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
-void
+void
UeManager::PrepareHandover (uint16_t cellId)
-{
- NS_LOG_FUNCTION (this << cellId);
+{
+ NS_LOG_FUNCTION (this << cellId);
switch (m_state)
{
- case CONNECTED_NORMALLY:
+ case CONNECTED_NORMALLY:
{
m_targetCellId = cellId;
EpcX2SapProvider::HandoverRequestParams params;
@@ -525,7 +532,7 @@
params.ueAggregateMaxBitRateDownlink = 200 * 1000;
params.ueAggregateMaxBitRateUplink = 100 * 1000;
params.bearers = GetErabList ();
-
+
LteRrcSap::HandoverPreparationInfo hpi;
hpi.asConfig.sourceUeIdentity = m_rnti;
hpi.asConfig.sourceDlCarrierFreq = m_rrc->m_dlEarfcn;
@@ -544,30 +551,30 @@
hpi.asConfig.sourceSystemInformationBlockType2.freqInfo.ulCarrierFreq = m_rrc->m_ulEarfcn;
hpi.asConfig.sourceSystemInformationBlockType2.freqInfo.ulBandwidth = m_rrc->m_ulBandwidth;
params.rrcContext = m_rrc->m_rrcSapUser->EncodeHandoverPreparationInformation (hpi);
-
+
NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
NS_LOG_LOGIC ("mmmUeS1apId = " << params.oldEnbUeX2apId);
NS_LOG_LOGIC ("rrcContext = " << params.rrcContext);
-
+
m_rrc->m_x2SapProvider->SendHandoverRequest (params);
SwitchToState (HANDOVER_PREPARATION);
}
- break;
-
+ break;
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
-void
+void
UeManager::RecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params)
{
NS_LOG_FUNCTION (this);
-
+
NS_ASSERT_MSG (params.notAdmittedBearers.empty (), "not admission of some bearers upon handover is not supported");
NS_ASSERT_MSG (params.admittedBearers.size () == m_drbMap.size (), "not enough bearers in admittedBearers");
@@ -575,16 +582,16 @@
// is expected to be sent transparently to the UE; however, here we
// decode the message and eventually reencode it. This way we can
// support both a real RRC protocol implementation and an ideal one
- // without actual RRC protocol encoding.
+ // without actual RRC protocol encoding.
Ptr<Packet> encodedHandoverCommand = params.rrcContext;
LteRrcSap::RrcConnectionReconfiguration handoverCommand = m_rrc->m_rrcSapUser->DecodeHandoverCommand (encodedHandoverCommand);
m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration (m_rnti, handoverCommand);
SwitchToState (HANDOVER_LEAVING);
- m_handoverLeavingTimeout = Simulator::Schedule (m_rrc->m_handoverLeavingTimeoutDuration,
- &LteEnbRrc::HandoverLeavingTimeout,
- m_rrc, m_rnti);
- NS_ASSERT (handoverCommand.haveMobilityControlInfo);
+ m_handoverLeavingTimeout = Simulator::Schedule (m_rrc->m_handoverLeavingTimeoutDuration,
+ &LteEnbRrc::HandoverLeavingTimeout,
+ m_rrc, m_rnti);
+ NS_ASSERT (handoverCommand.haveMobilityControlInfo);
m_rrc->m_handoverStartTrace (m_imsi, m_rrc->m_cellId, m_rnti, handoverCommand.mobilityControlInfo.targetPhysCellId);
EpcX2SapProvider::SnStatusTransferParams sst;
@@ -600,7 +607,7 @@
if (0 != drbIt->second->m_rlc->GetObject<LteRlcAm> ())
{
LtePdcp::Status status = drbIt->second->m_pdcp->GetStatus ();
- EpcX2Sap::ErabsSubjectToStatusTransferItem i;
+ EpcX2Sap::ErabsSubjectToStatusTransferItem i;
i.dlPdcpSn = status.txSn;
i.ulPdcpSn = status.rxSn;
sst.erabsSubjectToStatusTransferList.push_back (i);
@@ -617,7 +624,7 @@
return BuildRadioResourceConfigDedicated ();
}
-LteRrcSap::RrcConnectionReconfiguration
+LteRrcSap::RrcConnectionReconfiguration
UeManager::GetRrcConnectionReconfigurationForHandover ()
{
NS_LOG_FUNCTION (this);
@@ -628,15 +635,15 @@
UeManager::SendData (uint8_t bid, Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p << (uint16_t) bid);
- switch (m_state)
+ switch (m_state)
{
case INITIAL_RANDOM_ACCESS:
case CONNECTION_SETUP:
NS_LOG_WARN ("not connected, discarding packet");
return;
- break;
-
- case CONNECTED_NORMALLY:
+ break;
+
+ case CONNECTED_NORMALLY:
case CONNECTION_RECONFIGURATION:
case CONNECTION_REESTABLISHMENT:
case HANDOVER_PREPARATION:
@@ -653,27 +660,27 @@
pdcpSapProvider->TransmitPdcpSdu (params);
}
break;
-
+
case HANDOVER_LEAVING:
{
NS_LOG_LOGIC ("forwarding data to target eNB over X2-U");
- uint8_t drbid = Bid2Drbid (bid);
+ uint8_t drbid = Bid2Drbid (bid);
EpcX2Sap::UeDataParams params;
params.sourceCellId = m_rrc->m_cellId;
params.targetCellId = m_targetCellId;
params.gtpTeid = GetDataRadioBearerInfo (drbid)->m_gtpTeid;
params.ueData = p;
m_rrc->m_x2SapProvider->SendUeData (params);
- }
+ }
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
-std::vector<EpcX2Sap::ErabToBeSetupItem>
+std::vector<EpcX2Sap::ErabToBeSetupItem>
UeManager::GetErabList ()
{
NS_LOG_FUNCTION (this);
@@ -688,7 +695,7 @@
etbsi.dlForwarding = false;
etbsi.transportLayerAddress = it->second->m_transportLayerAddress;
etbsi.gtpTeid = it->second->m_gtpTeid;
- ret.push_back (etbsi);
+ ret.push_back (etbsi);
}
return ret;
}
@@ -698,7 +705,7 @@
{
NS_LOG_FUNCTION (this);
switch (m_state)
- {
+ {
case HANDOVER_PATH_SWITCH:
NS_LOG_INFO ("Send UE CONTEXT RELEASE from target eNB to source eNB");
EpcX2SapProvider::UeContextReleaseParams ueCtxReleaseParams;
@@ -709,36 +716,36 @@
SwitchToState (CONNECTED_NORMALLY);
m_rrc->m_handoverEndOkTrace (m_imsi, m_rrc->m_cellId, m_rnti);
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
-void
+void
UeManager::RecvHandoverPreparationFailure (uint16_t cellId)
{
NS_LOG_FUNCTION (this << cellId);
switch (m_state)
- {
- case HANDOVER_PREPARATION:
+ {
+ case HANDOVER_PREPARATION:
NS_ASSERT (cellId == m_targetCellId);
NS_LOG_INFO ("target eNB sent HO preparation failure, aborting HO");
SwitchToState (CONNECTED_NORMALLY);
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
-void
+void
UeManager::RecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params)
{
NS_LOG_FUNCTION (this);
- for (std::vector<EpcX2Sap::ErabsSubjectToStatusTransferItem>::iterator erabIt
+ for (std::vector<EpcX2Sap::ErabsSubjectToStatusTransferItem>::iterator erabIt
= params.erabsSubjectToStatusTransferList.begin ();
erabIt != params.erabsSubjectToStatusTransferList.end ();
++erabIt)
@@ -753,18 +760,18 @@
}
}
-void
+void
UeManager::RecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params)
{
NS_LOG_FUNCTION (this);
NS_ASSERT_MSG (m_state == HANDOVER_LEAVING, "method unexpected in state " << ToString (m_state));
- m_handoverLeavingTimeout.Cancel ();
+ m_handoverLeavingTimeout.Cancel ();
}
// methods forwarded from RRC SAP
-void
+void
UeManager::CompleteSetupUe (LteEnbRrcSapProvider::CompleteSetupUeParameters params)
{
NS_LOG_FUNCTION (this);
@@ -778,16 +785,16 @@
NS_LOG_FUNCTION (this);
switch (m_state)
{
- case INITIAL_RANDOM_ACCESS:
- {
+ case INITIAL_RANDOM_ACCESS:
+ {
if (m_rrc->m_admitRrcConnectionRequest == true)
{
m_connectionTimeout.Cancel ();
- m_imsi = msg.ueIdentity;
+ m_imsi = msg.ueIdentity;
if (m_rrc->m_s1SapProvider != 0)
{
m_rrc->m_s1SapProvider->InitialUeMessage (m_imsi, m_rnti);
- }
+ }
LteRrcSap::RrcConnectionSetup msg2;
msg2.rrcTransactionIdentifier = GetNewRrcTransactionIdentifier ();
msg2.radioResourceConfigDedicated = BuildRadioResourceConfigDedicated ();
@@ -802,17 +809,17 @@
LteRrcSap::RrcConnectionReject rejectMsg;
rejectMsg.waitTime = 3;
m_rrc->m_rrcSapUser->SendRrcConnectionReject (m_rnti, rejectMsg);
- m_connectionRejectedTimeout = Simulator::Schedule (m_rrc->m_connectionRejectedTimeoutDuration,
- &LteEnbRrc::ConnectionRejectedTimeout,
- m_rrc, m_rnti);
+ m_connectionRejectedTimeout = Simulator::Schedule (m_rrc->m_connectionRejectedTimeoutDuration,
+ &LteEnbRrc::ConnectionRejectedTimeout,
+ m_rrc, m_rnti);
SwitchToState (CONNECTION_REJECTED);
- }
+ }
}
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
@@ -827,10 +834,10 @@
SwitchToState (CONNECTED_NORMALLY);
m_rrc->m_connectionEstablishedTrace (m_imsi, m_rrc->m_cellId, m_rnti);
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
@@ -841,28 +848,28 @@
switch (m_state)
{
case CONNECTION_RECONFIGURATION:
- StartDataRadioBearers ();
+ StartDataRadioBearers ();
if (m_needTransmissionModeConfiguration)
- {
+ {
// configure MAC (and scheduler)
LteEnbCmacSapProvider::UeConfig req;
req.m_rnti = m_rnti;
req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
- m_rrc->m_cmacSapProvider->UeUpdateConfigurationReq (req);
-
+ m_rrc->m_cmacSapProvider->UeUpdateConfigurationReq (req);
+
// configure PHY
m_rrc->m_cphySapProvider->SetTransmissionMode (req.m_rnti, req.m_transmissionMode);
-
+
m_needTransmissionModeConfiguration = false;
}
SwitchToState (CONNECTED_NORMALLY);
m_rrc->m_connectionReconfigurationTrace (m_imsi, m_rrc->m_cellId, m_rnti);
break;
- case HANDOVER_LEAVING:
+ case HANDOVER_LEAVING:
NS_LOG_INFO ("ignoring RecvRrcConnectionReconfigurationCompleted in state " << ToString (m_state));
break;
-
+
case HANDOVER_JOINING:
{
m_handoverJoiningTimeout.Cancel ();
@@ -880,18 +887,18 @@
b.epsBearerId = it->second->m_epsBearerIdentity;
b.teid = it->second->m_gtpTeid;
params.bearersToBeSwitched.push_back (b);
- }
+ }
m_rrc->m_s1SapProvider->PathSwitchRequest (params);
}
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
}
-
-void
+
+void
UeManager::RecvRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg)
{
NS_LOG_FUNCTION (this);
@@ -900,13 +907,13 @@
case CONNECTED_NORMALLY:
break;
- case HANDOVER_LEAVING:
- m_handoverLeavingTimeout.Cancel ();
- break;
-
+ case HANDOVER_LEAVING:
+ m_handoverLeavingTimeout.Cancel ();
+ break;
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
- break;
+ break;
}
LteRrcSap::RrcConnectionReestablishment msg2;
@@ -916,31 +923,31 @@
SwitchToState (CONNECTION_REESTABLISHMENT);
}
-void
+void
UeManager::RecvRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg)
{
NS_LOG_FUNCTION (this);
SwitchToState (CONNECTED_NORMALLY);
}
-void
+void
UeManager::RecvMeasurementReport (LteRrcSap::MeasurementReport msg)
{
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC ("measId " << (uint16_t) msg.measResults.measId
- << " haveMeasResultNeighCells " << msg.measResults.haveMeasResultNeighCells
- << " measResultListEutra " << msg.measResults.measResultListEutra.size ());
+ << " haveMeasResultNeighCells " << msg.measResults.haveMeasResultNeighCells
+ << " measResultListEutra " << msg.measResults.measResultListEutra.size ());
NS_LOG_LOGIC ("serving cellId " << m_rrc->m_cellId
- << " RSRP " << (uint16_t) msg.measResults.rsrpResult
- << " RSRQ " << (uint16_t) msg.measResults.rsrqResult);
+ << " RSRP " << (uint16_t) msg.measResults.rsrpResult
+ << " RSRQ " << (uint16_t) msg.measResults.rsrqResult);
for (std::list <LteRrcSap::MeasResultEutra>::iterator it = msg.measResults.measResultListEutra.begin ();
it != msg.measResults.measResultListEutra.end ();
++it)
{
NS_LOG_LOGIC ("neighbour cellId " << it->physCellId
- << " RSRP " << (it->haveRsrpResult ? (uint16_t) it->rsrpResult : 255)
- << " RSRQ " << (it->haveRsrqResult ? (uint16_t) it->rsrqResult : 255));
+ << " RSRP " << (it->haveRsrpResult ? (uint16_t) it->rsrpResult : 255)
+ << " RSRQ " << (it->haveRsrqResult ? (uint16_t) it->rsrqResult : 255));
}
m_rrc->m_recvMeasurementReportTrace (m_imsi, m_rrc->m_cellId, m_rnti, msg);
@@ -971,8 +978,8 @@
if (it->second->m_rsrq > bestNeighbourRsrq)
{
Ptr<NeighbourRelation> neighbourRelation = m_rrc->m_neighbourRelationTable[it->second->m_cellId];
- if ((neighbourRelation->m_noHo == false) &&
- (neighbourRelation->m_noX2 == false))
+ if ((neighbourRelation->m_noHo == false)
+ && (neighbourRelation->m_noX2 == false))
{
bestNeighbour = it->second;
bestNeighbourRsrq = it->second->m_rsrq;
@@ -985,8 +992,8 @@
{
uint16_t targetCellId = bestNeighbour->m_cellId;
NS_LOG_LOGIC ("Best neighbour cellId " << targetCellId);
- if ( (bestNeighbour->m_rsrq - m_servingCellMeasures->m_rsrq >= m_rrc->m_neighbourCellHandoverOffset) &&
- (m_state == CONNECTED_NORMALLY) )
+ if ( (bestNeighbour->m_rsrq - m_servingCellMeasures->m_rsrq >= m_rrc->m_neighbourCellHandoverOffset)
+ && (m_state == CONNECTED_NORMALLY) )
{
NS_LOG_LOGIC ("Trigger Handover to cellId " << targetCellId);
NS_LOG_LOGIC ("target cell RSRQ " << (uint16_t) bestNeighbour->m_rsrq);
@@ -1000,7 +1007,7 @@
else if (msg.measResults.measId == 2)
{
// Update the NRT
- if (msg.measResults.haveMeasResultNeighCells && ! (msg.measResults.measResultListEutra.empty ()))
+ if (msg.measResults.haveMeasResultNeighCells && !(msg.measResults.measResultListEutra.empty ()))
{
for (std::list <LteRrcSap::MeasResultEutra>::iterator it = msg.measResults.measResultListEutra.begin ();
it != msg.measResults.measResultListEutra.end ();
@@ -1055,9 +1062,9 @@
}
else
{
- NS_LOG_LOGIC ("WARNING");
+ NS_LOG_LOGIC ("WARNING");
// NS_ASSERT_MSG ("Event A4 received without measure results for neighbour cells");
- // TODO Remove neighbours in the neighbourCellMeasures table
+ // TODO Remove neighbours in the neighbourCellMeasures table
}
}
}
@@ -1070,7 +1077,7 @@
{
NS_LOG_FUNCTION (this << m_rnti);
// at this stage used only by the scheduler for updating txMode
-
+
m_physicalConfigDedicated.antennaInfo.transmissionMode = cmacParams.m_transmissionMode;
m_needTransmissionModeConfiguration = true;
@@ -1128,7 +1135,7 @@
// do nothing, srs conf index will be correctly enforced upon
// RRC connection establishment
break;
-
+
default:
ScheduleRrcConnectionReconfiguration ();
break;
@@ -1145,9 +1152,9 @@
UeManager::AddDataRadioBearerInfo (Ptr<LteDataRadioBearerInfo> drbInfo)
{
NS_LOG_FUNCTION (this);
- const uint8_t MAX_DRB_ID = 32;
- for (uint8_t drbid = (m_lastAllocatedDrbid + 1) % MAX_DRB_ID;
- drbid != m_lastAllocatedDrbid;
+ const uint8_t MAX_DRB_ID = 32;
+ for (uint8_t drbid = (m_lastAllocatedDrbid + 1) % MAX_DRB_ID;
+ drbid != m_lastAllocatedDrbid;
drbid = (drbid + 1) % MAX_DRB_ID)
{
if (drbid != 0) // 0 is not allowed
@@ -1170,7 +1177,7 @@
{
NS_LOG_FUNCTION (this << (uint32_t) drbid);
NS_ASSERT (0 != drbid);
- std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
+ std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
NS_ABORT_IF (it == m_drbMap.end ());
return it->second;
}
@@ -1224,7 +1231,7 @@
reportConfigA2.reportConfigEutra.hysteresis = 0;
reportConfigA2.reportConfigEutra.timeToTrigger = 0;
reportConfigA2.reportConfigEutra.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRQ;
- reportConfigA2.reportConfigEutra.reportQuantity = LteRrcSap::ReportConfigEutra::SAME_AS_TRIGGER_QUANTITY;
+ reportConfigA2.reportConfigEutra.reportQuantity = LteRrcSap::ReportConfigEutra::SAME_AS_TRIGGER_QUANTITY;
reportConfigA2.reportConfigEutra.maxReportCells = LteRrcSap::MaxReportCells;
reportConfigA2.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS480;
reportConfigA2.reportConfigEutra.reportAmount = 255;
@@ -1238,7 +1245,7 @@
reportConfigA4.reportConfigEutra.hysteresis = 0;
reportConfigA4.reportConfigEutra.timeToTrigger = 0;
reportConfigA4.reportConfigEutra.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRQ;
- reportConfigA4.reportConfigEutra.reportQuantity = LteRrcSap::ReportConfigEutra::SAME_AS_TRIGGER_QUANTITY;
+ reportConfigA4.reportConfigEutra.reportQuantity = LteRrcSap::ReportConfigEutra::SAME_AS_TRIGGER_QUANTITY;
reportConfigA4.reportConfigEutra.maxReportCells = LteRrcSap::MaxReportCells;
reportConfigA4.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS480;
reportConfigA4.reportConfigEutra.reportAmount = 255;
@@ -1279,7 +1286,7 @@
stam.logicalChannelConfig = m_srb1->m_logicalChannelConfig;
rrcd.srbToAddModList.push_back (stam);
}
-
+
for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
it != m_drbMap.end ();
++it)
@@ -1298,51 +1305,51 @@
return rrcd;
}
-uint8_t
+uint8_t
UeManager::GetNewRrcTransactionIdentifier ()
{
return ++m_lastRrcTransactionIdentifier;
}
-uint8_t
+uint8_t
UeManager::Lcid2Drbid (uint8_t lcid)
{
NS_ASSERT (lcid > 2);
return lcid - 2;
}
-uint8_t
+uint8_t
UeManager::Drbid2Lcid (uint8_t drbid)
{
return drbid + 2;
}
-uint8_t
+uint8_t
UeManager::Lcid2Bid (uint8_t lcid)
{
NS_ASSERT (lcid > 2);
return lcid - 2;
}
-uint8_t
+uint8_t
UeManager::Bid2Lcid (uint8_t bid)
{
return bid + 2;
}
-uint8_t
+uint8_t
UeManager::Drbid2Bid (uint8_t drbid)
{
return drbid;
}
-uint8_t
+uint8_t
UeManager::Bid2Drbid (uint8_t bid)
{
return bid;
}
-void
+void
UeManager::SwitchToState (State newState)
{
NS_LOG_FUNCTION (this << newState);
@@ -1350,18 +1357,18 @@
m_state = newState;
NS_LOG_INFO ("IMSI " << m_imsi << " RNTI " << m_rnti << " UeManager " << ToString (oldState) << " --> " << ToString (newState));
m_stateTransitionTrace (m_imsi, m_rrc->m_cellId, m_rnti, oldState, newState);
-
+
switch (newState)
{
case INITIAL_RANDOM_ACCESS:
case HANDOVER_JOINING:
- NS_FATAL_ERROR ("cannot switch to an initial state");
+ NS_FATAL_ERROR ("cannot switch to an initial state");
break;
case CONNECTION_SETUP:
break;
- case CONNECTED_NORMALLY:
+ case CONNECTED_NORMALLY:
{
if (m_pendingRrcConnectionReconfiguration == true)
{
@@ -1375,9 +1382,9 @@
case CONNECTION_REESTABLISHMENT:
break;
-
+
case HANDOVER_LEAVING:
- break;
+ break;
default:
break;
@@ -1385,7 +1392,371 @@
}
-
+// ///////////////////////////
+// MBMS Manager
+// //////////////////////////
+
+NS_OBJECT_ENSURE_REGISTERED (MbmsManager);
+
+
+MbmsManager::MbmsManager ()
+{
+ NS_FATAL_ERROR ("this constructor is not espected to be used");
+}
+
+
+MbmsManager::MbmsManager (Ptr<LteEnbRrc> rrc, uint16_t mrnti)
+ : m_lastAllocatedDrbid (0),
+ m_mrnti (mrnti),
+ m_lastRrcTransactionIdentifier (0),
+ m_rrc (rrc),
+ m_needTransmissionModeConfiguration (false)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+MbmsManager::DoInitialize ()
+{
+ NS_LOG_FUNCTION (this);
+ m_drbPdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<MbmsManager> (this);
+
+ m_physicalConfigDedicated.haveAntennaInfoDedicated = true;
+ m_physicalConfigDedicated.antennaInfo.transmissionMode = m_rrc->m_defaultTransmissionMode;
+ m_physicalConfigDedicated.haveSoundingRsUlConfigDedicated = true;
+ m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex = m_rrc->GetNewSrsConfigurationIndex ();
+ m_physicalConfigDedicated.soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::SETUP;
+ m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth = 0;
+
+
+ m_rrc->m_cmacSapProvider->AddMbms (m_mrnti);
+ m_rrc->m_cphySapProvider->AddMbms (m_mrnti);
+
+ // setup the eNB side of SRB0
+ {
+ uint8_t lcid = 0;
+
+ Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
+ rlc->SetLteMacSapProvider (m_rrc->m_macSapProvider);
+ rlc->SetMrnti (m_mrnti);
+ rlc->SetLcId (lcid);
+
+ m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
+ m_srb0->m_rlc = rlc;
+ m_srb0->m_srbIdentity = 0;
+ // no need to store logicalChannelConfig as SRB0 is pre-configured
+
+ LteEnbCmacSapProvider::LcInfo lcinfo;
+ lcinfo.rnti = m_mrnti;
+ lcinfo.lcId = lcid;
+ // leave the rest of lcinfo empty as CCCH (LCID 0) is pre-configured
+ m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
+
+ }
+
+ // setup the eNB side of SRB1; the UE side will be set up upon RRC connection establishment
+ {
+ uint8_t lcid = 1;
+
+ Ptr<LteRlc> rlc = CreateObject<LteRlcUm> ()->GetObject<LteRlc> ();
+ rlc->SetLteMacSapProvider (m_rrc->m_macSapProvider);
+ rlc->SetMrnti (m_mrnti);
+ rlc->SetLcId (lcid);
+
+ Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
+ pdcp->SetMrnti (m_mrnti);
+ pdcp->SetLcId (lcid);
+ pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
+ pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
+ rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
+
+ m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
+ m_srb1->m_rlc = rlc;
+ m_srb1->m_pdcp = pdcp;
+ m_srb1->m_srbIdentity = 1;
+ m_srb1->m_logicalChannelConfig.priority = 0;
+ m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = 100;
+ m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = 100;
+ m_srb1->m_logicalChannelConfig.logicalChannelGroup = 0;
+
+ LteEnbCmacSapProvider::LcInfo lcinfo;
+ lcinfo.rnti = m_mrnti;
+ lcinfo.lcId = lcid;
+ lcinfo.lcGroup = 0; // all SRBs always mapped to LCG 0
+ lcinfo.qci = EpsBearer::GBR_CONV_VOICE; // not sure why the FF API requires a CQI even for SRBs...
+ lcinfo.isGbr = true;
+ lcinfo.mbrUl = 1e6;
+ lcinfo.mbrDl = 1e6;
+ lcinfo.gbrUl = 1e4;
+ lcinfo.gbrDl = 1e4;
+ m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
+ }
+
+// LteEnbRrcSapUser::SetupUeParameters ueParams;
+// ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
+// ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
+// m_rrc->m_rrcSapUser->SetupUe (m_mrnti, ueParams);
+
+ // configure MAC (and scheduler)
+ LteEnbCmacSapProvider::UeConfig req;
+ req.m_rnti = m_mrnti;
+ req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
+ m_rrc->m_cmacSapProvider->UeUpdateConfigurationReq (req);
+
+ // configure PHY
+// m_rrc->m_cphySapProvider->SetTransmissionMode (m_mrnti, m_physicalConfigDedicated.antennaInfo.transmissionMode);
+// m_rrc->m_cphySapProvider->SetSrsConfigurationIndex (m_mrnti, m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex);
+
+ // schedule this MbmsManager instance to be deleted if the UE does not give any sign of life within a reasonable time
+ Time maxConnectionDelay;
+/*
+ m_servingCellMeasures = CreateObject<UeMeasure> ();
+ m_servingCellMeasures->m_cellId = m_rrc->m_cellId;
+ m_servingCellMeasures->m_rsrp = 0;
+ m_servingCellMeasures->m_rsrq = 0;
+*/
+}
+
+
+MbmsManager::~MbmsManager (void)
+{
+}
+
+void
+MbmsManager::DoDispose ()
+{
+ delete m_drbPdcpSapUser;
+ // delete eventual X2-U TEIDs
+ for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
+ it != m_drbMap.end ();
+ ++it)
+ {
+ m_rrc->m_x2uTeidInfoMap.erase (it->second->m_gtpTeid);
+ }
+
+ m_servingCellMeasures = 0;
+}
+
+TypeId MbmsManager::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::MbmsManager")
+ .SetParent<Object> ()
+ .AddConstructor<MbmsManager> ()
+ .AddAttribute ("DataRadioBearerMap", "List of UE DataRadioBearerInfo by DRBID.",
+ ObjectMapValue (),
+ MakeObjectMapAccessor (&MbmsManager::m_drbMap),
+ MakeObjectMapChecker<LteDataRadioBearerInfo> ())
+ .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
+ PointerValue (),
+ MakePointerAccessor (&MbmsManager::m_srb0),
+ MakePointerChecker<LteSignalingRadioBearerInfo> ())
+ .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
+ PointerValue (),
+ MakePointerAccessor (&MbmsManager::m_srb1),
+ MakePointerChecker<LteSignalingRadioBearerInfo> ())
+ .AddAttribute ("M-RNTI",
+ "Multicast Radio Network Temporary Identifier",
+ TypeId::ATTR_GET, // read-only attribute
+ UintegerValue (0), // unused, read-only attribute
+ MakeUintegerAccessor (&MbmsManager::m_mrnti),
+ MakeUintegerChecker<uint16_t> ())
+ ;
+ return tid;
+}
+
+void
+MbmsManager::SetupDataRadioBearerMbms (EpsBearer bearer, uint8_t bearerId, Ipv4Address transportLayerAddress)
+{
+ NS_LOG_FUNCTION (this << (uint32_t) m_mrnti);
+
+ Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
+ uint8_t drbid = AddDataRadioBearerInfo (drbInfo);
+ uint8_t lcid = Drbid2Lcid (drbid);
+ uint8_t bid = Drbid2Bid (drbid);
+ NS_ASSERT_MSG ( bearerId == 0 || bid == bearerId, "bearer ID mismatch (" << (uint32_t) bid << " != " << (uint32_t) bearerId << ", the assumption that ID are allocated in the same way by MME and RRC is not valid any more");
+ drbInfo->m_epsBearerIdentity = bid;
+ drbInfo->m_drbIdentity = drbid;
+ drbInfo->m_logicalChannelIdentity = lcid;
+ drbInfo->m_gtpTeid = 0;
+ drbInfo->m_transportLayerAddress = transportLayerAddress;
+
+
+
+ TypeId rlcTypeId = m_rrc->GetRlcType (bearer);
+
+ ObjectFactory rlcObjectFactory;
+ rlcObjectFactory.SetTypeId (rlcTypeId);
+ Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
+ rlc->SetLteMacSapProvider (m_rrc->m_macSapProvider);
+ rlc->SetMrnti (m_mrnti);
+
+ drbInfo->m_rlc = rlc;
+
+ rlc->SetLcId (lcid);
+
+ // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
+ // if we are using RLC/SM we don't care of anything above RLC
+ if (rlcTypeId != LteRlcSm::GetTypeId ())
+ {
+ Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
+ pdcp->SetMrnti (m_mrnti);
+ pdcp->SetLcId (lcid);
+ pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
+ pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
+ rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
+ drbInfo->m_pdcp = pdcp;
+ }
+
+ LteEnbCmacSapProvider::LcInfo lcinfo;
+ lcinfo.rnti = m_mrnti;
+ lcinfo.lcId = lcid;
+ lcinfo.lcGroup = m_rrc->GetLogicalChannelGroup (bearer);
+ lcinfo.qci = bearer.qci;
+ lcinfo.isGbr = bearer.IsGbr ();
+ lcinfo.mbrUl = bearer.gbrQosInfo.mbrUl;
+ lcinfo.mbrDl = bearer.gbrQosInfo.mbrDl;
+ lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
+ lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
+ m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
+
+ drbInfo->m_rlcConfig.choice = LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL;
+
+ drbInfo->m_logicalChannelIdentity = lcid;
+ drbInfo->m_logicalChannelConfig.priority = m_rrc->GetLogicalChannelPriority (bearer);
+ drbInfo->m_logicalChannelConfig.logicalChannelGroup = m_rrc->GetLogicalChannelGroup (bearer);
+ if (bearer.IsGbr ())
+ {
+ drbInfo->m_logicalChannelConfig.prioritizedBitRateKbps = bearer.gbrQosInfo.gbrUl;
+ }
+ else
+ {
+ drbInfo->m_logicalChannelConfig.prioritizedBitRateKbps = 0;
+ }
+ drbInfo->m_logicalChannelConfig.bucketSizeDurationMs = 1000;
+
+ //ScheduleRrcConnectionReconfiguration ();
+}
+
+LteRrcSap::PmchInfoList
+MbmsManager::BuildMbmsAreaConfiguration ()
+{
+ LteRrcSap::PmchInfoList pmchInfoList;
+
+
+ for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
+ it != m_drbMap.end ();
+ ++it)
+ {
+ pmchInfoList.mrnti = m_mrnti;
+ pmchInfoList.sessionId = it->second->m_epsBearerIdentity;
+ pmchInfoList.drbIdentity = it->second->m_drbIdentity;
+ pmchInfoList.rlcConfig = it->second->m_rlcConfig;
+ pmchInfoList.logicalChannelIdentity = it->second->m_logicalChannelIdentity;
+ pmchInfoList.logicalChannelConfig = it->second->m_logicalChannelConfig;
+
+ }
+ return pmchInfoList;
+}
+
+void
+MbmsManager::SendData (uint8_t bid, Ptr<Packet> p)
+{
+ NS_LOG_FUNCTION (this << p << (uint16_t) bid);
+ NS_LOG_LOGIC ("queueing data on PDCP for transmission over the air");
+ LtePdcpSapProvider::TransmitPdcpSduParameters params;
+ params.pdcpSdu = p;
+ params.rnti = m_mrnti;
+ params.lcid = Bid2Lcid (bid);
+ uint8_t drbid = Bid2Drbid (bid);
+ LtePdcpSapProvider* pdcpSapProvider = GetDataRadioBearerInfo (drbid)->m_pdcp->GetLtePdcpSapProvider ();
+ pdcpSapProvider->TransmitPdcpSdu (params);
+}
+
+// methods forwarded from RRC SAP
+// methods forwarded from CMAC SAP
+
+// methods forwarded from PDCP SAP
+void
+MbmsManager::DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params)
+{
+
+}
+
+uint16_t
+MbmsManager::GetMrnti (void)
+{
+ return m_mrnti;
+}
+
+uint8_t
+MbmsManager::AddDataRadioBearerInfo (Ptr<LteDataRadioBearerInfo> drbInfo)
+{
+ NS_LOG_FUNCTION (this);
+ const uint8_t MAX_DRB_ID = 32;
+ for (uint8_t drbid = (m_lastAllocatedDrbid + 5) % MAX_DRB_ID;
+ drbid != m_lastAllocatedDrbid;
+ drbid = (drbid + 1) % MAX_DRB_ID)
+ {
+ if (drbid != 0) // 0 is not allowed
+ {
+ if (m_drbMap.find (drbid) == m_drbMap.end ())
+ {
+ m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (drbid, drbInfo));
+ drbInfo->m_drbIdentity = drbid;
+ m_lastAllocatedDrbid = drbid;
+ return drbid;
+ }
+ }
+ }
+ NS_FATAL_ERROR ("no more data radio bearer ids available");
+ return 0;
+}
+
+Ptr<LteDataRadioBearerInfo>
+MbmsManager::GetDataRadioBearerInfo (uint8_t drbid)
+{
+ NS_LOG_FUNCTION (this << (uint32_t) drbid);
+ NS_ASSERT (0 != drbid);
+ std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
+ NS_ABORT_IF (it == m_drbMap.end ());
+ return it->second;
+}
+
+
+void
+MbmsManager::RemoveDataRadioBearerInfo (uint8_t drbid)
+{
+ NS_LOG_FUNCTION (this << (uint32_t) drbid);
+ std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
+ NS_ASSERT_MSG (it != m_drbMap.end (), "request to remove radio bearer with unknown drbid " << drbid);
+ m_drbMap.erase (it);
+}
+
+uint8_t
+MbmsManager::Drbid2Lcid (uint8_t drbid)
+{
+ return drbid + 2;
+}
+
+uint8_t
+MbmsManager::Bid2Lcid (uint8_t bid)
+{
+ return bid + 2;
+}
+
+uint8_t
+MbmsManager::Drbid2Bid (uint8_t drbid)
+{
+ return drbid;
+}
+
+uint8_t
+MbmsManager::Bid2Drbid (uint8_t bid)
+{
+ return bid;
+}
+
+
// ///////////////////////////
// eNB RRC methods
// ///////////////////////////
@@ -1412,7 +1783,7 @@
m_s1SapUser = new MemberEpcEnbS1SapUser<LteEnbRrc> (this);
m_cphySapUser = new MemberLteEnbCphySapUser<LteEnbRrc> (this);
-
+
}
@@ -1427,6 +1798,7 @@
{
NS_LOG_FUNCTION (this);
m_ueMap.clear ();
+ m_mbmsMap.clear ();
delete m_cmacSapUser;
delete m_rrcSapProvider;
delete m_x2SapUser;
@@ -1445,12 +1817,16 @@
ObjectMapValue (),
MakeObjectMapAccessor (&LteEnbRrc::m_ueMap),
MakeObjectMapChecker<UeManager> ())
+ .AddAttribute ("MbmsMap", "List of MbmsManager by M-RNTI.",
+ ObjectMapValue (),
+ MakeObjectMapAccessor (&LteEnbRrc::m_mbmsMap),
+ MakeObjectMapChecker<MbmsManager> ())
.AddAttribute ("DefaultTransmissionMode",
- "The default UEs' transmission mode (0: SISO)",
- UintegerValue (0), // default tx-mode
- MakeUintegerAccessor (&LteEnbRrc::m_defaultTransmissionMode),
- MakeUintegerChecker<uint8_t> ())
- .AddAttribute ("EpsBearerToRlcMapping",
+ "The default UEs' transmission mode (0: SISO)",
+ UintegerValue (0), // default tx-mode
+ MakeUintegerAccessor (&LteEnbRrc::m_defaultTransmissionMode),
+ MakeUintegerChecker<uint8_t> ())
+ .AddAttribute ("EpsBearerToRlcMapping",
"Specify which type of RLC will be used for each type of EPS bearer. ",
EnumValue (RLC_SM_ALWAYS),
MakeEnumAccessor (&LteEnbRrc::m_epsBearerToRlcMapping),
@@ -1460,43 +1836,48 @@
PER_BASED, "PacketErrorRateBased"))
.AddAttribute ("SystemInformationPeriodicity",
"The interval for sending system information (Time value)",
- TimeValue (MilliSeconds (80)),
+ TimeValue (MilliSeconds (80)),
MakeTimeAccessor (&LteEnbRrc::m_systemInformationPeriodicity),
MakeTimeChecker ())
+ .AddAttribute ("MbmsAreaConfigurationPeriodicity",
+ "The interval for sending MBMS Area Configuration (Time value)",
+ TimeValue (Seconds (0.1)),
+ MakeTimeAccessor (&LteEnbRrc::m_mbmsAreaConfigurationPeriodicity),
+ MakeTimeChecker ())
.AddAttribute ("SrsPeriodicity",
"The SRS periodicity in milliseconds",
- UintegerValue (40),
- MakeUintegerAccessor (&LteEnbRrc::SetSrsPeriodicity,
+ UintegerValue (40),
+ MakeUintegerAccessor (&LteEnbRrc::SetSrsPeriodicity,
&LteEnbRrc::GetSrsPeriodicity),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("ConnectionTimeoutDuration",
"After a RA attempt, if no RRC Connection Request is received before this time, the UE context is destroyed. Must account for reception of RAR and transmission of RRC CONNECTION REQUEST over UL GRANT.",
- TimeValue (MilliSeconds (15)),
+ TimeValue (MilliSeconds (15)),
MakeTimeAccessor (&LteEnbRrc::m_connectionTimeoutDuration),
MakeTimeChecker ())
.AddAttribute ("ConnectionRejectedTimeoutDuration",
"Time to wait between sending a RRC CONNECTION REJECT and destroying the UE context",
- TimeValue (MilliSeconds (30)),
+ TimeValue (MilliSeconds (30)),
MakeTimeAccessor (&LteEnbRrc::m_connectionRejectedTimeoutDuration),
MakeTimeChecker ())
.AddAttribute ("HandoverJoiningTimeoutDuration",
"After accepting a handover request, if no RRC Connection Reconfiguration Completed is received before this time, the UE context is destroyed. Must account for reception of X2 HO REQ ACK by source eNB, transmission of the Handover Command, non-contention-based random access and reception of the RRC Connection Reconfiguration Completed message.",
- TimeValue (MilliSeconds (200)),
+ TimeValue (MilliSeconds (200)),
MakeTimeAccessor (&LteEnbRrc::m_handoverJoiningTimeoutDuration),
MakeTimeChecker ())
.AddAttribute ("HandoverLeavingTimeoutDuration",
"After issuing a Handover Command, if neither RRC Connection Reestablishment nor X2 UE Context Release has been previously received, the UE context is destroyed.",
- TimeValue (MilliSeconds (500)),
+ TimeValue (MilliSeconds (500)),
MakeTimeAccessor (&LteEnbRrc::m_handoverLeavingTimeoutDuration),
MakeTimeChecker ())
- .AddAttribute ("AdmitHandoverRequest",
+ .AddAttribute ("AdmitHandoverRequest",
"Whether to admit an X2 handover request from another eNB",
- BooleanValue (true),
+ BooleanValue (true),
MakeBooleanAccessor (&LteEnbRrc::m_admitHandoverRequest),
- MakeBooleanChecker ())
- .AddAttribute ("AdmitRrcConnectionRequest",
+ MakeBooleanChecker ())
+ .AddAttribute ("AdmitRrcConnectionRequest",
"Whether to admit a connection request from a Ue",
- BooleanValue (true),
+ BooleanValue (true),
MakeBooleanAccessor (&LteEnbRrc::m_admitRrcConnectionRequest),
MakeBooleanChecker ())
.AddAttribute ("EventA2Threshold",
@@ -1590,14 +1971,14 @@
m_macSapProvider = s;
}
-void
+void
LteEnbRrc::SetS1SapProvider (EpcEnbS1SapProvider * s)
{
m_s1SapProvider = s;
}
-
-EpcEnbS1SapUser*
+
+EpcEnbS1SapUser*
LteEnbRrc::GetS1SapUser ()
{
return m_s1SapUser;
@@ -1622,11 +2003,31 @@
{
NS_LOG_FUNCTION (this << (uint32_t) rnti);
NS_ASSERT (0 != rnti);
- std::map<uint16_t, Ptr<UeManager> >::iterator it = m_ueMap.find (rnti);
+ std::map<uint16_t, Ptr<UeManager> >::iterator it = m_ueMap.find (rnti);
NS_ASSERT_MSG (it != m_ueMap.end (), "RNTI " << rnti << " not found in eNB with cellId " << m_cellId);
return it->second;
}
+Ptr<MbmsManager>
+LteEnbRrc::GetMbmsManager (uint16_t mrnti)
+{
+ NS_LOG_FUNCTION (this << (uint32_t) mrnti);
+ NS_ASSERT (0 != mrnti);
+ std::map<uint16_t, Ptr<MbmsManager> >::iterator it = m_mbmsMap.find (mrnti);
+ NS_ASSERT_MSG (it != m_mbmsMap.end (), "MRNTI " << mrnti << " not found in eNB with cellId " << m_cellId);
+ return it->second;
+}
+
+void
+LteEnbRrc::SetupDataRadioBearerMbms (uint16_t mrnti, EpsBearer bearer, uint8_t bearerId, Ipv4Address mbmsAddress)
+{
+ NS_LOG_FUNCTION (this << (uint32_t) mrnti);
+ NS_ASSERT (0 != mrnti);
+ Ptr<MbmsManager> mbmsManager = GetMbmsManager (mrnti);
+ mbmsManager->SetupDataRadioBearerMbms (bearer, bearerId, mbmsAddress);
+
+}
+
void
LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth, uint16_t ulEarfcn, uint16_t dlEarfcn, uint16_t cellId)
{
@@ -1648,6 +2049,9 @@
// the first time System Information is sent
Simulator::Schedule (MilliSeconds (16), &LteEnbRrc::SendSystemInformation, this);
+
+ //Send MBMS Area Configuration
+ Simulator::Schedule (Seconds (0.1), &LteEnbRrc::SendMbmsAreaConfiguration, this);
}
@@ -1664,14 +2068,29 @@
EpsBearerTag tag;
bool found = packet->RemovePacketTag (tag);
- NS_ASSERT_MSG (found, "no EpsBearerTag found in packet to be sent");
- Ptr<UeManager> ueManager = GetUeManager (tag.GetRnti ());
- ueManager->SendData (tag.GetBid (), packet);
-
+ if (found)
+ {
+ NS_ASSERT_MSG (found, "no EpsBearerTag found in packet to be sent");
+ Ptr<UeManager> ueManager = GetUeManager (tag.GetRnti ());
+ ueManager->SendData (tag.GetBid (), packet);
+ }
+ else
+ {
+ EpsBearerMbmsTag tagMbms;
+ bool foundMbms = packet->RemovePacketTag (tagMbms);
+ NS_ASSERT_MSG (foundMbms, "no Bearer Tag found in packet to be sent");
+ Ptr<MbmsManager> mbmsManager = GetMbmsManager (tagMbms.GetMrnti ());
+ mbmsManager->SendData (tagMbms.GetBid (), packet);
+ }
+
+
+
+
+
return true;
}
-void
+void
LteEnbRrc::SetForwardUpCallback (Callback <void, Ptr<Packet> > cb)
{
m_forwardUpCallback = cb;
@@ -1681,7 +2100,7 @@
LteEnbRrc::ConnectionTimeout (uint16_t rnti)
{
NS_LOG_FUNCTION (this << rnti);
- NS_ASSERT_MSG (GetUeManager (rnti)->GetState () == UeManager::INITIAL_RANDOM_ACCESS,
+ NS_ASSERT_MSG (GetUeManager (rnti)->GetState () == UeManager::INITIAL_RANDOM_ACCESS,
"ConnectionTimeout in unexpected state " << ToString (GetUeManager (rnti)->GetState ()));
RemoveUe (rnti);
}
@@ -1699,7 +2118,7 @@
LteEnbRrc::HandoverJoiningTimeout (uint16_t rnti)
{
NS_LOG_FUNCTION (this << rnti);
- NS_ASSERT_MSG (GetUeManager (rnti)->GetState () == UeManager::HANDOVER_JOINING,
+ NS_ASSERT_MSG (GetUeManager (rnti)->GetState () == UeManager::HANDOVER_JOINING,
"HandoverJoiningTimeout in unexpected state " << ToString (GetUeManager (rnti)->GetState ()));
RemoveUe (rnti);
}
@@ -1708,7 +2127,7 @@
LteEnbRrc::HandoverLeavingTimeout (uint16_t rnti)
{
NS_LOG_FUNCTION (this << rnti);
- NS_ASSERT_MSG (GetUeManager (rnti)->GetState () == UeManager::HANDOVER_LEAVING,
+ NS_ASSERT_MSG (GetUeManager (rnti)->GetState () == UeManager::HANDOVER_LEAVING,
"HandoverLeavingTimeout in unexpected state " << ToString (GetUeManager (rnti)->GetState ()));
RemoveUe (rnti);
}
@@ -1722,10 +2141,10 @@
Ptr<UeManager> ueManager = GetUeManager (rnti);
ueManager->PrepareHandover (cellId);
-
+
}
-void
+void
LteEnbRrc::DoCompleteSetupUe (uint16_t rnti, LteEnbRrcSapProvider::CompleteSetupUeParameters params)
{
NS_LOG_FUNCTION (this << rnti);
@@ -1736,8 +2155,8 @@
LteEnbRrc::DoRecvRrcConnectionRequest (uint16_t rnti, LteRrcSap::RrcConnectionRequest msg)
{
NS_LOG_FUNCTION (this << rnti);
-
- GetUeManager (rnti)->RecvRrcConnectionRequest (msg);
+
+ GetUeManager (rnti)->RecvRrcConnectionRequest (msg);
}
void
@@ -1753,36 +2172,36 @@
NS_LOG_FUNCTION (this << rnti);
GetUeManager (rnti)->RecvRrcConnectionReconfigurationCompleted (msg);
}
-
-void
+
+void
LteEnbRrc::DoRecvRrcConnectionReestablishmentRequest (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentRequest msg)
{
NS_LOG_FUNCTION (this << rnti);
- GetUeManager (rnti)->RecvRrcConnectionReestablishmentRequest (msg);
+ GetUeManager (rnti)->RecvRrcConnectionReestablishmentRequest (msg);
}
-void
+void
LteEnbRrc::DoRecvRrcConnectionReestablishmentComplete (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentComplete msg)
{
NS_LOG_FUNCTION (this << rnti);
GetUeManager (rnti)->RecvRrcConnectionReestablishmentComplete (msg);
}
-void
+void
LteEnbRrc::DoRecvMeasurementReport (uint16_t rnti, LteRrcSap::MeasurementReport msg)
{
NS_LOG_FUNCTION (this << rnti);
GetUeManager (rnti)->RecvMeasurementReport (msg);
}
-void
+void
LteEnbRrc::DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters request)
{
Ptr<UeManager> ueManager = GetUeManager (request.rnti);
- ueManager->SetupDataRadioBearer (request.bearer, request.bearerId, request.gtpTeid, request.transportLayerAddress);
+ ueManager->SetupDataRadioBearer (request.bearer, request.bearerId, request.gtpTeid, request.transportLayerAddress);
}
-void
+void
LteEnbRrc::DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params)
{
Ptr<UeManager> ueManager = GetUeManager (params.rnti);
@@ -1808,14 +2227,14 @@
NS_LOG_INFO ("rejecting handover request from cellId " << req.sourceCellId);
EpcX2Sap::HandoverPreparationFailureParams res;
res.oldEnbUeX2apId = req.oldEnbUeX2apId;
- res.sourceCellId = req.sourceCellId ;
- res.targetCellId = req.targetCellId ;
+ res.sourceCellId = req.sourceCellId;
+ res.targetCellId = req.targetCellId;
res.cause = 0;
res.criticalityDiagnostics = 0;
m_x2SapProvider->SendHandoverPreparationFailure (res);
return;
}
-
+
uint16_t rnti = AddUe (UeManager::HANDOVER_JOINING);
LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue anrcrv = m_cmacSapProvider->AllocateNcRaPreamble (rnti);
if (anrcrv.valid == false)
@@ -1824,7 +2243,7 @@
RemoveUe (rnti);
NS_FATAL_ERROR ("should trigger HO Preparation Failure, but it is not implemented");
return;
- }
+ }
Ptr<UeManager> ueManager = GetUeManager (rnti);
ueManager->SetSource (req.sourceCellId, req.oldEnbUeX2apId);
@@ -1883,16 +2302,16 @@
LteEnbRrc::DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params)
{
NS_LOG_FUNCTION (this);
-
+
NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST ACK");
-
+
NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
uint16_t rnti = params.oldEnbUeX2apId;
- Ptr<UeManager> ueManager = GetUeManager (rnti);
+ Ptr<UeManager> ueManager = GetUeManager (rnti);
ueManager->RecvHandoverRequestAck (params);
}
@@ -1981,9 +2400,9 @@
NS_LOG_LOGIC ("ueData = " << params.ueData);
NS_LOG_LOGIC ("ueData size = " << params.ueData->GetSize ());
- std::map<uint32_t, X2uTeidInfo>::iterator
+ std::map<uint32_t, X2uTeidInfo>::iterator
teidInfoIt = m_x2uTeidInfoMap.find (params.gtpTeid);
- if (teidInfoIt != m_x2uTeidInfoMap.end ())
+ if (teidInfoIt != m_x2uTeidInfoMap.end ())
{
GetUeManager (teidInfoIt->second.rnti)->SendData (teidInfoIt->second.drbid, params.ueData);
}
@@ -1994,7 +2413,7 @@
}
-uint16_t
+uint16_t
LteEnbRrc::DoAllocateTemporaryCellRnti ()
{
NS_LOG_FUNCTION (this);
@@ -2023,14 +2442,14 @@
NS_LOG_FUNCTION (this);
bool found = false;
uint16_t rnti;
- for (rnti = m_lastAllocatedRnti;
+ for (rnti = m_lastAllocatedRnti;
(rnti != m_lastAllocatedRnti - 1) && (!found);
++rnti)
{
if ((rnti != 0) && (m_ueMap.find (rnti) == m_ueMap.end ()))
{
found = true;
- break;
+ break;
}
}
@@ -2039,12 +2458,37 @@
Ptr<UeManager> ueManager = CreateObject<UeManager> (this, rnti, state);
m_ueMap.insert (std::pair<uint16_t, Ptr<UeManager> > (rnti, ueManager));
ueManager->Initialize ();
- NS_LOG_DEBUG (this << " New UE RNTI " << rnti << " cellId " << m_cellId << " srs CI " << ueManager->GetSrsConfigurationIndex ());
- m_newUeContextTrace (m_cellId, rnti);
+ NS_LOG_DEBUG (this << " New UE RNTI " << rnti << " cellId " << m_cellId << " srs CI " << ueManager->GetSrsConfigurationIndex ());
+ m_newUeContextTrace (m_cellId, rnti);
return rnti;
}
void
+LteEnbRrc::AddMbms (uint16_t mrnti)
+{
+/*
+ bool found = false;
+ uint16_t mrnti;
+ for (mrnti = m_lastAllocatedMrnti;
+ (mrnti != m_lastAllocatedMrnti - 1) && (!found);
+ ++mrnti)
+ {
+ if ((mrnti != 0) && (m_mbmsMap.find (mrnti) == m_mbmsMap.end ()))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ m_lastAllocatedMrnti = mrnti;
+*/
+ Ptr<MbmsManager> mbmsManager = CreateObject<MbmsManager> (this, mrnti);
+ m_mbmsMap.insert (std::pair<uint16_t, Ptr<MbmsManager> > (mrnti, mbmsManager));
+ mbmsManager->Initialize ();
+ NS_LOG_DEBUG (this << " New MBMS RNTI " << mrnti << " cellId " << m_cellId);
+}
+
+void
LteEnbRrc::RemoveUe (uint16_t rnti)
{
NS_LOG_FUNCTION (this << (uint32_t) rnti);
@@ -2059,8 +2503,8 @@
m_s1SapProvider->UeContextRelease (rnti);
}
// need to do this after UeManager has been deleted
- RemoveSrsConfigurationIndex (srsCi);
- }
+ RemoveSrsConfigurationIndex (srsCi);
+}
TypeId
LteEnbRrc::GetRlcType (EpsBearer bearer)
@@ -2120,7 +2564,7 @@
uint16_t g_srsCiLow[SRS_ENTRIES] = {0, 0, 2, 7, 17, 37, 77, 157, 317};
uint16_t g_srsCiHigh[SRS_ENTRIES] = {0, 1, 6, 16, 36, 76, 156, 316, 636};
-void
+void
LteEnbRrc::SetSrsPeriodicity (uint32_t p)
{
NS_LOG_FUNCTION (this << p);
@@ -2141,7 +2585,7 @@
NS_FATAL_ERROR ("illecit SRS periodicity value " << p << ". Allowed values: " << allowedValues.str ());
}
-uint32_t
+uint32_t
LteEnbRrc::GetSrsPeriodicity () const
{
NS_LOG_FUNCTION (this);
@@ -2161,10 +2605,10 @@
NS_LOG_DEBUG (this << " SRS p " << g_srsPeriodicity[m_srsCurrentPeriodicityId] << " set " << m_ueSrsConfigurationIndexSet.size ());
if (m_ueSrsConfigurationIndexSet.size () >= g_srsPeriodicity[m_srsCurrentPeriodicityId])
{
- NS_FATAL_ERROR ("too many UEs (" << m_ueSrsConfigurationIndexSet.size () + 1
- << ") for current SRS periodicity "
- << g_srsPeriodicity[m_srsCurrentPeriodicityId]
- << ", consider increasing the value of ns3::LteEnbRrc::SrsPeriodicity");
+ NS_FATAL_ERROR ("too many UEs (" << m_ueSrsConfigurationIndexSet.size () + 1
+ << ") for current SRS periodicity "
+ << g_srsPeriodicity[m_srsCurrentPeriodicityId]
+ << ", consider increasing the value of ns3::LteEnbRrc::SrsPeriodicity");
}
if (m_ueSrsConfigurationIndexSet.empty ())
@@ -2188,20 +2632,20 @@
else
{
// look for released ones
- for (uint16_t srcCi = g_srsCiLow[m_srsCurrentPeriodicityId]; srcCi < g_srsCiHigh[m_srsCurrentPeriodicityId]; srcCi++)
+ for (uint16_t srcCi = g_srsCiLow[m_srsCurrentPeriodicityId]; srcCi < g_srsCiHigh[m_srsCurrentPeriodicityId]; srcCi++)
{
std::set<uint16_t>::iterator it = m_ueSrsConfigurationIndexSet.find (srcCi);
- if (it==m_ueSrsConfigurationIndexSet.end ())
+ if (it == m_ueSrsConfigurationIndexSet.end ())
{
m_lastAllocatedConfigurationIndex = srcCi;
m_ueSrsConfigurationIndexSet.insert (srcCi);
break;
}
}
- }
+ }
}
return m_lastAllocatedConfigurationIndex;
-
+
}
@@ -2214,7 +2658,7 @@
m_ueSrsConfigurationIndexSet.erase (it);
}
-uint8_t
+uint8_t
LteEnbRrc::GetLogicalChannelGroup (EpsBearer bearer)
{
if (bearer.IsGbr ())
@@ -2227,7 +2671,7 @@
}
}
-uint8_t
+uint8_t
LteEnbRrc::GetLogicalChannelPriority (EpsBearer bearer)
{
return bearer.qci;
@@ -2237,13 +2681,13 @@
LteEnbRrc::SendSystemInformation ()
{
// NS_LOG_FUNCTION (this);
- // for simplicity, we use the same periodicity for all sibs
- // note that in real systems the periodicy of each sibs could be different
+// for simplicity, we use the same periodicity for all sibs
+// note that in real systems the periodicy of each sibs could be different
LteRrcSap::SystemInformation si;
si.haveSib2 = true;
si.sib2.freqInfo.ulCarrierFreq = m_ulEarfcn;
si.sib2.freqInfo.ulBandwidth = m_ulBandwidth;
-
+
LteEnbCmacSapProvider::RachConfig rc = m_cmacSapProvider->GetRachConfig ();
LteRrcSap::RachConfigCommon rachConfigCommon;
rachConfigCommon.preambleInfo.numberOfRaPreambles = rc.numberOfRaPreambles;
@@ -2255,5 +2699,19 @@
Simulator::Schedule (m_systemInformationPeriodicity, &LteEnbRrc::SendSystemInformation, this);
}
+void
+LteEnbRrc::SendMbmsAreaConfiguration ()
+{
+ //Creazione messaggio
+ LteRrcSap::RrcMbmsAreaConfiguration msg;
+ std::map<uint16_t, Ptr<MbmsManager> >::iterator it;
+ for (it = m_mbmsMap.begin (); it != m_mbmsMap.end (); ++it)
+ {
+ msg.pmchInfoList = it->second->BuildMbmsAreaConfiguration ();
+ }
+ m_rrcSapUser->SendMbmsAreaConfiguration (msg);
+ Simulator::Schedule (m_mbmsAreaConfigurationPeriodicity, &LteEnbRrc::SendMbmsAreaConfiguration, this);
+}
+
} // namespace ns3
--- a/src/lte/model/lte-enb-rrc.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-enb-rrc.h Thu Jun 13 11:32:13 2013 +0200
@@ -17,7 +17,7 @@
*
* Authors: Nicola Baldo <nbaldo@cttc.es>
* Marco Miozzo <mmiozzo@cttc.es>
- * Manuel Requena <manuel.requena@cttc.es>
+ * Manuel Requena <manuel.requena@cttc.es>
*/
#ifndef LTE_ENB_RRC_H
@@ -87,37 +87,35 @@
friend class LtePdcpSpecificLtePdcpSapUser<UeManager>;
public:
-
-
/**
* The state of the UeManager at the eNB RRC
- *
+ *
*/
enum State
- {
- INITIAL_RANDOM_ACCESS = 0,
- CONNECTION_SETUP,
- CONNECTION_REJECTED,
- CONNECTED_NORMALLY,
- CONNECTION_RECONFIGURATION,
- CONNECTION_REESTABLISHMENT,
- HANDOVER_PREPARATION,
- HANDOVER_JOINING,
- HANDOVER_PATH_SWITCH,
- HANDOVER_LEAVING,
- NUM_STATES
- };
+ {
+ INITIAL_RANDOM_ACCESS = 0,
+ CONNECTION_SETUP,
+ CONNECTION_REJECTED,
+ CONNECTED_NORMALLY,
+ CONNECTION_RECONFIGURATION,
+ CONNECTION_REESTABLISHMENT,
+ HANDOVER_PREPARATION,
+ HANDOVER_JOINING,
+ HANDOVER_PATH_SWITCH,
+ HANDOVER_LEAVING,
+ NUM_STATES
+ };
UeManager ();
-
- /**
+
+ /**
* UeManager constructor
- *
+ *
* \param rrc pointer to the LteEnbRrc holding this UeManager
* \param rnti RNTI of the UE
* \param s initial state of the UeManager
- *
- * \return
+ *
+ * \return
*/
UeManager (Ptr<LteEnbRrc> rrc, uint16_t rnti, State s);
@@ -127,48 +125,48 @@
protected:
virtual void DoInitialize ();
virtual void DoDispose ();
-public:
+public:
static TypeId GetTypeId (void);
- /**
+ /**
* Set the identifiers of the source eNB for the case where a UE
- * joins the current eNB as part of a handover procedure
- *
- * \param sourceCellId
- * \param sourceX2apId
+ * joins the current eNB as part of a handover procedure
+ *
+ * \param sourceCellId
+ * \param sourceX2apId
*/
void SetSource (uint16_t sourceCellId, uint16_t sourceX2apId);
- /**
+ /**
* Set the IMSI
- *
+ *
* \param imsi the IMSI
*/
void SetImsi (uint64_t imsi);
- /**
+ /**
* Setup a new data radio bearer, including both the configuration
* within the eNB and the necessary RRC signaling with the UE
- *
+ *
* \param bearer the QoS characteristics of the bearer
* \param bearerId the EPS bearer identifier
* \param gtpTeid S1-bearer GTP tunnel endpoint identifier, see 36.423 9.2.1
* \param transportLayerAddress IP Address of the SGW, see 36.423 9.2.1
- *
+ *
*/
void SetupDataRadioBearer (EpsBearer bearer, uint8_t bearerId, uint32_t gtpTeid, Ipv4Address transportLayerAddress);
- /**
+ /**
* Start all configured data radio bearers. It is safe to call this
* method if any bearer had been already started previously.
- *
+ *
*/
void RecordDataRadioBearersToBeStarted ();
-
- /**
+
+ /**
* Start the data radio bearers that have been previously recorded
- * to be started using RecordDataRadioBearersToBeStarted()
- *
+ * to be started using RecordDataRadioBearersToBeStarted()
+ *
*/
void StartDataRadioBearers ();
@@ -180,85 +178,85 @@
*/
void ReleaseDataRadioBearer (uint8_t drbid);
- /**
+ /**
* schedule an RRC Connection Reconfiguration procedure with the UE
- *
+ *
*/
void ScheduleRrcConnectionReconfiguration ();
- /**
+ /**
* Start the handover preparation and send the handover request
- *
+ *
* \param cellId id of the target cell
*/
void PrepareHandover (uint16_t cellId);
- /**
+ /**
* take the necessary actions in response to the reception of an X2 HANDOVER REQUEST ACK message
- *
- * \param params
+ *
+ * \param params
*/
void RecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
-
- /**
- *
+
+ /**
+ *
* \return the HandoverPreparationInfo sent by the source eNB to the
* target eNB in the X2-based handover procedure
*/
LteRrcSap::RadioResourceConfigDedicated GetRadioResourceConfigForHandoverPreparationInfo ();
- /**
- *
+ /**
+ *
* \return retrieve the data that the target eNB needs to send to the source
* eNB as the Handover Command in the X2-based handover
* procedure.
*
* \note mobility control info is not expected to be filled in
- * (shall be filled in by the caller).
+ * (shall be filled in by the caller).
*/
LteRrcSap::RrcConnectionReconfiguration GetRrcConnectionReconfigurationForHandover ();
- /**
+ /**
* Send a data packet over the appropriate Data Radio Bearer
- *
+ *
* \param bid the corresponding EPS Bearer ID
* \param p the packet
*/
void SendData (uint8_t bid, Ptr<Packet> p);
- /**
- *
+ /**
+ *
* \return a list of ERAB-to-be-setup items to be put in a X2 HO REQ message
*/
std::vector<EpcX2Sap::ErabToBeSetupItem> GetErabList ();
- /**
+ /**
* send the UE CONTEXT RELEASE X2 message to the source eNB, thus
- * successfully terminating an X2 handover procedure
- *
+ * successfully terminating an X2 handover procedure
+ *
*/
void SendUeContextRelease ();
- /**
+ /**
* Take the necessary actions in response to the reception of an X2 HO preparation failure message
- *
+ *
* \param cellId id of the target cell
*/
void RecvHandoverPreparationFailure (uint16_t cellId);
- /**
+ /**
* Take the necessary actions in response to the reception of an X2 SN STATUS TRANSFER message
- *
+ *
* \param params the SN STATUS
*/
void RecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params);
-
- /**
+
+ /**
* Take the necessary actions in response to the reception of an X2 UE CONTEXT RELEASE message
- *
+ *
* \param params the SN STATUS
*/
- void RecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params);
+ void RecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params);
// methods forwarded from RRC SAP
void CompleteSetupUe (LteEnbRrcSapProvider::CompleteSetupUeParameters params);
@@ -276,138 +274,137 @@
// methods forwarded from PDCP SAP
void DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params);
-
- /**
- *
+
+ /**
+ *
* \return the RNTI, i.e., an UE identifier that is unique within
* the cell
*/
uint16_t GetRnti (void);
- /**
+ /**
*
* \return the IMSI, i.e., a globally unique UE identifier
*/
uint64_t GetImsi (void);
- /**
- *
+ /**
+ *
* \return the SRS Configuration Index
*/
- uint16_t GetSrsConfigurationIndex (void);
+ uint16_t GetSrsConfigurationIndex (void);
- /**
+ /**
* Set the SRS configuration index and do the necessary reconfiguration
- *
- * \param srsConfIndex
+ *
+ * \param srsConfIndex
*/
void SetSrsConfigurationIndex (uint16_t srsConfIndex);
- /**
- *
+ /**
+ *
* \return the current state
*/
State GetState ();
private:
-
- /**
+ /**
* Add a new LteDataRadioBearerInfo structure to the UeManager
- *
- * \param radioBearerInfo
- *
+ *
+ * \param radioBearerInfo
+ *
* \return the id of the newly added data radio bearer structure
*/
uint8_t AddDataRadioBearerInfo (Ptr<LteDataRadioBearerInfo> radioBearerInfo);
- /**
+ /**
* \param drbid the Data Radio Bearer id
- *
+ *
* \return the corresponding LteDataRadioBearerInfo
*/
Ptr<LteDataRadioBearerInfo> GetDataRadioBearerInfo (uint8_t drbid);
- /**
+ /**
* remove the LteDataRadioBearerInfo corresponding to a bearer being released
*
* \param drbid the Data Radio Bearer id
*/
void RemoveDataRadioBearerInfo (uint8_t drbid);
- /**
- *
+ /**
+ *
* \return an RrcConnectionReconfiguration struct built based on the
* current configuration
*/
LteRrcSap::RrcConnectionReconfiguration BuildRrcConnectionReconfiguration ();
-
- /**
- *
+
+ /**
+ *
* \return a RadioResourceConfigDedicated struct built based on the
* current configuration
*/
LteRrcSap::RadioResourceConfigDedicated BuildRadioResourceConfigDedicated ();
- /**
- *
+ /**
+ *
* \return a MeasConfig struct built based on the
* current configuration
*/
LteRrcSap::MeasConfig BuildMeasConfig ();
- /**
- *
+ /**
+ *
* \return a newly allocated identifier for a new RRC transaction
*/
uint8_t GetNewRrcTransactionIdentifier ();
- /**
+ /**
* \param lcid a Logical Channel Identifier
- *
+ *
* \return the corresponding Data Radio Bearer Id
*/
uint8_t Lcid2Drbid (uint8_t lcid);
- /**
+ /**
* \param drbid a Data Radio Bearer Id
- *
+ *
* \return the corresponding Logical Channel Identifier
*/
uint8_t Drbid2Lcid (uint8_t drbid);
- /**
+ /**
* \param lcid a Logical Channel Identifier
- *
+ *
* \return the corresponding EPS Bearer Identifier
*/
uint8_t Lcid2Bid (uint8_t lcid);
- /**
+ /**
* \param bid an EPS Bearer Identifier
- *
+ *
* \return the corresponding Logical Channel Identifier
*/
uint8_t Bid2Lcid (uint8_t bid);
- /**
+ /**
* \param drbid Data Radio Bearer Id
- *
+ *
* \return the corresponding EPS Bearer Identifier
*/
uint8_t Drbid2Bid (uint8_t drbid);
- /**
+ /**
* \param bid an EPS Bearer Identifier
- *
+ *
* \return the corresponding Data Radio Bearer Id
*/
uint8_t Bid2Drbid (uint8_t bid);
-
- /**
+
+ /**
* Switch the UeManager to the given state
- *
+ *
* \param s the given state
*/
void SwitchToState (State s);
@@ -418,6 +415,7 @@
Ptr<LteSignalingRadioBearerInfo> m_srb1;
uint8_t m_lastAllocatedDrbid;
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint64_t m_imsi;
uint8_t m_lastRrcTransactionIdentifier;
LteRrcSap::PhysicalConfigDedicated m_physicalConfigDedicated;
@@ -444,10 +442,198 @@
};
+/**
+ * Manages all the radio bearer information possessed by the ENB RRC for a single MBMS
+ *
+ */
+class MbmsManager : public Object
+{
+ friend class LtePdcpSpecificLtePdcpSapUser<MbmsManager>;
+
+public:
+ MbmsManager ();
+
+ /**
+ * UeManager constructor
+ *
+ * \param rrc pointer to the LteEnbRrc holding this UeManager
+ * \param rnti RNTI of the UE
+ * \param s initial state of the UeManager
+ *
+ * \return
+ */
+ MbmsManager (Ptr<LteEnbRrc> rrc, uint16_t mrnti);
+
+ virtual ~MbmsManager (void);
+
+ // inherited from Object
+protected:
+ virtual void DoInitialize ();
+ virtual void DoDispose ();
+public:
+ static TypeId GetTypeId (void);
+
+
+ /**
+ * Setup a new data radio bearer, including both the configuration
+ * within the eNB and the necessary RRC signaling with the UE
+ *
+ * \param bearer the QoS characteristics of the bearer
+ * \param bearerId the EPS bearer identifier
+ * \param gtpTeid S1-bearer GTP tunnel endpoint identifier, see 36.423 9.2.1
+ * \param transportLayerAddress IP Address of the SGW, see 36.423 9.2.1
+ *
+ */
+ void SetupDataRadioBearerMbms (EpsBearer bearer, uint8_t bearerId, Ipv4Address mbmsAddress);
+
+ /**
+ * Start all configured data radio bearers. It is safe to call this
+ * method if any bearer had been already started previously.
+ *
+ */
+ void RecordDataRadioBearersToBeStarted ();
+
+ /**
+ * Start the data radio bearers that have been previously recorded
+ * to be started using RecordDataRadioBearersToBeStarted()
+ *
+ */
+ void StartDataRadioBearers ();
+
+ /**
+ *
+ * Release a given radio bearer
+ *
+ * \param drbid the data radio bearer id of the bearer to be released
+ */
+ void ReleaseDataRadioBearer (uint8_t drbid);
+
+
+ /**
+ * Send a data packet over the appropriate Data Radio Bearer
+ *
+ * \param bid the corresponding EPS Bearer ID
+ * \param p the packet
+ */
+ void SendData (uint8_t bid, Ptr<Packet> p);
+
+
+
+ // methods forwarded from PDCP SAP
+ void DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params);
+
+ /**
+ *
+ * \return the RNTI, i.e., an UE identifier that is unique within
+ * the cell
+ */
+ uint16_t GetMrnti (void);
+
+ /**
+ * Build MBMS Area Configuration message
+ *
+ * \param msg the RrcMbmsAreaConfigurationMessage to send
+ *
+ */
+ LteRrcSap::PmchInfoList BuildMbmsAreaConfiguration ();
+
+
+private:
+ /**
+ * Add a new LteDataRadioBearerInfo structure to the MbmsManager
+ *
+ * \param radioBearerInfo
+ *
+ * \return the id of the newly added data radio bearer structure
+ */
+ uint8_t AddDataRadioBearerInfo (Ptr<LteDataRadioBearerInfo> radioBearerInfo);
+
+ /**
+ * \param drbid the Data Radio Bearer id
+ *
+ * \return the corresponding LteDataRadioBearerInfo
+ */
+ Ptr<LteDataRadioBearerInfo> GetDataRadioBearerInfo (uint8_t drbid);
+
+ /**
+ * remove the LteDataRadioBearerInfo corresponding to a bearer being released
+ *
+ * \param drbid the Data Radio Bearer id
+ */
+ void RemoveDataRadioBearerInfo (uint8_t drbid);
+
+ /**
+ * \param lcid a Logical Channel Identifier
+ *
+ * \return the corresponding Data Radio Bearer Id
+ */
+ uint8_t Lcid2Drbid (uint8_t lcid);
+
+ /**
+ * \param drbid a Data Radio Bearer Id
+ *
+ * \return the corresponding Logical Channel Identifier
+ */
+ uint8_t Drbid2Lcid (uint8_t drbid);
+
+ /**
+ * \param lcid a Logical Channel Identifier
+ *
+ * \return the corresponding EPS Bearer Identifier
+ */
+ uint8_t Lcid2Bid (uint8_t lcid);
+
+ /**
+ * \param bid an EPS Bearer Identifier
+ *
+ * \return the corresponding Logical Channel Identifier
+ */
+ uint8_t Bid2Lcid (uint8_t bid);
+
+ /**
+ * \param drbid Data Radio Bearer Id
+ *
+ * \return the corresponding EPS Bearer Identifier
+ */
+ uint8_t Drbid2Bid (uint8_t drbid);
+
+ /**
+ * \param bid an EPS Bearer Identifier
+ *
+ * \return the corresponding Data Radio Bearer Id
+ */
+ uint8_t Bid2Drbid (uint8_t bid);
+
+
+ std::map <uint8_t, Ptr<LteDataRadioBearerInfo> > m_drbMap;
+ Ptr<LteSignalingRadioBearerInfo> m_srb0;
+ Ptr<LteSignalingRadioBearerInfo> m_srb1;
+ uint8_t m_lastAllocatedDrbid;
+ uint16_t m_mrnti;
+ uint8_t m_lastRrcTransactionIdentifier;
+ LteRrcSap::PhysicalConfigDedicated m_physicalConfigDedicated;
+ Ptr<LteEnbRrc> m_rrc;
+ LtePdcpSapUser* m_drbPdcpSapUser;
+ // imsi cellid rnti old new
+ uint16_t m_targetCellId;
+ std::list<uint8_t> m_drbsToBeStarted;
+ bool m_needTransmissionModeConfiguration;
+
+ EventId m_connectionTimeout;
+ EventId m_connectionRejectedTimeout;
+ EventId m_handoverJoiningTimeout;
+ EventId m_handoverLeavingTimeout;
+
+ Ptr<UeMeasure> m_servingCellMeasures;
+ // cellid
+ std::map<uint16_t, Ptr<UeMeasure> > m_neighbourCellMeasures;
+
+};
+
/**
* \ingroup lte
- *
+ *
* The LTE Radio Resource Control entity at the eNB
*/
class LteEnbRrc : public Object
@@ -458,6 +644,7 @@
friend class MemberEpcEnbS1SapUser<LteEnbRrc>;
friend class EpcX2SpecificEpcX2SapUser<LteEnbRrc>;
friend class UeManager;
+ friend class MbmsManager;
public:
/**
@@ -485,7 +672,7 @@
*/
void SetEpcX2SapProvider (EpcX2SapProvider* s);
- /**
+ /**
* Get the X2 SAP offered by this RRC
* \return s the X2 SAP User interface offered to the X2 entity by this RRC entity
*/
@@ -499,7 +686,7 @@
*/
void SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s);
- /**
+ /**
* Get the CMAC SAP offered by this RRC
* \return s the CMAC SAP User interface offered to the MAC by this RRC
*/
@@ -530,15 +717,15 @@
void SetLteMacSapProvider (LteMacSapProvider* s);
- /**
+ /**
* Set the S1 SAP Provider
- *
+ *
* \param s the S1 SAP Provider
*/
void SetS1SapProvider (EpcEnbS1SapProvider * s);
- /**
- *
+ /**
+ *
* \return the S1 SAP user
*/
EpcEnbS1SapUser* GetS1SapUser ();
@@ -558,16 +745,31 @@
*/
LteEnbCphySapUser* GetLteEnbCphySapUser ();
- /**
- *
- *
+ /**
+ *
+ *
* \param rnti the identifier of an UE
- *
+ *
* \return the corresponding UeManager instance
*/
Ptr<UeManager> GetUeManager (uint16_t rnti);
/**
+ *
+ * \param mrnti the identifier of a MBMS traffic
+ *
+ * \return the corresponding MbmsManager instance
+ */
+ Ptr<MbmsManager> GetMbmsManager (uint16_t mrnti);
+
+ /**
+ *
+ * \param mrnti
+ *
+ */
+ void SetupDataRadioBearerMbms (uint16_t mrnti, EpsBearer bearer, uint8_t bearerId, Ipv4Address mbmsAddress);
+
+ /**
* configure cell-specific parameters
*
* \param ulBandwidth the uplink bandwidth in number of RB
@@ -578,93 +780,94 @@
*/
void ConfigureCell (uint8_t ulBandwidth,
uint8_t dlBandwidth,
- uint16_t ulEarfcn,
+ uint16_t ulEarfcn,
uint16_t dlEarfcn,
uint16_t cellId);
-
- /**
+
+ /**
* set the cell id of this eNB
- *
- * \param m_cellId
+ *
+ * \param m_cellId
*/
void SetCellId (uint16_t m_cellId);
- /**
+ /**
* Enqueue an IP data packet on the proper bearer for downlink
* transmission. Normally expected to be called by the NetDevice
- * forwarding a packet coming from the EpcEnbApplication
- *
+ * forwarding a packet coming from the EpcEnbApplication
+ *
* \param p the packet
- *
+ *
* \return true if successful, false if an error occurred
*/
bool SendData (Ptr<Packet> p);
- /**
+ /**
* set the callback used to forward data packets up the stack
- *
- * \param void
- * \param cb
+ *
+ * \param void
+ * \param cb
*/
void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
- /**
+ /**
* Method triggered when a UE is expected to get connected but does
* not do so in a reasonable time
- *
+ *
* \param rnti the T-C-RNTI whose timeout expired
*/
void ConnectionTimeout (uint16_t rnti);
- /**
+ /**
* Method triggered a while after sending RRC Connection Rejected
- *
+ *
* \param rnti the T-C-RNTI whose timeout expired
*/
void ConnectionRejectedTimeout (uint16_t rnti);
- /**
- * Method triggered when a UE is expected to join the cell for a handover
+ /**
+ * Method triggered when a UE is expected to join the cell for a handover
* but does not do so in a reasonable time
- *
+ *
* \param rnti the C-RNTI whose timeout expired
*/
void HandoverJoiningTimeout (uint16_t rnti);
- /**
+ /**
* Method triggered when a UE is expected to leave a cell for a handover
* but no feedback is received in a reasonable time
- *
+ *
* \param rnti the C-RNTI whose timeout expired
*/
void HandoverLeavingTimeout (uint16_t rnti);
- /**
+ /**
* Send a HandoverRequest through the X2 SAP interface
- *
+ *
* This method will trigger a handover which is started by the RRC
* by sending a handover request to the target eNB over the X2
- * interface
+ * interface
*
- * \param imsi the id of the UE to be handed over
+ * \param imsi the id of the UE to be handed over
* \param cellId the id of the target eNB
*/
void SendHandoverRequest (uint16_t rnti, uint16_t cellId);
/**
* Identifies how EPS Bearer parameters are mapped to different RLC types
- *
+ *
*/
- enum LteEpsBearerToRlcMapping_t {RLC_SM_ALWAYS = 1,
- RLC_UM_ALWAYS = 2,
- RLC_AM_ALWAYS = 3,
- PER_BASED = 4};
+ enum LteEpsBearerToRlcMapping_t
+ {
+ RLC_SM_ALWAYS = 1,
+ RLC_UM_ALWAYS = 2,
+ RLC_AM_ALWAYS = 3,
+ PER_BASED = 4
+ };
private:
-
+ // methods forwarded from RRC SAP
- // methods forwarded from RRC SAP
-
void DoCompleteSetupUe (uint16_t rnti, LteEnbRrcSapProvider::CompleteSetupUeParameters params);
void DoRecvRrcConnectionRequest (uint16_t rnti, LteRrcSap::RrcConnectionRequest msg);
void DoRecvRrcConnectionSetupCompleted (uint16_t rnti, LteRrcSap::RrcConnectionSetupCompleted msg);
@@ -676,7 +879,7 @@
// S1 SAP methods
void DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params);
- void DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params);
+ void DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params);
// X2 SAP methods
void DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params);
void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
@@ -692,7 +895,7 @@
uint16_t DoAllocateTemporaryCellRnti ();
void DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
void DoRrcConfigurationUpdateInd (LteEnbCmacSapUser::UeConfig params);
-
+
// Internal methods
@@ -715,10 +918,10 @@
void RemoveUe (uint16_t rnti);
- /**
- *
+ /**
+ *
* \param bearer the specification of an EPS bearer
- *
+ *
* \return the type of RLC that is to be created for the given EPS bearer
*/
TypeId GetRlcType (EpsBearer bearer);
@@ -726,63 +929,65 @@
public:
-
- /**
+ /**
* Add a neighbour with an X2 interface
*
* \param cellid neighbouring cell id
*/
void AddX2Neighbour (uint16_t cellId);
- /**
- *
+ /**
+ *
* \param p the SRS periodicity in num TTIs
*/
void SetSrsPeriodicity (uint32_t p);
- /**
+ /**
*
* \return the current SRS periodicity
*/
uint32_t GetSrsPeriodicity () const;
-private:
+ /**
+ * Add MBMS Bearer
+ */
+ void AddMbms (uint16_t mrnti);
- /**
- * Allocate a new SRS configuration index for a new UE.
+ /**
+ * Allocate a new SRS configuration index for a new UE.
*
* \note this method can have the side effect of updating the SRS
* configuration index of all UEs
- *
+ *
* \return the newly allocated SRS configuration index
*/
uint16_t GetNewSrsConfigurationIndex (void);
- /**
+ /**
* remove a previously allocated SRS configuration index
*
* \note this method can have the side effect of updating the SRS
* configuration index of all UEs
- *
+ *
* \param srcCi the indext to be removed
*/
void RemoveSrsConfigurationIndex (uint16_t srcCi);
-
+
- /**
- *
+ /**
+ *
* \param bearer the characteristics of the bearer
- *
+ *
* \return the Logical Channel Group in a bearer with these
- * characteristics is put. Used for MAC Buffer Status Reporting purposes.
+ * characteristics is put. Used for MAC Buffer Status Reporting purposes.
*/
uint8_t GetLogicalChannelGroup (EpsBearer bearer);
- /**
- *
+ /**
+ *
* \param bearer the characteristics of the bearer
- *
+ *
* \return the priority level of a bearer with these
* characteristics is put. Used for the part of UL MAC Scheduling
* carried out by the UE
@@ -790,12 +995,18 @@
uint8_t GetLogicalChannelPriority (EpsBearer bearer);
- /**
+ /**
* method used to periodically send System Information
- *
+ *
*/
void SendSystemInformation ();
+ /**
+ * method user to periodically send MBMS Area Configuration message
+ *
+ */
+ void SendMbmsAreaConfiguration ();
+
Callback <void, Ptr<Packet> > m_forwardUpCallback;
EpcX2SapUser* m_x2SapUser;
@@ -822,24 +1033,27 @@
uint16_t m_dlBandwidth;
uint16_t m_ulBandwidth;
uint16_t m_lastAllocatedRnti;
+ uint16_t m_lastAllocatedMrnti;
- std::map<uint16_t, Ptr<UeManager> > m_ueMap;
+ std::map<uint16_t, Ptr<UeManager> > m_ueMap;
+ std::map<uint16_t, Ptr<MbmsManager> > m_mbmsMap;
struct X2uTeidInfo
{
uint16_t rnti;
uint8_t drbid;
};
-
+
// TEID RNTI, DRBID
- std::map<uint32_t, X2uTeidInfo> m_x2uTeidInfoMap;
-
+ std::map<uint32_t, X2uTeidInfo> m_x2uTeidInfoMap;
+
uint8_t m_defaultTransmissionMode;
enum LteEpsBearerToRlcMapping_t m_epsBearerToRlcMapping;
Time m_systemInformationPeriodicity;
-
+ Time m_mbmsAreaConfigurationPeriodicity;
+
// SRS related attributes
uint16_t m_srsCurrentPeriodicityId;
std::set<uint16_t> m_ueSrsConfigurationIndexSet;
@@ -858,21 +1072,21 @@
Time m_connectionTimeoutDuration;
Time m_connectionRejectedTimeoutDuration;
Time m_handoverJoiningTimeoutDuration;
- Time m_handoverLeavingTimeoutDuration;
+ Time m_handoverLeavingTimeoutDuration;
// cellid
std::map<uint16_t, Ptr<NeighbourRelation> > m_neighbourRelationTable;
- // cellid rnti
+ // cellid rnti
TracedCallback<uint16_t, uint16_t> m_newUeContextTrace;
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_connectionEstablishedTrace;
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_connectionReconfigurationTrace;
// imsi cellid rnti targetCellId
TracedCallback<uint64_t, uint16_t, uint16_t, uint16_t> m_handoverStartTrace;
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_handoverEndOkTrace;
// imsi cellid rnti
--- a/src/lte/model/lte-mac-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-mac-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -46,6 +46,7 @@
{
Ptr<Packet> pdu; /**< the RLC PDU */
uint16_t rnti; /**< the C-RNTI identifying the UE */
+ uint16_t mrnti; /**< the M-RNTI identifying the MBMS */
uint8_t lcid; /**< the logical channel id corresponding to the sending RLC instance */
uint8_t layer; /**< the layer value that was passed by the MAC in the call to NotifyTxOpportunity that generated this PDU */
uint8_t harqProcessId; /**< the HARQ process id that was passed by the MAC in the call to NotifyTxOpportunity that generated this PDU */
@@ -66,6 +67,7 @@
struct ReportBufferStatusParameters
{
uint16_t rnti; /**< the C-RNTI identifying the UE */
+ uint16_t mrnti; /**< the M-RNTI identifying the MBMS traffic */
uint8_t lcid; /**< the logical channel id corresponding to the sending RLC instance */
uint32_t txQueueSize; /**< the current size of the RLC transmission queue */
uint16_t txQueueHolDelay; /**< the Head Of Line delay of the transmission queue */
--- a/src/lte/model/lte-pdcp-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-pdcp-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -44,6 +44,7 @@
{
Ptr<Packet> pdcpSdu; /**< the RRC PDU */
uint16_t rnti; /**< the C-RNTI identifying the UE */
+ uint16_t mrnti; /**< the M-RNTI identifying the MBMS */
uint8_t lcid; /**< the logical channel id corresponding to the sending RLC instance */
};
@@ -77,6 +78,7 @@
{
Ptr<Packet> pdcpSdu; /**< the RRC PDU */
uint16_t rnti; /**< the C-RNTI identifying the UE */
+ uint16_t mrnti; /**< the M-RNTI identifying the MBMS */
uint8_t lcid; /**< the logical channel id corresponding to the sending RLC instance */
};
--- a/src/lte/model/lte-pdcp.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-pdcp.cc Thu Jun 13 11:32:13 2013 +0200
@@ -67,6 +67,7 @@
: m_pdcpSapUser (0),
m_rlcSapProvider (0),
m_rnti (0),
+ m_mrnti (0),
m_lcid (0),
m_txSequenceNumber (0),
m_rxSequenceNumber (0)
@@ -113,6 +114,13 @@
}
void
+LtePdcp::SetMrnti (uint16_t mrnti)
+{
+ NS_LOG_FUNCTION(this << (uint32_t) mrnti);
+ m_mrnti = mrnti;
+}
+
+void
LtePdcp::SetLcId (uint8_t lcId)
{
NS_LOG_FUNCTION (this << (uint32_t) lcId);
@@ -168,7 +176,7 @@
void
LtePdcp::DoTransmitPdcpSdu (Ptr<Packet> p)
{
- NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
+ NS_LOG_FUNCTION (this << m_rnti << m_mrnti << (uint32_t) m_lcid << p->GetSize ());
LtePdcpHeader pdcpHeader;
pdcpHeader.SetSequenceNumber (m_txSequenceNumber);
@@ -191,6 +199,7 @@
LteRlcSapProvider::TransmitPdcpPduParameters params;
params.rnti = m_rnti;
+ params.mrnti = m_mrnti;
params.lcid = m_lcid;
params.pdcpPdu = p;
@@ -224,6 +233,7 @@
LtePdcpSapUser::ReceivePdcpSduParameters params;
params.pdcpSdu = p;
params.rnti = m_rnti;
+ params.mrnti = m_mrnti;
params.lcid = m_lcid;
m_pdcpSapUser->ReceivePdcpSdu (params);
}
--- a/src/lte/model/lte-pdcp.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-pdcp.h Thu Jun 13 11:32:13 2013 +0200
@@ -53,6 +53,12 @@
/**
*
+ * \param mrnti
+ */
+ void SetMrnti (uint16_t mrnti);
+
+ /**
+ *
*
* \param lcId
*/
@@ -125,6 +131,7 @@
LteRlcSapProvider* m_rlcSapProvider;
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint8_t m_lcid;
/**
--- a/src/lte/model/lte-radio-bearer-tag.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-radio-bearer-tag.cc Thu Jun 13 11:32:13 2013 +0200
@@ -53,18 +53,21 @@
LteRadioBearerTag::LteRadioBearerTag ()
: m_rnti (0),
+ m_mrnti (0),
m_lcid (0),
m_layer (0)
{
}
-LteRadioBearerTag::LteRadioBearerTag (uint16_t rnti, uint8_t lcid)
+LteRadioBearerTag::LteRadioBearerTag (uint16_t rnti, uint16_t mrnti, uint8_t lcid)
: m_rnti (rnti),
+ m_mrnti (mrnti),
m_lcid (lcid)
{
}
-LteRadioBearerTag::LteRadioBearerTag (uint16_t rnti, uint8_t lcid, uint8_t layer)
+LteRadioBearerTag::LteRadioBearerTag (uint16_t rnti, uint16_t mrnti, uint8_t lcid, uint8_t layer)
: m_rnti (rnti),
+ m_mrnti (mrnti),
m_lcid (lcid),
m_layer (layer)
{
@@ -77,6 +80,12 @@
}
void
+LteRadioBearerTag::SetMrnti (uint16_t mrnti)
+{
+ m_mrnti = mrnti;
+}
+
+void
LteRadioBearerTag::SetLcid (uint8_t lcid)
{
m_lcid = lcid;
@@ -91,13 +100,14 @@
uint32_t
LteRadioBearerTag::GetSerializedSize (void) const
{
- return 4;
+ return 6;
}
void
LteRadioBearerTag::Serialize (TagBuffer i) const
{
i.WriteU16 (m_rnti);
+ i.WriteU16 (m_mrnti);
i.WriteU8 (m_lcid);
i.WriteU8 (m_layer);
}
@@ -106,6 +116,7 @@
LteRadioBearerTag::Deserialize (TagBuffer i)
{
m_rnti = (uint16_t) i.ReadU16 ();
+ m_mrnti = (uint16_t) i.ReadU16 ();
m_lcid = (uint8_t) i.ReadU8 ();
m_layer = (uint8_t) i.ReadU8 ();
}
@@ -116,6 +127,12 @@
return m_rnti;
}
+uint16_t
+LteRadioBearerTag::GetMrnti () const
+{
+ return m_mrnti;
+}
+
uint8_t
LteRadioBearerTag::GetLcid () const
{
--- a/src/lte/model/lte-radio-bearer-tag.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-radio-bearer-tag.h Thu Jun 13 11:32:13 2013 +0200
@@ -43,14 +43,14 @@
LteRadioBearerTag ();
/**
- * Create a LteRadioBearerTag with the given RNTI and LC id
+ * Create a LteRadioBearerTag with the given RNTI, M-RNTI and LC id
*/
- LteRadioBearerTag (uint16_t rnti, uint8_t lcId);
+ LteRadioBearerTag (uint16_t rnti, uint16_t mrnti, uint8_t lcId);
/**
- * Create a LteRadioBearerTag with the given RNTI, LC id and layer
+ * Create a LteRadioBearerTag with the given RNTI, M-RNTI, LC id and layer
*/
- LteRadioBearerTag (uint16_t rnti, uint8_t lcId, uint8_t layer);
+ LteRadioBearerTag (uint16_t rnti, uint16_t mrnti, uint8_t lcId, uint8_t layer);
/**
* Set the RNTI to the given value.
@@ -60,6 +60,13 @@
void SetRnti (uint16_t tid);
/**
+ * Set the MRNTI to the given value.
+ *
+ * @param mrnti the value of the M-RNTI to set
+ */
+ void SetMrnti (uint16_t tid);
+
+ /**
* Set the LC id to the given value.
*
* @param lcid the value of the RNTI to set
@@ -80,11 +87,13 @@
virtual void Print (std::ostream &os) const;
uint16_t GetRnti (void) const;
+ uint16_t GetMrnti (void) const;
uint8_t GetLcid (void) const;
uint8_t GetLayer (void) const;
private:
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint8_t m_lcid;
uint8_t m_layer;
--- a/src/lte/model/lte-rlc-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rlc-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -44,6 +44,7 @@
{
Ptr<Packet> pdcpPdu; /**< the PDCP PDU */
uint16_t rnti; /**< the C-RNTI identifying the UE */
+ uint16_t mrnti; /**<the M-RNTI identifying the MBMS traffic */
uint8_t lcid; /**< the logical channel id corresponding to the sending RLC instance */
};
--- a/src/lte/model/lte-rlc-um.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rlc-um.cc Thu Jun 13 11:32:13 2013 +0200
@@ -25,6 +25,7 @@
#include "ns3/lte-rlc-um.h"
#include "ns3/lte-rlc-sdu-status-tag.h"
#include "ns3/lte-rlc-tag.h"
+#include "ns3/lte-mrnti-tag.h"
NS_LOG_COMPONENT_DEFINE ("LteRlcUm");
@@ -83,7 +84,7 @@
void
LteRlcUm::DoTransmitPdcpPdu (Ptr<Packet> p)
{
- NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
+ NS_LOG_FUNCTION (this << m_rnti << m_mrnti << (uint32_t) m_lcid << p->GetSize ());
if (m_txBufferSize + p->GetSize () <= m_maxTxBufferSize)
{
@@ -378,9 +379,14 @@
LteMacSapProvider::TransmitPduParameters params;
params.pdu = packet;
params.rnti = m_rnti;
+ params.mrnti = m_mrnti;
params.lcid = m_lcid;
params.layer = layer;
params.harqProcessId = harqId;
+ //Aggiunta tag MRNTI
+ LteMrntiTag tagMrnti;
+ tagMrnti.SetMrnti (m_mrnti);
+ packet->AddPacketTag (tagMrnti);
m_macSapProvider->TransmitPdu (params);
@@ -1124,6 +1130,7 @@
LteMacSapProvider::ReportBufferStatusParameters r;
r.rnti = m_rnti;
+ r.mrnti = m_mrnti;
r.lcid = m_lcid;
r.txQueueSize = queueSize;
r.txQueueHolDelay = holDelay.GetMilliSeconds () ;
--- a/src/lte/model/lte-rlc.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rlc.cc Thu Jun 13 11:32:13 2013 +0200
@@ -87,6 +87,7 @@
: m_rlcSapUser (0),
m_macSapProvider (0),
m_rnti (0),
+ m_mrnti (0),
m_lcid (0)
{
NS_LOG_FUNCTION (this);
@@ -129,6 +130,13 @@
}
void
+LteRlc::SetMrnti(uint16_t mrnti)
+{
+ NS_LOG_FUNCTION(this << (uint32_t) mrnti);
+ m_mrnti = mrnti;
+}
+
+void
LteRlc::SetLcId (uint8_t lcId)
{
NS_LOG_FUNCTION (this << (uint32_t) lcId);
--- a/src/lte/model/lte-rlc.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rlc.h Thu Jun 13 11:32:13 2013 +0200
@@ -67,6 +67,13 @@
/**
*
*
+ * \param mrnti
+ */
+ void SetMrnti (uint16_t mrnti);
+
+ /**
+ *
+ *
* \param lcId
*/
void SetLcId (uint8_t lcId);
@@ -120,6 +127,7 @@
LteMacSapProvider* m_macSapProvider;
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint8_t m_lcid;
/**
--- a/src/lte/model/lte-rrc-protocol-ideal.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rrc-protocol-ideal.cc Thu Jun 13 11:32:13 2013 +0200
@@ -673,7 +673,35 @@
return msg;
}
-
+void
+LteEnbRrcProtocolIdeal::DoSendMbmsAreaConfiguration (LteRrcSap::RrcMbmsAreaConfiguration msg)
+{
+ NS_LOG_FUNCTION (this << m_cellId);
+ Ptr<LteUeRrc> ueRrc;
+ for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ int nDevs = node->GetNDevices ();
+ for (int j = 0; j < nDevs; ++j)
+ {
+ Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
+ if (ueDev != 0)
+ {
+ Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
+ NS_LOG_LOGIC ("considering UE IMSI " << ueDev->GetImsi () << " that has cellId " << ueRrc->GetCellId ());
+ if (ueRrc->GetCellId () == m_cellId)
+ {
+ NS_LOG_LOGIC ("sending MbmsAreaConfiguration to IMSI " << ueDev->GetImsi ());
+ ueRrc->GetLteUeRrcSapProvider ()->RecvMbmsAreaConfiguration (msg);
+ Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
+ &LteUeRrcSapProvider::RecvMbmsAreaConfiguration,
+ ueRrc->GetLteUeRrcSapProvider (),
+ msg);
+ }
+ }
+ }
+ }
+}
--- a/src/lte/model/lte-rrc-protocol-ideal.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rrc-protocol-ideal.h Thu Jun 13 11:32:13 2013 +0200
@@ -130,6 +130,7 @@
LteRrcSap::HandoverPreparationInfo DoDecodeHandoverPreparationInformation (Ptr<Packet> p);
Ptr<Packet> DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg);
LteRrcSap::RrcConnectionReconfiguration DoDecodeHandoverCommand (Ptr<Packet> p);
+ void DoSendMbmsAreaConfiguration (LteRrcSap::RrcMbmsAreaConfiguration);
uint16_t m_rnti;
--- a/src/lte/model/lte-rrc-protocol-real.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rrc-protocol-real.cc Thu Jun 13 11:32:13 2013 +0200
@@ -805,6 +805,11 @@
return msg;
}
+void
+LteEnbRrcProtocolReal::DoSendMbmsAreaConfiguration (LteRrcSap::RrcMbmsAreaConfiguration)
+{
+ //TO-DO
+}
//////////////////////////////////////////////////////
RealProtocolRlcSapUser::RealProtocolRlcSapUser (LteEnbRrcProtocolReal* pdcp, uint16_t rnti)
--- a/src/lte/model/lte-rrc-protocol-real.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rrc-protocol-real.h Thu Jun 13 11:32:13 2013 +0200
@@ -142,6 +142,7 @@
LteRrcSap::HandoverPreparationInfo DoDecodeHandoverPreparationInformation (Ptr<Packet> p);
Ptr<Packet> DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg);
LteRrcSap::RrcConnectionReconfiguration DoDecodeHandoverCommand (Ptr<Packet> p);
+ void DoSendMbmsAreaConfiguration (LteRrcSap::RrcMbmsAreaConfiguration msg);
void DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params);
void DoReceivePdcpPdu (uint16_t rnti, Ptr<Packet> p);
--- a/src/lte/model/lte-rrc-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-rrc-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -477,6 +477,16 @@
std::list<MeasResultEutra> measResultListEutra;
};
+ struct PmchInfoList
+ {
+ uint16_t mrnti; //delete in future
+ uint16_t sessionId;
+ uint8_t drbIdentity;
+ uint8_t logicalChannelIdentity;
+ RlcConfig rlcConfig;
+ LogicalChannelConfig logicalChannelConfig;
+ };
+
// Messages
struct RrcConnectionRequest
@@ -553,6 +563,11 @@
MeasResults measResults;
};
+ struct RrcMbmsAreaConfiguration
+ {
+ PmchInfoList pmchInfoList;
+ };
+
};
@@ -607,6 +622,7 @@
virtual void RecvRrcConnectionReestablishmentReject (RrcConnectionReestablishmentReject msg) = 0;
virtual void RecvRrcConnectionRelease (RrcConnectionRelease msg) = 0;
virtual void RecvRrcConnectionReject (RrcConnectionReject msg) = 0;
+ virtual void RecvMbmsAreaConfiguration (RrcMbmsAreaConfiguration msg) = 0;
};
@@ -640,6 +656,7 @@
virtual HandoverPreparationInfo DecodeHandoverPreparationInformation (Ptr<Packet> p) = 0;
virtual Ptr<Packet> EncodeHandoverCommand (RrcConnectionReconfiguration msg) = 0;
virtual RrcConnectionReconfiguration DecodeHandoverCommand (Ptr<Packet> p) = 0;
+ virtual void SendMbmsAreaConfiguration (RrcMbmsAreaConfiguration) = 0;
};
@@ -786,6 +803,7 @@
virtual void RecvRrcConnectionReestablishmentReject (RrcConnectionReestablishmentReject msg);
virtual void RecvRrcConnectionRelease (RrcConnectionRelease msg);
virtual void RecvRrcConnectionReject (RrcConnectionReject msg);
+ virtual void RecvMbmsAreaConfiguration (RrcMbmsAreaConfiguration msg);
private:
MemberLteUeRrcSapProvider ();
@@ -873,6 +891,13 @@
Simulator::ScheduleNow (&C::DoRecvRrcConnectionReject, m_owner, msg);
}
+template <class C>
+void
+MemberLteUeRrcSapProvider<C>::RecvMbmsAreaConfiguration (RrcMbmsAreaConfiguration msg)
+{
+ Simulator::ScheduleNow (&C::DoRecvMbmsAreaConfiguration, m_owner, msg);
+}
+
/**
* Template for the implementation of the LteEnbRrcSapUser as a member
@@ -902,6 +927,7 @@
virtual HandoverPreparationInfo DecodeHandoverPreparationInformation (Ptr<Packet> p);
virtual Ptr<Packet> EncodeHandoverCommand (RrcConnectionReconfiguration msg);
virtual RrcConnectionReconfiguration DecodeHandoverCommand (Ptr<Packet> p);
+ virtual void SendMbmsAreaConfiguration (RrcMbmsAreaConfiguration msg);
private:
MemberLteEnbRrcSapUser ();
@@ -1025,6 +1051,13 @@
return m_owner->DoDecodeHandoverCommand (p);
}
+template <class C>
+void
+MemberLteEnbRrcSapUser<C>::SendMbmsAreaConfiguration (RrcMbmsAreaConfiguration msg)
+{
+ m_owner->DoSendMbmsAreaConfiguration (msg);
+}
+
/**
* Template for the implementation of the LteEnbRrcSapProvider as a member
* of an owner class of type C to which all methods are forwarded
--- a/src/lte/model/lte-spectrum-phy.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-spectrum-phy.cc Thu Jun 13 11:32:13 2013 +0200
@@ -45,13 +45,13 @@
-// duration of SRS portion of UL subframe
+// duration of SRS portion of UL subframe
// = 1 symbol for SRS -1ns as margin to avoid overlapping simulator events
-static const Time UL_SRS_DURATION = NanoSeconds (71429 -1);
+static const Time UL_SRS_DURATION = NanoSeconds (71429 - 1);
// duration of the control portion of a subframe
// = 0.001 / 14 * 3 (ctrl fixed to 3 symbols) -1ns as margin to avoid overlapping simulator events
-static const Time DL_CTRL_DURATION = NanoSeconds (214286 -1);
+static const Time DL_CTRL_DURATION = NanoSeconds (214286 - 1);
double EffectiveCodingRate[29] = {
0.08,
@@ -87,14 +87,15 @@
-
+
TbId_t::TbId_t ()
{
}
-TbId_t::TbId_t (const uint16_t a, const uint8_t b)
-: m_rnti (a),
- m_layer (b)
+TbId_t::TbId_t (const uint16_t a, const uint16_t c, const uint8_t b)
+ : m_rnti (a),
+ m_mrnti (c),
+ m_layer (b)
{
}
@@ -114,8 +115,8 @@
LteSpectrumPhy::LteSpectrumPhy ()
: m_state (IDLE),
- m_transmissionMode (0),
- m_layersNum (1)
+ m_transmissionMode (0),
+ m_layersNum (1)
{
NS_LOG_FUNCTION (this);
m_random = CreateObject<UniformRandomVariable> ();
@@ -157,7 +158,7 @@
m_ltePhyUlHarqFeedbackCallback = MakeNullCallback< void, UlInfoListElement_s > ();
m_ltePhyRxPssCallback = MakeNullCallback< void, uint16_t, Ptr<SpectrumValue> > ();
SpectrumPhy::DoDispose ();
-}
+}
std::ostream& operator<< (std::ostream& os, LteSpectrumPhy::State s)
{
@@ -203,15 +204,15 @@
"Trace fired when a previosuly started RX terminates with an error",
MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxEndErrorTrace))
.AddAttribute ("DataErrorModelEnabled",
- "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) [by default is active].",
- BooleanValue (true),
+ "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) [by default is active].",
+ BooleanValue (true),
MakeBooleanAccessor (&LteSpectrumPhy::m_dataErrorModelEnabled),
- MakeBooleanChecker ())
+ MakeBooleanChecker ())
.AddAttribute ("CtrlErrorModelEnabled",
- "Activate/Deactivate the error model of control (PCFICH-PDCCH decodification) [by default is active].",
- BooleanValue (true),
- MakeBooleanAccessor (&LteSpectrumPhy::m_ctrlErrorModelEnabled),
- MakeBooleanChecker ())
+ "Activate/Deactivate the error model of control (PCFICH-PDCCH decodification) [by default is active].",
+ BooleanValue (true),
+ MakeBooleanAccessor (&LteSpectrumPhy::m_ctrlErrorModelEnabled),
+ MakeBooleanChecker ())
.AddTraceSource ("DlPhyReception",
"DL reception PHY layer statistics.",
MakeTraceSourceAccessor (&LteSpectrumPhy::m_dlPhyReception))
@@ -263,7 +264,7 @@
m_channel = c;
}
-Ptr<SpectrumChannel>
+Ptr<SpectrumChannel>
LteSpectrumPhy::GetChannel ()
{
return m_channel;
@@ -295,8 +296,8 @@
m_interferenceCtrl->SetNoisePowerSpectralDensity (noisePsd);
}
-
-void
+
+void
LteSpectrumPhy::Reset ()
{
NS_LOG_FUNCTION (this);
@@ -420,55 +421,55 @@
{
NS_LOG_FUNCTION (this << pb);
NS_LOG_LOGIC (this << " state: " << m_state);
-
+
m_phyTxStartTrace (pb);
-
+
switch (m_state)
- {
+ {
case RX_DATA:
case RX_CTRL:
NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
break;
-
+
case TX:
NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
break;
-
+
case IDLE:
- {
- /*
- m_txPsd must be setted by the device, according to
- (i) the available subchannel for transmission
- (ii) the power transmission
- */
- NS_ASSERT (m_txPsd);
- m_txPacketBurst = pb;
-
- // we need to convey some PHY meta information to the receiver
- // to be used for simulation purposes (e.g., the CellId). This
- // is done by setting the ctrlMsgList parameter of
- // LteSpectrumSignalParametersDataFrame
- ChangeState (TX);
- NS_ASSERT (m_channel);
- Ptr<LteSpectrumSignalParametersDataFrame> txParams = Create<LteSpectrumSignalParametersDataFrame> ();
- txParams->duration = duration;
- txParams->txPhy = GetObject<SpectrumPhy> ();
- txParams->txAntenna = m_antenna;
- txParams->psd = m_txPsd;
- txParams->packetBurst = pb;
- txParams->ctrlMsgList = ctrlMsgList;
- txParams->cellId = m_cellId;
- m_channel->StartTx (txParams);
- m_endTxEvent = Simulator::Schedule (duration, &LteSpectrumPhy::EndTx, this);
- }
- return false;
- break;
-
+ {
+ /*
+ m_txPsd must be setted by the device, according to
+ (i) the available subchannel for transmission
+ (ii) the power transmission
+ */
+ NS_ASSERT (m_txPsd);
+ m_txPacketBurst = pb;
+
+ // we need to convey some PHY meta information to the receiver
+ // to be used for simulation purposes (e.g., the CellId). This
+ // is done by setting the ctrlMsgList parameter of
+ // LteSpectrumSignalParametersDataFrame
+ ChangeState (TX);
+ NS_ASSERT (m_channel);
+ Ptr<LteSpectrumSignalParametersDataFrame> txParams = Create<LteSpectrumSignalParametersDataFrame> ();
+ txParams->duration = duration;
+ txParams->txPhy = GetObject<SpectrumPhy> ();
+ txParams->txAntenna = m_antenna;
+ txParams->psd = m_txPsd;
+ txParams->packetBurst = pb;
+ txParams->ctrlMsgList = ctrlMsgList;
+ txParams->cellId = m_cellId;
+ m_channel->StartTx (txParams);
+ m_endTxEvent = Simulator::Schedule (duration, &LteSpectrumPhy::EndTx, this);
+ }
+ return false;
+ break;
+
default:
NS_FATAL_ERROR ("unknown state");
return true;
break;
- }
+ }
}
bool
@@ -476,56 +477,56 @@
{
NS_LOG_FUNCTION (this << " PSS " << (uint16_t)pss);
NS_LOG_LOGIC (this << " state: " << m_state);
-
-
+
+
// m_phyTxStartTrace (pb);
-
+
switch (m_state)
- {
+ {
case RX_DATA:
case RX_CTRL:
NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
break;
-
+
case TX:
NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
break;
-
+
case IDLE:
- {
- /*
- m_txPsd must be setted by the device, according to
- (i) the available subchannel for transmission
- (ii) the power transmission
- */
- NS_ASSERT (m_txPsd);
-
- // we need to convey some PHY meta information to the receiver
- // to be used for simulation purposes (e.g., the CellId). This
- // is done by setting the cellId parameter of
- // LteSpectrumSignalParametersDlCtrlFrame
- ChangeState (TX);
- NS_ASSERT (m_channel);
+ {
+ /*
+ m_txPsd must be setted by the device, according to
+ (i) the available subchannel for transmission
+ (ii) the power transmission
+ */
+ NS_ASSERT (m_txPsd);
+
+ // we need to convey some PHY meta information to the receiver
+ // to be used for simulation purposes (e.g., the CellId). This
+ // is done by setting the cellId parameter of
+ // LteSpectrumSignalParametersDlCtrlFrame
+ ChangeState (TX);
+ NS_ASSERT (m_channel);
- Ptr<LteSpectrumSignalParametersDlCtrlFrame> txParams = Create<LteSpectrumSignalParametersDlCtrlFrame> ();
- txParams->duration = DL_CTRL_DURATION;
- txParams->txPhy = GetObject<SpectrumPhy> ();
- txParams->txAntenna = m_antenna;
- txParams->psd = m_txPsd;
- txParams->cellId = m_cellId;
- txParams->pss = pss;
- txParams->ctrlMsgList = ctrlMsgList;
- m_channel->StartTx (txParams);
- m_endTxEvent = Simulator::Schedule (DL_CTRL_DURATION, &LteSpectrumPhy::EndTx, this);
- }
- return false;
- break;
-
+ Ptr<LteSpectrumSignalParametersDlCtrlFrame> txParams = Create<LteSpectrumSignalParametersDlCtrlFrame> ();
+ txParams->duration = DL_CTRL_DURATION;
+ txParams->txPhy = GetObject<SpectrumPhy> ();
+ txParams->txAntenna = m_antenna;
+ txParams->psd = m_txPsd;
+ txParams->cellId = m_cellId;
+ txParams->pss = pss;
+ txParams->ctrlMsgList = ctrlMsgList;
+ m_channel->StartTx (txParams);
+ m_endTxEvent = Simulator::Schedule (DL_CTRL_DURATION, &LteSpectrumPhy::EndTx, this);
+ }
+ return false;
+ break;
+
default:
NS_FATAL_ERROR ("unknown state");
return true;
break;
- }
+ }
}
@@ -534,53 +535,53 @@
{
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC (this << " state: " << m_state);
-
+
// m_phyTxStartTrace (pb);
-
+
switch (m_state)
- {
+ {
case RX_DATA:
case RX_CTRL:
NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
break;
-
+
case TX:
NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
break;
-
+
case IDLE:
- {
- /*
- m_txPsd must be setted by the device, according to
- (i) the available subchannel for transmission
- (ii) the power transmission
- */
- NS_ASSERT (m_txPsd);
- NS_LOG_LOGIC (this << " m_txPsd: " << *m_txPsd);
-
- // we need to convey some PHY meta information to the receiver
- // to be used for simulation purposes (e.g., the CellId). This
- // is done by setting the cellId parameter of
- // LteSpectrumSignalParametersDlCtrlFrame
- ChangeState (TX);
- NS_ASSERT (m_channel);
- Ptr<LteSpectrumSignalParametersUlSrsFrame> txParams = Create<LteSpectrumSignalParametersUlSrsFrame> ();
- txParams->duration = UL_SRS_DURATION;
- txParams->txPhy = GetObject<SpectrumPhy> ();
- txParams->txAntenna = m_antenna;
- txParams->psd = m_txPsd;
- txParams->cellId = m_cellId;
- m_channel->StartTx (txParams);
- m_endTxEvent = Simulator::Schedule (UL_SRS_DURATION, &LteSpectrumPhy::EndTx, this);
- }
- return false;
- break;
-
+ {
+ /*
+ m_txPsd must be setted by the device, according to
+ (i) the available subchannel for transmission
+ (ii) the power transmission
+ */
+ NS_ASSERT (m_txPsd);
+ NS_LOG_LOGIC (this << " m_txPsd: " << *m_txPsd);
+
+ // we need to convey some PHY meta information to the receiver
+ // to be used for simulation purposes (e.g., the CellId). This
+ // is done by setting the cellId parameter of
+ // LteSpectrumSignalParametersDlCtrlFrame
+ ChangeState (TX);
+ NS_ASSERT (m_channel);
+ Ptr<LteSpectrumSignalParametersUlSrsFrame> txParams = Create<LteSpectrumSignalParametersUlSrsFrame> ();
+ txParams->duration = UL_SRS_DURATION;
+ txParams->txPhy = GetObject<SpectrumPhy> ();
+ txParams->txAntenna = m_antenna;
+ txParams->psd = m_txPsd;
+ txParams->cellId = m_cellId;
+ m_channel->StartTx (txParams);
+ m_endTxEvent = Simulator::Schedule (UL_SRS_DURATION, &LteSpectrumPhy::EndTx, this);
+ }
+ return false;
+ break;
+
default:
NS_FATAL_ERROR ("unknown state");
return true;
break;
- }
+ }
}
@@ -615,10 +616,10 @@
{
NS_LOG_FUNCTION (this << spectrumRxParams);
NS_LOG_LOGIC (this << " state: " << m_state);
-
+
Ptr <const SpectrumValue> rxPsd = spectrumRxParams->psd;
Time duration = spectrumRxParams->duration;
-
+
// the device might start RX only if the signal is of a type
// understood by this device - in this case, an LTE signal.
Ptr<LteSpectrumSignalParametersDataFrame> lteDataRxParams = DynamicCast<LteSpectrumSignalParametersDataFrame> (spectrumRxParams);
@@ -631,7 +632,7 @@
{
Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (spectrumRxParams);
Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (spectrumRxParams);
- if ((lteDlCtrlRxParams!=0)||(lteUlSrsRxParams!=0))
+ if ((lteDlCtrlRxParams != 0)||(lteUlSrsRxParams != 0))
{
m_interferenceCtrl->AddSignal (rxPsd, duration);
StartRxCtrl (spectrumRxParams);
@@ -652,72 +653,72 @@
NS_LOG_FUNCTION (this);
switch (m_state)
{
- case TX:
- NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
- break;
- case RX_CTRL:
- NS_FATAL_ERROR ("cannot RX Data while receiving control");
- break;
- case IDLE:
- case RX_DATA:
- // the behavior is similar when
- // we're IDLE or RX because we can receive more signals
- // simultaneously (e.g., at the eNB).
- {
- // To check if we're synchronized to this signal, we check
- // for the CellId which is reported in the
- // LteSpectrumSignalParametersDataFrame
- if (params->cellId == m_cellId)
- {
- NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << params->cellId << ")");
- if ((m_rxPacketBurstList.empty ())&&(m_rxControlMessageList.empty ()))
- {
- NS_ASSERT (m_state == IDLE);
- // first transmission, i.e., we're IDLE and we
- // start RX
- m_firstRxStart = Simulator::Now ();
- m_firstRxDuration = params->duration;
- NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration.GetSeconds () << "s");
- m_endRxDataEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxData, this);
- }
- else
- {
- NS_ASSERT (m_state == RX_DATA);
- // sanity check: if there are multiple RX events, they
- // should occur at the same time and have the same
- // duration, otherwise the interference calculation
- // won't be correct
- NS_ASSERT ((m_firstRxStart == Simulator::Now ())
- && (m_firstRxDuration == params->duration));
- }
-
- ChangeState (RX_DATA);
- if (params->packetBurst)
- {
- m_rxPacketBurstList.push_back (params->packetBurst);
- m_interferenceData->StartRx (params->psd);
-
- m_phyRxStartTrace (params->packetBurst);
- }
- NS_LOG_DEBUG (this << " insert msgs " << params->ctrlMsgList.size ());
- m_rxControlMessageList.insert (m_rxControlMessageList.end (), params->ctrlMsgList.begin (), params->ctrlMsgList.end ());
-
- NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
- }
- else
- {
- NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
- << params->cellId << ", m_cellId=" << m_cellId << ")");
- }
- }
- break;
-
- default:
- NS_FATAL_ERROR ("unknown state");
- break;
+ case TX:
+ NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
+ break;
+ case RX_CTRL:
+ NS_FATAL_ERROR ("cannot RX Data while receiving control");
+ break;
+ case IDLE:
+ case RX_DATA:
+ // the behavior is similar when
+ // we're IDLE or RX because we can receive more signals
+ // simultaneously (e.g., at the eNB).
+ {
+ // To check if we're synchronized to this signal, we check
+ // for the CellId which is reported in the
+ // LteSpectrumSignalParametersDataFrame
+ if (params->cellId == m_cellId)
+ {
+ NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << params->cellId << ")");
+ if ((m_rxPacketBurstList.empty ())&&(m_rxControlMessageList.empty ()))
+ {
+ NS_ASSERT (m_state == IDLE);
+ // first transmission, i.e., we're IDLE and we
+ // start RX
+ m_firstRxStart = Simulator::Now ();
+ m_firstRxDuration = params->duration;
+ NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration.GetSeconds () << "s");
+ m_endRxDataEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxData, this);
+ }
+ else
+ {
+ NS_ASSERT (m_state == RX_DATA);
+ // sanity check: if there are multiple RX events, they
+ // should occur at the same time and have the same
+ // duration, otherwise the interference calculation
+ // won't be correct
+ NS_ASSERT ((m_firstRxStart == Simulator::Now ())
+ && (m_firstRxDuration == params->duration));
+ }
+
+ ChangeState (RX_DATA);
+ if (params->packetBurst)
+ {
+ m_rxPacketBurstList.push_back (params->packetBurst);
+ m_interferenceData->StartRx (params->psd);
+
+ m_phyRxStartTrace (params->packetBurst);
+ }
+ NS_LOG_DEBUG (this << " insert msgs " << params->ctrlMsgList.size ());
+ m_rxControlMessageList.insert (m_rxControlMessageList.end (), params->ctrlMsgList.begin (), params->ctrlMsgList.end ());
+
+ NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
+ }
+ else
+ {
+ NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
+ << params->cellId << ", m_cellId=" << m_cellId << ")");
+ }
}
-
- NS_LOG_LOGIC (this << " state: " << m_state);
+ break;
+
+ default:
+ NS_FATAL_ERROR ("unknown state");
+ break;
+ }
+
+ NS_LOG_LOGIC (this << " state: " << m_state);
}
@@ -727,7 +728,7 @@
{
NS_LOG_FUNCTION (this);
switch (m_state)
- {
+ {
case TX:
NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
break;
@@ -746,7 +747,7 @@
uint16_t cellId;
bool dl;
Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (params);
- if (lteDlCtrlRxParams!=0)
+ if (lteDlCtrlRxParams != 0)
{
cellId = lteDlCtrlRxParams->cellId;
dl = true;
@@ -758,67 +759,67 @@
dl = false;
}
if (dl)
- {
- // check presence of PSS for UE measuerements
- if (lteDlCtrlRxParams->pss == true)
- {
- SpectrumValue pssPsd = *params->psd;
- if (!m_ltePhyRxPssCallback.IsNull ())
- {
- m_ltePhyRxPssCallback (cellId, params->psd);
- }
- }
- }
- if (cellId == m_cellId)
- {
- NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
- if (m_state == IDLE)
{
- // first transmission, i.e., we're IDLE and we
- // start RX
- NS_ASSERT (m_rxControlMessageList.empty ());
- m_firstRxStart = Simulator::Now ();
- m_firstRxDuration = params->duration;
- NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration);
- if (dl==true)
+ // check presence of PSS for UE measuerements
+ if (lteDlCtrlRxParams->pss == true)
{
- // store the DCIs
- m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
- m_endRxDlCtrlEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxDlCtrl, this);
- }
- else
- {
- m_endRxUlSrsEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxUlSrs, this);
+ SpectrumValue pssPsd = *params->psd;
+ if (!m_ltePhyRxPssCallback.IsNull ())
+ {
+ m_ltePhyRxPssCallback (cellId, params->psd);
+ }
}
}
- else if (m_state == RX_CTRL)
+ if (cellId == m_cellId)
{
- // sanity check: if there are multiple RX events, they
- // should occur at the same time and have the same
- // duration, otherwise the interference calculation
- // won't be correct
- NS_ASSERT ((m_firstRxStart == Simulator::Now ())
- && (m_firstRxDuration == params->duration));
+ NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
+ if (m_state == IDLE)
+ {
+ // first transmission, i.e., we're IDLE and we
+ // start RX
+ NS_ASSERT (m_rxControlMessageList.empty ());
+ m_firstRxStart = Simulator::Now ();
+ m_firstRxDuration = params->duration;
+ NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration);
+ if (dl == true)
+ {
+ // store the DCIs
+ m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
+ m_endRxDlCtrlEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxDlCtrl, this);
+ }
+ else
+ {
+ m_endRxUlSrsEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxUlSrs, this);
+ }
+ }
+ else if (m_state == RX_CTRL)
+ {
+ // sanity check: if there are multiple RX events, they
+ // should occur at the same time and have the same
+ // duration, otherwise the interference calculation
+ // won't be correct
+ NS_ASSERT ((m_firstRxStart == Simulator::Now ())
+ && (m_firstRxDuration == params->duration));
+ }
+
+ ChangeState (RX_CTRL);
+ m_interferenceCtrl->StartRx (params->psd);
+
+// NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
}
-
- ChangeState (RX_CTRL);
- m_interferenceCtrl->StartRx (params->psd);
-
-// NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
- }
else
- {
- NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
- << cellId << ", m_cellId=" << m_cellId << ")");
- }
+ {
+ NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
+ << cellId << ", m_cellId=" << m_cellId << ")");
+ }
}
break;
-
- default:
- NS_FATAL_ERROR ("unknown state");
- break;
- }
-
+
+ default:
+ NS_FATAL_ERROR ("unknown state");
+ break;
+ }
+
NS_LOG_LOGIC (this << " state: " << m_state);
}
@@ -832,11 +833,12 @@
void
-LteSpectrumPhy::AddExpectedTb (uint16_t rnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer, uint8_t harqId,uint8_t rv, bool downlink)
+LteSpectrumPhy::AddExpectedTb (uint16_t rnti, uint16_t mrnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer, uint8_t harqId,uint8_t rv, bool downlink)
{
- NS_LOG_FUNCTION (this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv " << (uint16_t)rv);
+ NS_LOG_FUNCTION (this << " rnti: " << rnti << " mrnti: " << mrnti << " NDI " << (uint16_t)ndi << " size " << size << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv " << (uint16_t)rv);
TbId_t tbId;
tbId.m_rnti = rnti;
+ tbId.m_mrnti = mrnti;
tbId.m_layer = layer;
expectedTbs_t::iterator it;
it = m_expectedTbs.find (tbId);
@@ -865,15 +867,15 @@
NS_LOG_DEBUG (this << " No. of burts " << m_rxPacketBurstList.size ());
NS_LOG_DEBUG (this << " Expected TBs " << m_expectedTbs.size ());
expectedTbs_t::iterator itTb = m_expectedTbs.begin ();
-
+
// apply transmission mode gain
NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
-
- while (itTb!=m_expectedTbs.end ())
+
+ while (itTb != m_expectedTbs.end ())
{
- if ((m_dataErrorModelEnabled)&&(m_rxPacketBurstList.size ()>0)) // avoid to check for errors when there is no actual data transmitted
+ if ((m_dataErrorModelEnabled)&&(m_rxPacketBurstList.size () > 0)) // avoid to check for errors when there is no actual data transmitted
{
// retrieve HARQ info
HarqProcessInfoList_t harqInfoList;
@@ -906,7 +908,7 @@
params.m_size = (*itTb).second.size;
params.m_rv = (*itTb).second.rv;
params.m_ndi = (*itTb).second.ndi;
- params.m_correctness = (uint8_t)!(*itTb).second.corrupt;
+ params.m_correctness = (uint8_t) !(*itTb).second.corrupt;
if ((*itTb).second.downlink)
{
// DL
@@ -918,112 +920,140 @@
params.m_rv = harqInfoList.size ();
m_ulPhyReception (params);
}
- }
-
+ }
+
itTb++;
}
- std::map <uint16_t, DlInfoListElement_s> harqDlInfoMap;
- for (std::list<Ptr<PacketBurst> >::const_iterator i = m_rxPacketBurstList.begin ();
- i != m_rxPacketBurstList.end (); ++i)
- {
- for (std::list<Ptr<Packet> >::const_iterator j = (*i)->Begin (); j != (*i)->End (); ++j)
- {
- // retrieve TB info of this packet
- LteRadioBearerTag tag;
- (*j)->PeekPacketTag (tag);
- TbId_t tbId;
- tbId.m_rnti = tag.GetRnti ();
- tbId.m_layer = tag.GetLayer ();
- itTb = m_expectedTbs.find (tbId);
- NS_LOG_INFO (this << " Packet of " << tbId.m_rnti << " layer " << (uint16_t) tag.GetLayer ());
- if (itTb!=m_expectedTbs.end ())
- {
- if (!(*itTb).second.corrupt)
- {
- m_phyRxEndOkTrace (*j);
-
- if (!m_ltePhyRxDataEndOkCallback.IsNull ())
- {
- m_ltePhyRxDataEndOkCallback (*j);
- }
- }
- else
- {
- // TB received with errors
- m_phyRxEndErrorTrace (*j);
- }
+ std::map <uint16_t, DlInfoListElement_s> harqDlInfoMap;
+ for (std::list<Ptr<PacketBurst> >::const_iterator i = m_rxPacketBurstList.begin ();
+ i != m_rxPacketBurstList.end (); ++i)
+ {
+ for (std::list<Ptr<Packet> >::const_iterator j = (*i)->Begin (); j != (*i)->End (); ++j)
+ {
+ // retrieve TB info of this packet
+ LteRadioBearerTag tag;
+ (*j)->PeekPacketTag (tag);
+ TbId_t tbId;
+ tbId.m_rnti = tag.GetRnti ();
+ tbId.m_mrnti = tag.GetMrnti ();
+ tbId.m_layer = tag.GetLayer ();
+ itTb = m_expectedTbs.find (tbId);
+ NS_LOG_INFO (this << " Packet of " << tbId.m_rnti << " layer " << (uint16_t) tag.GetLayer ());
+
+ if (tag.GetMrnti () != 0) //Controllo se pacchetto multicast
+ {
+
+ if (itTb != m_expectedTbs.end ())
+ {
+ if (!(*itTb).second.corrupt)
+ {
+
+ m_phyRxEndOkTrace (*j);
- // send HARQ feedback (if not already done for this TB)
- if (!(*itTb).second.harqFeedbackSent)
- {
- (*itTb).second.harqFeedbackSent = true;
- if (!(*itTb).second.downlink)
- {
- UlInfoListElement_s harqUlInfo;
- harqUlInfo.m_rnti = tbId.m_rnti;
- harqUlInfo.m_tpc = 0;
- if ((*itTb).second.corrupt)
- {
- harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
- NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
- m_harqPhyModule->UpdateUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
- }
- else
- {
- harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
- NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
- m_harqPhyModule->ResetUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.harqProcessId);
- }
+ if (!m_ltePhyRxDataEndOkCallback.IsNull ())
+ {
+ m_ltePhyRxDataEndOkCallback (*j);
+ }
+ }
+ else
+ {
+ // TB received with errors
+ m_phyRxEndErrorTrace (*j);
+ }
+ }
+ }
+ else if (tag.GetRnti () != 0) //Gestione traffico unicast
+ {
+
+ if (itTb != m_expectedTbs.end ())
+ {
+ if (!(*itTb).second.corrupt)
+ {
+ m_phyRxEndOkTrace (*j);
+
+ if (!m_ltePhyRxDataEndOkCallback.IsNull ())
+ {
+ m_ltePhyRxDataEndOkCallback (*j);
+ }
+ }
+ else
+ {
+ // TB received with errors
+ m_phyRxEndErrorTrace (*j);
+ }
+
+ // send HARQ feedback (if not already done for this TB)
+ if (!(*itTb).second.harqFeedbackSent)
+ {
+ (*itTb).second.harqFeedbackSent = true;
+ if (!(*itTb).second.downlink)
+ {
+ UlInfoListElement_s harqUlInfo;
+ harqUlInfo.m_rnti = tbId.m_rnti;
+ harqUlInfo.m_tpc = 0;
+ if ((*itTb).second.corrupt)
+ {
+ harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
+ NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
+ m_harqPhyModule->UpdateUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
+ }
+ else
+ {
+ harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
+ NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
+ m_harqPhyModule->ResetUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.harqProcessId);
+ }
if (!m_ltePhyUlHarqFeedbackCallback.IsNull ())
{
m_ltePhyUlHarqFeedbackCallback (harqUlInfo);
}
- }
- else
- {
- std::map <uint16_t, DlInfoListElement_s>::iterator itHarq = harqDlInfoMap.find (tbId.m_rnti);
- if (itHarq==harqDlInfoMap.end ())
- {
- DlInfoListElement_s harqDlInfo;
- harqDlInfo.m_harqStatus.resize (m_layersNum, DlInfoListElement_s::NACK);
- harqDlInfo.m_rnti = tbId.m_rnti;
- harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
- if ((*itTb).second.corrupt)
- {
- harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
- NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " <<(uint16_t)tbId.m_layer << " send DL-HARQ-NACK");
- m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
- }
- else
- {
+ }
+ else
+ {
+ std::map <uint16_t, DlInfoListElement_s>::iterator itHarq = harqDlInfoMap.find (tbId.m_rnti);
+ if (itHarq == harqDlInfoMap.end ())
+ {
+ DlInfoListElement_s harqDlInfo;
+ harqDlInfo.m_harqStatus.resize (m_layersNum, DlInfoListElement_s::NACK);
+ harqDlInfo.m_rnti = tbId.m_rnti;
+ harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
+ if ((*itTb).second.corrupt)
+ {
+ harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
+ NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " send DL-HARQ-NACK");
+ m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
+ }
+ else
+ {
- harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
- NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " <<(uint16_t)tbId.m_layer << " size " << (*itTb).second.size << " send DL-HARQ-ACK");
- m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
- }
- harqDlInfoMap.insert (std::pair <uint16_t, DlInfoListElement_s> (tbId.m_rnti, harqDlInfo));
- }
- else
- {
- if ((*itTb).second.corrupt)
- {
- (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
- NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " <<(uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-NACK");
- m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
+ harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
+ NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itTb).second.size << " send DL-HARQ-ACK");
+ m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
+ }
+ harqDlInfoMap.insert (std::pair <uint16_t, DlInfoListElement_s> (tbId.m_rnti, harqDlInfo));
}
else
{
- NS_ASSERT_MSG (tbId.m_layer < (*itHarq).second.m_harqStatus.size (), " layer " << (uint16_t)tbId.m_layer);
- (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
- NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-ACK");
- m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
+ if ((*itTb).second.corrupt)
+ {
+ (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
+ NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-NACK");
+ m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
+ }
+ else
+ {
+ NS_ASSERT_MSG (tbId.m_layer < (*itHarq).second.m_harqStatus.size (), " layer " << (uint16_t)tbId.m_layer);
+ (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
+ NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-ACK");
+ m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
+ }
}
- }
- } // end if ((*itTb).second.downlink) HARQ
- } // end if (!(*itTb).second.harqFeedbackSent)
- }
- }
- }
+ } // end if ((*itTb).second.downlink) HARQ
+ } // end if (!(*itTb).second.harqFeedbackSent)
+ }
+ }
+ }
+ }
// send DL HARQ feedback to LtePhy
std::map <uint16_t, DlInfoListElement_s>::iterator itHarq;
@@ -1054,16 +1084,16 @@
{
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC (this << " state: " << m_state);
-
+
NS_ASSERT (m_state == RX_CTRL);
-
+
// this will trigger CQI calculation and Error Model evaluation
// as a side effect, the error model should update the error status of all TBs
m_interferenceCtrl->EndRx ();
// apply transmission mode gain
NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
- if (m_transmissionMode>0)
+ if (m_transmissionMode > 0)
{
// in case of MIMO, ctrl is always txed as TX diversity
m_sinrPerceived *= m_txModeGain.at (1);
@@ -1107,7 +1137,7 @@
// nothing to do (used only for SRS at this stage)
}
-void
+void
LteSpectrumPhy::SetCellId (uint16_t cellId)
{
m_cellId = cellId;
@@ -1145,7 +1175,7 @@
m_interferenceCtrl->AddSinrChunkProcessor (p);
}
-void
+void
LteSpectrumPhy::SetTransmissionMode (uint8_t txMode)
{
NS_LOG_FUNCTION (this << (uint16_t) txMode);
@@ -1155,30 +1185,30 @@
}
-void
+void
LteSpectrumPhy::SetTxModeGain (uint8_t txMode, double gain)
{
NS_LOG_FUNCTION (this << " txmode " << (uint16_t)txMode << " gain " << gain);
// convert to linear
gain = std::pow (10.0, (gain / 10.0));
if (m_txModeGain.size () < txMode)
- {
- m_txModeGain.resize (txMode);
- }
+ {
+ m_txModeGain.resize (txMode);
+ }
std::vector <double> temp;
temp = m_txModeGain;
m_txModeGain.clear ();
for (uint8_t i = 0; i < temp.size (); i++)
- {
- if (i==txMode-1)
{
- m_txModeGain.push_back (gain);
+ if (i == txMode - 1)
+ {
+ m_txModeGain.push_back (gain);
+ }
+ else
+ {
+ m_txModeGain.push_back (temp.at (i));
+ }
}
- else
- {
- m_txModeGain.push_back (temp.at (i));
- }
- }
}
int64_t
--- a/src/lte/model/lte-spectrum-phy.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-spectrum-phy.h Thu Jun 13 11:32:13 2013 +0200
@@ -47,11 +47,12 @@
struct TbId_t
{
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint8_t m_layer;
public:
TbId_t ();
- TbId_t (const uint16_t a, const uint8_t b);
+ TbId_t (const uint16_t a, const uint16_t c, const uint8_t b);
friend bool operator == (const TbId_t &a, const TbId_t &b);
friend bool operator < (const TbId_t &a, const TbId_t &b);
@@ -377,7 +378,7 @@
* \param harqId the id of the HARQ process (valid only for DL)
* \param downlink true when the TB is for DL
*/
- void AddExpectedTb (uint16_t rnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer, uint8_t harqId, uint8_t rv, bool downlink);
+ void AddExpectedTb (uint16_t rnti, uint16_t mrnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer, uint8_t harqId, uint8_t rv, bool downlink);
/**
--- a/src/lte/model/lte-ue-cmac-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-cmac-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -48,23 +48,23 @@
uint8_t preambleTransMax;
uint8_t raResponseWindowSize;
};
-
+
virtual void ConfigureRach (RachConfig rc) = 0;
- /**
+ /**
* tell the MAC to start a contention-based random access procedure,
- * e.g., to perform RRC connection establishment
- *
+ * e.g., to perform RRC connection establishment
+ *
*/
virtual void StartContentionBasedRandomAccessProcedure () = 0;
- /**
+ /**
* tell the MAC to start a non-contention-based random access
* procedure, e.g., as a consequence of handover
- *
+ *
* \param rnti
* \param rapId Random Access Preamble Identifier
- * \param prachMask
+ * \param prachMask
*/
virtual void StartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t rapId, uint8_t prachMask) = 0;
@@ -76,29 +76,35 @@
uint16_t bucketSizeDurationMs;
uint8_t logicalChannelGroup;
};
-
- /**
- * add a new Logical Channel (LC)
- *
+
+ /**
+ * add a new Logical Channel (LC)
+ *
* \param lcId the ID of the LC
* \param lcConfig the LC configuration provided by the RRC
* \param msu the corresponding LteMacSapUser
*/
virtual void AddLc (uint8_t lcId, LogicalChannelConfig lcConfig, LteMacSapUser* msu) = 0;
- /**
+ /**
+ * add M-RNTI (temporary solution)
+ * \param mrnti
+ */
+ virtual void SetMrnti (uint16_t mrnti) = 0;
+
+ /**
* remove an existing LC
- *
- * \param lcId
+ *
+ * \param lcId
*/
virtual void RemoveLc (uint8_t lcId) = 0;
- /**
+ /**
* reset the MAC
- *
+ *
*/
virtual void Reset () = 0;
-
+
};
@@ -111,25 +117,24 @@
class LteUeCmacSapUser
{
public:
-
virtual ~LteUeCmacSapUser ();
- /**
- *
- *
+ /**
+ *
+ *
* \param rnti the T-C-RNTI, which will eventually become the C-RNTI after contention resolution
*/
virtual void SetTemporaryCellRnti (uint16_t rnti) = 0;
- /**
+ /**
* Notify the RRC that the MAC Random Access procedure completed successfully
- *
+ *
*/
virtual void NotifyRandomAccessSuccessful () = 0;
- /**
+ /**
* Notify the RRC that the MAC Random Access procedure failed
- *
+ *
*/
virtual void NotifyRandomAccessFailed () = 0;
};
--- a/src/lte/model/lte-ue-cphy-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-cphy-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -41,45 +41,51 @@
class LteUeCphySapProvider
{
public:
-
- /**
+ /**
* destructor
*/
virtual ~LteUeCphySapProvider ();
- /**
+ /**
* reset the PHY
- *
+ *
*/
virtual void Reset () = 0;
- /**
+ /**
* tell the PHY to synchronize with a given eNB for communication purposes
- *
+ *
* \param cellId the ID of the eNB
* \param dlEarfcn the carrier frequency (EARFCN) in downlink
*/
virtual void SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn) = 0;
-
+
/**
* \param dlBandwidth the DL bandwidth in PRBs
*/
virtual void SetDlBandwidth (uint8_t dlBandwidth) = 0;
- /**
+ /**
* Configure uplink (normally done after reception of SIB2)
- *
+ *
* \param ulEarfcn the carrier frequency (EARFCN) in uplink
* \param ulBandwidth the UL bandwidth in PRBs
*/
virtual void ConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth) = 0;
- /**
- *
+ /**
+ *
* \param rnti the cell-specific UE identifier
*/
virtual void SetRnti (uint16_t rnti) = 0;
+
+ /**
+ *
+ * \param mrnti the MRNTi of MBMS traffic
+ */
+ virtual void SetMrnti (uint16_t mrnti) = 0;
+
/**
* \param txMode the transmissionMode of the user
*/
@@ -102,31 +108,30 @@
class LteUeCphySapUser
{
public:
-
- /**
+ /**
* destructor
*/
virtual ~LteUeCphySapUser ();
-
+
/**
* Parameters of the ReportUeMeasurements primitive: RSRP [dBm] and RSRQ [dB]
* See section 5.1.1 and 5.1.3 of TS 36.214
*/
struct UeMeasurementsElement
- {
- uint16_t m_cellId;
- double m_rsrp; // [dBm]
- double m_rsrq; // [dB]
- };
+ {
+ uint16_t m_cellId;
+ double m_rsrp; // [dBm]
+ double m_rsrq; // [dB]
+ };
struct UeMeasurementsParameters
- {
- std::vector <struct UeMeasurementsElement> m_ueMeasurementsList;
- };
+ {
+ std::vector <struct UeMeasurementsElement> m_ueMeasurementsList;
+ };
- /**
- *
+ /**
+ *
* \param mib the Master Information Block received on the BCH
*/
virtual void RecvMasterInformationBlock (LteRrcSap::MasterInformationBlock mib) = 0;
@@ -144,7 +149,7 @@
/**
* Template for the implementation of the LteUeCphySapProvider as a member
* of an owner class of type C to which all methods are forwarded
- *
+ *
*/
template <class C>
class MemberLteUeCphySapProvider : public LteUeCphySapProvider
@@ -154,10 +159,11 @@
// inherited from LteUeCphySapProvider
virtual void Reset ();
- virtual void SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
+ virtual void SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
virtual void SetDlBandwidth (uint8_t ulBandwidth);
virtual void ConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth);
virtual void SetRnti (uint16_t rnti);
+ virtual void SetMrnti (uint16_t mrnti);
virtual void SetTransmissionMode (uint8_t txMode);
virtual void SetSrsConfigurationIndex (uint16_t srcCi);
@@ -178,49 +184,56 @@
}
template <class C>
-void
+void
MemberLteUeCphySapProvider<C>::Reset ()
{
m_owner->DoReset ();
}
template <class C>
-void
+void
MemberLteUeCphySapProvider<C>::SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn)
{
m_owner->DoSyncronizeWithEnb (cellId, dlEarfcn);
}
template <class C>
-void
+void
MemberLteUeCphySapProvider<C>::SetDlBandwidth (uint8_t dlBandwidth)
{
m_owner->DoSetDlBandwidth (dlBandwidth);
}
template <class C>
-void
+void
MemberLteUeCphySapProvider<C>::ConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth)
{
m_owner->DoConfigureUplink (ulEarfcn, ulBandwidth);
}
template <class C>
-void
+void
MemberLteUeCphySapProvider<C>::SetRnti (uint16_t rnti)
{
m_owner->DoSetRnti (rnti);
}
template <class C>
-void
+void
+MemberLteUeCphySapProvider<C>::SetMrnti (uint16_t mrnti)
+{
+ m_owner->DoSetMrnti (mrnti);
+}
+
+template <class C>
+void
MemberLteUeCphySapProvider<C>::SetTransmissionMode (uint8_t txMode)
{
m_owner->DoSetTransmissionMode (txMode);
}
template <class C>
-void
+void
MemberLteUeCphySapProvider<C>::SetSrsConfigurationIndex (uint16_t srcCi)
{
m_owner->DoSetSrsConfigurationIndex (srcCi);
@@ -231,7 +244,7 @@
/**
* Template for the implementation of the LteUeCphySapUser as a member
* of an owner class of type C to which all methods are forwarded
- *
+ *
*/
template <class C>
class MemberLteUeCphySapUser : public LteUeCphySapUser
@@ -260,8 +273,8 @@
{
}
-template <class C>
-void
+template <class C>
+void
MemberLteUeCphySapUser<C>::RecvMasterInformationBlock (LteRrcSap::MasterInformationBlock mib)
{
m_owner->DoRecvMasterInformationBlock (mib);
--- a/src/lte/model/lte-ue-mac.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-mac.cc Thu Jun 13 11:32:13 2013 +0200
@@ -59,6 +59,7 @@
virtual void StartContentionBasedRandomAccessProcedure ();
virtual void StartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask);
virtual void AddLc (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
+ virtual void SetMrnti (uint16_t mrnti);
virtual void RemoveLc (uint8_t lcId);
virtual void Reset ();
@@ -72,19 +73,19 @@
{
}
-void
+void
UeMemberLteUeCmacSapProvider::ConfigureRach (RachConfig rc)
{
m_mac->DoConfigureRach (rc);
}
- void
+void
UeMemberLteUeCmacSapProvider::StartContentionBasedRandomAccessProcedure ()
{
m_mac->DoStartContentionBasedRandomAccessProcedure ();
}
- void
+void
UeMemberLteUeCmacSapProvider::StartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask)
{
m_mac->DoStartNonContentionBasedRandomAccessProcedure (rnti, preambleId, prachMask);
@@ -98,6 +99,12 @@
}
void
+UeMemberLteUeCmacSapProvider::SetMrnti (uint16_t mrnti)
+{
+ m_mac->DoSetMrnti (mrnti);
+}
+
+void
UeMemberLteUeCmacSapProvider::RemoveLc (uint8_t lcid)
{
m_mac->DoRemoveLc (lcid);
@@ -201,14 +208,16 @@
LteUeMac::LteUeMac ()
- : m_bsrPeriodicity (MilliSeconds (1)), // ideal behavior
- m_bsrLast (MilliSeconds (0)),
- m_freshUlBsr (false),
- m_harqProcessId (0),
- m_rnti (0),
- m_rachConfigured (false),
- m_waitingForRaResponse (false)
-
+ : m_bsrPeriodicity (MilliSeconds (1)),
+ // ideal behavior
+ m_bsrLast (MilliSeconds (0)),
+ m_freshUlBsr (false),
+ m_harqProcessId (0),
+ m_rnti (0),
+ m_mrnti (0),
+ m_rachConfigured (false),
+ m_waitingForRaResponse (false)
+
{
NS_LOG_FUNCTION (this);
m_miUlHarqProcessesPacket.resize (HARQ_PERIOD);
@@ -218,7 +227,7 @@
m_miUlHarqProcessesPacket.at (i) = pb;
}
m_miUlHarqProcessesPacketTimer.resize (HARQ_PERIOD, 0);
-
+
m_macSapProvider = new UeMemberLteMacSapProvider (this);
m_cmacSapProvider = new UeMemberLteUeCmacSapProvider (this);
m_uePhySapUser = new UeMemberLteUePhySapUser (this);
@@ -274,13 +283,25 @@
return m_cmacSapProvider;
}
+void
+LteUeMac::SetMrnti (uint16_t mrnti)
+{
+ m_mrnti = mrnti;
+}
+
+uint16_t
+LteUeMac::GetMrnti ()
+{
+ return m_mrnti;
+}
+
void
LteUeMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
{
NS_LOG_FUNCTION (this);
NS_ASSERT_MSG (m_rnti == params.rnti, "RNTI mismatch between RLC and MAC");
- LteRadioBearerTag tag (params.rnti, params.lcid, 0 /* UE works in SISO mode*/);
+ LteRadioBearerTag tag (params.rnti, 0, params.lcid, 0 /* UE works in SISO mode*/);
params.pdu->AddPacketTag (tag);
// store pdu in HARQ buffer
m_miUlHarqProcessesPacket.at (m_harqProcessId)->AddPacket (params.pdu);
@@ -292,12 +313,12 @@
LteUeMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params)
{
NS_LOG_FUNCTION (this << (uint32_t) params.lcid);
-
+
std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
-
-
+
+
it = m_ulBsrReceived.find (params.lcid);
- if (it!=m_ulBsrReceived.end ())
+ if (it != m_ulBsrReceived.end ())
{
// update entry
(*it).second = params;
@@ -318,20 +339,20 @@
if (m_rnti == 0)
{
NS_LOG_INFO ("MAC not initialized, BSR deferred");
- return;
+ return;
}
if (m_ulBsrReceived.size () == 0)
{
NS_LOG_INFO ("No BSR report to transmit");
- return;
+ return;
}
MacCeListElement_s bsr;
bsr.m_rnti = m_rnti;
bsr.m_macCeType = MacCeListElement_s::BSR;
// BSR is reported for each LCG
- std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
+ std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
std::vector<uint32_t> queue (4, 0); // one value per each of the 4 LCGs, initialized to 0
for (it = m_ulBsrReceived.begin (); it != m_ulBsrReceived.end (); it++)
{
@@ -356,18 +377,18 @@
}
-void
+void
LteUeMac::RandomlySelectAndSendRaPreamble ()
{
NS_LOG_FUNCTION (this);
- // 3GPP 36.321 5.1.1
+ // 3GPP 36.321 5.1.1
NS_ASSERT_MSG (m_rachConfigured, "RACH not configured");
// assume that there is no Random Access Preambles group B
m_raPreambleId = m_raPreambleUniformVariable->GetInteger (0, m_rachConfig.numberOfRaPreambles - 1);
bool contention = true;
SendRaPreamble (contention);
}
-
+
void
LteUeMac::SendRaPreamble (bool contention)
{
@@ -378,26 +399,26 @@
// m_uePhySapProvider->SendLteControlMessage (msg)) so that it can
// bypass the m_ulConfigured flag. This is reasonable, since In fact
// the RACH preamble is sent on 6RB bandwidth so the uplink
- // bandwidth does not need to be configured.
+ // bandwidth does not need to be configured.
NS_ASSERT (m_subframeNo > 0); // sanity check for subframe starting at 1
m_raRnti = m_subframeNo - 1;
m_uePhySapProvider->SendRachPreamble (m_raPreambleId, m_raRnti);
NS_LOG_INFO (this << " sent preamble id " << (uint32_t) m_raPreambleId << ", RA-RNTI " << (uint32_t) m_raRnti);
- // 3GPP 36.321 5.1.4
- Time raWindowBegin = MilliSeconds (3);
+ // 3GPP 36.321 5.1.4
+ Time raWindowBegin = MilliSeconds (3);
Time raWindowEnd = MilliSeconds (3 + m_rachConfig.raResponseWindowSize);
Simulator::Schedule (raWindowBegin, &LteUeMac::StartWaitingForRaResponse, this);
m_noRaResponseReceivedEvent = Simulator::Schedule (raWindowEnd, &LteUeMac::RaResponseTimeout, this, contention);
}
-void
+void
LteUeMac::StartWaitingForRaResponse ()
{
- NS_LOG_FUNCTION (this);
- m_waitingForRaResponse = true;
+ NS_LOG_FUNCTION (this);
+ m_waitingForRaResponse = true;
}
-void
+void
LteUeMac::RecvRaResponse (BuildRarListElement_s raResponse)
{
NS_LOG_FUNCTION (this);
@@ -413,7 +434,7 @@
m_cmacSapUser->NotifyRandomAccessSuccessful ();
}
-void
+void
LteUeMac::RaResponseTimeout (bool contention)
{
NS_LOG_FUNCTION (this << contention);
@@ -439,7 +460,7 @@
}
}
-void
+void
LteUeMac::DoConfigureRach (LteUeCmacSapProvider::RachConfig rc)
{
NS_LOG_FUNCTION (this);
@@ -447,7 +468,7 @@
m_rachConfigured = true;
}
-void
+void
LteUeMac::DoStartContentionBasedRandomAccessProcedure ()
{
NS_LOG_FUNCTION (this);
@@ -459,7 +480,7 @@
RandomlySelectAndSendRaPreamble ();
}
-void
+void
LteUeMac::DoStartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask)
{
NS_LOG_FUNCTION (this << " rnti" << rnti);
@@ -475,7 +496,8 @@
{
NS_LOG_FUNCTION (this << " lcId" << (uint32_t) lcId);
NS_ASSERT_MSG (m_lcInfoMap.find (lcId) == m_lcInfoMap.end (), "cannot add channel because LCID " << lcId << " is already present");
-
+ std::cout << "ADDRESS TX: " << msu << " LCID: " << static_cast <unsigned int>(lcId) << std::endl;
+
LcInfo lcInfo;
lcInfo.lcConfig = lcConfig;
lcInfo.macSapUser = msu;
@@ -483,6 +505,12 @@
}
void
+LteUeMac::DoSetMrnti (uint16_t mrnti)
+{
+ m_mrnti = mrnti;
+}
+
+void
LteUeMac::DoRemoveLc (uint8_t lcId)
{
NS_LOG_FUNCTION (this << " lcId" << lcId);
@@ -499,7 +527,7 @@
{
// don't delete CCCH)
if (it->first == 0)
- {
+ {
++it;
}
else
@@ -518,12 +546,17 @@
{
LteRadioBearerTag tag;
p->RemovePacketTag (tag);
- if (tag.GetRnti () == m_rnti)
+std::cout << "CIAO!!" << std::endl;
+ if (tag.GetRnti () == m_rnti || tag.GetMrnti () == m_mrnti)
{
+
// packet is for the current user
std::map <uint8_t, LcInfo>::const_iterator it = m_lcInfoMap.find (tag.GetLcid ());
NS_ASSERT_MSG (it != m_lcInfoMap.end (), "received packet with unknown lcid");
- it->second.macSapUser->ReceivePdu (p);
+ std::cout << "ADDRESS RX: " << it->second.macSapUser << std::endl;
+ LteMacSapUser* macSapUser = it->second.macSapUser;
+ macSapUser->ReceivePdu(p);
+ //it->second.macSapUser->ReceivePdu (p);
}
}
@@ -536,7 +569,7 @@
{
Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
UlDciListElement_s dci = msg2->GetDci ();
- if (dci.m_ndi==1)
+ if (dci.m_ndi == 1)
{
// New transmission -> emtpy pkt buffer queue (for deleting eventual pkts not acked )
Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
@@ -550,11 +583,11 @@
if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
{
activeLcs++;
- if (((*itBsr).second.statusPduSize!=0)&&((*itBsr).second.statusPduSize < statusPduMinSize))
+ if (((*itBsr).second.statusPduSize != 0)&&((*itBsr).second.statusPduSize < statusPduMinSize))
{
statusPduMinSize = (*itBsr).second.statusPduSize;
}
- if (((*itBsr).second.statusPduSize!=0)&&(statusPduMinSize == 0))
+ if (((*itBsr).second.statusPduSize != 0)&&(statusPduMinSize == 0))
{
statusPduMinSize = (*itBsr).second.statusPduSize;
}
@@ -579,14 +612,14 @@
}
}
NS_LOG_LOGIC (this << " UE " << m_rnti << ": UL-CQI notified TxOpportunity of " << dci.m_tbSize << " => " << bytesPerActiveLc << " bytes per active LC" << " statusPduMinSize " << statusPduMinSize);
- for (it = m_lcInfoMap.begin (); it!=m_lcInfoMap.end (); it++)
+ for (it = m_lcInfoMap.begin (); it != m_lcInfoMap.end (); it++)
{
itBsr = m_ulBsrReceived.find ((*it).first);
NS_LOG_DEBUG (this << " Processing LC " << (uint32_t)(*it).first << " bytesPerActiveLc " << bytesPerActiveLc);
- if ( (itBsr!=m_ulBsrReceived.end ()) &&
- ( ((*itBsr).second.statusPduSize > 0) ||
- ((*itBsr).second.retxQueueSize > 0) ||
- ((*itBsr).second.txQueueSize > 0)) )
+ if ( (itBsr != m_ulBsrReceived.end ())
+ && ( ((*itBsr).second.statusPduSize > 0)
+ || ((*itBsr).second.retxQueueSize > 0)
+ || ((*itBsr).second.txQueueSize > 0)) )
{
if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
{
@@ -608,15 +641,15 @@
}
else
{
- if ((*itBsr).second.statusPduSize>bytesForThisLc)
+ if ((*itBsr).second.statusPduSize > bytesForThisLc)
{
NS_FATAL_ERROR ("Insufficient Tx Opportunity for sending a status message");
}
}
-
- if ((bytesForThisLc > 7) && // 7 is the min TxOpportunity useful for Rlc
- (((*itBsr).second.retxQueueSize > 0) ||
- ((*itBsr).second.txQueueSize > 0)))
+
+ if ((bytesForThisLc > 7) // 7 is the min TxOpportunity useful for Rlc
+ && (((*itBsr).second.retxQueueSize > 0)
+ || ((*itBsr).second.txQueueSize > 0)))
{
if ((*itBsr).second.retxQueueSize > 0)
{
@@ -640,8 +673,8 @@
// for SRB1 (using RLC AM) it's better to
// overestimate RLC overhead rather than
// underestimate it and risk unneeded
- // segmentation which increases delay
- rlcOverhead = 4;
+ // segmentation which increases delay
+ rlcOverhead = 4;
}
else
{
@@ -662,7 +695,7 @@
}
else
{
- if ( ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
+ if ( ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
{
// resend BSR info for updating eNB peer MAC
m_freshUlBsr = true;
@@ -684,7 +717,7 @@
Ptr<Packet> pkt = (*j)->Copy ();
m_uePhySapProvider->SendMacPdu (pkt);
}
- m_miUlHarqProcessesPacketTimer.at (m_harqProcessId) = HARQ_PERIOD;
+ m_miUlHarqProcessesPacketTimer.at (m_harqProcessId) = HARQ_PERIOD;
}
}
@@ -750,7 +783,7 @@
m_frameNo = frameNo;
m_subframeNo = subframeNo;
RefreshHarqProcessesPacketBuffer ();
- if ((Simulator::Now () >= m_bsrLast + m_bsrPeriodicity) && (m_freshUlBsr==true))
+ if ((Simulator::Now () >= m_bsrLast + m_bsrPeriodicity) && (m_freshUlBsr == true))
{
SendReportBufferStatus ();
m_bsrLast = Simulator::Now ();
--- a/src/lte/model/lte-ue-mac.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-mac.h Thu Jun 13 11:32:13 2013 +0200
@@ -68,7 +68,7 @@
* \param s a pointer to the PHY SAP Provider
*/
void SetLteUePhySapProvider (LteUePhySapProvider* s);
-
+
/**
* \brief Forwarded from LteUePhySapUser: trigger the start from a new frame
*
@@ -77,16 +77,28 @@
*/
void DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo);
- /**
- * Assign a fixed random variable stream number to the random variables
- * used by this model. Return the number of streams (possibly zero) that
- * have been assigned.
- *
- * \param stream first stream index to use
- * \return the number of stream indices assigned by this model
- */
+ /**
+ * Assign a fixed random variable stream number to the random variables
+ * used by this model. Return the number of streams (possibly zero) that
+ * have been assigned.
+ *
+ * \param stream first stream index to use
+ * \return the number of stream indices assigned by this model
+ */
int64_t AssignStreams (int64_t stream);
+ /**
+ * Set the M-RNTI of MBMS transmission
+ *
+ * \param mrnti the M-MRNTI
+ */
+ void SetMrnti (uint16_t mrnti);
+
+ /**
+ * Get the M-RNTI of MBMS transmission
+ */
+ uint16_t GetMrnti ();
+
private:
// forwarded from MAC SAP
void DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params);
@@ -97,13 +109,14 @@
void DoStartContentionBasedRandomAccessProcedure ();
void DoStartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t rapId, uint8_t prachMask);
void DoAddLc (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
+ void DoSetMrnti (uint16_t mrnti);
void DoRemoveLc (uint8_t lcId);
void DoReset ();
// forwarded from PHY SAP
void DoReceivePhyPdu (Ptr<Packet> p);
void DoReceiveLteControlMessage (Ptr<LteControlMessage> msg);
-
+
// internal methods
void RandomlySelectAndSendRaPreamble ();
void SendRaPreamble (bool contention);
@@ -114,7 +127,6 @@
void RefreshHarqProcessesPacketBuffer (void);
private:
-
struct LcInfo
{
LteUeCmacSapProvider::LogicalChannelConfig lcConfig;
@@ -130,13 +142,13 @@
LteUePhySapProvider* m_uePhySapProvider;
LteUePhySapUser* m_uePhySapUser;
-
+
std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters> m_ulBsrReceived; // BSR received from RLC (the last one)
-
-
+
+
Time m_bsrPeriodicity;
Time m_bsrLast;
-
+
bool m_freshUlBsr; // true when a BSR has been received in the last TTI
uint8_t m_harqProcessId;
@@ -144,6 +156,7 @@
std::vector < uint8_t > m_miUlHarqProcessesPacketTimer; // timer for packet life in the buffer
uint16_t m_rnti;
+ uint16_t m_mrnti;
bool m_rachConfigured;
LteUeCmacSapProvider::RachConfig m_rachConfig;
--- a/src/lte/model/lte-ue-net-device.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-net-device.cc Thu Jun 13 11:32:13 2013 +0200
@@ -91,7 +91,7 @@
}
- LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas, uint64_t imsi)
+LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas, uint64_t imsi)
{
NS_LOG_FUNCTION (this);
m_phy = phy;
@@ -129,7 +129,7 @@
NS_LOG_FUNCTION (this);
m_nas->SetImsi (m_imsi);
m_rrc->SetImsi (m_imsi);
-
+
}
@@ -186,7 +186,7 @@
return m_targetEnb;
}
-void
+void
LteUeNetDevice::DoInitialize (void)
{
NS_LOG_FUNCTION (this);
@@ -201,7 +201,7 @@
{
NS_LOG_FUNCTION (this << dest << protocolNumber);
NS_ASSERT_MSG (protocolNumber == Ipv4L3Protocol::PROT_NUMBER, "unsupported protocol " << protocolNumber << ", only IPv4 is supported");
-
+
return m_nas->Send (packet);
}
--- a/src/lte/model/lte-ue-net-device.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-net-device.h Thu Jun 13 11:32:13 2013 +0200
@@ -63,7 +63,7 @@
* \param rrc the RRC entity
* \param nas the NAS entity
* \param imsi the unique UE identifier
- *
+ *
*/
LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas, uint64_t imsi);
@@ -73,25 +73,25 @@
// inherited from NetDevice
virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
-
+
Ptr<LteUeMac> GetMac (void) const;
- Ptr<LteUeRrc> GetRrc () const ;
+ Ptr<LteUeRrc> GetRrc () const;
Ptr<LteUePhy> GetPhy (void) const;
-
+
Ptr<EpcUeNas> GetNas (void) const;
uint64_t GetImsi () const;
-
+
/**
* \brief Set the targer eNB where the UE is registered
* \param enb
*/
void SetTargetEnb (Ptr<LteEnbNetDevice> enb);
-
+
/**
* \brief Get the targer eNB where the UE is registered
* \return the pointer to the enb
@@ -105,7 +105,6 @@
private:
-
/**
* Some attributes are exported as
* attributes of the LteUeNetDevice from a user perspective, but
@@ -124,7 +123,7 @@
Ptr<EpcUeNas> m_nas;
uint64_t m_imsi;
-
+
};
} // namespace ns3
--- a/src/lte/model/lte-ue-phy-sap.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-phy-sap.h Thu Jun 13 11:32:13 2013 +0200
@@ -53,9 +53,9 @@
*/
virtual void SendLteControlMessage (Ptr<LteControlMessage> msg) = 0;
- /**
+ /**
* send a preamble on the PRACH
- *
+ *
* \param prachId the ID of the preamble
*/
virtual void SendRachPreamble (uint32_t prachId, uint32_t raRnti) = 0;
--- a/src/lte/model/lte-ue-phy.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-phy.cc Thu Jun 13 11:32:13 2013 +0200
@@ -50,11 +50,11 @@
// = TTI - 1 symbol for SRS - 1ns as margin to avoid overlapping simulator events
// (symbol duration in nanoseconds = TTI / 14 (rounded))
// in other words, duration of data portion of UL subframe = TTI*(13/14) -1ns
-static const Time UL_DATA_DURATION = NanoSeconds (1e6 - 71429 - 1);
+static const Time UL_DATA_DURATION = NanoSeconds (1e6 - 71429 - 1);
-// delay from subframe start to transmission of SRS
-// = TTI - 1 symbol for SRS
-static const Time UL_SRS_DELAY_FROM_SUBFRAME_START = NanoSeconds (1e6 - 71429);
+// delay from subframe start to transmission of SRS
+// = TTI - 1 symbol for SRS
+static const Time UL_SRS_DELAY_FROM_SUBFRAME_START = NanoSeconds (1e6 - 71429);
@@ -118,8 +118,10 @@
LteUePhy::LteUePhy (Ptr<LteSpectrumPhy> dlPhy, Ptr<LteSpectrumPhy> ulPhy)
: LtePhy (dlPhy, ulPhy),
- m_p10CqiPeriocity (MilliSeconds (1)), // ideal behavior
- m_a30CqiPeriocity (MilliSeconds (1)), // ideal behavior
+ m_p10CqiPeriocity (MilliSeconds (1)),
+ // ideal behavior
+ m_a30CqiPeriocity (MilliSeconds (1)),
+ // ideal behavior
m_uePhySapUser (0),
m_ueCphySapUser (0),
m_subframeNo (0),
@@ -134,7 +136,7 @@
m_uePhySapProvider = new UeMemberLteUePhySapProvider (this);
m_ueCphySapProvider = new MemberLteUeCphySapProvider<LteUePhy> (this);
m_macChTtiDelay = UL_PUSCH_TTIS_DELAY;
-
+
NS_ASSERT_MSG (Simulator::Now ().GetNanoSeconds () == 0,
"Cannot create UE devices after simulation started");
Simulator::ScheduleNow (&LteUePhy::SubframeIndication, this, 1, 1);
@@ -169,7 +171,7 @@
.AddAttribute ("TxPower",
"Transmission power in dBm",
DoubleValue (10.0),
- MakeDoubleAccessor (&LteUePhy::SetTxPower,
+ MakeDoubleAccessor (&LteUePhy::SetTxPower,
&LteUePhy::GetTxPower),
MakeDoubleChecker<double> ())
.AddAttribute ("NoiseFigure",
@@ -181,44 +183,44 @@
" are connected to sources at the standard noise temperature T0.\" "
"In this model, we consider T0 = 290K.",
DoubleValue (9.0),
- MakeDoubleAccessor (&LteUePhy::SetNoiseFigure,
+ MakeDoubleAccessor (&LteUePhy::SetNoiseFigure,
&LteUePhy::GetNoiseFigure),
MakeDoubleChecker<double> ())
.AddAttribute ("TxMode1Gain",
- "Transmission mode 1 gain in dB",
- DoubleValue (0.0),
+ "Transmission mode 1 gain in dB",
+ DoubleValue (0.0),
MakeDoubleAccessor (&LteUePhy::SetTxMode1Gain ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddAttribute ("TxMode2Gain",
- "Transmission mode 2 gain in dB",
- DoubleValue (4.2),
+ "Transmission mode 2 gain in dB",
+ DoubleValue (4.2),
MakeDoubleAccessor (&LteUePhy::SetTxMode2Gain ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddAttribute ("TxMode3Gain",
- "Transmission mode 3 gain in dB",
- DoubleValue (-2.8),
+ "Transmission mode 3 gain in dB",
+ DoubleValue (-2.8),
MakeDoubleAccessor (&LteUePhy::SetTxMode3Gain ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddAttribute ("TxMode4Gain",
- "Transmission mode 4 gain in dB",
- DoubleValue (0.0),
+ "Transmission mode 4 gain in dB",
+ DoubleValue (0.0),
MakeDoubleAccessor (&LteUePhy::SetTxMode4Gain ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddAttribute ("TxMode5Gain",
- "Transmission mode 5 gain in dB",
- DoubleValue (0.0),
+ "Transmission mode 5 gain in dB",
+ DoubleValue (0.0),
MakeDoubleAccessor (&LteUePhy::SetTxMode5Gain ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddAttribute ("TxMode6Gain",
- "Transmission mode 6 gain in dB",
- DoubleValue (0.0),
+ "Transmission mode 6 gain in dB",
+ DoubleValue (0.0),
MakeDoubleAccessor (&LteUePhy::SetTxMode6Gain ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddAttribute ("TxMode7Gain",
- "Transmission mode 7 gain in dB",
- DoubleValue (0.0),
+ "Transmission mode 7 gain in dB",
+ DoubleValue (0.0),
MakeDoubleAccessor (&LteUePhy::SetTxMode7Gain ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddTraceSource ("ReportCurrentCellRsrpSinr",
"RSRP and SINR statistics.",
MakeTraceSourceAccessor (&LteUePhy::m_reportCurrentCellRsrpSinrTrace))
@@ -243,15 +245,15 @@
MakePointerAccessor (&LteUePhy::GetUlSpectrumPhy),
MakePointerChecker <LteSpectrumPhy> ())
.AddAttribute ("RsrqUeMeasThreshold",
- "Receive threshold for PSS on RSRQ [dB]",
- DoubleValue (-1000.0),
+ "Receive threshold for PSS on RSRQ [dB]",
+ DoubleValue (-1000.0),
MakeDoubleAccessor (&LteUePhy::m_pssReceptionThreshold ),
- MakeDoubleChecker<double> ())
+ MakeDoubleChecker<double> ())
.AddAttribute ("UeMeasurementsFilterPeriod",
- "Time period for reporting UE measurements (default 200 ms.) ",
- TimeValue (MilliSeconds (200)),
- MakeTimeAccessor (&LteUePhy::m_ueMeasurementsFilterPeriod),
- MakeTimeChecker ())
+ "Time period for reporting UE measurements (default 200 ms.) ",
+ TimeValue (MilliSeconds (200)),
+ MakeTimeAccessor (&LteUePhy::m_ueMeasurementsFilterPeriod),
+ MakeTimeChecker ())
.AddTraceSource ("ReportUeMeasurements",
"Report UE measurements RSRP (dBm) and RSRQ (dB).",
MakeTraceSourceAccessor (&LteUePhy::m_reportUeMeasurements))
@@ -440,7 +442,7 @@
// Generate PHY trace
m_rsrpSinrSampleCounter++;
- if (m_rsrpSinrSampleCounter==m_rsrpSinrSamplePeriod)
+ if (m_rsrpSinrSampleCounter == m_rsrpSinrSamplePeriod)
{
NS_ASSERT_MSG (m_rsReceivedPowerUpdated, " RS received power info obsolete");
// RSRP evaluated as averaged received power among RBs
@@ -450,8 +452,8 @@
for (it = m_rsReceivedPower.ConstValuesBegin (); it != m_rsReceivedPower.ConstValuesEnd (); it++)
{
// convert PSD [W/Hz] to linear power [W] for the single RE
- // we consider only one RE for the RS since the channel is
- // flat within the same RB
+ // we consider only one RE for the RS since the channel is
+ // flat within the same RB
double powerTxW = ((*it) * 180000.0) / 12.0;
sum += powerTxW;
rbNum++;
@@ -524,11 +526,11 @@
}
itPss++;
}
- m_pssList.clear ();
+ m_pssList.clear ();
}
-
+
}
void
@@ -542,7 +544,7 @@
{
NS_LOG_FUNCTION (this << interf);
m_rsInterferencePowerUpdated = true;
- m_rsIntereferencePower = interf;
+ m_rsIntereferencePower = interf;
}
void
@@ -550,7 +552,7 @@
{
NS_LOG_FUNCTION (this << power);
m_rsReceivedPowerUpdated = true;
- m_rsReceivedPower = power;
+ m_rsReceivedPower = power;
}
@@ -559,7 +561,7 @@
LteUePhy::CreateDlCqiFeedbackMessage (const SpectrumValue& sinr)
{
NS_LOG_FUNCTION (this);
-
+
// apply transmission mode gain
NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
@@ -573,7 +575,7 @@
if (Simulator::Now () > m_p10CqiLast + m_p10CqiPeriocity)
{
cqi = m_amc->CreateCqiFeedbacks (newSinr, m_dlBandwidth);
-
+
int nLayer = TransmissionModesLayers::TxMode2LayerNum (m_transmissionMode);
int nbSubChannels = cqi.size ();
double cqiSum = 0.0;
@@ -675,7 +677,7 @@
// report to UE measurements trace
m_reportUeMeasurements (m_rnti, m_cellId, avg_rsrp, avg_rsrq, ((*it).first == m_cellId ? 1 : 0));
}
- m_ueCphySapUser-> ReportUeMeasurements(ret);
+ m_ueCphySapUser->ReportUeMeasurements (ret);
m_UeMeasurementsMap.clear ();
Simulator::Schedule (m_ueMeasurementsFilterPeriod, &LteUePhy::ReportUeMeasurements, this);
}
@@ -690,7 +692,7 @@
SetControlMessages (msg);
}
-void
+void
LteUePhy::DoSendRachPreamble (uint32_t raPreambleId, uint32_t raRnti)
{
NS_LOG_FUNCTION (this << raPreambleId);
@@ -708,138 +710,138 @@
LteUePhy::ReceiveLteControlMessageList (std::list<Ptr<LteControlMessage> > msgList)
{
NS_LOG_FUNCTION (this);
-
+
std::list<Ptr<LteControlMessage> >::iterator it;
- for (it = msgList.begin (); it != msgList.end(); it++)
- {
- Ptr<LteControlMessage> msg = (*it);
-
- if (msg->GetMessageType () == LteControlMessage::DL_DCI)
+ for (it = msgList.begin (); it != msgList.end (); it++)
{
- Ptr<DlDciLteControlMessage> msg2 = DynamicCast<DlDciLteControlMessage> (msg);
-
- DlDciListElement_s dci = msg2->GetDci ();
- if (dci.m_rnti != m_rnti)
- {
- // DCI not for me
- continue;
- }
-
- if (dci.m_resAlloc != 0)
- {
- NS_FATAL_ERROR ("Resource Allocation type not implemented");
- }
-
- std::vector <int> dlRb;
-
- // translate the DCI to Spectrum framework
- uint32_t mask = 0x1;
- for (int i = 0; i < 32; i++)
- {
- if (((dci.m_rbBitmap & mask) >> i) == 1)
+ Ptr<LteControlMessage> msg = (*it);
+
+ if (msg->GetMessageType () == LteControlMessage::DL_DCI)
{
- for (int k = 0; k < GetRbgSize (); k++)
- {
- dlRb.push_back ((i * GetRbgSize ()) + k);
+ Ptr<DlDciLteControlMessage> msg2 = DynamicCast<DlDciLteControlMessage> (msg);
+
+ DlDciListElement_s dci = msg2->GetDci ();
+ if (dci.m_rnti != m_rnti && dci.m_mrnti != m_mrnti)
+ {
+ // DCI not for me
+ continue;
+ }
+
+ if (dci.m_resAlloc != 0)
+ {
+ NS_FATAL_ERROR ("Resource Allocation type not implemented");
+ }
+
+ std::vector <int> dlRb;
+
+ // translate the DCI to Spectrum framework
+ uint32_t mask = 0x1;
+ for (int i = 0; i < 32; i++)
+ {
+ if (((dci.m_rbBitmap & mask) >> i) == 1)
+ {
+ for (int k = 0; k < GetRbgSize (); k++)
+ {
+ dlRb.push_back ((i * GetRbgSize ()) + k);
// NS_LOG_DEBUG(this << " RNTI " << m_rnti << " RBG " << i << " DL-DCI allocated PRB " << (i*GetRbgSize()) + k);
- }
- }
- mask = (mask << 1);
- }
-
- // send TB info to LteSpectrumPhy
- NS_LOG_DEBUG (this << " UE " << m_rnti << " DL-DCI " << dci.m_rnti << " bitmap " << dci.m_rbBitmap);
- for (uint8_t i = 0; i < dci.m_tbsSize.size (); i++)
- {
- m_downlinkSpectrumPhy->AddExpectedTb (dci.m_rnti, dci.m_ndi.at (i), dci.m_tbsSize.at (i), dci.m_mcs.at (i), dlRb, i, dci.m_harqProcess, dci.m_rv.at (i), true /* DL */);
- }
-
- SetSubChannelsForReception (dlRb);
-
-
- }
- else if (msg->GetMessageType () == LteControlMessage::UL_DCI)
- {
- // set the uplink bandwidht according to the UL-CQI
- Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
- UlDciListElement_s dci = msg2->GetDci ();
- if (dci.m_rnti != m_rnti)
- {
- // DCI not for me
- continue;
+ }
+ }
+ mask = (mask << 1);
+ }
+
+ // send TB info to LteSpectrumPhy
+ NS_LOG_DEBUG (this << " UE " << m_rnti << " M-RNTI " << m_mrnti << " DL-DCI " << dci.m_rnti << " bitmap " << dci.m_rbBitmap);
+ for (uint8_t i = 0; i < dci.m_tbsSize.size (); i++)
+ {
+ m_downlinkSpectrumPhy->AddExpectedTb (dci.m_rnti, dci.m_mrnti, dci.m_ndi.at (i), dci.m_tbsSize.at (i), dci.m_mcs.at (i), dlRb, i, dci.m_harqProcess, dci.m_rv.at (i), true /* DL */);
+ }
+
+ SetSubChannelsForReception (dlRb);
+
+
}
- NS_LOG_INFO (this << " UL DCI");
- std::vector <int> ulRb;
- for (int i = 0; i < dci.m_rbLen; i++)
- {
- ulRb.push_back (i + dci.m_rbStart);
- //NS_LOG_DEBUG (this << " UE RB " << i + dci.m_rbStart);
- }
- QueueSubChannelsForTransmission (ulRb);
- // fire trace of UL Tx PHY stats
- HarqProcessInfoList_t harqInfoList = m_harqPhyModule->GetHarqProcessInfoUl (m_rnti, 0);
- PhyTransmissionStatParameters params;
- params.m_cellId = m_cellId;
- params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
- params.m_timestamp = Simulator::Now ().GetMilliSeconds () + UL_PUSCH_TTIS_DELAY;
- params.m_rnti = m_rnti;
- params.m_txMode = 0; // always SISO for UE
- params.m_layer = 0;
- params.m_mcs = dci.m_mcs;
- params.m_size = dci.m_tbSize;
- params.m_rv = harqInfoList.size ();
- params.m_ndi = dci.m_ndi;
- m_ulPhyTransmission (params);
- // pass the info to the MAC
- m_uePhySapUser->ReceiveLteControlMessage (msg);
+ else if (msg->GetMessageType () == LteControlMessage::UL_DCI)
+ {
+ // set the uplink bandwidht according to the UL-CQI
+ Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
+ UlDciListElement_s dci = msg2->GetDci ();
+ if (dci.m_rnti != m_rnti)
+ {
+ // DCI not for me
+ continue;
+ }
+ NS_LOG_INFO (this << " UL DCI");
+ std::vector <int> ulRb;
+ for (int i = 0; i < dci.m_rbLen; i++)
+ {
+ ulRb.push_back (i + dci.m_rbStart);
+ //NS_LOG_DEBUG (this << " UE RB " << i + dci.m_rbStart);
+ }
+ QueueSubChannelsForTransmission (ulRb);
+ // fire trace of UL Tx PHY stats
+ HarqProcessInfoList_t harqInfoList = m_harqPhyModule->GetHarqProcessInfoUl (m_rnti, 0);
+ PhyTransmissionStatParameters params;
+ params.m_cellId = m_cellId;
+ params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
+ params.m_timestamp = Simulator::Now ().GetMilliSeconds () + UL_PUSCH_TTIS_DELAY;
+ params.m_rnti = m_rnti;
+ params.m_txMode = 0; // always SISO for UE
+ params.m_layer = 0;
+ params.m_mcs = dci.m_mcs;
+ params.m_size = dci.m_tbSize;
+ params.m_rv = harqInfoList.size ();
+ params.m_ndi = dci.m_ndi;
+ m_ulPhyTransmission (params);
+ // pass the info to the MAC
+ m_uePhySapUser->ReceiveLteControlMessage (msg);
+ }
+ else if (msg->GetMessageType () == LteControlMessage::RAR)
+ {
+ Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
+ if (rarMsg->GetRaRnti () == m_raRnti)
+ {
+ for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
+ {
+ if (it->rapId != m_raPreambleId)
+ {
+ // UL grant not for me
+ continue;
+ }
+ else
+ {
+ NS_LOG_INFO ("received RAR RNTI " << m_raRnti);
+ // set the uplink bandwidht according to the UL grant
+ std::vector <int> ulRb;
+ for (int i = 0; i < it->rarPayload.m_grant.m_rbLen; i++)
+ {
+ ulRb.push_back (i + it->rarPayload.m_grant.m_rbStart);
+ }
+
+ QueueSubChannelsForTransmission (ulRb);
+ // pass the info to the MAC
+ m_uePhySapUser->ReceiveLteControlMessage (msg);
+ // reset RACH variables with out of range values
+ m_raPreambleId = 255;
+ m_raRnti = 11;
+ }
+ }
+ }
+ }
+ else if (msg->GetMessageType () == LteControlMessage::MIB)
+ {
+ NS_LOG_INFO ("received MIB");
+ Ptr<MibLteControlMessage> msg2 = DynamicCast<MibLteControlMessage> (msg);
+ m_ueCphySapUser->RecvMasterInformationBlock (msg2->GetMib ());
+ }
+ else
+ {
+ // pass the message to UE-MAC
+ m_uePhySapUser->ReceiveLteControlMessage (msg);
+ }
+
}
- else if (msg->GetMessageType () == LteControlMessage::RAR)
- {
- Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
- if (rarMsg->GetRaRnti () == m_raRnti)
- {
- for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
- {
- if (it->rapId != m_raPreambleId)
- {
- // UL grant not for me
- continue;
- }
- else
- {
- NS_LOG_INFO ("received RAR RNTI " << m_raRnti);
- // set the uplink bandwidht according to the UL grant
- std::vector <int> ulRb;
- for (int i = 0; i < it->rarPayload.m_grant.m_rbLen; i++)
- {
- ulRb.push_back (i + it->rarPayload.m_grant.m_rbStart);
- }
- QueueSubChannelsForTransmission (ulRb);
- // pass the info to the MAC
- m_uePhySapUser->ReceiveLteControlMessage (msg);
- // reset RACH variables with out of range values
- m_raPreambleId = 255;
- m_raRnti = 11;
- }
- }
- }
- }
- else if (msg->GetMessageType () == LteControlMessage::MIB)
- {
- NS_LOG_INFO ("received MIB");
- Ptr<MibLteControlMessage> msg2 = DynamicCast<MibLteControlMessage> (msg);
- m_ueCphySapUser->RecvMasterInformationBlock (msg2->GetMib ());
- }
- else
- {
- // pass the message to UE-MAC
- m_uePhySapUser->ReceiveLteControlMessage (msg);
- }
-
- }
-
-
+
}
@@ -884,37 +886,37 @@
NS_LOG_FUNCTION (this << frameNo << subframeNo);
NS_ASSERT_MSG (frameNo > 0, "the SRS index check code assumes that frameNo starts at 1");
-
+
// refresh internal variables
m_rsReceivedPowerUpdated = false;
m_rsInterferencePowerUpdated = false;
m_pssReceived = false;
-
+
if (m_ulConfigured)
{
// update uplink transmission mask according to previous UL-CQIs
SetSubChannelsForTransmission (m_subChannelsForTransmissionQueue.at (0));
-
+
// shift the queue
for (uint8_t i = 1; i < m_macChTtiDelay; i++)
{
- m_subChannelsForTransmissionQueue.at (i-1) = m_subChannelsForTransmissionQueue.at (i);
+ m_subChannelsForTransmissionQueue.at (i - 1) = m_subChannelsForTransmissionQueue.at (i);
}
- m_subChannelsForTransmissionQueue.at (m_macChTtiDelay-1).clear ();
-
+ m_subChannelsForTransmissionQueue.at (m_macChTtiDelay - 1).clear ();
+
if (m_srsConfigured && (m_srsStartTime <= Simulator::Now ()))
{
NS_ASSERT_MSG (subframeNo > 0 && subframeNo <= 10, "the SRS index check code assumes that subframeNo starts at 1");
- if ((((frameNo-1)*10 + (subframeNo-1)) % m_srsPeriodicity) == m_srsSubframeOffset)
+ if ((((frameNo - 1) * 10 + (subframeNo - 1)) % m_srsPeriodicity) == m_srsSubframeOffset)
{
NS_LOG_INFO ("frame " << frameNo << " subframe " << subframeNo << " sending SRS (offset=" << m_srsSubframeOffset << ", period=" << m_srsPeriodicity << ")");
- m_sendSrsEvent = Simulator::Schedule (UL_SRS_DELAY_FROM_SUBFRAME_START,
+ m_sendSrsEvent = Simulator::Schedule (UL_SRS_DELAY_FROM_SUBFRAME_START,
&LteUePhy::SendSrs,
this);
}
}
-
+
std::list<Ptr<LteControlMessage> > ctrlMsg = GetControlMessages ();
// send packets in queue
NS_LOG_LOGIC (this << " UE - start slot for PUSCH + PUCCH - RNTI " << m_rnti << " CELLID " << m_cellId);
@@ -926,8 +928,8 @@
}
else
{
- // send only PUCCH (ideal: fake null bandwidth signal)
- if (ctrlMsg.size ()>0)
+ // send only PUCCH (ideal: fake null bandwidth signal)
+ if (ctrlMsg.size () > 0)
{
NS_LOG_LOGIC (this << " UE - start TX PUCCH (NO PUSCH)");
std::vector <int> dlRb;
@@ -940,10 +942,10 @@
}
}
} // m_configured
-
+
// trigger the MAC
m_uePhySapUser->SubframeIndication (frameNo, subframeNo);
-
+
m_subframeNo = subframeNo;
++subframeNo;
if (subframeNo > 10)
@@ -951,11 +953,11 @@
++frameNo;
subframeNo = 1;
}
-
+
// schedule next subframe indication
- Simulator::Schedule (Seconds (GetTti ()), &LteUePhy::SubframeIndication, this, frameNo, subframeNo);
+ Simulator::Schedule (Seconds (GetTti ()), &LteUePhy::SubframeIndication, this, frameNo, subframeNo);
}
-
+
void
LteUePhy::SendSrs ()
{
@@ -976,7 +978,7 @@
LteUePhy::DoReset ()
{
NS_LOG_FUNCTION (this);
-
+
m_rnti = 0;
m_transmissionMode = 0;
m_srsPeriodicity = 0;
@@ -1020,8 +1022,8 @@
m_dlBandwidth = 6;
Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
- m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
-
+ m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
+
m_dlConfigured = false;
m_ulConfigured = false;
}
@@ -1048,16 +1050,16 @@
break;
}
}
-
+
Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
- m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
+ m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
}
m_dlConfigured = true;
}
-void
+void
LteUePhy::DoConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth)
{
m_ulEarfcn = ulEarfcn;
@@ -1065,14 +1067,21 @@
m_ulConfigured = true;
}
-
+
void
LteUePhy::DoSetRnti (uint16_t rnti)
{
NS_LOG_FUNCTION (this << rnti);
m_rnti = rnti;
}
-
+
+void
+LteUePhy::DoSetMrnti (uint16_t mrnti)
+{
+ NS_LOG_FUNCTION (this << mrnti);
+ m_mrnti = mrnti;
+}
+
void
LteUePhy::DoSetTransmissionMode (uint8_t txMode)
{
@@ -1096,43 +1105,43 @@
}
-void
+void
LteUePhy::SetTxMode1Gain (double gain)
{
SetTxModeGain (1, gain);
}
-void
+void
LteUePhy::SetTxMode2Gain (double gain)
{
SetTxModeGain (2, gain);
}
-void
+void
LteUePhy::SetTxMode3Gain (double gain)
{
SetTxModeGain (3, gain);
}
-void
+void
LteUePhy::SetTxMode4Gain (double gain)
{
SetTxModeGain (4, gain);
}
-void
+void
LteUePhy::SetTxMode5Gain (double gain)
{
SetTxModeGain (5, gain);
}
-void
+void
LteUePhy::SetTxMode6Gain (double gain)
{
SetTxModeGain (6, gain);
}
-void
+void
LteUePhy::SetTxMode7Gain (double gain)
{
SetTxModeGain (7, gain);
@@ -1154,7 +1163,7 @@
m_txModeGain.clear ();
for (uint8_t i = 0; i < temp.size (); i++)
{
- if (i==txMode-1)
+ if (i == txMode - 1)
{
m_txModeGain.push_back (gainLin);
}
--- a/src/lte/model/lte-ue-phy.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-phy.h Thu Jun 13 11:32:13 2013 +0200
@@ -74,7 +74,7 @@
/**
* \brief Get the PHY SAP provider
- * \return a pointer to the SAP Provider
+ * \return a pointer to the SAP Provider
*/
LteUePhySapProvider* GetLteUePhySapProvider ();
@@ -179,8 +179,8 @@
// callbacks for LteSpectrumPhy
virtual void ReceiveLteControlMessageList (std::list<Ptr<LteControlMessage> >);
virtual void ReceivePss (uint16_t cellId, Ptr<SpectrumValue> p);
-
-
+
+
@@ -203,10 +203,10 @@
* \brief Send the SRS signal in the last symbols of the frame
*/
void SendSrs ();
-
- /**
- * \brief PhySpectrum generated a new DL HARQ feedback
- */
+
+ /**
+* \brief PhySpectrum generated a new DL HARQ feedback
+*/
virtual void ReceiveLteDlHarqFeedback (DlInfoListElement_s mes);
/**
@@ -218,7 +218,6 @@
private:
-
void SetTxMode1Gain (double gain);
void SetTxMode2Gain (double gain);
void SetTxMode3Gain (double gain);
@@ -233,25 +232,26 @@
void ReportUeMeasurements ();
// UE CPHY SAP methods
- void DoReset ();
- void DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
+ void DoReset ();
+ void DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
void DoSetDlBandwidth (uint8_t ulBandwidth);
void DoConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth);
void DoSetRnti (uint16_t rnti);
+ void DoSetMrnti (uint16_t mrnti);
void DoSetTransmissionMode (uint8_t txMode);
void DoSetSrsConfigurationIndex (uint16_t srcCi);
- // UE PHY SAP methods
- virtual void DoSendMacPdu (Ptr<Packet> p);
+ // UE PHY SAP methods
+ virtual void DoSendMacPdu (Ptr<Packet> p);
virtual void DoSendLteControlMessage (Ptr<LteControlMessage> msg);
virtual void DoSendRachPreamble (uint32_t prachId, uint32_t raRnti);
-
+
std::vector <int> m_subChannelsForTransmission;
std::vector <int> m_subChannelsForReception;
-
+
std::vector< std::vector <int> > m_subChannelsForTransmissionQueue;
-
-
+
+
Ptr<LteAmc> m_amc;
Time m_p10CqiPeriocity; /**< Wideband Periodic CQI: 2, 5, 10, 16, 20, 32, 40, 64, 80 or 160 ms */
@@ -269,10 +269,11 @@
LteUeCphySapUser* m_ueCphySapUser;
uint16_t m_rnti;
+ uint16_t m_mrnti;
uint8_t m_transmissionMode;
std::vector <double> m_txModeGain;
-
+
uint16_t m_srsPeriodicity;
uint16_t m_srsSubframeOffset;
uint16_t m_srsConfigured;
@@ -291,22 +292,22 @@
bool m_pssReceived;
struct PssElement
- {
- uint16_t cellId;
- double pssPsdSum;
- uint16_t nRB;
- };
+ {
+ uint16_t cellId;
+ double pssPsdSum;
+ uint16_t nRB;
+ };
std::list <PssElement> m_pssList;
double m_pssReceptionThreshold; // on RSRQ [W]
struct UeMeasurementsElement
- {
- double rsrpSum;
- uint8_t rsrpNum;
- double rsrqSum;
- uint8_t rsrqNum;
- };
+ {
+ double rsrpSum;
+ uint8_t rsrpNum;
+ double rsrqSum;
+ uint8_t rsrqNum;
+ };
std::map <uint16_t, UeMeasurementsElement> m_UeMeasurementsMap;
Time m_ueMeasurementsFilterPeriod;
--- a/src/lte/model/lte-ue-rrc.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-rrc.cc Thu Jun 13 11:32:13 2013 +0200
@@ -40,6 +40,9 @@
#include <cmath>
+#include <ns3/lte-mrnti-tag.h>
+#include "ns3/packet.h"
+
NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
namespace ns3 {
@@ -58,7 +61,7 @@
virtual void SetTemporaryCellRnti (uint16_t rnti);
virtual void NotifyRandomAccessSuccessful ();
virtual void NotifyRandomAccessFailed ();
-
+
private:
LteUeRrc* m_rrc;
};
@@ -93,17 +96,17 @@
-const char* g_ueRrcStateName[LteUeRrc::NUM_STATES] =
- {
- "IDLE_CELL_SELECTION",
- "IDLE_WAIT_SYSTEM_INFO",
- "IDLE_CAMPED_NORMALLY",
- "IDLE_RANDOM_ACCESS",
- "IDLE_CONNECTING",
- "CONNECTED_NORMALLY",
- "CONNECTED_REESTABLISHING",
- "CONNECTED_HANDOVER"
- };
+const char* g_ueRrcStateName[LteUeRrc::NUM_STATES] =
+{
+ "IDLE_CELL_SELECTION",
+ "IDLE_WAIT_SYSTEM_INFO",
+ "IDLE_CAMPED_NORMALLY",
+ "IDLE_RANDOM_ACCESS",
+ "IDLE_CONNECTING",
+ "CONNECTED_NORMALLY",
+ "CONNECTED_REESTABLISHING",
+ "CONNECTED_HANDOVER"
+};
std::string ToString (LteUeRrc::State s)
{
@@ -206,7 +209,7 @@
.AddTraceSource ("HandoverEndOk",
"trace fired upon successful termination of a handover procedure",
MakeTraceSourceAccessor (&LteUeRrc::m_handoverEndOkTrace))
- ;
+ ;
return tid;
}
@@ -266,13 +269,13 @@
m_asSapUser = s;
}
-LteAsSapProvider*
+LteAsSapProvider*
LteUeRrc::GetAsSapProvider ()
{
return m_asSapProvider;
}
-void
+void
LteUeRrc::SetImsi (uint64_t imsi)
{
NS_LOG_FUNCTION (this << imsi);
@@ -300,27 +303,27 @@
}
-uint8_t
+uint8_t
LteUeRrc::GetUlBandwidth () const
{
NS_LOG_FUNCTION (this);
return m_ulBandwidth;
}
-uint8_t
+uint8_t
LteUeRrc::GetDlBandwidth () const
{
NS_LOG_FUNCTION (this);
return m_dlBandwidth;
}
-uint16_t
+uint16_t
LteUeRrc::GetDlEarfcn () const
{
return m_dlEarfcn;
}
-uint16_t
+uint16_t
LteUeRrc::GetUlEarfcn () const
{
NS_LOG_FUNCTION (this);
@@ -336,12 +339,100 @@
}
void
-LteUeRrc::SetUseRlcSm (bool val)
+LteUeRrc::SetUseRlcSm (bool val)
{
NS_LOG_FUNCTION (this);
m_useRlcSm = val;
}
+void
+LteUeRrc::SetMbmsBearer (LteRrcSap::RrcMbmsAreaConfiguration msg)
+{
+
+ LteRrcSap::DrbToAddMod dtam;
+ dtam.epsBearerIdentity = msg.pmchInfoList.sessionId;
+ dtam.drbIdentity = msg.pmchInfoList.drbIdentity;
+ dtam.rlcConfig = msg.pmchInfoList.rlcConfig;
+ dtam.logicalChannelIdentity = msg.pmchInfoList.logicalChannelIdentity;
+ dtam.logicalChannelConfig = msg.pmchInfoList.logicalChannelConfig;
+
+ prova.drbToAddModList.push_back (dtam);
+ m_cphySapProvider->SetMrnti (msg.pmchInfoList.mrnti);
+ m_cmacSapProvider->SetMrnti (msg.pmchInfoList.mrnti);
+ ApplyRadioResourceConfigDedicated (prova);
+/*
+ //std::cout << "RNTI : " << m_rnti << " MRNTI: " << msg.pmchInfoList.mrnti << " LCID: " << static_cast<unsigned int> (msg.pmchInfoList.logicalChannelIdentity) << std::endl;
+ TypeId rlcTypeId;
+ if (m_useRlcSm)
+ {
+ rlcTypeId = LteRlcSm::GetTypeId ();
+ }
+ else
+ {
+ switch (msg.pmchInfoList.rlcConfig.choice)
+ {
+ case LteRrcSap::RlcConfig::AM:
+ rlcTypeId = LteRlcAm::GetTypeId ();
+ break;
+
+ case LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL:
+ rlcTypeId = LteRlcUm::GetTypeId ();
+ break;
+
+ default:
+ NS_FATAL_ERROR ("unsupported RLC configuration");
+ break;
+ }
+ }
+ ObjectFactory rlcObjectFactory;
+ rlcObjectFactory.SetTypeId (rlcTypeId);
+ Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
+ rlc->SetLteMacSapProvider (m_macSapProvider);
+ //rlc->SetRnti (m_rnti);
+ rlc->SetMrnti (msg.pmchInfoList.mrnti);
+ rlc->SetLcId (msg.pmchInfoList.logicalChannelIdentity);
+
+ Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
+ drbInfo->m_rlc = rlc;
+ drbInfo->m_epsBearerIdentity = msg.pmchInfoList.sessionId;
+ drbInfo->m_logicalChannelIdentity = msg.pmchInfoList.logicalChannelIdentity;
+ drbInfo->m_drbIdentity = msg.pmchInfoList.drbIdentity;
+
+ Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
+ //pdcp->SetRnti (m_rnti);
+ pdcp->SetMrnti (msg.pmchInfoList.mrnti);
+ pdcp->SetLcId (msg.pmchInfoList.logicalChannelIdentity);
+ pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
+ pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
+ rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
+ drbInfo->m_pdcp = pdcp;
+
+
+ m_cphySapProvider->SetMrnti (msg.pmchInfoList.mrnti);
+ m_cmacSapProvider->SetMrnti (msg.pmchInfoList.mrnti);
+
+ //TO-DO
+ struct LteUeCmacSapProvider::LogicalChannelConfig lcConfig;
+
+ lcConfig.priority = msg.pmchInfoList.logicalChannelConfig.priority;
+ lcConfig.prioritizedBitRateKbps = msg.pmchInfoList.logicalChannelConfig.prioritizedBitRateKbps;
+ lcConfig.bucketSizeDurationMs = msg.pmchInfoList.logicalChannelConfig.bucketSizeDurationMs;
+ lcConfig.logicalChannelGroup = msg.pmchInfoList.logicalChannelConfig.logicalChannelGroup;
+ m_cmacSapProvider->AddLc (msg.pmchInfoList.logicalChannelIdentity, lcConfig, rlc->GetLteMacSapUser ());
+ rlc->Start ();
+
+ std::cout << "PROVA STAMPA: " << rlc->GetLteMacSapUser() << " " << rlc->GetTypeId() << std::endl;
+*/
+}
+
+void
+LteUeRrc::AddBearerMbms (uint16_t mrnti, uint8_t bearerId, EpsBearer bearer)
+{
+ MbmsBearerInfo mbmsInfo;
+ mbmsInfo.mrnti = mrnti;
+ mbmsInfo.bearer = bearer;
+ m_mbmsBearerToAdd.insert (std::pair<uint8_t, MbmsBearerInfo> (bearerId, mbmsInfo));
+}
void
LteUeRrc::DoInitialize (void)
@@ -356,7 +447,7 @@
rlc->SetRnti (m_rnti);
rlc->SetLcId (lcid);
- m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
+ m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
m_srb0->m_rlc = rlc;
m_srb0->m_srbIdentity = 0;
LteUeRrcSapUser::SetupParameters ueParams;
@@ -372,7 +463,7 @@
lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
-
+
}
@@ -391,9 +482,9 @@
params.pdcpSdu = packet;
params.rnti = m_rnti;
params.lcid = it->second->m_logicalChannelIdentity;
-
+
NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending " << packet << "on DRBID " << (uint32_t) drbid << " (LCID" << params.lcid << ")" << " (" << packet->GetSize () << " bytes)");
- it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
+ it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
}
void
@@ -402,7 +493,7 @@
NS_LOG_FUNCTION (this);
switch (m_state)
- {
+ {
case IDLE_CELL_SELECTION:
case IDLE_CAMPED_NORMALLY:
NS_LOG_INFO ("already disconnected");
@@ -412,13 +503,13 @@
NS_LOG_INFO ("aborting connection setup procedure");
SwitchToState (IDLE_CAMPED_NORMALLY);
break;
-
+
case CONNECTED_NORMALLY:
case CONNECTED_REESTABLISHING:
case CONNECTED_HANDOVER:
LeaveConnectedMode ();
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
break;
@@ -446,21 +537,21 @@
LteUeRrc::DoNotifyRandomAccessSuccessful ()
{
NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
- m_randomAccessSuccessfulTrace (m_imsi, m_cellId, m_rnti);
+ m_randomAccessSuccessfulTrace (m_imsi, m_cellId, m_rnti);
switch (m_state)
{
- case IDLE_RANDOM_ACCESS:
+ case IDLE_RANDOM_ACCESS:
{
// we just received a RAR with a T-C-RNTI and an UL grant
- // send RRC connection request as message 3 of the random access procedure
+ // send RRC connection request as message 3 of the random access procedure
SwitchToState (IDLE_CONNECTING);
LteRrcSap::RrcConnectionRequest msg;
msg.ueIdentity = m_imsi;
- m_rrcSapUser->SendRrcConnectionRequest (msg);
+ m_rrcSapUser->SendRrcConnectionRequest (msg);
}
break;
-
- case CONNECTED_HANDOVER:
+
+ case CONNECTED_HANDOVER:
{
LteRrcSap::RrcConnectionReconfigurationCompleted msg;
msg.rrcTransactionIdentifier = m_lastRrcTransactionIdentifier;
@@ -469,11 +560,11 @@
m_handoverEndOkTrace (m_imsi, m_cellId, m_rnti);
}
break;
-
+
default:
NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
- break;
- }
+ break;
+ }
}
void
@@ -483,18 +574,18 @@
}
-void
+void
LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint16_t earfcn)
{
NS_LOG_FUNCTION (this << cellId << earfcn);
-
+
m_cellId = cellId;
m_dlEarfcn = earfcn;
- m_cphySapProvider->SyncronizeWithEnb (m_cellId, m_dlEarfcn);
+ m_cphySapProvider->SyncronizeWithEnb (m_cellId, m_dlEarfcn);
SwitchToState (IDLE_WAIT_SYSTEM_INFO);
}
-void
+void
LteUeRrc::DoConnect ()
{
NS_LOG_FUNCTION (this);
@@ -505,21 +596,21 @@
m_connectionPending = true;
break;
- case IDLE_CAMPED_NORMALLY:
+ case IDLE_CAMPED_NORMALLY:
StartConnection ();
break;
case IDLE_RANDOM_ACCESS:
case IDLE_CONNECTING:
- NS_LOG_WARN ("already connecting (state " << ToString (m_state) << ")");
+ NS_LOG_WARN ("already connecting (state " << ToString (m_state) << ")");
break;
case CONNECTED_NORMALLY:
case CONNECTED_REESTABLISHING:
case CONNECTED_HANDOVER:
- NS_LOG_WARN ("already connected (state " << ToString (m_state) << ")");
- break;
-
+ NS_LOG_WARN ("already connected (state " << ToString (m_state) << ")");
+ break;
+
default:
NS_FATAL_ERROR ("cannot connect while in state " << ToString (m_state));
break;
@@ -532,9 +623,9 @@
// CPHY SAP methods
-void
-LteUeRrc::DoRecvMasterInformationBlock (LteRrcSap::MasterInformationBlock msg)
-{
+void
+LteUeRrc::DoRecvMasterInformationBlock (LteRrcSap::MasterInformationBlock msg)
+{
NS_LOG_FUNCTION (this);
m_dlBandwidth = msg.dlBandwidth;
m_cphySapProvider->SetDlBandwidth (msg.dlBandwidth);
@@ -551,9 +642,9 @@
NS_LOG_FUNCTION (this);
for (std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt = params.m_ueMeasurementsList.begin (); newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
- {
- NS_LOG_LOGIC (this << " CellId " << newMeasIt->m_cellId << " RSRP " << newMeasIt->m_rsrp << " RSRQ " << newMeasIt->m_rsrq);
-
+ {
+ NS_LOG_LOGIC (this << " CellId " << newMeasIt->m_cellId << " RSRP " << newMeasIt->m_rsrp << " RSRQ " << newMeasIt->m_rsrq);
+
// 3GPP TS 36.331 section 5.5.3.2 Layer 3 filtering
std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (newMeasIt->m_cellId);
if (storedMeasIt == m_storedMeasValues.end ())
@@ -563,49 +654,49 @@
v.rsrp = newMeasIt->m_rsrp;
v.rsrq = newMeasIt->m_rsrq;
std::pair<uint16_t, MeasValues> val (newMeasIt->m_cellId, v);
- std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
- ret = m_storedMeasValues.insert (val);
+ std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
+ ret = m_storedMeasValues.insert (val);
NS_ASSERT_MSG (ret.second == true, "element already existed");
storedMeasIt = ret.first;
}
else
{
// F_n = (1-a) F_{n-1} + a M_n
- storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
- + m_varMeasConfig.aRsrp * newMeasIt->m_rsrp;
- storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
- + m_varMeasConfig.aRsrq * newMeasIt->m_rsrq;
- }
+ storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
+ + m_varMeasConfig.aRsrp * newMeasIt->m_rsrp;
+ storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
+ + m_varMeasConfig.aRsrq * newMeasIt->m_rsrq;
+ }
storedMeasIt->second.timestamp = Simulator::Now ();
}
-
+
// 3GPP TS 36.331 section 5.5.4.1 Measurement report triggering - General
- for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
+ for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
= m_varMeasConfig.measIdList.begin ();
measIdIt != m_varMeasConfig.measIdList.end ();
- ++measIdIt)
+ ++measIdIt)
{
NS_ASSERT (measIdIt->first == measIdIt->second.measId);
uint8_t measId = measIdIt->first;
NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
- std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
+ std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
- std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
+ std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
- std::map<uint8_t, VarMeasReport>::iterator
+ std::map<uint8_t, VarMeasReport>::iterator
measReportIt = m_varMeasReportList.find (measId);
-
+
// we don't check the purpose field, as it is only included for
- // triggerType == periodical, which is not supported
- NS_ASSERT_MSG (reportConfigEutra.triggerType
+ // triggerType == periodical, which is not supported
+ NS_ASSERT_MSG (reportConfigEutra.triggerType
== LteRrcSap::ReportConfigEutra::EVENT,
"only triggerType == event is supported");
// only EUTRA is supported, no need to check for it
@@ -615,7 +706,7 @@
std::list<uint16_t> concernedCellsEntry;
std::list<uint16_t> concernedCellsLeaving;
-
+
switch (reportConfigEutra.eventId)
{
case LteRrcSap::ReportConfigEutra::EVENT_A2:
@@ -628,27 +719,27 @@
case LteRrcSap::ReportConfigEutra::RSRP:
ms = m_storedMeasValues[m_cellId].rsrp;
//ms = EutranMeasurementMapping::QuantizeRsrp (m_storedMeasValues[m_cellId].rsrp);
- NS_ASSERT (reportConfigEutra.threshold1.choice
+ NS_ASSERT (reportConfigEutra.threshold1.choice
== LteRrcSap::ThresholdEutra::THRESHOLD_RSRP);
thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
break;
case LteRrcSap::ReportConfigEutra::RSRQ:
ms = m_storedMeasValues[m_cellId].rsrq;
//ms = EutranMeasurementMapping::QuantizeRsrq (m_storedMeasValues[m_cellId].rsrq);
- NS_ASSERT (reportConfigEutra.threshold1.choice
- == LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ);
+ NS_ASSERT (reportConfigEutra.threshold1.choice
+ == LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ);
thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
break;
default:
NS_FATAL_ERROR ("unsupported triggerQuantity");
break;
- }
+ }
// Inequality A2-1 (Entering condition) : Ms + Hys < Thresh
bool entryCond = ms + hys < thresh;
- if (entryCond == true
+ if (entryCond == true
&& (measReportIt == m_varMeasReportList.end ()
- || (measReportIt != m_varMeasReportList.end ()
- && (measReportIt->second.cellsTriggeredList.find (m_cellId)
+ || (measReportIt != m_varMeasReportList.end ()
+ && (measReportIt->second.cellsTriggeredList.find (m_cellId)
== measReportIt->second.cellsTriggeredList.end ()))))
{
concernedCellsEntry.push_back (m_cellId);
@@ -656,16 +747,16 @@
}
// Inequality A2-2 (Leaving condition) : Ms − Hys > Thresh
bool leavingCond = ms - hys > thresh;
- if (leavingCond
+ if (leavingCond
&& measReportIt != m_varMeasReportList.end ()
- && (measReportIt->second.cellsTriggeredList.find (m_cellId)
+ && (measReportIt->second.cellsTriggeredList.find (m_cellId)
!= measReportIt->second.cellsTriggeredList.end ()))
{
concernedCellsLeaving.push_back (m_cellId);
eventLeavingCondApplicable = true;
}
NS_LOG_LOGIC ("event A2: serving cell " << m_cellId << " ms=" << ms << " thresh=" << thresh << " entryCond=" << entryCond << " leavingCond=" << leavingCond);
- }
+ }
break;
case LteRrcSap::ReportConfigEutra::EVENT_A4:
@@ -675,7 +766,7 @@
++storedMeasIt)
{
uint16_t cellId = storedMeasIt->first;
- if (cellId != m_cellId)
+ if (cellId != m_cellId)
{
double mn; // Mn, the measurement for neighboring cell
double thresh; // Tresh, the threshold parameter for this event
@@ -685,27 +776,27 @@
case LteRrcSap::ReportConfigEutra::RSRP:
mn = storedMeasIt->second.rsrp;
//mn = EutranMeasurementMapping::QuantizeRsrp (storedMeasIt->second.rsrp);
- NS_ASSERT (reportConfigEutra.threshold1.choice
- == LteRrcSap::ThresholdEutra::THRESHOLD_RSRP);
- thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
+ NS_ASSERT (reportConfigEutra.threshold1.choice
+ == LteRrcSap::ThresholdEutra::THRESHOLD_RSRP);
+ thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
break;
case LteRrcSap::ReportConfigEutra::RSRQ:
mn = storedMeasIt->second.rsrq;
//mn = EutranMeasurementMapping::QuantizeRsrq (storedMeasIt->second.rsrq);
- NS_ASSERT (reportConfigEutra.threshold1.choice
- == LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ);
+ NS_ASSERT (reportConfigEutra.threshold1.choice
+ == LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ);
thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
break;
default:
NS_FATAL_ERROR ("unsupported triggerQuantity");
break;
- }
+ }
// Inequality A4-1 (Entering condition) : Mn + Ofn + Ocn − Hys > Thresh
bool entryCond = mn + measObjectEutra.offsetFreq + 0.0 - hys > thresh;
- if (entryCond == true
+ if (entryCond == true
&& (measReportIt == m_varMeasReportList.end ()
- || (measReportIt != m_varMeasReportList.end ()
- && (measReportIt->second.cellsTriggeredList.find (cellId)
+ || (measReportIt != m_varMeasReportList.end ()
+ && (measReportIt->second.cellsTriggeredList.find (cellId)
== measReportIt->second.cellsTriggeredList.end ()))))
{
concernedCellsEntry.push_back (cellId);
@@ -713,15 +804,15 @@
}
// Inequality A4-2 (Leaving condition) : Mn + Ofn + Ocn + Hys < Thresh
bool leavingCond = mn + measObjectEutra.offsetFreq + 0.0 + hys < thresh;
- if (leavingCond
+ if (leavingCond
&& measReportIt != m_varMeasReportList.end ()
- && (measReportIt->second.cellsTriggeredList.find (cellId)
+ && (measReportIt->second.cellsTriggeredList.find (cellId)
!= measReportIt->second.cellsTriggeredList.end ()))
{
concernedCellsLeaving.push_back (cellId);
eventLeavingCondApplicable = true;
}
-
+
NS_LOG_LOGIC ("event A4: neighbor cell " << cellId << " mn=" << mn << " thresh=" << thresh << " entryCond=" << entryCond << " leavingCond=" << leavingCond);
}
}
@@ -731,23 +822,23 @@
default:
NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
break;
-
- } // switch (event type)
+
+ } // switch (event type)
NS_LOG_LOGIC ("eventEntryCondApplicable=" << eventEntryCondApplicable
- << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
+ << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
bool initiateUeMeasurementReportingProcedure = false;
if (eventEntryCondApplicable)
- {
+ {
if (measReportIt == m_varMeasReportList.end ())
{
VarMeasReport r;
- r.measId = measId;
+ r.measId = measId;
std::pair<uint8_t, VarMeasReport> val (measId, r);
- std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
- ret = m_varMeasReportList.insert (val);
+ std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
+ ret = m_varMeasReportList.insert (val);
NS_ASSERT_MSG (ret.second == true, "element already existed");
measReportIt = ret.first;
}
@@ -760,9 +851,9 @@
measReportIt->second.numberOfReportsSent = 0;
initiateUeMeasurementReportingProcedure = true;
}
-
+
if (eventLeavingCondApplicable)
- {
+ {
NS_ASSERT (measReportIt != m_varMeasReportList.end ());
for (std::list<uint16_t>::iterator it = concernedCellsLeaving.begin ();
it != concernedCellsLeaving.end ();
@@ -772,35 +863,35 @@
}
// reportOnLeave will only be set when eventId = eventA3
- if(reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
+ if (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
{
if (reportConfigEutra.reportOnLeave)
{
initiateUeMeasurementReportingProcedure = true;
}
- }
+ }
}
if (initiateUeMeasurementReportingProcedure)
{
SendMeasurementReport (measId);
- }
-
+ }
+
if ((measReportIt != m_varMeasReportList.end ())
&& (measReportIt->second.cellsTriggeredList.empty ()))
{
measReportIt->second.periodicReportTimer.Cancel ();
m_varMeasReportList.erase (measReportIt);
}
-
- } // for each measId in m_varMeasConfig.measIdList
+
+ } // for each measId in m_varMeasConfig.measIdList
}
// RRC SAP methods
-void
+void
LteUeRrc::DoCompleteSetup (LteUeRrcSapProvider::CompleteSetupParameters params)
{
NS_LOG_FUNCTION (this);
@@ -812,15 +903,15 @@
}
-void
+void
LteUeRrc::DoRecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
{
NS_LOG_FUNCTION (this);
// to be implemented
}
-
-void
+
+void
LteUeRrc::DoRecvSystemInformation (LteRrcSap::SystemInformation msg)
{
NS_LOG_FUNCTION (this);
@@ -838,14 +929,14 @@
}
if (m_state == IDLE_WAIT_SYSTEM_INFO && m_receivedMib && m_receivedSib2)
{
- SwitchToState (IDLE_CAMPED_NORMALLY);
+ SwitchToState (IDLE_CAMPED_NORMALLY);
}
}
-void
+void
LteUeRrc::DoRecvRrcConnectionSetup (LteRrcSap::RrcConnectionSetup msg)
-{
+{
NS_LOG_FUNCTION (this);
switch (m_state)
{
@@ -860,7 +951,7 @@
m_connectionEstablishedTrace (m_imsi, m_cellId, m_rnti);
}
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
break;
@@ -885,12 +976,12 @@
m_cellId = mci.targetPhysCellId;
NS_ASSERT (mci.haveCarrierFreq);
NS_ASSERT (mci.haveCarrierBandwidth);
- m_cphySapProvider->SyncronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
- m_cphySapProvider->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
- m_cphySapProvider->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
+ m_cphySapProvider->SyncronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
+ m_cphySapProvider->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
+ m_cphySapProvider->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
m_rnti = msg.mobilityControlInfo.newUeIdentity;
m_srb0->m_rlc->SetRnti (m_rnti);
- NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
+ NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
m_cmacSapProvider->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
m_cphySapProvider->SetRnti (m_rnti);
m_lastRrcTransactionIdentifier = msg.rrcTransactionIdentifier;
@@ -901,11 +992,11 @@
// it's in the current stack, so we would corrupt the stack
// if we did so. Hence we schedule it for later disposal
m_srb1Old = m_srb1;
- Simulator::ScheduleNow (&LteUeRrc::DisposeOldSrb1, this);
+ Simulator::ScheduleNow (&LteUeRrc::DisposeOldSrb1, this);
m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
m_drbMap.clear (); // dispose all DRBs
- ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
+ ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
if (msg.haveMeasConfig)
{
@@ -920,11 +1011,11 @@
if (msg.haveRadioResourceConfigDedicated)
{
ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
- }
+ }
if (msg.haveMeasConfig)
{
ApplyMeasConfig (msg.measConfig);
- }
+ }
LteRrcSap::RrcConnectionReconfigurationCompleted msg2;
msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
m_rrcSapUser->SendRrcConnectionReconfigurationCompleted (msg2);
@@ -938,7 +1029,7 @@
}
}
-void
+void
LteUeRrc::DoRecvRrcConnectionReestablishment (LteRrcSap::RrcConnectionReestablishment msg)
{
switch (m_state)
@@ -947,14 +1038,14 @@
{
}
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
break;
}
}
-void
+void
LteUeRrc::DoRecvRrcConnectionReestablishmentReject (LteRrcSap::RrcConnectionReestablishmentReject msg)
{
NS_LOG_FUNCTION (this);
@@ -965,20 +1056,20 @@
LeaveConnectedMode ();
}
break;
-
+
default:
NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
break;
}
}
-void
+void
LteUeRrc::DoRecvRrcConnectionRelease (LteRrcSap::RrcConnectionRelease msg)
{
NS_LOG_FUNCTION (this);
}
-void
+void
LteUeRrc::DoRecvRrcConnectionReject (LteRrcSap::RrcConnectionReject msg)
{
NS_LOG_FUNCTION (this);
@@ -986,14 +1077,32 @@
SwitchToState (IDLE_CAMPED_NORMALLY);
}
+void
+LteUeRrc::DoRecvMbmsAreaConfiguration (LteRrcSap::RrcMbmsAreaConfiguration msg)
+{
+ NS_LOG_FUNCTION (this);
+ uint8_t bearerId = msg.pmchInfoList.drbIdentity;
+ std::map<uint8_t, MbmsBearerInfo>::iterator it = m_mbmsBearerToAdd.find (bearerId);
+ if (it != m_mbmsBearerToAdd.end ())
+ {
+ NS_LOG_INFO ("New MBMS Bearer to add");
+ SetMbmsBearer (msg);
+ m_mbmsBearerToAdd.erase (bearerId);
+ }
+ else
+ {
+ NS_LOG_INFO ("MBMS Bearer connect");
+ }
+}
-void
+void
LteUeRrc::ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd)
{
NS_LOG_FUNCTION (this);
+ prova = rrcd;
const struct LteRrcSap::PhysicalConfigDedicated& pcd = rrcd.physicalConfigDedicated;
-
+
if (pcd.haveAntennaInfoDedicated)
{
m_cphySapProvider->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
@@ -1008,8 +1117,8 @@
{
if (m_srb1 == 0)
{
- // SRB1 not setup yet
- NS_ASSERT_MSG ((m_state == IDLE_CONNECTING) || (m_state == CONNECTED_HANDOVER),
+ // SRB1 not setup yet
+ NS_ASSERT_MSG ((m_state == IDLE_CONNECTING) || (m_state == CONNECTED_HANDOVER),
"unexpected state " << ToString (m_state));
NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
@@ -1018,7 +1127,7 @@
Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
rlc->SetLteMacSapProvider (m_macSapProvider);
rlc->SetRnti (m_rnti);
- rlc->SetLcId (lcid);
+ rlc->SetLcId (lcid);
Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
pdcp->SetRnti (m_rnti);
@@ -1031,7 +1140,7 @@
m_srb1->m_rlc = rlc;
m_srb1->m_pdcp = pdcp;
m_srb1->m_srbIdentity = 1;
-
+
m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
@@ -1042,12 +1151,12 @@
lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
-
+
m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
-
+
++stamIt;
- NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
-
+ NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
+
LteUeRrcSapUser::SetupParameters ueParams;
ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
@@ -1073,7 +1182,7 @@
if (drbMapIt == m_drbMap.end ())
{
NS_LOG_INFO ("New Data Radio Bearer");
-
+
TypeId rlcTypeId;
if (m_useRlcSm)
{
@@ -1083,20 +1192,20 @@
{
switch (dtamIt->rlcConfig.choice)
{
- case LteRrcSap::RlcConfig::AM:
+ case LteRrcSap::RlcConfig::AM:
rlcTypeId = LteRlcAm::GetTypeId ();
break;
-
- case LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL:
+
+ case LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL:
rlcTypeId = LteRlcUm::GetTypeId ();
break;
-
+
default:
NS_FATAL_ERROR ("unsupported RLC configuration");
- break;
+ break;
}
}
-
+
ObjectFactory rlcObjectFactory;
rlcObjectFactory.SetTypeId (rlcTypeId);
Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
@@ -1109,7 +1218,7 @@
drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
drbInfo->m_drbIdentity = dtamIt->drbIdentity;
-
+
// we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
// if we are using RLC/SM we don't care of anything above RLC
if (rlcTypeId != LteRlcSm::GetTypeId ())
@@ -1124,15 +1233,15 @@
}
m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
-
+
m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
-
+
struct LteUeCmacSapProvider::LogicalChannelConfig lcConfig;
lcConfig.priority = dtamIt->logicalChannelConfig.priority;
lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
- lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
+ lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
m_cmacSapProvider->AddLc (dtamIt->logicalChannelIdentity,
lcConfig,
@@ -1146,7 +1255,7 @@
// TODO: currently not implemented. Would need to modify drbInfo, and then propagate changes to the MAC
}
}
-
+
std::list<uint8_t>::iterator dtdmIt;
for (dtdmIt = rrcd.drbToReleaseList.begin ();
dtdmIt != rrcd.drbToReleaseList.end ();
@@ -1156,18 +1265,18 @@
NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid << drbid);
std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
- m_drbMap.erase (it);
+ m_drbMap.erase (it);
m_bid2DrbidMap.erase (drbid);
}
}
-void
+void
LteUeRrc::ApplyMeasConfig (LteRrcSap::MeasConfig mc)
{
NS_LOG_FUNCTION (this);
- // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
+ // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
// 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
@@ -1189,7 +1298,7 @@
m_varMeasConfig.measIdList.erase (measIdIt++);
std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
if (measReportIt != m_varMeasReportList.end ())
- {
+ {
NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
measReportIt->second.periodicReportTimer.Cancel ();
m_varMeasReportList.erase (measReportIt);
@@ -1199,11 +1308,11 @@
{
++measIdIt;
}
- }
-
- }
+ }
- // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
+ }
+
+ // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
it != mc.measObjectToAddModList.end ();
++it)
@@ -1213,19 +1322,19 @@
NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
- NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false , "cellForWhichToReportCGI is not supported");
-
-
- uint8_t measObjectId = it->measObjectId;
- std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
+ NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false, "cellForWhichToReportCGI is not supported");
+
+
+ uint8_t measObjectId = it->measObjectId;
+ std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
if (measObjectIt != m_varMeasConfig.measObjectList.end ())
{
NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
- measObjectIt->second = *it;
- for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
+ measObjectIt->second = *it;
+ for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
= m_varMeasConfig.measIdList.begin ();
measIdIt != m_varMeasConfig.measIdList.end ();
- ++measIdIt)
+ ++measIdIt)
{
if (measIdIt->second.measObjectId == measObjectId)
{
@@ -1243,9 +1352,9 @@
}
else
{
- NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
+ NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
m_varMeasConfig.measObjectList[measObjectId] = *it;
- }
+ }
}
// 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
@@ -1268,7 +1377,7 @@
m_varMeasConfig.measIdList.erase (measIdIt++);
std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
if (measReportIt != m_varMeasReportList.end ())
- {
+ {
NS_LOG_LOGIC (this << " deleting existing report for measId" << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
measReportIt->second.periodicReportTimer.Cancel ();
m_varMeasReportList.erase (measReportIt);
@@ -1278,10 +1387,10 @@
{
++measIdIt;
}
- }
+ }
}
-
+
// 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
it != mc.reportConfigToAddModList.end ();
@@ -1294,17 +1403,17 @@
|| it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A4,
"only events A2 and A4 are supported");
NS_ASSERT_MSG (it->reportConfigEutra.timeToTrigger == 0, "timeToTrigger > 0 is not supported");
-
- uint8_t reportConfigId = it->reportConfigId;
- std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
+
+ uint8_t reportConfigId = it->reportConfigId;
+ std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
{
NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
- m_varMeasConfig.reportConfigList[reportConfigId] = *it;
- for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
+ m_varMeasConfig.reportConfigList[reportConfigId] = *it;
+ for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
= m_varMeasConfig.measIdList.begin ();
measIdIt != m_varMeasConfig.measIdList.end ();
- ++measIdIt)
+ ++measIdIt)
{
if (measIdIt->second.reportConfigId == reportConfigId)
{
@@ -1322,9 +1431,9 @@
}
else
{
- NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
+ NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
m_varMeasConfig.reportConfigList[reportConfigId] = *it;
- }
+ }
}
@@ -1343,22 +1452,22 @@
m_varMeasConfig.measIdList.erase (measIdIt++);
std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
if (measReportIt != m_varMeasReportList.end ())
- {
+ {
NS_LOG_LOGIC (this << " deleting existing report for measId" << (uint32_t) measId);
measReportIt->second.periodicReportTimer.Cancel ();
m_varMeasReportList.erase (measReportIt);
}
}
// we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
- m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP/4.0);
- m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ/4.0);
+ m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
+ m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
}
- // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
+ // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
it != mc.measIdToRemoveList.end ();
++it)
@@ -1380,12 +1489,12 @@
it != mc.measIdToAddModList.end ();
++it)
{
- NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId << " (measObjectId="
- << (uint32_t) it->measObjectId << ", reportConfigId=" << (uint32_t) it->reportConfigId << ")");
+ NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId << " (measObjectId="
+ << (uint32_t) it->measObjectId << ", reportConfigId=" << (uint32_t) it->reportConfigId << ")");
NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
!= m_varMeasConfig.measObjectList.end ());
NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
- != m_varMeasConfig.reportConfigList.end ());
+ != m_varMeasConfig.reportConfigList.end ());
m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
if (measReportIt != m_varMeasReportList.end ())
@@ -1414,17 +1523,17 @@
}
}
-void
+void
LteUeRrc::SendMeasurementReport (uint8_t measId)
{
NS_LOG_FUNCTION (this << (uint32_t) measId);
// 3GPP TS 36.331 section 5.5.5 Measurement reporting
- std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
+ std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
measIdIt = m_varMeasConfig.measIdList.find (measId);
NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
-
- std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
+
+ std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
@@ -1432,7 +1541,7 @@
LteRrcSap::MeasurementReport measurementReport;
LteRrcSap::MeasResults& measResults = measurementReport.measResults;
measResults.measId = measId;
-
+
std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
measResults.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
@@ -1451,8 +1560,8 @@
if (!(measReportIt->second.cellsTriggeredList.empty ()))
{
measResults.haveMeasResultNeighCells = true;
-
- std::multimap<double, uint16_t> sortedNeighCells;
+
+ std::multimap<double, uint16_t> sortedNeighCells;
for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
++cellsTriggeredIt)
@@ -1461,7 +1570,7 @@
if (cellId != m_cellId)
{
std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
- double triggerValue;
+ double triggerValue;
switch (reportConfigEutra.triggerQuantity)
{
case LteRrcSap::ReportConfigEutra::RSRP:
@@ -1473,11 +1582,11 @@
default:
NS_FATAL_ERROR ("unsupported triggerQuantity");
break;
- }
+ }
sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
}
}
-
+
std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
uint32_t count;
for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
@@ -1486,19 +1595,19 @@
{
uint16_t cellId = sortedNeighCellsIt->second;
std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
- NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
+ NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
LteRrcSap::MeasResultEutra measResultEutra;
measResultEutra.physCellId = cellId;
measResultEutra.haveCgiInfo = false;
measResultEutra.haveRsrpResult = true;
measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
measResultEutra.haveRsrqResult = true;
- measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
- NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
- << " RSRP " << (uint32_t) measResultEutra.rsrpResult
- << " (" << neighborMeasIt->second.rsrp << " dBm) "
- << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
- << " (" << neighborMeasIt->second.rsrq << " dB)");
+ measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
+ NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
+ << " RSRP " << (uint32_t) measResultEutra.rsrpResult
+ << " (" << neighborMeasIt->second.rsrp << " dBm) "
+ << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
+ << " (" << neighborMeasIt->second.rsrq << " dB)");
measResults.measResultListEutra.push_back (measResultEutra);
}
}
@@ -1508,7 +1617,7 @@
}
measReportIt->second.numberOfReportsSent++;
measReportIt->second.periodicReportTimer.Cancel ();
-
+
// the current LteRrcSap implementation is broken in that it does not allow for infinite values
// which is probably the most reasonable setting. So we just assume infinite reportAmount
// if (measReportIt->numberOfReportsSent < reportConfigEutra.reportAmount)
@@ -1518,31 +1627,31 @@
case LteRrcSap::ReportConfigEutra::MS480:
intervalMs = 480;
break;
-
+
default:
NS_FATAL_ERROR ("unsupported reportInterval");
- break;
+ break;
}
- measReportIt->second.periodicReportTimer
- = Simulator::Schedule (MilliSeconds (intervalMs),
+ measReportIt->second.periodicReportTimer
+ = Simulator::Schedule (MilliSeconds (intervalMs),
&LteUeRrc::SendMeasurementReport,
this,
measId);
m_rrcSapUser->SendMeasurementReport (measurementReport);
- }
+ }
}
-void
+void
LteUeRrc::StartConnection ()
{
NS_LOG_FUNCTION (this);
m_connectionPending = false;
- SwitchToState (IDLE_RANDOM_ACCESS);
+ SwitchToState (IDLE_RANDOM_ACCESS);
m_cmacSapProvider->StartContentionBasedRandomAccessProcedure ();
}
-void
+void
LteUeRrc::LeaveConnectedMode ()
{
NS_LOG_FUNCTION (this << m_imsi);
@@ -1566,7 +1675,7 @@
m_srb1Old = 0;
}
-uint8_t
+uint8_t
LteUeRrc::Bid2Drbid (uint8_t bid)
{
std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
@@ -1575,7 +1684,7 @@
}
-void
+void
LteUeRrc::SwitchToState (State newState)
{
NS_LOG_FUNCTION (this << newState);
@@ -1604,7 +1713,7 @@
case IDLE_CONNECTING:
break;
-
+
case CONNECTED_NORMALLY:
break;
@@ -1613,14 +1722,14 @@
case CONNECTED_HANDOVER:
break;
-
+
default:
break;
}
}
-
+
-
-
+
+
} // namespace ns3
--- a/src/lte/model/lte-ue-rrc.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/lte-ue-rrc.h Thu Jun 13 11:32:13 2013 +0200
@@ -58,23 +58,22 @@
friend class MemberLteUeRrcSapProvider<LteUeRrc>;
public:
-
/**
* The states of the UE RRC entity
- *
+ *
*/
enum State
- {
- IDLE_CELL_SELECTION = 0,
- IDLE_WAIT_SYSTEM_INFO,
- IDLE_CAMPED_NORMALLY,
- IDLE_RANDOM_ACCESS,
- IDLE_CONNECTING,
- CONNECTED_NORMALLY,
- CONNECTED_REESTABLISHING,
- CONNECTED_HANDOVER,
- NUM_STATES
- };
+ {
+ IDLE_CELL_SELECTION = 0,
+ IDLE_WAIT_SYSTEM_INFO,
+ IDLE_CAMPED_NORMALLY,
+ IDLE_RANDOM_ACCESS,
+ IDLE_CONNECTING,
+ CONNECTED_NORMALLY,
+ CONNECTED_REESTABLISHING,
+ CONNECTED_HANDOVER,
+ NUM_STATES
+ };
/**
@@ -150,22 +149,22 @@
*/
void SetLteMacSapProvider (LteMacSapProvider* s);
- /**
+ /**
* Set the AS SAP user to interact with the NAS entity
- *
+ *
* \param s the AS SAP user
*/
void SetAsSapUser (LteAsSapUser* s);
- /**
- *
- *
+ /**
+ *
+ *
* \return the AS SAP provider exported by this RRC
*/
LteAsSapProvider* GetAsSapProvider ();
- /**
- *
+ /**
+ *
* \param imsi the unique UE identifier
*/
void SetImsi (uint64_t imsi);
@@ -191,41 +190,50 @@
uint16_t GetCellId () const;
- /**
+ /**
* \return the uplink bandwidth in RBs
*/
uint8_t GetUlBandwidth () const;
- /**
+ /**
* \return the downlink bandwidth in RBs
*/
uint8_t GetDlBandwidth () const;
- /**
+ /**
* \return the downlink carrier frequency (EARFCN)
*/
uint16_t GetDlEarfcn () const;
- /**
+ /**
* \return the uplink carrier frequency (EARFCN)
*/
uint16_t GetUlEarfcn () const;
- /**
- *
+ /**
+ *
* \return the current state
*/
State GetState ();
- /**
- *
- *
+ /**
+ *
+ *
* \param val true if RLC SM is to be used, false if RLC UM/AM are to be used
*/
void SetUseRlcSm (bool val);
+ /**
+ * Set bearer MBMS
+ *
+ */
+ void SetMbmsBearer (LteRrcSap::RrcMbmsAreaConfiguration msg);
-private:
+ /**
+ * Add MBMS bearer of interest
+ *
+ */
+ void AddBearerMbms (uint16_t mrnti, uint8_t bearerId, EpsBearer bearer);
// PDCP SAP methods
@@ -235,7 +243,7 @@
void DoSetTemporaryCellRnti (uint16_t rnti);
void DoNotifyRandomAccessSuccessful ();
void DoNotifyRandomAccessFailed ();
-
+
// LTE AS SAP methods
void DoForceCampedOnEnb (uint16_t cellId, uint16_t earfcn);
void DoConnect ();
@@ -256,8 +264,9 @@
void DoRecvRrcConnectionReestablishmentReject (LteRrcSap::RrcConnectionReestablishmentReject msg);
void DoRecvRrcConnectionRelease (LteRrcSap::RrcConnectionRelease msg);
void DoRecvRrcConnectionReject (LteRrcSap::RrcConnectionReject msg);
+ void DoRecvMbmsAreaConfiguration (LteRrcSap::RrcMbmsAreaConfiguration msg);
-
+
// internal methods
void ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd);
void ApplyMeasConfig (LteRrcSap::MeasConfig mc);
@@ -281,7 +290,7 @@
LteMacSapProvider* m_macSapProvider;
LtePdcpSapUser* m_drbPdcpSapUser;
-
+
LteAsSapProvider* m_asSapProvider;
LteAsSapUser* m_asSapUser;
@@ -291,11 +300,22 @@
uint16_t m_rnti;
uint16_t m_cellId;
+ struct
+ MbmsBearerInfo
+ {
+ uint16_t mrnti;
+ EpsBearer bearer;
+ };
+
+ std::map<uint8_t, MbmsBearerInfo> m_mbmsBearerToAdd;
+
+ LteRrcSap::RadioResourceConfigDedicated prova;
+
Ptr<LteSignalingRadioBearerInfo> m_srb0;
Ptr<LteSignalingRadioBearerInfo> m_srb1;
Ptr<LteSignalingRadioBearerInfo> m_srb1Old;
std::map <uint8_t, Ptr<LteDataRadioBearerInfo> > m_drbMap;
-
+
bool m_useRlcSm;
uint8_t m_lastRrcTransactionIdentifier;
@@ -306,17 +326,17 @@
uint16_t m_dlEarfcn; /**< downlink carrier frequency */
uint16_t m_ulEarfcn; /**< uplink carrier frequency */
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t, State, State> m_stateTransitionTrace;
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_randomAccessSuccessfulTrace;
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_connectionEstablishedTrace;
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_connectionReconfigurationTrace;
// imsi cellid rnti targetCellId
TracedCallback<uint64_t, uint16_t, uint16_t, uint16_t> m_handoverStartTrace;
- // imsi cellid rnti
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_handoverEndOkTrace;
bool m_connectionPending; /**< true if a connection request by upper layers is pending */
@@ -328,31 +348,31 @@
* Includes the accumulated configuration of the measurements to be
* performed by the UE, see TS 36.331 section 7.1. Also note that some
* optional variables in the specs are omitted.
- *
+ *
*/
struct VarMeasConfig
{
std::map<uint8_t, LteRrcSap::MeasIdToAddMod> measIdList;
std::map<uint8_t, LteRrcSap::MeasObjectToAddMod> measObjectList;
std::map<uint8_t, LteRrcSap::ReportConfigToAddMod> reportConfigList;
- LteRrcSap::QuantityConfig quantityConfig;
+ LteRrcSap::QuantityConfig quantityConfig;
double aRsrp;
double aRsrq;
};
-
+
struct VarMeasReport
{
uint8_t measId;
std::set<uint16_t> cellsTriggeredList; // note: only EUTRA is
- // supported
+ // supported
uint32_t numberOfReportsSent;
EventId periodicReportTimer;
};
-
+
VarMeasConfig m_varMeasConfig;
// measId
std::map<uint8_t, VarMeasReport> m_varMeasReportList;
-
+
struct MeasValues
{
double rsrp;
@@ -362,7 +382,7 @@
/////////cellId
std::map<uint16_t, MeasValues> m_storedMeasValues;
-
+
};
--- a/src/lte/model/pf-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/pf-ff-mac-scheduler.cc Thu Jun 13 11:32:13 2013 +0200
@@ -57,6 +57,7 @@
virtual void CschedLcConfigReq (const struct CschedLcConfigReqParameters& params);
virtual void CschedLcReleaseReq (const struct CschedLcReleaseReqParameters& params);
virtual void CschedUeReleaseReq (const struct CschedUeReleaseReqParameters& params);
+ virtual void CschedMbmsConfigReq (const struct CschedMbmsConfigReqParameters& params);
private:
PfSchedulerMemberCschedSapProvider ();
@@ -103,7 +104,11 @@
m_scheduler->DoCschedUeReleaseReq (params);
}
-
+void
+PfSchedulerMemberCschedSapProvider::CschedMbmsConfigReq (const struct CschedMbmsConfigReqParameters& params)
+{
+ m_scheduler->DoCschedMbmsConfigReq (params);
+}
class PfSchedulerMemberSchedSapProvider : public FfMacSchedSapProvider
@@ -123,7 +128,7 @@
virtual void SchedUlSrInfoReq (const struct SchedUlSrInfoReqParameters& params);
virtual void SchedUlMacCtrlInfoReq (const struct SchedUlMacCtrlInfoReqParameters& params);
virtual void SchedUlCqiInfoReq (const struct SchedUlCqiInfoReqParameters& params);
-
+ virtual void SchedMbmsTriggerReq (const struct SchedDlTriggerReqParameters& params);
private:
PfSchedulerMemberSchedSapProvider ();
@@ -208,6 +213,12 @@
m_scheduler->DoSchedUlCqiInfoReq (params);
}
+void
+PfSchedulerMemberSchedSapProvider::SchedMbmsTriggerReq (const struct SchedDlTriggerReqParameters& params)
+{
+ m_scheduler->DoSchedMbmsTriggerReq (params);
+}
+
@@ -384,7 +395,7 @@
{
std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
- while (it!=m_rlcBufferReq.end ())
+ while (it != m_rlcBufferReq.end ())
{
if (((*it).first.m_rnti == params.m_rnti) && ((*it).first.m_lcId == params.m_logicalChannelIdentity.at (i)))
{
@@ -405,7 +416,7 @@
PfFfMacScheduler::DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params)
{
NS_LOG_FUNCTION (this);
-
+
m_uesTxMode.erase (params.m_rnti);
m_dlHarqCurrentProcessId.erase (params.m_rnti);
m_dlHarqProcessesStatus.erase (params.m_rnti);
@@ -420,7 +431,7 @@
m_ceBsrRxed.erase (params.m_rnti);
std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
- while (it!=m_rlcBufferReq.end ())
+ while (it != m_rlcBufferReq.end ())
{
if ((*it).first.m_rnti == params.m_rnti)
{
@@ -441,6 +452,12 @@
return;
}
+void
+PfFfMacScheduler::DoCschedMbmsConfigReq (const struct FfMacCschedSapProvider::CschedMbmsConfigReqParameters& params)
+{
+ NS_LOG_FUNCTION (this << " MRNTI " << params.m_mrnti << " txMode " << (uint16_t)params.m_transmissionMode);
+}
+
void
PfFfMacScheduler::DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params)
@@ -600,14 +617,14 @@
NS_LOG_FUNCTION (this);
std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itTimers;
- for (itTimers = m_dlHarqProcessesTimer.begin (); itTimers != m_dlHarqProcessesTimer.end (); itTimers ++)
+ for (itTimers = m_dlHarqProcessesTimer.begin (); itTimers != m_dlHarqProcessesTimer.end (); itTimers++)
{
for (uint16_t i = 0; i < HARQ_PROC_NUM; i++)
{
if ((*itTimers).second.at (i) == HARQ_DL_TIMEOUT)
{
// reset HARQ process
-
+
NS_LOG_DEBUG (this << " Reset HARQ proc " << i << " for RNTI " << (*itTimers).first);
std::map <uint16_t, DlHarqProcessesStatus_t>::iterator itStat = m_dlHarqProcessesStatus.find ((*itTimers).first);
if (itStat == m_dlHarqProcessesStatus.end ())
@@ -623,7 +640,7 @@
}
}
}
-
+
}
@@ -919,7 +936,7 @@
(*itHarq).second.at (harqId).m_rv = dci.m_rv;
// refresh timer
std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itHarqTimer = m_dlHarqProcessesTimer.find (rnti);
- if (itHarqTimer== m_dlHarqProcessesTimer.end ())
+ if (itHarqTimer == m_dlHarqProcessesTimer.end ())
{
NS_FATAL_ERROR ("Unable to find HARQ timer for RNTI " << (uint16_t)rnti);
}
@@ -968,13 +985,13 @@
{
// UE already allocated for HARQ or without HARQ process available -> drop it
if (itRnti != rntiAllocated.end ())
- {
- NS_LOG_DEBUG (this << " RNTI discared for HARQ tx" << (uint16_t)(*it).first);
- }
+ {
+ NS_LOG_DEBUG (this << " RNTI discared for HARQ tx" << (uint16_t)(*it).first);
+ }
if (!HarqProcessAvailability ((*it).first))
- {
- NS_LOG_DEBUG (this << " RNTI discared for HARQ id" << (uint16_t)(*it).first);
- }
+ {
+ NS_LOG_DEBUG (this << " RNTI discared for HARQ id" << (uint16_t)(*it).first);
+ }
continue;
}
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
@@ -1220,7 +1237,7 @@
(*itDci).second.at (newDci.m_harqProcess) = newDci;
// refresh timer
std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itHarqTimer = m_dlHarqProcessesTimer.find (newEl.m_rnti);
- if (itHarqTimer== m_dlHarqProcessesTimer.end ())
+ if (itHarqTimer == m_dlHarqProcessesTimer.end ())
{
NS_FATAL_ERROR ("Unable to find HARQ timer for RNTI " << (uint16_t)newEl.m_rnti);
}
@@ -1269,12 +1286,17 @@
}
void
+PfFfMacScheduler::DoSchedMbmsTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params)
+{
+}
+
+void
PfFfMacScheduler::DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params)
{
NS_LOG_FUNCTION (this);
m_rachList = params.m_rachList;
-
+
return;
}
@@ -1412,7 +1434,7 @@
}
for (uint16_t i = 0; i < params.m_ulInfoList.size (); i++)
- {
+ {
if (params.m_ulInfoList.at (i).m_receptionStatus == UlInfoListElement_s::NotOk)
{
// retx correspondent block: retrieve the UL-DCI
@@ -1475,7 +1497,7 @@
ret.m_dciList.push_back (dci);
rntiAllocated.insert (dci.m_rnti);
}
- else
+ else
{
NS_LOG_INFO (this << " HARQ-ACK feedback from RNTI " << params.m_ulInfoList.at (i).m_rnti);
}
@@ -1501,7 +1523,7 @@
{
m_schedSapUser->SchedUlConfigInd (ret);
}
-
+
return; // no flows to be scheduled
}
@@ -1557,7 +1579,7 @@
if (rbPerFlow < 3)
{
// terminate allocation
- rbPerFlow = 0;
+ rbPerFlow = 0;
}
}
@@ -1601,7 +1623,7 @@
if (rbPerFlow < 3)
{
// terminate allocation
- rbPerFlow = 0;
+ rbPerFlow = 0;
}
}
}
@@ -1649,8 +1671,8 @@
// translate SINR -> cqi: WILD ACK: same as DL
double s = log2 ( 1 + (
- std::pow (10, minSinr / 10 ) /
- ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
+ std::pow (10, minSinr / 10 ) /
+ ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
cqi = m_amc->GetCqiFromSpectralEfficiency (s);
if (cqi == 0)
{
@@ -1732,7 +1754,7 @@
break;
}
}
- while (((*it).first != m_nextRntiUl)&&(rbPerFlow!=0));
+ while (((*it).first != m_nextRntiUl)&&(rbPerFlow != 0));
// Update global UE stats
@@ -1790,7 +1812,7 @@
uint8_t bsrId = params.m_macCeList.at (i).m_macCeValue.m_bufferStatus.at (lcg);
buffer += BufferSizeLevelBsr::BsrId2BufferSize (bsrId);
}
-
+
uint16_t rnti = params.m_macCeList.at (i).m_rnti;
NS_LOG_LOGIC (this << "RNTI=" << rnti << " buffer=" << buffer);
it = m_ceBsrRxed.find (rnti);
@@ -2055,7 +2077,7 @@
// Update status queue
if (((*it).second.m_rlcStatusPduSize > 0) && (size >= (*it).second.m_rlcStatusPduSize))
{
- (*it).second.m_rlcStatusPduSize = 0;
+ (*it).second.m_rlcStatusPduSize = 0;
}
else if (((*it).second.m_rlcRetransmissionQueueSize > 0) && (size >= (*it).second.m_rlcRetransmissionQueueSize))
{
@@ -2069,8 +2091,8 @@
// for SRB1 (using RLC AM) it's better to
// overestimate RLC overhead rather than
// underestimate it and risk unneeded
- // segmentation which increases delay
- rlcOverhead = 4;
+ // segmentation which increases delay
+ rlcOverhead = 4;
}
else
{
@@ -2083,7 +2105,7 @@
(*it).second.m_rlcTransmissionQueueSize = 0;
}
else
- {
+ {
(*it).second.m_rlcTransmissionQueueSize -= size - rlcOverhead;
}
}
--- a/src/lte/model/pf-ff-mac-scheduler.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/pf-ff-mac-scheduler.h Thu Jun 13 11:32:13 2013 +0200
@@ -118,6 +118,8 @@
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
+ void DoCschedMbmsConfigReq (const struct FfMacCschedSapProvider::CschedMbmsConfigReqParameters& params);
+
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
@@ -145,6 +147,7 @@
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
+ void DoSchedMbmsTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
int GetRbgSize (int dlbandwidth);
--- a/src/lte/model/rr-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/rr-ff-mac-scheduler.cc Thu Jun 13 11:32:13 2013 +0200
@@ -59,7 +59,7 @@
virtual void CschedLcConfigReq (const struct CschedLcConfigReqParameters& params);
virtual void CschedLcReleaseReq (const struct CschedLcReleaseReqParameters& params);
virtual void CschedUeReleaseReq (const struct CschedUeReleaseReqParameters& params);
-
+ virtual void CschedMbmsConfigReq (const struct CschedMbmsConfigReqParameters& params);
private:
RrSchedulerMemberCschedSapProvider ();
RrFfMacScheduler* m_scheduler;
@@ -105,7 +105,11 @@
m_scheduler->DoCschedUeReleaseReq (params);
}
-
+void
+RrSchedulerMemberCschedSapProvider::CschedMbmsConfigReq (const struct CschedMbmsConfigReqParameters& params)
+{
+ m_scheduler->DoCschedMbmsConfigReq (params);
+}
class RrSchedulerMemberSchedSapProvider : public FfMacSchedSapProvider
@@ -125,7 +129,7 @@
virtual void SchedUlSrInfoReq (const struct SchedUlSrInfoReqParameters& params);
virtual void SchedUlMacCtrlInfoReq (const struct SchedUlMacCtrlInfoReqParameters& params);
virtual void SchedUlCqiInfoReq (const struct SchedUlCqiInfoReqParameters& params);
-
+ virtual void SchedMbmsTriggerReq (const struct SchedDlTriggerReqParameters& params);
private:
RrSchedulerMemberSchedSapProvider ();
@@ -210,7 +214,11 @@
m_scheduler->DoSchedUlCqiInfoReq (params);
}
-
+void
+RrSchedulerMemberSchedSapProvider::SchedMbmsTriggerReq (const struct SchedDlTriggerReqParameters& params)
+{
+ m_scheduler->DoSchedMbmsTriggerReq (params);
+}
@@ -266,6 +274,11 @@
UintegerValue (0),
MakeUintegerAccessor (&RrFfMacScheduler::m_ulGrantMcs),
MakeUintegerChecker<uint8_t> ())
+ .AddAttribute ("Cqi",
+ "Viene impostato manualmente il CQI",
+ UintegerValue (7),
+ MakeUintegerAccessor (&RrFfMacScheduler::m_cqiManual),
+ MakeUintegerChecker<uint32_t> ())
;
return tid;
}
@@ -360,10 +373,10 @@
RrFfMacScheduler::DoCschedLcReleaseReq (const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters& params)
{
NS_LOG_FUNCTION (this);
- for (uint16_t i = 0; i < params.m_logicalChannelIdentity.size (); i++)
+ for (uint16_t i = 0; i < params.m_logicalChannelIdentity.size (); i++)
{
- std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
- while (it!=m_rlcBufferReq.end ())
+ std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
+ while (it != m_rlcBufferReq.end ())
{
if (((*it).m_rnti == params.m_rnti)&&((*it).m_logicalChannelIdentity == params.m_logicalChannelIdentity.at (i)))
{
@@ -382,7 +395,7 @@
RrFfMacScheduler::DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params)
{
NS_LOG_FUNCTION (this << " Release RNTI " << params.m_rnti);
-
+
m_uesTxMode.erase (params.m_rnti);
m_dlHarqCurrentProcessId.erase (params.m_rnti);
m_dlHarqProcessesStatus.erase (params.m_rnti);
@@ -415,42 +428,94 @@
{
m_nextRntiDl = 0;
}
-
+
return;
}
+void
+RrFfMacScheduler::DoCschedMbmsConfigReq (const struct FfMacCschedSapProvider::CschedMbmsConfigReqParameters& params)
+{
+ NS_LOG_FUNCTION (this << " MRNTI " << params.m_mrnti << " txMode " << (uint16_t)params.m_transmissionMode);
+ std::map <uint16_t,uint8_t>::iterator it = m_mbmsTxMode.find (params.m_mrnti);
+
+ if (it == m_mbmsTxMode.end ())
+ {
+ m_mbmsTxMode.insert (std::pair <uint16_t, double> (params.m_mrnti, params.m_transmissionMode));
+ }
+ else
+ {
+ (*it).second = params.m_transmissionMode;
+ }
+ return;
+}
void
RrFfMacScheduler::DoSchedDlRlcBufferReq (const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters& params)
{
- NS_LOG_FUNCTION (this << params.m_rnti << (uint32_t) params.m_logicalChannelIdentity);
- // API generated by RLC for updating RLC parameters on a LC (tx and retx queues)
- std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
- bool newLc = true;
- while (it != m_rlcBufferReq.end ())
+ NS_LOG_FUNCTION (this << params.m_rnti << params.m_mrnti << (uint32_t) params.m_logicalChannelIdentity);
+
+ if (params.m_rnti != 0)
{
- // remove old entries of this UE-LC
- if (((*it).m_rnti == params.m_rnti)&&((*it).m_logicalChannelIdentity == params.m_logicalChannelIdentity))
+ // API generated by RLC for updating RLC parameters on a LC (tx and retx queues)
+ std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
+ bool newLc = true;
+ while (it != m_rlcBufferReq.end ())
{
- it = m_rlcBufferReq.erase (it);
- newLc = false;
+ // remove old entries of this UE-LC
+ if (((*it).m_rnti == params.m_rnti)&&((*it).m_logicalChannelIdentity == params.m_logicalChannelIdentity))
+ {
+ it = m_rlcBufferReq.erase (it);
+ newLc = false;
+ }
+ else
+ {
+ ++it;
+ }
}
- else
+ // add the new parameters
+ m_rlcBufferReq.insert (it, params);
+ NS_LOG_INFO (this << " RNTI " << params.m_rnti << " LC " << (uint16_t)params.m_logicalChannelIdentity << " RLC tx size " << params.m_rlcTransmissionQueueHolDelay << " RLC retx size " << params.m_rlcRetransmissionQueueSize << " RLC stat size " << params.m_rlcStatusPduSize);
+ // initialize statistics of the flow in case of new flows
+ if (newLc == true)
{
- ++it;
+ m_p10CqiRxed.insert ( std::pair<uint16_t, uint8_t > (params.m_rnti, 1)); // only codeword 0 at this stage (SISO)
+ // initialized to 1 (i.e., the lowest value for transmitting a signal)
+ m_p10CqiTimers.insert ( std::pair<uint16_t, uint32_t > (params.m_rnti, m_cqiTimersThreshold));
}
}
- // add the new parameters
- m_rlcBufferReq.insert (it, params);
- NS_LOG_INFO (this << " RNTI " << params.m_rnti << " LC " << (uint16_t)params.m_logicalChannelIdentity << " RLC tx size " << params.m_rlcTransmissionQueueHolDelay << " RLC retx size " << params.m_rlcRetransmissionQueueSize << " RLC stat size " << params.m_rlcStatusPduSize);
- // initialize statistics of the flow in case of new flows
- if (newLc == true)
+ else if (params.m_mrnti != 0)
{
- m_p10CqiRxed.insert ( std::pair<uint16_t, uint8_t > (params.m_rnti, 1)); // only codeword 0 at this stage (SISO)
- // initialized to 1 (i.e., the lowest value for transmitting a signal)
- m_p10CqiTimers.insert ( std::pair<uint16_t, uint32_t > (params.m_rnti, m_cqiTimersThreshold));
+ // API generated by RLC for updating RLC parameters on a LC (tx and retx queues)
+ std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferMbmsReq.begin ();
+ while (it != m_rlcBufferMbmsReq.end ())
+ {
+ // remove old entries of this UE-LC
+ if (((*it).m_mrnti == params.m_mrnti)&&((*it).m_logicalChannelIdentity == params.m_logicalChannelIdentity))
+ {
+ it = m_rlcBufferMbmsReq.erase (it);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ // add the new parameters
+ m_rlcBufferMbmsReq.insert (it, params);
+ NS_LOG_INFO (this << " MRNTI " << params.m_mrnti << " LC " << (uint16_t)params.m_logicalChannelIdentity << " RLC tx size " << params.m_rlcTransmissionQueueHolDelay << " RLC retx size " << params.m_rlcRetransmissionQueueSize << " RLC stat size " << params.m_rlcStatusPduSize);
+ /*
+ // initialize statistics of the flow in case of new flows
+ if (newLc == true)
+ {
+ m_p10CqiRxed.insert ( std::pair<uint16_t, uint8_t > (params.m_rnti, 1)); // only codeword 0 at this stage (SISO)
+ // initialized to 1 (i.e., the lowest value for transmitting a signal)
+ m_p10CqiTimers.insert ( std::pair<uint16_t, uint32_t > (params.m_rnti, m_cqiTimersThreshold));
+ }
+ */
}
-
+ else
+ {
+ NS_LOG_ERROR ("Error!!! C-RNTI=0 and M-RNTI=0");
+ }
return;
}
@@ -490,6 +555,11 @@
return (i.m_rnti < j.m_rnti);
}
+bool
+RrFfMacScheduler::SortRlcBufferMbmsReq (FfMacSchedSapProvider::SchedDlRlcBufferReqParameters i,FfMacSchedSapProvider::SchedDlRlcBufferReqParameters j)
+{
+ return (i.m_mrnti < j.m_mrnti);
+}
uint8_t
RrFfMacScheduler::HarqProcessAvailability (uint16_t rnti)
@@ -571,7 +641,7 @@
NS_LOG_FUNCTION (this);
std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itTimers;
- for (itTimers = m_dlHarqProcessesTimer.begin (); itTimers != m_dlHarqProcessesTimer.end (); itTimers ++)
+ for (itTimers = m_dlHarqProcessesTimer.begin (); itTimers != m_dlHarqProcessesTimer.end (); itTimers++)
{
for (uint16_t i = 0; i < HARQ_PROC_NUM; i++)
{
@@ -887,7 +957,7 @@
(*itHarq).second.at (harqId).m_rv = dci.m_rv;
// refresh timer
std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itHarqTimer = m_dlHarqProcessesTimer.find (rnti);
- if (itHarqTimer== m_dlHarqProcessesTimer.end ())
+ if (itHarqTimer == m_dlHarqProcessesTimer.end ())
{
NS_FATAL_ERROR ("Unable to find HARQ timer for RNTI " << (uint16_t)rnti);
}
@@ -1042,9 +1112,11 @@
// create new BuildDataListElement_s for this RNTI
BuildDataListElement_s newEl;
newEl.m_rnti = (*it).m_rnti;
+ newEl.m_mrnti = 0;
// create the DlDciListElement_s
DlDciListElement_s newDci;
newDci.m_rnti = (*it).m_rnti;
+ newDci.m_mrnti = 0;
newDci.m_harqProcess = UpdateHarqProcessId ((*it).m_rnti);
newDci.m_resAlloc = 0;
newDci.m_rbBitmap = 0;
@@ -1137,7 +1209,7 @@
(*itDci).second.at (newDci.m_harqProcess) = newDci;
// refresh timer
std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itHarqTimer = m_dlHarqProcessesTimer.find (newEl.m_rnti);
- if (itHarqTimer== m_dlHarqProcessesTimer.end ())
+ if (itHarqTimer == m_dlHarqProcessesTimer.end ())
{
NS_FATAL_ERROR ("Unable to find HARQ timer for RNTI " << (uint16_t)newEl.m_rnti);
}
@@ -1154,7 +1226,7 @@
}
while ((*it).m_rnti != m_nextRntiDl);
- ret.m_nrOfPdcchOfdmSymbols = 1; // TODO: check correct value according the DCIs txed
+ ret.m_nrOfPdcchOfdmSymbols = 1; // TODO: check correct value according the DCIs txed
m_schedSapUser->SchedDlConfigInd (ret);
return;
@@ -1164,7 +1236,7 @@
RrFfMacScheduler::DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params)
{
NS_LOG_FUNCTION (this);
-
+
m_rachList = params.m_rachList;
return;
@@ -1216,6 +1288,218 @@
}
void
+RrFfMacScheduler::DoSchedMbmsTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params)
+{
+ NS_LOG_FUNCTION (this << " DL Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf));
+ // API generated by RLC for triggering the scheduling of a DL subframe
+
+ RefreshDlCqiMaps ();
+ int rbgSize = GetRbgSize (m_cschedCellConfig.m_dlBandwidth);
+ int rbgNum = m_cschedCellConfig.m_dlBandwidth / rbgSize;
+ FfMacSchedSapUser::SchedDlConfigIndParameters ret;
+
+ // Generate RBGs map
+ std::vector <bool> rbgMap;
+ uint16_t rbgAllocatedNum = 0;
+ std::set <uint16_t> mrntiAllocated;
+ rbgMap.resize (m_cschedCellConfig.m_dlBandwidth / rbgSize, false);
+
+
+ // Get the actual active flows (queue!=0)
+ std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
+ m_rlcBufferMbmsReq.sort (SortRlcBufferReq);
+ int nflows = 0;
+ int nTbs = 0;
+ std::map <uint16_t,uint8_t> lcActivesPerMrnti; // tracks how many active LCs per RNTI there are
+ std::map <uint16_t,uint8_t>::iterator itLcMrnti;
+ for (it = m_rlcBufferMbmsReq.begin (); it != m_rlcBufferMbmsReq.end (); it++)
+ {
+ // remove old entries of this MBMS-LC
+ std::set <uint16_t>::iterator itMrnti = mrntiAllocated.find ((*it).m_mrnti);
+ if ( (((*it).m_rlcTransmissionQueueSize > 0)
+ || ((*it).m_rlcRetransmissionQueueSize > 0)
+ || ((*it).m_rlcStatusPduSize > 0))
+ && (itMrnti == mrntiAllocated.end ())
+ )
+
+ {
+ NS_LOG_LOGIC (this << " MBMS " << (*it).m_mrnti << " LC " << (uint16_t)(*it).m_logicalChannelIdentity << " is active, status " << (*it).m_rlcStatusPduSize);
+ nflows++;
+ itLcMrnti = lcActivesPerMrnti.find ((*it).m_mrnti);
+ if (itLcMrnti != lcActivesPerMrnti.end ())
+ {
+ (*itLcMrnti).second++;
+ }
+ else
+ {
+ lcActivesPerMrnti.insert (std::pair<uint16_t, uint8_t > ((*it).m_mrnti, 1));
+ // nTbs++;
+ }
+ }
+ }
+
+ if (nflows == 0)
+ {
+ if ((ret.m_buildDataList.size () > 0) || (ret.m_buildRarList.size () > 0))
+ {
+ m_schedSapUser->SchedDlConfigInd (ret);
+ }
+ return;
+ }
+ // Divide the resource equally among the active users according to
+ // Resource allocation type 0 (see sec 7.1.6.1 of 36.213)
+ nTbs = 1;
+ int rbgPerTb = (rbgNum - rbgAllocatedNum) / nTbs;
+ NS_LOG_INFO (this << " Flows to be transmitted " << nflows << " rbgPerTb " << rbgPerTb);
+ if (rbgPerTb == 0)
+ {
+ rbgPerTb = 1; // at least 1 rbg per TB (till available resource)
+ }
+ int rbgAllocated = 0;
+
+ // round robin assignment to all UEs registered starting from the subsequent of the one
+ // served last scheduling trigger event
+ if (m_nextMrntiDl != 0)
+ {
+ for (it = m_rlcBufferMbmsReq.begin (); it != m_rlcBufferMbmsReq.end (); it++)
+ {
+ if ((*it).m_mrnti == m_nextMrntiDl)
+ {
+ break;
+ }
+ }
+
+ if (it == m_rlcBufferMbmsReq.end ())
+ {
+ NS_LOG_ERROR (this << " no user found");
+ }
+ }
+ else
+ {
+ it = m_rlcBufferMbmsReq.begin ();
+ m_nextMrntiDl = (*it).m_mrnti;
+ }
+ std::map <uint16_t,uint8_t>::iterator itTxMode;
+ do
+ {
+ itLcMrnti = lcActivesPerMrnti.find ((*it).m_mrnti);
+ std::set <uint16_t>::iterator itMrnti = mrntiAllocated.find ((*it).m_mrnti);
+ if ((itLcMrnti == lcActivesPerMrnti.end ())||(itMrnti != mrntiAllocated.end ()))
+ {
+ // skip this RNTI (no active queue or yet allocated for HARQ)
+ uint16_t mrntiDiscared = (*it).m_mrnti;
+ while (it != m_rlcBufferMbmsReq.end ())
+ {
+ if ((*it).m_mrnti != mrntiDiscared)
+ {
+ break;
+ }
+ it++;
+ }
+ if (it == m_rlcBufferMbmsReq.end ())
+ {
+ // restart from the first
+ it = m_rlcBufferMbmsReq.begin ();
+ }
+ continue;
+ }
+
+ itTxMode = m_mbmsTxMode.find ((*it).m_mrnti);
+ if (itTxMode == m_mbmsTxMode.end ())
+ {
+ NS_FATAL_ERROR ("No Transmission Mode info on user " << (*it).m_mrnti);
+ }
+ int nLayer = TransmissionModesLayers::TxMode2LayerNum ((*itTxMode).second);
+ int lcNum = (*itLcMrnti).second;
+ // create new BuildDataListElementMbms_s for this M-RNTI
+ BuildDataListElement_s newEl;
+ newEl.m_rnti = 0;
+ newEl.m_mrnti = (*it).m_mrnti;
+ // create the DlDciListElement_s
+ DlDciListElement_s newDci;
+ newDci.m_rnti = 0;
+ newDci.m_mrnti = (*it).m_mrnti;
+ //newDci.m_harqProcess = UpdateHarqProcessId ((*it).m_rnti); // No HARQ
+ newDci.m_resAlloc = 0;
+ newDci.m_rbBitmap = 0;
+
+ for (uint8_t i = 0; i < nLayer; i++)
+ {
+ newDci.m_mcs.push_back ( m_amc->GetMcsFromCqi (m_cqiManual));
+ }
+ int tbSize = (m_amc->GetTbSizeFromMcs (newDci.m_mcs.at (0), rbgPerTb * rbgSize) / 8);
+ uint16_t rlcPduSize = tbSize / lcNum;
+ while ((*it).m_mrnti == newEl.m_mrnti)
+ {
+ if ( ((*it).m_rlcTransmissionQueueSize > 0)
+ || ((*it).m_rlcRetransmissionQueueSize > 0)
+ || ((*it).m_rlcStatusPduSize > 0) )
+ {
+ std::vector <struct RlcPduListElement_s> newRlcPduLe;
+ for (uint8_t j = 0; j < nLayer; j++)
+ {
+ RlcPduListElement_s newRlcEl;
+ newRlcEl.m_logicalChannelIdentity = (*it).m_logicalChannelIdentity;
+ NS_LOG_INFO (this << "LCID " << (uint32_t) newRlcEl.m_logicalChannelIdentity << " size " << rlcPduSize << " ID " << (*it).m_rnti << " layer " << (uint16_t)j);
+ newRlcEl.m_size = rlcPduSize;
+ UpdateDlRlcBufferInfo ((*it).m_rnti, newRlcEl.m_logicalChannelIdentity, rlcPduSize);
+ newRlcPduLe.push_back (newRlcEl);
+ }
+ newEl.m_rlcPduList.push_back (newRlcPduLe);
+ lcNum--;
+ }
+ it++;
+ if (it == m_rlcBufferMbmsReq.end ())
+ {
+ // restart from the first
+ it = m_rlcBufferMbmsReq.begin ();
+ break;
+ }
+ }
+ uint32_t rbgMask = 0;
+ uint16_t i = 0;
+ NS_LOG_INFO (this << " DL - Allocate user " << newEl.m_mrnti << " LCs " << (uint16_t)(*itLcMrnti).second << " bytes " << tbSize << " mcs " << (uint16_t) newDci.m_mcs.at (0));
+ NS_LOG_INFO ("RBG:");
+ while (i < rbgPerTb)
+ {
+ if (rbgMap.at (rbgAllocated) == false)
+ {
+ rbgMask = rbgMask + (0x1 << rbgAllocated);
+ NS_LOG_INFO ("\t " << rbgAllocated);
+ i++;
+ rbgMap.at (rbgAllocated) = true;
+ rbgAllocatedNum++;
+ }
+ rbgAllocated++;
+ }
+ newDci.m_rbBitmap = rbgMask; // (32 bit bitmap see 7.1.6 of 36.213)
+
+ for (int i = 0; i < nLayer; i++)
+ {
+ newDci.m_tbsSize.push_back (tbSize);
+ newDci.m_ndi.push_back (1);
+ newDci.m_rv.push_back (0);
+ }
+ newEl.m_dci = newDci;
+
+
+ ret.m_buildDataList.push_back (newEl);
+ if (rbgAllocatedNum == rbgNum)
+ {
+ m_nextMrntiDl = newEl.m_mrnti; // store last RNTI served
+ break; // no more RGB to be allocated
+ }
+ }
+ while ((*it).m_mrnti != m_nextMrntiDl);
+
+ ret.m_nrOfPdcchOfdmSymbols = 1; // TODO: check correct value according the DCIs txed
+
+ m_schedSapUser->SchedDlConfigIndMbms (ret);
+ return;
+
+}
+
+void
RrFfMacScheduler::DoSchedUlTriggerReq (const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters& params)
{
NS_LOG_FUNCTION (this << " UL - Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf) << " size " << params.m_ulInfoList.size ());
@@ -1394,7 +1678,7 @@
if (rbPerFlow < 3)
{
// terminate allocation
- rbPerFlow = 0;
+ rbPerFlow = 0;
}
}
NS_LOG_INFO (this << " try to allocate " << (*it).first);
@@ -1439,7 +1723,7 @@
if (rbPerFlow < 3)
{
// terminate allocation
- rbPerFlow = 0;
+ rbPerFlow = 0;
}
}
}
@@ -1475,8 +1759,8 @@
}
// translate SINR -> cqi: WILD ACK: same as DL
double s = log2 ( 1 + (
- std::pow (10, minSinr / 10 ) /
- ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
+ std::pow (10, minSinr / 10 ) /
+ ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
cqi = m_amc->GetCqiFromSpectralEfficiency (s);
@@ -1547,7 +1831,7 @@
break;
}
}
- while (((*it).first != m_nextRntiUl)&&(rbPerFlow!=0));
+ while (((*it).first != m_nextRntiUl)&&(rbPerFlow != 0));
m_allocationMaps.insert (std::pair <uint16_t, std::vector <uint16_t> > (params.m_sfnSf, rbgAllocationMap));
@@ -1834,40 +2118,40 @@
NS_LOG_INFO (this << " UE " << rnti << " LC " << (uint16_t)lcid << " txqueue " << (*it).m_rlcTransmissionQueueSize << " retxqueue " << (*it).m_rlcRetransmissionQueueSize << " status " << (*it).m_rlcStatusPduSize << " decrease " << size);
// Update queues: RLC tx order Status, ReTx, Tx
// Update status queue
- if (((*it).m_rlcStatusPduSize > 0) && (size >= (*it).m_rlcStatusPduSize))
- {
- (*it).m_rlcStatusPduSize = 0;
- }
- else if (((*it).m_rlcRetransmissionQueueSize > 0) && (size >= (*it).m_rlcRetransmissionQueueSize))
- {
- (*it).m_rlcRetransmissionQueueSize = 0;
- }
- else if ((*it).m_rlcTransmissionQueueSize > 0)
- {
- uint32_t rlcOverhead;
- if (lcid == 1)
- {
- // for SRB1 (using RLC AM) it's better to
- // overestimate RLC overhead rather than
- // underestimate it and risk unneeded
- // segmentation which increases delay
- rlcOverhead = 4;
- }
- else
- {
- // minimum RLC overhead due to header
- rlcOverhead = 2;
- }
- // update transmission queue
- if ((*it).m_rlcTransmissionQueueSize <= size - rlcOverhead)
- {
- (*it).m_rlcTransmissionQueueSize = 0;
- }
- else
- {
- (*it).m_rlcTransmissionQueueSize -= size - rlcOverhead;
- }
- }
+ if (((*it).m_rlcStatusPduSize > 0) && (size >= (*it).m_rlcStatusPduSize))
+ {
+ (*it).m_rlcStatusPduSize = 0;
+ }
+ else if (((*it).m_rlcRetransmissionQueueSize > 0) && (size >= (*it).m_rlcRetransmissionQueueSize))
+ {
+ (*it).m_rlcRetransmissionQueueSize = 0;
+ }
+ else if ((*it).m_rlcTransmissionQueueSize > 0)
+ {
+ uint32_t rlcOverhead;
+ if (lcid == 1)
+ {
+ // for SRB1 (using RLC AM) it's better to
+ // overestimate RLC overhead rather than
+ // underestimate it and risk unneeded
+ // segmentation which increases delay
+ rlcOverhead = 4;
+ }
+ else
+ {
+ // minimum RLC overhead due to header
+ rlcOverhead = 2;
+ }
+ // update transmission queue
+ if ((*it).m_rlcTransmissionQueueSize <= size - rlcOverhead)
+ {
+ (*it).m_rlcTransmissionQueueSize = 0;
+ }
+ else
+ {
+ (*it).m_rlcTransmissionQueueSize -= size - rlcOverhead;
+ }
+ }
return;
}
}
@@ -1898,6 +2182,57 @@
}
+void
+RrFfMacScheduler::UpdateMbmsRlcBufferInfo (uint16_t mrnti, uint8_t lcid, uint16_t size)
+{
+ NS_LOG_FUNCTION (this);
+ std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
+ for (it = m_rlcBufferMbmsReq.begin (); it != m_rlcBufferMbmsReq.end (); it++)
+ {
+ if (((*it).m_mrnti == mrnti) && ((*it).m_logicalChannelIdentity == lcid))
+ {
+ NS_LOG_INFO (this << " MRNTI " << mrnti << " LC " << (uint16_t)lcid << " txqueue " << (*it).m_rlcTransmissionQueueSize << " retxqueue " << (*it).m_rlcRetransmissionQueueSize << " status " << (*it).m_rlcStatusPduSize << " decrease " << size);
+ // Update queues: RLC tx order Status, ReTx, Tx
+ // Update status queue
+ if (((*it).m_rlcStatusPduSize > 0) && (size >= (*it).m_rlcStatusPduSize))
+ {
+ (*it).m_rlcStatusPduSize = 0;
+ }
+ else if (((*it).m_rlcRetransmissionQueueSize > 0) && (size >= (*it).m_rlcRetransmissionQueueSize))
+ {
+ (*it).m_rlcRetransmissionQueueSize = 0;
+ }
+ else if ((*it).m_rlcTransmissionQueueSize > 0)
+ {
+ uint32_t rlcOverhead;
+ if (lcid == 1)
+ {
+ // for SRB1 (using RLC AM) it's better to
+ // overestimate RLC overhead rather than
+ // underestimate it and risk unneeded
+ // segmentation which increases delay
+ rlcOverhead = 4;
+ }
+ else
+ {
+ // minimum RLC overhead due to header
+ rlcOverhead = 2;
+ }
+ // update transmission queue
+ if ((*it).m_rlcTransmissionQueueSize <= size - rlcOverhead)
+ {
+ (*it).m_rlcTransmissionQueueSize = 0;
+ }
+ else
+ {
+ (*it).m_rlcTransmissionQueueSize -= size - rlcOverhead;
+ }
+ }
+ return;
+ }
+ }
+}
+
void
RrFfMacScheduler::TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode)
--- a/src/lte/model/rr-ff-mac-scheduler.h Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/model/rr-ff-mac-scheduler.h Thu Jun 13 11:32:13 2013 +0200
@@ -105,6 +105,8 @@
void DoCschedUeReleaseReq (const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters& params);
+ void DoCschedMbmsConfigReq (const struct FfMacCschedSapProvider::CschedMbmsConfigReqParameters& params);
+
//
// Implementation of the SCHED API primitives
// (See 4.2 for description of the primitives)
@@ -132,10 +134,12 @@
void DoSchedUlCqiInfoReq (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params);
+ void DoSchedMbmsTriggerReq (const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters& params);
int GetRbgSize (int dlbandwidth);
static bool SortRlcBufferReq (FfMacSchedSapProvider::SchedDlRlcBufferReqParameters i,FfMacSchedSapProvider::SchedDlRlcBufferReqParameters j);
+ static bool SortRlcBufferMbmsReq (FfMacSchedSapProvider::SchedDlRlcBufferReqParameters i,FfMacSchedSapProvider::SchedDlRlcBufferReqParameters j);
void RefreshDlCqiMaps (void);
void RefreshUlCqiMaps (void);
@@ -143,6 +147,8 @@
void UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size);
void UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size);
+ void UpdateMbmsRlcBufferInfo (uint16_t mrnti, uint8_t lcid, uint16_t size);
+
/**
* \brief Update and return a new process Id for the RNTI specified
*
@@ -172,6 +178,11 @@
*/
std::list <FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferReq;
+ /**
+ * Vectors of MBMS's RLC info
+ */
+ std::list <FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> m_rlcBufferMbmsReq;
+
/*
* Map of UE's DL CQI P01 received
*/
@@ -216,11 +227,14 @@
uint16_t m_nextRntiDl; // RNTI of the next user to be served next scheduling in DL
uint16_t m_nextRntiUl; // RNTI of the next user to be served next scheduling in UL
+ uint16_t m_nextMrntiDl; // M-RNTI of the next MBMS flow to be served next scheduling in DL
+
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::map <uint16_t, uint8_t> m_mbmsTxMode; //txMode of the MBMS
-
+ uint16_t m_cqiManual;
// HARQ attributes
/**
@@ -249,6 +263,9 @@
std::vector <struct RachListElement_s> m_rachList;
std::vector <uint16_t> m_rachAllocationMap;
uint8_t m_ulGrantMcs; // MCS for UL grant (default 0)
+
+
+
};
} // namespace ns3
--- a/src/lte/wscript Tue Jun 04 17:20:40 2013 +0200
+++ b/src/lte/wscript Thu Jun 13 11:32:13 2013 +0200
@@ -62,6 +62,7 @@
'model/lte-ue-mac.cc',
'model/lte-radio-bearer-tag.cc',
'model/eps-bearer-tag.cc',
+ 'model/eps-bearer-mbms-tag.cc',
'model/lte-phy-tag.cc',
'model/lte-enb-phy-sap.cc',
'model/lte-enb-cphy-sap.cc',
@@ -70,18 +71,11 @@
'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',
'model/epc-sgw-pgw-application.cc',
+ 'model/epc-mbmsgw-application.cc',
'model/epc-x2-sap.cc',
'model/epc-x2-header.cc',
'model/epc-x2.cc',
@@ -92,12 +86,25 @@
'model/epc-enb-s1-sap.cc',
'model/epc-s1ap-sap.cc',
'model/epc-s11-sap.cc',
+ 'model/epc-m1-sap.cc',
+ 'model/epc-m2-sap.cc',
+ 'model/epc-m3-sap.cc',
+ 'model/epc-sm-sap.cc',
+ 'model/epc-sgimb-sap.cc',
'model/lte-as-sap.cc',
'model/epc-ue-nas.cc',
'model/lte-harq-phy.cc',
'model/epc-mme.cc',
+ 'model/epc-mce.cc',
'model/lte-asn1-header.cc',
'model/lte-rrc-header.cc',
+ 'model/lte-mrnti-tag.cc',
+ 'helper/mbms-stats-calculator/helper/mbms-monitor-helper.cc',
+ 'helper/mbms-stats-calculator/model/mbms-monitor.cc',
+ 'helper/mbms-stats-calculator/model/mbms-classifier.cc',
+ 'helper/mbms-stats-calculator/model/mbms-ipv4-flow-probe.cc',
+ 'helper/mbms-stats-calculator/model/mbms-ipv4-flow-classifier.cc',
+ 'helper/mbms-stats-calculator/model/mbms-probe.cc',
]
module_test = bld.create_ns3_module_test_library('lte')
@@ -110,14 +117,6 @@
'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',
@@ -206,6 +205,7 @@
'model/lte-ue-mac.h',
'model/lte-radio-bearer-tag.h',
'model/eps-bearer-tag.h',
+ 'model/eps-bearer-mbms-tag.h',
'model/lte-phy-tag.h',
'model/lte-enb-phy-sap.h',
'model/lte-enb-cphy-sap.h',
@@ -214,18 +214,11 @@
'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',
'model/epc-sgw-pgw-application.h',
+ 'model/epc-mbmsgw-application.h',
'model/lte-vendor-specific-parameters.h',
'model/epc-x2-sap.h',
'model/epc-x2-header.h',
@@ -236,12 +229,26 @@
'model/epc-enb-s1-sap.h',
'model/epc-s1ap-sap.h',
'model/epc-s11-sap.h',
+ 'model/epc-m1-sap.h',
+ 'model/epc-m2-sap.h',
+ 'model/epc-m3-sap.h',
+ 'model/epc-sm-sap.h',
+ 'model/epc-sgimb-sap.h',
'model/lte-as-sap.h',
'model/epc-ue-nas.h',
'model/lte-harq-phy.h',
'model/epc-mme.h',
+ 'model/epc-mce.h',
'model/lte-asn1-header.h',
'model/lte-rrc-header.h',
+ 'model/lte-mrnti-tag.h',
+ 'helper/mbms-stats-calculator/helper/mbms-monitor-helper.h',
+ 'helper/mbms-stats-calculator/model/mbms-monitor.h',
+ 'helper/mbms-stats-calculator/model/mbms-classifier.h',
+ 'helper/mbms-stats-calculator/model/mbms-ipv4-flow-probe.h',
+ 'helper/mbms-stats-calculator/model/mbms-ipv4-flow-classifier.h',
+ 'helper/mbms-stats-calculator/model/mbms-probe.h',
+
]
if (bld.env['ENABLE_EXAMPLES']):