Ejemplo n.º 1
0
void TcpTransportFactory::start(
    Codec& codec, const Configuration& configuration, int64_t topologyId)
{
    // TODO: multithread (lock)
    // TODO: consistent hash
    bool pingOnStartup = configuration.isPingOnStartup();
    for (std::vector<ServerConfiguration>::const_iterator iter=configuration.getServersConfiguration().begin();
        iter!=configuration.getServersConfiguration().end(); iter++)
    {
        servers.push_back(InetSocketAddress(iter->getHost(), iter->getPort()));
    }

    balancer = RequestBalancingStrategy::newInstance();
    tcpNoDelay = configuration.isTcpNoDelay();
    soTimeout = configuration.getSocketTimeout();
    connectTimeout = configuration.getConnectionTimeout();

    // TODO: SSL configuration

    PropsKeyedObjectPoolFactory<InetSocketAddress, TcpTransport> poolFactory(
        *new TransportObjectFactory(codec, *this, topologyId, pingOnStartup),
        configuration.getConnectionPoolConfiguration());

    createAndPreparePool(poolFactory);
    balancer->setServers(servers);
    updateTransportCount();

    if (configuration.isPingOnStartup()) {
       pingServers();
    }
 }
Ejemplo n.º 2
0
void Codec20::readNewTopologyAndHash(Transport& transport, HeaderParams& params) const{
    // Just consume the header's byte
	// Do not evaluate new topology right now
	int newTopologyId = transport.readVInt();
    params.topologyId.setId(newTopologyId); //update topologyId reference
    uint32_t clusterSize = transport.readVInt();
    TRACE("Coded20::readNewToplogyAndhash(): clusterSize=%d",clusterSize);
    std::vector<InetSocketAddress> addresses(clusterSize);
    for (uint32_t i = 0; i < clusterSize; i++) {
       std::string host(transport.readString());
       int16_t port = transport.readUnsignedShort();
       addresses[i] = InetSocketAddress(host, port);
    }

    uint8_t hashFunctionVersion = transport.readByte();
    uint32_t numSegments = transport.readVInt();

    std::vector<std::vector<InetSocketAddress>> segmentOwners(numSegments);

    if (hashFunctionVersion > 0) {
       TRACE("Codec20::readNewTopologyAndHash: numSegments=%d", numSegments);
       for (uint32_t i = 0; i < numSegments; i++) {
          uint8_t numOwners = transport.readByte();
          segmentOwners[i]=std::vector<InetSocketAddress>(numOwners);
          for (uint8_t j = 0; j < numOwners; j++) {
             uint32_t memberIndex = transport.readVInt();
             segmentOwners[i][j] = addresses[memberIndex];
          }
       }
    }

    TransportFactory &tf = transport.getTransportFactory();
    bool noTopologyInfo=false;
    int currentTopology = 0;
    try
    {
      currentTopology = tf.getTopologyId(params.cacheName);
    }
    catch (std::exception &e)
    {
    	noTopologyInfo=true;
    }
    int topologyAge = tf.getTopologyAge();
    if (noTopologyInfo || (params.topologyAge == topologyAge && currentTopology != newTopologyId)) {
       params.topologyId = newTopologyId;
       tf.updateServers(addresses);
       if (hashFunctionVersion == 0) {
             TRACE("Not using a consistent hash function (hash function version == 0).");
       } else {
             TRACE("Updating client hash function with %u number of segments", numSegments);
       }
       tf.updateHashFunction(segmentOwners,
          numSegments, hashFunctionVersion, params.cacheName, params.topologyId.getId());
    } else {
       TRACE("Outdated topology received (topology id = %d, topology age = %d), so ignoring it: s",
             newTopologyId, topologyAge/*, Arrays.toString(addresses)*/);
    }
}
Ejemplo n.º 3
0
void FceApplication::StartApplication(void) {

	NS_LOG_FUNCTION ("");

	// initialize vehicle
	string vehicleId = Names::FindName(GetNode());
	vehicle.initialize(vehicleId);
	vehicle.setScenario(scenario);
	TIS::getInstance().initializeStaticTravelTimes(scenario.getAlternativeRoutes());

	// ns3
	mobilityModel = GetNode()->GetObject<ConstantVelocityMobilityModel>();
	// Connect the callback for the neighbor discovery service
	std::ostringstream oss;
	oss << "/NodeList/" << GetNode()->GetId() << "/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::BeaconingAdhocWifiMac/NeighborLost";
	Config::Connect(oss.str(), MakeCallback(&FceApplication::NeighborLost, this));
	std::ostringstream oss2;
	oss2 << "/NodeList/" << GetNode()->GetId() << "/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::BeaconingAdhocWifiMac/NewNeighbor";
	Config::Connect(oss2.str(), MakeCallback(&FceApplication::NewNeighborFound, this));
	// set socket
	Ptr<SocketFactory> socketFactory = GetNode()->GetObject<UdpSocketFactory> ();
	m_socket = socketFactory->CreateSocket();
	m_socket->Connect (InetSocketAddress (Ipv4Address::GetBroadcast(), m_port));
	m_socket->SetAllowBroadcast(true);
	m_socket->SetRecvCallback(MakeCallback(&FceApplication::ReceivePacket, this));
	m_socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), m_port));

	// start simualtion
	running = true;

	Log::getInstance().getStream("strategy") << strategy << endl;

	double r = (double)(rand()%RAND_MAX)/(double)RAND_MAX * SIMULATION_STEP_INTERVAL;
