From 786ae233a14440e21cc0c4bfce3e44680aabe5a1 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Tue, 10 Jun 2008 15:43:52 -0700 Subject: [PATCH] PHY-layer test scripts --- src/devices/wifi/wifi-phy-test.cc | 246 ++++++++++++++++++++++++++++++ src/devices/wifi/wscript | 4 + 2 files changed, 250 insertions(+) create mode 100644 src/devices/wifi/wifi-phy-test.cc diff --git a/src/devices/wifi/wifi-phy-test.cc b/src/devices/wifi/wifi-phy-test.cc new file mode 100644 index 000000000..e76358e3a --- /dev/null +++ b/src/devices/wifi/wifi-phy-test.cc @@ -0,0 +1,246 @@ +#include "wifi-phy.h" +#include "wifi-channel.h" +#include "propagation-loss-model.h" +#include "propagation-delay-model.h" +#include "ns3/ptr.h" +#include "ns3/mobility-model.h" +#include "ns3/static-mobility-model.h" +#include "ns3/vector.h" +#include "ns3/packet.h" +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/command-line.h" + +using namespace ns3; + +class PsrExperiment +{ +public: + struct Input + { + double distance; + std::string txMode; + uint8_t txPowerLevel; + uint32_t packetSize; + uint32_t nPackets; + }; + struct Output + { + uint32_t received; + }; + PsrExperiment (); + + static struct PsrExperiment::Input GetDefaultInput (void); + + struct PsrExperiment::Output Run (struct PsrExperiment::Input input); + +private: + void Send (void); + typedef Callback, double, WifiMode, enum WifiPreamble> SyncOkCallback; + void Receive (Ptr p, double snr, WifiMode mode, enum WifiPreamble preamble); + Ptr m_tx; + struct Input m_input; + struct Output m_output; +}; + +void +PsrExperiment::Send (void) +{ + Ptr p = Create (m_input.packetSize); + WifiMode mode = WifiMode (m_input.txMode); + m_tx->SendPacket (p, mode, WIFI_PREAMBLE_SHORT, m_input.txPowerLevel); +} + +void +PsrExperiment::Receive (Ptr p, double snr, WifiMode mode, enum WifiPreamble preamble) +{ + m_output.received++; +} + +PsrExperiment::PsrExperiment () +{} +struct PsrExperiment::Input +PsrExperiment::GetDefaultInput (void) +{ + struct PsrExperiment::Input input; + input.distance = 5.0; + input.packetSize = 2304; + input.nPackets = 400; + input.txPowerLevel = 0; + input.txMode = "wifia-6mbs"; + return input; +} + +struct PsrExperiment::Output +PsrExperiment::Run (struct PsrExperiment::Input input) +{ + m_output.received = 0; + m_input = input; + + Ptr posTx = CreateObject (); + posTx->SetPosition (Vector (0.0, 0.0, 0.0)); + Ptr posRx = CreateObject (); + posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0)); + + Ptr tx = CreateObject (); + Ptr rx = CreateObject (); + rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this)); + + Ptr channel = CreateObject (); + channel->SetPropagationDelayModel (CreateObject ()); + Ptr log = CreateObject (); + log->SetReferenceModel (CreateObject ()); + channel->SetPropagationLossModel (log); + + channel->Add (0, tx, posTx); + channel->Add (0, rx, posRx); + tx->SetChannel (channel); + rx->SetChannel (channel); + + for (uint32_t i = 0; i < m_input.nPackets; ++i) + { + Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this); + } + m_tx = tx; + Simulator::Run (); + return m_output; +} + +static void PrintPsr (int argc, char *argv[]) +{ + PsrExperiment experiment; + struct PsrExperiment::Input input = experiment.GetDefaultInput (); + + CommandLine cmd; + cmd.AddValue ("Distance", "The distance between two phys", input.distance); + cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize); + cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode); + cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets); + cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel); + cmd.Parse (argc, argv); + + struct PsrExperiment::Output output; + output = experiment.Run (input); + + double psr = output.received; + psr /= input.nPackets ; + + std::cout << psr << std::endl; +} + +double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input) +{ + double psr = output.received; + psr /= input.nPackets ; + return psr; +} + +static void PrintPsrVsDistance (int argc, char *argv[]) +{ + struct PsrExperiment::Input input = PsrExperiment::GetDefaultInput (); + CommandLine cmd; + cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel); + cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode); + cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets); + cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize); + cmd.Parse (argc, argv); + for (input.distance = 1.0; input.distance < 165; input.distance += 2.0) + { + std::cout << input.distance; + PsrExperiment experiment; + struct PsrExperiment::Output output; + + input.txMode = "wifia-6mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + input.txMode = "wifia-9mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + input.txMode = "wifia-12mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + input.txMode = "wifia-18mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + input.txMode = "wifia-24mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + input.txMode = "wifia-36mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + input.txMode = "wifia-48mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + input.txMode = "wifia-54mbs"; + output = experiment.Run (input); + std::cout << " " << CalcPsr (output, input); + + std::cout << std::endl; + } +} + +static void PrintSizeVsRange (int argc, char *argv[]) +{ + struct PsrExperiment::Input input = PsrExperiment::GetDefaultInput (); + CommandLine cmd; + cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel); + cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode); + cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets); + cmd.Parse (argc, argv); + for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40) + { + for (input.distance = 100.0; input.distance < 170; input.distance += 2.0) + { + struct PsrExperiment::Output output; + PsrExperiment experiment; + output = experiment.Run (input); + double psr = output.received; + psr /= input.nPackets ; + if (psr <= 0.05) + { + std::cout << input.packetSize << " " << input.distance << std::endl; + break; + } + } + } +} + + + +int main (int argc, char *argv[]) +{ + if (argc <= 1) + { + std::cout << "Available experiments: " + << "Psr " + << "SizeVsRange " + << "PsrVsDistance " + << std::endl; + return -1; + } + std::string type = argv[1]; + argc--; + argv[1] = argv[0]; + argv++; + if (type == "Psr") + { + PrintPsr (argc, argv); + } + else if (type == "SizeVsRange") + { + PrintSizeVsRange (argc, argv); + } + else if (type == "PsrVsDistance") + { + PrintPsrVsDistance (argc, argv); + } + + return 0; +} diff --git a/src/devices/wifi/wscript b/src/devices/wifi/wscript index 89711a426..535938434 100644 --- a/src/devices/wifi/wscript +++ b/src/devices/wifi/wscript @@ -69,3 +69,7 @@ def build(bld): 'wifi-phy.h', 'supported-rates.h', ] + + obj = bld.create_ns3_program('wifi-phy-test', + ['core', 'simulator', 'mobility', 'node', 'wifi']) + obj.source = 'wifi-phy-test.cc'