Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid
authoragougeon <adrien.gougeon@ens-rennes.fr>
Sun, 22 Nov 2020 15:20:30 +0000 (16:20 +0100)
committeragougeon <adrien.gougeon@ens-rennes.fr>
Sun, 22 Nov 2020 15:20:30 +0000 (16:20 +0100)
12 files changed:
MANIFEST.in
docs/source/ns3.rst
examples/platforms/wifi_ns3.xml [new file with mode: 0644]
examples/s4u/CMakeLists.txt
examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.cpp [new file with mode: 0644]
examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.tesh [new file with mode: 0644]
include/simgrid/kernel/routing/WifiZone.hpp
src/kernel/routing/RoutedZone.cpp
src/kernel/routing/WifiZone.cpp
src/surf/network_ns3.cpp
src/surf/ns3/ns3_simulator.hpp
tools/cmake/DefinePackages.cmake

index 823c901..0c9c04c 100644 (file)
@@ -473,6 +473,8 @@ include examples/s4u/mc-electric-fence/s4u-mc-electric-fence.cpp
 include examples/s4u/mc-electric-fence/s4u-mc-electric-fence.tesh
 include examples/s4u/mc-failing-assert/s4u-mc-failing-assert.cpp
 include examples/s4u/mc-failing-assert/s4u-mc-failing-assert.tesh
+include examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.cpp
+include examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.tesh
 include examples/s4u/network-ns3/3hosts_2links_d.xml
 include examples/s4u/network-ns3/3links-timer_d.xml
 include examples/s4u/network-ns3/3links_d.xml
@@ -1971,6 +1973,7 @@ include examples/platforms/two_peers.xml
 include examples/platforms/vivaldi.xml
 include examples/platforms/wifi.xml
 include examples/platforms/wifi_energy.xml
+include examples/platforms/wifi_ns3.xml
 include examples/python/CMakeLists.txt
 include examples/python/actor-create/actor-create_d.xml
 include examples/python/actor-lifetime/actor-lifetime_d.xml
index e27de74..a4b39fb 100644 (file)
@@ -139,74 +139,118 @@ to see which ones are used in our regression tests.
 WiFi platforms
 --------------
 
-In SimGrid, WiFi networks are modeled as regular links with a specific
-attribute, and these links are then added to routes between hosts. The main
-difference When using ns-3 WiFi networks is that the network performance is not
-given by the link bandwidth and latency but by the access point WiFi
-characteristics, and the distance between the access point and the hosts (called
-station in the WiFi world).
-
-So, to declare a new WiFi network, simply declare a link with the ``WiFi``
-sharing policy as you would do in a pure SimGrid simulation (you must still
-provide the ``bandwidth`` and ``latency`` attributes even if they are ignored,
-because they are mandatory to the SimGrid XML parser).
+In SimGrid, WiFi networks are modeled with WiFi zones, where a zone contains 
+the access point of the WiFi network and the hosts connected to it (called 
+station in the WiFi world). Links inside WiFi zones are modeled as regular 
+links with a specific attribute, and these links are then added to routes 
+between hosts. The main difference When using ns-3 WiFi networks is that 
+the network performance is not given by the link bandwidth and latency but 
+by the access point WiFi characteristics, and the distance between the access 
+point and the hosts.
+
+So, to declare a new WiFi network, simply declare a zone with the ``WIFI``
+routing.
 
 .. code-block:: xml
 
-        <link id="net0" bandwidth="0" latency="0" sharing_policy="WIFI"/>
+       <zone id="SSID_1" routing="WIFI">
 
-To declare that a given host is connected to this WiFi zone, use the
-``wifi_link`` property of that host. The property value must be the link id that
-you want to use as a WiFi zone. This is not needed when using pure SimGrid wifi,
-only when using ns-3 wifi, because the wifi performance is :ref:`configured <ns3_wifi_perf>`.
+Inside this zone you must declare which host or router will be the access point
+of the WiFi network.
 
 .. code-block:: xml
 
