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