From cce6ab4f4fb2bbc73b9d440c72ded7eb9be95f3d Mon Sep 17 00:00:00 2001 From: adrien gougeon Date: Mon, 19 Oct 2020 10:29:38 +0200 Subject: [PATCH] add WifiZone support for ns3 wifi --- include/simgrid/kernel/routing/WifiZone.hpp | 1 + src/kernel/routing/WifiZone.cpp | 2 +- src/surf/network_ns3.cpp | 93 +++++++++++++++++---- 3 files changed, 80 insertions(+), 16 deletions(-) diff --git a/include/simgrid/kernel/routing/WifiZone.hpp b/include/simgrid/kernel/routing/WifiZone.hpp index da6027d959..adc05ed2f9 100644 --- a/include/simgrid/kernel/routing/WifiZone.hpp +++ b/include/simgrid/kernel/routing/WifiZone.hpp @@ -30,6 +30,7 @@ public: s4u::Link* create_link(const std::string& name, const std::vector& bandwidths, double latency, s4u::Link::SharingPolicy policy, const std::unordered_map* props) override; + NetPoint* get_access_point() {return access_point_;} private: resource::LinkImpl* wifi_link_ = nullptr; // Representing the air media (there is no such thing in NS-3) diff --git a/src/kernel/routing/WifiZone.cpp b/src/kernel/routing/WifiZone.cpp index 4c64420581..d9eaefc6f3 100644 --- a/src/kernel/routing/WifiZone.cpp +++ b/src/kernel/routing/WifiZone.cpp @@ -39,7 +39,7 @@ void WifiZone::get_local_route(NetPoint* src, NetPoint* dst, RouteCreationArgs* if (wifi_link_ != nullptr) { // If src and dst are nodes, not access_point, we need to traverse the link twice - // Otherwise (if src or dst is access_poit), we need to traverse the link only once + // Otherwise (if src or dst is access_point), we need to traverse the link only once if (src != access_point_) { XBT_DEBUG("src %s is not our gateway", src->get_cname()); diff --git a/src/surf/network_ns3.cpp b/src/surf/network_ns3.cpp index f82de064a6..dd866f2585 100644 --- a/src/surf/network_ns3.cpp +++ b/src/surf/network_ns3.cpp @@ -28,6 +28,7 @@ #include "ns3/ns3_simulator.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" +#include "simgrid/kernel/routing/WifiZone.hpp" #include "simgrid/plugins/energy.h" #include "simgrid/s4u/Engine.hpp" #include "simgrid/s4u/NetZone.hpp" @@ -126,6 +127,81 @@ static void initialize_ns3_wifi() * Callbacks * *************/ +static void zoneCreation_cb(simgrid::s4u::NetZone const& zone) { + simgrid::kernel::routing::WifiZone* wifizone = dynamic_cast (zone.get_impl()); + if (wifizone == nullptr) return; + + wifi.SetStandard(ns3::WIFI_PHY_STANDARD_80211n_5GHZ); + + std::string ssid = wifizone->get_name(); + const char* mcs = wifizone->get_property("mcs"); + const char* nss = wifizone->get_property("nss"); + int mcs_value = mcs ? atoi(mcs) : 3; + int nss_value = nss ? atoi(nss) : 1; + wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", + "ControlMode", ns3::StringValue("HtMcs0"), + "DataMode", ns3::StringValue("HtMcs" + std::to_string(mcs_value))); + wifiPhy.SetChannel(wifiChannel.Create()); + wifiPhy.Set("Antennas", ns3::UintegerValue(nss_value)); + wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(nss_value)); + wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(nss_value)); + wifiMac.SetType("ns3::ApWifiMac", + "Ssid", ns3::SsidValue(ssid)); + + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + ns3::Ptr positionAllocS = ns3::CreateObject(); + positionAllocS->Add(ns3::Vector(0, 0, 0)); + + ns3::NetDeviceContainer netDevices; + NetPointNs3* access_point_netpoint_ns3 = wifizone->get_access_point()->extension(); + + ns3::Ptr access_point_ns3_node = access_point_netpoint_ns3->ns3_node_; + ns3::NodeContainer nodes = {access_point_ns3_node}; + std::vector hosts_netpoints = {access_point_netpoint_ns3}; + netDevices.Add(wifi.Install(wifiPhy, wifiMac,access_point_ns3_node)); + + wifiMac.SetType ("ns3::StaWifiMac", + "Ssid", ns3::SsidValue(ssid), + "ActiveProbing", ns3::BooleanValue(false)); + + NetPointNs3* station_netpoint_ns3 = nullptr; + ns3::Ptr station_ns3_node = nullptr; + const char* distance; + for (auto station_host : wifizone->get_all_hosts()) { + station_netpoint_ns3 = station_host->get_netpoint()->extension(); + if (station_netpoint_ns3 == access_point_netpoint_ns3) + continue; + hosts_netpoints.push_back(station_netpoint_ns3); + distance = station_host->get_property("wifi_distance"); + positionAllocS->Add(ns3::Vector(distance ? atof(distance) : 10.0, 0, 0)); + station_ns3_node = station_netpoint_ns3->ns3_node_; + nodes.Add(station_ns3_node); + netDevices.Add(wifi.Install(wifiPhy, wifiMac, station_ns3_node)); + } + + ns3::Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue(40)); + + mobility.SetPositionAllocator(positionAllocS); + mobility.Install(nodes); + + ns3::Ipv4AddressHelper address; + std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links); + address.SetBase(addr.c_str(), "255.255.0.0"); + XBT_DEBUG("\tInterface stack '%s'", addr.c_str()); + ns3::Ipv4InterfaceContainer addresses = address.Assign(netDevices); + for (int i = 0; i < hosts_netpoints.size(); i++) { + hosts_netpoints[i]->ipv4_address_ = transformIpv4Address(addresses.GetAddress(i)); + } + + if (number_of_links == 255) { + xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255"); + number_of_links = 1; + number_of_networks++; + } else { + number_of_links++; + } +} + static void clusterCreation_cb(simgrid::kernel::routing::ClusterCreationArgs const& cluster) { ns3::NodeContainer Nodes; @@ -271,6 +347,7 @@ NetworkNS3Model::NetworkNS3Model() : NetworkModel(Model::UpdateAlgo::FULL) }); routing::on_cluster_creation.connect(&clusterCreation_cb); s4u::NetZone::on_route_creation.connect(&routeCreation_cb); + s4u::NetZone::on_seal.connect(&zoneCreation_cb); } LinkImpl* NetworkNS3Model::create_link(const std::string& name, const std::vector& bandwidths, double latency, @@ -460,21 +537,6 @@ void LinkNS3::set_latency_profile(profile::Profile*) NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* src, s4u::Host* dst) : NetworkAction(model, *src, *dst, totalBytes, false) { - - // ns-3 fails when src = dst, so avoid the problem by considering that communications are infinitely fast on the - // loopback that does not exists - if (src == dst) { - static bool warned = false; - if (not warned) { - XBT_WARN("Sending from an host %s to itself is not supported by ns-3. Every such communication finishes " - "immediately upon startup.", - src->get_cname()); - warned = true; - } - finish(Action::State::FINISHED); - return; - } - // If there is no other started actions, we need to move NS-3 forward to be sync with SimGrid if (model->get_started_action_set()->size()==1){ while(double_positive(surf_get_clock() - ns3::Simulator::Now().GetSeconds(), sg_surf_precision)){ @@ -618,6 +680,7 @@ void ns3_add_direct_route(simgrid::kernel::routing::NetPoint* src, simgrid::kern std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links); address.SetBase(addr.c_str(), "255.255.0.0"); XBT_DEBUG("\tInterface stack '%s'", addr.c_str()); + auto addresses = address.Assign(netA); host_src->ipv4_address_ = transformIpv4Address(addresses.GetAddress(0)); -- 2.20.1