+
+static std::string transformIpv4Address(ns3::Ipv4Address from)
+{
+ std::stringstream sstream;
+ sstream << from ;
+ return sstream.str();
+}
+
+void ns3_add_direct_route(NetPointNs3* src, NetPointNs3* dst, double bw, double lat, std::string link_name,
+ simgrid::s4u::Link::SharingPolicy policy)
+{
+ ns3::Ipv4AddressHelper address;
+ ns3::NetDeviceContainer netA;
+
+ int srcNum = src->node_num;
+ int dstNum = dst->node_num;
+
+ ns3::Ptr<ns3::Node> a = src->ns3_node_;
+ ns3::Ptr<ns3::Node> b = dst->ns3_node_;
+
+ if (policy == simgrid::s4u::Link::SharingPolicy::WIFI) {
+ xbt_assert(WifiZone::is_ap(a) != WifiZone::is_ap(b), "A wifi route can only exist between an access point node and a station node.");
+
+ ns3::Ptr<ns3::Node> apNode = WifiZone::is_ap(a) ? a : b;
+ ns3::Ptr<ns3::Node> staNode = apNode == a ? b : a;
+
+ WifiZone* zone = WifiZone::by_name(link_name);
+
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
+ "ControlMode", ns3::StringValue ("HtMcs0"),
+ "DataMode", ns3::StringValue ("HtMcs" + std::to_string(zone->get_mcs())));
+
+ wifiPhy.SetChannel (zone->get_channel());
+ wifiPhy.Set("Antennas", ns3::UintegerValue(zone->get_nss()));
+ wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
+ wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
+
+ wifiMac.SetType ("ns3::StaWifiMac",
+ "Ssid", ns3::SsidValue(link_name),
+ "ActiveProbing", ns3::BooleanValue(false));
+
+ netA.Add(wifi.Install (wifiPhy, wifiMac, staNode));
+
+ ns3::Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue (40));
+
+ NetPointNs3* sta_netpointNs3 = WifiZone::is_ap(src->ns3_node_) ? dst : src;
+ const char* wifi_distance = simgrid::s4u::Host::by_name(sta_netpointNs3->name_)->get_property("wifi_distance");
+ ns3::Ptr<ns3::ListPositionAllocator> positionAllocS = ns3::CreateObject<ns3::ListPositionAllocator> ();
+ positionAllocS->Add(ns3::Vector( wifi_distance ? atof(wifi_distance) : 10.0 , 0, 0));
+ mobility.SetPositionAllocator(positionAllocS);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install(staNode);
+
+ std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", zone->get_network(), zone->get_link());
+ address.SetBase(addr.c_str(), "255.255.0.0", ("0.0.0." + std::to_string(zone->get_n_sta_nodes() + 2)).c_str());
+ zone->add_sta_node();
+ XBT_DEBUG("\tInterface stack '%s'", addr.c_str());
+ interfaces.Add(address.Assign (netA));
+ if (IPV4addr.size() <= (unsigned)dstNum)
+ IPV4addr.resize(dstNum + 1);
+ IPV4addr[dstNum] = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 1));
+ } else {
+ ns3::PointToPointHelper pointToPoint;
+ XBT_DEBUG("\tAdd PTP from %d to %d bw:'%f Bps' lat:'%fs'", srcNum, dstNum, bw, lat);
+ pointToPoint.SetDeviceAttribute("DataRate",
+ ns3::DataRateValue(ns3::DataRate(bw * 8))); // ns-3 takes bps, but we provide Bps
+ pointToPoint.SetChannelAttribute("Delay", ns3::TimeValue(ns3::Seconds(lat)));
+
+ netA.Add(pointToPoint.Install(a, b));
+
+ 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());
+ interfaces.Add(address.Assign (netA));
+
+ if (IPV4addr.size() <= (unsigned)srcNum)
+ IPV4addr.resize(srcNum + 1);
+ IPV4addr[srcNum] = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 2));
+
+ if (IPV4addr.size() <= (unsigned)dstNum)
+ IPV4addr.resize(dstNum + 1);
+ IPV4addr[dstNum] = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 1));
+
+ 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++;
+ }
+ }