void
LenaPssFfMacSchedulerTestCase2::DoRun (void)
{

  if (!m_errorModelEnabled)
    {
      Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
      Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
    }

  Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (true));


  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
  Ptr<PointToPointEpcHelper>  epcHelper = CreateObject<PointToPointEpcHelper> ();
  lteHelper->SetEpcHelper (epcHelper);

  Ptr<Node> pgw = epcHelper->GetPgwNode ();

  // Create a single RemoteHost
  NodeContainer remoteHostContainer;
  remoteHostContainer.Create (1);
  Ptr<Node> remoteHost = remoteHostContainer.Get (0);
  InternetStackHelper internet;
  internet.Install (remoteHostContainer);

  // Create the Internet
  PointToPointHelper p2ph;
  p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
  p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
  p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
  NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
  Ipv4AddressHelper ipv4h;
  ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
  // interface 0 is localhost, 1 is the p2p device
  Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);

  Ipv4StaticRoutingHelper ipv4RoutingHelper;
  Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
  remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);


//   LogComponentDisableAll (LOG_LEVEL_ALL);
  //LogComponentEnable ("LenaTestPssFfMacCheduler", LOG_LEVEL_ALL);
   
  lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));

  // Create Nodes: eNodeB and UE
  NodeContainer enbNodes;
  NodeContainer ueNodes;
  enbNodes.Create (1);
  ueNodes.Create (m_nUser);

  // Install Mobility Model
  MobilityHelper mobility;
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (enbNodes);
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (ueNodes);

  // Create Devices and install them in the Nodes (eNB and UE)
  NetDeviceContainer enbDevs;
  NetDeviceContainer ueDevs;
  lteHelper->SetSchedulerType ("ns3::PssFfMacScheduler");
  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
  ueDevs = lteHelper->InstallUeDevice (ueNodes);

  Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
  Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
  enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
  enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));

  // Set UEs' position and power
  for (int i = 0; i < m_nUser; i++)
    {
      Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
      mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
      Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
      Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
      uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
      uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
    }

  // Install the IP stack on the UEs
  internet.Install (ueNodes);
  Ipv4InterfaceContainer ueIpIface;
  ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));

  // Assign IP address to UEs
  for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
    {
      Ptr<Node> ueNode = ueNodes.Get (u);
      // Set the default gateway for the UE
      Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
      ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
    }

  // Attach a UE to a eNB
  lteHelper->Attach (ueDevs, enbDevs.Get (0));

  // Activate an EPS bearer on all UEs

  for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
    {
      Ptr<NetDevice> ueDevice = ueDevs.Get (u);
      GbrQosInformation qos;
      qos.gbrDl = (m_packetSize.at (u) + 32) * (1000 / m_interval) * 8;  // bit/s, considering IP, UDP, RLC, PDCP header size
      qos.gbrUl = (m_packetSize.at (u) + 32) * (1000 / m_interval) * 8;
      qos.mbrDl = qos.gbrDl;
      qos.mbrUl = qos.gbrUl;
  
      enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
      EpsBearer bearer (q, qos);
      lteHelper->ActivateDedicatedEpsBearer (ueDevice, bearer, EpcTft::Default ());  
    }


  // Install downlind and uplink applications
  uint16_t dlPort = 1234;
  uint16_t ulPort = 2000;
  PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
  PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
  ApplicationContainer clientApps;
  ApplicationContainer serverApps;
  for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
    {
      ++ulPort;
      serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
      serverApps.Add (ulPacketSinkHelper.Install (remoteHost));  // receive packets from UEs

      UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
      dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
      dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
      dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));

      UdpClientHelper ulClient (remoteHostAddr, ulPort);           // downlink packets generator
      ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
      ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
      ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));

      clientApps.Add (dlClient.Install (remoteHost));
      clientApps.Add (ulClient.Install (ueNodes.Get (u)));
   }

  serverApps.Start (Seconds (0.030));
  clientApps.Start (Seconds (0.030));

  double statsStartTime = 0.04; // need to allow for RRC connection establishment + SRS
  double statsDuration = 0.5;
  double tolerance = 0.1;
  Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.0001));

  lteHelper->EnableRlcTraces ();
  Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
  rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime)));
  rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (statsDuration)));


  Simulator::Run ();

  /**
   * Check that the downlink assignation is done in a "token bank fair queue" manner
   */

  NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s)");
  std::vector <uint64_t> dlDataRxed;
  for (int i = 0; i < m_nUser; i++)
    {
      // get the imsi
      uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
      // get the lcId
      uint8_t lcId = 4;
      dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
      NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << "  thr " << (double)dlDataRxed.at (i) / statsDuration << " ref " << m_estThrPssDl.at (i));
    }

  for (int i = 0; i < m_nUser; i++)
    {
      NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / statsDuration, m_estThrPssDl.at (i), m_estThrPssDl.at (i) * tolerance, " Unfair Throughput!");
    }

  Simulator::Destroy ();

}
Example #2
0
c_RestResponse_HttpData* c_RestResponse::PrepareHttpData(c_RestRequest* RestRequest)
{
  
try
{


    
  char tempHeader[4096];
  
  //string sResponseHeader;
  Ptr<MgByteReader> outputReader;

  Ptr<c_RestResult> result = GetResult();
  STATUS status = result->GetStatusCode();
  STRING statusMessage = result->GetHttpStatusMessage();
  if (status != 200)
  {
    
    if (statusMessage == MapAgentStrings::FailedAuth1 ||
      statusMessage == MapAgentStrings::FailedAuth2
      )
    {
      RequestAuth(RestRequest);
    }
    else
    {
      //TODO: Use a resource for the HTML error message
      char content[4096];

      STRING shortError = result->GetErrorMessage();
      STRING longError = result->GetDetailedErrorMessage();

      sprintf(content,"\r\n"
        "<html>\n<head>\n"
        "<title>%s</title>\n"
        "<meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\">\n"
        "</head>\n"
        "<body>\n<h2>%s</h2>\n%s\n</body>\n</html>\n",
        MG_WCHAR_TO_CHAR(statusMessage),
        MG_WCHAR_TO_CHAR(shortError),
        MG_WCHAR_TO_CHAR(longError));

      DWORD  content_length = strlen(content);

      /*
      sprintf(tempHeader, MapAgentStrings::StatusHeader, status, MG_WCHAR_TO_CHAR(statusMessage));
      sResponseHeader.append(tempHeader);

      sprintf(tempHeader, MapAgentStrings::ContentLengthHeader, (int)content_length);
      sResponseHeader.append(tempHeader);

      sprintf(tempHeader, MapAgentStrings::ContentTypeHeader, MapAgentStrings::TextHtml, "");
      sResponseHeader.append(tempHeader);
      */
      
      m_HttpData.SetStatusAndReason(status,MG_WCHAR_TO_CHAR(statusMessage));      
      m_HttpData.AddHeader(MapAgentStrings::ContentTypeKey,MapAgentStrings::TextHtml);
      sprintf(tempHeader, "%d", (int)content_length);
      m_HttpData.AddHeader(MapAgentStrings::ContentLengthKey,tempHeader);
      
      
      m_HttpData.SetContent(content);
  
    }
  }
  else
  {

    // Status was ok.  Send the real result back.
    STRING result_contentType = result->GetResultContentType();
    STRING response_contentType = GetContentType();
    std::string stringval_utf8;

    //sprintf(tempHeader, MapAgentStrings::StatusOkHeader);
    //sResponseHeader.append(tempHeader);
    
    m_HttpData.SetStatusAndReason(200,"OK");
    

    if (response_contentType.length() > 0)
    {
      // If we are returning text, state that it is utf-8.
      
      STRING mime = response_contentType;
      if( response_contentType == RestMimeType::JsonP )
      {
        mime = L"text/plain";
      }
      else
      { 
        if( response_contentType == RestMimeType::Json )
        {
          mime = L"text/plain";
        }
      } 
      
      string charSet = "";
      if (mime.find(L"text") != mime.npos)  //NOXLATE
      {
        charSet = MapAgentStrings::Utf8Text;
      }
      //sprintf(tempHeader, MapAgentStrings::ContentTypeHeader, MG_WCHAR_TO_CHAR(response_contentType), charSet.c_str());
      //sResponseHeader.append(tempHeader);
      sprintf(tempHeader, "%s%s", MG_WCHAR_TO_CHAR(mime), charSet.c_str());
      m_HttpData.AddHeader(MapAgentStrings::ContentTypeKey,tempHeader);
    }
    else
    {
      //sprintf(tempHeader, MapAgentStrings::ContentTypeHeader, MapAgentStrings::TextPlain, MapAgentStrings::Utf8Text);
      //sResponseHeader.append(tempHeader);
      sprintf(tempHeader, "%s%s", MapAgentStrings::TextPlain, MapAgentStrings::Utf8Text);
      m_HttpData.AddHeader(MapAgentStrings::ContentTypeKey,tempHeader);
    }
    



    Ptr<MgDisposable> resultObj = result->GetResultObject();
    MgDisposable* pResultObj = (MgDisposable*)resultObj;

    // Test type of response needed
    Ptr<c_RestDataReader> restreader = NULL;

    MgProxyFeatureReader* proxyfreader = dynamic_cast<MgProxyFeatureReader*>(pResultObj);
    if( proxyfreader )
    {
      restreader = new c_RestDataReader_MgFeatureReader(proxyfreader);
      
    }
    else
    {
      restreader = SAFE_ADDREF(dynamic_cast<c_RestDataReader*>(pResultObj));
    }
    
    
    if( RestRequest->m_CfgRepresentation && RestRequest->m_CfgRepresentation->GetType() == c_CfgRepresentation::e_Template)
    {
      if( response_contentType == RestMimeType::Html  )
      {      
        c_FeatureReaderToHtml::ToHtml(restreader,RestRequest,RestRequest->GetOriginalFullUri(),RestRequest->GetBaseUri(),stringval_utf8,result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);            
        
      }
      else
      {
        if( response_contentType == RestMimeType::Kml  )
        {
            c_FeatureReaderToHtml::ToKml(restreader.p,RestRequest,RestRequest->GetOriginalFullUri(),RestRequest->GetBaseUri(),stringval_utf8,result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);            
        }
        else
        {
          if( response_contentType == RestMimeType::Kmz  )
          {
              outputReader = c_FeatureReaderToHtml::ToKmz(restreader.p,RestRequest,RestRequest->GetOriginalFullUri(),RestRequest->GetBaseUri(),result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);
          }
          else
          {
            c_FeatureReaderToHtml::ToTemplate(false,restreader,RestRequest,RestRequest->GetOriginalFullUri(),RestRequest->GetBaseUri(),stringval_utf8,result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);              
            
          }
        }
      }
    }
    
    if( RestRequest->m_CfgRepresentation && RestRequest->m_CfgRepresentation->GetType() == c_CfgRepresentation::e_FeaturesXML)
    {
      if( restreader.p )
      {
        c_FeatureReaderToXML::ToXml(restreader.p,stringval_utf8,result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);
      }
    }
    if( RestRequest->m_CfgRepresentation && RestRequest->m_CfgRepresentation->GetType() == c_CfgRepresentation::e_Sitemap)
    {
      if( restreader.p )
      {
        c_FeatureReaderToXML::ToSitemapXml(restreader.p,RestRequest,RestRequest->GetBaseUri(),stringval_utf8,result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);
      }
    }
    if( RestRequest->m_CfgRepresentation && RestRequest->m_CfgRepresentation->GetType() == c_CfgRepresentation::e_FeaturesJSON)
    {
      if( restreader.p )
      {
        c_FeatureReaderToGeoJson::ToGeoJson(restreader.p,stringval_utf8,result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);
      }
    }
    if( RestRequest->m_CfgRepresentation && RestRequest->m_CfgRepresentation->GetType() == c_CfgRepresentation::e_Custom)
    {
      if( restreader.p )
      {
        //std::stringstream strs;
        c_CfgRepresentation_Custom *customrep =  (c_CfgRepresentation_Custom *)RestRequest->m_CfgRepresentation;
        
        Ptr<c_StreamResponse_FReader2Custom> streamout = new c_StreamResponse_FReader2Custom(restreader.p,customrep);
        m_HttpData.SetContent(streamout);
        
        return &m_HttpData;  // need to go out here - bellow is closing featuer reader - setting hhtp header for content length etc..
         
        ///(*(customrep->m_CustomRenderer->m_FuncContent2Stream))(restreader.p,&strs);
        
        //stringval_utf8 = strs.str();
        //c_FeatureReaderToGeoJson::ToGeoJson(restreader.p,stringval_utf8,result->m_FeatureReader_StartIndex,result->m_FeatureReader_Count);
      }
    }
    if( restreader.p )
    {
      restreader->Close();
    }
    
    if (NULL != dynamic_cast<c_RestPrimitiveValue*>(pResultObj))
    { 
      stringval_utf8 = ((c_RestPrimitiveValue*)pResultObj)->ToStringUTF8();;

    }
    else if (NULL != dynamic_cast<MgByteReader*>(pResultObj))
    {
      outputReader = (MgByteReader*) SAFE_ADDREF(pResultObj);

    }
    else if (NULL != dynamic_cast<MgStringCollection*>(pResultObj))
    {
      outputReader = ((MgStringCollection*)pResultObj)->ToXml();

    }
    else if (NULL != dynamic_cast<MgSqlDataReader*>(pResultObj))
    {
      outputReader = ((MgSqlDataReader*)pResultObj)->ToXml();

    }
    else if (NULL != dynamic_cast<MgDataReader*>(pResultObj))
    {
      outputReader = ((MgDataReader*)pResultObj)->ToXml();

    }    
    

    if (stringval_utf8.length() > 0)
    {

      if( response_contentType == RestMimeType::JsonP || 
        ( response_contentType == RestMimeType::Json && (GetJsonpCallbackName().length()>0))
        )
      {
        //utf8 = response->GetJsonpCallbackName() + "( \"" + utf8 + "\" )"; ...
        std::string jsonp;
        CreateJsonpCallbackString(GetJsonpCallbackName(),stringval_utf8,jsonp);
        stringval_utf8 = jsonp;
      }

      sprintf(tempHeader, "%d", stringval_utf8.length());
      m_HttpData.AddHeader(MapAgentStrings::ContentLengthKey,tempHeader);
      

      m_HttpData.SetContent(stringval_utf8);
      
    }
    else if (outputReader != NULL)
    {
      if( response_contentType == RestMimeType::Json || response_contentType == RestMimeType::JsonP )
      {
        MgXmlJsonConvert convert;
        convert.ToJson(outputReader);

        if( response_contentType == RestMimeType::JsonP )
        {
          string json;
          // set read back to text from Jason so it can be converted to string with function 'ToStringUtf8'
          outputReader->GetByteSource()->SetMimeType(RestMimeType::Text);
          outputReader->ToStringUtf8(json);

          string jsonp;
          CreateJsonpCallbackString(GetJsonpCallbackName(),json,jsonp);

          Ptr<MgByteSource> byteSource = new MgByteSource(
            (unsigned char*)jsonp.c_str(), (INT32)jsonp.length());
          byteSource->SetMimeType(RestMimeType::JsonP);
          outputReader.Attach(byteSource->GetReader());   
        }
      }

      INT64 outLen = outputReader->GetLength();
      sprintf(tempHeader, "%d", (INT32)outLen);
      
      m_HttpData.AddHeader(MapAgentStrings::ContentLengthKey,tempHeader);
      
     
      m_HttpData.SetContent(outputReader);

      // Tell IIS to keep the connection open 
      //DWORD dwState = HSE_STATUS_SUCCESS_AND_KEEP_CONN;
      //m_pECB->ServerSupportFunction(m_pECB->ConnID, HSE_REQ_DONE_WITH_SESSION, &dwState, NULL, 0);
    }
    else
    {
      
      sprintf(tempHeader, "%d", 0);

      m_HttpData.AddHeader(MapAgentStrings::ContentLengthKey,tempHeader);
      

      // Tell IIS to keep the connection open 
      //DWORD dwState = HSE_STATUS_SUCCESS_AND_KEEP_CONN;
      //m_pECB->ServerSupportFunction(m_pECB->ConnID, HSE_REQ_DONE_WITH_SESSION, &dwState, NULL, 0);
    }
  }
  
  return &m_HttpData;
}                                                                         
catch (MgException* exc)                                                    
{       
  SendError(exc);
  exc->Release();                                                                
}                                                                        
catch (exception& e)                                                     
{                                                                         
  Ptr<MgException> mgException = MgSystemException::Create(e, L"c_RestResponse::PrepareHttpData", __LINE__, __WFILE__); 
  SendError(mgException);
}                                                                         
catch (...)                                                               
{                                                                         
  Ptr<MgException> mgException = new MgUnclassifiedException(L"c_RestResponse::PrepareHttpData", __LINE__, __WFILE__, NULL, L"", NULL); 
  SendError(mgException);
}  

}//end of c_RestResponse::PrepareHttpData
int main (int argc, char *argv[])
{	
  CommandLine cmd;
  cmd.Parse (argc, argv);
	
  // to save a template default attribute file run it like this:
  // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim
  //
  // to load a previously created default attribute file
  // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Load --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim

  ConfigStore inputConfig;
  inputConfig.ConfigureDefaults ();

  // parse again so you can override default values from the command line
  cmd.Parse (argc, argv);

  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
  lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
  // Uncomment to enable logging
  //lteHelper->EnableLogComponents ();

  // Create Nodes: eNodeB and UE
  NodeContainer enbNodes;
  NodeContainer ueNodes;
  enbNodes.Create (1);
  ueNodes.Create (1);

  // Install Mobility Model
  MobilityHelper mobility;
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (enbNodes);
  BuildingsHelper::Install (enbNodes);
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (ueNodes);
  BuildingsHelper::Install (ueNodes);

  // Create Devices and install them in the Nodes (eNB and UE)
  NetDeviceContainer enbDevs;
  NetDeviceContainer ueDevs;
//   lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
  lteHelper->SetSchedulerType ("ns3::PfFfMacScheduler");
  lteHelper->SetSchedulerAttribute ("CqiTimerThreshold", UintegerValue (3));
  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
  ueDevs = lteHelper->InstallUeDevice (ueNodes);
  
  lteHelper->EnableRlcTraces();
  lteHelper->EnableMacTraces();

  // Attach a UE to a eNB
  lteHelper->Attach (ueDevs, enbDevs.Get (0));
  
  Simulator::Schedule (Seconds (0.010), &ChangePosition, ueNodes.Get (0));
  Simulator::Schedule (Seconds (0.020), &ChangePosition, ueNodes.Get (0));

  // Activate a data radio bearer
  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
  EpsBearer bearer (q);
  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);


  Simulator::Stop (Seconds (0.030));

  Simulator::Run ();

  //GtkConfigStore config;
  //config.ConfigureAttributes ();

  Simulator::Destroy ();
  return 0;
}
Example #4
0
int main (int argc, char *argv[])
{	
  CommandLine cmd;
  cmd.Parse (argc, argv);
	
  // to save a template default attribute file run it like this:
  // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim
  //
  // to load a previously created default attribute file
  // ./waf --command-template="%s --ns3::ConfigStore::Filename=input-defaults.txt --ns3::ConfigStore::Mode=Load --ns3::ConfigStore::FileFormat=RawText" --run src/lte/examples/lena-first-sim

  ConfigStore inputConfig;
  inputConfig.ConfigureDefaults ();

  // Parse again so you can override default values from the command line
  cmd.Parse (argc, argv);

  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();

  // Uncomment to enable logging
  //lteHelper->EnableLogComponents ();

  // Create Nodes: eNodeB and UE
  NodeContainer enbNodes;
  NodeContainer ueNodes;
  enbNodes.Create (1);
  ueNodes.Create (1);

  // Install Mobility Model
  MobilityHelper mobility;
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (enbNodes);
  BuildingsHelper::Install (enbNodes);
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (ueNodes);
  BuildingsHelper::Install (ueNodes);

  // Create Devices and install them in the Nodes (eNB and UE)
  NetDeviceContainer enbDevs;
  NetDeviceContainer ueDevs;
  // Default scheduler is PF, uncomment to use RR
  //lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");

  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
  ueDevs = lteHelper->InstallUeDevice (ueNodes);

  // Attach a UE to a eNB
  lteHelper->Attach (ueDevs, enbDevs.Get (0));

  // Activate an EPS bearer
  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
  EpsBearer bearer (q);
  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);


  // Configure Radio Environment Map (REM) output
  // for LTE-only simulations always use /ChannelList/0 which is the downlink channel
  Ptr<RadioEnvironmentMapHelper> remHelper = CreateObject<RadioEnvironmentMapHelper> ();
  remHelper->SetAttribute ("ChannelPath", StringValue ("/ChannelList/0"));
  remHelper->SetAttribute ("OutputFile", StringValue ("rem.out"));
  remHelper->SetAttribute ("XMin", DoubleValue (-400.0));
  remHelper->SetAttribute ("XMax", DoubleValue (400.0));
  remHelper->SetAttribute ("YMin", DoubleValue (-300.0));
  remHelper->SetAttribute ("YMax", DoubleValue (300.0));
  remHelper->SetAttribute ("Z", DoubleValue (0.0));
  remHelper->Install ();

  // here's a minimal gnuplot script that will plot the above:
  // 
  // set view map;
  // set term x11;
  // set xlabel "X"
  // set ylabel "Y"
  // set cblabel "SINR (dB)"
  // plot "rem.out" using ($1):($2):(10*log10($4)) with image
  
    
  BuildingsHelper::MakeMobilityModelConsistent ();


  Simulator::Run ();

  //GtkConfigStore config;
  //config.ConfigureAttributes ();

  Simulator::Destroy ();
  return 0;
}
int
main (int argc, char *argv[])
{
  uint32_t nEnbPerFloor = 1;
  uint32_t nUe = 1;
  uint32_t nFloors = 0;
  double simTime = 1.0;
  CommandLine cmd;

  cmd.AddValue ("nEnb", "Number of eNodeBs per floor", nEnbPerFloor);
  cmd.AddValue ("nUe", "Number of UEs", nUe);
  cmd.AddValue ("nFloors", "Number of floors, 0 for Friis propagation model",
                nFloors);
  cmd.AddValue ("simTime", "Total duration of the simulation (in seconds)",
                simTime);
  cmd.Parse (argc, argv);

  ConfigStore inputConfig;
  inputConfig.ConfigureDefaults ();

  // parse again so you can override default values from the command line
  cmd.Parse (argc, argv);

  // Geometry of the scenario (in meters)
  // Assume squared building
  double nodeHeight = 1.5;
  double roomHeight = 3;
  double roomLength = 8;
  uint32_t nRooms = std::ceil (std::sqrt (nEnbPerFloor));
  uint32_t nEnb;

  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
  //lteHelper->EnableLogComponents ();
  //LogComponentEnable ("BuildingsPropagationLossModel", LOG_LEVEL_ALL);
  if (nFloors == 0)
    {
      lteHelper->SetAttribute ("PathlossModel",
                               StringValue ("ns3::FriisPropagationLossModel"));
      nEnb = nEnbPerFloor;
    }
  else
    {
      lteHelper->SetAttribute ("PathlossModel",
                               StringValue ("ns3::HybridBuildingsPropagationLossModel"));
      nEnb = nFloors * nEnbPerFloor;
    }

  // Create Nodes: eNodeB and UE
  NodeContainer enbNodes;
  std::vector<NodeContainer> ueNodes;

  enbNodes.Create (nEnb);
  for (uint32_t i = 0; i < nEnb; i++)
    {
      NodeContainer ueNode;
      ueNode.Create (nUe);
      ueNodes.push_back (ueNode);
    }

  MobilityHelper mobility;
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  std::vector<Vector> enbPosition;
  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
  Ptr<Building> building;

  if (nFloors == 0)
    {
      // Position of eNBs
      uint32_t plantedEnb = 0;
      for (uint32_t row = 0; row < nRooms; row++)
        {
          for (uint32_t column = 0; column < nRooms && plantedEnb < nEnbPerFloor; column++, plantedEnb++)
            {
              Vector v (roomLength * (column + 0.5), roomLength * (row + 0.5), nodeHeight);
              positionAlloc->Add (v);
              enbPosition.push_back (v);
              mobility.Install (ueNodes.at(plantedEnb));
            }
        }
      mobility.SetPositionAllocator (positionAlloc);
      mobility.Install (enbNodes);
      BuildingsHelper::Install (enbNodes);

      // Position of UEs attached to eNB
      for (uint32_t i = 0; i < nEnb; i++)
        {
          Ptr<UniformRandomVariable> posX = CreateObject<UniformRandomVariable> ();
          posX->SetAttribute ("Min", DoubleValue (enbPosition.at(i).x - roomLength * 0.5));
          posX->SetAttribute ("Max", DoubleValue (enbPosition.at(i).x + roomLength * 0.5));
          Ptr<UniformRandomVariable> posY = CreateObject<UniformRandomVariable> ();
          posY->SetAttribute ("Min", DoubleValue (enbPosition.at(i).y - roomLength * 0.5));
          posY->SetAttribute ("Max", DoubleValue (enbPosition.at(i).y + roomLength * 0.5));
          positionAlloc = CreateObject<ListPositionAllocator> ();
          for (uint32_t j = 0; j < nUe; j++)
            {
              positionAlloc->Add (Vector (posX->GetValue (), posY->GetValue (), nodeHeight));
              mobility.SetPositionAllocator (positionAlloc);
            }
          mobility.Install (ueNodes.at(i));
          BuildingsHelper::Install (ueNodes.at(i));
        }

    }
  else
    {
      building = CreateObject<Building> ();
      building->SetBoundaries (Box (0.0, nRooms * roomLength,
                                    0.0, nRooms * roomLength,
                                    0.0, nFloors* roomHeight));
      building->SetBuildingType (Building::Residential);
      building->SetExtWallsType (Building::ConcreteWithWindows);
      building->SetNFloors (nFloors);
      building->SetNRoomsX (nRooms);
      building->SetNRoomsY (nRooms);
      mobility.Install (enbNodes);
      BuildingsHelper::Install (enbNodes);
      uint32_t plantedEnb = 0;
      for (uint32_t floor = 0; floor < nFloors; floor++)
        {
          uint32_t plantedEnbPerFloor = 0;
          for (uint32_t row = 0; row < nRooms; row++)
            {
              for (uint32_t column = 0; column < nRooms && plantedEnbPerFloor < nEnbPerFloor; column++, plantedEnb++, plantedEnbPerFloor++)
                {
                  Vector v (roomLength * (column + 0.5),
                            roomLength * (row + 0.5),
                            nodeHeight + roomHeight * floor);
                  positionAlloc->Add (v);
                  enbPosition.push_back (v);
                  Ptr<MobilityModel> mmEnb = enbNodes.Get (plantedEnb)->GetObject<MobilityModel> ();
                  mmEnb->SetPosition (v);

                  // Positioning UEs attached to eNB
                  mobility.Install (ueNodes.at(plantedEnb));
                  BuildingsHelper::Install (ueNodes.at(plantedEnb));
                  for (uint32_t ue = 0; ue < nUe; ue++)
                    {
                      Ptr<MobilityModel> mmUe = ueNodes.at(plantedEnb).Get (ue)->GetObject<MobilityModel> ();
                      Vector vUe (v.x, v.y, v.z);
                      mmUe->SetPosition (vUe);
                    }
                }
            }
        }
    }


  // Create Devices and install them in the Nodes (eNB and UE)
  NetDeviceContainer enbDevs;
  std::vector<NetDeviceContainer> ueDevs;
  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
  for (uint32_t i = 0; i < nEnb; i++)
    {
      NetDeviceContainer ueDev = lteHelper->InstallUeDevice (ueNodes.at(i));
      ueDevs.push_back (ueDev);
      lteHelper->Attach (ueDev, enbDevs.Get (i));
      enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
      EpsBearer bearer (q);
      lteHelper->ActivateDataRadioBearer (ueDev, bearer);
    }


  BuildingsHelper::MakeMobilityModelConsistent ();

  Simulator::Stop (Seconds (simTime));
  lteHelper->EnableTraces ();

  Simulator::Run ();

  /*GtkConfigStore config;
  config.ConfigureAttributes ();*/

  Simulator::Destroy ();
  return 0;
}
void
LenaMimoTestCase::DoRun (void)
{
  NS_LOG_FUNCTION (this << GetName ());
  Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
  Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
  Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (m_useIdealRrc));

  /**
   * Initialize Simulation Scenario: 1 eNB and m_nUser UEs
   */


  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
  Config::SetDefault ("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue (false));
  Config::SetDefault ("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue (false));
  
//   lteHelper->SetSchedulerAttribute ("HarqEnabled", BooleanValue (false));
  
  
  lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
  lteHelper->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (0.0));
  lteHelper->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (0.0));
  lteHelper->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0.0));
  
