/* * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle. * * 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: Sidharth Nabar , He Wu */ #include "ns3/config-store-module.h" #include "ns3/core-module.h" #include "ns3/energy-module.h" #include "ns3/internet-module.h" #include "ns3/mobility-module.h" #include "ns3/network-module.h" #include "ns3/wifi-radio-energy-model-helper.h" #include "ns3/yans-wifi-helper.h" #include #include #include #include using namespace ns3; NS_LOG_COMPONENT_DEFINE("EnergyExample"); /** * Print a received packet * * \param from sender address * \return a sting with the details of the packet: dst {IP, port}, time. */ static inline std::string PrintReceivedPacket(Address& from) { InetSocketAddress iaddr = InetSocketAddress::ConvertFrom(from); std::ostringstream oss; oss << "--\nReceived one packet! Socket: " << iaddr.GetIpv4() << " port: " << iaddr.GetPort() << " at time = " << Simulator::Now().GetSeconds() << "\n--"; return oss.str(); } /** * \param socket Pointer to socket. * * Packet receiving sink. */ void ReceivePacket(Ptr socket) { Ptr packet; Address from; while ((packet = socket->RecvFrom(from))) { if (packet->GetSize() > 0) { NS_LOG_UNCOND(PrintReceivedPacket(from)); } } } /** * \param socket Pointer to socket. * \param pktSize Packet size. * \param n Pointer to node. * \param pktCount Number of packets to generate. * \param pktInterval Packet sending interval. * * Traffic generator. */ static void GenerateTraffic(Ptr socket, uint32_t pktSize, Ptr n, uint32_t pktCount, Time pktInterval) { if (pktCount > 0) { socket->Send(Create(pktSize)); Simulator::Schedule(pktInterval, &GenerateTraffic, socket, pktSize, n, pktCount - 1, pktInterval); } else { socket->Close(); } } /** * Trace function for remaining energy at node. * * \param oldValue Old value * \param remainingEnergy New value */ void RemainingEnergy(double oldValue, double remainingEnergy) { NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s Current remaining energy = " << remainingEnergy << "J"); } /** * \brief Trace function for total energy consumption at node. * * \param oldValue Old value * \param totalEnergy New value */ void TotalEnergy(double oldValue, double totalEnergy) { NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s Total energy consumed by radio = " << totalEnergy << "J"); } int main(int argc, char* argv[]) { /* LogComponentEnable ("EnergySource", LOG_LEVEL_DEBUG); LogComponentEnable ("BasicEnergySource", LOG_LEVEL_DEBUG); LogComponentEnable ("DeviceEnergyModel", LOG_LEVEL_DEBUG); LogComponentEnable ("WifiRadioEnergyModel", LOG_LEVEL_DEBUG); */ LogComponentEnable("EnergyExample", LogLevel(LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_LEVEL_INFO)); std::string phyMode("DsssRate1Mbps"); double Prss = -80; // dBm uint32_t PpacketSize = 200; // bytes bool verbose = false; // simulation parameters uint32_t numPackets = 10000; // number of packets to send double interval = 1; // seconds double startTime = 0.0; // seconds double distanceToRx = 100.0; // meters CommandLine cmd(__FILE__); cmd.AddValue("phyMode", "Wifi Phy mode", phyMode); cmd.AddValue("Prss", "Intended primary RSS (dBm)", Prss); cmd.AddValue("PpacketSize", "size of application packet sent", PpacketSize); cmd.AddValue("numPackets", "Total number of packets to send", numPackets); cmd.AddValue("startTime", "Simulation start time", startTime); cmd.AddValue("distanceToRx", "X-Axis distance between nodes", distanceToRx); cmd.AddValue("verbose", "Turn on all device log components", verbose); cmd.Parse(argc, argv); // Convert to time object Time interPacketInterval = Seconds(interval); // 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("2200")); // Fix non-unicast data rate to be the same as that of unicast Config::SetDefault("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue(phyMode)); NodeContainer c; c.Create(2); // create 2 nodes NodeContainer networkNodes; networkNodes.Add(c.Get(0)); networkNodes.Add(c.Get(1)); // The below set of helpers will help us to put together the wifi NICs we want WifiHelper wifi; if (verbose) { wifi.EnableLogComponents(); } wifi.SetStandard(WIFI_STANDARD_80211b); /** Wifi PHY **/ /***************************************************************************/ YansWifiPhyHelper wifiPhy; /** wifi channel **/ YansWifiChannelHelper wifiChannel; wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel"); wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel"); // create wifi channel Ptr wifiChannelPtr = wifiChannel.Create(); wifiPhy.SetChannel(wifiChannelPtr); /** MAC layer **/ // Add a MAC and disable rate control WifiMacHelper wifiMac; wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue(phyMode), "ControlMode", StringValue(phyMode)); // Set it to ad-hoc mode wifiMac.SetType("ns3::AdhocWifiMac"); /** install PHY + MAC **/ NetDeviceContainer devices = wifi.Install(wifiPhy, wifiMac, networkNodes); /** mobility **/ MobilityHelper mobility; Ptr positionAlloc = CreateObject(); positionAlloc->Add(Vector(0.0, 0.0, 0.0)); positionAlloc->Add(Vector(2 * distanceToRx, 0.0, 0.0)); mobility.SetPositionAllocator(positionAlloc); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(c); /** Energy Model **/ /***************************************************************************/ /* energy source */ BasicEnergySourceHelper basicSourceHelper; // configure energy source basicSourceHelper.Set("BasicEnergySourceInitialEnergyJ", DoubleValue(0.1)); // install source EnergySourceContainer sources = basicSourceHelper.Install(c); /* device energy model */ WifiRadioEnergyModelHelper radioEnergyHelper; // configure radio energy model radioEnergyHelper.Set("TxCurrentA", DoubleValue(0.0174)); // install device model DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install(devices, sources); /***************************************************************************/ /** Internet stack **/ InternetStackHelper internet; internet.Install(networkNodes); Ipv4AddressHelper ipv4; NS_LOG_INFO("Assign IP Addresses."); ipv4.SetBase("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer i = ipv4.Assign(devices); TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory"); Ptr recvSink = Socket::CreateSocket(networkNodes.Get(1), tid); // node 1, receiver InetSocketAddress local = InetSocketAddress(Ipv4Address::GetAny(), 80); recvSink->Bind(local); recvSink->SetRecvCallback(MakeCallback(&ReceivePacket)); Ptr source = Socket::CreateSocket(networkNodes.Get(0), tid); // node 0, sender InetSocketAddress remote = InetSocketAddress(Ipv4Address::GetBroadcast(), 80); source->SetAllowBroadcast(true); source->Connect(remote); /** connect trace sources **/ /***************************************************************************/ // all sources are connected to node 1 // energy source Ptr basicSourcePtr = DynamicCast(sources.Get(1)); basicSourcePtr->TraceConnectWithoutContext("RemainingEnergy", MakeCallback(&RemainingEnergy)); // device energy model Ptr basicRadioModelPtr = basicSourcePtr->FindDeviceEnergyModels("ns3::WifiRadioEnergyModel").Get(0); NS_ASSERT(basicRadioModelPtr); basicRadioModelPtr->TraceConnectWithoutContext("TotalEnergyConsumption", MakeCallback(&TotalEnergy)); /***************************************************************************/ /** simulation setup **/ // start traffic Simulator::Schedule(Seconds(startTime), &GenerateTraffic, source, PpacketSize, networkNodes.Get(0), numPackets, interPacketInterval); Simulator::Stop(Seconds(10.0)); Simulator::Run(); for (DeviceEnergyModelContainer::Iterator iter = deviceModels.Begin(); iter != deviceModels.End(); iter++) { double energyConsumed = (*iter)->GetTotalEnergyConsumption(); NS_LOG_UNCOND("End of simulation (" << Simulator::Now().GetSeconds() << "s) Total energy consumed by radio = " << energyConsumed << "J"); NS_ASSERT(energyConsumed <= 0.1); } Simulator::Destroy(); return 0; }