-   <host id="alice" speed="1Gf">
-     <prop id="wifi_link" value="net0"/>
-   </host>
+       <prop id="access_point" value="alice"/>
 
-To connect the station node to the access point node, simply create a route
-between them:
+Afterward simply declare the hosts and routers inside the WiFi network. Remember 
+that one must have the same name as declared in the property "access point".
 
 .. code-block:: xml
 
-   <route src="alice" dst="bob">
-     <link_ctn id="net0" />
-   </route>
+       <router id="alice" speed="1Gf"/>
+       <host id="STA0-0" speed="1Gf"/>
+       <host id="STA0-1" speed="1Gf"/> 
 
-.. _ns3_wifi_perf:
+Finally, close the WiFi zone.
+
+.. code-block:: xml
+
+       </zone>
+
+The WiFi zone may be connected to another zone using a traditional link and 
+a zoneRoute. Note that the connection between two zones is always wired.
+
+.. code-block:: xml
+
+       <link id="wireline" bandwidth="100Mbps" latency="2ms" sharing_policy="SHARED"/>
+
+       <zoneRoute src="SSID_1" dst="SSID_2" gw_src="alice" gw_dst="bob">
+           <link_ctn id="wireline"/>
+       </zoneRoute>
 
 WiFi network performance
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 The performance of a wifi network is controlled by 3 property that can be added
-to the a host connected to the wifi zone:
+to hosts connected to the wifi zone:
 
- * ``wifi_mcs`` (`Modulation and Coding Scheme <https://en.wikipedia.org/wiki/Link_adaptation>`_)
+ * ``mcs`` (`Modulation and Coding Scheme <https://en.wikipedia.org/wiki/Link_adaptation>`_)
    Roughly speaking, it defines the speed at which the access point is
    exchanging data with all stations. It depends on its model and configuration,
    and the possible values are listed for example on Wikipedia.
-   |br| By default, ``wifi_mcs=3``.
- * ``wifi_nss`` (Number of Spatial Streams, or `number of antennas <https://en.wikipedia.org/wiki/IEEE_802.11n-2009#Number_of_antennas>`_)
+   |br| By default, ``mcs=3``. 
+   It is a property of the WiFi zone.
+ * ``nss`` (Number of Spatial Streams, or `number of antennas <https://en.wikipedia.org/wiki/IEEE_802.11n-2009#Number_of_antennas>`_)
    defines the amount of simultaneous data streams that the AP can sustain.
    Not all value of MCS and NSS are valid nor compatible (cf. `802.11n standard <https://en.wikipedia.org/wiki/IEEE_802.11n-2009#Data_rates>`_).
-   |br| By default, ``wifi_nss=1``.
+   |br| By default, ``nss=1``.
+   It is a property of the WiFi zone.
  * ``wifi_distance`` is the distance from the station to the access point. Each
    station can have a specific value.
    |br| By default, ``wifi_distance=10``.
+   It is a property of stations of the WiFi network.
+
+Here is an example of a zone changing ``mcs`` and ``nss`` values.
+
+.. code-block:: xml
+
+       <zone id="SSID_1" routing="WIFI">
+           <prop id="access_point" value="alice"/>
+           <prop id="mcs" value="2"/>
+           <prop id="nss" value="2"/>
+       ...
+       </zone>
+
+Here is an example of a host changing ``wifi_distance`` value.
+
+.. code-block:: xml
+
+       <host id="STA0-0" speed="1Gf">
+           <prop id="wifi_distance" value="37"/>
+       </host>
+
+Random Number Generator
+=======================
 
-Here is an example of host changing all these values:
+It is possible to define a fixed or random seed to the ns3 random number 
+generator using the config tag.
 
 .. code-block:: xml
 
