Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Implementation of NS3.
authorNavarrop <Pierre.Navarro@imag.fr>
Thu, 28 Jul 2011 15:48:39 +0000 (17:48 +0200)
committerNavarrop <Pierre.Navarro@imag.fr>
Thu, 28 Jul 2011 15:48:39 +0000 (17:48 +0200)
Add an example for ns3.
Add many functions for ns3.

buildtools/Cmake/MakeExe.cmake
examples/msg/ns3/CMakeLists.txt [new file with mode: 0644]
examples/msg/ns3/ns3.c [new file with mode: 0644]
examples/msg/ns3/onelink-d.xml [new file with mode: 0644]
examples/msg/ns3/onelink-p.xml [new file with mode: 0644]
src/surf/network_ns3.c
src/surf/ns3/ns3_interface.cc
src/surf/ns3/ns3_interface.h
src/surf/ns3/ns3_simulator.cc
src/surf/ns3/ns3_simulator.h
src/surf/surf.c

index 3048580..ed00683 100644 (file)
@@ -69,6 +69,10 @@ if(HAVE_GTNETS)
        add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/gtnets)\r
 endif(HAVE_GTNETS)\r
 \r
+if(HAVE_NS3)\r
+       add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/ns3)\r
+endif(HAVE_NS3)\r
+\r
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/amok/bandwidth)\r
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/amok/saturate)\r
 \r
