Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(643)

Unified Diff: src/contrib/physim-wifi/helper/physim-wifi-helper.cc

Issue 2173042: NS-3: New and accurate physical layer for IEEE 802.11 OFDM called PhySim-WiFi
Patch Set: Created 13 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/contrib/physim-wifi/helper/physim-wifi-helper.cc
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/contrib/physim-wifi/helper/physim-wifi-helper.cc
@@ -0,0 +1,462 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA, 2009,2010 Jens Mittag, Stylianos Papanastasiou
+ *
+ * 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
+ *
+ * Based on yans-wifi-helper.cc by:
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Major modifications by:
+ * Jens Mittag <jens.mittag@kit.edu>
+ * Stylianos Papanastasiou <stylianos@gmail.com>
+ */
+
+#include "ns3/config.h"
+#include "ns3/trace-helper.h"
+#include "ns3/propagation-delay-model.h"
+#include "ns3/physim-propagation-loss-model.h"
+#include "ns3/physim-wifi-channel.h"
+#include "ns3/physim-wifi-phy.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/radiotap-header.h"
+#include "ns3/pcap-file-wrapper.h"
+#include "ns3/simulator.h"
+#include "ns3/names.h"
+#include "ns3/abort.h"
+#include "ns3/log.h"
+#include "physim-wifi-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("PhySimWifiHelper");
+
+namespace ns3 {
+
+static void
+AsciiPhyTransmitSinkWithContext (
+ Ptr<OutputStreamWrapper> stream,
+ std::string context,
+ Ptr<const Packet> p,
+ Ptr<const PhySimWifiPhyTag> tag)
+{
+ NS_LOG_FUNCTION (stream << context << p << tag->GetTxWifiMode () << tag->GetWifiPreamble () << tag->GetTxPower ());
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
+}
+
+static void
+AsciiPhyTransmitSinkWithoutContext (
+ Ptr<OutputStreamWrapper> stream,
+ Ptr<const Packet> p,
+ Ptr<const PhySimWifiPhyTag> tag)
+{
+ NS_LOG_FUNCTION (stream << p << tag->GetTxWifiMode () << tag->GetWifiPreamble () << tag->GetTxPower ());
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+static void
+AsciiPhyReceiveSinkWithContext (
+ Ptr<OutputStreamWrapper> stream,
+ std::string context,
+ Ptr<const Packet> p,
+ Ptr<const PhySimWifiPhyTag> tag)
+{
+ NS_LOG_FUNCTION (stream << context << p << tag->GetPreambleSinr () << tag->GetRxWifiMode () << tag->GetWifiPreamble ());
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
+}
+
+static void
+AsciiPhyReceiveSinkWithoutContext (
+ Ptr<OutputStreamWrapper> stream,
+ Ptr<const Packet> p,
+ Ptr<const PhySimWifiPhyTag> tag)
+{
+ NS_LOG_FUNCTION (stream << p << tag->GetPreambleSinr () << tag->GetRxWifiMode () << tag->GetWifiPreamble ());
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+PhySimWifiChannelHelper::PhySimWifiChannelHelper ()
+{
+}
+
+PhySimWifiChannelHelper
+PhySimWifiChannelHelper::Default (void)
+{
+ PhySimWifiChannelHelper helper;
+ helper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ helper.AddPropagationLoss ("ns3::PhySimThreeLogDistancePropagationLoss");
+ return helper;
+}
+
+void
+PhySimWifiChannelHelper::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);
+ m_propagationLoss.push_back (factory);
+}
+
+void
+PhySimWifiChannelHelper::SetPropagationDelay (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);
+ m_propagationDelay = factory;
+}
+
+Ptr<PhySimWifiChannel>
+PhySimWifiChannelHelper::Create (void) const
+{
+ Ptr<PhySimWifiChannel> channel = CreateObject<PhySimWifiUniformChannel> ();
+ Ptr<PhySimPropagationLossModel> prev = 0;
+ for (std::vector<ObjectFactory>::const_iterator i = m_propagationLoss.begin (); i != m_propagationLoss.end (); ++i)
+ {
+ Ptr<PhySimPropagationLossModel> cur = (*i).Create<PhySimPropagationLossModel> ();
+ if (prev != 0)
+ {
+ prev->SetNext (cur);
+ }
+ if (m_propagationLoss.begin () == i)
+ {
+ channel->SetPropagationLossModel (cur);
+ }
+ prev = cur;
+ }
+ Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
+ channel->SetPropagationDelayModel (delay);
+ return channel;
+}
+
+
+PhySimWifiPhyHelper::PhySimWifiPhyHelper ()
+ : m_channel (0),
+ m_pcapDlt (PcapHelper::DLT_IEEE802_11)
+{
+ m_phy.SetTypeId ("ns3::PhySimWifiPhy");
+}
+
+PhySimWifiPhyHelper
+PhySimWifiPhyHelper::Default (void)
+{
+ PhySimWifiPhyHelper helper;
+ return helper;
+}
+
+void
+PhySimWifiPhyHelper::SetChannel (Ptr<PhySimWifiChannel> channel)
+{
+ m_channel = channel;
+}
+void
+PhySimWifiPhyHelper::SetChannel (std::string channelName)
+{
+ Ptr<PhySimWifiChannel> channel = Names::Find<PhySimWifiChannel> (channelName);
+ m_channel = channel;
+}
+void
+PhySimWifiPhyHelper::Set (std::string name, const AttributeValue &v)
+{
+ m_phy.Set (name, v);
+}
+
+Ptr<WifiPhy>
+PhySimWifiPhyHelper::Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const
+{
+ Ptr<PhySimWifiPhy> phy = m_phy.Create<PhySimWifiPhy> ();
+ phy->SetChannel (m_channel);
+ phy->SetMobility (node);
+ phy->SetDevice (device);
+ return phy;
+}
+
+static void
+PcapSniffTxEvent (
+ Ptr<PcapFileWrapper> file,
+ Ptr<const Packet> packet,
+ uint16_t channelFreqMhz,
+ uint16_t channelNumber,
+ uint32_t rate,
+ bool isShortPreamble)
+{
+ uint32_t dlt = file->GetDataLinkType ();
+
+ switch (dlt)
+ {
+ case PcapHelper::DLT_IEEE802_11:
+ file->Write (Simulator::Now (), packet);
+ return;
+ case PcapHelper::DLT_PRISM_HEADER:
+ {
+ NS_FATAL_ERROR ("PcapSniffTxEvent(): DLT_PRISM_HEADER not implemented");
+ return;
+ }
+ case PcapHelper::DLT_IEEE802_11_RADIO:
+ {
+ Ptr<Packet> p = packet->Copy ();
+ RadiotapHeader header;
+ uint8_t frameFlags = RadiotapHeader::FRAME_FLAG_NONE;
+ header.SetTsft (Simulator::Now ().GetMicroSeconds ());
+
+ // Our capture includes the FCS, so we set the flag to say so.
+ frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED;
+
+ if (isShortPreamble)
+ {
+ frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE;
+ }
+
+ header.SetFrameFlags (frameFlags);
+ header.SetRate (rate);
+
+ if (channelFreqMhz < 2500)
+ {
+ header.SetChannelFrequencyAndFlags (channelFreqMhz,
+ RadiotapHeader::CHANNEL_FLAG_SPECTRUM_2GHZ | RadiotapHeader::CHANNEL_FLAG_CCK);
+ }
+ else
+ {
+ header.SetChannelFrequencyAndFlags (channelFreqMhz,
+ RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ | RadiotapHeader::CHANNEL_FLAG_OFDM);
+ }
+
+ p->AddHeader (header);
+ file->Write (Simulator::Now (), p);
+ return;
+ }
+ default:
+ NS_ABORT_MSG ("PcapSniffTxEvent(): Unexpected data link type " << dlt);
+ }
+}
+
+static void
+PcapSniffRxEvent (
+ Ptr<PcapFileWrapper> file,
+ Ptr<const Packet> packet,
+ uint16_t channelFreqMhz,
+ uint16_t channelNumber,
+ uint32_t rate,
+ bool isShortPreamble,
+ double signalDbm,
+ double noiseDbm)
+{
+ uint32_t dlt = file->GetDataLinkType ();
+
+ switch (dlt)
+ {
+ case PcapHelper::DLT_IEEE802_11:
+ file->Write (Simulator::Now (), packet);
+ return;
+ case PcapHelper::DLT_PRISM_HEADER:
+ {
+ NS_FATAL_ERROR ("PcapSniffRxEvent(): DLT_PRISM_HEADER not implemented");
+ return;
+ }
+ case PcapHelper::DLT_IEEE802_11_RADIO:
+ {
+ Ptr<Packet> p = packet->Copy ();
+ RadiotapHeader header;
+ uint8_t frameFlags = RadiotapHeader::FRAME_FLAG_NONE;
+ header.SetTsft (Simulator::Now ().GetMicroSeconds ());
+
+ // Our capture includes the FCS, so we set the flag to say so.
+ frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED;
+
+ if (isShortPreamble)
+ {
+ frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE;
+ }
+
+ header.SetFrameFlags (frameFlags);
+ header.SetRate (rate);
+
+ if (channelFreqMhz < 2500)
+ {
+ header.SetChannelFrequencyAndFlags (channelFreqMhz,
+ RadiotapHeader::CHANNEL_FLAG_SPECTRUM_2GHZ | RadiotapHeader::CHANNEL_FLAG_CCK);
+ }
+ else
+ {
+ header.SetChannelFrequencyAndFlags (channelFreqMhz,
+ RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ | RadiotapHeader::CHANNEL_FLAG_OFDM);
+ }
+
+ header.SetAntennaSignalPower (signalDbm);
+ header.SetAntennaNoisePower (noiseDbm);
+
+ p->AddHeader (header);
+ file->Write (Simulator::Now (), p);
+ return;
+ }
+ default:
+ NS_ABORT_MSG ("PcapSniffRxEvent(): Unexpected data link type " << dlt);
+ }
+}
+
+void
+PhySimWifiPhyHelper::SetPcapDataLinkType (enum SupportedPcapDataLinkTypes dlt)
+{
+ switch (dlt)
+ {
+ case DLT_IEEE802_11:
+ m_pcapDlt = PcapHelper::DLT_IEEE802_11;
+ return;
+ case DLT_PRISM_HEADER:
+ m_pcapDlt = PcapHelper::DLT_PRISM_HEADER;
+ return;
+ case DLT_IEEE802_11_RADIO:
+ m_pcapDlt = PcapHelper::DLT_IEEE802_11_RADIO;
+ return;
+ default:
+ NS_ABORT_MSG ("PhySimWifiPhyHelper::SetPcapFormat(): Unexpected format");
+ }
+}
+
+void
+PhySimWifiPhyHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
+{
+ //
+ // All of the Pcap enable functions vector through here including the ones
+ // that are wandering through all of devices on perhaps all of the nodes in
+ // the system. We can only deal with devices of type WifiNetDevice.
+ //
+ Ptr<WifiNetDevice> device = nd->GetObject<WifiNetDevice> ();
+ if (device == 0)
+ {
+ NS_LOG_INFO ("PhySimWifiHelper::EnablePcapInternal(): Device " << &device << " not of type ns3::WifiNetDevice");
+ return;
+ }
+
+ Ptr<WifiPhy> phy = device->GetPhy ();
+ NS_ABORT_MSG_IF (phy == 0, "PhySimWifiPhyHelper::EnablePcapInternal(): Phy layer in WifiNetDevice must be set");
+
+ PcapHelper pcapHelper;
+
+ std::string filename;
+ if (explicitFilename)
+ {
+ filename = prefix;
+ }
+ else
+ {
+ filename = pcapHelper.GetFilenameFromDevice (prefix, device);
+ }
+
+ Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, m_pcapDlt);
+
+ phy->TraceConnectWithoutContext ("PromiscSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file));
+ phy->TraceConnectWithoutContext ("PromiscSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file));
+}
+
+void
+PhySimWifiPhyHelper::EnableAsciiInternal (
+ Ptr<OutputStreamWrapper> stream,
+ std::string prefix,
+ Ptr<NetDevice> nd,
+ bool explicitFilename)
+{
+ //
+ // All of the ascii enable functions vector through here including the ones
+ // that are wandering through all of devices on perhaps all of the nodes in
+ // the system. We can only deal with devices of type CsmaNetDevice.
+ //
+ Ptr<WifiNetDevice> device = nd->GetObject<WifiNetDevice> ();
+ if (device == 0)
+ {
+ NS_LOG_INFO ("PhySimWifiHelper::EnableAsciiInternal(): Device " << device << " not of type ns3::WifiNetDevice");
+ return;
+ }
+ Ptr<WifiPhy> phy = device->GetPhy ();
+
+ //
+ // Our trace sinks are going to use packet printing, so we have to make sure
+ // that is turned on.
+ //
+ Packet::EnablePrinting ();
+
+ uint32_t nodeid = nd->GetNode ()->GetId ();
+ uint32_t deviceid = nd->GetIfIndex ();
+ std::ostringstream oss;
+
+ //
+ // If we are not provided an OutputStreamWrapper, we are expected to create
+ // one using the usual trace filename conventions and write our traces
+ // without a context since there will be one file per context and therefore
+ // the context would be redundant.
+ //
+ if (stream == 0)
+ {
+ //
+ // Set up an output stream object to deal with private ofstream copy
+ // constructor and lifetime issues. Let the helper decide the actual
+ // name of the file given the prefix.
+ //
+ AsciiTraceHelper asciiTraceHelper;
+
+ std::string filename;
+ if (explicitFilename)
+ {
+ filename = prefix;
+ }
+ else
+ {
+ filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
+ }
+
+ Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
+ phy->TraceConnectWithoutContext ("RxOk", MakeBoundCallback (&AsciiPhyReceiveSinkWithoutContext, theStream));
+ phy->TraceConnectWithoutContext ("Tx", MakeBoundCallback (&AsciiPhyTransmitSinkWithoutContext, theStream));
+
+ return;
+ }
+
+ oss.str ("");
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/RxOk";
+ Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyReceiveSinkWithContext, stream));
+
+ oss.str ("");
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/Tx";
+ Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTransmitSinkWithContext, stream));
+
+}
+
+} // namespace ns3
« no previous file with comments | « src/contrib/physim-wifi/helper/physim-wifi-helper.h ('k') | src/contrib/physim-wifi/model/physim-blockinterleaver.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b