-   <host id="alice" speed="100.0Mf,50.0Mf,20.0Mf" pstate="0">
-     <prop id="wifi_link" value="net0"/>
-     <prop id="wifi_mcs" value="5"/>
-     <prop id="wifi_nss" value="2"/>
-     <prop id="wifi_distance" value="30" />
-   </host>
+       <?xml version='1.0'?><!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+       <platform version="4.1">
+           <config>
+                   <prop id = "network/model" value = "ns-3" />
+                   <prop id = "ns3/seed" value = "time" /> 
+           </config>
+       ... 
+       </platform>
+
+The first property defines that this platform will be used with the ns3 model.
+The second property defines the seed that will be used. Defined to ``time`` 
+it will use a random seed, defined to a number it will use this number as 
+the seed.
 
 Limitations
 ===========
diff --git a/examples/platforms/wifi_ns3.xml b/examples/platforms/wifi_ns3.xml
new file mode 100644 (file)
index 0000000..b737608
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version='1.0'?><!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+       <config>
+               <prop id = "network/model" value = "ns-3" />
+       </config>
+       <zone id="world" routing="Floyd">
+
+               <zone id="SSID_1" routing="WIFI">
+                       <prop id="access_point" value="alice"/>
+                       <prop id="mcs" value="2"/> <!-- Optionnal: default = 3 -->
+                       <prop id="nss" value="2"/> <!-- Optionnal: default = 1 -->
+
+                       <host id="alice" speed="1Gf"/>
+
+                       <host id="STA0-0" speed="1Gf">
+                               <prop id="wifi_distance" value="37"/> <!-- Optionnal: default = 10 -->
+                       </host>
+                       <host id="STA0-1" speed="1Gf"/> 
+               </zone>
+
+               <zone id="SSID_2" routing="WIFI">
+                       <prop id="access_point" value="bob"/>
+
+                       <router id="bob"/>
+
+                       <host id="STA1-0" speed="1Gf"/>
+                       <host id="STA1-1" speed="1Gf"/>
+                       <host id="STA1-2" speed="1Gf"/>
+               </zone>
+
+               <link id="wireline" bandwidth="100Mbps" latency="2ms" sharing_policy="SHARED"/>
+
+               <zoneRoute src="SSID_1" dst="SSID_2" gw_src="alice" gw_dst="bob">
+                       <link_ctn id="wireline"/>
+               </zoneRoute>
+       </zone>
+</platform>
+
index c449b48..f3d0c50 100644 (file)
@@ -55,6 +55,10 @@ if(SIMGRID_HAVE_NS3)
   target_link_libraries(s4u-network-ns3 simgrid)
   set_target_properties(s4u-network-ns3  PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/network-ns3)
   add_dependencies(tests s4u-network-ns3)
+  add_executable       (s4u-network-ns3-wifi EXCLUDE_FROM_ALL network-ns3-wifi/s4u-network-ns3-wifi.cpp)
+  target_link_libraries(s4u-network-ns3-wifi simgrid)
+  set_target_properties(s4u-network-ns3-wifi  PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/network-ns3-wifi)
+  add_dependencies(tests s4u-network-ns3-wifi)
 endif()
 
 # Deal with each example
@@ -183,6 +187,11 @@ if(SIMGRID_HAVE_NS3)
                                      --setenv bindir=${CMAKE_BINARY_DIR}/examples/s4u
                                      --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
                                      ${CMAKE_HOME_DIRECTORY}/examples/s4u/network-ns3/s4u-network-ns3.tesh)
+  ADD_TESH_FACTORIES(s4u-network-ns3-wifi "thread;ucontext;raw;boost"
+                                     --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/s4u
+                                     --setenv bindir=${CMAKE_BINARY_DIR}/examples/s4u
+                                     --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
+                                     ${CMAKE_HOME_DIRECTORY}/examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.tesh)
 endif()
 # Examples not accepting factories
 ##################################
@@ -210,10 +219,12 @@ endif()
 # Add all extra files to the archive
 ####################################
 
