Amiri
Amiri

Reputation: 2536

Why does FlowMonitor not collect data for dsr.cc in ns3?

I have tested FlowMonitor for some programs and it works. But for the dsr which is available in ns3 examples, it does not collect any data. What have I missed?

Here is the program, using Fedora 28, GCC 8, ns-3.28

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/mobility-module.h"
#include "ns3/config-store-module.h"
#include "ns3/wifi-module.h"
#include "ns3/internet-module.h"
#include "ns3/dsr-module.h"
#include "ns3/netanim-module.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/flow-monitor-module.h"

#include <sstream>

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("DsrTest");

int
main (int argc, char *argv[])
{
  //
  // Users may find it convenient to turn on explicit debugging
  // for selected modules; the below lines suggest how to do this
  //
#if 0
  LogComponentEnable ("Ipv4L3Protocol", LOG_LEVEL_ALL);
  LogComponentEnable ("UdpL4Protocol", LOG_LEVEL_ALL);
  LogComponentEnable ("UdpSocketImpl", LOG_LEVEL_ALL);
  LogComponentEnable ("NetDevice", LOG_LEVEL_ALL);
  LogComponentEnable ("Ipv4EndPointDemux", LOG_LEVEL_ALL);
#endif

#if 0
  LogComponentEnable ("DsrOptions", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrHelper", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrRouting", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrOptionHeader", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrFsHeader", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrGraReplyTable", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrSendBuffer", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrRouteCache", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrMaintainBuffer", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrRreqTable", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrErrorBuffer", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrNetworkQueue", LOG_LEVEL_ALL);
#endif

  NS_LOG_INFO ("creating the nodes");

  // General parameters 
  uint32_t nWifis = 50;
  uint32_t nSinks = 10;
  double TotalTime = 600.0;
  double dataTime = 500.0;
  double ppers = 1;
  uint32_t packetSize = 64;
  double dataStart = 1.0; // start sending data at 100s


  //mobility parameters
  double pauseTime = 0.0;
  double nodeSpeed = 20.0;
  double txpDistance = 250.0;
  std::string outputFileName = "Results/DSR/dsr_final_results_"+(std::to_string(nWifis));//+"-nWifis"+(std::to_string(nodeSpeed))+"-nodeSpeed_"+(std::to_string(nSinks))+"-nSinks_"+(std::to_string(txpDistance))+"-txpDistance";

  std::string rate = "0.512kbps";
  std::string dataMode ("DsssRate11Mbps");
  std::string phyMode ("DsssRate11Mbps");

  //Allow users to override the default parameters and set it to new ones from CommandLine.
  CommandLine cmd;
  cmd.AddValue ("nWifis", "Number of wifi nodes", nWifis);
  cmd.AddValue ("nSinks", "Number of SINK traffic nodes", nSinks);
  cmd.AddValue ("rate", "CBR traffic rate(in kbps), Default:8", rate);
  cmd.AddValue ("nodeSpeed", "Node speed in RandomWayPoint model, Default:20", nodeSpeed);
  cmd.AddValue ("packetSize", "The packet size", packetSize);
  cmd.AddValue ("txpDistance", "Specify node's transmit range, Default:300", txpDistance);
  cmd.AddValue ("pauseTime", "pauseTime for mobility model, Default: 0", pauseTime);
  cmd.Parse (argc, argv);

  SeedManager::SetSeed (10);
  SeedManager::SetRun (1);

  NodeContainer adhocNodes;
  adhocNodes.Create (nWifis);
  NetDeviceContainer allDevices;

  NS_LOG_INFO ("setting the default phy and channel parameters");
  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue (phyMode));
  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
  // disable fragmentation for frames below 2200 bytes
  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));

  NS_LOG_INFO ("setting the default phy and channel parameters ");
  WifiHelper wifi;
  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();

  YansWifiChannelHelper wifiChannel;
  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
  wifiChannel.AddPropagationLoss ("ns3::RangePropagationLossModel", "MaxRange", DoubleValue (txpDistance));
  wifiPhy.SetChannel (wifiChannel.Create ());

  // Add a mac and disable rate control
  WifiMacHelper wifiMac;
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue (dataMode), "ControlMode",
                                StringValue (phyMode));

  wifiMac.SetType ("ns3::AdhocWifiMac");
  allDevices = wifi.Install (wifiPhy, wifiMac, adhocNodes);

  NS_LOG_INFO ("Configure Tracing.");

  AsciiTraceHelper ascii;
  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (outputFileName+".tr");
  wifiPhy.EnableAsciiAll (stream);
  wifiPhy.EnablePcapAll(outputFileName);

  //read the SUMO generated trace file
  //Ns2MobilityHelper adhocMobility = Ns2MobilityHelper ("scratch/trace_files/dsr/dsr_final_"+(std::to_string(nWifis))+".tcl");
  Ns2MobilityHelper adhocMobility = Ns2MobilityHelper ("scratch/dsr_final_50.tcl");

  adhocMobility.Install();

  InternetStackHelper internet;
  DsrMainHelper dsrMain;
  DsrHelper dsr;
  internet.Install (adhocNodes);
  dsrMain.Install (dsr, adhocNodes);

  NS_LOG_INFO ("assigning ip address");
  Ipv4AddressHelper address;
  address.SetBase ("10.1.1.0", "255.255.255.0");
  Ipv4InterfaceContainer allInterfaces;
  allInterfaces = address.Assign (allDevices);

  uint16_t port = 9;
  double randomStartTime = (1 / ppers) / nSinks; //distributed btw 1s evenly as we are sending 4pkt/s

  for (uint32_t i = 0; i < nSinks; ++i)
    {
      PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
      ApplicationContainer apps_sink = sink.Install (adhocNodes.Get (i));
      apps_sink.Start (Seconds (0.0));
      apps_sink.Stop (Seconds (TotalTime));

      OnOffHelper onoff1 ("ns3::UdpSocketFactory", Address (InetSocketAddress (allInterfaces.GetAddress (i), port)));
      onoff1.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"));
      onoff1.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]"));
      onoff1.SetAttribute ("PacketSize", UintegerValue (packetSize));
      onoff1.SetAttribute ("DataRate", DataRateValue (DataRate (rate)));

      ApplicationContainer apps1 = onoff1.Install (adhocNodes.Get (i + nWifis - nSinks));
      apps1.Start (Seconds (dataStart + i * randomStartTime));
      apps1.Stop (Seconds (dataTime + i * randomStartTime));
    }

    Ptr<FlowMonitor> flowmon;
    FlowMonitorHelper flowmonHelper;
    flowmon = flowmonHelper.InstallAll ();


    NS_LOG_INFO ("Run Simulation.");

  Simulator::Stop (Seconds (TotalTime));

  AnimationInterface anim (outputFileName+"_anim.xml");
  anim.SetMaxPktsPerTraceFile(99999999999);

  Simulator::Run ();
  flowmon->CheckForLostPackets (); 
  Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier> (flowmonHelper.GetClassifier ());
  std::map<FlowId, FlowMonitor::FlowStats> stats = flowmon->GetFlowStats ();