//   lteHelper->EnableLogComponents ();

  // Create Nodes: eNodeB and UE
  NodeContainer enbNodes;
  NodeContainer ueNodes;
  enbNodes.Create (1);
  ueNodes.Create (1);

  // Install Mobility Model
  MobilityHelper mobility;
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (enbNodes);
  BuildingsHelper::Install (enbNodes);
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (ueNodes);
  BuildingsHelper::Install (ueNodes);

  // Create Devices and install them in the Nodes (eNB and UE)
  NetDeviceContainer enbDevs;
  NetDeviceContainer ueDevs;
  lteHelper->SetSchedulerType (m_schedulerType);
  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
  ueDevs = lteHelper->InstallUeDevice (ueNodes);
  
  // Attach a UE to a eNB
  lteHelper->Attach (ueDevs, enbDevs.Get (0));

  // Activate an EPS bearer
  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
  EpsBearer bearer (q);
  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
  

  Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
  Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
  enbPhy->SetAttribute ("TxPower", DoubleValue (46.0));
  enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
  Ptr<MobilityModel> mmenb = enbNodes.Get (0)->GetObject<MobilityModel> ();
  mmenb->SetPosition (Vector (0.0, 0.0, 30.0));

  // Set UE's position and power
  Ptr<MobilityModel> mmue = ueNodes.Get (0)->GetObject<MobilityModel> ();
  mmue->SetPosition (Vector (m_dist, 0.0, 1.0));
  Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (0)->GetObject<LteUeNetDevice> ();
  Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
  uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
  uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
  
  // need to allow for RRC connection establishment + SRS before enabling traces
  lteHelper->EnableRlcTraces ();
  lteHelper->EnableMacTraces ();
  double simulationTime = 0.6; 
  double tolerance = 0.1;
  
  uint8_t rnti = 1;
  Ptr<LteEnbNetDevice> enbNetDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
  
  PointerValue ptrval;
  enbNetDev->GetAttribute ("FfMacScheduler", ptrval);
  Ptr<PfFfMacScheduler> pfsched;
  Ptr<RrFfMacScheduler> rrsched;
  if (m_schedulerType.compare ("ns3::RrFfMacScheduler") == 0)
    {
      rrsched = ptrval.Get<RrFfMacScheduler> ();
      if (rrsched == 0)
        {
          NS_FATAL_ERROR ("No RR Scheduler available");
        }
      Simulator::Schedule (Seconds (0.2), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 1);
      Simulator::Schedule (Seconds (0.4), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 2);
    }
  else if (m_schedulerType.compare ("ns3::PfFfMacScheduler") == 0)
    {
      pfsched = ptrval.Get<PfFfMacScheduler> ();
      if (pfsched == 0)
        {
          NS_FATAL_ERROR ("No Pf Scheduler available");
        }
      
      Simulator::Schedule (Seconds (0.2), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 1);
      Simulator::Schedule (Seconds (0.4), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 2);
    }
  else
    {
      NS_FATAL_ERROR ("Scheduler not supported by this test");
    }
    
  
  Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
  rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.1)));

  NS_LOG_INFO (m_schedulerType << " MIMO test:");
  double sampleTime = 0.199999; // at 0.2 RlcStats are reset
  for (uint8_t j = 0; j < m_estThrDl.size (); j ++)
    {
      NS_LOG_INFO ("\t test with user at distance " << m_dist << " time " << sampleTime);
      // get the imsi
      uint64_t imsi = ueDevs.Get (0)->GetObject<LteUeNetDevice> ()->GetImsi ();
      uint8_t lcId = 3;
      Time t = Seconds (sampleTime);
      Simulator::Schedule(t, &LenaMimoTestCase::GetRlcBufferSample, this, rlcStats, imsi, lcId);
      sampleTime += 0.2;
    }
  Simulator::Stop (Seconds (simulationTime));
  Simulator::Run ();
  Simulator::Destroy ();

  NS_LOG_INFO ("Check consistency");
    for (uint8_t i = 0; i < m_estThrDl.size (); i++)
      {
        NS_LOG_INFO ("interval " << i + 1 << ": bytes rxed " << (double)m_dlDataRxed.at (i) << " ref " << m_estThrDl.at (i));
        NS_TEST_ASSERT_MSG_EQ_TOL ((double)m_dlDataRxed.at (i) , m_estThrDl.at (i), m_estThrDl.at (i) * tolerance, " Unfair Throughput!");
      }

}
LteFadingTestSuite::LteFadingTestSuite ()
: TestSuite ("lte-fading-model", SYSTEM)
{
  
  
  // -------------- COMPOUND TESTS ----------------------------------
  
  LogComponentEnable ("LteFadingTest", LOG_LEVEL_ALL);
  
  // NS_LOG_INFO ("Creating LteDownlinkSinrTestSuite");
  
  Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
  
  lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::BuildingsPropagationLossModel"));
  
  // Create Nodes: eNodeB, home eNB, UE and home UE (UE attached to HeNB)
  NodeContainer enbNodes;
  NodeContainer henbNodes;
  NodeContainer ueNodes;
  NodeContainer hueNodes;
  enbNodes.Create (1);
  henbNodes.Create (2);
  ueNodes.Create (5);
  hueNodes.Create (3);
  
  // Install Mobility Model
  MobilityHelper mobility;
  mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
  mobility.Install (enbNodes);
  mobility.Install (henbNodes);
  mobility.Install (ueNodes);
  mobility.Install (hueNodes);
  
  NetDeviceContainer enbDevs;
  NetDeviceContainer henbDevs;
  NetDeviceContainer ueDevs;
  NetDeviceContainer hueDevs;
  enbDevs = lteHelper->InstallEnbDevice (enbNodes);
  ueDevs = lteHelper->InstallUeDevice (ueNodes);
  henbDevs = lteHelper->InstallEnbDevice (henbNodes);
  hueDevs = lteHelper->InstallUeDevice (hueNodes);
  
  
  
  lteHelper->Attach (ueDevs, enbDevs.Get (0));
  lteHelper->Attach (hueDevs, henbDevs.Get (0));
  
  // Test #1 Okumura Hata Model (150 < freq < 1500 MHz) (Macro<->UE)
  
  double distance = 2000;
  double hm = 1;
  double hb = 30;
//   double freq = 869e6; // E_UTRA BAND #5 see table 5.5-1 of 36.101
  Ptr<BuildingsMobilityModel> mm1 = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
  mm1->SetPosition (Vector (0.0, 0.0, hb));
  
  Ptr<BuildingsMobilityModel> mm2 = ueNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
  mm2->SetPosition (Vector (distance, 0.0, hm));
  
  AddTestCase (new LteFadingTestCase (mm1, mm2, 137.93, "OH Urban Large city"), TestCase::QUICK);
    
  
}
void
LenaDlCtrlPhyErrorModelTestCase::DoRun (void)
{
  
  double ber = 0.03;
  Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (ber));
  Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
  Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (true));
  Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
  Config::SetDefault ("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue (false));
  Config::SetGlobal ("RngRun", IntegerValue (m_rngRun));

  /*
   * Initialize Simulation Scenario: 1 eNB and m_nUser UEs
   */

  int64_t stream = 1;
  Ptr<LteHelper> lena = CreateObject<LteHelper> ();
  
  // Create Nodes: eNodeB and UE
  NodeContainer enbNodes;
  NodeContainer ueNodes;
  enbNodes.Create (m_nEnb);
  ueNodes.Create (1);
  
  // Install Mobility Model
  MobilityHelper mobility;
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (enbNodes);
  BuildingsHelper::Install (enbNodes);
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (ueNodes);
  BuildingsHelper::Install (ueNodes);
  
  // remove random shadowing component
  lena->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
  lena->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (0.0));
  lena->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (0.0));
  lena->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0.0));
  
  // Create Devices and install them in the Nodes (eNB and UE)
  NetDeviceContainer enbDevs;
  NetDeviceContainer ueDevs;
  lena->SetSchedulerType ("ns3::RrFfMacScheduler");
  lena->SetSchedulerAttribute ("UlCqiFilter", EnumValue (FfMacScheduler::PUSCH_UL_CQI));
  
  enbDevs = lena->InstallEnbDevice (enbNodes);
  stream += lena->AssignStreams (enbDevs, stream);
  ueDevs = lena->InstallUeDevice (ueNodes);
  stream += lena->AssignStreams (ueDevs, stream);
  
  // Attach a UE to one eNB (the others are interfering ones)
  lena->Attach (ueDevs, enbDevs.Get (0));
  
  // Activate an EPS bearer
  enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
  EpsBearer bearer (q);
  lena->ActivateDataRadioBearer (ueDevs, bearer);
  
  // Set UEs' position and power
  for (int i = 0; i < m_nEnb; i++)
    {
      // place the HeNB over the default rooftop level (20 mt.)
      Ptr<MobilityModel> mm = enbNodes.Get (i)->GetObject<MobilityModel> ();
      mm->SetPosition (Vector (0.0, 0.0, 30.0));
      Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (i)->GetObject<LteEnbNetDevice> ();
      Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
      enbPhy->SetAttribute ("TxPower", DoubleValue (43.0));
      enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
    }
  
  // Set UEs' position and power
  Ptr<MobilityModel> mm = ueNodes.Get (0)->GetObject<MobilityModel> ();
  mm->SetPosition (Vector (m_dist, 0.0, 1.0));
  Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (0)->GetObject<LteUeNetDevice> ();
  Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
  uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
  uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
  
  Time statsDuration = Seconds (1.0);
  Simulator::Stop (m_statsStartTime + statsDuration - Seconds (0.0001));

  lena->EnableRlcTraces ();
  Ptr<RadioBearerStatsCalculator> rlcStats = lena->GetRlcStats ();
  rlcStats->SetAttribute ("StartTime", TimeValue (m_statsStartTime));
  rlcStats->SetAttribute ("EpochDuration", TimeValue (statsDuration));

  Simulator::Run ();
  
  NS_LOG_INFO ("\tTest downlink control channels (PCFICH+PDCCH)");
  NS_LOG_INFO ("Test with " << m_nEnb << " eNB(s) at distance " << m_dist << " expected BLER " << m_blerRef);
  int nUser = 1;
  for (int i = 0; i < nUser; i++)
    {
      // get the imsi
      uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
      uint8_t lcId = 3;
      double dlRxPackets = rlcStats->GetDlRxPackets (imsi, lcId);
      double dlTxPackets = rlcStats->GetDlTxPackets (imsi, lcId);
      double dlBler = 1.0 - (dlRxPackets/dlTxPackets);
      double expectedDlRxPackets = dlTxPackets -dlTxPackets*m_blerRef;
      NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " DOWNLINK"
                   << " pkts rx " << dlRxPackets << " tx " << dlTxPackets
                   << " BLER " << dlBler << " Err " << std::fabs (m_blerRef - dlBler)
                   << " expected rx " << expectedDlRxPackets
                   << " difference " << std::abs (expectedDlRxPackets - dlRxPackets)
                   << " tolerance " << m_toleranceRxPackets);
      NS_UNUSED (dlBler);

      // sanity check for whether the tx packets reported by the stats are correct
      // we expect one packet per TTI
      double expectedDlTxPackets = statsDuration.GetMilliSeconds ();
      NS_TEST_ASSERT_MSG_EQ_TOL (dlTxPackets, expectedDlTxPackets, expectedDlTxPackets * 0.005, 
                                 " too different DL TX packets reported");

      // this is the main test condition: check that the RX packets are within the expected range
      NS_TEST_ASSERT_MSG_EQ_TOL (dlRxPackets, expectedDlRxPackets, m_toleranceRxPackets,
                                 "too different DL RX packets reported");

    }
  
  Simulator::Destroy ();
}