-set(examples_src  ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/s4u-network-ns3.cpp              PARENT_SCOPE)
+set(examples_src  ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/s4u-network-ns3.cpp
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3-wifi/s4u-network-ns3-wifi.cpp              PARENT_SCOPE)
 set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/app-pingpong/simix-breakpoint.tesh
                                   ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/s4u-network-ns3.tesh             PARENT_SCOPE)
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/s4u-network-ns3.tesh
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3-wifi/s4u-network-ns3-wifi.tesh             PARENT_SCOPE)
 set(xml_files     ${xml_files}    ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-actor-create_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/actor-lifetime/s4u-actor-lifetime_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/actor-yield/s4u-actor-yield_d.xml
diff --git a/examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.cpp b/examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.cpp
new file mode 100644 (file)
index 0000000..be1342d
--- /dev/null
@@ -0,0 +1,69 @@
+/* Copyright (c) 2007-2020. The SimGrid Team. LEVEL_ALL rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "simgrid/s4u.hpp"
+#include <iostream>
+#include <iomanip>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(ns3_wifi_example, "Messages specific for this s4u example");
+
+class Message
+{
+    public:
+    std::string sender;
+    int size;
+
+    Message(std::string sender_, int size_) : sender(sender_), size(size_){}
+};
+
+static void sender(std::string mailbox, double msg_size, unsigned sleep_time)
+{
+  simgrid::s4u::this_actor::sleep_for(sleep_time);
+  simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name(mailbox);
+  Message* msg = new Message(simgrid::s4u::this_actor::get_host()->get_name(), msg_size);
+  mbox->put(msg, msg_size);
+}
+
+static void receiver(std::string mailbox)
+{
+  simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name(mailbox);
+  Message* msg = (Message*) mbox->get();
+  XBT_INFO("[%s] %s received %d bytes from %s",
+           mailbox.c_str(),
+           simgrid::s4u::this_actor::get_host()->get_name().c_str(),
+           msg->size,
+           msg->sender.c_str());
+}
+
+int main(int argc, char* argv[])
+{
+  simgrid::s4u::Engine e(&argc, argv);
+
+  e.load_platform(argv[1]);
+  double msg_size = 1E5;
+
+  /* Communication between STA in the same wifi zone */    
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA0-0"), sender, "1", msg_size, 10);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA0-1"), receiver, "1");
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA0-1"), sender, "2", msg_size, 20);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA0-0"), receiver, "2");
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA1-1"), sender, "3", msg_size, 30);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA1-2"), receiver, "3");
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA1-2"), sender, "4", msg_size, 40);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA1-1"), receiver, "4");
+
+  /* Communication between STA of different wifi zones */
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA0-0"), sender, "5", msg_size, 50);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA1-0"), receiver, "5");
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA1-0"), sender, "6", msg_size, 60);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA0-0"), receiver, "6");
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA0-1"), sender, "7", msg_size, 70);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA1-2"), receiver, "7");
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name("STA1-2"), sender, "8", msg_size, 80);
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("STA0-1"), receiver, "8");
+
+  e.run();
+  return 0;
+}
diff --git a/examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.tesh b/examples/s4u/network-ns3-wifi/s4u-network-ns3-wifi.tesh
new file mode 100644 (file)
index 0000000..df2170d
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/network-ns3-wifi/s4u-network-ns3-wifi ${platfdir}/wifi_ns3.xml "--log=root.fmt:[%h:%P(%i)]%e[%c/%p]%e%m%n"
+> [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3'
+> [STA0-1:receiver(2)] [ns3_wifi_example/INFO] [1] STA0-1 received 100000 bytes from STA0-0
+> [STA0-0:receiver(4)] [ns3_wifi_example/INFO] [2] STA0-0 received 100000 bytes from STA0-1
+> [STA1-2:receiver(6)] [ns3_wifi_example/INFO] [3] STA1-2 received 100000 bytes from STA1-1
+> [STA1-1:receiver(8)] [ns3_wifi_example/INFO] [4] STA1-1 received 100000 bytes from STA1-2
+> [STA1-0:receiver(10)] [ns3_wifi_example/INFO] [5] STA1-0 received 100000 bytes from STA0-0
+> [STA0-0:receiver(12)] [ns3_wifi_example/INFO] [6] STA0-0 received 100000 bytes from STA1-0
+> [STA1-2:receiver(14)] [ns3_wifi_example/INFO] [7] STA1-2 received 100000 bytes from STA0-1
+> [STA0-1:receiver(16)] [ns3_wifi_example/INFO] [8] STA0-1 received 100000 bytes from STA1-2
index da6027d..adc05ed 100644 (file)
@@ -30,6 +30,7 @@ public:
   s4u::Link* create_link(const std::string& name, const std::vector<double>& bandwidths, double latency,
                          s4u::Link::SharingPolicy policy,
                          const std::unordered_map<std::string, std::string>* 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)
index 2823682..f78403b 100644 (file)
@@ -172,6 +172,7 @@ void RoutedZone::add_route_check_params(NetPoint* src, NetPoint* dst, NetPoint*
     xbt_assert(not dst->is_netzone(),
                "When defining a route, dst cannot be a netzone such as '%s'. Did you meant to have a NetzoneRoute?",
                dstName);
+    s4u::NetZone::on_route_creation(symmetrical, src, dst, gw_src, gw_dst, link_list);
   } else {
     XBT_DEBUG("Load NetzoneRoute from %s@%s to %s@%s", srcName, gw_src->get_cname(), dstName, gw_dst->get_cname());
     xbt_assert(src->is_netzone(), "When defining a NetzoneRoute, src must be a netzone but '%s' is not", srcName);
@@ -190,9 +191,8 @@ void RoutedZone::add_route_check_params(NetPoint* src, NetPoint* dst, NetPoint*
                gw_dst->get_cname(), dstName);
     xbt_assert(not link_list.empty(), "Empty route (between %s@%s and %s@%s) forbidden.", srcName, gw_src->get_cname(),
                dstName, gw_dst->get_cname());
+    s4u::NetZone::on_route_creation(symmetrical,  gw_src, gw_dst, gw_src, gw_dst, link_list);
   }
-
-  s4u::NetZone::on_route_creation(symmetrical, src, dst, gw_src, gw_dst, link_list);
 }
 } // namespace routing
 } // namespace kernel
