--- a/src/helper/yans-wifi-helper.cc Thu Dec 31 10:20:06 2009 -0800
+++ b/src/helper/yans-wifi-helper.cc Mon Jan 04 10:35:32 2010 -0800
@@ -17,6 +17,8 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
+#include "pcap-helper.h"
+#include "pcap-user-helper.h"
#include "yans-wifi-helper.h"
#include "ns3/error-rate-model.h"
#include "ns3/propagation-loss-model.h"
@@ -24,29 +26,20 @@
#include "ns3/yans-wifi-channel.h"
#include "ns3/yans-wifi-phy.h"
#include "ns3/wifi-net-device.h"
+#include "ns3/radiotap-header.h"
#include "ns3/pcap-writer.h"
#include "ns3/ascii-writer.h"
+#include "ns3/pcap-file-object.h"
#include "ns3/simulator.h"
#include "ns3/config.h"
#include "ns3/names.h"
+#include "ns3/abort.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("YansWifiHelper");
namespace ns3 {
-static void PcapSniffTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz, uint16_t channelNumber,
- uint32_t rate, bool isShortPreamble)
-{
- const double unusedValue = 0;
- writer->WriteWifiMonitorPacket(packet, channelFreqMhz, channelNumber, rate, isShortPreamble, true, unusedValue, unusedValue);
-}
-
-
-static void PcapSniffRxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz, uint16_t channelNumber,
- uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm)
-{
- writer->WriteWifiMonitorPacket(packet, channelFreqMhz, channelNumber, rate, isShortPreamble, false, signalDbm, noiseDbm);
-}
-
-
static void AsciiPhyTxEvent (Ptr<AsciiWriter> writer, std::string path,
Ptr<const Packet> packet,
WifiMode mode, WifiPreamble preamble,
@@ -149,8 +142,7 @@
YansWifiPhyHelper::YansWifiPhyHelper ()
: m_channel (0),
- m_pcapFormat(PCAP_FORMAT_80211)
-
+ m_pcapDlt(PcapHelper::DLT_IEEE802_11)
{
m_phy.SetTypeId ("ns3::YansWifiPhy");
}
@@ -215,94 +207,177 @@
return phy;
}
+static void
+PcapSniffTxEvent (
+ Ptr<PcapFileObject> 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;
+ header.SetTsft (Simulator::Now ().GetMicroSeconds ());
+
+ if (isShortPreamble)
+ {
+ header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE);
+ }
+ else
+ {
+ header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_NONE);
+ }
+
+ 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<PcapFileObject> 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;
+ header.SetTsft (Simulator::Now ().GetMicroSeconds ());
+
+ if (isShortPreamble)
+ {
+ header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE);
+ }
+ else
+ {
+ header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_NONE);
+ }
+
+ 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
YansWifiPhyHelper::SetPcapFormat (enum PcapFormat format)
{
- m_pcapFormat = format;
-}
-
-
-void
-YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
-{
- std::ostringstream oss;
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
- Config::MatchContainer matches = Config::LookupMatches (oss.str ());
- if (matches.GetN () == 0)
+ switch (format)
{
+ case PCAP_FORMAT_80211:
+ m_pcapDlt = PcapHelper::DLT_IEEE802_11;
return;
- }
- oss.str ("");
- oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
- Ptr<PcapWriter> pcap = CreateObject<PcapWriter> ();
- pcap->Open (oss.str ());
-
- switch (m_pcapFormat) {
- case PCAP_FORMAT_80211:
- pcap->WriteWifiHeader ();
- break;
- case PCAP_FORMAT_80211_RADIOTAP:
- pcap->WriteWifiRadiotapHeader ();
- break;
- case PCAP_FORMAT_80211_PRISM:
- pcap->WriteWifiPrismHeader ();
- break;
- }
-
- oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
- oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferTx";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffTxEvent, pcap));
-
- oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
- oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferRx";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffRxEvent, pcap));
-}
-
-void
-YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)
-{
- for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
- {
- Ptr<NetDevice> dev = *i;
- EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+ case PCAP_FORMAT_80211_PRISM:
+ m_pcapDlt = PcapHelper::DLT_PRISM_HEADER;
+ return;
+ case PCAP_FORMAT_80211_RADIOTAP:
+ m_pcapDlt = PcapHelper::DLT_IEEE802_11_RADIO;
+ return;
+ default:
+ NS_ABORT_MSG ("YansWifiPhyHelper::SetPcapFormat(): Unexpected format");
}
}
void
-YansWifiPhyHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd)
+YansWifiPhyHelper::SetPcapDataLinkType (uint32_t dlt)
{
- EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+ m_pcapDlt = dlt;
}
void
-YansWifiPhyHelper::EnablePcap (std::string filename, std::string ndName)
+YansWifiPhyHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous)
{
- Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
- EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
-}
-
-void
-YansWifiPhyHelper::EnablePcap (std::string filename, NodeContainer n)
-{
- NetDeviceContainer devs;
- for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+ //
+ // 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)
{
- Ptr<Node> node = *i;
- for (uint32_t j = 0; j < node->GetNDevices (); ++j)
- {
- devs.Add (node->GetDevice (j));
- }
+ NS_LOG_INFO ("YansWifiHelper::EnablePcapInternal(): Device " << &device << " not of type ns3::WifiNetDevice");
+ return;
}
- EnablePcap (filename, devs);
-}
+
+ Ptr<WifiPhy> phy = device->GetPhy ();
+ NS_ABORT_MSG_IF (phy == 0, "YansWifiPhyHelper::EnablePcapInternal(): Phy layer in WifiNetDevice must be set");
-void
-YansWifiPhyHelper::EnablePcapAll (std::string filename)
-{
- EnablePcap (filename, NodeContainer::GetGlobal ());
+ PcapHelper pcapHelper;
+ std::string filename = pcapHelper.GetFilename (prefix, device);
+
+ Ptr<PcapFileObject> file = pcapHelper.CreateFile (filename, "w", m_pcapDlt);
+
+ phy->TraceConnectWithoutContext ("PromiscSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file));
+ phy->TraceConnectWithoutContext ("PromiscSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file));
}
void