/****************************************************/ /* Tento program je prilohou k diplomovej praci */ /* Bezdrotove siete pre velmi hustu prevadzku */ /* */ /* Autor: Veronika Marasova, CVUT FEL, Praha 2017 */ /* */ /****************************************************/ #include "ns3/core-module.h" #include "ns3/mobility-module.h" #include "ns3/applications-module.h" #include "ns3/wifi-module.h" #include "ns3/csma-module.h" #include "ns3/network-module.h" #include "ns3/internet-module.h" #include "ns3/bridge-helper.h" #include "ns3/flow-monitor-module.h" #include "ns3/netanim-module.h" #include "ns3/spectrum-module.h" #include "ns3/ipv4-global-routing-helper.h" #include #include #include #include #include using namespace ns3; NS_LOG_COMPONENT_DEFINE ("Simulation_script-HighDensity"); int main (int argc, char *argv[]) { uint32_t nAPs = 1; uint32_t nStreams = 2; bool shrtGI = true; bool enablePcap = false; bool uplink = true; // Define direction of traffic, if true STA -> AP, else AP -> STA std::string dataRate = "2Mbps"; // Application DataRate uint32_t payloadSize =1472; // Application payload uint8_t tos = 0x70; // AccessCategories - 0x70 - AC_BE, 0x28 - AC_BK, 0xb8 - AC_VI, 0xc0 - AC_VO double appStartTime = 1; double appStopTime = 11; double simulationStopTime = 11; std::string mcs = "VhtMcs0"; std::string fileName = "SIM"; uint32_t chWidth = 20; uint32_t nStas = 10; uint32_t perc=100; bool enableCtsRts=0; CommandLine cmd; cmd.AddValue ("nAP", "Number of APs", nAPs); cmd.AddValue ("nStas", "Number of stations per AP", nStas); cmd.AddValue ("nStreams", "Number of spatial streams of a STA devices (1-2)", nStreams); cmd.AddValue ("chWidth", "Channel width: 20, 40, 80 or 160 MHz", chWidth); cmd.AddValue ("shrtGI", "Short GuardInterval enabled", shrtGI); cmd.AddValue ("dataRate", "The rate of data transmission (with Mbps/kbps)", dataRate); cmd.AddValue ("perc", "Percentage of active devices (0-100):", perc); cmd.AddValue ("MCS", "Modulation and Coding Scheme", mcs); cmd.AddValue ("payloadSize", "Size of a data packet", payloadSize); cmd.AddValue ("fileName", "Size of a data packet", fileName); cmd.AddValue ("enPcap", "Enable .pcap tracing if true", enablePcap); cmd.AddValue ("upLink", "Direction of traffic: 0 - AP -> STA, 1 - STA -> AP", uplink); cmd.AddValue ("ToS", "Type of Service: 0x28 AC_BK; 0x70 AC_BE; 0xb8 AC_VI; 0xc0 AC_VO", tos); cmd.Parse (argc, argv); if((dataRate.find("Mbps") == std::string::npos) && (dataRate.find("kbps") == std::string::npos)){ std::cout << "Invalid datarate. \n"; return EXIT_FAILURE; } if((chWidth==20)&&(mcs=="VhtMcs9")) { std::cout << "Invalid combination of channel width and MCS. \n"; return EXIT_FAILURE; } if((chWidth==160)&&(nAPs>2)) { std::cout << "Invalid combination of channel width and number of APs. In case of 160 MHz channel maximum valid number of APs is 2. \n"; return EXIT_FAILURE; } if(nStreams>2) { std::cout << "Invalid number of spatial streams. The STA supports 1 or 2 spatial streams. \n"; return EXIT_FAILURE; } NS_LOG_UNCOND("Running simulation: " << nStas << " STA(s) per AP, " << nAPs << " AP(s), " << dataRate <<", " << mcs << " Channel: "< staNodes; std::vector staDevices; std::vector apDevices; std::vector staInterfaces; std::vector apInterfaces; InternetStackHelper stack; CsmaHelper csma; Ipv4AddressHelper ip; backboneNodes.Create (nAPs); stack.Install (backboneNodes); backboneDevices = csma.Install (backboneNodes); double apX, apY; //position of AP1 int chann[4], freq[4]; //define channels for different channel Widths double edt, cca; if (chWidth == 20) { chann[0] = 36; chann[1] = 60; chann[2] = 52; chann[3] = 44; freq[0] = 5180; freq[1] = 5300; freq[2] = 5260; freq[3] = 5220; edt= -82; cca = -62; } else if (chWidth == 40) { chann[0] = 38; chann[1] = 46; chann[2] = 54; chann[3] = 62; freq[0] = 5190; freq[1] = 5230; freq[2] = 5270; freq[3] = 5310; edt= -79; cca = -59; } else if (chWidth == 80) { chann[0] = 42; chann[1] = 122; chann[2] = 106; chann[3] = 58; freq[0] = 5210; freq[1] = 5610; freq[2] = 5530; freq[3] = 5290; edt= -76; cca = -56; } else if (chWidth == 160) { chann[0] = 50; chann[1] = 114; freq[0] = 5250; freq[1] = 5570; edt= -73; } for (uint32_t i = 0; i < nAPs; ++i) { int grid = ceil(sqrt(nStas)); if (i==0) { ip.SetBase ("10.0.0.0", "255.255.255.0"); apX = 10.0, apY = 10.0; } else if (i==1) { ip.SetBase ("10.1.0.0", "255.255.255.0"); apX = 11 + grid/2; apY =10.0; } else if (i==2) { ip.SetBase ("10.2.0.0", "255.255.255.0"); apX= 10.0; apY=10.5+grid; } else if (i==3) { ip.SetBase ("10.3.0.0", "255.255.255.0"); apX= 11 + grid/2; apY=10.5+grid; } SpectrumWifiPhyHelper wifiPhy; Ptr spectrumChannel; spectrumChannel = CreateObject (); Ptr lossModel = CreateObject (); spectrumChannel->AddPropagationLossModel (lossModel); Ptr delayModel = CreateObject (); spectrumChannel->SetPropagationDelayModel (delayModel); wifiPhy.SetChannel(spectrumChannel); std::ostringstream oss; oss << "HighDensity-" << i; Ssid ssid = Ssid (oss.str ()); NodeContainer sta; NetDeviceContainer staDev; NetDeviceContainer apDev; Ipv4InterfaceContainer staInterface; Ipv4InterfaceContainer apInterface; BridgeHelper bridge; // Configuring STAs sta.Create (nStas); WifiHelper wifi; wifi.SetStandard (WIFI_PHY_STANDARD_80211ac); wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue (mcs), "ControlMode", StringValue (mcs)); wifiPhy.Set ("ChannelNumber", UintegerValue(chann[i%4])); wifiPhy.Set ("Frequency", UintegerValue (freq[i%4])); wifiPhy.Set ("ShortGuardEnabled", BooleanValue (shrtGI)); wifiPhy.SetErrorRateModel("ns3::NistErrorRateModel"); wifiPhy.SetPcapDataLinkType(SpectrumWifiPhyHelper::DLT_IEEE802_11_RADIO); wifiPhy.Set("EnergyDetectionThreshold", DoubleValue (edt)); if (chWidth != 160){ wifiPhy.Set("CcaMode1Threshold", DoubleValue (cca)); } wifiPhy.Set ("TxPowerStart", DoubleValue (15)); wifiPhy.Set ("TxPowerEnd", DoubleValue (15)); wifiPhy.Set ("TxGain", DoubleValue (-2)); wifiPhy.Set ("RxGain", DoubleValue (-2)); wifiPhy.Set ("TxAntennas", UintegerValue (nStreams)); wifiPhy.Set ("RxAntennas", UintegerValue (nStreams)); VhtWifiMacHelper wifiMac; wifiMac.SetType ("ns3::StaWifiMac", "Ssid", SsidValue (ssid), "QosSupported", BooleanValue (true), "BE_BlockAckThreshold", UintegerValue (2), "BE_MaxAmpduSize", UintegerValue (2) ); staDev = wifi.Install (wifiPhy, wifiMac, sta); MobilityHelper mobility; mobility.SetPositionAllocator ("ns3::GridPositionAllocator", "MinX", DoubleValue (apX-grid/4), "MinY", DoubleValue (apY-(grid/2)), "DeltaX", DoubleValue (0.5), "DeltaY", DoubleValue (1), "GridWidth", UintegerValue (grid), "LayoutType", StringValue ("RowFirst")); stack.Install (sta); mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); mobility.Install (sta); staInterface = ip.Assign (staDev); // Configuring APs mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); mobility.Install (backboneNodes.Get (i)); AnimationInterface::SetConstantPosition (backboneNodes.Get (i), apX, apY, 3.5); wifiMac.SetType ("ns3::ApWifiMac", "Ssid", SsidValue (ssid), "BeaconGeneration", BooleanValue (true), "QosSupported", BooleanValue (true), "BeaconInterval", TimeValue (MilliSeconds (100))); wifiPhy.Set ("TxPowerStart", DoubleValue (20)); wifiPhy.Set ("TxPowerEnd", DoubleValue (20)); wifiPhy.Set ("TxGain", DoubleValue (0)); wifiPhy.Set ("RxGain", DoubleValue (0)); wifiPhy.Set ("TxAntennas", UintegerValue (4)); wifiPhy.Set ("RxAntennas", UintegerValue (4)); apDev = wifi.Install (wifiPhy, wifiMac, backboneNodes.Get (i)); NetDeviceContainer bridgeDev; bridgeDev = bridge.Install (backboneNodes.Get (i), NetDeviceContainer (apDev, backboneDevices.Get (i))); Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/ChannelNumber", UintegerValue (chann[i%4])); apInterface = ip.Assign (bridgeDev); staNodes.push_back (sta); apDevices.push_back (apDev); apInterfaces.push_back (apInterface); staDevices.push_back (staDev); staInterfaces.push_back (staInterface); if (enablePcap) { wifiPhy.EnablePcap (fileName,apDev); wifiPhy.EnablePcap (fileName,staDev); } } // Applications Address dest; std::string protocol; uint16_t port; uint16_t i,j; std::ostringstream fileN; fileN << fileName << ".xml"; AnimationInterface anim (fileN.str ()); anim.EnablePacketMetadata (); anim.SetMaxPktsPerTraceFile(1000000); uint32_t nActive=round(nStas*perc/100); std::cout << nActive << "\n"; for (j=0; j monitor = flowmon.InstallAll (); std::ostringstream fileN1; fileN1 << fileName << ".flowmon"; Simulator::Stop (Seconds (simulationStopTime)); Simulator::Run (); double sum=0, summ=0; // Print per flow statistics monitor->CheckForLostPackets (); Ptr classifier = DynamicCast (flowmon.GetClassifier ()); FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats (); monitor->SerializeToXmlFile(fileN1.str (), true, true); for (std::map::const_iterator i = stats.begin (); i != stats.end (); ++i) { uint32_t duration = appStopTime - appStartTime; std::cout << i->second.rxPackets << "\n"; std::cout << i->second.rxBytes * 8.0 / duration / 1024 / 1024 << "\n"; sum=sum+(i->second.rxBytes * 8.0 / duration / 1024 / 1024); summ=summ+ (i->second.rxPackets*(payloadSize)*8.0/duration/1024/1024); } double average = sum/nStas; std::cout << average << "\n"; std::cout << summ << "\n"; Simulator::Destroy (); }