index 80f6116..b375032 100644 (file)
@@ -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());
index c5e0525..1751d3e 100644 (file)
@@ -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"
@@ -71,60 +72,88 @@ NetPointNs3::NetPointNs3() : ns3_node_(ns3::CreateObject<ns3::Node>(0))
   stack.Install(ns3_node_);
 }
 
-WifiZone::WifiZone(const std::string& name_, simgrid::s4u::Host* host_, ns3::Ptr<ns3::Node> ap_node_,
-                   ns3::Ptr<ns3::YansWifiChannel> channel_, int mcs_, int nss_, int network_, int link_)
-    : name(name_)
-    , host(host_)
-    , ap_node(ap_node_)
-    , channel(channel_)
-    , mcs(mcs_)
-    , nss(nss_)
-    , network(network_)
-    , link(link_)
-{
-  n_sta_nodes       = 0;
-  wifi_zones[name_] = this;
-}
+/*************
+ * Callbacks *
+ *************/
 
-bool WifiZone::is_ap(ns3::Ptr<ns3::Node> node)
-{
-  for (std::pair<std::string, WifiZone*> zone : wifi_zones)
-    if (zone.second->get_ap_node() == node)
-      return true;
-  return false;
-}
+static void zoneCreation_cb(simgrid::s4u::NetZone const& zone) {
+    simgrid::kernel::routing::WifiZone* wifizone = dynamic_cast<simgrid::kernel::routing::WifiZone*> (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));
 
-WifiZone* WifiZone::by_name(const std::string& name)
-{
-  WifiZone* zone;
-  try {
-    zone = wifi_zones.at(name);
-  } catch (const std::out_of_range& oor) {
-    return nullptr;
-  }
-  return zone;
-}
+    mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
+    ns3::Ptr<ns3::ListPositionAllocator> positionAllocS = ns3::CreateObject<ns3::ListPositionAllocator>();
+    positionAllocS->Add(ns3::Vector(0, 0, 255 * 100 * number_of_networks + 100 * number_of_links));
 
