/* -*- mode: c++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2013 NICTA * * 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: Quincy Tse */ #include "ns3/core-module.h" #include "ns3/mobility-module.h" #include "ns3/wifi-module.h" #include "ns3/network-module.h" #include "ns3/applications-module.h" #include NS_LOG_COMPONENT_DEFINE ("Main"); using namespace ns3; using std::map; class MyPhyListener { public: typedef Time* Iterator; MyPhyListener (uint32_t numPackets = 5000) { m_maxPackets = numPackets; m_idlePeriods = new Time[numPackets]; m_currSize = 0; } ~MyPhyListener () { delete[] m_idlePeriods; } void NotifyNewState (Time start, Time duration, enum WifiPhy::State state) { if (state == WifiPhy::IDLE) { m_idlePeriods[m_currSize++] = duration; if (m_currSize >= m_maxPackets) Simulator::Stop (); } } Iterator Begin () { return m_idlePeriods; } Iterator End () { return m_idlePeriods + m_currSize; } size_t LogSize () { return m_currSize; } private: uint32_t m_maxPackets; Time *m_idlePeriods; uint32_t m_currSize; }; class Experiment { public: void Run (const WifiHelper & wifi, const YansWifiPhyHelper &wifiPhy, const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel); }; void Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel) { NodeContainer c; c.Create (3); PacketSocketHelper packetSocket; packetSocket.Install (c); YansWifiPhyHelper phy = wifiPhy; phy.SetChannel (wifiChannel.Create()); NqosWifiMacHelper mac = wifiMac; NetDeviceContainer devices = wifi.Install (phy, mac, c); MobilityHelper mobility; Ptr positionAlloc = CreateObject (); positionAlloc->Add (Vector (0,0,0)); positionAlloc->Add (Vector (0,0,0)); positionAlloc->Add (Vector (0,0,0)); mobility.SetPositionAllocator (positionAlloc); mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); mobility.Install (c); MyPhyListener pl; Callback sl = MakeCallback (&MyPhyListener::NotifyNewState, &pl); PointerValue p; Config::ConnectWithoutContext ("/NodeList/0/DeviceList/0/Phy/State/State", sl); PacketSocketAddress socket; socket.SetSingleDevice(devices.Get (0)->GetIfIndex ()); socket.SetPhysicalAddress (devices.Get (0)->GetBroadcast ()); socket.SetProtocol (1); OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket)); onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]")); onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]")); onoff.SetAttribute ("DataRate", DataRateValue (DataRate (60000000))); onoff.SetAttribute ("PacketSize", UintegerValue (800)); ApplicationContainer apps = onoff.Install (c); apps.Start (Seconds (0)); apps.Stop (Seconds (600.0)); Config::Set ("/NodeList/*/DeviceList/*/Mac/EifsNoDifs", TimeValue(Seconds(0))); /// Don't know why these don't work. /// Config::Set ("/NodeList/*/DeviceList/*/Mac/DcaTxop/MinCw", UintegerValue(cw)); /// Config::Set ("/NodeList/*/DeviceList/*/Mac/DcaTxop/Aifsn", UintegerValue(2)); for (NetDeviceContainer::Iterator it = devices.Begin(); it != devices.End(); ++it) { (*it)->GetAttribute ("Mac", p); Ptr rwm = p.Get (); rwm->GetAttribute ("DcaTxop", p); Ptr txop = p.Get (); txop->SetMinCw (15); txop->SetAifsn (2); } Simulator::Run (); devices.Get(0)->GetAttribute ("Mac", p); Ptr awm = p.Get (); TimeValue t; awm->GetAttribute("Sifs", t); const Time SIFS = t.Get (); awm->GetAttribute("Slot", t); const Time ST = t.Get (); const Time DIFS = SIFS + ST + ST; map distribution; for (MyPhyListener::Iterator it = pl.Begin (); it != pl.End (); ++it) { uint32_t slots = (uint32_t) std::floor((*it - DIFS).GetNanoSeconds () / (double)(ST.GetNanoSeconds ()) + 0.5); distribution[slots]++; } for (std::map::iterator it = distribution.begin (); it != distribution.end (); ++it) { std::cout << it->first << " - " << it->second/double(pl.LogSize ()) << " (" << it->second << ")" << std::endl; } Simulator::Destroy (); } int main (int argc, char *argv[]) { // Default action - load Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Load")); CommandLine cmd; cmd.Parse (argc, argv); Experiment experiment; WifiHelper wifi = WifiHelper::Default (); wifi.SetStandard (WIFI_PHY_STANDARD_80211a); wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager"); NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default (); YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); YansWifiChannelHelper wifiChannel; wifiChannel.AddPropagationLoss ("ns3::RangePropagationLossModel", "MaxRange", DoubleValue (9e9)); wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel); return 0; }