This commit is contained in:
Marco Miozzo
2012-12-03 18:48:23 +01:00
2 changed files with 344 additions and 0 deletions

View File

@@ -0,0 +1,260 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Nicola Baldo <nbaldo@cttc.es>
*/
#include <ns3/log.h>
#include "radio-bearer-stats-connector.h"
#include "radio-bearer-stats-calculator.h"
#include <ns3/lte-enb-rrc.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-rrc.h>
#include <ns3/lte-ue-net-device.h>
NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsConnector");
namespace ns3 {
struct BoundCallbackArgument : public SimpleRefCount<BoundCallbackArgument>
{
public:
Ptr<RadioBearerStatsCalculator> stats;
uint64_t imsi;
uint16_t cellId;
};
void
DlTxPduCallback (Ptr<BoundCallbackArgument> arg, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize)
{
NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize);
arg->stats->DlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
}
void
DlRxPduCallback (Ptr<BoundCallbackArgument> arg, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize << delay);
arg->stats->DlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
}
void
UlTxPduCallback (Ptr<BoundCallbackArgument> arg, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize)
{
NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize);
arg->stats->UlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
}
void
UlRxPduCallback (Ptr<BoundCallbackArgument> arg, std::string path,
uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize << delay);
arg->stats->UlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
}
RadioBearerStatsConnector::RadioBearerStatsConnector ()
: m_connected (false)
{
}
void
RadioBearerStatsConnector::EnableRlcStats (Ptr<RadioBearerStatsCalculator> rlcStats)
{
m_rlcStats = rlcStats;
EnsureConnected ();
}
void
RadioBearerStatsConnector::EnablePdcpStats (Ptr<RadioBearerStatsCalculator> pdcpStats)
{
m_pdcpStats = pdcpStats;
EnsureConnected ();
}
void
RadioBearerStatsConnector::EnsureConnected ()
{
NS_LOG_FUNCTION (this);
if (!m_connected)
{
Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/ConnectionReconfiguration",
MakeBoundCallback (&RadioBearerStatsConnector::NotifyConnectionReconfigurationEnb, this));
Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionReconfiguration",
MakeBoundCallback (&RadioBearerStatsConnector::NotifyConnectionReconfigurationUe, this));
Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart",
MakeBoundCallback (&RadioBearerStatsConnector::NotifyHandoverStartEnb, this));
Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
MakeBoundCallback (&RadioBearerStatsConnector::NotifyHandoverStartUe, this));
Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk",
MakeBoundCallback (&RadioBearerStatsConnector::NotifyHandoverEndOkEnb, this));
Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk",
MakeBoundCallback (&RadioBearerStatsConnector::NotifyHandoverEndOkUe, this));
}
}
void
RadioBearerStatsConnector::NotifyConnectionReconfigurationUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
c->ConnectTracesUeIfFirstTime (context, imsi, cellid, rnti);
}
void
RadioBearerStatsConnector::NotifyHandoverStartUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
{
c->DisconnectTracesUe (context, imsi, cellid, rnti);
}
void
RadioBearerStatsConnector::NotifyHandoverEndOkUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
c->ConnectTracesUe (context, imsi, cellid, rnti);
}
void
RadioBearerStatsConnector::NotifyConnectionReconfigurationEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
c->ConnectTracesEnbIfFirstTime (context, imsi, cellid, rnti);
}
void
RadioBearerStatsConnector::NotifyHandoverStartEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
{
c->DisconnectTracesEnb (context, imsi, cellid, rnti);
}
void
RadioBearerStatsConnector::NotifyHandoverEndOkEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
c->ConnectTracesEnb (context, imsi, cellid, rnti);
}
void
RadioBearerStatsConnector::ConnectTracesUeIfFirstTime (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
NS_LOG_FUNCTION (this << context);
if (m_imsiSeenUe.find (imsi) == m_imsiSeenUe.end ())
{
m_imsiSeenUe.insert (imsi);
ConnectTracesUe (context, imsi, cellid, rnti);
}
}
void
RadioBearerStatsConnector::ConnectTracesEnbIfFirstTime (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
NS_LOG_FUNCTION (this << context);
if (m_imsiSeenEnb.find (imsi) == m_imsiSeenEnb.end ())
{
m_imsiSeenEnb.insert (imsi);
ConnectTracesEnb (context, imsi, cellid, rnti);
}
}
void
RadioBearerStatsConnector::ConnectTracesUe (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
NS_LOG_FUNCTION (this << context);
NS_LOG_LOGIC (this << "expected context should match /NodeList/*/DeviceList/*/LteUeRrc/");
std::string basePath = context.substr (0, context.rfind ("/"));
if (m_rlcStats)
{
Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
arg->imsi = imsi;
arg->cellId = cellid;
arg->stats = m_rlcStats;
Config::Connect (basePath + "/DataRadioBearerMap/*/LteRlc/TxPDU",
MakeBoundCallback (&UlTxPduCallback, arg));
Config::Connect (basePath + "/DataRadioBearerMap/*/LteRlc/RxPDU",
MakeBoundCallback (&DlRxPduCallback, arg));
}
if (m_pdcpStats)
{
Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
arg->imsi = imsi;
arg->cellId = cellid;
arg->stats = m_pdcpStats;
Config::Connect (basePath + "/DataRadioBearerMap/*/LtePdcp/RxPDU",
MakeBoundCallback (&DlRxPduCallback, arg));
Config::Connect (basePath + "/DataRadioBearerMap/*/LtePdcp/TxPDU",
MakeBoundCallback (&UlTxPduCallback, arg));
}
}
void
RadioBearerStatsConnector::ConnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
NS_LOG_FUNCTION (this << context);
NS_LOG_LOGIC (this << "expected context should match /NodeList/*/DeviceList/*/LteEnbRrc/");
std::ostringstream basePath;
basePath << context.substr (0, context.rfind ("/")) << "/UeMap/" << (uint32_t) rnti << "/DataRadioBearerMap/*/";
if (m_rlcStats)
{
Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
arg->imsi = imsi;
arg->cellId = cellid;
arg->stats = m_rlcStats;
Config::Connect (basePath.str () + "LteRlc/RxPDU",
MakeBoundCallback (&UlRxPduCallback, arg));
Config::Connect (basePath.str () + "LteRlc/TxPDU",
MakeBoundCallback (&DlTxPduCallback, arg));
}
if (m_pdcpStats)
{
Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
arg->imsi = imsi;
arg->cellId = cellid;
arg->stats = m_pdcpStats;
Config::Connect (basePath.str () + "LtePdcp/TxPDU",
MakeBoundCallback (&DlTxPduCallback, arg));
Config::Connect (basePath.str () + "LtePdcp/RxPDU",
MakeBoundCallback (&UlRxPduCallback, arg));
}
}
void
RadioBearerStatsConnector::DisconnectTracesUe (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
NS_LOG_FUNCTION (this);
}
void
RadioBearerStatsConnector::DisconnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
{
NS_LOG_FUNCTION (this);
}
} // namespace ns3