//	double r = rando.GetValue(0, SIMULATION_STEP_INTERVAL);
	double r2 = (double)(rand()%RAND_MAX)/(double)RAND_MAX * TRAFFIC_INFORMATION_SENDING_INTERVAL;
//	double r2 = rando.GetValue(0, TRAFFIC_INFORMATION_SENDING_INTERVAL);

	m_simulationEvent = Simulator::Schedule(Seconds(r), &FceApplication::SimulationRun, this);
	m_trafficInformationEvent = Simulator::Schedule(Seconds(1+r2), &FceApplication::SendTrafficInformation, this);

}
Ejemplo n.º 4
0
LiveAppModuleImpl::LiveAppModuleImpl(const LiveAppModuleCreateParam& param, const TCHAR* tagname, bool tagMutate) : 
                m_CreateParam( param ),
                m_NormalUDPSender(param.NormalUDPSender),		
                m_TCPProxyUDPSender(param.TCPProxyUDPSender), 
                m_HTTPProxyUDPSender(param.HTTPProxyUDPSender),
                m_AutoMaxAppPeerCount(20),
                m_AutoMinAppPeerCount(0), 
		m_BootModule( new BootModule(param.NormalUDPSender) )
{
	TEST_LOG_OPEN( paths::combine( param.ConfigDirectory, _T("live_test.log") ).c_str() );

	m_SysInfo = static_cast<const CSysInfo*>(param.SysInfo);
	m_PeerInformation.reset(new PeerInformation(param.ChannelGUID, param.SysInfo->PeerGUID, param.AppVersion, param.AppVersionNumber16, CreatePeerNetInfo(*m_SysInfo)));
	m_PeerInformation->NetInfo->CoreInfo.PeerType = param.PeerType;

	LIVE_ASSERT(m_SysInfo != NULL);
	m_PeerCountLimit = m_SysInfo->MaxAppPeerCount;
	LIMIT_MIN(m_PeerCountLimit, PPL_MIN_PEER_COUNT_LIMIT);
	// 传入的最大peer个数应该不超过一个最大限制PPL_MAX_PEER_COUNT_LIMIT
	LIVE_ASSERT(m_PeerCountLimit <= PPL_MAX_PEER_COUNT_LIMIT);
	LIMIT_MAX(m_PeerCountLimit, PPL_MAX_PEER_COUNT_LIMIT);


	m_iptable.Load(m_CreateParam.BaseDirectory);

	boost::shared_ptr<IDGenerator> trackerTransactionID(new IDGenerator());
	boost::shared_ptr<IDGenerator> peerTransactionID(new IDGenerator());
	m_UDPConnectionlessPacketBuilder.reset(new UDPConnectionlessPacketBuilder(peerTransactionID));
	m_TCPConnectionlessPacketBuilder.reset(new TCPConnectionlessPacketBuilder());

	m_OldTrackerPacketBuilder.reset(new UDPPacketBuilder(trackerTransactionID)); // 用于tracker报文
	m_SecureUDPPacketBuilder.reset( new SecureTrackerRequestPacketBuilder( trackerTransactionID ) );

	boost::shared_ptr<UDPConnectionPacketBuilder> udpConnectionPacketBuilder(new UDPConnectionPacketBuilder(peerTransactionID));
	boost::shared_ptr<TCPConnectionPacketBuilder> tcpPacketBuilder(new TCPConnectionPacketBuilder());
	m_SecureTrackerProxyPacketBuilder.reset( new SecureTrackerProxyPacketBuilder( trackerTransactionID ) );
	m_SecureTrackerProxyPacketBuilder->Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID );

	m_OldTrackerPacketBuilder->InitHeadInfo( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID );
	m_SecureUDPPacketBuilder->Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, m_PeerInformation->NetInfo->CoreInfo, m_PeerInformation->AppVersion );
	m_UDPConnectionlessPacketBuilder->PeerInfo.Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, 
		*m_PeerInformation->NetInfo, m_PeerInformation->AppVersion);
	m_TCPConnectionlessPacketBuilder->PeerInfo.Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, 
		*m_PeerInformation->NetInfo, m_PeerInformation->AppVersion);

	m_UDPPacketSender.reset(new TrackerPacketSender(m_OldTrackerPacketBuilder, m_SecureUDPPacketBuilder, m_NormalUDPSender, m_TCPProxyUDPSender, m_HTTPProxyUDPSender, 
		m_PeerInformation, m_Statistics.OldUDPFlow.Upload, m_Statistics.TotalFlow.Upload));

	m_UDPConnectionlessPacketSender.reset( new UDPConnectionlessPacketSender( m_UDPConnectionlessPacketBuilder, m_NormalUDPSender, 
		m_PeerInformation, m_Statistics.UDPConnectionlessFlow.Upload, m_Statistics.TotalFlow.Upload ) );
	m_UDPConnectionPacketSender.reset( new UDPConnectionPacketSender( udpConnectionPacketBuilder, m_NormalUDPSender, m_Statistics.UDPConnectionFlow.Upload, m_Statistics.TotalFlow.Upload ) );

	m_TCPConnectionlessPacketSender.reset( new TCPConnectionlessPacketSender( m_TCPConnectionlessPacketBuilder, m_PeerInformation, m_Statistics.TCPConnectionlessFlow.Upload, m_Statistics.TotalFlow.Upload ) );
	m_TCPConnectionPacketSender.reset( new TCPConnectionPacketSender( tcpPacketBuilder, m_Statistics.TCPConnectionFlow.Upload, m_Statistics.TotalFlow.Upload ) );

	VIEW_ERROR("Create New AppModule! " << this << " ResourceGUID=" << param.ChannelGUID);
	m_LiveInfo = CreateLiveInfo(m_StatisticsInfo, m_MappingLiveInfo, tagname, m_PeerCountLimit, param, m_PeerInformation->AppVersion, tagMutate);

	LoadTracker(param.Trackers);

	InitPeerAuthInfo(*m_PeerInformation->AuthInfo, param);

	{
//#if defined(_PPL_PLATFORM_LINUX) || defined(_PPL_USE_ASIO)
//		ini_file ini;
//		this->InitIni(ini);
//		ini.set_section(_T("media"));
//		int netWriterMode = ini.get_int(_T("NetWriterMode"), 0);
//		m_mediaServerListener.reset(CreateMediaServerListener(netWriterMode));
//#elif defined(_PPL_PLATFORM_MSWIN)
		m_mediaServerListener.reset(CreateMediaServerListener(*m_LiveInfo));
//#endif
	}

