diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 5d770e1e8..44591da71 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -21,6 +21,14 @@ Supported platforms New user-visible features ------------------------- +- SpectrumChannel models now support the usage of single-frequency + propagation loss models based on the PropagationLossModel + class. These model can be used in conjunction with + the frequency-dependent propagation loss model based on the + SpectrumPropagationLossModel class already supported by + SpectrumChannel. + + Bugs fixed ---------- - bug 1033 - Mesh airtime-metric fixed diff --git a/src/aodv/model/aodv-routing-protocol.cc b/src/aodv/model/aodv-routing-protocol.cc index 23a952921..c6f362216 100644 --- a/src/aodv/model/aodv-routing-protocol.cc +++ b/src/aodv/model/aodv-routing-protocol.cc @@ -873,8 +873,11 @@ RoutingProtocol::SendRequest (Ipv4Address dst) ScheduleRreqRetry (dst); if (EnableHello) { - m_htimer.Cancel (); - m_htimer.Schedule (HelloInterval - Time (0.01 * MilliSeconds (UniformVariable ().GetInteger (0, 10)))); + if (!m_htimer.IsRunning ()) + { + m_htimer.Cancel (); + m_htimer.Schedule (HelloInterval - Time (0.01 * MilliSeconds (UniformVariable ().GetInteger (0, 10)))); + } } } @@ -1137,8 +1140,11 @@ RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, Ipv4Address s if (EnableHello) { - m_htimer.Cancel (); - m_htimer.Schedule (HelloInterval - Time (0.1 * MilliSeconds (UniformVariable ().GetInteger (0, 10)))); + if (!m_htimer.IsRunning ()) + { + m_htimer.Cancel (); + m_htimer.Schedule (HelloInterval - Time (0.1 * MilliSeconds (UniformVariable ().GetInteger (0, 10)))); + } } } @@ -1412,19 +1418,14 @@ RoutingProtocol::RecvError (Ptr p, Ipv4Address src ) std::pair un; while (rerrHeader.RemoveUnDestination (un)) { - if (m_nb.IsNeighbor (un.first)) - SendRerrWhenBreaksLinkToNextHop (un.first); - else - { - for (std::map::const_iterator i = - dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i) - { - if (i->first == un.first) - { - unreachable.insert (un); - } - } - } + for (std::map::const_iterator i = + dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i) + { + if (i->first == un.first) + { + unreachable.insert (un); + } + } } std::vector precursors; diff --git a/src/aodv/test/aodv-chain-regression-test-0-0.pcap b/src/aodv/test/aodv-chain-regression-test-0-0.pcap index a586ee47f..92a39f6a0 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-0-0.pcap and b/src/aodv/test/aodv-chain-regression-test-0-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-1-0.pcap b/src/aodv/test/aodv-chain-regression-test-1-0.pcap index e3290531a..45b546c1b 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-1-0.pcap and b/src/aodv/test/aodv-chain-regression-test-1-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-2-0.pcap b/src/aodv/test/aodv-chain-regression-test-2-0.pcap index 61591279c..b3ce3fec6 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-2-0.pcap and b/src/aodv/test/aodv-chain-regression-test-2-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-3-0.pcap b/src/aodv/test/aodv-chain-regression-test-3-0.pcap index 5ce41e6ed..676b85896 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-3-0.pcap and b/src/aodv/test/aodv-chain-regression-test-3-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-4-0.pcap b/src/aodv/test/aodv-chain-regression-test-4-0.pcap index dd300867f..80c00b16c 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-4-0.pcap and b/src/aodv/test/aodv-chain-regression-test-4-0.pcap differ diff --git a/src/aodv/test/bug-606-test-0-0.pcap b/src/aodv/test/bug-606-test-0-0.pcap index 00dba9e4f..f4f5a2134 100644 Binary files a/src/aodv/test/bug-606-test-0-0.pcap and b/src/aodv/test/bug-606-test-0-0.pcap differ diff --git a/src/aodv/test/bug-606-test-1-0.pcap b/src/aodv/test/bug-606-test-1-0.pcap index bad346549..f993b1802 100644 Binary files a/src/aodv/test/bug-606-test-1-0.pcap and b/src/aodv/test/bug-606-test-1-0.pcap differ diff --git a/src/aodv/test/bug-606-test-2-0.pcap b/src/aodv/test/bug-606-test-2-0.pcap index 979511752..0febfead8 100644 Binary files a/src/aodv/test/bug-606-test-2-0.pcap and b/src/aodv/test/bug-606-test-2-0.pcap differ diff --git a/src/aodv/test/tcp-chain-test-0-0.pcap b/src/aodv/test/tcp-chain-test-0-0.pcap index b6a27c094..5f7f29c01 100644 Binary files a/src/aodv/test/tcp-chain-test-0-0.pcap and b/src/aodv/test/tcp-chain-test-0-0.pcap differ diff --git a/src/aodv/test/tcp-chain-test-9-0.pcap b/src/aodv/test/tcp-chain-test-9-0.pcap index 0f756630e..f2a57ed28 100644 Binary files a/src/aodv/test/tcp-chain-test-9-0.pcap and b/src/aodv/test/tcp-chain-test-9-0.pcap differ diff --git a/src/aodv/test/udp-chain-test-0-0.pcap b/src/aodv/test/udp-chain-test-0-0.pcap index 6f3653eca..1a33a064c 100644 Binary files a/src/aodv/test/udp-chain-test-0-0.pcap and b/src/aodv/test/udp-chain-test-0-0.pcap differ diff --git a/src/aodv/test/udp-chain-test-9-0.pcap b/src/aodv/test/udp-chain-test-9-0.pcap index a906b5aec..e19f89047 100644 Binary files a/src/aodv/test/udp-chain-test-9-0.pcap and b/src/aodv/test/udp-chain-test-9-0.pcap differ diff --git a/src/click/examples/nsclick-udp-client-server-wifi.cc b/src/click/examples/nsclick-udp-client-server-wifi.cc index e83388d6d..d4029f0b5 100644 --- a/src/click/examples/nsclick-udp-client-server-wifi.cc +++ b/src/click/examples/nsclick-udp-client-server-wifi.cc @@ -17,17 +17,23 @@ // Adaptation of examples/udp/udp-client-server.cc for // Click based nodes running wifi. // -// Network topology +// Network topology: +// +// (1.4) +// (( n4 )) // // 172.16.1.0/24 +// // (1.1) (1.2) (1.3) // n0 )) (( n1 )) (( n2 // WLAN // -// - UDP flows from n0 to n1 +// - UDP flows from n0 to n1 and n2 to n1. // - All nodes are Click based. // - The single ethernet interface that each node // uses is named 'eth0' in the Click file. +// - Node 4 is running in promiscuous mode and can listen in on +// the packets being exchanged between n0-n1 and n2-n1. // #include @@ -59,16 +65,6 @@ WriteArp (Ptr clickRouter) // Access the handler NS_LOG_INFO (clickRouter->WriteHandler ("wifi/arpquerier", "insert", "172.16.1.2 00:00:00:00:00:02")); } - -void SetPromisc (Ptr clickRouter) -{ - // 4th node can listen to traffic in promisc mode - // Note: Promiscuous mode support for Click has - // been added ahead of the official Wifi support - // for promiscuous mode. Thus, the below line will - // not work until then. - clickRouter->SetPromiscuous ("eth0"); -} #endif int @@ -142,7 +138,14 @@ main (int argc, char *argv[]) // Install Click on the nodes // ClickInternetStackHelper clickinternet; - clickinternet.SetClickFile (n, "src/click/examples/nsclick-wifi-single-interface.click"); + clickinternet.SetClickFile (n.Get (0), "src/click/examples/nsclick-wifi-single-interface.click"); + clickinternet.SetClickFile (n.Get (1), "src/click/examples/nsclick-wifi-single-interface.click"); + clickinternet.SetClickFile (n.Get (2), "src/click/examples/nsclick-wifi-single-interface.click"); + + // Node 4 is to run in promiscuous mode. This can be verified + // from the pcap trace Node4_in_eth0.pcap generated after running + // this script. + clickinternet.SetClickFile (n.Get (3), "src/click/examples/nsclick-wifi-single-interface-promisc.click"); clickinternet.SetRoutingTableElement (n, "rt"); clickinternet.Install (n); Ipv4AddressHelper ipv4; @@ -180,9 +183,6 @@ main (int argc, char *argv[]) wifiPhy.EnablePcap ("nsclick-udp-client-server-wifi", d); - // Call SetPromiscuous mode on Click Router for node 4 - Simulator::Schedule (Seconds (0.1), &SetPromisc, n.Get (3)->GetObject ()); - // Force the MAC address of the second node: The current ARP // implementation of Click sends only one ARP request per incoming // packet for an unknown destination and does not retransmit if no diff --git a/src/click/examples/nsclick-wifi-single-interface-promisc.click b/src/click/examples/nsclick-wifi-single-interface-promisc.click new file mode 100644 index 000000000..b0360878d --- /dev/null +++ b/src/click/examples/nsclick-wifi-single-interface-promisc.click @@ -0,0 +1,114 @@ +// nsclick-wifi-single-interface.click +// +// Copyright (c) 2011, Deutsche Telekom Laboratories +// +// 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: Ruben Merz +// +// This is a single host Click configuration for wifi. +// Sets the interface in promiscuous mode +// The node broadcasts ARP requests if it wants to find a destination +// address, and it responds to ARP requests made for it. + +elementclass WiFiSimHost { + $ipaddr, $hwaddr | + + cl::Classifier(12/0806 20/0001,12/0806 20/0002, -); + forhost::IPClassifier(dst host $ipaddr,-); + arpquerier::ARPQuerier(eth0); + arpresponder::ARPResponder(eth0); + + ethout::Queue + -> ToDump(out_eth0.pcap,PER_NODE 1) + -> ToSimDevice(eth0); + + // All packets received on eth0 are silently + // dropped if they are destined for another location + FromSimDevice(eth0,SNAPLEN 4096,PROMISC true) + -> ToDump(in_eth0.pcap,PER_NODE 1,ENCAP ETHER) + -> cl; + + // ARP queries from other nodes go to the ARP responder element + cl[0] -> arpresponder; + + // ARP responses go to our ARP query element + cl[1] -> [1]arpquerier; + + // All other packets get checked whether they are meant for us + cl[2] + -> Strip (14) + -> CheckIPHeader2 + -> MarkIPHeader + -> GetIPAddress(16) // Sets destination IP address annotation from packet data + -> forhost; + + // Packets for us are pushed outside + forhost[0] + ->[0]output; + + // Packets for other folks or broadcast packets get sent to output 1 + forhost[1] + -> ToDump(discard.pcap,2000,PER_NODE 1,ENCAP IP) + -> [1]output; + + // Incoming packets get pushed into the ARP query module + input[0] + -> arpquerier; + + // Both the ARP query and response modules send data out to + // the simulated network device, eth0. + arpquerier + -> ToDump(out_arpquery.pcap,PER_NODE 1) + -> ethout; + + arpresponder + -> ToDump(out_arprespond.pcap,PER_NODE 1) + -> ethout; + +} + +elementclass TapSimHost { + $dev | + + // Packets go to "tap0" which sends them to the kernel + input[0] + -> ToDump(tokernel.pcap,2000,IP,PER_NODE 1) + -> ToSimDevice($dev,IP); + + // Packets sent out by the "kernel" get pushed outside + FromSimDevice($dev,SNAPLEN 4096) + -> CheckIPHeader2 + -> ToDump(fromkernel.pcap,2000,IP,PER_NODE 1) + -> GetIPAddress(16) + -> [0]output; +} + +// Instantiate elements +wifi::WiFiSimHost(eth0:ip,eth0:eth); +kernel::TapSimHost(tap0); + +// Users can do some processing between the two elements +wifi[0] -> kernel; +kernel -> wifi; +// Packets not for us are discarded +wifi[1] -> Discard; + +// It is mandatory to use an IPRouteTable element with ns-3-click +// (but we do not use it in this example) +rt :: LinearIPLookup (172.16.1.0/24 0.0.0.0 1); +// We are actually not using the routing table +Idle () -> rt; +rt[0] -> Discard; +rt[1] -> Discard; diff --git a/src/click/model/ipv4-click-routing.cc b/src/click/model/ipv4-click-routing.cc index 3f05043fc..235a7e8ff 100644 --- a/src/click/model/ipv4-click-routing.cc +++ b/src/click/model/ipv4-click-routing.cc @@ -388,14 +388,11 @@ Ipv4ClickRouting::WriteHandler (std::string elementName, std::string handlerName } void -Ipv4ClickRouting::SetPromiscuous (std::string ifName) +Ipv4ClickRouting::SetPromisc (int ifid) { Ptr ipv4l3 = DynamicCast (m_ipv4); - NS_ASSERT (ipv4l3); - // Interface ethN gets index 1+N, but netdevice will start at 0 - // To ensure this, install a Click stack on a node only after - // all NetDevices have been installed. - ipv4l3->SetPromisc (GetInterfaceId (ifName.c_str ()) - 1); + NS_ASSERT(ipv4l3); + ipv4l3->SetPromisc (ifid); } Ptr @@ -628,6 +625,16 @@ int simclick_sim_command (simclick_node_t *simnode, int cmd, ...) break; } + case SIMCLICK_IF_PROMISC: + { + int ifid = va_arg(val, int); + clickInstance->SetPromisc (ifid); + + retval = 0; + NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_PROMISC: " << ifid << " " << ns3::Simulator::Now ()); + break; + } + case SIMCLICK_IF_READY: { int ifid = va_arg (val, int); // Commented out so that optimized build works diff --git a/src/click/model/ipv4-click-routing.h b/src/click/model/ipv4-click-routing.h index c2ea3125a..75ccce184 100644 --- a/src/click/model/ipv4-click-routing.h +++ b/src/click/model/ipv4-click-routing.h @@ -108,7 +108,8 @@ public: * * \brief Sets an interface to run on promiscuous mode. */ - void SetPromiscuous (std::string ifName); + void SetPromisc (int ifid); + private: simclick_node_t *m_simNode; diff --git a/src/click/model/ipv4-l3-click-protocol.cc b/src/click/model/ipv4-l3-click-protocol.cc index 5b0f19d37..dd975dd44 100644 --- a/src/click/model/ipv4-l3-click-protocol.cc +++ b/src/click/model/ipv4-l3-click-protocol.cc @@ -574,35 +574,22 @@ Ipv4L3ClickProtocol::SetForwarding (uint32_t i, bool val) void Ipv4L3ClickProtocol::SetPromisc (uint32_t i) { - NS_ASSERT (i <= m_node->GetNDevices ()); - if (i > m_promiscDeviceList.size ()) - { - m_promiscDeviceList.resize (i); - } - std::vector::iterator it = m_promiscDeviceList.begin (); - std::advance (it, i); - m_promiscDeviceList.insert (it, true); + NS_ASSERT(i <= m_node->GetNDevices ()); + Ptr netdev = GetNetDevice (i); + NS_ASSERT (netdev); + Ptr node = GetObject (); + NS_ASSERT (node); + node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this), + 0, netdev,true); } uint32_t Ipv4L3ClickProtocol::AddInterface (Ptr device) { NS_LOG_FUNCTION (this << &device); - Ptr node = GetObject (); - NS_LOG_DEBUG ("Size:" << m_promiscDeviceList.size () << " Interface index" << device->GetIfIndex ()); - if (m_promiscDeviceList.size () > 0 - && (m_promiscDeviceList.size () >= device->GetIfIndex ()) - && (m_promiscDeviceList[device->GetIfIndex ()])) - { - node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this), - 0, device,true); - } - else - { - node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this), - Ipv4L3ClickProtocol::PROT_NUMBER, device); - } + node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this), + Ipv4L3ClickProtocol::PROT_NUMBER, device); node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this), ArpL3Protocol::PROT_NUMBER, device); diff --git a/src/spectrum/examples/adhoc-aloha-ideal-phy-matrix-propagation-loss-model.cc b/src/spectrum/examples/adhoc-aloha-ideal-phy-matrix-propagation-loss-model.cc new file mode 100644 index 000000000..44f143db3 --- /dev/null +++ b/src/spectrum/examples/adhoc-aloha-ideal-phy-matrix-propagation-loss-model.cc @@ -0,0 +1,151 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2010 CTTC + * + * 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: Nicola Baldo + */ + + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NS_LOG_COMPONENT_DEFINE ("TestAdhocOfdmAloha"); + +using namespace ns3; + +static bool g_verbose = false; +static uint64_t g_rxBytes; + +void +PhyRxEndOkTrace (std::string context, Ptr p) +{ + if (g_verbose) + { + std::cout << context << " PHY RX END OK p:" << p << std::endl; + } + g_rxBytes += p->GetSize (); +} + + +int main (int argc, char** argv) +{ + CommandLine cmd; + double lossDb; + double txPowerW = 0.1; + uint64_t phyRate = 500000; + uint32_t pktSize = 1000; + cmd.AddValue ("verbose", "Print trace information if true", g_verbose); + cmd.AddValue ("lossDb", "link loss in dB", lossDb); + cmd.AddValue ("txPowerW", "txPower in Watts", txPowerW); + cmd.AddValue ("phyRate", "PHY rate in bps", phyRate); + cmd.AddValue ("pktSize", "packet size in bytes", pktSize); + cmd.Parse (argc, argv); + + NodeContainer c; + c.Create (2); + + MobilityHelper mobility; + Ptr positionAlloc = CreateObject (); + positionAlloc->Add (Vector (0.0, 0.0, 0.0)); + positionAlloc->Add (Vector (5.0, 0.0, 0.0)); + mobility.SetPositionAllocator (positionAlloc); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + + + mobility.Install (c); + + + SpectrumChannelHelper channelHelper; + channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel"); + channelHelper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); + Ptr propLoss = CreateObject (); + propLoss->SetLoss (c.Get (0)->GetObject (), c.Get (1)->GetObject (), lossDb, true); + channelHelper.AddPropagationLoss (propLoss); + Ptr channel = channelHelper.Create (); + + + WifiSpectrumValue5MhzFactory sf; + + uint32_t channelNumber = 1; + Ptr txPsd = sf.CreateTxPowerSpectralDensity (txPowerW, channelNumber); + + // for the noise, we use the Power Spectral Density of thermal noise + // at room temperature. The value of the PSD will be constant over the band of interest. + const double k = 1.381e-23; //Boltzmann's constant + const double T = 290; // temperature in Kelvin + double noisePsdValue = k * T; // watts per hertz + Ptr noisePsd = sf.CreateConstant (noisePsdValue); + + AdhocAlohaNoackIdealPhyHelper deviceHelper; + deviceHelper.SetChannel (channel); + deviceHelper.SetTxPowerSpectralDensity (txPsd); + deviceHelper.SetNoisePowerSpectralDensity (noisePsd); + deviceHelper.SetPhyAttribute ("Rate", DataRateValue (DataRate (phyRate))); + NetDeviceContainer devices = deviceHelper.Install (c); + + PacketSocketHelper packetSocket; + packetSocket.Install (c); + + PacketSocketAddress socket; + socket.SetSingleDevice (devices.Get (0)->GetIfIndex ()); + socket.SetPhysicalAddress (devices.Get (1)->GetAddress ()); + socket.SetProtocol (1); + + OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket)); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (2*phyRate))); + onoff.SetAttribute ("PacketSize", UintegerValue (pktSize)); + + ApplicationContainer apps = onoff.Install (c.Get (0)); + apps.Start (Seconds (0.0)); + apps.Stop (Seconds (10.0)); + + Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndOk", MakeCallback (&PhyRxEndOkTrace)); + + g_rxBytes = 0; + Simulator::Stop (Seconds (10.0001)); + Simulator::Run (); + double throughputBps = (g_rxBytes * 8.0) / 10.0; + + std::cerr << "throughput: " << std::setw (20) << std::fixed << throughputBps << " bps" << std::endl; + std::cerr << "phy rate : " << std::setw (20) << std::fixed << phyRate*1.0 << " bps" << std::endl; + double rxPowerW = txPowerW / (pow (10.0, lossDb/10.0)); + double capacity = 20e6*log2 (1.0 + (rxPowerW/20.0e6)/noisePsdValue); + std::cerr << "shannon capacity: " << std::setw (20) << std::fixed << capacity << " bps" << std::endl; + + + Simulator::Destroy (); + return 0; +} diff --git a/src/spectrum/examples/wscript b/src/spectrum/examples/wscript index 3b369eb0e..27deedb91 100644 --- a/src/spectrum/examples/wscript +++ b/src/spectrum/examples/wscript @@ -5,6 +5,10 @@ def build(bld): ['spectrum', 'mobility']) obj.source = 'adhoc-aloha-ideal-phy.cc' + obj = bld.create_ns3_program('adhoc-aloha-ideal-phy-matrix-propagation-loss-model', + ['spectrum', 'mobility']) + obj.source = 'adhoc-aloha-ideal-phy-matrix-propagation-loss-model.cc' + obj = bld.create_ns3_program('adhoc-aloha-ideal-phy-with-microwave-oven', ['spectrum', 'mobility']) obj.source = 'adhoc-aloha-ideal-phy-with-microwave-oven.cc' diff --git a/src/spectrum/helper/spectrum-helper.cc b/src/spectrum/helper/spectrum-helper.cc index 7c3714558..53f9fff67 100644 --- a/src/spectrum/helper/spectrum-helper.cc +++ b/src/spectrum/helper/spectrum-helper.cc @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include #include #include @@ -66,6 +64,38 @@ SpectrumChannelHelper::SetChannel (std::string type, m_channel.Set (n7, v7); } +void +SpectrumChannelHelper::AddPropagationLoss (std::string type, + std::string n0, const AttributeValue &v0, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7) +{ + ObjectFactory factory; + factory.SetTypeId (type); + factory.Set (n0, v0); + factory.Set (n1, v1); + factory.Set (n2, v2); + factory.Set (n3, v3); + factory.Set (n4, v4); + factory.Set (n5, v5); + factory.Set (n6, v6); + factory.Set (n7, v7); + Ptr m = factory.Create (); + AddPropagationLoss (m); +} + + +void +SpectrumChannelHelper::AddPropagationLoss (Ptr m) +{ + m->SetNext (m_propagationLossModel); + m_propagationLossModel = m; +} void SpectrumChannelHelper::AddSpectrumPropagationLoss (std::string type, @@ -88,7 +118,15 @@ SpectrumChannelHelper::AddSpectrumPropagationLoss (std::string type, factory.Set (n5, v5); factory.Set (n6, v6); factory.Set (n7, v7); - m_spectrumPropagationLoss.push_back (factory); + Ptr m = factory.Create (); + AddSpectrumPropagationLoss (m); +} + +void +SpectrumChannelHelper::AddSpectrumPropagationLoss (Ptr m) +{ + m->SetNext (m_spectrumPropagationLossModel); + m_spectrumPropagationLossModel = m; } void @@ -119,30 +157,14 @@ Ptr SpectrumChannelHelper::Create (void) const { Ptr channel = (m_channel.Create ())->GetObject (); - Ptr prev = 0; - for (std::vector::const_iterator i = m_spectrumPropagationLoss.begin (); i != m_spectrumPropagationLoss.end (); ++i) - { - Ptr cur = (*i).Create (); - if (prev == 0) - { - channel->AddSpectrumPropagationLossModel (cur); - } - else - { - prev->SetNext (cur); - } - prev = cur; - } + channel->AddSpectrumPropagationLossModel (m_spectrumPropagationLossModel); + channel->AddPropagationLossModel (m_propagationLossModel); Ptr delay = m_propagationDelay.Create (); channel->SetPropagationDelayModel (delay); return channel; } - - - - void SpectrumPhyHelper::SetPhy (std::string type, std::string n0, const AttributeValue &v0, diff --git a/src/spectrum/helper/spectrum-helper.h b/src/spectrum/helper/spectrum-helper.h index f2cdf344d..41dc68ea5 100644 --- a/src/spectrum/helper/spectrum-helper.h +++ b/src/spectrum/helper/spectrum-helper.h @@ -26,6 +26,8 @@ #include #include #include +#include +#include namespace ns3 { @@ -72,6 +74,44 @@ public: std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + /** + * \param name the name of the model to set + * \param n0 the name of the attribute to set + * \param v0 the value of the attribute to set + * \param n1 the name of the attribute to set + * \param v1 the value of the attribute to set + * \param n2 the name of the attribute to set + * \param v2 the value of the attribute to set + * \param n3 the name of the attribute to set + * \param v3 the value of the attribute to set + * \param n4 the name of the attribute to set + * \param v4 the value of the attribute to set + * \param n5 the name of the attribute to set + * \param v5 the value of the attribute to set + * \param n6 the name of the attribute to set + * \param v6 the value of the attribute to set + * \param n7 the name of the attribute to set + * \param v7 the value of the attribute to set + * + * Add a new single-frequency propagation loss model to this channel helper. + */ + void AddPropagationLoss (std::string name, + std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + + + /** + * Add a new single-frequency propagation loss model instance to this channel helper. + * + * \param m a pointer to the instance of the propagation loss model + */ + void AddPropagationLoss (Ptr m); /** * \param name the name of the model to set @@ -92,7 +132,7 @@ public: * \param n7 the name of the attribute to set * \param v7 the value of the attribute to set * - * Add a new spectrum propagation loss to this channel helper. + * Add a new frequency-dependent propagation loss model to this channel helper. */ void AddSpectrumPropagationLoss (std::string name, std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), @@ -103,6 +143,14 @@ public: std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + + /** + * Add a new frequency-dependent propagation loss model instance to this channel helper. + * + * \param m a pointer to the instance of the propagation loss model + */ + void AddSpectrumPropagationLoss (Ptr m); + /** * \param name the name of the model to set * \param n0 the name of the attribute to set @@ -142,7 +190,8 @@ public: Ptr Create (void) const; private: - std::vector m_spectrumPropagationLoss; + Ptr m_spectrumPropagationLossModel; + Ptr m_propagationLossModel; ObjectFactory m_propagationDelay; ObjectFactory m_channel; }; diff --git a/src/spectrum/model/aloha-noack-net-device.cc b/src/spectrum/model/aloha-noack-net-device.cc index fec88a508..c7ecbcc28 100644 --- a/src/spectrum/model/aloha-noack-net-device.cc +++ b/src/spectrum/model/aloha-noack-net-device.cc @@ -346,7 +346,7 @@ AlohaNoackNetDevice::SendFrom (Ptr packet, const Address& src, const Add m_macTxTrace (packet); - + bool sendOk = true; // // If the device is idle, transmission starts immediately. Otherwise, // the transmission will be started by NotifyTransmissionEnd @@ -366,12 +366,8 @@ AlohaNoackNetDevice::SendFrom (Ptr packet, const Address& src, const Add if (m_queue->Enqueue (packet) == false) { m_macTxDropTrace (packet); - return false; + sendOk = false; } - NS_LOG_LOGIC ("transmitting head-of-queue packet"); - m_currentPkt = m_queue->Dequeue (); - NS_ASSERT (m_currentPkt != 0); - StartTransmission (); } } else @@ -381,10 +377,10 @@ AlohaNoackNetDevice::SendFrom (Ptr packet, const Address& src, const Add if (m_queue->Enqueue (packet) == false) { m_macTxDropTrace (packet); - return false; + sendOk = false; } } - return true; + return sendOk; } void @@ -425,6 +421,7 @@ AlohaNoackNetDevice::NotifyTransmissionEnd (Ptr) { m_currentPkt = m_queue->Dequeue (); NS_ASSERT (m_currentPkt); + NS_LOG_LOGIC ("scheduling transmission now"); Simulator::ScheduleNow (&AlohaNoackNetDevice::StartTransmission, this); } } diff --git a/src/spectrum/model/multi-model-spectrum-channel.cc b/src/spectrum/model/multi-model-spectrum-channel.cc index cd6a4cf49..5bddf80b5 100644 --- a/src/spectrum/model/multi-model-spectrum-channel.cc +++ b/src/spectrum/model/multi-model-spectrum-channel.cc @@ -25,9 +25,13 @@ #include #include #include +#include #include #include #include +#include +#include +#include #include #include #include "multi-model-spectrum-channel.h" @@ -72,8 +76,6 @@ RxSpectrumModelInfo::RxSpectrumModelInfo (Ptr rxSpectrumMod MultiModelSpectrumChannel::MultiModelSpectrumChannel () - : m_PropagationDelay (0), - m_PropagationLoss (0) { NS_LOG_FUNCTION (this); } @@ -82,8 +84,9 @@ void MultiModelSpectrumChannel::DoDispose () { NS_LOG_FUNCTION (this); - m_PropagationLoss = 0; - m_PropagationDelay = 0; + m_propagationDelay = 0; + m_propagationLoss = 0; + m_spectrumPropagationLoss = 0; m_txSpectrumModelInfoMap.clear (); m_rxSpectrumModelInfoMap.clear (); m_phyVector.clear (); @@ -96,6 +99,18 @@ MultiModelSpectrumChannel::GetTypeId (void) static TypeId tid = TypeId ("ns3::MultiModelSpectrumChannel") .SetParent () .AddConstructor () + .AddAttribute ("MaxLossDb", + "If a single-frequency PropagationLossModel is used, this value " + "represents the maximum loss in dB for which transmissions will be " + "passed to the receiving PHY. Signals for which the PropagationLossModel " + "returns a loss bigger than this value will not be propagated to the receiver. " + "This parameter is to be used to reduce " + "the computational load by not propagating signals that are far beyond " + "the interference range. Note that the default value corresponds to " + "considering all signals for reception. Tune this value with care. ", + DoubleValue (1.0e9), + MakeDoubleAccessor (&MultiModelSpectrumChannel::m_maxLossDb), + MakeDoubleChecker ()) ; return tid; } @@ -241,45 +256,44 @@ MultiModelSpectrumChannel::StartTx (Ptr p, Ptr orig convertedTxPowerSpectrum = rxConverterIterator->second.Convert (originalTxPowerSpectrum); } - std::list >::const_iterator rxPhyIterator = rxInfoIterator->second.m_rxPhyList.begin (); - while (rxPhyIterator != rxInfoIterator->second.m_rxPhyList.end ()) + for (std::list >::const_iterator rxPhyIterator = rxInfoIterator->second.m_rxPhyList.begin (); + rxPhyIterator != rxInfoIterator->second.m_rxPhyList.end (); + ++rxPhyIterator) { NS_ASSERT_MSG ((*rxPhyIterator)->GetRxSpectrumModel ()->GetUid () == rxSpectrumModelUid, "MultiModelSpectrumChannel only supports devices that use a single RxSpectrumModel that does not change for the whole simulation"); if ((*rxPhyIterator) != txPhy) { - Ptr rxPowerSpectrum; - Time delay; + Ptr rxPowerSpectrum = convertedTxPowerSpectrum->Copy (); + Time delay = MicroSeconds (0); + Ptr receiverMobility = (*rxPhyIterator)->GetMobility ()->GetObject (); if (txMobility && receiverMobility) { - if (m_PropagationLoss) + if (m_propagationLoss) { - rxPowerSpectrum = m_PropagationLoss->CalcRxPowerSpectralDensity (convertedTxPowerSpectrum, txMobility, receiverMobility); - } - else - { - // rxPowerSpectrum = Copy (convertedTxPowerSpectrum); - rxPowerSpectrum = convertedTxPowerSpectrum->Copy (); + double gainDb = m_propagationLoss->CalcRxPower (0, txMobility, receiverMobility); + if ( (-gainDb) > m_maxLossDb) + { + // beyond range + continue; + } + double gainLinear = pow (10.0, gainDb/10.0); + *rxPowerSpectrum = (*rxPowerSpectrum) * gainLinear; } - if (m_PropagationDelay) + if (m_spectrumPropagationLoss) { - delay = m_PropagationDelay->GetDelay (txMobility, receiverMobility); + rxPowerSpectrum = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity (rxPowerSpectrum, txMobility, receiverMobility); } - else + + if (m_propagationDelay) { - delay = MicroSeconds (0); + delay = m_propagationDelay->GetDelay (txMobility, receiverMobility); } } - else - { - // rxPowerSpectrum = Copy (convertedTxPowerSpectrum); - rxPowerSpectrum = convertedTxPowerSpectrum->Copy (); - delay = MicroSeconds (0); - } Ptr pktBurstCopy = p->Copy (); Ptr netDevObj = (*rxPhyIterator)->GetDevice (); @@ -297,7 +311,6 @@ MultiModelSpectrumChannel::StartTx (Ptr p, Ptr orig pktBurstCopy, rxPowerSpectrum, st, duration, *rxPhyIterator); } } - ++rxPhyIterator; } } @@ -329,25 +342,33 @@ MultiModelSpectrumChannel::GetDevice (uint32_t i) const +void +MultiModelSpectrumChannel::AddPropagationLossModel (Ptr loss) +{ + NS_LOG_FUNCTION (this << loss); + NS_ASSERT (m_propagationLoss == 0); + m_propagationLoss = loss; +} + void MultiModelSpectrumChannel::AddSpectrumPropagationLossModel (Ptr loss) { - NS_ASSERT (m_PropagationLoss == 0); - m_PropagationLoss = loss; + NS_ASSERT (m_propagationLoss == 0); + m_spectrumPropagationLoss = loss; } void MultiModelSpectrumChannel::SetPropagationDelayModel (Ptr delay) { - NS_ASSERT (m_PropagationDelay == 0); - m_PropagationDelay = delay; + NS_ASSERT (m_propagationDelay == 0); + m_propagationDelay = delay; } Ptr MultiModelSpectrumChannel::GetSpectrumPropagationLossModel (void) { NS_LOG_FUNCTION (this); - return m_PropagationLoss; + return m_spectrumPropagationLoss; } diff --git a/src/spectrum/model/multi-model-spectrum-channel.h b/src/spectrum/model/multi-model-spectrum-channel.h index 0f5f12e81..2720353d2 100644 --- a/src/spectrum/model/multi-model-spectrum-channel.h +++ b/src/spectrum/model/multi-model-spectrum-channel.h @@ -88,6 +88,7 @@ public: static TypeId GetTypeId (void); // inherited from SpectrumChannel + virtual void AddPropagationLossModel (Ptr loss); virtual void AddSpectrumPropagationLossModel (Ptr loss); virtual void SetPropagationDelayModel (Ptr delay); virtual void AddRx (Ptr phy); @@ -147,15 +148,19 @@ private: * propagation delay model to be used with this channel * */ - Ptr m_PropagationDelay; - + Ptr m_propagationDelay; /** - * propagation loss model to be used with this channel + * single-frequency propagation loss model to be used with this channel + * + */ + Ptr m_propagationLoss; + + /** + * frequency-dependent propagation loss model to be used with this channel * */ - Ptr m_PropagationLoss; - + Ptr m_spectrumPropagationLoss; /** @@ -180,6 +185,9 @@ private: * */ std::vector > m_phyVector; + + + double m_maxLossDb; }; diff --git a/src/spectrum/model/single-model-spectrum-channel.cc b/src/spectrum/model/single-model-spectrum-channel.cc index 025dd8051..9426296e8 100644 --- a/src/spectrum/model/single-model-spectrum-channel.cc +++ b/src/spectrum/model/single-model-spectrum-channel.cc @@ -25,8 +25,14 @@ #include #include #include +#include #include #include +#include +#include +#include + + #include "single-model-spectrum-channel.h" @@ -39,9 +45,6 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (SingleModelSpectrumChannel); SingleModelSpectrumChannel::SingleModelSpectrumChannel () - : m_spectrumModel (0), - m_PropagationDelay (0), - m_PropagationLoss (0) { NS_LOG_FUNCTION (this); } @@ -52,8 +55,9 @@ SingleModelSpectrumChannel::DoDispose () NS_LOG_FUNCTION (this); m_phyList.clear (); m_spectrumModel = 0; - m_PropagationDelay = 0; - m_PropagationLoss = 0; + m_propagationDelay = 0; + m_propagationLoss = 0; + m_spectrumPropagationLoss = 0; SpectrumChannel::DoDispose (); } @@ -64,6 +68,18 @@ SingleModelSpectrumChannel::GetTypeId (void) static TypeId tid = TypeId ("ns3::SingleModelSpectrumChannel") .SetParent () .AddConstructor () + .AddAttribute ("MaxLossDb", + "If a single-frequency PropagationLossModel is used, this value " + "represents the maximum loss in dB for which transmissions will be " + "passed to the receiving PHY. Signals for which the PropagationLossModel " + "returns a loss bigger than this value will not be propagated to the receiver. " + "This parameter is to be used to reduce " + "the computational load by not propagating signals that are far beyond " + "the interference range. Note that the default value corresponds to " + "considering all signals for reception. Tune this value with care. ", + DoubleValue (1.0e9), + MakeDoubleAccessor (&SingleModelSpectrumChannel::m_maxLossDb), + MakeDoubleChecker ()) ; return tid; } @@ -98,47 +114,45 @@ SingleModelSpectrumChannel::StartTx (Ptr p, Ptr txP } - PhyList::const_iterator rxPhyIterator = m_phyList.begin (); + Ptr senderMobility = txPhy->GetMobility ()->GetObject (); - NS_ASSERT (rxPhyIterator != m_phyList.end ()); - - while (rxPhyIterator != m_phyList.end ()) + for (PhyList::const_iterator rxPhyIterator = m_phyList.begin (); + rxPhyIterator != m_phyList.end (); + ++rxPhyIterator) { if ((*rxPhyIterator) != txPhy) { - Ptr rxPsd; - Time delay; + Ptr rxPsd = Copy (txPsd); + Time delay = MicroSeconds (0); + Ptr receiverMobility = (*rxPhyIterator)->GetMobility ()->GetObject (); if (senderMobility && receiverMobility) { - - - if (m_PropagationLoss) + if (m_propagationLoss) { - rxPsd = m_PropagationLoss->CalcRxPowerSpectralDensity (txPsd, senderMobility, receiverMobility); - } - else - { - rxPsd = txPsd; + double gainDb = m_propagationLoss->CalcRxPower (0, senderMobility, receiverMobility); + if ( (-gainDb) > m_maxLossDb) + { + // beyond range + continue; + } + double gainLinear = pow (10.0, gainDb/10.0); + *rxPsd = (*rxPsd) * gainLinear; } - if (m_PropagationDelay) + if (m_spectrumPropagationLoss) { - delay = m_PropagationDelay->GetDelay (senderMobility, receiverMobility); + rxPsd = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity (rxPsd, senderMobility, receiverMobility); } - else + + if (m_propagationDelay) { - delay = MicroSeconds (0); + delay = m_propagationDelay->GetDelay (senderMobility, receiverMobility); } } - else - { - rxPsd = txPsd; - delay = MicroSeconds (0); - } Ptr pktBurstCopy = p->Copy (); Ptr netDevObj = (*rxPhyIterator)->GetDevice (); @@ -156,7 +170,6 @@ SingleModelSpectrumChannel::StartTx (Ptr p, Ptr txP pktBurstCopy, rxPsd, st, duration, *rxPhyIterator); } } - ++rxPhyIterator; } } @@ -186,21 +199,29 @@ SingleModelSpectrumChannel::GetDevice (uint32_t i) const } +void +SingleModelSpectrumChannel::AddPropagationLossModel (Ptr loss) +{ + NS_LOG_FUNCTION (this << loss); + NS_ASSERT (m_propagationLoss == 0); + m_propagationLoss = loss; +} + void SingleModelSpectrumChannel::AddSpectrumPropagationLossModel (Ptr loss) { NS_LOG_FUNCTION (this << loss); - NS_ASSERT (m_PropagationLoss == 0); - m_PropagationLoss = loss; + NS_ASSERT (m_propagationLoss == 0); + m_spectrumPropagationLoss = loss; } void SingleModelSpectrumChannel::SetPropagationDelayModel (Ptr delay) { NS_LOG_FUNCTION (this << delay); - NS_ASSERT (m_PropagationDelay == 0); - m_PropagationDelay = delay; + NS_ASSERT (m_propagationDelay == 0); + m_propagationDelay = delay; } @@ -208,7 +229,7 @@ Ptr SingleModelSpectrumChannel::GetSpectrumPropagationLossModel (void) { NS_LOG_FUNCTION (this); - return m_PropagationLoss; + return m_spectrumPropagationLoss; } diff --git a/src/spectrum/model/single-model-spectrum-channel.h b/src/spectrum/model/single-model-spectrum-channel.h index 25be58dc5..a3fb15010 100644 --- a/src/spectrum/model/single-model-spectrum-channel.h +++ b/src/spectrum/model/single-model-spectrum-channel.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +//* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2009 CTTC * @@ -23,8 +23,6 @@ #include -#include -#include namespace ns3 { @@ -47,6 +45,7 @@ public: // inherited from SpectrumChannel + virtual void AddPropagationLossModel (Ptr loss); virtual void AddSpectrumPropagationLossModel (Ptr loss); virtual void SetPropagationDelayModel (Ptr delay); virtual void AddRx (Ptr phy); @@ -97,15 +96,23 @@ private: * propagation delay model to be used with this channel * */ - Ptr m_PropagationDelay; + Ptr m_propagationDelay; /** - * propagation loss model to be used with this channel + * single-frequency propagation loss model to be used with this channel + * + */ + Ptr m_propagationLoss; + + /** + * frequency-dependent propagation loss model to be used with this channel * */ - Ptr m_PropagationLoss; + Ptr m_spectrumPropagationLoss; + + double m_maxLossDb; }; diff --git a/src/spectrum/model/spectrum-channel.h b/src/spectrum/model/spectrum-channel.h index 247f65a26..91850130a 100644 --- a/src/spectrum/model/spectrum-channel.h +++ b/src/spectrum/model/spectrum-channel.h @@ -34,6 +34,7 @@ class PacketBurst; class SpectrumValue; class SpectrumPhy; class SpectrumPropagationLossModel; +class PropagationLossModel; class PropagationDelayModel; /** @@ -50,8 +51,16 @@ public: /** - * set the propagation loss model to be used - * \param loss Ptr to the propagation loss model to be used. + * set the single-frequency propagation loss model to be used + * \warning only models that do not depend on the TX power should be used. + * + * \param loss a pointer to the propagation loss model to be used. + */ + virtual void AddPropagationLossModel (Ptr loss) = 0; + + /** + * set the frequency-dependent propagation loss model to be used + * \param loss a pointer to the propagation loss model to be used. */ virtual void AddSpectrumPropagationLossModel (Ptr loss) = 0; diff --git a/src/spectrum/test/examples-to-run.py b/src/spectrum/test/examples-to-run.py index 2f92d6588..879354120 100644 --- a/src/spectrum/test/examples-to-run.py +++ b/src/spectrum/test/examples-to-run.py @@ -10,6 +10,7 @@ cpp_examples = [ ("adhoc-aloha-ideal-phy", "True", "True"), ("adhoc-aloha-ideal-phy-with-microwave-oven", "True", "True"), + ("adhoc-aloha-ideal-phy-matrix-propagation-loss-model", "True", "True"), ] # A list of Python examples to run in order to ensure that they remain diff --git a/src/spectrum/test/spectrum-ideal-phy-test.cc b/src/spectrum/test/spectrum-ideal-phy-test.cc new file mode 100644 index 000000000..8f01bb838 --- /dev/null +++ b/src/spectrum/test/spectrum-ideal-phy-test.cc @@ -0,0 +1,245 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 CTTC + * + * 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: Nicola Baldo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NS_LOG_COMPONENT_DEFINE ("SpectrumIdealPhyTest"); + +namespace ns3 { + + +static uint64_t g_rxBytes; +static double g_bandwidth = 20e6; // Hz + +void +PhyRxEndOkTrace (std::string context, Ptr p) +{ + g_rxBytes += p->GetSize (); +} + + +class SpectrumIdealPhyTestCase : public TestCase +{ +public: + SpectrumIdealPhyTestCase (double snrLinear, + uint64_t phyRate, + bool rateIsAchievable, + std::string channelType); + virtual ~SpectrumIdealPhyTestCase (); + +private: + virtual void DoRun (void); + + double m_snrLinear; + uint64_t m_phyRate; + bool m_rateIsAchievable; + std::string m_channelType; +}; + + + + +SpectrumIdealPhyTestCase::SpectrumIdealPhyTestCase (double snrLinear, + uint64_t phyRate, + bool rateIsAchievable, + std::string channelType) + : TestCase (""), + m_snrLinear (snrLinear), + m_phyRate (phyRate), + m_rateIsAchievable (rateIsAchievable), + m_channelType (channelType) +{ + std::ostringstream oss; + oss << channelType + << " snr = " << snrLinear << " (linear), " + << " phyRate = " << phyRate << " bps"; + SetName (oss.str ()); +} + +SpectrumIdealPhyTestCase::~SpectrumIdealPhyTestCase () +{ +} + + +void +SpectrumIdealPhyTestCase::DoRun (void) +{ + NS_LOG_FUNCTION (m_snrLinear << m_phyRate); + double txPowerW = 0.1; + // for the noise, we use the Power Spectral Density of thermal noise + // at room temperature. The value of the PSD will be constant over the band of interest. + const double k = 1.381e-23; //Boltzmann's constant + const double T = 290; // temperature in Kelvin + double noisePsdValue = k * T; // W/Hz + double lossLinear = (txPowerW) / (m_snrLinear * noisePsdValue * g_bandwidth); + double lossDb = 10 * log10 (lossLinear); + uint64_t phyRate = m_phyRate; // bps + uint32_t pktSize = 50; // bytes + + uint32_t numPkts = 200; //desired number of packets in the + //test. Directly related with the accuracy + //of the measurement. + + double testDuration = (numPkts * pktSize * 8.0) / phyRate; + NS_LOG_INFO ("test duration = " << std::fixed << testDuration); + + NodeContainer c; + c.Create (2); + + MobilityHelper mobility; + Ptr positionAlloc = CreateObject (); + positionAlloc->Add (Vector (0.0, 0.0, 0.0)); + positionAlloc->Add (Vector (5.0, 0.0, 0.0)); + mobility.SetPositionAllocator (positionAlloc); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + + + mobility.Install (c); + + + SpectrumChannelHelper channelHelper; + channelHelper.SetChannel (m_channelType); + channelHelper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); + Ptr propLoss = CreateObject (); + propLoss->SetLoss (c.Get(0)->GetObject (), c.Get(1)->GetObject (), lossDb, true); + channelHelper.AddPropagationLoss (propLoss); + Ptr channel = channelHelper.Create (); + + + WifiSpectrumValue5MhzFactory sf; + + uint32_t channelNumber = 1; + Ptr txPsd = sf.CreateTxPowerSpectralDensity (txPowerW, channelNumber); + + Ptr noisePsd = sf.CreateConstant (noisePsdValue); + + AdhocAlohaNoackIdealPhyHelper deviceHelper; + deviceHelper.SetChannel (channel); + deviceHelper.SetTxPowerSpectralDensity (txPsd); + deviceHelper.SetNoisePowerSpectralDensity (noisePsd); + deviceHelper.SetPhyAttribute ("Rate", DataRateValue (DataRate (phyRate))); + NetDeviceContainer devices = deviceHelper.Install (c); + + PacketSocketHelper packetSocket; + packetSocket.Install (c); + + PacketSocketAddress socket; + socket.SetSingleDevice (devices.Get (0)->GetIfIndex ()); + socket.SetPhysicalAddress (devices.Get (1)->GetAddress ()); + socket.SetProtocol (1); + + OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket)); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (1.2*phyRate))); + onoff.SetAttribute ("PacketSize", UintegerValue (pktSize)); + + ApplicationContainer apps = onoff.Install (c.Get (0)); + apps.Start (Seconds (0.0)); + apps.Stop (Seconds (testDuration)); + + Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxEndOk", MakeCallback (&PhyRxEndOkTrace)); + + g_rxBytes = 0; + Simulator::Stop (Seconds (testDuration+0.000000001)); + Simulator::Run (); + double throughputBps = (g_rxBytes * 8.0) / testDuration; + + if (m_rateIsAchievable) + { + NS_TEST_ASSERT_MSG_EQ_TOL (throughputBps, m_phyRate, m_phyRate*0.01, "throughput does not match PHY rate"); + } + else + { + NS_TEST_ASSERT_MSG_EQ (throughputBps, 0.0, "PHY rate is not achievable but throughput is non-zero"); + } + + Simulator::Destroy (); +} + + + + +class SpectrumIdealPhyTestSuite : public TestSuite +{ +public: + SpectrumIdealPhyTestSuite (); +}; + +SpectrumIdealPhyTestSuite::SpectrumIdealPhyTestSuite () + : TestSuite ("spectrum-ideal-phy", SYSTEM) +{ + + NS_LOG_INFO ("creating SpectrumIdealPhyTestSuite"); + + for (double snr = 0.01; snr <= 10 ; snr *= 2) + { + double achievableRate = g_bandwidth*log2(1+snr); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.1, true, "ns3::SingleModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.5, true, "ns3::SingleModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.95, true, "ns3::SingleModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*1.05, false, "ns3::SingleModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*2, false, "ns3::SingleModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*4, false, "ns3::SingleModelSpectrumChannel")); + } + for (double snr = 0.01; snr <= 10 ; snr *= 10) + { + double achievableRate = g_bandwidth*log2(1+snr); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.1, true, "ns3::MultiModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.5, true, "ns3::MultiModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*0.95, true, "ns3::MultiModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*1.05, false, "ns3::MultiModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*2, false, "ns3::MultiModelSpectrumChannel")); + AddTestCase (new SpectrumIdealPhyTestCase (snr, achievableRate*4, false, "ns3::MultiModelSpectrumChannel")); + } +} + +static SpectrumIdealPhyTestSuite g_spectrumIdealPhyTestSuite; + +} // namespace ns3 diff --git a/src/spectrum/wscript b/src/spectrum/wscript index 6f88b8d26..1ab4383c1 100644 --- a/src/spectrum/wscript +++ b/src/spectrum/wscript @@ -37,6 +37,7 @@ def build(bld): module_test.source = [ 'test/spectrum-interference-test.cc', 'test/spectrum-value-test.cc', + 'test/spectrum-ideal-phy-test.cc', ] headers = bld.new_task_gen('ns3header') diff --git a/src/wifi/bindings/modulegen__gcc_ILP32.py b/src/wifi/bindings/modulegen__gcc_ILP32.py index 2ca7aa4f7..7a48328f9 100644 --- a/src/wifi/bindings/modulegen__gcc_ILP32.py +++ b/src/wifi/bindings/modulegen__gcc_ILP32.py @@ -163,7 +163,7 @@ def register_types(module): ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount [class] module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Object', 'ns3::ObjectBase', 'ns3::ObjectDeleter'], parent=root_module['ns3::ObjectBase'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## simulator.h (module 'core'): ns3::Simulator [class] - module.add_class('Simulator', is_singleton=True, import_from_module='ns.core') + module.add_class('Simulator', destructor_visibility='private', import_from_module='ns.core') ## status-code.h (module 'wifi'): ns3::StatusCode [class] module.add_class('StatusCode') ## tag.h (module 'network'): ns3::Tag [class] @@ -326,6 +326,8 @@ def register_types(module): module.add_enum('QosAckPolicy', ['NORMAL_ACK', 'NO_ACK', 'NO_EXPLICIT_ACK', 'BLOCK_ACK'], outer_class=root_module['ns3::WifiMacHeader']) ## wifi-mac-header.h (module 'wifi'): ns3::WifiMacHeader::AddressType [enumeration] module.add_enum('AddressType', ['ADDR1', 'ADDR2', 'ADDR3', 'ADDR4'], outer_class=root_module['ns3::WifiMacHeader']) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue [class] + module.add_class('WifiMacQueue', parent=root_module['ns3::Object']) ## wifi-phy.h (module 'wifi'): ns3::WifiPhy [class] module.add_class('WifiPhy', parent=root_module['ns3::Object']) ## wifi-phy.h (module 'wifi'): ns3::WifiPhy::State [enumeration] @@ -644,6 +646,7 @@ def register_methods(root_module): register_Ns3WifiInformationElementVector_methods(root_module, root_module['ns3::WifiInformationElementVector']) register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac']) register_Ns3WifiMacHeader_methods(root_module, root_module['ns3::WifiMacHeader']) + register_Ns3WifiMacQueue_methods(root_module, root_module['ns3::WifiMacQueue']) register_Ns3WifiPhy_methods(root_module, root_module['ns3::WifiPhy']) register_Ns3WifiRemoteStationManager_methods(root_module, root_module['ns3::WifiRemoteStationManager']) register_Ns3YansWifiPhy_methods(root_module, root_module['ns3::YansWifiPhy']) @@ -4084,8 +4087,8 @@ def register_Ns3Empty_methods(root_module, cls): return def register_Ns3Int64x64_t_methods(root_module, cls): - cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', 'right')) + cls.add_binary_comparison_operator('!=') cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long long unsigned int const', 'right')) cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long unsigned int const', 'right')) cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('unsigned int const', 'right')) @@ -5225,8 +5228,8 @@ def register_Ns3SimpleRefCount__Ns3WifiInformationElement_Ns3Empty_Ns3DefaultDel return def register_Ns3Time_methods(root_module, cls): - cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', 'right')) + cls.add_binary_comparison_operator('!=') cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right')) cls.add_binary_numeric_operator('-', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right')) cls.add_binary_comparison_operator('<') @@ -5765,6 +5768,11 @@ def register_Ns3WifiMac_methods(root_module, cls): 'void', [param('ns3::Time', 'pifs')], is_pure_virtual=True, is_virtual=True) + ## wifi-mac.h (module 'wifi'): void ns3::WifiMac::SetPromisc() [member function] + cls.add_method('SetPromisc', + 'void', + [], + is_pure_virtual=True, is_virtual=True) ## wifi-mac.h (module 'wifi'): void ns3::WifiMac::SetSifs(ns3::Time sifs) [member function] cls.add_method('SetSifs', 'void', @@ -6231,6 +6239,88 @@ def register_Ns3WifiMacHeader_methods(root_module, cls): []) return +def register_Ns3WifiMacQueue_methods(root_module, cls): + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue(ns3::WifiMacQueue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::WifiMacQueue const &', 'arg0')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue() [constructor] + cls.add_constructor([]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue(ns3::WifiMacHeader * hdr) [member function] + cls.add_method('Dequeue', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTidAndAddress(ns3::WifiMacHeader * hdr, uint8_t tid, ns3::WifiMacHeader::AddressType type, ns3::Mac48Address addr) [member function] + cls.add_method('DequeueByTidAndAddress', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('uint8_t', 'tid'), param('ns3::WifiMacHeader::AddressType', 'type'), param('ns3::Mac48Address', 'addr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::WifiMacHeader * hdr, ns3::Time & tStamp, ns3::QosBlockedDestinations const * blockedPackets) [member function] + cls.add_method('DequeueFirstAvailable', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('ns3::Time &', 'tStamp'), param('ns3::QosBlockedDestinations const *', 'blockedPackets')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::Enqueue(ns3::Ptr packet, ns3::WifiMacHeader const & hdr) [member function] + cls.add_method('Enqueue', + 'void', + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::Flush() [member function] + cls.add_method('Flush', + 'void', + []) + ## wifi-mac-queue.h (module 'wifi'): ns3::Time ns3::WifiMacQueue::GetMaxDelay() const [member function] + cls.add_method('GetMaxDelay', + 'ns3::Time', + [], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetMaxSize() const [member function] + cls.add_method('GetMaxSize', + 'uint32_t', + [], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetNPacketsByTidAndAddress(uint8_t tid, ns3::WifiMacHeader::AddressType type, ns3::Mac48Address addr) [member function] + cls.add_method('GetNPacketsByTidAndAddress', + 'uint32_t', + [param('uint8_t', 'tid'), param('ns3::WifiMacHeader::AddressType', 'type'), param('ns3::Mac48Address', 'addr')]) + ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetSize() [member function] + cls.add_method('GetSize', + 'uint32_t', + []) + ## wifi-mac-queue.h (module 'wifi'): static ns3::TypeId ns3::WifiMacQueue::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::IsEmpty() [member function] + cls.add_method('IsEmpty', + 'bool', + []) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Peek(ns3::WifiMacHeader * hdr) [member function] + cls.add_method('Peek', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekByTidAndAddress(ns3::WifiMacHeader * hdr, uint8_t tid, ns3::WifiMacHeader::AddressType type, ns3::Mac48Address addr) [member function] + cls.add_method('PeekByTidAndAddress', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('uint8_t', 'tid'), param('ns3::WifiMacHeader::AddressType', 'type'), param('ns3::Mac48Address', 'addr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekFirstAvailable(ns3::WifiMacHeader * hdr, ns3::Time & tStamp, ns3::QosBlockedDestinations const * blockedPackets) [member function] + cls.add_method('PeekFirstAvailable', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('ns3::Time &', 'tStamp'), param('ns3::QosBlockedDestinations const *', 'blockedPackets')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::PushFront(ns3::Ptr packet, ns3::WifiMacHeader const & hdr) [member function] + cls.add_method('PushFront', + 'void', + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::Remove(ns3::Ptr packet) [member function] + cls.add_method('Remove', + 'bool', + [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::SetMaxDelay(ns3::Time delay) [member function] + cls.add_method('SetMaxDelay', + 'void', + [param('ns3::Time', 'delay')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::SetMaxSize(uint32_t maxSize) [member function] + cls.add_method('SetMaxSize', + 'void', + [param('uint32_t', 'maxSize')]) + return + def register_Ns3WifiPhy_methods(root_module, cls): ## wifi-phy.h (module 'wifi'): ns3::WifiPhy::WifiPhy(ns3::WifiPhy const & arg0) [copy constructor] cls.add_constructor([param('ns3::WifiPhy const &', 'arg0')]) @@ -6536,12 +6626,12 @@ def register_Ns3WifiPhy_methods(root_module, cls): 'bool', [], is_pure_virtual=True, is_virtual=True) - ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyPromiscSniffRx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) [member function] - cls.add_method('NotifyPromiscSniffRx', + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyMonitorSniffRx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) [member function] + cls.add_method('NotifyMonitorSniffRx', 'void', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint16_t', 'channelNumber'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('double', 'signalDbm'), param('double', 'noiseDbm')]) - ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyPromiscSniffTx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble) [member function] - cls.add_method('NotifyPromiscSniffTx', + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyMonitorSniffTx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble) [member function] + cls.add_method('NotifyMonitorSniffTx', 'void', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint16_t', 'channelNumber'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble')]) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyRxBegin(ns3::Ptr packet) [member function] @@ -8829,6 +8919,10 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('SetPifs', 'void', [param('ns3::Time', 'pifs')]) + ## mac-low.h (module 'wifi'): void ns3::MacLow::SetPromisc() [member function] + cls.add_method('SetPromisc', + 'void', + []) ## mac-low.h (module 'wifi'): void ns3::MacLow::SetRxCallback(ns3::Callback, ns3::WifiMacHeader const*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function] cls.add_method('SetRxCallback', 'void', @@ -9669,6 +9763,11 @@ def register_Ns3RegularWifiMac_methods(root_module, cls): 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## regular-wifi-mac.h (module 'wifi'): void ns3::RegularWifiMac::SetPromisc() [member function] + cls.add_method('SetPromisc', + 'void', + [], + is_virtual=True) ## regular-wifi-mac.h (module 'wifi'): void ns3::RegularWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function] cls.add_method('Enqueue', 'void', diff --git a/src/wifi/bindings/modulegen__gcc_LP64.py b/src/wifi/bindings/modulegen__gcc_LP64.py index 2ca7aa4f7..7a48328f9 100644 --- a/src/wifi/bindings/modulegen__gcc_LP64.py +++ b/src/wifi/bindings/modulegen__gcc_LP64.py @@ -163,7 +163,7 @@ def register_types(module): ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount [class] module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Object', 'ns3::ObjectBase', 'ns3::ObjectDeleter'], parent=root_module['ns3::ObjectBase'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## simulator.h (module 'core'): ns3::Simulator [class] - module.add_class('Simulator', is_singleton=True, import_from_module='ns.core') + module.add_class('Simulator', destructor_visibility='private', import_from_module='ns.core') ## status-code.h (module 'wifi'): ns3::StatusCode [class] module.add_class('StatusCode') ## tag.h (module 'network'): ns3::Tag [class] @@ -326,6 +326,8 @@ def register_types(module): module.add_enum('QosAckPolicy', ['NORMAL_ACK', 'NO_ACK', 'NO_EXPLICIT_ACK', 'BLOCK_ACK'], outer_class=root_module['ns3::WifiMacHeader']) ## wifi-mac-header.h (module 'wifi'): ns3::WifiMacHeader::AddressType [enumeration] module.add_enum('AddressType', ['ADDR1', 'ADDR2', 'ADDR3', 'ADDR4'], outer_class=root_module['ns3::WifiMacHeader']) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue [class] + module.add_class('WifiMacQueue', parent=root_module['ns3::Object']) ## wifi-phy.h (module 'wifi'): ns3::WifiPhy [class] module.add_class('WifiPhy', parent=root_module['ns3::Object']) ## wifi-phy.h (module 'wifi'): ns3::WifiPhy::State [enumeration] @@ -644,6 +646,7 @@ def register_methods(root_module): register_Ns3WifiInformationElementVector_methods(root_module, root_module['ns3::WifiInformationElementVector']) register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac']) register_Ns3WifiMacHeader_methods(root_module, root_module['ns3::WifiMacHeader']) + register_Ns3WifiMacQueue_methods(root_module, root_module['ns3::WifiMacQueue']) register_Ns3WifiPhy_methods(root_module, root_module['ns3::WifiPhy']) register_Ns3WifiRemoteStationManager_methods(root_module, root_module['ns3::WifiRemoteStationManager']) register_Ns3YansWifiPhy_methods(root_module, root_module['ns3::YansWifiPhy']) @@ -4084,8 +4087,8 @@ def register_Ns3Empty_methods(root_module, cls): return def register_Ns3Int64x64_t_methods(root_module, cls): - cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', 'right')) + cls.add_binary_comparison_operator('!=') cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long long unsigned int const', 'right')) cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long unsigned int const', 'right')) cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('unsigned int const', 'right')) @@ -5225,8 +5228,8 @@ def register_Ns3SimpleRefCount__Ns3WifiInformationElement_Ns3Empty_Ns3DefaultDel return def register_Ns3Time_methods(root_module, cls): - cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', 'right')) + cls.add_binary_comparison_operator('!=') cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right')) cls.add_binary_numeric_operator('-', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right')) cls.add_binary_comparison_operator('<') @@ -5765,6 +5768,11 @@ def register_Ns3WifiMac_methods(root_module, cls): 'void', [param('ns3::Time', 'pifs')], is_pure_virtual=True, is_virtual=True) + ## wifi-mac.h (module 'wifi'): void ns3::WifiMac::SetPromisc() [member function] + cls.add_method('SetPromisc', + 'void', + [], + is_pure_virtual=True, is_virtual=True) ## wifi-mac.h (module 'wifi'): void ns3::WifiMac::SetSifs(ns3::Time sifs) [member function] cls.add_method('SetSifs', 'void', @@ -6231,6 +6239,88 @@ def register_Ns3WifiMacHeader_methods(root_module, cls): []) return +def register_Ns3WifiMacQueue_methods(root_module, cls): + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue(ns3::WifiMacQueue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::WifiMacQueue const &', 'arg0')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue() [constructor] + cls.add_constructor([]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue(ns3::WifiMacHeader * hdr) [member function] + cls.add_method('Dequeue', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTidAndAddress(ns3::WifiMacHeader * hdr, uint8_t tid, ns3::WifiMacHeader::AddressType type, ns3::Mac48Address addr) [member function] + cls.add_method('DequeueByTidAndAddress', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('uint8_t', 'tid'), param('ns3::WifiMacHeader::AddressType', 'type'), param('ns3::Mac48Address', 'addr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::WifiMacHeader * hdr, ns3::Time & tStamp, ns3::QosBlockedDestinations const * blockedPackets) [member function] + cls.add_method('DequeueFirstAvailable', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('ns3::Time &', 'tStamp'), param('ns3::QosBlockedDestinations const *', 'blockedPackets')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::Enqueue(ns3::Ptr packet, ns3::WifiMacHeader const & hdr) [member function] + cls.add_method('Enqueue', + 'void', + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::Flush() [member function] + cls.add_method('Flush', + 'void', + []) + ## wifi-mac-queue.h (module 'wifi'): ns3::Time ns3::WifiMacQueue::GetMaxDelay() const [member function] + cls.add_method('GetMaxDelay', + 'ns3::Time', + [], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetMaxSize() const [member function] + cls.add_method('GetMaxSize', + 'uint32_t', + [], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetNPacketsByTidAndAddress(uint8_t tid, ns3::WifiMacHeader::AddressType type, ns3::Mac48Address addr) [member function] + cls.add_method('GetNPacketsByTidAndAddress', + 'uint32_t', + [param('uint8_t', 'tid'), param('ns3::WifiMacHeader::AddressType', 'type'), param('ns3::Mac48Address', 'addr')]) + ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetSize() [member function] + cls.add_method('GetSize', + 'uint32_t', + []) + ## wifi-mac-queue.h (module 'wifi'): static ns3::TypeId ns3::WifiMacQueue::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::IsEmpty() [member function] + cls.add_method('IsEmpty', + 'bool', + []) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Peek(ns3::WifiMacHeader * hdr) [member function] + cls.add_method('Peek', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekByTidAndAddress(ns3::WifiMacHeader * hdr, uint8_t tid, ns3::WifiMacHeader::AddressType type, ns3::Mac48Address addr) [member function] + cls.add_method('PeekByTidAndAddress', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('uint8_t', 'tid'), param('ns3::WifiMacHeader::AddressType', 'type'), param('ns3::Mac48Address', 'addr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekFirstAvailable(ns3::WifiMacHeader * hdr, ns3::Time & tStamp, ns3::QosBlockedDestinations const * blockedPackets) [member function] + cls.add_method('PeekFirstAvailable', + 'ns3::Ptr< ns3::Packet const >', + [param('ns3::WifiMacHeader *', 'hdr'), param('ns3::Time &', 'tStamp'), param('ns3::QosBlockedDestinations const *', 'blockedPackets')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::PushFront(ns3::Ptr packet, ns3::WifiMacHeader const & hdr) [member function] + cls.add_method('PushFront', + 'void', + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')]) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::Remove(ns3::Ptr packet) [member function] + cls.add_method('Remove', + 'bool', + [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::SetMaxDelay(ns3::Time delay) [member function] + cls.add_method('SetMaxDelay', + 'void', + [param('ns3::Time', 'delay')]) + ## wifi-mac-queue.h (module 'wifi'): void ns3::WifiMacQueue::SetMaxSize(uint32_t maxSize) [member function] + cls.add_method('SetMaxSize', + 'void', + [param('uint32_t', 'maxSize')]) + return + def register_Ns3WifiPhy_methods(root_module, cls): ## wifi-phy.h (module 'wifi'): ns3::WifiPhy::WifiPhy(ns3::WifiPhy const & arg0) [copy constructor] cls.add_constructor([param('ns3::WifiPhy const &', 'arg0')]) @@ -6536,12 +6626,12 @@ def register_Ns3WifiPhy_methods(root_module, cls): 'bool', [], is_pure_virtual=True, is_virtual=True) - ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyPromiscSniffRx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) [member function] - cls.add_method('NotifyPromiscSniffRx', + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyMonitorSniffRx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) [member function] + cls.add_method('NotifyMonitorSniffRx', 'void', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint16_t', 'channelNumber'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('double', 'signalDbm'), param('double', 'noiseDbm')]) - ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyPromiscSniffTx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble) [member function] - cls.add_method('NotifyPromiscSniffTx', + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyMonitorSniffTx(ns3::Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble) [member function] + cls.add_method('NotifyMonitorSniffTx', 'void', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint16_t', 'channelNumber'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble')]) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyRxBegin(ns3::Ptr packet) [member function] @@ -8829,6 +8919,10 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('SetPifs', 'void', [param('ns3::Time', 'pifs')]) + ## mac-low.h (module 'wifi'): void ns3::MacLow::SetPromisc() [member function] + cls.add_method('SetPromisc', + 'void', + []) ## mac-low.h (module 'wifi'): void ns3::MacLow::SetRxCallback(ns3::Callback, ns3::WifiMacHeader const*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function] cls.add_method('SetRxCallback', 'void', @@ -9669,6 +9763,11 @@ def register_Ns3RegularWifiMac_methods(root_module, cls): 'ns3::Mac48Address', [], is_const=True, is_virtual=True) + ## regular-wifi-mac.h (module 'wifi'): void ns3::RegularWifiMac::SetPromisc() [member function] + cls.add_method('SetPromisc', + 'void', + [], + is_virtual=True) ## regular-wifi-mac.h (module 'wifi'): void ns3::RegularWifiMac::Enqueue(ns3::Ptr packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function] cls.add_method('Enqueue', 'void', diff --git a/src/wifi/doc/wifi.rst b/src/wifi/doc/wifi.rst index bf8748737..8f882222b 100644 --- a/src/wifi/doc/wifi.rst +++ b/src/wifi/doc/wifi.rst @@ -318,7 +318,7 @@ SNIR function. *SNIR function over time.* -From the SNIR function we can derive the Bit Error Rate (BER) and Packet Error Rate (PER) for the modulation and coding scheme being used for the transmission. Please refer to [pei80211validation]_ and [lacage2006yans]_ for a detailed description of the available BER/PER models. +From the SNIR function we can derive the Bit Error Rate (BER) and Packet Error Rate (PER) for the modulation and coding scheme being used for the transmission. Please refer to [pei80211ofdm]_, [pei80211b]_ and [lacage2006yans]_ for a detailed description of the available BER/PER models. WifiChannel configuration @@ -365,7 +365,9 @@ References .. [ieee80211] IEEE Std 802.11-2007 *Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications* -.. [pei80211validation] \G. Pei and Tom Henderson, `Validation of ns-3 802.11b PHY model* `__ +.. [pei80211b] \G. Pei and Tom Henderson, `Validation of ns-3 802.11b PHY model `__ + +.. [pei80211ofdm] \G. Pei and Tom Henderson, `Validation of OFDM error rate model in ns-3 `__ .. [lacage2006yans] \M. Lacage and T. Henderson, `Yet another Network Simulator `__ diff --git a/src/wifi/test/wifi-phy-test.cc b/src/wifi/examples/wifi-phy-test.cc similarity index 100% rename from src/wifi/test/wifi-phy-test.cc rename to src/wifi/examples/wifi-phy-test.cc diff --git a/src/wifi/examples/wscript b/src/wifi/examples/wscript new file mode 100644 index 000000000..0e42f7c52 --- /dev/null +++ b/src/wifi/examples/wscript @@ -0,0 +1,9 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + if not bld.env['ENABLE_EXAMPLES']: + return; + + obj = bld.create_ns3_program('wifi-phy-test', + ['core', 'mobility', 'network', 'wifi']) + obj.source = 'wifi-phy-test.cc' diff --git a/src/wifi/helper/yans-wifi-helper.cc b/src/wifi/helper/yans-wifi-helper.cc index 6905d52de..8a817fbf7 100644 --- a/src/wifi/helper/yans-wifi-helper.cc +++ b/src/wifi/helper/yans-wifi-helper.cc @@ -444,8 +444,8 @@ YansWifiPhyHelper::EnablePcapInternal (std::string prefix, Ptr nd, bo Ptr file = pcapHelper.CreateFile (filename, std::ios::out, m_pcapDlt); - phy->TraceConnectWithoutContext ("PromiscSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file)); - phy->TraceConnectWithoutContext ("PromiscSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file)); + phy->TraceConnectWithoutContext ("MonitorSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file)); + phy->TraceConnectWithoutContext ("MonitorSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file)); } void diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc index b934895ed..2f8e9c115 100644 --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -366,6 +366,7 @@ MacLow::MacLow () NS_LOG_FUNCTION (this); m_lastNavDuration = Seconds (0); m_lastNavStart = Seconds (0); + m_promisc = false; } MacLow::~MacLow () @@ -522,6 +523,11 @@ MacLow::SetBssid (Mac48Address bssid) { m_bssid = bssid; } +void +MacLow::SetPromisc (void) +{ + m_promisc = true; +} Mac48Address MacLow::GetAddress (void) const { @@ -893,6 +899,14 @@ MacLow::ReceiveOk (Ptr packet, double rxSnr, WifiMode txMode, WifiPreamb // DROP } } + else if (m_promisc) + { + NS_ASSERT (hdr.GetAddr1 () != m_self); + if (hdr.IsData ()) + { + goto rxPacket; + } + } else { //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet)); diff --git a/src/wifi/model/mac-low.h b/src/wifi/model/mac-low.h index 9aaf9682b..75103761b 100644 --- a/src/wifi/model/mac-low.h +++ b/src/wifi/model/mac-low.h @@ -388,6 +388,7 @@ public: void SetSlotTime (Time slotTime); void SetPifs (Time pifs); void SetBssid (Mac48Address ad); + void SetPromisc (void); Mac48Address GetAddress (void) const; Time GetAckTimeout (void) const; Time GetBasicBlockAckTimeout () const; @@ -632,6 +633,8 @@ private: Time m_lastNavStart; Time m_lastNavDuration; + bool m_promisc; + // Listerner needed to monitor when a channel switching occurs. class PhyMacLowListener * m_phyMacLowListener; diff --git a/src/wifi/model/regular-wifi-mac.cc b/src/wifi/model/regular-wifi-mac.cc index 2ae2bf0b4..4ef8e463f 100644 --- a/src/wifi/model/regular-wifi-mac.cc +++ b/src/wifi/model/regular-wifi-mac.cc @@ -390,6 +390,12 @@ RegularWifiMac::GetBssid (void) const return m_low->GetBssid (); } +void +RegularWifiMac::SetPromisc (void) +{ + m_low->SetPromisc (); +} + void RegularWifiMac::Enqueue (Ptr packet, Mac48Address to, Mac48Address from) diff --git a/src/wifi/model/regular-wifi-mac.h b/src/wifi/model/regular-wifi-mac.h index 81b4323eb..93e50a564 100644 --- a/src/wifi/model/regular-wifi-mac.h +++ b/src/wifi/model/regular-wifi-mac.h @@ -130,6 +130,14 @@ public: * \returns the bssid of the network this device belongs to. */ virtual Mac48Address GetBssid (void) const; + /** + * \brief Sets the interface in promiscuous mode. + * + * Enables promiscuous mode on the interface. Note that any further + * filtering on the incoming frame path may affect the overall + * behavior. + */ + virtual void SetPromisc (void); /** * \param packet the packet to send. diff --git a/src/wifi/model/wifi-mac.h b/src/wifi/model/wifi-mac.h index 2a1b91ac0..a208abb4a 100644 --- a/src/wifi/model/wifi-mac.h +++ b/src/wifi/model/wifi-mac.h @@ -133,6 +133,14 @@ public: * \returns the bssid of the network this device belongs to. */ virtual Mac48Address GetBssid (void) const = 0; + /** + * \brief Sets the interface in promiscuous mode. + * + * Enables promiscuous mode on the interface. Note that any further + * filtering on the incoming frame path may affect the overall + * behavior. + */ + virtual void SetPromisc (void) = 0; /** * \param packet the packet to send. diff --git a/src/wifi/model/wifi-net-device.cc b/src/wifi/model/wifi-net-device.cc index 8accbbb09..6b654b14e 100644 --- a/src/wifi/model/wifi-net-device.cc +++ b/src/wifi/model/wifi-net-device.cc @@ -356,6 +356,7 @@ void WifiNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) { m_promiscRx = cb; + m_mac->SetPromisc(); } bool diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index db2c19814..8040ef791 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -74,12 +74,12 @@ WifiPhy::GetTypeId (void) .AddTraceSource ("PhyRxDrop", "Trace source indicating a packet has been dropped by the device during reception", MakeTraceSourceAccessor (&WifiPhy::m_phyRxDropTrace)) - .AddTraceSource ("PromiscSnifferRx", + .AddTraceSource ("MonitorSnifferRx", "Trace source simulating a wifi device in monitor mode sniffing all received frames", - MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSniffRxTrace)) - .AddTraceSource ("PromiscSnifferTx", + MakeTraceSourceAccessor (&WifiPhy::m_phyMonitorSniffRxTrace)) + .AddTraceSource ("MonitorSnifferTx", "Trace source simulating the capability of a wifi device in monitor mode to sniff all frames being transmitted", - MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSniffTxTrace)) + MakeTraceSourceAccessor (&WifiPhy::m_phyMonitorSniffTxTrace)) ; return tid; } @@ -338,15 +338,15 @@ WifiPhy::NotifyRxDrop (Ptr packet) } void -WifiPhy::NotifyPromiscSniffRx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) +WifiPhy::NotifyMonitorSniffRx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) { - m_phyPromiscSniffRxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble, signalDbm, noiseDbm); + m_phyMonitorSniffRxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble, signalDbm, noiseDbm); } void -WifiPhy::NotifyPromiscSniffTx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble) +WifiPhy::NotifyMonitorSniffTx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble) { - m_phyPromiscSniffTxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble); + m_phyMonitorSniffTxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble); } diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index 8763bfab9..b165faa54 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -415,7 +415,7 @@ public: /** * - * Public method used to fire a PromiscSniffer trace for a wifi packet being received. Implemented for encapsulation + * Public method used to fire a MonitorSniffer trace for a wifi packet being received. Implemented for encapsulation * purposes. * * @param packet the packet being received @@ -433,12 +433,12 @@ public: * @param signalDbm signal power in dBm * @param noiseDbm noise power in dBm */ - void NotifyPromiscSniffRx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, + void NotifyMonitorSniffRx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm); /** * - * Public method used to fire a PromiscSniffer trace for a wifi packet being transmitted. Implemented for encapsulation + * Public method used to fire a MonitorSniffer trace for a wifi packet being transmitted. Implemented for encapsulation * purposes. * * @param packet the packet being transmitted @@ -449,7 +449,7 @@ public: * units used both for the radiotap and for the prism header) * @param isShortPreamble true if short preamble is used, false otherwise */ - void NotifyPromiscSniffTx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble); + void NotifyMonitorSniffTx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble); private: @@ -510,7 +510,7 @@ private: * * \see class CallBackTraceSource */ - TracedCallback, uint16_t, uint16_t, uint32_t, bool, double, double> m_phyPromiscSniffRxTrace; + TracedCallback, uint16_t, uint16_t, uint32_t, bool, double, double> m_phyMonitorSniffRxTrace; /** * A trace source that emulates a wifi device in monitor mode @@ -522,7 +522,7 @@ private: * * \see class CallBackTraceSource */ - TracedCallback, uint16_t, uint16_t, uint32_t, bool> m_phyPromiscSniffTxTrace; + TracedCallback, uint16_t, uint16_t, uint32_t, bool> m_phyMonitorSniffTxTrace; }; diff --git a/src/wifi/model/yans-wifi-phy.cc b/src/wifi/model/yans-wifi-phy.cc index 5b38810e9..8465fd806 100644 --- a/src/wifi/model/yans-wifi-phy.cc +++ b/src/wifi/model/yans-wifi-phy.cc @@ -516,7 +516,7 @@ YansWifiPhy::SendPacket (Ptr packet, WifiMode txMode, WifiPreamble NotifyTxBegin (packet); uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000; bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble); - NotifyPromiscSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble); + NotifyMonitorSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble); m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower); m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble); } @@ -787,7 +787,7 @@ YansWifiPhy::EndReceive (Ptr packet, Ptr even bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ()); double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30; double noiseDbm = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30; - NotifyPromiscSniffRx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm); + NotifyMonitorSniffRx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm); m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ()); } else diff --git a/src/wifi/test/examples-to-run.py b/src/wifi/test/examples-to-run.py new file mode 100644 index 000000000..156deb8d6 --- /dev/null +++ b/src/wifi/test/examples-to-run.py @@ -0,0 +1,18 @@ +#! /usr/bin/env python +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +# A list of C++ examples to run in order to ensure that they remain +# buildable and runnable over time. Each tuple in the list contains +# +# (example_name, do_run, do_valgrind_run). +# +# See test.py for more information. +cpp_examples = [] + +# A list of Python examples to run in order to ensure that they remain +# runnable over time. Each tuple in the list contains +# +# (example_name, do_run). +# +# See test.py for more information. +python_examples = [] diff --git a/src/wifi/wscript b/src/wifi/wscript index 1c4963c44..0784c8ee2 100644 --- a/src/wifi/wscript +++ b/src/wifi/wscript @@ -143,9 +143,8 @@ def build(bld): obj.uselib = 'GSL GSLCBLAS M' obj_test.uselib = 'GSL GSLCBLAS M' - obj = bld.create_ns3_program('wifi-phy-test', - ['core', 'mobility', 'network', 'wifi']) - obj.source = 'test/wifi-phy-test.cc' + if (bld.env['ENABLE_EXAMPLES']): + bld.add_subdirs('examples') bld.ns3_python_bindings() diff --git a/src/wscript b/src/wscript index 5e646ab9e..220ebabca 100644 --- a/src/wscript +++ b/src/wscript @@ -103,52 +103,126 @@ def configure(conf): conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules] -def create_ns3_module(bld, name, dependencies=(), test=False): - # Create a separate library for this module. - if bld.env['ENABLE_STATIC_NS3']: - module = bld.new_task_gen('cxx', 'cstaticlib') - else: - module = bld.new_task_gen('cxx', 'cshlib') - if not test: - pcfile = bld.new_task_gen('ns3pcfile') - pcfile.module = module +class ns3module_taskgen(TaskGen.task_gen): + def __init__(self, *args, **kwargs): + super(ns3module_taskgen, self).__init__(*args, **kwargs) + self.libs = [] + def apply(self): + static_enabled = False + shared_enabled = True + bld = self.bld + if bld.env['ENABLE_STATIC_NS3']: + static_enabled = True + shared_enabled = False + if bld.env['ENABLE_SHARED_AND_STATIC_NS3']: + static_enabled = True + shared_enabled = True + + assert self.name.startswith("ns3-") + name = self.name.split("ns3-")[1] + + if static_enabled: + static = self._create_ns3_module(self.bld, name, self.dependencies, True) + self.libs.append(static) + else: + static = None + + if shared_enabled: + shared = self._create_ns3_module(self.bld, name, self.dependencies, False) + self.libs.append(shared) + else: + shared = None + + if static is not None and shared is None: + static.name = self.name + "--lib" + static.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies] + + elif shared is not None and static is None: + shared.name = self.name + "--lib" + shared.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies] + else: + shared.name = self.name + "--lib" + shared.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies] + static.name = self.name + "--static" + static.uselib_local = ['ns3-%s--static' % (dep,) for dep in self.dependencies] + + if not self.test: + pcfile = bld.new_task_gen('ns3pcfile') + pcfile.module = self + + + def _create_ns3_module(self, bld, name, dependencies, static): + + # FIXME: env modifications are overwritten by parent caller + + # Create a separate library for this module. + if static: + module = bld.new_task_gen('cxx', 'cstaticlib') + else: + module = bld.new_task_gen('cxx', 'cshlib') + + module.source = self.source + module.env = self.env.copy() + features = list(self.features) + features.remove("ns3module") + module.features.extend(features) + module.path = self.path + module.uselib = self.uselib + if hasattr(self, 'includes'): + module.includes = self.includes + if hasattr(self, "is_ns3_module"): + module.is_ns3_module = self.is_ns3_module + + module.is_static = static + module.vnum = wutils.VNUM + # Add the proper path to the module's name. + module.target = '%s/ns3-%s' % (bld.srcnode.relpath_gen(self.path), name) + # Set the libraries this module depends on. + module.module_deps = list(dependencies) + if not static: + module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) + module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS']) + # Turn on the link flags for shared libraries if we have the + # proper compiler and platform. + if module.env['CXX_NAME'] in ['gcc', 'icc'] and module.env['WL_SONAME_SUPPORTED']: + # Get the module library name without any relative paths + # at its beginning because all of the libraries will end + # up in the same directory. + module_library_name = os.path.basename(ccroot.get_target_name(module)) + module.env.append_value('LINKFLAGS', '-Wl,--soname=%s' % module_library_name) + elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \ + os.uname()[4] == 'x86_64' and \ + module.env['ENABLE_PYTHON_BINDINGS']: + # enable that flag for static builds only on x86-64 platforms + # when gcc is present and only when we want python bindings + # (it's more efficient to not use this option if we can avoid it) + module.env.append_value('CXXFLAGS', '-mcmodel=large') + module.env.append_value('CCFLAGS', '-mcmodel=large') + module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION") + module.env.append_value('CCDEFINES', "NS3_MODULE_COMPILATION") + + module.install_path = "${LIBDIR}" + + return module + + +def create_ns3_module(bld, name, dependencies=(), test=False): + module = bld.new_task_gen('ns3module') + module.bld = bld + module.name = "ns3-" + name + module.dependencies = dependencies # Initially create an empty value for this because the pcfile # writing task assumes every module has a uselib attribute. module.uselib = '' - - module.is_ns3_module = True - module.name = 'ns3-' + name - module.vnum = wutils.VNUM - # Add the proper path to the module's name. - module.target = '%s/ns3-%s' % (bld.srcnode.relpath_gen(bld.path), name) - # Set the libraries this module depends on. module.uselib_local = ['ns3-' + dep for dep in dependencies] module.module_deps = list(dependencies) - if not module.env['ENABLE_STATIC_NS3']: - module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) - module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS']) - # Turn on the link flags for shared libraries if we have the - # proper compiler and platform. - if module.env['CXX_NAME'] in ['gcc', 'icc'] and module.env['WL_SONAME_SUPPORTED']: - # Get the module library name without any relative paths - # at its beginning because all of the libraries will end - # up in the same directory. - module_library_name = os.path.basename(ccroot.get_target_name(module)) - module.env.append_value('LINKFLAGS', '-Wl,--soname=%s' % module_library_name) - elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \ - os.uname()[4] == 'x86_64' and \ - module.env['ENABLE_PYTHON_BINDINGS']: - # enable that flag for static builds only on x86-64 platforms - # when gcc is present and only when we want python bindings - # (it's more efficient to not use this option if we can avoid it) - module.env.append_value('CXXFLAGS', '-mcmodel=large') - module.env.append_value('CCFLAGS', '-mcmodel=large') - - module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION") - module.env.append_value('CCDEFINES', "NS3_MODULE_COMPILATION") + module.test = test + module.is_ns3_module = True + return module + def create_ns3_module_test_library(bld, name): # Create an ns3 module for the test library that depends only on # the module being tested. @@ -258,15 +332,17 @@ def ns3_python_bindings(bld): pymod.source = ['bindings/ns3module.cc'] pymod.target = '%s/%s' % (module_target_dir, extension_name) pymod.name = 'ns3module_%s' % module - pymod.uselib_local = pymod.env['NS3_ENABLED_MODULES'] # Should be '"ns3-"+module', but see bug 1117 + pymod.uselib_local = ["%s--lib" % mod for mod in pymod.env['NS3_ENABLED_MODULES']] # Should be '"ns3-"+module', but see bug 1117 if pymod.env['ENABLE_STATIC_NS3']: if sys.platform == 'darwin': pymod.env.append_value('LINKFLAGS', '-Wl,-all_load') for mod in pymod.uselib_local: + mod = mod.split("--lib")[0] pymod.env.append_value('LINKFLAGS', '-l' + mod) else: pymod.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic') for mod in pymod.uselib_local: + mod = mod.split("--lib")[0] pymod.env.append_value('LINKFLAGS', '-l' + mod) pymod.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive') defines = list(pymod.env['CXXDEFINES']) @@ -416,7 +492,6 @@ class ns3header_taskgen(TaskGen.task_gen): def apply(self): for filename in set(self.to_list(self.source)): src_node = self.path.find_resource(filename) - self.bld.install_files('${PREFIX}/include/ns3', [src_node]) if self.module is None: raise Utils.WafError("'module' missing on ns3headers object %s" % self) ns3_dir_node = self.bld.path.find_dir("ns3") @@ -431,6 +506,7 @@ class ns3header_taskgen(TaskGen.task_gen): task = self.create_task('ns3header', env=self.env) task.mode = self.mode if self.mode == 'install': + self.bld.install_files('${PREFIX}/include/ns3', [src_node]) task.set_inputs([src_node]) task.set_outputs([dst_node]) else: @@ -598,13 +674,13 @@ class ns3moduleheader_taskgen(TaskGen.task_gen): raise Utils.WscriptError("error finding headers for module %s" % self.module) if not all_headers_inputs: return - self.bld.install_files('${PREFIX}/include/ns3', - ns3_dir_node.find_or_declare("%s-module.h" % self.module)) all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)] task = self.create_task('gen_ns3_module_header', env=self.env) task.module = self.module task.mode = self.mode if self.mode == 'install': + self.bld.install_files('${PREFIX}/include/ns3', + ns3_dir_node.find_or_declare("%s-module.h" % self.module)) task.set_inputs(all_headers_inputs) task.set_outputs(all_headers_outputs) module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env) diff --git a/utils/wscript b/utils/wscript index f97874c72..ade5ef6e6 100644 --- a/utils/wscript +++ b/utils/wscript @@ -10,7 +10,7 @@ def build(bld): # Set the libraries the testrunner depends on equal to the list of # enabled modules plus the list of enabled module test libraries. - test_runner.uselib_local = env['NS3_ENABLED_MODULES'] + env['NS3_ENABLED_MODULE_TEST_LIBRARIES'] + test_runner.uselib_local = [mod+"--lib" for mod in (env['NS3_ENABLED_MODULES'] + env['NS3_ENABLED_MODULE_TEST_LIBRARIES'])] obj = bld.create_ns3_program('bench-simulator', ['core']) obj.source = 'bench-simulator.cc' @@ -18,6 +18,7 @@ def build(bld): obj = bld.create_ns3_program('bench-packets', ['network']) obj.source = 'bench-packets.cc' - obj = bld.create_ns3_program('print-introspected-doxygen', ['core', 'network', 'internet', 'olsr', 'mobility']) + obj = bld.create_ns3_program('print-introspected-doxygen') obj.source = 'print-introspected-doxygen.cc' + obj.uselib_local = [mod+"--lib" for mod in env['NS3_ENABLED_MODULES']] diff --git a/wscript b/wscript index 5ddf22f5a..b47897860 100644 --- a/wscript +++ b/wscript @@ -207,6 +207,10 @@ def set_options(opt): help=('Compile NS-3 statically: works only on linux, without python'), dest='enable_static', action='store_true', default=False) + opt.add_option('--enable-shared-and-static', + help=('Compile NS-3 both shared and static libraries at the same time: static works only on linux'), + dest='enable_shared_and_static', action='store_true', + default=False) opt.add_option('--enable-mpi', help=('Compile NS-3 with MPI and distributed simulation support'), dest='enable_mpi', action='store_true', @@ -316,12 +320,15 @@ def configure(conf): env['WL_SONAME_SUPPORTED'] = True env['ENABLE_STATIC_NS3'] = False - if Options.options.enable_static: + if Options.options.enable_static or Options.options.enable_shared_and_static: if env['PLATFORM'].startswith('linux') and \ env['CXX_NAME'] in ['gcc', 'icc']: if re.match('i[3-6]86', os.uname()[4]): conf.report_optional_feature("static", "Static build", True, '') - env['ENABLE_STATIC_NS3'] = True + if Options.options.enable_static: + env['ENABLE_STATIC_NS3'] = True + if Options.options.enable_shared_and_static: + env['ENABLE_SHARED_AND_STATIC_NS3'] = True elif os.uname()[4] == 'x86_64': if env['ENABLE_PYTHON_BINDINGS'] and \ not conf.check_compilation_flag('-mcmodel=large'): @@ -332,12 +339,18 @@ def configure(conf): "compiler to at least gcc 4.3.x.") else: conf.report_optional_feature("static", "Static build", True, '') - env['ENABLE_STATIC_NS3'] = True + if Options.options.enable_static: + env['ENABLE_STATIC_NS3'] = True + if Options.options.enable_shared_and_static: + env['ENABLE_SHARED_AND_STATIC_NS3'] = True elif env['CXX_NAME'] == 'gcc' and \ (env['PLATFORM'].startswith('darwin') or \ env['PLATFORM'].startswith('cygwin')): conf.report_optional_feature("static", "Static build", True, '') - env['ENABLE_STATIC_NS3'] = True + if Options.options.enable_static: + env['ENABLE_STATIC_NS3'] = True + if Options.options.enable_shared_and_static: + env['ENABLE_SHARED_AND_STATIC_NS3'] = True else: conf.report_optional_feature("static", "Static build", False, "Unsupported platform") @@ -558,18 +571,7 @@ def create_ns3_program(bld, name, dependencies=('core',)): program.name = name program.target = program.name # Each of the modules this program depends on has its own library. - program.uselib_local = ['ns3-' + dep for dep in dependencies] program.ns3_module_dependencies = ['ns3-'+dep for dep in dependencies] - if program.env['ENABLE_STATIC_NS3']: - if sys.platform == 'darwin': - program.env.append_value('LINKFLAGS', '-Wl,-all_load') - for dep in dependencies: - program.env.append_value('LINKFLAGS', '-lns3-' + dep) - else: - program.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic') - for dep in dependencies: - program.env.append_value('LINKFLAGS', '-lns3-' + dep) - program.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive') return program def register_ns3_script(bld, name, dependencies=('core',)): @@ -606,6 +608,22 @@ def add_scratch_programs(bld): obj.name = obj.target +def _add_ns3_program_missing_deps(bld, program): + deps_found = program.ns3_module_dependencies + program.uselib_local = getattr(program, "uselib_local", []) + [dep + "--lib" for dep in deps_found] + if program.env['ENABLE_STATIC_NS3'] and not program.env['ENABLE_SHARED_AND_STATIC_NS3']: + if sys.platform == 'darwin': + program.env.append_value('LINKFLAGS', '-Wl,-all_load') + for dep in deps_found: + program.env.append_value('LINKFLAGS', '-l' + dep) + else: + program.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic') + for dep in deps_found: + program.env.append_value('LINKFLAGS', '-l' + dep) + program.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive') + + + def build(bld): # If --enabled-modules option was given, then print a warning # message and exit this function. @@ -672,10 +690,6 @@ def build(bld): if mod in bld.env['NS3_ENABLED_MODULES']: bld.env.append_value('NS3_ENABLED_MODULE_TEST_LIBRARIES', testlib) - # Process this subfolder here after the lists of enabled modules - # and module test libraries have been set. - bld.add_subdirs('utils') - add_examples_programs(bld) add_scratch_programs(bld) @@ -751,6 +765,35 @@ def build(bld): bld.add_subdirs('bindings/python') + ## do a topological sort on the modules graph + dep_graph = [] + for gen in bld.all_task_gen: + if type(gen).__name__ in ['ns3module_taskgen']: + for dep in gen.dependencies: + dep_graph.append(("ns3-"+dep, gen.name)) + dep_graph.sort() + sys.path.insert(0, "bindings/python") + from topsort import topsort + sorted_ns3_modules = topsort(dep_graph) + #print sorted_ns3_modules + + # we need to post() the ns3 modules, so they create libraries underneath, and programs can list them in uselib_local + for module in sorted_ns3_modules: + gen = bld.name_to_obj(module, bld.env) + if type(gen).__name__ in ['ns3module_taskgen']: + gen.post() + for lib in gen.libs: + lib.post() + + # Process this subfolder here after the lists of enabled modules + # and module test libraries have been set. + bld.add_subdirs('utils') + + for gen in bld.all_task_gen: + if not getattr(gen, "is_ns3_program", False) or not hasattr(gen, "ns3_module_dependencies"): + continue + _add_ns3_program_missing_deps(bld, gen) + if Options.options.run: # Check that the requested program name is valid program_name, dummy_program_argv = wutils.get_run_program(Options.options.run, wutils.get_command_template(env))