View File

@@ -0,0 +1,84 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Nicola Baldo <nbaldo@cttc.es>
*/
#ifndef RADIO_BEARER_STATS_CONNECTOR_H
#define RADIO_BEARER_STATS_CONNECTOR_H
#include <ns3/traced-callback.h>
#include <ns3/config.h>
#include <ns3/simple-ref-count.h>
#include <ns3/ptr.h>
#include <set>
namespace ns3 {
class RadioBearerStatsCalculator;
class RadioBearerStatsConnector
{
public:
static uint64_t FindImsiFromEnbRlcPath (std::string path);
static uint16_t FindCellIdFromEnbRlcPath (std::string path);
static uint64_t FindImsiFromUeRlcPath (std::string path);
static uint16_t FindCellIdFromUeRlcPath (std::string path);
RadioBearerStatsConnector ();
void EnableRlcStats (Ptr<RadioBearerStatsCalculator> rlcStats);
void EnablePdcpStats (Ptr<RadioBearerStatsCalculator> pdcpStats);
void EnsureConnected ();
// trace sinks, to be used with MakeBoundCallback
static void NotifyConnectionReconfigurationUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
static void NotifyHandoverStartUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId);
static void NotifyHandoverEndOkUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
static void NotifyConnectionReconfigurationEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
static void NotifyHandoverStartEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId);
static void NotifyHandoverEndOkEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
private:
void ConnectTracesUeIfFirstTime (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
void ConnectTracesEnbIfFirstTime (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
void ConnectTracesUe (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
void DisconnectTracesUe (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
void ConnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
void DisconnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti);
Ptr<RadioBearerStatsCalculator> m_rlcStats;
Ptr<RadioBearerStatsCalculator> m_pdcpStats;
bool m_connected;
std::set<uint64_t> m_imsiSeenUe;
std::set<uint64_t> m_imsiSeenEnb;
};
} // namespace ns3
#endif // RADIO_BEARER_STATS_CONNECTOR_H