/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// 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.3 192.168.0.4 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.2
// +---------+ +---------+
// | AP Node | | AP Node |
// +---------+ +---------+
//
#include "ns3/core-module.h"
#include "ns3/simulator-module.h"
#include "ns3/mobility-module.h"
#include "ns3/helper-module.h"
#include "ns3/wifi-module.h"
#include "ns3/node-module.h"
#include "ns3/global-route-manager.h"
#include <vector>
#include <stdint.h>
#include <sstream>
#include <fstream>
using namespace ns3;
int main (int argc, char *argv[])
{
uint32_t nWifis = 2;
uint32_t nStas = 2;
bool sendIp = true;
CommandLine cmd;
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.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);
double wifiX = 0.0;
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 = WifiHelper::Default ();
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
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::NqapWifiMac",
"Ssid", SsidValue (ssid),
"BeaconGeneration", BooleanValue (true),
"BeaconInterval", TimeValue (Seconds (2.5)));
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 ("Constant:1.0"),
"Bounds", RectangleValue (Rectangle (wifiX, wifiX+5.0,0.0, (nStas+1)*5.0)));
mobility.Install (sta);
wifiMac.SetType ("ns3::NqstaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
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.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
ApplicationContainer apps = onoff.Install (staNodes[0].Get (0));
apps.Start (Seconds (0.5));
apps.Stop (Seconds (3.0));
YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[0]);
YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[1]);
std::ofstream os;
os.open ("wifi-wired-bridging.mob");
MobilityHelper::EnableAsciiAll (os);
Simulator::Stop (Seconds (100.0));
Simulator::Run ();
Simulator::Destroy ();
}