232 lines
5.5 KiB
C++
232 lines
5.5 KiB
C++
/*
|
|
* Copyright (c) 2005,2006,2007 INRIA
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
|
*
|
|
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
|
*/
|
|
|
|
#include "ns3/athstats-helper.h"
|
|
#include "ns3/boolean.h"
|
|
#include "ns3/command-line.h"
|
|
#include "ns3/config.h"
|
|
#include "ns3/mobility-helper.h"
|
|
#include "ns3/mobility-model.h"
|
|
#include "ns3/on-off-helper.h"
|
|
#include "ns3/packet-socket-address.h"
|
|
#include "ns3/packet-socket-helper.h"
|
|
#include "ns3/ssid.h"
|
|
#include "ns3/string.h"
|
|
#include "ns3/yans-wifi-channel.h"
|
|
#include "ns3/yans-wifi-helper.h"
|
|
|
|
using namespace ns3;
|
|
|
|
/// True for verbose output.
|
|
static bool g_verbose = true;
|
|
|
|
/**
|
|
* MAC-level TX trace.
|
|
*
|
|
* @param context The context.
|
|
* @param p The packet.
|
|
*/
|
|
void
|
|
DevTxTrace(std::string context, Ptr<const Packet> p)
|
|
{
|
|
if (g_verbose)
|
|
{
|
|
std::cout << " TX p: " << *p << std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MAC-level RX trace.
|
|
*
|
|
* @param context The context.
|
|
* @param p The packet.
|
|
*/
|
|
void
|
|
DevRxTrace(std::string context, Ptr<const Packet> p)
|
|
{
|
|
if (g_verbose)
|
|
{
|
|
std::cout << " RX p: " << *p << std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PHY-level RX OK trace
|
|
*
|
|
* @param context The context.
|
|
* @param packet The packet.
|
|
* @param snr The SNR.
|
|
* @param mode The wifi mode.
|
|
* @param preamble The preamble.
|
|
*/
|
|
void
|
|
PhyRxOkTrace(std::string context,
|
|
Ptr<const Packet> packet,
|
|
double snr,
|
|
WifiMode mode,
|
|
WifiPreamble preamble)
|
|
{
|
|
if (g_verbose)
|
|
{
|
|
std::cout << "PHYRXOK mode=" << mode << " snr=" << snr << " " << *packet << std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PHY-level RX error trace
|
|
*
|
|
* @param context The context.
|
|
* @param packet The packet.
|
|
* @param snr The SNR.
|
|
*/
|
|
void
|
|
PhyRxErrorTrace(std::string context, Ptr<const Packet> packet, double snr)
|
|
{
|
|
if (g_verbose)
|
|
{
|
|
std::cout << "PHYRXERROR snr=" << snr << " " << *packet << std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PHY-level TX trace.
|
|
*
|
|
* @param context The context.
|
|
* @param packet The packet.
|
|
* @param mode The wifi mode.
|
|
* @param preamble The preamble.
|
|
* @param txPower The TX power.
|
|
*/
|
|
void
|
|
PhyTxTrace(std::string context,
|
|
Ptr<const Packet> packet,
|
|
WifiMode mode,
|
|
WifiPreamble preamble,
|
|
uint8_t txPower)
|
|
{
|
|
if (g_verbose)
|
|
{
|
|
std::cout << "PHYTX mode=" << mode << " " << *packet << std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PHY state trace.
|
|
*
|
|
* @param context The context.
|
|
* @param start Start time of the state.
|
|
* @param duration Duration of the state.
|
|
* @param state The state.
|
|
*/
|
|
void
|
|
PhyStateTrace(std::string context, Time start, Time duration, WifiPhyState state)
|
|
{
|
|
if (g_verbose)
|
|
{
|
|
std::cout << " state=" << state << " start=" << start << " duration=" << duration
|
|
<< std::endl;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Move a node position by 5m on the x axis every second, up to 210m.
|
|
*
|
|
* @param node The node.
|
|
*/
|
|
static void
|
|
AdvancePosition(Ptr<Node> node)
|
|
{
|
|
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
|
|
Vector pos = mobility->GetPosition();
|
|
pos.x += 5.0;
|
|
if (pos.x >= 210.0)
|
|
{
|
|
return;
|
|
}
|
|
mobility->SetPosition(pos);
|
|
|
|
Simulator::Schedule(Seconds(1), &AdvancePosition, node);
|
|
}
|
|
|
|
int
|
|
main(int argc, char* argv[])
|
|
{
|
|
CommandLine cmd(__FILE__);
|
|
cmd.AddValue("verbose", "Print trace information if true", g_verbose);
|
|
cmd.Parse(argc, argv);
|
|
|
|
Packet::EnablePrinting();
|
|
|
|
WifiHelper wifi;
|
|
MobilityHelper mobility;
|
|
NodeContainer stas;
|
|
NodeContainer ap;
|
|
NetDeviceContainer staDevs;
|
|
PacketSocketHelper packetSocket;
|
|
|
|
stas.Create(2);
|
|
ap.Create(1);
|
|
|
|
// give packet socket powers to nodes.
|
|
packetSocket.Install(stas);
|
|
packetSocket.Install(ap);
|
|
|
|
WifiMacHelper wifiMac;
|
|
YansWifiPhyHelper wifiPhy;
|
|
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();
|
|
wifiPhy.SetChannel(wifiChannel.Create());
|
|
Ssid ssid = Ssid("wifi-default");
|
|
// setup stas.
|
|
wifiMac.SetType("ns3::StaWifiMac",
|
|
"ActiveProbing",
|
|
BooleanValue(true),
|
|
"Ssid",
|
|
SsidValue(ssid));
|
|
staDevs = wifi.Install(wifiPhy, wifiMac, stas);
|
|
// setup ap.
|
|
wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
|
|
wifi.Install(wifiPhy, wifiMac, ap);
|
|
|
|
// mobility.
|
|
mobility.Install(stas);
|
|
mobility.Install(ap);
|
|
|
|
Simulator::Schedule(Seconds(1), &AdvancePosition, ap.Get(0));
|
|
|
|
PacketSocketAddress socket;
|
|
socket.SetSingleDevice(staDevs.Get(0)->GetIfIndex());
|
|
socket.SetPhysicalAddress(staDevs.Get(1)->GetAddress());
|
|
socket.SetProtocol(1);
|
|
|
|
OnOffHelper onoff("ns3::PacketSocketFactory", Address(socket));
|
|
onoff.SetConstantRate(DataRate("500kb/s"));
|
|
|
|
ApplicationContainer apps = onoff.Install(stas.Get(0));
|
|
apps.Start(Seconds(0.5));
|
|
apps.Stop(Seconds(43));
|
|
|
|
Simulator::Stop(Seconds(44));
|
|
|
|
Config::Connect("/NodeList/*/DeviceList/*/Mac/MacTx", MakeCallback(&DevTxTrace));
|
|
Config::Connect("/NodeList/*/DeviceList/*/Mac/MacRx", MakeCallback(&DevRxTrace));
|
|
Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxOk", MakeCallback(&PhyRxOkTrace));
|
|
Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxError", MakeCallback(&PhyRxErrorTrace));
|
|
Config::Connect("/NodeList/*/DeviceList/*/Phy/State/Tx", MakeCallback(&PhyTxTrace));
|
|
Config::Connect("/NodeList/*/DeviceList/*/Phy/State/State", MakeCallback(&PhyStateTrace));
|
|
|
|
AthstatsHelper athstats;
|
|
athstats.EnableAthstats("athstats-sta", stas);
|
|
athstats.EnableAthstats("athstats-ap", ap);
|
|
|
|
Simulator::Run();
|
|
|
|
Simulator::Destroy();
|
|
|
|
return 0;
|
|
}
|