diff --git a/examples/msg/ns3/CMakeLists.txt b/examples/msg/ns3/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1111655
--- /dev/null
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 2.6)
+
+set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_executable(ns3 "ns3.c")
+
+### Add definitions for compile
+target_link_libraries(ns3 simgrid m )
+
diff --git a/examples/msg/ns3/ns3.c b/examples/msg/ns3/ns3.c
new file mode 100644 (file)
index 0000000..a40a8d5
--- /dev/null
@@ -0,0 +1,210 @@
+/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include "msg/msg.h"
+#include "xbt/log.h"
+#include "xbt/asserts.h"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
+                             "Messages specific for this msg example");
+
+int master(int argc, char *argv[]);
+int slave(int argc, char *argv[]);
+int timer(int argc, char *argv[]);
+MSG_error_t test_all(const char *platform_file,
+                     const char *application_file);
+
+int timer_start = 1;
+
+typedef enum {
+  PORT_22 = 0,
+  MAX_CHANNEL
+} channel_t;
+
+//keep a pointer to all surf running tasks.
+#define NTASKS 1500
+int bool_printed = 0;
+double start_time, end_time, elapsed_time;
+double gl_data_size[NTASKS];
+m_task_t gl_task_array[NTASKS];
+const char *slavenames[NTASKS];
+const char *masternames[NTASKS];
+int gl_task_array_id = 0;
+int count_finished = 0;
+
+#define FINALIZE ((void*)221297)        /* a magic number to tell people to stop working */
+
+/** master */
+int master(int argc, char *argv[])
+{
+  char *slavename = NULL;
+  double task_comm_size = 0;
+  m_task_t todo;
+  char id_alias[10];
+  //unique id to control statistics
+  int id = -1;
+
+  if (argc != 4) {
+    XBT_INFO("Strange number of arguments expected 3 got %d", argc - 1);
+  }
+
+  /* data size */
+  int read;
+  read = sscanf(argv[1], "%lg", &task_comm_size);
+  xbt_assert(read, "Invalid argument %s\n", argv[1]);
+
+  /* slave name */
+  slavename = argv[2];
+  id = atoi(argv[3]);
+  sprintf(id_alias, "flow_%d", id);
+  slavenames[id] = slavename;
+  TRACE_category(id_alias);
+
+  masternames[id] = MSG_host_get_name(MSG_host_self());
+
+  {                             /*  Task creation.  */
+    char sprintf_buffer[64] = "Task_0";
+    todo = MSG_task_create(sprintf_buffer, 100*task_comm_size, task_comm_size, NULL);
+    TRACE_msg_set_task_category(todo, id_alias);
+    //keep track of running tasks
+    gl_task_array[id] = todo;
+    gl_data_size[id] = task_comm_size;
+  }
+
+  {                             /* Process organisation */
+    MSG_get_host_by_name(slavename);
+  }
+
+  count_finished++;
+
+  /* time measurement */
+  sprintf(id_alias, "%d", id);
+  start_time = MSG_get_clock();
+  //MSG_task_execute(todo);
+  MSG_task_send(todo, id_alias);
+  end_time = MSG_get_clock();
+
+
+  return 0;
+}                               /* end_of_master */
+
+
+/** Timer function  */
+int timer(int argc, char *argv[])
+{
+  int sleep_time;
+  int first_sleep;
+
+  if (argc != 3) {
+    XBT_INFO("Strange number of arguments expected 2 got %d", argc - 1);
+  }
+
+  sscanf(argv[1], "%d", &first_sleep);
+  sscanf(argv[2], "%d", &sleep_time);
+
+  if(first_sleep){
+      MSG_process_sleep(first_sleep);
+  }
+
+  while(timer_start){
+      MSG_process_sleep(sleep_time);
+  }
+
+  return 0;
+}
+
+/** Receiver function  */
+int slave(int argc, char *argv[])
+{
+
+  m_task_t task = NULL;
+  int a = MSG_OK;
+  int id = 0;
+  char id_alias[10];
+
+  if (argc != 2) {
+    XBT_INFO("Strange number of arguments expected 1 got %d", argc - 1);
+  }
+
+  id = atoi(argv[1]);
+  sprintf(id_alias, "%d", id);
+
+  a = MSG_task_receive(&(task), id_alias);
+
+  count_finished--;
+  if(count_finished == 0){
+      timer_start = 0;
+  }
+
+
+
+  if (a != MSG_OK) {
+    XBT_INFO("Hey?! What's up?");
+    xbt_die("Unexpected behavior.");
+  }
+
+  elapsed_time = MSG_get_clock() - start_time;
+  
+  XBT_INFO("FLOW[%d] : Receive %.0f bytes from %s to %s",
+                 id,
+                 MSG_task_get_data_size(task),
+       masternames[id],
+       slavenames[id]);
+
+  MSG_task_destroy(task);
+
+  return 0;
+}                               /* end_of_slave */
+
+/** Test function */
+MSG_error_t test_all(const char *platform_file,
+                     const char *application_file)
+{
+  MSG_error_t res = MSG_OK;
+
+  /* MSG_config("workstation/model", "GTNETS"); */
+  /* MSG_config("workstation/model","KCCFLN05"); */
+  {                             /*  Simulation setting */
+    MSG_set_channel_number(MAX_CHANNEL);
+    MSG_create_environment(platform_file);
+  }
+
+  TRACE_declare_mark("endmark");
+
+  {                             /*   Application deployment */
+    MSG_function_register("master", master);
+    MSG_function_register("slave", slave);
+    MSG_function_register("timer", timer);
+
+    MSG_launch_application(application_file);
+  }
+  res = MSG_main();
+  return res;
+}                               /* end_of_test_all */
+
+/** Main function */
+int main(int argc, char *argv[])
+{
+  MSG_error_t res = MSG_OK;
+  bool_printed = 0;
+
+  MSG_global_init(&argc, argv);
+  if (argc < 3) {
+    printf("Usage: %s platform_file deployment_file\n", argv[0]);
+    exit(1);
+  }
+
+  res = test_all(argv[1], argv[2]);
+
+  MSG_clean();
+
+  if (res == MSG_OK)
+    return 0;
+  else
+    return 1;
+}                               /* end_of_main */
diff --git a/examples/msg/ns3/onelink-d.xml b/examples/msg/ns3/onelink-d.xml
new file mode 100644 (file)
index 0000000..b9a1cf4
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+<platform version="3">
+
+  <process host="S1" function="master">
+      <argument value="100"/>
+      <argument value="C1"/>
+      <argument value="1"/>
+  </process>
+
+  <process host="C1" function="slave">
+    <argument value="1"/>
+  </process>
+
+  <process host="S2" function="master">
+      <argument value="1000"/>
+      <argument value="C2"/>
+      <argument value="2"/>
+  </process>
+  
+  <process host="C2" function="slave">
+    <argument value="2"/>
+  </process>
+   
+   
+    <process host="S3" function="master">
+      <argument value="2000"/>
+      <argument value="C3"/>
+      <argument value="3"/>
+  </process>
+  
+  <process host="C3" function="slave">
+    <argument value="3"/>
+  </process>
+     
+</platform>
diff --git a/examples/msg/ns3/onelink-p.xml b/examples/msg/ns3/onelink-p.xml
new file mode 100644 (file)
index 0000000..b05e780
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version='1.0'?>
+ <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+ <platform version="3">
+ <AS  id="AS0"  routing="Full">
+   <host id="S1" power="1000000000"/>
+   <host id="C1" power="1000000000"/>
+   <host id="S2" power="1000000000"/>
+   <host id="C2" power="1000000000"/>
+   <host id="S3" power="1000000000"/>
+   <host id="C3" power="1000000000"/>
+   <link id="1" bandwidth="1000" latency="0.01"/>
+   <link id="2" bandwidth="1000" latency="0.01"/>
+   <link id="3" bandwidth="1000" latency="0.01"/>
+   <route src="S1" dst="C1">
+      <link_ctn id="1"/>
+   </route>
+   <route src="S2" dst="C2">
+      <link_ctn id="2"/>
+   </route>
+   <route src="S3" dst="C3">
+      <link_ctn id="3"/>
+   </route>
+  
+ </AS>
+ </platform>
\ No newline at end of file
index 50cf119..8e63b46 100644 (file)
@@ -18,6 +18,21 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_ns3, surf,
                                 "Logging specific to the SURF network NS3 module");
 
 extern routing_global_t global_routing;
