201 lines
7.0 KiB
C++
201 lines
7.0 KiB
C++
/*
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
|
*/
|
|
|
|
// Default network topology includes some number of AP nodes specified by
|
|
// the variable nWifis (defaults to two). Off of each AP node, there are some
|
|
// number of STA nodes specified by the variable nStas (defaults to two).
|
|
// Each AP talks to its associated STA nodes. There are bridge net devices
|
|
// on each AP node that bridge the whole thing into one network.
|
|
//
|
|
// +-----+ +-----+ +-----+ +-----+
|
|
// | STA | | STA | | STA | | STA |
|
|
// +-----+ +-----+ +-----+ +-----+
|
|
// 192.168.0.2 192.168.0.3 192.168.0.5 192.168.0.6
|
|
// -------- -------- -------- --------
|
|
// WIFI STA WIFI STA WIFI STA WIFI STA
|
|
// -------- -------- -------- --------
|
|
// ((*)) ((*)) | ((*)) ((*))
|
|
// |
|
|
// ((*)) | ((*))
|
|
// ------- -------
|
|
// WIFI AP CSMA ========= CSMA WIFI AP
|
|
// ------- ---- ---- -------
|
|
// ############## ##############
|
|
// BRIDGE BRIDGE
|
|
// ############## ##############
|
|
// 192.168.0.1 192.168.0.4
|
|
// +---------+ +---------+
|
|
// | AP Node | | AP Node |
|
|
// +---------+ +---------+
|
|
|
|
#include "ns3/bridge-helper.h"
|
|
#include "ns3/command-line.h"
|
|
#include "ns3/csma-helper.h"
|
|
#include "ns3/double.h"
|
|
#include "ns3/internet-stack-helper.h"
|
|
#include "ns3/ipv4-address-helper.h"
|
|
#include "ns3/mobility-helper.h"
|
|
#include "ns3/on-off-helper.h"
|
|
#include "ns3/packet-socket-address.h"
|
|
#include "ns3/rectangle.h"
|
|
#include "ns3/ssid.h"
|
|
#include "ns3/string.h"
|
|
#include "ns3/uinteger.h"
|
|
#include "ns3/yans-wifi-channel.h"
|
|
#include "ns3/yans-wifi-helper.h"
|
|
|
|
using namespace ns3;
|
|
|
|
int
|
|
main(int argc, char* argv[])
|
|
{
|
|
uint32_t nWifis = 2;
|
|
uint32_t nStas = 2;
|
|
bool sendIp = true;
|
|
bool writeMobility = false;
|
|
|
|
CommandLine cmd(__FILE__);
|
|
cmd.AddValue("nWifis", "Number of wifi networks", nWifis);
|
|
cmd.AddValue("nStas", "Number of stations per wifi network", nStas);
|
|
cmd.AddValue("SendIp", "Send Ipv4 or raw packets", sendIp);
|
|
cmd.AddValue("writeMobility", "Write mobility trace", writeMobility);
|
|
cmd.Parse(argc, argv);
|
|
|
|
NodeContainer backboneNodes;
|
|
NetDeviceContainer backboneDevices;
|
|
Ipv4InterfaceContainer backboneInterfaces;
|
|
std::vector<NodeContainer> staNodes;
|
|
std::vector<NetDeviceContainer> staDevices;
|
|
std::vector<NetDeviceContainer> apDevices;
|
|
std::vector<Ipv4InterfaceContainer> staInterfaces;
|
|
std::vector<Ipv4InterfaceContainer> apInterfaces;
|
|
|
|
InternetStackHelper stack;
|
|
CsmaHelper csma;
|
|
Ipv4AddressHelper ip;
|
|
ip.SetBase("192.168.0.0", "255.255.255.0");
|
|
|
|
backboneNodes.Create(nWifis);
|
|
stack.Install(backboneNodes);
|
|
|
|
backboneDevices = csma.Install(backboneNodes);
|
|
|
|
meter_u wifiX = 0.0;
|
|
|
|
YansWifiPhyHelper wifiPhy;
|
|
wifiPhy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
|
|
|
|
for (uint32_t i = 0; i < nWifis; ++i)
|
|
{
|
|
// calculate ssid for wifi subnetwork
|
|
std::ostringstream oss;
|
|
oss << "wifi-default-" << i;
|
|
Ssid ssid = Ssid(oss.str());
|
|
|
|
NodeContainer sta;
|
|
NetDeviceContainer staDev;
|
|
NetDeviceContainer apDev;
|
|
Ipv4InterfaceContainer staInterface;
|
|
Ipv4InterfaceContainer apInterface;
|
|
MobilityHelper mobility;
|
|
BridgeHelper bridge;
|
|
WifiHelper wifi;
|
|
WifiMacHelper wifiMac;
|
|
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();
|
|
wifiPhy.SetChannel(wifiChannel.Create());
|
|
|
|
sta.Create(nStas);
|
|
mobility.SetPositionAllocator("ns3::GridPositionAllocator",
|
|
"MinX",
|
|
DoubleValue(wifiX),
|
|
"MinY",
|
|
DoubleValue(0.0),
|
|
"DeltaX",
|
|
DoubleValue(5.0),
|
|
"DeltaY",
|
|
DoubleValue(5.0),
|
|
"GridWidth",
|
|
UintegerValue(1),
|
|
"LayoutType",
|
|
StringValue("RowFirst"));
|
|
|
|
// setup the AP.
|
|
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
|
|
mobility.Install(backboneNodes.Get(i));
|
|
wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
|
|
apDev = wifi.Install(wifiPhy, wifiMac, backboneNodes.Get(i));
|
|
|
|
NetDeviceContainer bridgeDev;
|
|
bridgeDev =
|
|
bridge.Install(backboneNodes.Get(i), NetDeviceContainer(apDev, backboneDevices.Get(i)));
|
|
|
|
// assign AP IP address to bridge, not wifi
|
|
apInterface = ip.Assign(bridgeDev);
|
|
|
|
// setup the STAs
|
|
stack.Install(sta);
|
|
mobility.SetMobilityModel(
|
|
"ns3::RandomWalk2dMobilityModel",
|
|
"Mode",
|
|
StringValue("Time"),
|
|
"Time",
|
|
StringValue("2s"),
|
|
"Speed",
|
|
StringValue("ns3::ConstantRandomVariable[Constant=1.0]"),
|
|
"Bounds",
|
|
RectangleValue(Rectangle(wifiX, wifiX + 5.0, 0.0, (nStas + 1) * 5.0)));
|
|
mobility.Install(sta);
|
|
wifiMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
|
|
staDev = wifi.Install(wifiPhy, wifiMac, sta);
|
|
staInterface = ip.Assign(staDev);
|
|
|
|
// save everything in containers.
|
|
staNodes.push_back(sta);
|
|
apDevices.push_back(apDev);
|
|
apInterfaces.push_back(apInterface);
|
|
staDevices.push_back(staDev);
|
|
staInterfaces.push_back(staInterface);
|
|
|
|
wifiX += 20.0;
|
|
}
|
|
|
|
Address dest;
|
|
std::string protocol;
|
|
if (sendIp)
|
|
{
|
|
dest = InetSocketAddress(staInterfaces[1].GetAddress(1), 1025);
|
|
protocol = "ns3::UdpSocketFactory";
|
|
}
|
|
else
|
|
{
|
|
PacketSocketAddress tmp;
|
|
tmp.SetSingleDevice(staDevices[0].Get(0)->GetIfIndex());
|
|
tmp.SetPhysicalAddress(staDevices[1].Get(0)->GetAddress());
|
|
tmp.SetProtocol(0x807);
|
|
dest = tmp;
|
|
protocol = "ns3::PacketSocketFactory";
|
|
}
|
|
|
|
OnOffHelper onoff = OnOffHelper(protocol, dest);
|
|
onoff.SetConstantRate(DataRate("500kb/s"));
|
|
ApplicationContainer apps = onoff.Install(staNodes[0].Get(0));
|
|
apps.Start(Seconds(0.5));
|
|
apps.Stop(Seconds(3.0));
|
|
|
|
wifiPhy.EnablePcap("wifi-wired-bridging", apDevices[0]);
|
|
wifiPhy.EnablePcap("wifi-wired-bridging", apDevices[1]);
|
|
|
|
if (writeMobility)
|
|
{
|
|
AsciiTraceHelper ascii;
|
|
MobilityHelper::EnableAsciiAll(ascii.CreateFileStream("wifi-wired-bridging.mob"));
|
|
}
|
|
|
|
Simulator::Stop(Seconds(5.0));
|
|
Simulator::Run();
|
|
Simulator::Destroy();
|
|
|
|
return 0;
|
|
}
|