#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/aqua-sim-ng-module.h"
#include "ns3/applications-module.h"
#include "ns3/log.h"
#include "ns3/callback.h"
#include "ns3/netanim-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("ASBroadcastMac");
int
main (int argc, char *argv[])
{
double simStop = 1800; //seconds
int nodes = 15;
// int sinks = 1;
uint32_t m_dataRate = 800;
uint32_t m_packetSize = 40;
LogComponentEnable ("ASBroadcastMac", LOG_LEVEL_INFO);
LogComponentEnable ("AquaSimAloha", LOG_LEVEL_INFO);
//to change on the fly
CommandLine cmd;
cmd.AddValue ("simStop", "Length of simulation", simStop);
cmd.AddValue ("nodes", "Amount of regular underwater nodes", nodes);
// cmd.AddValue ("sinks", "Amount of underwater sinks", sinks);
cmd.Parse(argc,argv);
std::cout << "-----------Initializing simulation-----------\n";
NodeContainer nodesCon;
nodesCon.Create(nodes);
PacketSocketHelper socketHelper;
socketHelper.Install(nodesCon);
//establish layers using helper's pre-build settings
AquaSimChannelHelper channel = AquaSimChannelHelper::Default();
AquaSimHelper asHelper = AquaSimHelper::Default();
asHelper.SetChannel(channel.Create());
asHelper.SetMac("ns3::AquaSimAloha");
asHelper.SetRouting("ns3::AquaSimRoutingDummy");
/*
* Set up mobility model for nodes and sinks
*/
MobilityHelper mobility;
NetDeviceContainer devices;
Ptr<ListPositionAllocator> position = CreateObject<ListPositionAllocator> ();
std::cout << "Creating Nodes\n";
//sink
Ptr<AquaSimNetDevice> newDevice0 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(6000,10000,0));
Ptr<AquaSimNetDevice> sink = asHelper.Create(nodesCon.Get(0), newDevice0);
sink->SetSinkStatus();
devices.Add(sink);
//row 1
Ptr<AquaSimNetDevice> newDevice1 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(4000,8000,0));
Ptr<AquaSimNetDevice> dev1 = asHelper.Create(nodesCon.Get(1), newDevice1);
devices.Add(dev1);
Ptr<AquaSimNetDevice> newDevice2 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(8000,8000,0));
Ptr<AquaSimNetDevice> dev2 = asHelper.Create(nodesCon.Get(2), newDevice2);
devices.Add(dev2);
//row 2
Ptr<AquaSimNetDevice> newDevice3 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(2000,6000,0));
Ptr<AquaSimNetDevice> dev3 = asHelper.Create(nodesCon.Get(3), newDevice3);
devices.Add(dev3);
Ptr<AquaSimNetDevice> newDevice4 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(6000,6000,0));
Ptr<AquaSimNetDevice> dev4 = asHelper.Create(nodesCon.Get(4), newDevice4);
devices.Add(dev4);
Ptr<AquaSimNetDevice> newDevice5 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(10000,6000,0));
Ptr<AquaSimNetDevice> dev5 = asHelper.Create(nodesCon.Get(5), newDevice5);
devices.Add(dev5);
//row 3
Ptr<AquaSimNetDevice> newDevice6 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(1000,3000,0));
Ptr<AquaSimNetDevice> dev6 = asHelper.Create(nodesCon.Get(6), newDevice6);
devices.Add(dev6);
Ptr<AquaSimNetDevice> newDevice7 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(6000,3000,0));
Ptr<AquaSimNetDevice> dev7 = asHelper.Create(nodesCon.Get(7), newDevice7);
devices.Add(dev7);
Ptr<AquaSimNetDevice> newDevice8 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(11000,3000,0));
Ptr<AquaSimNetDevice> dev8 = asHelper.Create(nodesCon.Get(8), newDevice8);
devices.Add(dev8);
//data sources:
Ptr<AquaSimNetDevice> newDevice9 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(0,0,0));
Ptr<AquaSimNetDevice> dev9 = asHelper.Create(nodesCon.Get(9), newDevice9);
devices.Add(dev9);
Ptr<AquaSimNetDevice> newDevice10 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(2000,0,0));
Ptr<AquaSimNetDevice> dev10 = asHelper.Create(nodesCon.Get(10), newDevice10);
devices.Add(dev10);
Ptr<AquaSimNetDevice> newDevice11 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(5000,0,0));
Ptr<AquaSimNetDevice> dev11 = asHelper.Create(nodesCon.Get(11), newDevice11);
devices.Add(dev11);
Ptr<AquaSimNetDevice> newDevice12 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(7000,0,0));
Ptr<AquaSimNetDevice> dev12 = asHelper.Create(nodesCon.Get(12), newDevice12);
devices.Add(dev12);
Ptr<AquaSimNetDevice> newDevice13 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(10000,0,0));
Ptr<AquaSimNetDevice> dev13 = asHelper.Create(nodesCon.Get(13), newDevice13);
devices.Add(dev13);
Ptr<AquaSimNetDevice> newDevice14 = CreateObject<AquaSimNetDevice>();
position->Add(Vector(12000,0,0));
Ptr<AquaSimNetDevice> dev14 = asHelper.Create(nodesCon.Get(14), newDevice14);
devices.Add(dev14);
mobility.SetPositionAllocator(position);
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.Install(nodesCon);
PacketSocketAddress socket;
socket.SetAllDevices();
socket.SetPhysicalAddress (devices.Get(0)->GetAddress()); //Set dest to first sink
socket.SetProtocol (0);
OnOffHelper app ("ns3::PacketSocketFactory", Address (socket));
app.SetAttribute("OnTime",StringValue("ns3::ConstantRandomVariable[Constant=0.4]"));
app.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=99.6]"));
app.SetAttribute ("DataRate", DataRateValue (m_dataRate));
app.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
ApplicationContainer apps = app.Install (nodesCon);
apps.Start (Seconds (0.5));
apps.Stop (Seconds (simStop+1));
Ptr<Node> sinkNode = nodesCon.Get(0);
TypeId psfid = TypeId::LookupByName ("ns3::PacketSocketFactory");
Ptr<Socket> sinkSocket = Socket::CreateSocket (sinkNode, psfid);
sinkSocket->Bind (socket);
std::cout << "sink node id(start from 0)=" << nodesCon.Get (0)->GetId () << std::endl;
AnimationInterface anim("test0.xml");
Packet::EnablePrinting (); //for debugging purposes
std::cout << "-----------Running Simulation-----------\n";
Simulator::Stop(Seconds(simStop));
Simulator::Run();
std::cout << "-----------Printing Simulation Results-----------\n";
asHelper.GetChannel()->PrintCounters();
Simulator::Destroy();
std::cout << "fin.\n";
return 0;
}