-std::unordered_map<std::string, WifiZone*> WifiZone::wifi_zones;
+    ns3::NetDeviceContainer netDevices;
+    NetPointNs3* access_point_netpoint_ns3 = wifizone->get_access_point()->extension<NetPointNs3>();
 
-static void initialize_ns3_wifi()
-{
-  wifi.SetStandard(ns3::WIFI_PHY_STANDARD_80211n_5GHZ);
+    ns3::Ptr<ns3::Node> access_point_ns3_node = access_point_netpoint_ns3->ns3_node_;
+    ns3::NodeContainer nodes = {access_point_ns3_node};
+    std::vector<NetPointNs3*> hosts_netpoints = {access_point_netpoint_ns3};
+    netDevices.Add(wifi.Install(wifiPhy, wifiMac,access_point_ns3_node));
 
-  for (auto host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
-    const char* wifi_link = host->get_property("wifi_link");
-    const char* wifi_mcs  = host->get_property("wifi_mcs");
-    const char* wifi_nss  = host->get_property("wifi_nss");
+    wifiMac.SetType ("ns3::StaWifiMac",
+                     "Ssid", ns3::SsidValue(ssid),
+                     "ActiveProbing", ns3::BooleanValue(false));
 
-    if (wifi_link)
-      new WifiZone(wifi_link, host, host->get_netpoint()->extension<NetPointNs3>()->ns3_node_, wifiChannel.Create(),
-                   wifi_mcs ? atoi(wifi_mcs) : 3, wifi_nss ? atoi(wifi_nss) : 1, 0, 0);
-  }
-}
+    NetPointNs3* station_netpoint_ns3 = nullptr;
+    ns3::Ptr<ns3::Node> station_ns3_node = nullptr;
+    double distance;
+    double angle = 0;
+    int nb_stations = wifizone->get_all_hosts().size() - 1;
+    double step = 2 * M_PI / nb_stations;
+    for (auto station_host : wifizone->get_all_hosts()) {
+        station_netpoint_ns3 = station_host->get_netpoint()->extension<NetPointNs3>();
+        if (station_netpoint_ns3 == access_point_netpoint_ns3)
+            continue;
+        hosts_netpoints.push_back(station_netpoint_ns3);
+        distance = station_host->get_property("wifi_distance") ? atof(station_host->get_property("wifi_distance")) : 10.0;
+        positionAllocS->Add(ns3::Vector(distance * std::cos(angle), distance * std::sin(angle), 255 * 100 * number_of_networks + 100 * number_of_links));
+        angle += step;
+        station_ns3_node = station_netpoint_ns3->ns3_node_;
+        nodes.Add(station_ns3_node);
+        netDevices.Add(wifi.Install(wifiPhy, wifiMac, station_ns3_node));
+    }
 
-/*************
- * Callbacks *
- *************/
+    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)
 {
@@ -271,6 +300,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<double>& bandwidths, double latency,
@@ -384,57 +414,6 @@ LinkNS3::LinkNS3(NetworkNS3Model* model, const std::string& name, double bandwid
   bandwidth_.peak = bandwidth;
   latency_.peak   = latency;
 
-  /* If wifi, create the wifizone now. If not, don't do anything: the links will be created in routeCreate_cb */
-
-  if (policy == simgrid::s4u::Link::SharingPolicy::WIFI) {
-    static bool wifi_init = false;
-    if (!wifi_init) {
-      initialize_ns3_wifi();
-      wifi_init = true;
-    }
-
-    ns3::NetDeviceContainer netA;
-    WifiZone* zone = WifiZone::by_name(name);
-    xbt_assert(zone != nullptr, "Link name '%s' does not match the 'wifi_link' property of a host.", name.c_str());
-    auto* netpoint_ns3 = zone->get_host()->get_netpoint()->extension<NetPointNs3>();
-
-    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::ApWifiMac",
-                    "Ssid", ns3::SsidValue(name));
-
-    netA.Add(wifi.Install(wifiPhy, wifiMac, zone->get_ap_node()));
-
-    ns3::Ptr<ns3::ListPositionAllocator> positionAllocS = ns3::CreateObject<ns3::ListPositionAllocator>();
-    positionAllocS->Add(ns3::Vector(0, 0, 0));
-    mobility.SetPositionAllocator(positionAllocS);
-    mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
-    mobility.Install(zone->get_ap_node());
-
-    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());
-    auto addresses = address.Assign(netA);
-    zone->set_network(number_of_networks);
-    zone->set_link(number_of_links);
-
-    netpoint_ns3->ipv4_address_ = transformIpv4Address(addresses.GetAddress(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++;
-    }
-  }
   s4u::Link::on_creation(*this->get_iface());
 }
 