/* ----------Removed by Tady, 04142010: Moved into Func. Start().
	if ( NORMAL_PEER == param.PeerType )
	{
		// 检查stun type
		MY_STUN_NAT_TYPE natType = this->LoadNATType();
		if ( STUN_TYPE_INVALID == natType )
		{
			// 读取nat类型失败,另起线程检测
			m_StunTypeResolver.reset( new StunTypeResolver );
			m_StunTypeResolver->Resolve(StunTypeResolver::CallbackType(boost::bind(&LiveAppModuleImpl::OnNATQuerySucceeded, this, _1)));
		}
		else
		{
			// 保存nat类型到NetInfo对象
			m_PeerInformation->NetInfo->SetNATType( natType );
			m_LiveInfo->LocalPeerInfo.NetInfo.CoreInfo.NATType = natType;
		}
	}
*/
	{
		std::vector<InetSocketAddress> stunServers;
		ini_file ini;
		this->InitConfig(ini);
		ini.set_section(_T("stun"));
		tstring serverListStr = ini.get_string(_T("servers"), _T(""));
		int day = ini.get_int(_T("time"), -1);
		SYSTEMTIME st;
		GetLocalTime(&st);
		if ( false == serverListStr.empty() && ( day > 0 ) && (abs(st.wDay - day) < 3) )
		{
			std::vector<tstring> serverList;
			strings::split(std::back_inserter(serverList), serverListStr, _T('|'));
			for ( size_t serverIndex = 0; serverIndex < serverList.size(); ++serverIndex )
			{
				pair<tstring, tstring> ipAndPort = strings::split_pair(serverList[serverIndex], _T(':'));
				if ( false == ipAndPort.first.empty() && false == ipAndPort.second.empty() )
				{
					UINT ip = ResolveHostName(ipAndPort.first);
					WORD port = static_cast<WORD>( _ttoi(ipAndPort.second.c_str()) );
					if ( ip != 0 && ip != INADDR_NONE && port != 0)
					{
						stunServers.push_back(InetSocketAddress(ip, port));
					}
				}
			}
		}
		if ( false == stunServers.empty() )
		{
			this->StartStunModule(stunServers);
		}
		else
		{
			// 向boot server查询
			m_BootModule->QueryNTSList(BootModule::NTSListCallbackType(boost::bind(&LiveAppModuleImpl::OnNTSListOK, this, _1)));
		}
	}

	m_LogClient.reset( new LogClient( m_CreateParam.BaseDirectory, m_CreateParam.ConfigDirectory, m_PeerInformation ) );

	m_timer.set_callback(boost::bind(&LiveAppModuleImpl::OnAppTimer, this));


