/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include <iostream>
#include <stdlib.h>
#include <limits.h>
#include "ns3/core-module.h"
#include "ns3/csma-helper.h"
#include "ns3/yans-wifi-channel.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/network-module.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/nqos-wifi-mac-helper.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/udp-echo-helper.h"
#include "ns3/ssid.h"
#include "ns3/rectangle.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-flow-classifier.h"
#include "ns3/gnuplot.h"
#include "ns3/mobility-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/gnuplot.h"
#include "ns3/flow-monitor.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/animation-interface.h"
using namespace ns3;
int main (int argc, char *argv[])
{
// Default Enviroment_________________________________________________________
double minX;
double minY;
uint32_t i; // Counters
uint32_t j; // Counters
uint32_t Ap = 1; // Number of Access points (and number of servers)
uint32_t Md = 1; // Number of mobile devices in each Access point
double Interval = 0; // Delay in seconds
int BB_Delay = 6560; // Delay of CSMA network in nano seconds
int packet = 100; // Mobile device packet size byte
bool Rw = false; // Boolean to allow Random Walk
// Bring In Comandline arguments______________________________________________
CommandLine cmd;
cmd.AddValue("nAp", "Number of access points", Ap);
cmd.AddValue("nMd", "Number of mobile devices", Md);
cmd.AddValue("MPSize", "Size of mobile device packet", packet);
cmd.AddValue("RandOn", "Allow for \"Random Walk\" fuctionality", Rw);
cmd.AddValue("csmaDelay","delay of the csma \"Back Bone\" in nano sec", BB_Delay);
cmd.Parse(argc,argv);
Interval = (double)packet/(1024000.0); // Caluclate Interval for 128Kbps bandwidth
std::cout << Interval << std::endl;
// SetUp Network______________________________________________________________
NetDeviceContainer S_devices;
NetDeviceContainer A_devices;
NetDeviceContainer M_devices;
//Setup "Back Bone" of the network
CsmaHelper csma;
csma.SetChannelAttribute("DataRate", StringValue("10Mbps"));
csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(BB_Delay)));
//Setup Servers
NodeContainer ServerNode; //Hold Servers
//Setup wifi access points
NodeContainer wifiStaNode; //Hold access point
NodeContainer wifiMdNode; //Hold mobile devices
//Setup wifi comminication
YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
channel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
channel.AddPropagationLoss ("ns3::RangePropagationLossModel","MaxRange", DoubleValue (120.0));
YansWifiPhyHelper phy = YansWifiPhyHelper::Default();
phy.SetChannel (channel.Create());
WifiHelper wifi = WifiHelper::Default ();
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager");
NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();
Ssid ssid = Ssid ("ns-3-ssid");
//Mobility and location manager
MobilityHelper mobility;
ServerNode.Create(Ap); //Create one server concection
S_devices = csma.Install(ServerNode); //Install the Server to the back bone
wifiStaNode.Create(Ap); //Create one Access Point
mac.SetType ("ns3::StaWifiMac","Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
wifi.Install(phy,mac,wifiStaNode);
A_devices = csma.Install(wifiStaNode); //Install the Access Point
mac.SetType ("ns3::ApWifiMac","Ssid", SsidValue (ssid),
"BeaconGeneration", BooleanValue (true),
"BeaconInterval", TimeValue (Seconds (2.5)));
wifiMdNode.Create(Md); //Create the moble devices
M_devices = wifi.Install(phy,mac,wifiMdNode); //Add the mobile devices
for(i = 0; i < Ap; i++)
{//Ran for each access point
//Set up Random Walk
minX = i*100.0;
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (minX),
"MinY", DoubleValue (0.0));
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.Install(wifiStaNode.Get(i)); //Install each Access Point 100 apart
mobility.Install(ServerNode.Get(i));
for(j = 0; j < Md; j++)
{//Randomly install moble devices in wifi area (allow for mobility if need be)
minX = 100.0*i + (float)(rand()%100);
minY = rand()%100;
mobility.SetPositionAllocator("ns3::GridPositionAllocator",
"MinX", DoubleValue(minX),
"MinY", DoubleValue(minY));
if(Rw){
mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel","Bounds",
RectangleValue(Rectangle(-300, 300, -50, 50)));
}
else{
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
}
mobility.Install(wifiMdNode.Get(i+j));
}//end for loop
}//end for loop, end setup
// Setup address and stack for devices
InternetStackHelper stack;
stack.Install(ServerNode);
stack.Install(wifiStaNode);
stack.Install(wifiMdNode);
Ipv4AddressHelper address;
address.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer S_interfaces = address.Assign(S_devices);
address.SetBase("10.2.1.0", "255.255.255.0");
Ipv4InterfaceContainer Ap_interfaces = address.Assign(A_devices);
address.SetBase("10.3.1.0", "255.255.255.0");
Ipv4InterfaceContainer Md_interfaces = address.Assign(M_devices);
// Setup Communication
ApplicationContainer clientApps;
ApplicationContainer serverApps;
UdpClientHelper ClientHelper;
UdpServerHelper ServerHelper(9);
for(i=0;i<Ap;i++)
{
ClientHelper = UdpClientHelper(S_interfaces.GetAddress(i),9); //Have Client talk to Server
ClientHelper.SetAttribute("MaxPackets",UintegerValue(INT_MAX)); //Set up comunication requirements
ClientHelper.SetAttribute("Interval",TimeValue(Seconds(Interval))); //
ClientHelper.SetAttribute("PacketSize",UintegerValue(packet)); //
serverApps.Add(ServerHelper.Install(ServerNode.Get(i))); //Install Server to serverApps
for(j=0;j<Md;j++)
clientApps.Add(ClientHelper.Install(wifiMdNode.Get(i*Md + j))); //Install mobile device to clientApps
}//end for loop //Comunication setup Complete
std::cout << std::endl << clientApps.GetN() << std::endl;
std::cout << std::endl << serverApps.GetN() << std::endl;
// Run Simulation_____________________________________________________________
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
serverApps.Start(Seconds (1.0));
serverApps.Stop (Seconds (102.0));
clientApps.Start(Seconds (1.5));
clientApps.Stop (Seconds (102.0));
Simulator::Stop (Seconds (105.0));
//plotting code, Added by martin
//
std::string fileNameWithNoExtension = "FlowVSThroughput";
std::string graphicsFileName = fileNameWithNoExtension + ".png";
std::string plotFileName = fileNameWithNoExtension + ".plt";
std::string plotTitle = "Flow vs Throughput";
std::string dataTitle = "Throughput";
// Instantiate the plot and set its title.
Gnuplot gnuplot(graphicsFileName);
gnuplot.SetTitle (plotTitle);
// Make the graphics file, which the plot file will be when it
// is used with Gnuplot, be a PNG file.
gnuplot.SetTerminal ("png");
// Set the labels for each axis.
gnuplot.SetLegend ("Flow", "Throughput");
Gnuplot2dDataset dataset;
dataset.SetTitle (dataTitle);
dataset.SetStyle (Gnuplot2dDataset::LINES_POINTS);
// end added by martin
//Enable Trace
// Tracing certain info: - added by martin
//
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll();
monitor = flowmon.GetMonitor();
// end part added by martin
AnimationInterface anim ("animation.xml"); // added by martin
std::cout << "\n\nI'm Running Baby =D\n\n";
Simulator::Run ();
// Do we need a destroy here?
//Tracing, added by martin:
monitor->CheckForLostPackets ();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier> (flowmon.GetClassifier ());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats ();
for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin (); i != stats.end (); ++i)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (i->first);
std::cout << "Flow " << i->first - 2 << " (" << t.sourceAddress << " -> " << t.destinationAddress << ")\n";
std::cout << " Tx Bytes: " << i->second.txBytes << "\n";
std::cout << " Rx Bytes: " << i->second.rxBytes << "\n";
std::cout << " Throughput: " << i->second.rxBytes * 8.0 / 10.0 / 1024 / 1024 << " Mbps\n";
}
monitor->SerializeToXmlFile ("results.xml",false,true);
// End code added by martin
//Plotting code, added by martin
//
NS_LOG_UNCOND("Flow monitor statistics: ");
// Print per flow statistics
/*if(true){
monitor->CheckForLostPackets ();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier>(flowmon.GetClassifier ());
std::map< FlowId, FlowMonitor::FlowStats > stats =monitor->GetFlowStats ();
double Throughput=0.0;
for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator iter =stats.begin (); iter != stats.end (); ++iter)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (iter->first);
std::cout << "Flow ID: " << iter->first << " Src Addr " <<t.sourceAddress << " Dst Addr " << t.destinationAddress;
std::cout <<"Tx Packets = " << iter->second.txPackets;
std::cout << "Rx Packets = " << iter->second.rxPackets;
Throughput=iter->second.rxBytes * 8.0 /(iter->second.timeLastRxPacket.GetSeconds()-iter->second.timeFirstTxPacket.GetSeconds())/1024;
//NS_LOG_UNCOND("Throughput: " << Throughput << " Kbps");
dataset.Add((double)iter->first,(double) Throughput);
}
std::cout << "Done";
}*/
//Gnuplot ...continued
gnuplot.AddDataset (dataset);
// Open the plot file.
std::ofstream plotFile (plotFileName.c_str());
// Write the plot file.
gnuplot.GenerateOutput (plotFile);
// Close the plot file.
plotFile.close ();
//End code added by martin
Simulator::Destroy ();
std::cout << "\n\nSimulator Distroyed\n\n";
//anim.StopAnimation(); // added by martin, open animation.xml in netanim 3.0
return 0;
}//END MAIN //END of myProj4.cc