@@ -561,46 +540,7 @@ void ns3_add_direct_route(simgrid::kernel::routing::NetPoint* src, simgrid::kern
   xbt_assert(host_dst != nullptr, "Network element %s does not seem to be ns-3-ready", dst->get_cname());
 
   if (policy == simgrid::s4u::Link::SharingPolicy::WIFI) {
-    auto a = host_src->ns3_node_;
-    auto b = host_dst->ns3_node_;
-    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));
-
-    simgrid::kernel::routing::NetPoint* sta_netpoint = WifiZone::is_ap(host_src->ns3_node_) ? dst : src;
-    const char* wifi_distance    = simgrid::s4u::Host::by_name(sta_netpoint->get_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());
-    auto addresses          = address.Assign(netA);
-    host_dst->ipv4_address_ = transformIpv4Address(addresses.GetAddress(1));
+      xbt_die("The wifi sharing policy is not supported for links. You want to use a wifi zone (see documentation).");
   } else {
     ns3::PointToPointHelper pointToPoint;
 
@@ -614,6 +554,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));
index 8c8f740..b060756 100644 (file)
@@ -51,39 +51,4 @@ static inline std::string transform_socket_ptr(ns3::Ptr<ns3::Socket> local_socke
   return sstream.str();
 }
 
-class XBT_PRIVATE WifiZone {
-public:
-  WifiZone(const std::string& name_, simgrid::s4u::Host* host_, ns3::Ptr<ns3::Node> ap_node_,
-           ns3::Ptr<ns3::YansWifiChannel> channel_, int mcs_, int nss_, int network_, int link_);
-
-  const char* get_cname() { return name.c_str(); }
-  simgrid::s4u::Host* get_host() { return host; }
-  ns3::Ptr<ns3::Node> get_ap_node() { return ap_node; }
-  ns3::Ptr<ns3::YansWifiChannel> get_channel() { return channel; }
-  int get_mcs() { return mcs; }
-  int get_nss() { return nss; }
-  int get_network() { return network; }
-  int get_link() { return link; }
-  int get_n_sta_nodes() { return n_sta_nodes; }
-
-  void set_network(int network_) { network = network_; }
-  void set_link(int link_) { link = link_; }
-  void add_sta_node() { n_sta_nodes++; }
-
-  static bool is_ap(ns3::Ptr<ns3::Node> node);
-  static WifiZone* by_name(const std::string& name);
-
-private:
-  std::string name;
-  simgrid::s4u::Host* host;
-  ns3::Ptr<ns3::Node> ap_node;
-  ns3::Ptr<ns3::YansWifiChannel> channel;
-  int mcs;
-  int nss;
-  int network;
-  int link;
-  int n_sta_nodes = 0;
-  static std::unordered_map<std::string, WifiZone*> wifi_zones;
-};
-
 #endif
index 1062af7..aba92ee 100644 (file)
@@ -1216,6 +1216,7 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/two_peers.xml
   examples/platforms/vivaldi.xml
   examples/platforms/wifi_energy.xml
+  examples/platforms/wifi_ns3.xml
   examples/platforms/wifi.xml
   )