//#ifdef _DEBUG
#ifdef _PPL_PLATFORM_MSWIN
#pragma message("!!!!!!从params.ini中加载TransferMethod设置")
#endif
	{
		ini_file ini;
		this->InitIni(ini);
		ini.set_section(_T("connector"));
		int method = ini.get_int(_T("TransferMethod"), 0);
		VIEW_DEBUG("Load TransferMethod " << method);
		if (method != TRANSFER_ALL && method != TRANSFER_UDP && method != TRANSFER_TCP && method != TRANSFER_NO_DETECT)
		{
			method = TRANSFER_ALL;
		}
		m_LiveInfo->TransferMethod = (BYTE)method;
	}
//#endif


	TEST_LOG_OUT("live start");
	TEST_LOG_OUT("channel id " << param.ChannelGUID);
	TEST_LOG_OUT("peer id " << param.SysInfo->PeerGUID);
	TEST_LOG_OUT("peer address " << m_PeerInformation->NetInfo->Address);
	TEST_LOG_FLUSH();
}
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 ();

}
void 
EpcS1uDlTestCase::DoRun ()
{
  Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
  Ptr<Node> pgw = epcHelper->GetPgwNode ();

  // allow jumbo packets
  Config::SetDefault ("ns3::CsmaNetDevice::Mtu", UintegerValue (30000));
  Config::SetDefault ("ns3::PointToPointNetDevice::Mtu", UintegerValue (30000));
  epcHelper->SetAttribute ("S1uLinkMtu", UintegerValue (30000));
  
  // 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")));
  NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);  
  Ipv4AddressHelper ipv4h;
  ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
  ipv4h.Assign (internetDevices);
  
  // setup default gateway for the remote hosts
  Ipv4StaticRoutingHelper ipv4RoutingHelper;
  Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());

  // hardcoded UE addresses for now
  remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.255.255.0"), 1);
  



  NodeContainer enbs;
  uint16_t cellIdCounter = 0;

  for (std::vector<EnbDlTestData>::iterator enbit = m_enbDlTestData.begin ();
       enbit < m_enbDlTestData.end ();
       ++enbit)
    {
      Ptr<Node> enb = CreateObject<Node> ();
      enbs.Add (enb);

      // we test EPC without LTE, hence we use:
      // 1) a CSMA network to simulate the cell
      // 2) a raw socket opened on the CSMA device to simulate the LTE socket

      uint16_t cellId = ++cellIdCounter;

      NodeContainer ues;
      ues.Create (enbit->ues.size ());

      NodeContainer cell;
      cell.Add (ues);
      cell.Add (enb);

      CsmaHelper csmaCell;      
      NetDeviceContainer cellDevices = csmaCell.Install (cell);

      // the eNB's CSMA NetDevice acting as an LTE NetDevice. 
      Ptr<NetDevice> enbDevice = cellDevices.Get (cellDevices.GetN () - 1);

      // Note that the EpcEnbApplication won't care of the actual NetDevice type
      epcHelper->AddEnb (enb, enbDevice, cellId);      

      // Plug test RRC entity
      Ptr<EpcEnbApplication> enbApp = enb->GetApplication (0)->GetObject<EpcEnbApplication> ();
      NS_ASSERT_MSG (enbApp != 0, "cannot retrieve EpcEnbApplication");
      Ptr<EpcTestRrc> rrc = CreateObject<EpcTestRrc> ();
      rrc->SetS1SapProvider (enbApp->GetS1SapProvider ());
      enbApp->SetS1SapUser (rrc->GetS1SapUser ());
      
      // we install the IP stack on UEs only
      InternetStackHelper internet;
      internet.Install (ues);

      // assign IP address to UEs, and install applications
      for (uint32_t u = 0; u < ues.GetN (); ++u)
        {
          Ptr<NetDevice> ueLteDevice = cellDevices.Get (u);
          Ipv4InterfaceContainer ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevice));

          Ptr<Node> ue = ues.Get (u);

          // disable IP Forwarding on the UE. This is because we use
          // CSMA broadcast MAC addresses for this test. The problem
          // won't happen with a LteUeNetDevice. 
          ue->GetObject<Ipv4> ()->SetAttribute ("IpForward", BooleanValue (false));
          
          uint16_t port = 1234;
          PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
          ApplicationContainer apps = packetSinkHelper.Install (ue);
          apps.Start (Seconds (1.0));
          apps.Stop (Seconds (10.0));
          enbit->ues[u].serverApp = apps.Get (0)->GetObject<PacketSink> ();
          
          Time interPacketInterval = Seconds (0.01);
          UdpEchoClientHelper client (ueIpIface.GetAddress (0), port);
          client.SetAttribute ("MaxPackets", UintegerValue (enbit->ues[u].numPkts));
          client.SetAttribute ("Interval", TimeValue (interPacketInterval));
          client.SetAttribute ("PacketSize", UintegerValue (enbit->ues[u].pktSize));
          apps = client.Install (remoteHost);
          apps.Start (Seconds (2.0));
          apps.Stop (Seconds (10.0));   
          enbit->ues[u].clientApp = apps.Get (0);

          uint64_t imsi = u+1;
          epcHelper->AddUe (ueLteDevice, imsi);
          epcHelper->ActivateEpsBearer (ueLteDevice, imsi, EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
          enbApp->GetS1SapProvider ()->InitialUeMessage (imsi, (uint16_t) imsi);
        } 
            
    } 
  
  Simulator::Run ();

  for (std::vector<EnbDlTestData>::iterator enbit = m_enbDlTestData.begin ();
       enbit < m_enbDlTestData.end ();
       ++enbit)
    {
      for (std::vector<UeDlTestData>::iterator ueit = enbit->ues.begin ();
           ueit < enbit->ues.end ();
           ++ueit)
        {
          NS_TEST_ASSERT_MSG_EQ (ueit->serverApp->GetTotalRx (), (ueit->numPkts) * (ueit->pktSize), "wrong total received bytes");
        }      
    }
  
  Simulator::Destroy ();
}