src/helper/yans-wifi-helper.cc
author Nicola Baldo <nbaldo@cttc.es>
Thu Aug 13 09:36:53 2009 +0200 (2009-08-13)
changeset 4709 b0743dbc4e55
parent 4497 43c7dfd72eb1
child 4712 74ed62336c36
permissions -rw-r--r--
bug 639: add configurable capture size to pcap
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2008 INRIA
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    19  */
    20 #include "yans-wifi-helper.h"
    21 #include "ns3/error-rate-model.h"
    22 #include "ns3/propagation-loss-model.h"
    23 #include "ns3/propagation-delay-model.h"
    24 #include "ns3/yans-wifi-channel.h"
    25 #include "ns3/yans-wifi-phy.h"
    26 #include "ns3/wifi-net-device.h"
    27 #include "ns3/pcap-writer.h"
    28 #include "ns3/simulator.h"
    29 #include "ns3/config.h"
    30 #include "ns3/names.h"
    31 
    32 namespace ns3 {
    33 
    34 static void PcapSniffTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz,  
    35                               uint32_t rate, bool isShortPreamble)
    36 {
    37   const double unusedValue = 0;
    38   writer->WriteWifiMonitorPacket(packet, channelFreqMhz, rate, isShortPreamble, true, unusedValue, unusedValue); 
    39 }
    40 
    41 
    42 static void PcapSniffRxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz,  
    43                               uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm)
    44 {
    45   writer->WriteWifiMonitorPacket(packet, channelFreqMhz, rate, isShortPreamble, false, signalDbm, noiseDbm); 
    46 }
    47 
    48 
    49 static void AsciiPhyTxEvent (std::ostream *os, std::string context, 
    50                              Ptr<const Packet> packet,
    51                              WifiMode mode, WifiPreamble preamble, 
    52                              uint8_t txLevel)
    53 {
    54   *os << "+ " << Simulator::Now () << " " << context << " " << *packet << std::endl;
    55 }
    56 
    57 static void AsciiPhyRxOkEvent (std::ostream *os, std::string context, 
    58                                Ptr<const Packet> packet, double snr, WifiMode mode, 
    59                                enum WifiPreamble preamble)
    60 {
    61   *os << "r " << Simulator::Now () << " " << context << " " << *packet << std::endl;
    62 }
    63 
    64 
    65 YansWifiChannelHelper::YansWifiChannelHelper ()
    66 {}
    67 
    68 YansWifiChannelHelper 
    69 YansWifiChannelHelper::Default (void)
    70 {
    71   YansWifiChannelHelper helper;
    72   helper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
    73   helper.AddPropagationLoss ("ns3::LogDistancePropagationLossModel");
    74   return helper;
    75 }
    76 
    77 void 
    78 YansWifiChannelHelper::AddPropagationLoss (std::string type,
    79 					   std::string n0, const AttributeValue &v0,
    80 					   std::string n1, const AttributeValue &v1,
    81 					   std::string n2, const AttributeValue &v2,
    82 					   std::string n3, const AttributeValue &v3,
    83 					   std::string n4, const AttributeValue &v4,
    84 					   std::string n5, const AttributeValue &v5,
    85 					   std::string n6, const AttributeValue &v6,
    86 					   std::string n7, const AttributeValue &v7)
    87 {
    88   ObjectFactory factory;
    89   factory.SetTypeId (type);
    90   factory.Set (n0, v0);
    91   factory.Set (n1, v1);
    92   factory.Set (n2, v2);
    93   factory.Set (n3, v3);
    94   factory.Set (n4, v4);
    95   factory.Set (n5, v5);
    96   factory.Set (n6, v6);
    97   factory.Set (n7, v7);
    98   m_propagationLoss.push_back (factory);
    99 }
   100 
   101 void 
   102 YansWifiChannelHelper::SetPropagationDelay (std::string type,
   103 					    std::string n0, const AttributeValue &v0,
   104 					    std::string n1, const AttributeValue &v1,
   105 					    std::string n2, const AttributeValue &v2,
   106 					    std::string n3, const AttributeValue &v3,
   107 					    std::string n4, const AttributeValue &v4,
   108 					    std::string n5, const AttributeValue &v5,
   109 					    std::string n6, const AttributeValue &v6,
   110 					    std::string n7, const AttributeValue &v7)
   111 {
   112   ObjectFactory factory;
   113   factory.SetTypeId (type);
   114   factory.Set (n0, v0);
   115   factory.Set (n1, v1);
   116   factory.Set (n2, v2);
   117   factory.Set (n3, v3);
   118   factory.Set (n4, v4);
   119   factory.Set (n5, v5);
   120   factory.Set (n6, v6);
   121   factory.Set (n7, v7);
   122   m_propagationDelay = factory;
   123 }
   124 
   125 Ptr<YansWifiChannel> 
   126 YansWifiChannelHelper::Create (void) const
   127 {
   128   Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
   129   Ptr<PropagationLossModel> prev = 0;
   130   for (std::vector<ObjectFactory>::const_iterator i = m_propagationLoss.begin (); i != m_propagationLoss.end (); ++i)
   131     {
   132       Ptr<PropagationLossModel> cur = (*i).Create<PropagationLossModel> ();
   133       if (prev != 0)
   134 	{
   135 	  prev->SetNext (cur);
   136 	}
   137       if (m_propagationLoss.begin () == i)
   138 	{
   139 	  channel->SetPropagationLossModel (cur);
   140 	}
   141       prev = cur;
   142     }
   143   Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
   144   channel->SetPropagationDelayModel (delay);
   145   return channel;
   146 }
   147 
   148 
   149 YansWifiPhyHelper::YansWifiPhyHelper ()
   150   : m_channel (0),
   151     m_pcapFormat(PCAP_FORMAT_80211)
   152     
   153 {
   154   m_phy.SetTypeId ("ns3::YansWifiPhy");
   155 }
   156 
   157 YansWifiPhyHelper 
   158 YansWifiPhyHelper::Default (void)
   159 {
   160   YansWifiPhyHelper helper;
   161   helper.SetErrorRateModel ("ns3::YansErrorRateModel");
   162   return helper;
   163 }
   164 
   165 void 
   166 YansWifiPhyHelper::SetChannel (Ptr<YansWifiChannel> channel)
   167 {
   168   m_channel = channel;
   169 }
   170 void 
   171 YansWifiPhyHelper::SetChannel (std::string channelName)
   172 {
   173   Ptr<YansWifiChannel> channel = Names::Find<YansWifiChannel> (channelName);
   174   m_channel = channel;
   175 }
   176 void 
   177 YansWifiPhyHelper::Set (std::string name, const AttributeValue &v)
   178 {
   179   m_phy.Set (name, v);
   180 }
   181 
   182 void 
   183 YansWifiPhyHelper::SetErrorRateModel (std::string name,
   184                                      std::string n0, const AttributeValue &v0,
   185                                      std::string n1, const AttributeValue &v1,
   186                                      std::string n2, const AttributeValue &v2,
   187                                      std::string n3, const AttributeValue &v3,
   188                                      std::string n4, const AttributeValue &v4,
   189                                      std::string n5, const AttributeValue &v5,
   190                                      std::string n6, const AttributeValue &v6,
   191                                      std::string n7, const AttributeValue &v7)
   192 {
   193   m_errorRateModel = ObjectFactory ();
   194   m_errorRateModel.SetTypeId (name);
   195   m_errorRateModel.Set (n0, v0);
   196   m_errorRateModel.Set (n1, v1);
   197   m_errorRateModel.Set (n2, v2);
   198   m_errorRateModel.Set (n3, v3);
   199   m_errorRateModel.Set (n4, v4);
   200   m_errorRateModel.Set (n5, v5);
   201   m_errorRateModel.Set (n6, v6);
   202   m_errorRateModel.Set (n7, v7);
   203 }
   204 
   205 Ptr<WifiPhy> 
   206 YansWifiPhyHelper::Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const
   207 {
   208   Ptr<YansWifiPhy> phy = m_phy.Create<YansWifiPhy> ();
   209   Ptr<ErrorRateModel> error = m_errorRateModel.Create<ErrorRateModel> ();
   210   phy->SetErrorRateModel (error);
   211   phy->SetChannel (m_channel);
   212   phy->SetMobility (node);
   213   phy->SetDevice (device);
   214   return phy;
   215 }
   216 
   217 
   218 void 
   219 YansWifiPhyHelper::SetPcapFormat (enum PcapFormat format)
   220 {
   221   m_pcapFormat = format;
   222 }
   223 
   224 
   225 void 
   226 YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
   227 {
   228   std::ostringstream oss;
   229   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
   230   Config::MatchContainer matches = Config::LookupMatches (oss.str ());
   231   if (matches.GetN () == 0)
   232     {
   233       return;
   234     }
   235   oss.str ("");
   236   oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
   237   Ptr<PcapWriter> pcap = CreateObject<PcapWriter> ();
   238   pcap->Open (oss.str ());
   239 
   240   switch (m_pcapFormat) {
   241   case PCAP_FORMAT_80211:
   242     pcap->WriteWifiHeader ();  
   243     break;
   244   case PCAP_FORMAT_80211_RADIOTAP:
   245     pcap->WriteWifiRadiotapHeader ();  
   246     break;
   247   case PCAP_FORMAT_80211_PRISM:
   248     pcap->WriteWifiPrismHeader ();  
   249     break;
   250   }
   251   
   252   oss.str ("");
   253   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
   254   oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferTx";
   255   Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffTxEvent, pcap));
   256 
   257   oss.str ("");
   258   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
   259   oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferRx";
   260   Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffRxEvent, pcap));  
   261 }
   262 
   263 void 
   264 YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)
   265 {
   266   for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
   267     {
   268       Ptr<NetDevice> dev = *i;
   269       EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
   270     }
   271 }
   272 
   273 void 
   274 YansWifiPhyHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd)
   275 {
   276   EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
   277 }
   278 
   279 void 
   280 YansWifiPhyHelper::EnablePcap (std::string filename, std::string ndName)
   281 {
   282   Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
   283   EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
   284 }
   285 
   286 void
   287 YansWifiPhyHelper::EnablePcap (std::string filename, NodeContainer n)
   288 {
   289   NetDeviceContainer devs;
   290   for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
   291     {
   292       Ptr<Node> node = *i;
   293       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
   294         {
   295           devs.Add (node->GetDevice (j));
   296         }
   297     }
   298   EnablePcap (filename, devs);
   299 }
   300 
   301 void
   302 YansWifiPhyHelper::EnablePcapAll (std::string filename)
   303 {
   304   EnablePcap (filename, NodeContainer::GetGlobal ());
   305 }
   306 
   307 void 
   308 YansWifiPhyHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
   309 {
   310   Packet::EnablePrinting ();
   311   std::ostringstream oss;
   312   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
   313   Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyRxOkEvent, &os));
   314   oss.str ("");
   315   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
   316   Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTxEvent, &os));
   317 }
   318 void 
   319 YansWifiPhyHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
   320 {
   321   for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
   322     {
   323       Ptr<NetDevice> dev = *i;
   324       EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
   325     }
   326 }
   327 void
   328 YansWifiPhyHelper::EnableAscii (std::ostream &os, NodeContainer n)
   329 {
   330   NetDeviceContainer devs;
   331   for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
   332     {
   333       Ptr<Node> node = *i;
   334       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
   335         {
   336           devs.Add (node->GetDevice (j));
   337         }
   338     }
   339   EnableAscii (os, devs);
   340 }
   341 
   342 void
   343 YansWifiPhyHelper::EnableAsciiAll (std::ostream &os)
   344 {
   345   EnableAscii (os, NodeContainer::GetGlobal ());
   346 }
   347 
   348 } // namespace ns3