+
+}
+}
+
+void ns3_simulator(double maxSeconds)
+{
+ if (maxSeconds > 0.0) // If there is a maximum amount of time to run
+ ns3::Simulator::Stop(ns3::Seconds(maxSeconds));
+ XBT_DEBUG("Start simulator for at most %fs (current time: %f)", maxSeconds, surf_get_clock());
+ ns3::Simulator::Run ();
+}
+
+void ns3_create_flow(simgrid::s4u::Host* src, simgrid::s4u::Host* dst, double startTime, u_int32_t TotalBytes,
+ simgrid::surf::NetworkNS3Action* action)
+{
+ int node1 = src->pimpl_netpoint->extension<NetPointNs3>()->node_num;
+ int node2 = dst->pimpl_netpoint->extension<NetPointNs3>()->node_num;
+
+ ns3::Ptr<ns3::Node> src_node = nodes.Get(node1);
+ ns3::Ptr<ns3::Node> dst_node = nodes.Get(node2);
+
+ char* addr = IPV4addr.at(node2);
+
+ XBT_DEBUG("ns3_create_flow %d Bytes from %d to %d with Interface %s",TotalBytes, node1, node2,addr);
+ ns3::PacketSinkHelper sink("ns3::TcpSocketFactory", ns3::InetSocketAddress (ns3::Ipv4Address::GetAny(), port_number));
+ sink.Install (dst_node);
+
+ ns3::Ptr<ns3::Socket> sock = ns3::Socket::CreateSocket (src_node, ns3::TcpSocketFactory::GetTypeId());
+
+ xbt_dict_set(flowFromSock, transformSocketPtr(sock), new SgFlow(TotalBytes, action), nullptr);
+
+ sock->Bind(ns3::InetSocketAddress(port_number));
+ XBT_DEBUG("Create flow starting to %fs + %fs = %fs",
+ startTime-ns3::Simulator::Now().GetSeconds(), ns3::Simulator::Now().GetSeconds(), startTime);
+
+ ns3::Simulator::Schedule (ns3::Seconds(startTime-ns3::Simulator::Now().GetSeconds()),
+ &StartFlow, sock, addr, port_number);
+
+ port_number++;
+ xbt_assert(port_number <= 65000, "Too many connections! Port number is saturated.");
+}
+
+// initialize the NS3 interface and environment
+void ns3_initialize(const char* TcpProtocol){
+// tcpModel are:
+// "ns3::TcpNewReno"
+// "ns3::TcpReno"
+// "ns3::TcpTahoe"
+
+ ns3::Config::SetDefault ("ns3::TcpSocket::SegmentSize", ns3::UintegerValue (1024)); // 1024-byte packet for easier reading
+ ns3::Config::SetDefault ("ns3::TcpSocket::DelAckCount", ns3::UintegerValue (1));
+
+ if (!strcmp(TcpProtocol,"default"))
+ return;
+
+ if (!strcmp(TcpProtocol,"Reno")) {
+ XBT_INFO("Switching Tcp protocol to '%s'",TcpProtocol);
+ ns3::Config::SetDefault ("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::TcpReno"));
+ return;
+ }
+ if (!strcmp(TcpProtocol,"NewReno")) {
+ XBT_INFO("Switching Tcp protocol to '%s'",TcpProtocol);
+ ns3::Config::SetDefault ("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::TcpNewReno"));
+ return;
+ }
+ if(!strcmp(TcpProtocol,"Tahoe")){
+ XBT_INFO("Switching Tcp protocol to '%s'",TcpProtocol);
+ ns3::Config::SetDefault ("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::TcpTahoe"));
+ return;
+ }
+
+ xbt_die("The ns3/TcpModel must be : NewReno or Reno or Tahoe");
+}
+
+void ns3_add_cluster(const char* id, char* bw, char* lat)
+{
+ ns3::NodeContainer Nodes;
+
+ for (unsigned int i = number_of_clusters_nodes; i < Cluster_nodes.GetN(); i++) {
+ Nodes.Add(Cluster_nodes.Get(i));
+ XBT_DEBUG("Add node %d to cluster",i);
+ }
+ number_of_clusters_nodes = Cluster_nodes.GetN();
+
+ XBT_DEBUG("Add router %d to cluster",nodes.GetN()-Nodes.GetN()-1);
+ Nodes.Add(nodes.Get(nodes.GetN()-Nodes.GetN()-1));
+
+ xbt_assert(Nodes.GetN() <= 65000, "Cluster with NS3 is limited to 65000 nodes");
+ ns3::CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", ns3::StringValue (bw));
+ csma.SetChannelAttribute ("Delay", ns3::StringValue (lat));
+ ns3::NetDeviceContainer devices = csma.Install (Nodes);
+ XBT_DEBUG("Create CSMA");
+
+ char * adr = bprintf("%d.%d.0.0",number_of_networks,number_of_links);
+ XBT_DEBUG("Assign IP Addresses %s to CSMA.",adr);
+ ns3::Ipv4AddressHelper ipv4;
+ ipv4.SetBase (adr, "255.255.0.0");
+ free(adr);
+ interfaces.Add(ipv4.Assign (devices));
+
+ 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++;
+ }
+ XBT_DEBUG("Number of nodes in Cluster_nodes: %d",Cluster_nodes.GetN());
+}
+
+static char* transformIpv4Address (ns3::Ipv4Address from){
+ std::stringstream sstream;
+ sstream << from ;
+ std::string s = sstream.str();
+ return bprintf("%s",s.c_str());
+}
+
+void ns3_add_link(int src, int dst, char *bw, char *lat)
+{
+ ns3::PointToPointHelper pointToPoint;
+
+ ns3::NetDeviceContainer netA;
+ ns3::Ipv4AddressHelper address;
+
+ ns3::Ptr<ns3::Node> a = nodes.Get(src);
+ ns3::Ptr<ns3::Node> b = nodes.Get(dst);
+
+ XBT_DEBUG("\tAdd PTP from %d to %d bw:'%s' lat:'%s'",src,dst,bw,lat);
+ pointToPoint.SetDeviceAttribute ("DataRate", ns3::StringValue (bw));
+ pointToPoint.SetChannelAttribute ("Delay", ns3::StringValue (lat));
+
+ netA.Add(pointToPoint.Install (a, b));
+
+ char * adr = bprintf("%d.%d.0.0",number_of_networks,number_of_links);
+ address.SetBase (adr, "255.255.0.0");
+ XBT_DEBUG("\tInterface stack '%s'",adr);
+ free(adr);
+ interfaces.Add(address.Assign (netA));
+
+ if (IPV4addr.size() <= (unsigned)src)
+ IPV4addr.resize(src + 1, nullptr);
+ IPV4addr.at(src) = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 2));
+
+ if (IPV4addr.size() <= (unsigned)dst)
+ IPV4addr.resize(dst + 1, nullptr);
+ IPV4addr.at(dst) = 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++;
+ }
+}