+extern xbt_dict_t dict_socket;
+
+static double time_to_next_flow_completion = -1;
+
+static double ns3_share_resources(double min);
+static void ns3_update_actions_state(double now, double delta);
+static void finalize(void);
+static surf_action_t communicate(const char *src_name,
+                                 const char *dst_name, double size, double rate);
+static void action_suspend(surf_action_t action);
+static void action_resume(surf_action_t action);
+static int action_is_suspended(surf_action_t action);
+static int action_unref(surf_action_t action);
+
+xbt_dynar_t IPV4addr;
 
 static void replace_str(char *str, const char *orig, const char *rep)
 {
@@ -65,6 +80,8 @@ void parse_ns3_add_link(void)
 {
        XBT_DEBUG("NS3_ADD_LINK '%s'",A_surfxml_link_id);
 
+       if(!IPV4addr) IPV4addr = xbt_dynar_new(sizeof(char*),free);
+
        tmgr_trace_t bw_trace;
        tmgr_trace_t state_trace;
        tmgr_trace_t lat_trace;
@@ -234,44 +251,18 @@ static xbt_dynar_t ns3_get_route(const char *src, const char *dst)
 void parse_ns3_end_platform(void)
 {
        ns3_end_platform();
-
-         xbt_lib_cursor_t cursor = NULL;
-         char *name = NULL;
-         void **data = NULL;
-         XBT_DEBUG("link_lib");
-         xbt_lib_foreach(link_lib, cursor, name, data) {
-                       XBT_DEBUG("\tSee link '%s'\t--> NS3_LEVEL %p",
-                                       name,
-                                       data[NS3_LINK_LEVEL]);
-         }
-         XBT_DEBUG(" ");
-         XBT_DEBUG("host_lib");
-         xbt_lib_foreach(host_lib, cursor, name, data) {
-                       XBT_DEBUG("\tSee host '%s'\t--> NS3_LEVEL %p",
-                                       name,
-                                       data[NS3_HOST_LEVEL]);
-         }
-         XBT_DEBUG(" ");
-         XBT_DEBUG("as_router_lib");
-         xbt_lib_foreach(as_router_lib, cursor, name, data) {
-                       XBT_DEBUG("\tSee ASR '%s'\t--> NS3_LEVEL %p",
-                                       name,
-                                       data[NS3_ASR_LEVEL]);
-         }
-
-         XBT_DEBUG(" ");
 }
 
 /* Create the ns3 topology based on routing strategy */
 void create_ns3_topology()
 {
-   XBT_INFO("Starting topology generation");
+   XBT_DEBUG("Starting topology generation");
 
    //get the onelinks from the parsed platform
    xbt_dynar_t onelink_routes = global_routing->get_onelink_routes();
    if (!onelink_routes)
      xbt_die("There is no routes!");
-   XBT_INFO("Have get_onelink_routes, found %ld routes",onelink_routes->used);
+   XBT_DEBUG("Have get_onelink_routes, found %ld routes",onelink_routes->used);
    //save them in trace file
    onelink_t onelink;
    unsigned int iter;
@@ -281,17 +272,15 @@ void create_ns3_topology()
      void *link = onelink->link_ptr;
 
      if( strcmp(src,dst) && ((surf_ns3_link_t)link)->created){
-     XBT_INFO("Route from '%s' to '%s' with link '%s'",src,dst,((surf_ns3_link_t)link)->data->id);
-     char * link_bdw = xbt_strdup(((surf_ns3_link_t)link)->data->bdw);
-        char * link_lat = xbt_strdup(((surf_ns3_link_t)link)->data->lat);
+     XBT_DEBUG("Route from '%s' to '%s' with link '%s'",src,dst,((surf_ns3_link_t)link)->data->id);
+     char * link_bdw = bprintf("%sBps",((surf_ns3_link_t)link)->data->bdw);
+        char * link_lat = bprintf("%ss",(((surf_ns3_link_t)link)->data->lat));
         ((surf_ns3_link_t)link)->created = 0;
 
-        replace_bdw_ns3(link_bdw);
-        replace_lat_ns3(link_lat);
-//      XBT_INFO("src (%s), dst (%s), src_id = %d, dst_id = %d",src,dst, src_id, dst_id);
-     XBT_INFO("\tLink (%s) bdw:%s->%s lat:%s->%s",((surf_ns3_link_t)link)->data->id,
-                ((surf_ns3_link_t)link)->data->bdw,link_bdw,
-                ((surf_ns3_link_t)link)->data->lat,link_lat
+        //      XBT_DEBUG("src (%s), dst (%s), src_id = %d, dst_id = %d",src,dst, src_id, dst_id);
+     XBT_DEBUG("\tLink (%s) bdw:%s lat:%s",((surf_ns3_link_t)link)->data->id,
+                link_bdw,
+                link_lat
                 );
 
      //create link ns3
@@ -344,11 +333,30 @@ static void free_ns3_host(void * elmts)
 
 void surf_network_model_init_NS3(const char *filename)
 {
+       if (surf_network_model)
+               return;
+
        surf_network_model = surf_model_init();
        surf_network_model->name = "network NS3";
        surf_network_model->extension.network.get_link_latency = ns3_get_link_latency;
        surf_network_model->extension.network.get_link_bandwidth = ns3_get_link_bandwidth;
        surf_network_model->extension.network.get_route = ns3_get_route;
+
+       surf_network_model->model_private->share_resources = ns3_share_resources;
+       surf_network_model->model_private->update_actions_state = ns3_update_actions_state;
+       surf_network_model->model_private->finalize = finalize;
+
+       surf_network_model->suspend = action_suspend;
+       surf_network_model->resume = action_resume;
+       surf_network_model->is_suspended = action_is_suspended;
+       surf_network_model->action_unref = action_unref;
+       surf_network_model->extension.network.communicate = communicate;
+
+       /* Added the initialization for NS3 interface */
+       if (ns3_initialize()) {
+       xbt_die("Impossible to initialize NS3 interface");
+       }
+
        routing_model_create(sizeof(s_surf_ns3_link_t), NULL, NULL);
        define_callbacks_ns3(filename);
 
@@ -356,6 +364,102 @@ void surf_network_model_init_NS3(const char *filename)
        NS3_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,(void_f_pvoid_t)free_ns3_host);
        NS3_LINK_LEVEL = xbt_lib_add_level(link_lib,(void_f_pvoid_t)free_ns3_link);
 
+       xbt_dynar_push(model_list, &surf_network_model);
        update_model_description(surf_network_model_description,
                    "NS3", surf_network_model);
 }
+
+static void finalize(void)
+{
+       ns3_finalize();
+       xbt_dynar_free_container(&IPV4addr);
+}
+
+static double ns3_share_resources(double min)
+{
+       XBT_DEBUG("ns3_share_resources");
+
+       xbt_swag_t running_actions =
+         surf_network_model->states.running_action_set;
+
+       //get the first relevant value from the running_actions list
+       if (!xbt_swag_size(running_actions))
+       return -1.0;
+
+       ns3_simulator(min);
+       time_to_next_flow_completion = ns3_time() - surf_get_clock();
+
+       xbt_assert(time_to_next_flow_completion,
+                         "Time to next flow completion not initialized!\n");
+
+       XBT_DEBUG("ns3_share_resources return %f",time_to_next_flow_completion);
+       return time_to_next_flow_completion;
+}
+
+static void ns3_update_actions_state(double now, double delta)
+{
+         xbt_dict_cursor_t cursor = NULL;
+         char *key;
+         void *data;
+
+         surf_action_t action = NULL;
+         xbt_swag_t running_actions =
+             surf_network_model->states.running_action_set;
+
+         /* If there are no running flows, just return */
+         if (!xbt_swag_size(running_actions))
+               return;
+
+         xbt_dict_foreach(dict_socket,cursor,key,data){
+               action = (surf_action_t)ns3_get_socket_action(data);
+               action->remains = ns3_get_socket_remains(data);
+               if(ns3_get_socket_is_finished(data) == 1){
+                       action->finish = now;
+                       surf_action_state_set(action, SURF_ACTION_DONE);
+               }
+         }
+         return;
+}
+
+/* Max durations are not supported */
+static surf_action_t communicate(const char *src_name,
+                                 const char *dst_name, double size, double rate)
+{
+  surf_action_t action = NULL;
+
+  XBT_DEBUG("Communicate from %s to %s",src_name,dst_name);
+  action = surf_action_new(sizeof(s_surf_action_t), size, surf_network_model, 0);
+
+  ns3_create_flow(src_name, dst_name, surf_get_clock(), size, action);
+
+  return (surf_action_t) action;
+}
+
+/* Suspend a flow() */
+static void action_suspend(surf_action_t action)
+{
+  THROW_UNIMPLEMENTED;
+}
+
+/* Resume a flow() */
+static void action_resume(surf_action_t action)
+{
+  THROW_UNIMPLEMENTED;
+}
+
+/* Test whether a flow is suspended */
+static int action_is_suspended(surf_action_t action)
+{
+  return 0;
+}
+
+static int action_unref(surf_action_t action)
+{
+  action->refcount--;
+  if (!action->refcount) {
+    xbt_swag_remove(action, action->state_set);
+    surf_action_free(&action);
+    return 1;
+  }
+  return 0;
+}
index 4542034..8fcc51e 100644 (file)
@@ -5,6 +5,11 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "ns3_interface.h"
+#include "ns3_simulator.h"
+#include "xbt/lib.h"
+#include "xbt/log.h"
+#include "xbt/dynar.h"
+
 #include "ns3/core-module.h"
 #include "ns3/simulator-module.h"
 #include "ns3/node-module.h"
 
 using namespace ns3;
 
+extern xbt_lib_t host_lib;
+extern int NS3_HOST_LEVEL;             //host node for ns3
+extern xbt_dynar_t IPV4addr;
+
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(interface_ns3, surf,
                                 "Logging specific to the SURF network NS3 module");
 
@@ -23,21 +32,87 @@ NodeContainer nodes;
 NodeContainer Cluster_nodes;
 Ipv4InterfaceContainer interfaces;
 
+
+
 int number_of_nodes = 0;
 int number_of_clusters_nodes = 0;
 int number_of_links = 1;
 int number_of_networks = 1;
+int port_number = 1025; //Port number is limited from 1025 to 65 000
+
+static NS3Sim* ns3_sim = 0;
+
+void ns3_simulator(double min){
+                       ns3_sim->simulator_stop(min);
+                       ns3_sim->simulator_start();
+}
+
+void* ns3_get_socket_action(void *socket){
+               return ns3_sim->get_action_from_socket(socket);
+}
+
+double ns3_get_socket_remains(void *socket){
+               return ns3_sim->get_remains_from_socket(socket);
+}
+
+char ns3_get_socket_is_finished(void *socket){
+               return ns3_sim->get_finished(socket);
+}
+
+
+double ns3_time(){
+       return Simulator::Now().GetSeconds();
+}
+
+int ns3_create_flow(const char* a,const char *b,double start,u_int32_t TotalBytes,void * action)
+{
+       ns3_nodes_t node1 = (ns3_nodes_t) xbt_lib_get_or_null(host_lib,a,NS3_HOST_LEVEL);
+       ns3_nodes_t node2 = (ns3_nodes_t) xbt_lib_get_or_null(host_lib,b,NS3_HOST_LEVEL);
+
+       Ptr<Node> src_node = nodes.Get(node1->node_num);
+       Ptr<Node> dst_node = nodes.Get(node2->node_num);
+
+       char* addr = (char*)xbt_dynar_get_ptr(IPV4addr,node2->node_num);
+
+       XBT_INFO("ns3_create_flow %d Bytes from %d to %d with Interface %s",TotalBytes, node1->node_num, node2->node_num,addr);
+       ns3_sim->create_flow_NS3(src_node,
+                       dst_node,
+                       port_number,
+                       start,
+                       addr,
+                       TotalBytes,
+                       action);
+
+       port_number++;
+       if(port_number >= 65001 ) xbt_die("Too many connections! Port number is saturated.");
+       return 0;
+}
+
+// clean up
+int ns3_finalize(void){
+       if (!ns3_sim) return -1;
+       delete ns3_sim;
+       ns3_sim = 0;
+       return 0;
+}
+
+// initialize the NS3 interface and environment
+int ns3_initialize(void){
+  xbt_assert(!ns3_sim, "ns3 already initialized");
+  ns3_sim = new NS3Sim();
+  return 0;
+}
 
 void * ns3_add_host(char * id)
 {
        ns3_nodes_t host  = xbt_new0(s_ns3_nodes_t,1);
-       XBT_INFO("Interface ns3 add host[%d] '%s'",number_of_nodes,id);
+       XBT_DEBUG("Interface ns3 add host[%d] '%s'",number_of_nodes,id);
        Ptr<Node> node =  CreateObject<Node> (0);
        stack.Install(node);
        nodes.Add(node);
        host->node_num = number_of_nodes;
        host->type = NS3_NETWORK_ELEMENT_HOST;
-       host->data = node;
+       host->data = GetPointer(node);
        number_of_nodes++;
        return host;
 }
@@ -45,7 +120,7 @@ void * ns3_add_host(char * id)
 void * ns3_add_host_cluster(char * id)
 {
        ns3_nodes_t host  = xbt_new0(s_ns3_nodes_t,1);
-       XBT_INFO("Interface ns3 add host[%d] '%s'",number_of_nodes,id);
+       XBT_DEBUG("Interface ns3 add host[%d] '%s'",number_of_nodes,id);
        Ptr<Node> node =  CreateObject<Node> (0);
        stack.Install(node);
        Cluster_nodes.Add(node);
@@ -60,7 +135,7 @@ void * ns3_add_host_cluster(char * id)
 void * ns3_add_router(char * id)
 {
        ns3_nodes_t router  = xbt_new0(s_ns3_nodes_t,1);
-       XBT_INFO("Interface ns3 add router[%d] '%s'",number_of_nodes,id);
+       XBT_DEBUG("Interface ns3 add router[%d] '%s'",number_of_nodes,id);
        Ptr<Node> node =  CreateObject<Node> (0);
        stack.Install(node);
        nodes.Add(node);
@@ -118,10 +193,19 @@ void * ns3_add_cluster(char * bw,char * lat,char *id)
 
 void * ns3_add_AS(char * id)
 {
-       XBT_INFO("Interface ns3 add AS '%s'",id);
+       XBT_DEBUG("Interface ns3 add AS '%s'",id);
        return NULL;
 }
 
+static char* transformIpv4Address (Ipv4Address from){
+       std::stringstream sstream;
+               sstream << interfaces.GetAddress(interfaces.GetN()-2);
+               std::string s = sstream.str();
+               size_t size = s.size() + 1;
+               char* IPaddr = bprintf("%s",s.c_str());
+               return IPaddr;
+}
+
 void * ns3_add_link(int src,int dst,char * bw,char * lat)
 {
        if(number_of_links == 1 ) {
@@ -146,9 +230,15 @@ void * ns3_add_link(int src,int dst,char * bw,char * lat)
        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));
 
-       XBT_DEBUG(" ");
+       xbt_dynar_set(IPV4addr,src,
+                       transformIpv4Address(interfaces.GetAddress(interfaces.GetN()-2)));
+
+       xbt_dynar_set(IPV4addr,dst,
+                       transformIpv4Address(interfaces.GetAddress(interfaces.GetN()-1)));
+
        if(number_of_links == 255){
                if(number_of_networks == 255)
                        xbt_die("Number of links and networks exceed 255*255");
@@ -161,48 +251,7 @@ void * ns3_add_link(int src,int dst,char * bw,char * lat)
 
 void * ns3_end_platform(void)
 {
-       XBT_INFO("InitializeRoutes");
+       XBT_DEBUG("InitializeRoutes");
        GlobalRouteManager::BuildGlobalRoutingDatabase();
        GlobalRouteManager::InitializeRoutes();
-
-       //TODO REMOVE ;)
-       Ptr<Node> a = nodes.Get(0);
-       Ptr<Node> b = nodes.Get(1);
-       Ptr<Node> c = nodes.Get(2);
-       Ptr<Node> d = nodes.Get(3);
-
-       UdpEchoServerHelper echoServer (9);
-
-       ApplicationContainer serverApps = echoServer.Install (a);
-       serverApps.Start (Seconds (1.0));
-       serverApps.Stop (Seconds (20.0));
-
-       UdpEchoClientHelper echoClient (interfaces.GetAddress (0), 9);
-       echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
-       echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
-       echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
-       ApplicationContainer clientApps_b = echoClient.Install (b);
-       clientApps_b.Start (Seconds (2.0));
-       clientApps_b.Stop (Seconds (10.0));
-
-       UdpEchoClientHelper echoClient2 (interfaces.GetAddress (0), 9);
-       echoClient2.SetAttribute ("MaxPackets", UintegerValue (1));
-       echoClient2.SetAttribute ("Interval", TimeValue (Seconds (1.)));
-       echoClient2.SetAttribute ("PacketSize", UintegerValue (512));
-       ApplicationContainer clientApps_c = echoClient2.Install (c);
-       clientApps_c.Start (Seconds (3.0));
-       clientApps_c.Stop (Seconds (10.0));
-
-       UdpEchoClientHelper echoClient3 (interfaces.GetAddress (0), 9);
-       echoClient3.SetAttribute ("MaxPackets", UintegerValue (1));
-       echoClient3.SetAttribute ("Interval", TimeValue (Seconds (1.)));
-       echoClient3.SetAttribute ("PacketSize", UintegerValue (256));
-       ApplicationContainer clientApps_d = echoClient3.Install (d);
-       clientApps_d.Start (Seconds (4.0));
-       clientApps_d.Stop (Seconds (10.0));
-
-       Simulator::Run ();
-       Simulator::Destroy ();
-
-       //HEEEEEEE
 }
index 73780c0..e6d2187 100644 (file)
@@ -29,6 +29,14 @@ typedef struct ns3_nodes{
 extern "C" {
 #endif
 
+XBT_PUBLIC(int)    ns3_finalize(void);
+XBT_PUBLIC(int)    ns3_initialize(void);
+XBT_PUBLIC(int)    ns3_create_flow(const char* a,const char *b,double start,u_int32_t TotalBytes,void * action);
+XBT_PUBLIC(void)   ns3_simulator(double min);
+XBT_PUBLIC(double) ns3_time(void);
+XBT_PUBLIC(void*)  ns3_get_socket_action(void *socket);
+XBT_PUBLIC(double) ns3_get_socket_remains(void *socket);
+XBT_PUBLIC(char)   ns3_get_socket_is_finished(void *socket);
 XBT_PUBLIC(void *) ns3_add_host(char * id);
 XBT_PUBLIC(void *) ns3_add_host_cluster(char * id);
 XBT_PUBLIC(void *) ns3_add_router(char * id);
index 29fd20e..41ef634 100644 (file)
@@ -5,6 +5,26 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "surf/ns3/ns3_simulator.h"
+#include "xbt/dict.h"
+#include "xbt/log.h"
+
+using namespace ns3;
+using namespace std;
+
+static const uint32_t writeSize  = 1024; // limit the amout of data to write
+uint8_t data[writeSize];
+xbt_dict_t dict_socket = NULL;
+
+NS3Sim SimulatorNS3;
+
+static void receive_callback(Ptr<Socket> localSocket);
+static void send_callback(Ptr<Socket> localSocket, uint32_t txSpace);
+static void StartFlow(Ptr<Socket> sock,
+    const char *to,
+    uint16_t port_number);
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simulator_ns3, surf,
+                                "Logging specific to the SURF network NS3 module");
 
 // Constructor.
 NS3Sim::NS3Sim(){
@@ -12,3 +32,118 @@ NS3Sim::NS3Sim(){
 //Destructor.
 NS3Sim::~NS3Sim(){
 }
+
+/*
+ * This function create a flow from src to dst
+ *
+ * Parameters
+ *             src: node source
+ *             dst: node destination
+ *             port_number: The port number to use
+ *             start: the time the communication start
+ *             addr:  ip address
+ *             TotalBytes: number of bytes to transmit
+ */
+void NS3Sim::create_flow_NS3(
+               Ptr<Node> src,
+               Ptr<Node> dst,
+               uint16_t port_number,
+               double start,
+               const char *addr,
+               uint32_t TotalBytes,
+               void * action)
+{
+       if(!dict_socket) dict_socket = xbt_dict_new();
+       PacketSinkHelper sink ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny(), port_number));
+       sink.Install (dst);
+       Ptr<Socket> sock = Socket::CreateSocket (src, TypeId::LookupByName ("ns3::TcpSocketFactory"));
+       MySocket *mysocket = new MySocket();
+       mysocket->TotalBytes = TotalBytes;
+       mysocket->remaining = TotalBytes;
+       mysocket->sentBytes = 0;
+       mysocket->finished = 0;
+       mysocket->action = action;
+       xbt_dict_set(dict_socket,(const char*)&sock, mysocket,NULL);
+       sock->Bind(InetSocketAddress(port_number));
+       Simulator::Schedule (Seconds(start),&StartFlow, sock, addr, port_number);
+}
+
+void* NS3Sim::get_action_from_socket(void *socket){
+       return ((MySocket *)socket)->action;
+}
+
+char NS3Sim::get_finished(void *socket){
+       return ((MySocket *)socket)->finished;
+}
+
+double NS3Sim::get_remains_from_socket(void *socket){
+       return ((MySocket *)socket)->remaining;
+}
+
+void NS3Sim::simulator_stop(double min){
+       if(min > 0.0)
+               Simulator::Stop(Seconds(min));
+       else
+               Simulator::Stop();
+}
+
+void NS3Sim::simulator_start(void){
+       XBT_DEBUG("Start simulator");
+       Simulator::Run ();
+}
+
+static void receive_callback(Ptr<Socket> localSocket){
+  Address addr;
+  localSocket->GetSockName (addr);
+  InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr);
+  MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket);
+  mysocket->finished = 1;
+
+  //cout << "[" << Simulator::Now ().GetSeconds() << "] " << "Received [" << mysocket->TotalBytes << "bytes],  from: " << iaddr.GetIpv4 () << " port: " << iaddr.GetPort () << endl;
+       std::stringstream sstream;
+               sstream << Simulator::Now ().GetSeconds();
+               std::string s = sstream.str();
+               size_t size = s.size() + 1;
+               char * time_sec = new char[ size ];
+               strncpy( time_sec, s.c_str(), size );
+  XBT_DEBUG("Stop simulator at %s seconds",time_sec);
+  Simulator::Stop();
+}
+
+static void send_callback(Ptr<Socket> localSocket, uint32_t txSpace){
+
+       Address addr;
+       localSocket->GetSockName (addr);
+       InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr);
+       MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket);
+       uint32_t totalBytes = mysocket->TotalBytes;
+       while ((mysocket->sentBytes) < totalBytes && localSocket->GetTxAvailable () > 0){
+      uint32_t toWrite = min ((mysocket->remaining), writeSize);
+      toWrite = min (toWrite, localSocket->GetTxAvailable ());
+      int amountSent = localSocket->Send (&data[0], toWrite, 0);
+
+//      cout << Simulator::Now () << "  AmountSend: " << amountSent << "  Towrite: " << toWrite << endl;
+      if(amountSent < 0)
+         return;
+         (mysocket->sentBytes) += amountSent;
+         (mysocket->remaining) -= amountSent;
+         //cout << "[" << Simulator::Now ().GetSeconds() << "] " << "Send one packet, remaining "<<  mysocket->remaining << " bytes!" << endl;
+    }
+       if ((mysocket->sentBytes) >= totalBytes){
+               localSocket->Close();
+       }
+
+}
+
+static void StartFlow(Ptr<Socket> sock,
+    const char *to,
+    uint16_t port_number)
+{
+  InetSocketAddress serverAddr (to, port_number);
+
+  //cout << "[" <<  Simulator::Now().GetSeconds() << "] Starting flow to " << to << " using port " << port_number << endl;
+
+  sock->Connect(serverAddr);
+  sock->SetSendCallback (MakeCallback (&send_callback));
+  sock->SetRecvCallback (MakeCallback (&receive_callback));
+}
index dce821b..0966670 100644 (file)
@@ -9,15 +9,45 @@
 
 #ifdef __cplusplus
 
+#include "ns3/core-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-routing-module.h"
+#include "ns3/tcp-socket-factory.h"
+
+using namespace ns3;
+using namespace std;
+
+struct MySocket{
+       uint32_t sentBytes;
+       uint32_t remaining;
+       uint32_t TotalBytes;
+       char finished;
+       void* action;
+};
+
 //Simulator s;
 class NS3Sim {
-       NS3Sim();
-       ~NS3Sim();
 
 private:
 
 public:
-
+       NS3Sim();
+       ~NS3Sim();
+       void create_flow_NS3(Ptr<Node> src,
+                                               Ptr<Node> dst,
+                                               uint16_t port_number,
+                                               double start,
+                                               const char *addr,
+                                               uint32_t TotalBytes,
+                                               void * action);
+       void simulator_stop(double min);
+       void simulator_start(void);
+       void* get_action_from_socket(void *socket);
+       double get_remains_from_socket(void *socket);
+       char get_finished(void *socket);
 };
 
 #endif                          /* __cplusplus */
index bd46602..f1eb0f5 100644 (file)
@@ -442,14 +442,30 @@ double surf_solve(double max_date)
 
   XBT_DEBUG("Looking for next action end");
   xbt_dynar_foreach(model_list, iter, model) {
-    XBT_DEBUG("Running for Resource [%s]", model->name);
-    model_next_action_end = model->model_private->share_resources(NOW);
-    XBT_DEBUG("Resource [%s] : next action end = %f",
-           model->name, model_next_action_end);
-    if (((min < 0.0) || (model_next_action_end < min))
-        && (model_next_action_end >= 0.0))
-      min = model_next_action_end;
+
+       if(strcmp(model->name,"network NS3") ){
+               XBT_DEBUG("Running for Resource [%s]", model->name);
+               model_next_action_end = model->model_private->share_resources(NOW);
+               XBT_DEBUG("Resource [%s] : next action end = %f",
+                          model->name, model_next_action_end);
+               if (((min < 0.0) || (model_next_action_end < min))
+                       && (model_next_action_end >= 0.0))
+                 min = model_next_action_end;
+         }
   }
+
+  XBT_DEBUG("Min for other resources : %f", min);
+
+
+  if(!strcmp(surf_network_model->name,"network NS3")){
+       // run until min or next flow
+       model_next_action_end = surf_network_model->model_private->share_resources(min);
+       XBT_DEBUG("Min for NS3 : %f", model_next_action_end);
+       if ( ((min < 0.0) || (model_next_action_end < min)) && ( model_next_action_end >= 0.0 ))
+               min = model_next_action_end;
+  }
+
+
   XBT_DEBUG("Next action end : %f", min);
 
   XBT_DEBUG("Looking for next event");