From: Navarrop Date: Thu, 28 Jul 2011 15:48:39 +0000 (+0200) Subject: Implementation of NS3. X-Git-Tag: v3_6_2~188^2~1^2~4 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/7f6d6d56876d2e286d0f11bfb390af6de6c9863e Implementation of NS3. Add an example for ns3. Add many functions for ns3. --- diff --git a/buildtools/Cmake/MakeExe.cmake b/buildtools/Cmake/MakeExe.cmake index 30485806d9..ed00683542 100644 --- a/buildtools/Cmake/MakeExe.cmake +++ b/buildtools/Cmake/MakeExe.cmake @@ -69,6 +69,10 @@ if(HAVE_GTNETS) add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/gtnets) endif(HAVE_GTNETS) +if(HAVE_NS3) + add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/ns3) +endif(HAVE_NS3) + add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/amok/bandwidth) add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/amok/saturate) diff --git a/examples/msg/ns3/CMakeLists.txt b/examples/msg/ns3/CMakeLists.txt new file mode 100644 index 0000000000..1111655a04 --- /dev/null +++ b/examples/msg/ns3/CMakeLists.txt @@ -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 index 0000000000..a40a8d5ff6 --- /dev/null +++ b/examples/msg/ns3/ns3.c @@ -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 +#include +#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 index 0000000000..b9a1cf4fff --- /dev/null +++ b/examples/msg/ns3/onelink-d.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/msg/ns3/onelink-p.xml b/examples/msg/ns3/onelink-p.xml new file mode 100644 index 0000000000..b05e780dce --- /dev/null +++ b/examples/msg/ns3/onelink-p.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/surf/network_ns3.c b/src/surf/network_ns3.c index 50cf119289..8e63b468e8 100644 --- a/src/surf/network_ns3.c +++ b/src/surf/network_ns3.c @@ -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; +} diff --git a/src/surf/ns3/ns3_interface.cc b/src/surf/ns3/ns3_interface.cc index 4542034b7a..8fcc51e0bf 100644 --- a/src/surf/ns3/ns3_interface.cc +++ b/src/surf/ns3/ns3_interface.cc @@ -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" @@ -15,6 +20,10 @@ 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 src_node = nodes.Get(node1->node_num); + Ptr 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 = CreateObject (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 = CreateObject (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 = CreateObject (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 a = nodes.Get(0); - Ptr b = nodes.Get(1); - Ptr c = nodes.Get(2); - Ptr 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 } diff --git a/src/surf/ns3/ns3_interface.h b/src/surf/ns3/ns3_interface.h index 73780c0007..e6d2187751 100644 --- a/src/surf/ns3/ns3_interface.h +++ b/src/surf/ns3/ns3_interface.h @@ -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); diff --git a/src/surf/ns3/ns3_simulator.cc b/src/surf/ns3/ns3_simulator.cc index 29fd20e182..41ef6345ab 100644 --- a/src/surf/ns3/ns3_simulator.cc +++ b/src/surf/ns3/ns3_simulator.cc @@ -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 localSocket); +static void send_callback(Ptr localSocket, uint32_t txSpace); +static void StartFlow(Ptr 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 src, + Ptr 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 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 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 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 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)); +} diff --git a/src/surf/ns3/ns3_simulator.h b/src/surf/ns3/ns3_simulator.h index dce821b559..096667067e 100644 --- a/src/surf/ns3/ns3_simulator.h +++ b/src/surf/ns3/ns3_simulator.h @@ -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 src, + Ptr 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 */ diff --git a/src/surf/surf.c b/src/surf/surf.c index bd4660229c..f1eb0f5053 100644 --- a/src/surf/surf.c +++ b/src/surf/surf.c @@ -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");