/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2009 University of Washington * * 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 * */ #include "ns3/core-module.h" #include "ns3/common-module.h" #include "ns3/node-module.h" #include "ns3/helper-module.h" #include "ns3/mobility-module.h" #include "ns3/contrib-module.h" #include "ns3/wifi-module.h" #include #include #include #include NS_LOG_COMPONENT_DEFINE ("AeroExperiment"); using namespace ns3; class AeroExperiment { public: AeroExperiment (); void Run (uint32_t dataRate, uint32_t gridSize, uint32_t numNodes, uint32_t packetSize, std::string phyMode, std::string rtsThreshold, uint32_t transmissionPower, uint32_t transmissionRange, bool verbose, std::string CSVfileName, uint32_t helloInterval, double queueInterval, uint32_t neighborHoldTime, uint32_t maxQueueLen, uint32_t maxQueueTime, std::string mobilityModel, std::string routingProtocol, uint32_t warmupSeconds, uint32_t runApplicationSeconds, std::string propagationLossModel, int32_t rssForFixedRssLossModel, uint32_t speed, bool ferry, bool wifiTrace, bool pcapTrace, bool flowMonitor, bool mobilityTrace); std::string CommandSetup (int argc, char **argv); private: Vector GetPosition (Ptr node); Ptr SetupPacketReceive (Ipv4Address addr, Ptr node); NodeContainer GenerateNeighbors(NodeContainer c, uint32_t senderId); void ApplicationSetup (Ptr client, Ptr server, double start, double stop); void AssignNeighbors (NodeContainer c); void SelectSrcDest (NodeContainer c); void ReceivePacket (Ptr socket); void CheckThroughput (); void SendMultiDestinations (Ptr sender, NodeContainer c); void AdvancePosition (Ptr node); Gnuplot2dDataset m_output; uint32_t port; uint32_t bytesTotal; uint32_t packetsReceived; uint32_t m_dataRate; uint32_t m_gridSize; uint32_t m_numNodes; uint32_t m_packetSize; std::string m_phyMode; std::string m_rtsThreshold; std::string m_CSVfileName; uint32_t m_transmissionPower; std::string m_mobilityModel; std::string m_routingProtocol; bool m_verbose; bool m_ferry; uint32_t m_warmupSeconds; uint32_t m_runApplicationSeconds; int32_t m_rssForFixedRssLossModel; std::string m_propagationLossModel; //AerorRP settings uint32_t m_helloInterval; uint32_t m_transmissionRange; double m_queueInterval; uint32_t m_neighborHoldTime; uint32_t m_maxQueueLen; uint32_t m_maxQueueTime; uint32_t m_speed; }; AeroExperiment::AeroExperiment () : port(50000), bytesTotal(0), packetsReceived(0), m_CSVfileName("output.csv") { } void AeroExperiment::ReceivePacket (Ptr socket) { NS_LOG_UNCOND (Simulator::Now().GetSeconds () << " Received one packet!"); Ptr packet; while (packet = socket->Recv ()) { bytesTotal += packet->GetSize(); packetsReceived += 1; } } void AeroExperiment::CheckThroughput() { double kbs = (bytesTotal * 8.0) / 1000; bytesTotal = 0; m_output.Add ((Simulator::Now ()).GetSeconds (), kbs); std::ofstream out(m_CSVfileName.c_str(), std::ios::app); out << (Simulator::Now ()).GetSeconds () << "," << kbs << "," << packetsReceived << "," << m_dataRate << "," << m_gridSize << "," << m_numNodes << "," << m_packetSize << "," << m_phyMode << "," << m_rtsThreshold << "," << m_transmissionPower << "," << m_transmissionRange << "," << m_helloInterval << "," << m_queueInterval << "," << m_neighborHoldTime << "," << m_maxQueueLen << "," << m_maxQueueTime << "," << m_mobilityModel << "," << m_routingProtocol << "," << m_warmupSeconds << "," << m_runApplicationSeconds << "," << m_propagationLossModel << "," << m_rssForFixedRssLossModel << "," << m_speed << "," << m_ferry << std::endl; out.close(); packetsReceived = 0; Simulator::Schedule (Seconds (1.0), &AeroExperiment::CheckThroughput, this); } Ptr AeroExperiment::SetupPacketReceive (Ipv4Address addr, Ptr node) { TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory"); Ptr sink = Socket::CreateSocket (node, tid); InetSocketAddress local = InetSocketAddress (addr, port); sink->Bind (local); sink->SetRecvCallback (MakeCallback (&AeroExperiment::ReceivePacket, this)); return sink; } std::string AeroExperiment::CommandSetup (int argc, char **argv) { CommandLine cmd; cmd.AddValue("CSVfileName", "The name of the CSV output file name", m_CSVfileName); cmd.Parse (argc, argv); return m_CSVfileName; } int main (int argc, char *argv[]) { AeroExperiment experiment; std::string CSVfileName = experiment.CommandSetup(argc,argv); //blank out the last output file and write the column headers std::ofstream out(CSVfileName.c_str()); out << "SimulationSecond," << "ReceiveRate," << "PacketsReceived," << "SendRate," << "GridWidth," << "NumNodes," << "PacketSize," << "PhyMode," << "RTS_Threshold," << "TransmissionPower," << "TransmissionRange," << "HelloInterval," << "QueueCheckInterval," << "NeighborHoldTime," << "MaxQueueLength," << "MaxQueueTime," << "MobilityModel," << "RoutingProtocol," << "WarmupSeconds," << "RunApplicationSeconds," << "PropagationLossModel," << "RssForFixedRssLossModel," << "Speed," << "Ferry" << std::endl; out.close(); uint32_t dataRate = 8; uint32_t gridSize = 150000; uint32_t numNodes = 60; uint32_t packetSize = 1000; std::string phyMode = "wifib-11mbs"; std::string rtsThreshold = "2200"; uint32_t transmissionPower; uint32_t transmissionRange = 27800; bool verbose = false; uint32_t helloInterval = 2; double queueInterval = 0.5; uint32_t neighborHoldTime = 4; uint32_t maxQueueLen = 5000; uint32_t maxQueueTime = 300; std::string mobilityModel; std::string routingProtocol; uint32_t warmupSeconds = 30; uint32_t runApplicationSeconds = 100; std::string propagationLossModel; int32_t rssForFixedRssLossModel = -85; uint32_t speed = 1200; bool ferry = false;; bool wifiTrace = false; bool pcapTrace = false; bool flowMonitor = false; bool mobilityTrace = false; std::string mobilityModels [] = { "ConstantPosition" }; std::string routingProtocols [] = { "AODV" }; for(int j = 10; j <= 60; j = j+10) { numNodes = j; mobilityModel = mobilityModels[0]; routingProtocol = routingProtocols[0]; experiment = AeroExperiment(); std::string propagationLossModel = "FriisPropagationLossModel"; transmissionPower = 50; experiment.Run(dataRate, gridSize, numNodes, packetSize, phyMode, rtsThreshold, transmissionPower, transmissionRange, verbose, CSVfileName, helloInterval, queueInterval, neighborHoldTime, maxQueueLen, maxQueueTime, mobilityModel, routingProtocol, warmupSeconds, runApplicationSeconds, propagationLossModel, rssForFixedRssLossModel, speed, ferry, wifiTrace, pcapTrace, flowMonitor, mobilityTrace); } return 0; } void AeroExperiment::Run (uint32_t dataRate, uint32_t gridSize, uint32_t numNodes, uint32_t packetSize, std::string phyMode, std::string rtsThreshold, uint32_t transmissionPower, uint32_t transmissionRange, bool verbose, std::string CSVfileName, uint32_t helloInterval, double queueInterval, uint32_t neighborHoldTime, uint32_t maxQueueLen, uint32_t maxQueueTime, std::string mobilityModel, std::string routingProtocol, uint32_t warmupSeconds, uint32_t runApplicationSeconds, std::string propagationLossModel, int32_t rssForFixedRssLossModel, uint32_t speed, bool ferry, bool wifiTrace, bool pcapTrace, bool flowMonitor, bool mobilityTrace) { m_dataRate = dataRate; m_gridSize = gridSize; m_numNodes = numNodes; m_packetSize = packetSize; m_phyMode = phyMode; m_rtsThreshold = rtsThreshold; m_transmissionPower = transmissionPower; m_transmissionRange = transmissionRange; m_verbose = verbose; m_CSVfileName = CSVfileName; m_helloInterval = helloInterval; m_queueInterval = queueInterval; m_neighborHoldTime = neighborHoldTime; m_maxQueueLen = maxQueueLen; m_maxQueueTime = maxQueueTime; m_mobilityModel = mobilityModel; m_routingProtocol = routingProtocol; m_warmupSeconds = warmupSeconds; m_runApplicationSeconds = runApplicationSeconds; m_propagationLossModel = propagationLossModel; m_rssForFixedRssLossModel = rssForFixedRssLossModel; m_speed = speed; m_ferry = ferry; // disable fragmentation for frames below 2200 bytes Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200")); // turn off RTS/CTS for frames below 2200 bytes Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue (m_rtsThreshold)); // Fix non-unicast data rate to be the same as that of unicast Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue (m_phyMode)); NodeContainer tas; tas.Create (m_numNodes); NodeContainer sinkNodeContainer; sinkNodeContainer.Create (1); WifiHelper wifi; if (verbose) { wifi.EnableLogComponents (); // Turn on all Wifi logging } wifi.SetStandard (WIFI_PHY_STANDARD_80211b); YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); wifiPhy.Set ("TxPowerStart",DoubleValue (m_transmissionPower)); wifiPhy.Set ("TxPowerEnd",DoubleValue (m_transmissionPower)); //http://www.nsnam.org/bugzilla/show_bug.cgi?id=689 wifiPhy.Set ("EnergyDetectionThreshold", DoubleValue (-96)); wifiPhy.Set ("CcaMode1Threshold", DoubleValue (-99)); YansWifiChannelHelper wifiChannel; wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); if(propagationLossModel == "LogDistancePropagationLossModel") { wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel"); } else if (propagationLossModel == "FixedRssLossModel") { wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",DoubleValue(rssForFixedRssLossModel)); } else if (propagationLossModel == "FriisPropagationLossModel") { wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel"); } wifiPhy.SetChannel (wifiChannel.Create ()); // Add a non-QoS upper mac, and disable rate control NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default (); wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode",StringValue(m_phyMode), "ControlMode",StringValue(m_phyMode)); wifiMac.SetType ("ns3::AdhocWifiMac"); NetDeviceContainer taDevices = wifi.Install (wifiPhy, wifiMac, tas); NetDeviceContainer sinkDevice = wifi.Install (wifiPhy, wifiMac, sinkNodeContainer); MobilityHelper mobility; if(mobilityModel == "RandomWaypoint") { ObjectFactory pos; pos.SetTypeId ("ns3::RandomRectanglePositionAllocator"); pos.Set ("X", RandomVariableValue (UniformVariable (0.0, m_gridSize))); pos.Set ("Y", RandomVariableValue (UniformVariable (0.0, m_gridSize))); Ptr taPositionAlloc = pos.Create ()->GetObject (); mobility.SetPositionAllocator (taPositionAlloc); mobility.SetMobilityModel ("ns3::RandomWaypointMobilityModel", "Speed", RandomVariableValue (ConstantVariable (m_speed)), "Pause", RandomVariableValue (ConstantVariable (0)), "PositionAllocator", PointerValue (taPositionAlloc)); } else if(mobilityModel == "ConstantPosition") { ObjectFactory pos; pos.SetTypeId ("ns3::RandomRectanglePositionAllocator"); pos.Set ("X", RandomVariableValue (UniformVariable (0.0, m_gridSize))); pos.Set ("Y", RandomVariableValue (UniformVariable (0.0, m_gridSize))); Ptr taPositionAlloc = pos.Create ()->GetObject (); mobility.SetPositionAllocator (taPositionAlloc); mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); } mobility.Install (tas); //now, setup the stationary GS in the center mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); Ptr positionAlloc = CreateObject (); positionAlloc->Add(Vector (m_gridSize/2, m_gridSize/2, 0.0)) ; mobility.SetPositionAllocator (positionAlloc); mobility.Install (sinkNodeContainer); Ipv4ListRoutingHelper list; if (routingProtocol == "OLSR") { OlsrHelper olsr; list.Add (olsr, 20); } else if (routingProtocol == "AODV") { AodvHelper aodv; list.Add(aodv, 20); } InternetStackHelper internet; internet.SetRoutingHelper (list); internet.Install (NodeContainer (tas,sinkNodeContainer)); Ipv4AddressHelper ipv4; ipv4.SetBase ("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer taAddresses = ipv4.Assign (taDevices); Ipv4InterfaceContainer sinkAddresses = ipv4.Assign (sinkDevice); std::stringstream ssa; ssa << m_dataRate; std::string m_dataRate2 = ssa.str() + "kb/s"; OnOffHelper onoff ("ns3::UdpSocketFactory", Address ()); onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); onoff.SetAttribute ("DataRate", DataRateValue (DataRate (m_dataRate2))); onoff.SetAttribute ("PacketSize", UintegerValue (m_packetSize)); ApplicationContainer TA_apps; for (uint32_t i = 0; i < tas.GetN (); ++i) { AddressValue remoteAddress (InetSocketAddress (sinkAddresses.GetAddress (0), port)); onoff.SetAttribute ("Remote", remoteAddress); UniformVariable var; ApplicationContainer temp = onoff.Install (tas.Get (i)); temp.Start(Seconds (var.GetValue(m_warmupSeconds,m_warmupSeconds + 1))); temp.Stop (Seconds (m_warmupSeconds + m_runApplicationSeconds)); } Ptr sink = SetupPacketReceive (sinkAddresses.GetAddress (0), sinkNodeContainer.Get(0)); std::string outputFileName = m_dataRate2; size_t j; for ( ; (j = outputFileName.find( "/" )) != std::string::npos ; ) { outputFileName.replace( j, 1, "" );} std::stringstream ss; ss << numNodes; std::string nodes = ss.str(); std::stringstream ss2; ss2 << transmissionRange; std::string range = ss2.str(); outputFileName = outputFileName + "_" + routingProtocol + "_" + nodes + "Nodes" + "_" + range + "TxRange" + "_" + mobilityModel; if(propagationLossModel == "LogDistancePropagationLossModel") { outputFileName = outputFileName + "_LogDistance"; } else if (propagationLossModel == "FixedRssLossModel") { outputFileName = outputFileName + "_FixedRss"; } else if (propagationLossModel == "FriisPropagationLossModel") { outputFileName = outputFileName + "_Friis"; } std::ofstream ascii; if(wifiTrace) { Packet::EnablePrinting (); ascii.open ((outputFileName+".tr").c_str()); YansWifiPhyHelper::EnableAsciiAll (ascii); } if(pcapTrace) { wifiPhy.EnablePcap ( outputFileName, sinkNodeContainer); } Ptr flowmon; if(flowMonitor) { FlowMonitorHelper flowmonHelper; flowmon = flowmonHelper.InstallAll (); } std::ofstream mobilityAscii; if(mobilityTrace) { mobilityAscii.open ((outputFileName+"_mobility.tr").c_str()); MobilityHelper::EnableAsciiAll(mobilityAscii); } CheckThroughput (); Simulator::Stop (Seconds (m_warmupSeconds + m_runApplicationSeconds + 100)); Simulator::Run (); if(flowMonitor) { flowmon->SerializeToXmlFile (outputFileName+".xml", false, false); } Simulator::Destroy (); }