/* * Copyright (c) 2011 University of Kansas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Justin Rohrer * * James P.G. Sterbenz , director * ResiliNets Research Group https://resilinets.org/ * Information and Telecommunication Technology Center (ITTC) * and Department of Electrical Engineering and Computer Science * The University of Kansas Lawrence, KS USA. * * Work supported in part by NSF FIND (Future Internet Design) Program * under grant CNS-0626918 (Postmodern Internet Architecture), * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI), * US Department of Defense (DoD), and ITTC at The University of Kansas. */ /* * This example program allows one to run ns-3 DSDV, AODV, or OLSR under * a typical random waypoint mobility model. * * By default, the simulation runs for 200 simulated seconds, of which * the first 50 are used for start-up time. The number of nodes is 50. * Nodes move according to RandomWaypointMobilityModel with a speed of * 20 m/s and no pause time within a 300x1500 m region. The WiFi is * in ad hoc mode with a 2 Mb/s rate (802.11b) and a Friis loss model. * The transmit power is set to 7.5 dBm. * * It is possible to change the mobility and density of the network by * directly modifying the speed and the number of nodes. It is also * possible to change the characteristics of the network by changing * the transmit power (as power increases, the impact of mobility * decreases and the effective density increases). * * By default, OLSR is used, but specifying a value of 2 for the protocol * will cause AODV to be used, and specifying a value of 3 will cause * DSDV to be used. * * By default, there are 10 source/sink data pairs sending UDP data * at an application rate of 2.048 Kb/s each. This is typically done * at a rate of 4 64-byte packets per second. Application data is * started at a random time between 50 and 51 seconds and continues * to the end of the simulation. * * The program outputs a few items: * - packet receptions are notified to stdout such as: * received one packet from * - each second, the data reception statistics are tabulated and output * to a comma-separated value (csv) file * - some tracing and flow monitor configuration that used to work is * left commented inline in the program */ #include "ns3/aodv-module.h" #include "ns3/applications-module.h" #include "ns3/core-module.h" #include "ns3/dsdv-module.h" #include "ns3/dsr-module.h" #include "ns3/internet-module.h" #include "ns3/mobility-module.h" #include "ns3/network-module.h" #include "ns3/olsr-module.h" #include "ns3/yans-wifi-helper.h" #include #include using namespace ns3; using namespace dsr; NS_LOG_COMPONENT_DEFINE("manet-routing-compare"); /** * Routing experiment class. * * It handles the creation and run of an experiment. */ class RoutingExperiment { public: RoutingExperiment(); /** * Run the experiment. * \param nSinks The number of Sink Nodes. * \param txp The Tx power. * \param CSVfileName The output CSV filename. */ void Run(int nSinks, double txp, std::string CSVfileName); // static void SetMACParam (ns3::NetDeviceContainer & devices, // int slotDistance); /** * Handles the command-line parmeters. * \param argc The argument count. * \param argv The argument vector. * \return the CSV filename. */ std::string CommandSetup(int argc, char** argv); private: /** * Setup the receiving socket in a Sink Node. * \param addr The address of the node. * \param node The node pointer. * \return the socket. */ Ptr SetupPacketReceive(Ipv4Address addr, Ptr node); /** * Receive a packet. * \param socket The receiving socket. */ void ReceivePacket(Ptr socket); /** * Compute the throughput. */ void CheckThroughput(); uint32_t port; //!< Receiving port number. uint32_t bytesTotal; //!< Total received bytes. uint32_t packetsReceived; //!< Total received packets. std::string m_CSVfileName; //!< CSV filename. int m_nSinks; //!< Number of sink nodes. std::string m_protocolName; //!< Protocol name. double m_txp; //!< Tx power. bool m_traceMobility; //!< Enavle mobility tracing. uint32_t m_protocol; //!< Protocol type. }; RoutingExperiment::RoutingExperiment() : port(9), bytesTotal(0), packetsReceived(0), m_CSVfileName("manet-routing.output.csv"), m_traceMobility(false), m_protocol(2) // AODV { } static inline std::string PrintReceivedPacket(Ptr socket, Ptr packet, Address senderAddress) { std::ostringstream oss; oss << Simulator::Now().GetSeconds() << " " << socket->GetNode()->GetId(); if (InetSocketAddress::IsMatchingType(senderAddress)) { InetSocketAddress addr = InetSocketAddress::ConvertFrom(senderAddress); oss << " received one packet from " << addr.GetIpv4(); } else { oss << " received one packet!"; } return oss.str(); } void RoutingExperiment::ReceivePacket(Ptr socket) { Ptr packet; Address senderAddress; while ((packet = socket->RecvFrom(senderAddress))) { bytesTotal += packet->GetSize(); packetsReceived += 1; NS_LOG_UNCOND(PrintReceivedPacket(socket, packet, senderAddress)); } } void RoutingExperiment::CheckThroughput() { double kbs = (bytesTotal * 8.0) / 1000; bytesTotal = 0; std::ofstream out(m_CSVfileName, std::ios::app); out << (Simulator::Now()).GetSeconds() << "," << kbs << "," << packetsReceived << "," << m_nSinks << "," << m_protocolName << "," << m_txp << "" << std::endl; out.close(); packetsReceived = 0; Simulator::Schedule(Seconds(1.0), &RoutingExperiment::CheckThroughput, this); } Ptr RoutingExperiment::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(&RoutingExperiment::ReceivePacket, this)); return sink; } std::string RoutingExperiment::CommandSetup(int argc, char** argv) { CommandLine cmd(__FILE__); cmd.AddValue("CSVfileName", "The name of the CSV output file name", m_CSVfileName); cmd.AddValue("traceMobility", "Enable mobility tracing", m_traceMobility); cmd.AddValue("protocol", "1=OLSR;2=AODV;3=DSDV;4=DSR", m_protocol); cmd.Parse(argc, argv); return m_CSVfileName; } int main(int argc, char* argv[]) { RoutingExperiment experiment; std::string CSVfileName = experiment.CommandSetup(argc, argv); // blank out the last output file and write the column headers std::ofstream out(CSVfileName); out << "SimulationSecond," << "ReceiveRate," << "PacketsReceived," << "NumberOfSinks," << "RoutingProtocol," << "TransmissionPower" << std::endl; out.close(); int nSinks = 10; double txp = 7.5; experiment.Run(nSinks, txp, CSVfileName); return 0; } void RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName) { Packet::EnablePrinting(); m_nSinks = nSinks; m_txp = txp; m_CSVfileName = CSVfileName; int nWifis = 50; double TotalTime = 200.0; std::string rate("2048bps"); std::string phyMode("DsssRate11Mbps"); std::string tr_name("manet-routing-compare"); int nodeSpeed = 20; // in m/s int nodePause = 0; // in s m_protocolName = "protocol"; Config::SetDefault("ns3::OnOffApplication::PacketSize", StringValue("64")); Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue(rate)); // Set Non-unicastMode rate to unicast mode Config::SetDefault("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue(phyMode)); NodeContainer adhocNodes; adhocNodes.Create(nWifis); // setting up wifi phy and channel using helpers WifiHelper wifi; wifi.SetStandard(WIFI_STANDARD_80211b); YansWifiPhyHelper wifiPhy; YansWifiChannelHelper wifiChannel; wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel"); wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel"); wifiPhy.SetChannel(wifiChannel.Create()); // Add a mac and disable rate control WifiMacHelper wifiMac; wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue(phyMode), "ControlMode", StringValue(phyMode)); wifiPhy.Set("TxPowerStart", DoubleValue(txp)); wifiPhy.Set("TxPowerEnd", DoubleValue(txp)); wifiMac.SetType("ns3::AdhocWifiMac"); NetDeviceContainer adhocDevices = wifi.Install(wifiPhy, wifiMac, adhocNodes); MobilityHelper mobilityAdhoc; int64_t streamIndex = 0; // used to get consistent mobility across scenarios ObjectFactory pos; pos.SetTypeId("ns3::RandomRectanglePositionAllocator"); pos.Set("X", StringValue("ns3::UniformRandomVariable[Min=0.0|Max=300.0]")); pos.Set("Y", StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1500.0]")); Ptr taPositionAlloc = pos.Create()->GetObject(); streamIndex += taPositionAlloc->AssignStreams(streamIndex); std::stringstream ssSpeed; ssSpeed << "ns3::UniformRandomVariable[Min=0.0|Max=" << nodeSpeed << "]"; std::stringstream ssPause; ssPause << "ns3::ConstantRandomVariable[Constant=" << nodePause << "]"; mobilityAdhoc.SetMobilityModel("ns3::RandomWaypointMobilityModel", "Speed", StringValue(ssSpeed.str()), "Pause", StringValue(ssPause.str()), "PositionAllocator", PointerValue(taPositionAlloc)); mobilityAdhoc.SetPositionAllocator(taPositionAlloc); mobilityAdhoc.Install(adhocNodes); streamIndex += mobilityAdhoc.AssignStreams(adhocNodes, streamIndex); AodvHelper aodv; OlsrHelper olsr; DsdvHelper dsdv; DsrHelper dsr; DsrMainHelper dsrMain; Ipv4ListRoutingHelper list; InternetStackHelper internet; switch (m_protocol) { case 1: list.Add(olsr, 100); m_protocolName = "OLSR"; break; case 2: list.Add(aodv, 100); m_protocolName = "AODV"; break; case 3: list.Add(dsdv, 100); m_protocolName = "DSDV"; break; case 4: m_protocolName = "DSR"; break; default: NS_FATAL_ERROR("No such protocol:" << m_protocol); } if (m_protocol < 4) { internet.SetRoutingHelper(list); internet.Install(adhocNodes); } else if (m_protocol == 4) { internet.Install(adhocNodes); dsrMain.Install(dsr, adhocNodes); } NS_LOG_INFO("assigning ip address"); Ipv4AddressHelper addressAdhoc; addressAdhoc.SetBase("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer adhocInterfaces; adhocInterfaces = addressAdhoc.Assign(adhocDevices); OnOffHelper onoff1("ns3::UdpSocketFactory", Address()); onoff1.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1.0]")); onoff1.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0.0]")); for (int i = 0; i < nSinks; i++) { Ptr sink = SetupPacketReceive(adhocInterfaces.GetAddress(i), adhocNodes.Get(i)); AddressValue remoteAddress(InetSocketAddress(adhocInterfaces.GetAddress(i), port)); onoff1.SetAttribute("Remote", remoteAddress); Ptr var = CreateObject(); ApplicationContainer temp = onoff1.Install(adhocNodes.Get(i + nSinks)); temp.Start(Seconds(var->GetValue(100.0, 101.0))); temp.Stop(Seconds(TotalTime)); } std::stringstream ss; ss << nWifis; std::string nodes = ss.str(); std::stringstream ss2; ss2 << nodeSpeed; std::string sNodeSpeed = ss2.str(); std::stringstream ss3; ss3 << nodePause; std::string sNodePause = ss3.str(); std::stringstream ss4; ss4 << rate; std::string sRate = ss4.str(); // NS_LOG_INFO("Configure Tracing."); // tr_name = tr_name + "_" + m_protocolName +"_" + nodes + "nodes_" + sNodeSpeed + "speed_" + // sNodePause + "pause_" + sRate + "rate"; // AsciiTraceHelper ascii; // Ptr osw = ascii.CreateFileStream(tr_name + ".tr"); // wifiPhy.EnableAsciiAll(osw); AsciiTraceHelper ascii; MobilityHelper::EnableAsciiAll(ascii.CreateFileStream(tr_name + ".mob")); // Ptr flowmon; // FlowMonitorHelper flowmonHelper; // flowmon = flowmonHelper.InstallAll(); NS_LOG_INFO("Run Simulation."); CheckThroughput(); Simulator::Stop(Seconds(TotalTime)); Simulator::Run(); // flowmon->SerializeToXmlFile(tr_name + ".flowmon", false, false); Simulator::Destroy(); }