for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator iter = stats.begin (); iter != stats.end (); ++iter)
  {
  Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (iter->first);

      NS_LOG_UNCOND("Flow ID: " << iter->first << " Src Addr " << t.sourceAddress << " Dst Addr " << t.destinationAddress);
          NS_LOG_UNCOND("Tx Packets = " << iter->second.txPackets);
          NS_LOG_UNCOND("Rx Packets = " << iter->second.rxPackets);
          NS_LOG_UNCOND("Throughput: " << iter->second.rxBytes * 8.0 / (iter->second.timeLastRxPacket.GetSeconds()-iter->second.timeFirstTxPacket.GetSeconds()) / 1024  << " Kbps");
  }
  flowmon->SerializeToXmlFile (outputFileName+"_flow.xml", true, true);


  Simulator::Destroy ();
}

Upvotes: 0

Views: 551

Answers (1)

Amiri
Amiri

Reputation: 2536

It's due to the way that DSR is implemented. See the discussions in the Bug 1844

DSR is an IP-level routing protocol. FlowMonitor doesn't track it for two reasons: 1) FlowMonitor doesn't track multicast packets (and DSR uses broadcast addresses), and 2) DSR packets aren't UDP or TCP (FlowMonitor only tracks L4 protocols).

So, an empty report is pretty much normal.

I'd close this bug as "Invalid".

If you want we can open another bug (enhancement level) to track that it would be nice to track multicast and IP-level traffic (maybe dividing it according to the protocol).

The difficulty might be to find appropriate statistic for those kind of traffic, as some of the actually tracked ones have little or no sense at all for multicast/broadcast messages.

and

Dsr is a shim protocol between UDP/TCP and IP. Actually it encapsulates the L4 traffic in its own packet. Or, if you like more the idea, it's adding its headers between IP and UDP/TCP.

FlowMonitor is not able to understand this, and packets are not tracked. Simple as this.

A way to fix this would be to mark the packets at UDP/TCP level and not at IP level, which is a bit more complex than one might think.

On the other hand, we could do it with the actual tag system, but I'll have to think about it.

Upvotes: 0

Related Questions