diff --git a/openair2/UTIL/FIFO/types.h b/openair2/UTIL/FIFO/types.h
index 063bb1ed9d30f292a495ab33166f0e5b2f8fc945..0ea9915c7030b1edf2282a61f4397f7d9e6b92a6 100644
--- a/openair2/UTIL/FIFO/types.h
+++ b/openair2/UTIL/FIFO/types.h
@@ -53,6 +53,8 @@ typedef enum  {
 /* decomposition of node functions into jobs for a given event */
 typedef enum Job_type_e { JT_OTG, JT_PDCP, JT_PHY_MAC, JT_INIT_SYNC, JT_DL, JT_UL, RN_DL, RN_UL, JT_END} Job_Type_t;
 
+typedef enum Operation_Type_e { READ, WRITE, RESET} Operation_Type_t;
+
 typedef struct Job_s {
     enum Job_type_e type;
     int             exe_time; /* execution time at the worker*/
@@ -87,9 +89,12 @@ typedef struct Packet_otg_s {
 
 typedef struct {
     Event_Type_t type;
+		enum Operation_Type_e optype; //op
     char             *key;
     void             *value;
     frame_t           frame;
+		int ue;
+		int lcid;
 } Event_t;
 
 /*typedef struct Global_Time {
@@ -101,6 +106,8 @@ typedef struct {
   double time_ms;
 };*/
 
+
+
 typedef struct Packet_otg_elt_s {
     struct Packet_otg_elt_s *next;
     struct Packet_otg_elt_s *previous;
diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c
index ad672d1859d241701845b367a7d14741eed1e6ae..3ea9d47b52090ce88e6bf3934403cda1c1c3e7a6 100755
--- a/openair2/UTIL/LOG/log.c
+++ b/openair2/UTIL/LOG/log.c
@@ -178,7 +178,7 @@ int logInit (void)
     g_log->log_component[OMG].interval =  1;
     g_log->log_component[OMG].fd = 0;
     g_log->log_component[OMG].filelog = 0;
-    g_log->log_component[OMG].filelog_name = "";
+    g_log->log_component[OMG].filelog_name = "/tmp/omg.csv";
 
     g_log->log_component[OTG].name = "OTG";
     g_log->log_component[OTG].level = LOG_EMERG;
diff --git a/openair2/UTIL/Makefile.inc b/openair2/UTIL/Makefile.inc
index efad62244fd1288ee60106aa3469c9133bfbe72a..fac8d7e9a17885e0f03f321217b69fa547f4ab78 100644
--- a/openair2/UTIL/Makefile.inc
+++ b/openair2/UTIL/Makefile.inc
@@ -50,7 +50,7 @@ OMG_OBJS +=  $(OMG_DIR)/job.o
 OMG_OBJS +=  $(OMG_DIR)/static.o
 OMG_OBJS +=  $(OMG_DIR)/rwp.o
 OMG_OBJS +=  $(OMG_DIR)/rwalk.o
-OMG_OBJS +=  $(OMG_DIR)/omg_hashtable.o
+#OMG_OBJS +=  $(OMG_DIR)/omg_hashtable.o
 OMG_OBJS +=  $(OMG_DIR)/mobility_parser.o
 OMG_OBJS +=  $(OMG_DIR)/trace.o
 OMG_OBJS +=  $(OMG_DIR)/sumo.o
@@ -58,6 +58,10 @@ OMG_OBJS +=  $(OMG_DIR)/id_manager.o
 OMG_OBJS +=  $(OMG_DIR)/client_traci_OMG.o
 OMG_OBJS +=  $(OMG_DIR)/storage_traci_OMG.o
 OMG_OBJS +=  $(OMG_DIR)/socket_traci_OMG.o
+OMG_OBJS +=  $(OMG_DIR)/steadystaterwp.o
+OMG_OBJS +=  $(OMG_DIR)/grid.o
+OMG_OBJS +=  $(OMG_DIR)/trace_hashtable.o
+
 
 OTG_OBJS =  $(OTG_DIR)/otg_tx.o
 OTG_OBJS +=  $(OTG_DIR)/otg.o
diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h
index 69e66d9934d09ee46462545d0cdd4cb04e154ae5..fa2e88677787c0f1eda298c0601cd40ff45e4859 100644
--- a/openair2/UTIL/OCG/OCG.h
+++ b/openair2/UTIL/OCG/OCG.h
@@ -295,6 +295,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
   ////// options of UE_Mobility_Type
   typedef struct
   {
+    char *selected_option; 
     int horizontal_grid;
     int vertical_grid;
   } Grid_Map;
@@ -464,6 +465,32 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
 /* @}*/
 
 
+  typedef struct
+  {
+	uint16_t priority[11];//pas possible d'acceder au MAX_NUM_LCID
+	//
+	uint8_t DCI_aggregation_min;
+	uint8_t DLSCH_dci_size_bits;
+	//UL transmission bandwidth in RBs
+	uint8_t ul_bandwidth[11];
+	//DL transmission bandwidth in RBs
+	uint8_t dl_bandwidth[11];
+	//UL transmission bandwidth in RBs
+	uint8_t min_ul_bandwidth[11];
+	//DL transmission bandwidth in RBs
+	uint8_t min_dl_bandwidth[11];
+	//aggregated bit rate of non-gbr bearer per UE
+	uint64_t ue_AggregatedMaximumBitrateDL;
+	//aggregated bit rate of non-gbr bearer per UE
+	uint64_t ue_AggregatedMaximumBitrateUL;
+	//CQI scheduling interval in subframes.
+	uint16_t cqiSchedInterval;
+	//Contention resolution timer used during random access
+	uint8_t mac_ContentionResolutionTimer;		
+	uint16_t max_allowed_rbs[11];
+	uint8_t max_mcs[11];	
+  } Mac_config;
+
 /** @defgroup _Predefined_traffic Configuration
  *  @ingroup _OSD_basic
  *  @brief Including Application type, Source, destination, background, etc
@@ -684,7 +711,8 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
     unsigned char otg_bg_traffic_enabled;
     unsigned char omg_model_rn;
     unsigned char omg_model_enb;
-    unsigned char omg_model_ue;
+    unsigned char omg_model_ue; 
+    unsigned char omg_rwp_type;
     unsigned char omg_model_ue_current;	// when mixed mbility is used 
     // control eNB/UE instance through CLI
     unsigned char cli_enabled;
@@ -733,6 +761,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need
  * @{*/
   typedef struct
   {
+    		Mac_config mac_config[NUMBER_OF_UE_MAX];		
     Environment_System_Config environment_system_config;	/*!< \brief Evironment configuration */
     Topology_Config topology_config;	/*!< \brief Topology configuration */
     Application_Config application_config;	/*!< \brief Applications configuration */
diff --git a/openair2/UTIL/OCG/OCG_parse_XML.c b/openair2/UTIL/OCG/OCG_parse_XML.c
index d828a87a46d207fae2b6f41224b62d34dc816a04..b75e75ed90034884af9787ddd25256cc6abd13de 100644
--- a/openair2/UTIL/OCG/OCG_parse_XML.c
+++ b/openair2/UTIL/OCG/OCG_parse_XML.c
@@ -1015,14 +1015,18 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
 			} else if (mobility_) {
 				if (UE_mobility_) {
 					if (UE_mobility_type_) {
-						oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = strndup(ch, len);
-					} else if (grid_walk_) {
+						oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = strndup(ch, len);	
+				 
+				  }else if (grid_walk_) {
 						if (grid_map_) {
+							 oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.selected_option = strndup(ch, len);
+	/*
 							if (horizontal_grid_) {
 								oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid = atoi(ch);
 							} else if (vertical_grid_) {
 								oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid = atoi(ch);
 							}
+*/
 						} else if (grid_trip_type_) {
 							oai_emulation.topology_config.mobility.UE_mobility.grid_walk.grid_trip_type.selected_option = strndup(ch, len);
 						}	
@@ -1087,6 +1091,7 @@ void characters(void *user_data, const xmlChar *xmlch, int xmllen) { // called o
 				} else if (eNB_mobility_) {
 					if (eNB_mobility_type_) {
 						oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option = strndup(ch, len);
+						
 					} else if (eNB_initial_distribution_) {
 						oai_emulation.topology_config.mobility.eNB_mobility.eNB_initial_distribution.selected_option = strndup(ch, len);
 					} else if (eNB_initial_coordinates_) {
diff --git a/openair2/UTIL/OMG/TRACE/static_2ues.tr b/openair2/UTIL/OMG/TRACE/static_2ues.tr
index b7e5a17789278b3330f95a790c361b8ece6ebf97..f669f8107350af6293803e2e261d0b63544e9818 100644
--- a/openair2/UTIL/OMG/TRACE/static_2ues.tr
+++ b/openair2/UTIL/OMG/TRACE/static_2ues.tr
@@ -1,2 +1,3 @@
 1 0 2050 1500 0
 1 1 2150 1500 0
+ 
diff --git a/openair2/UTIL/OMG/client_traci_OMG.c b/openair2/UTIL/OMG/client_traci_OMG.c
index 63667b23e822207e3f44d90a09f0a1eaa1bd3674..f622b34fbf80ba3646c34f623529bb125fc1c8e1 100644
--- a/openair2/UTIL/OMG/client_traci_OMG.c
+++ b/openair2/UTIL/OMG/client_traci_OMG.c
@@ -105,12 +105,12 @@ void init(int max_sim_time) {
   sendExact(storageLength(storageStart));
   extractCommandStatus(receiveExact(), CMD_SUBSCRIBE_SIM_VARIABLE, description);
   if (departed == NULL) {
-    departed = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
+    departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
     departed->string = NULL;
     departed->next = NULL;
   }
   if (arrived == NULL) {
-    arrived = (String_list)malloc(sizeof(String_list));  // arrived MUST point to HEAD
+    arrived = (string_list*) malloc(sizeof(string_list));  // arrived MUST point to HEAD
     arrived->string = NULL;
     arrived->next = NULL;
   } 
@@ -123,8 +123,8 @@ void init(int max_sim_time) {
 void processSubscriptions() {
    int noSubscriptions = readInt();
 
-   String_list tmp_departed = departed;
-   String_list tmp_arrived = arrived;
+   string_list* tmp_departed = departed;
+   string_list* tmp_arrived = arrived;
    int s;
    for (s = 0; s<noSubscriptions; ++s) {
     
@@ -240,12 +240,12 @@ void commandSimulationStep(double time)
         extractCommandStatus(receiveExact(), CMD_SIMSTEP2, description);
 
         if (departed == NULL) {
-    		departed = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
+    		departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
     		departed->string = NULL;
     		departed->next = NULL;
   	}
   	if (arrived == NULL) {
-    		arrived = (String_list)malloc(sizeof(String_list));  // arrived MUST point to HEAD
+    		arrived = (string_list*) malloc(sizeof(string_list));  // arrived MUST point to HEAD
     		arrived->string = NULL;
     		arrived->next = NULL;
   	}	
@@ -402,14 +402,14 @@ int commandGetMaxSUMONodesVariable()
 
 
 
-void GetSpeed(NodePtr node, char * sumo_id)
+void GetSpeed(node_struct* node, char * sumo_id)
 {
     commandGetVehicleVariable(sumo_id, VAR_SPEED);
     double speed_double = readDouble();
     node->mob->speed = speed_double;
 }
 
-void GetPosition(NodePtr node, char * sumo_id)
+void GetPosition(node_struct* node, char * sumo_id)
 {    
     commandGetVehicleVariable(sumo_id, VAR_POSITION);
     double x_double = readDouble();
@@ -420,6 +420,6 @@ void GetPosition(NodePtr node, char * sumo_id)
     if (y_double < 0.0)
       y_double = 0.0;
 
-    node->X_pos = x_double;
-    node->Y_pos = y_double;
+    node->x_pos = x_double;
+    node->y_pos = y_double;
 }
diff --git a/openair2/UTIL/OMG/client_traci_OMG.h b/openair2/UTIL/OMG/client_traci_OMG.h
index df643d42a76dcc8e2cf53fc636b726258c8505c4..3384be1ca6a86f81916430ed5a737a6cb6ba19e1 100644
--- a/openair2/UTIL/OMG/client_traci_OMG.h
+++ b/openair2/UTIL/OMG/client_traci_OMG.h
@@ -56,8 +56,8 @@ int targetTime;
 
 char *description;
 
-String_list departed;  // string list of all vehicles appearing in SUMO at the current time step
-String_list arrived;  // string list of all vehicles leaving SUMO at the current time step
+string_list* departed;  // string list of all vehicles appearing in SUMO at the current time step
+string_list* arrived;  // string list of all vehicles leaving SUMO at the current time step
 
 /**
  * Global parameters defined in storage_traci_OMG.h
@@ -89,10 +89,10 @@ int extractCommandStatus(storage *, unsigned char , char *);
 void commandSimulationStep(double);
 
 /**
- * \fn commandClose();
+ * \fn commandClose(void);
  * \brief Send termination command to SUMO
  */
-void commandClose();
+void commandClose(void);
 
 /**
  * \fn commandGetVehicleVariable(char *vehID, int varID)
@@ -103,10 +103,10 @@ void commandGetVehicleVariable(char *vehID, int varID);
 
 
 /**
- * \fn get_num_sumo_nodes()
+ * \fn get_num_sumo_nodes(void)
  * \brief Return the total number of nodes to be simulated in SUMO
  */
-int commandGetMaxSUMONodesVariable();
+int commandGetMaxSUMONodesVariable(void);
 
 /**
  * \fn init(int max_sim_time)
@@ -126,7 +126,7 @@ void processSubscriptions(void);
  * \param NodePtr node the pointer to the OAISim node
  * \param char *sumo_id the SUMO ID of the target node
  */
-void GetSpeed(NodePtr node, char * sumo_id);
+void GetSpeed(node_struct* node, char * sumo_id);
 
 /**
  * \fn void Position(NodePtr node, char * sumo_id);
@@ -134,7 +134,7 @@ void GetSpeed(NodePtr node, char * sumo_id);
  * \param NodePtr node the pointer to the OAISim node
  * \param char *sumo_id the SUMO ID of the target node
  */
-void GetPosition(NodePtr node, char * sumo_id);
+void GetPosition(node_struct* node, char * sumo_id);
 
 
 #endif 
diff --git a/openair2/UTIL/OMG/common.c b/openair2/UTIL/OMG/common.c
index fb830654515aaac0d8f5efb54d05a3eac7d80f5b..f19f59aa423303f06a27b7301ed03bf55ec85781 100644
--- a/openair2/UTIL/OMG/common.c
+++ b/openair2/UTIL/OMG/common.c
@@ -47,297 +47,392 @@
 
 #define frand() ((double) rand() / (RAND_MAX+1))
 //#ifndef STANDALONE
-mapping nodes_type[] =
-{
-    {"eNB", eNB},
-    {"UE", UE},
-    {NULL, -1}
+mapping nodes_type[] = {
+  {"eNB", eNB}
+  ,
+  {"UE", UE}
+  ,
+  {NULL, -1}
 };
 
-mapping nodes_status[] =
-{
-    {"sleeping", 0},
-    {"moving", 1},
-    {NULL, -1}
+mapping nodes_status[] = {
+  {"sleeping", 0}
+  ,
+  {"moving", 1}
+  ,
+  {NULL, -1}
 };
 
-mapping mob_type[] =
-{
-    {"STATIC", STATIC},
-    {"RWP", RWP},
-    {"RWALK", RWALK},
-    {"TRACE", TRACE},
-    {"SUMO", SUMO},    
-    {NULL, -1}
+mapping mob_type[] = {
+  {"STATIC", STATIC}
+  ,
+  {"RWP", RWP}
+  ,
+  {"RWALK", RWALK}
+  ,
+  {"TRACE", TRACE}
+  ,
+  {"SUMO", SUMO}
+  ,
+  {NULL, -1}
 };
+
 //#endif
-NodePtr create_node(void) {
-	NodePtr ptr;
-	ptr = calloc(1, sizeof(node_struct));
-	return ptr;
+
+node_struct *
+create_node (void)
+{
+  node_struct *ptr;
+  ptr = calloc (1, sizeof (node_struct));
+  return ptr;
 }
 
-void delete_node(NodePtr node) {
-  free(node->mob);
+
+void
+delete_node (node_struct * node)
+{
+  free (node->mob);
   node->mob = NULL;
-  free(node);
+  free (node);
 }
 
-double randomGen(double a, double b){
+double
+randomgen (double a, double b)
+{
 
-    return ( rand()/(double)RAND_MAX ) * (b-a) + a;
+  return (rand () / (double) RAND_MAX) * (b - a) + a;
 }
 
 
-MobilityPtr create_mobility(void) {
-	MobilityPtr ptr;
-	ptr = calloc(1, sizeof(mobility_struct));
-	return ptr;
+mobility_struct *
+create_mobility (void)
+{
+  mobility_struct *ptr;
+  ptr = calloc (1, sizeof (mobility_struct));
+  return ptr;
 }
 
 
-Node_list add_entry(NodePtr node, Node_list Node_Vector){
-    Node_list entry = malloc(sizeof(node_list_struct));
-    entry->node = node;
-    entry->next = NULL;
-    if (Node_Vector == NULL) {
-    // LOG_D(OMG, "\nempty Node_list");
-	//LOG_D(OMG, "\nadded elmt ID %d\n", entry->node->ID);
-        return entry;
+node_list *
+add_entry (node_struct * node, node_list * node_vector_end)
+{
+  node_list *entry = malloc (sizeof (struct node_list_struct));
+  entry->node = node;
+  entry->next = NULL;
+  if (node_vector_end == NULL)
+    {
+      return entry;
     }
-    else {
-        Node_list tmp = Node_Vector;
-        while (tmp->next != NULL){
-            tmp = tmp->next;
-        }
-        tmp->next = entry;
-        //LOG_D(OMG, "\nnon empty Node_list");
-	     //LOG_D(OMG, "added elmt ID %d\n", entry->node->ID);
-	
-        return Node_Vector;
+  else
+    {
+      node_list *tmp = node_vector_end;
+      tmp->next = entry;
     }
+  return entry;
 }
 
-Node_list remove_node_entry(NodePtr node, Node_list Node_Vector){
-  Node_list  list = Node_Vector;
-  Node_list tmp, toRemove;
-  if (list == NULL){  
-    return NULL;
-  }
-  if(list->node->ID == node->ID) {
-    // TODO delete the entry
-    toRemove = list;
-    LOG_D(OMG,"removed entry for node %d \n",list->node->ID);
-    if(list->next ==NULL) {
-    	Node_Vector = NULL;
-        return NULL;
+
+node_list *
+remove_node_entry (node_struct * node, node_list * node_vector)
+{
+  node_list *list = node_vector;
+  node_list *tmp, *toremove;
+  if (list == NULL)
+    {
+      return NULL;
     }
-    else {
-      Node_Vector = list->next;
+  if (list->node->id == node->id)
+    {
+      // TODO delete the entry
+      toremove = list;
+      LOG_D (OMG, "removed entry for node %d \n", list->node->id);
+      if (list->next == NULL)
+	{
+	  node_vector = NULL;
+	  return NULL;
+	}
+      else
+	{
+	  node_vector = list->next;
+	}
+    }
+  else
+    {
+      while (list->next != NULL)
+	{
+	  tmp = list;
+	  if (list->next->node->id == node->id)
+	    {
+	      toremove = tmp;	// TODO delete the entry
+	      tmp = list->next->next;
+	      if (tmp != NULL)
+		{
+		  list->next = tmp;
+		}
+	      else
+		{
+		  list->next = NULL;
+		}
+	    }
+	}
     }
-  } 
-  else{
-     while (list->next !=NULL) {
-       tmp = list;
-       if(list->next->node->ID == node->ID) {
-          toRemove = tmp; // TODO delete the entry
-          tmp = list->next->next;
-          if(tmp !=NULL) {
-             list->next = tmp;
-          }
-          else{
-             list->next = NULL; 
-          }
-       }
-     }
-  }
-  return Node_Vector;
+  return node_vector;
 }
 
 
 // display list of nodes
-void display_node_list(Node_list Node_Vector){
-    Node_list tmp = Node_Vector;
-    
-    while ((tmp != NULL) &&
-	   (tmp->node != NULL)){
-      LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.3f, %.3f)\n", 
-	    map_int_to_str(mob_type, tmp->node->generator),
-	    map_int_to_str(nodes_type, tmp->node->type),  
-	    tmp->node->ID,
-	    map_int_to_str(nodes_status, tmp->node->mobile), 
-	    tmp->node->X_pos,
-	    tmp->node->Y_pos );
-
-    //LOG_I(OMG, "node number %d\tstatus(fix/mobile) %d\tX_pos %.2f\tY_pos %.2f\tnode_type(eNB, UE)%d\t", tmp->node->ID,tmp->node->mobile, tmp->node->X_pos,tmp->node->Y_pos, tmp->node->type);
+void
+display_node_list (node_list * node_vector)
+{
+  node_list *tmp = node_vector;
+  if (tmp == NULL)
+    {
+#ifdef STANDALONE
+      printf ("Empty Node_list\n");
+#else
+      LOG_I (OMG, "Empty Node_list\n");
+#endif
+    }
+  while (tmp != NULL)
+    {
+      /*LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.3f, %.3f)\n", 
+         map_int_to_str(mob_type, tmp->node->generator),
+         map_int_to_str(nodes_type, tmp->node->type),  
+         tmp->node->ID,
+         map_int_to_str(nodes_status, tmp->node->mobile), 
+         tmp->node->X_pos,
+         tmp->node->Y_pos ); */
+      LOG_I (OMG, "[%s %d][%s] \t at (%.3f, %.3f)\n",
+	     		map_int_to_str(nodes_type, tmp->node->type),  
+          tmp->node->id,
+					map_int_to_str(mob_type, tmp->node->generator),
+          tmp->node->x_pos, tmp->node->y_pos);
+			
+				// two options: view node mobility of one node during the entire simulation or just a snapshot of all nodes for different timestamps
+		// note:gnu plot requiredifferent files for each timestamp
+			//use a python script to postprocess the positions, check the
+	
+// support: view node mobility of one node during the entire simulation OR only one snapshot
+		LOG_F(OMG,"%d; %.3f; %.3f; %.3f\n",
+					tmp->node->id,
+		      tmp->node->x_pos, tmp->node->y_pos);
+
+      //LOG_I(OMG, "node number %d\tstatus(fix/mobile) %d\tX_pos %.2f\tY_pos %.2f\tnode_type(eNB, UE)%d\t", tmp->node->ID,tmp->node->mobile, tmp->node->X_pos,tmp->node->Y_pos, tmp->node->type);
       //LOG_D(OMG, "mob->X_from %.3f\tmob->Y_from %.3f\tmob->X_to %.3f\tmob->Y_to %.3f\t", tmp->node->mob->X_from,tmp->node->mob->Y_from, tmp->node->mob->X_to, tmp->node->mob->Y_to );
       tmp = tmp->next;
     }
 }
 
-void display_node_position(int ID, int generator, int type, int mobile, double X, double Y){
-  LOG_I(OMG,"[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n", 
-	map_int_to_str(mob_type, generator),
-	map_int_to_str(nodes_type, type),  
-	ID,
-	map_int_to_str(nodes_status, mobile),
-	X,
-	Y
-	);
+void
+display_node_position (int id, int generator, int type, int mobile, double x,
+		       double y)
+{
+  LOG_I (OMG,
+	 "[%s][%s] Node of ID %d is %s. Now, it is at location (%.2f, %.2f) \n",
+	 map_int_to_str (mob_type, generator), map_int_to_str (nodes_type,
+							       type), id,
+	 map_int_to_str (nodes_status, mobile), x, y);
 }
 
-Node_list filter(Node_list Vector, int node_type){
-  Node_list tmp1, tmp2;
-  tmp1 = Vector;
+node_list *
+filter (node_list * vector, int node_type)
+{
+  node_list *tmp1, *tmp2;
+  tmp1 = vector;
   tmp2 = NULL;
-  while (tmp1 != NULL){
-    if (tmp1->node->type == node_type){
-      tmp2 = add_entry(tmp1->node, tmp2);
+  while (tmp1 != NULL)
+    {
+      if (tmp1->node->type == node_type)
+	{
+	  tmp2 = add_entry (tmp1->node, tmp2);
+	}
+      tmp1 = tmp1->next;
     }
-    tmp1 = tmp1->next;
-  }
   return tmp2;
 }
 
-void delete_node_entry(Node_list entry) {
-	NodePtr node = entry->node;
-	delete_node(node);
-        entry->node = NULL;
-        free(entry);
+
+void
+delete_node_entry (node_list * entry)
+{
+  node_struct *node = entry->node;
+  delete_node (node);
+  entry->node = NULL;
+  free (entry);
 }
 
-Node_list remove_node(Node_list list, int nID, int node_type){
-  
+node_list *
+remove_node (node_list * list, int nid, int node_type)
+{
+
   int found;
-  Node_list  current, previous;
+  node_list *current, *previous;
   //int cond=0;
   //int i=0;
-  if (list == NULL){  
-    found = 1; //false
-    return NULL;
-  } 
-  else{                             //start search
-    current = list;
-    while ((current != NULL) && ((current->node->ID != nID) || (current->node->type != node_type ))){
-      previous = current;        //  previous hobbles after
-      current = current->next;
-    }
-    //holds: current = NULL or  type != node_type or.., but not both
-    if (current ==NULL) { 
-      found= 1  ;
-      LOG_E(OMG," Element to remove is not found\n "); 
+  if (list == NULL)
+    {
+      found = 1;		//false
       return NULL;
-    }              //value not found
-    else{
-      found = 0; // true                value found
-      if (current == list) {
-	list = current->next;
-	LOG_D(OMG,"Element to remove is found at beginning\n");
-      }    
-      
-      else {
-	previous->next = current->next;
-	
-      }
-      delete_node_entry(current); // freeing memory
-      current = NULL;
-      
     }
-    return list;
-  }
-}
+  else
+    {				//start search
+      current = list;
+      while ((current != NULL)
+	     && ((current->node->id != nid)
+		 || (current->node->type != node_type)))
+	{
+	  previous = current;	//  previous hobbles after
+	  current = current->next;
+	}
+      //holds: current = NULL or  type != node_type or.., but not both
+      if (current == NULL)
+	{
+	  found = 1;
+	  LOG_E (OMG, " Element to remove is not found\n ");
+	  return NULL;
+	}			//value not found
+      else
+	{
+	  found = 0;		// true                value found
+	  if (current == list)
+	    {
+	      list = current->next;
+	      LOG_D (OMG, "Element to remove is found at beginning\n");
+	    }
+
+	  else
+	    {
+	      previous->next = current->next;
+
+	    }
+	  delete_node_entry (current);	// freeing memory
+	  current = NULL;
 
-int length(char* s){
-	int count = 0;
-	while(s[count] != '\0'){
-		++count;
 	}
-	return count;
+      return list;
+    }
 }
 
-NodePtr find_node(Node_list list, int nID, int node_type){
-  
+int
+length (char *s)
+{
+  int count = 0;
+  while (s[count] != '\0')
+    {
+      ++count;
+    }
+  return count;
+}
+
+node_struct *
+find_node (node_list * list, int nid, int node_type)
+{
+
   int found;
-  Node_list  current;
- 
-  if (list == NULL){  
-    printf(" Node_LIST for nodeID %d is NULL \n ",nID);
-    return NULL;
-  } 
-  else{                             //start search
-    current = list;
-    while ((current != NULL) && ((current->node->ID != nID) || (current->node->type != node_type ))){
-      current = current->next;
+  node_list *current;
+
+  if (list == NULL)
+    {
+      printf (" Node_LIST for nodeID %d is NULL \n ", nid);
+      return NULL;
     }
-    //holds: current = NULL or  type != node_type or.., but not both
-    if (current ==NULL) { 
-      found= 1  ;
-      LOG_D(OMG," Element to find in Node_Vector with ID: %d could not be found\n ",nID); 
+  else
+    {				//start search
+      current = list;
+      while ((current != NULL)
+	     && ((current->node->id != nid)
+		 || (current->node->type != node_type)))
+	{
+	  current = current->next;
+	}
+      //holds: current = NULL or  type != node_type or.., but not both
+      if (current == NULL)
+	{
+	  found = 1;
+	  LOG_D (OMG,
+		 " Element to find in Node_Vector with ID: %d could not be found\n ",
+		 nid);
+	  return NULL;
+	}			//value not found
+      else
+	{
+	  //printf(" found a node for nodeID %d  \n ",nID);
+	  return current->node;
+	}
       return NULL;
-    }              //value not found
-    else{
-      //printf(" found a node for nodeID %d  \n ",nID);
-      return current->node;
     }
-    return NULL;
-  }
 }
 
-Node_list clear_node_list(Node_list list) {
-  Node_list  tmp;
-
-  if (list == NULL){  
-    return NULL;
-  } 
-  else{
-     while (list->next !=NULL) {
-       tmp = list;
-       list = list->next;
-       delete_node_entry(tmp); 
-     }
-     delete_node_entry(list); // clearing the last one
-  }
+node_list *
+clear_node_list (node_list * list)
+{
+  node_list *tmp;
+
+  if (list == NULL)
+    {
+      return NULL;
+    }
+  else
+    {
+      while (list->next != NULL)
+	{
+	  tmp = list;
+	  list = list->next;
+	  delete_node_entry (tmp);
+	}
+      delete_node_entry (list);	// clearing the last one
+    }
   return NULL;
 }
 
 // TODO rewrite this part...not working correctly
-Node_list reset_node_list(Node_list list) {
-  Node_list  tmp;
-  Node_list last = list;
-  if (list == NULL){  
-    //printf("Node_list is NULL\n");
-    return NULL;
-  } 
-  else{
-     while (list->next !=NULL) {
-       tmp = list;
-       list = list->next;
-       tmp->node = NULL;
-       //free(tmp);
-     }
-     list->node = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
-     //free(last);
-  }
+node_list *
+reset_node_list (node_list * list)
+{
+  node_list *tmp;
+  node_list *last = list;
+  if (list == NULL)
+    {
+      //printf("Node_list is NULL\n");
+      return NULL;
+    }
+  else
+    {
+      while (list->next != NULL)
+	{
+	  tmp = list;
+	  list = list->next;
+	  tmp->node = NULL;
+	  //free(tmp);
+	}
+      list->node = NULL;	// clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
+      //free(last);
+    }
   return list;
 }
 
 // TODO rewrite this part...not working correctly
-String_list clear_String_list(String_list list) {
-   String_list  tmp;
-
-   if (list == NULL){  
-    return NULL;
-   } 
-   else{
-     while (list->next !=NULL) {
-       tmp = list;
-       list = list->next;
-       free(tmp->string);
-       tmp->string = NULL;
-       free(tmp);
-     }
-     list->string = NULL; // clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
-  }
+string_list *
+clear_string_list (string_list * list)
+{
+  string_list *tmp;
+
+  if (list == NULL)
+    {
+      return NULL;
+    }
+  else
+    {
+      while (list->next != NULL)
+	{
+	  tmp = list;
+	  list = list->next;
+	  free (tmp->string);
+	  tmp->string = NULL;
+	  free (tmp);
+	}
+      list->string = NULL;	// clearing the last one | JHNOTE: dangerous here: the pointer is not NULL, but node is...that leads to segfault...
+    }
   return list;
 }
 
@@ -347,32 +442,43 @@ String_list clear_String_list(String_list list) {
  * with string value NULL
  */
 /* map a string to an int. Takes a mapping array and a string as arg */
-int map_str_to_int(mapping *map, const char *str){
-    while (1) {
-        if (map->name == NULL) {
-            return(-1);
-        }
-        if (!strcmp(map->name, str)) {
-            return(map->value);
-        }
-        map++;
+int
+map_str_to_int (mapping * map, const char *str)
+{
+  while (1)
+    {
+      if (map->name == NULL)
+	{
+	  return (-1);
+	}
+      if (!strcmp (map->name, str))
+	{
+	  return (map->value);
+	}
+      map++;
     }
 }
 
 /* map an int to a string. Takes a mapping array and a value */
-char *map_int_to_str(mapping *map, int val) {
-    while (1) {
-        if (map->name == NULL) {
-            return NULL;
-        }
-        if (map->value == val) {
-            return map->name;
-        }
-        map++;
+char *
+map_int_to_str (mapping * map, int val)
+{
+  while (1)
+    {
+      if (map->name == NULL)
+	{
+	  return NULL;
+	}
+      if (map->value == val)
+	{
+	  return map->name;
+	}
+      map++;
     }
 }
 
-#endif
 
 
 
+
+#endif
diff --git a/openair2/UTIL/OMG/defs.h b/openair2/UTIL/OMG/defs.h
index 6ee2b6c71f14285635a5ea16642afbaf7ebf29d9..118971d32e484ca121ccc4d5d64b061c61bbbc16 100644
--- a/openair2/UTIL/OMG/defs.h
+++ b/openair2/UTIL/OMG/defs.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Eurecom OpenAirInterface
-  Copyright(c) 1999 - 2014 Eurecom
+  Copyright(c) 1999 - 2011 Eurecom
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -28,16 +28,9 @@
 *******************************************************************************/
 
 /**
-* \file defs.h
-* \brief Typedefs & Prototypes of OMG functions
-* \author Navid Nikaein and Andre Gomes (one source)
-* \date 2014
-* \version 1.0
-* \company Eurecom
-* \email: navid.nikaein@eurecom.fr
-* \note
-* \warning
-*/
+ * \file defs.h
+ * \brief Typedefs & Prototypes of OMG functions
+ */
 
 #ifndef __DEFS_H__
 #define  __DEFS_H__
@@ -61,69 +54,90 @@ int  map_str_to_int(mapping *map, const char *str);
 char *map_int_to_str(mapping *map, int val);
 #endif
 
-/*!A sructure that includes all the characteristic mobility elements of a node  */
-typedef struct mobility_struct {
-	double X_from; /*!< The X coordinate of the previous location of the node */
-	double Y_from; /*!< The Y coordinate of the previous location of the node */
-	double X_to; /*!< The X coordinate of the destination location of the node */
-	double Y_to; /*!< The Y coordinate of the destination location of the node */
+/****************************************************************************
+!A sructure that includes all the characteristic mobility elements of a node 
+*****************************************************************************/
+struct mobility_struct {
+	double x_from; /*!< The X coordinate of the previous location of the node */
+	double y_from; /*!< The Y coordinate of the previous location of the node */
+	double x_to; /*!< The X coordinate of the destination location of the node */
+	double y_to; /*!< The Y coordinate of the destination location of the node */
 	double speed; /*!< The speed of the node */
 	double sleep_duration; /*!< The sleep duration of the node (Used with the RWP model) */
 	double azimuth; /*!< The direction in which the node moves (Used with RWALK model) */
 	double journey_time; /*!< The duration of the node trip */
 	double start_journey; /*!< The instant on which the node trip starts*/
-  double target_time;/*!<The time instant before the node should complete>*/  double target_speed;/*!<The time instant before the node should complete>*/
-}mobility_struct;
+        double target_time;/*!<The time instant before the node should complete>*/  
+        double target_speed;/*!<The time instant before the node should complete>*/
+};
 
-typedef struct mobility_struct *MobilityPtr; /*!< The typedef that reflects a #mobility_struct*/
+typedef struct mobility_struct mobility_struct; /*!< The typedef that reflects a #mobility_struct*/
 
-/*!A sructure that defines a node and its associated informaion  */
-typedef struct node_struct {
-	int ID; /*!< The identifier of the node in question */
+/******************************************************************************
+!A sructure that defines a node and its associated informaion 
+*******************************************************************************/
+struct node_struct {
+	int id; /*!< The identifier of the node in question */
+        int gid;  /*!< given id of node used for trace mobility */
 	int type; /*!< The node's type, it is one of types enumarated in #node_types */
 	int mobile;  /*!< The node status: static or mobile  */
-	double X_pos; /*!< The X coordinate of the current location of the node */
-	double Y_pos; /*!< The Y coordinate of the current location of the node */
-	mobility_struct *mob; /*!< An instantiation of the structure #mobility_struct that includes the mobility elements corresponding to the node*/
+	double x_pos; /*!< The X coordinate of the current location of the node */
+	double y_pos; /*!< The Y coordinate of the current location of the node */
+	struct mobility_struct *mob; /*!< An instantiation of the structure #mobility_struct that includes the mobility elements corresponding to the node*/
 	int generator; /*!< The mobility generator according to which the node is moving or stagnating. It is one of the types enumarated in #mobility_types*/
-}node_struct;
+        int block_num; /*!<block identification for connected domain rwp*/
+        int event_num;
+};
 
-typedef struct node_struct* NodePtr; /*!< The typedef that reflects a #node_struct*/
+typedef struct node_struct node_struct; /*!< The typedef that reflects a #node_struct*/
 
-/*!A sructure that gathers all the existing nodes */
+/********************************************************************************
+!A sructure that gathers all the existing nodes 
+*********************************************************************************/
 struct node_list_struct {
-	node_struct *node;  /*!< Avariable of type #NodePtr. It represents a node */
+	struct node_struct *node;  /*!< Avariable of type #NodePtr. It represents a node */
 	struct node_list_struct *next; /*!< A pointer to the next element */
-}node_list_struct;
+};
 
-typedef struct node_list_struct* Node_list; /*!< The typedef that reflects a #node_list_struct*/
+typedef struct node_list_struct node_list; /*!< The typedef that reflects a #node_list_struct*/
 
-/*!A sructure that represents a peer (Node, Time), i.e the node in question and its job (move or sleep) execution time. It is the atomic component of the #job_list_struct structure*/
-typedef struct pair_struct {
+/********************************************************************************
+!A sructure that represents a peer (Node, Time), 
+i.e the node in question and its job (move or sleep) execution time. 
+It is the atomic component of the #job_list_struct structure
+*********************************************************************************/
+
+struct pair_struct {
 	node_struct *b; /*!< A variable of type #NodePtr. It represents a node */
-	double a;  /*!< The corresponding time of job execution */
-}pair_struct;
+	double next_event_t;  /*!< The corresponding time of job execution */
+};
 
-typedef struct pair_struct* Pair;  /*!< The typedef that reflects a #pair_struct*/
+typedef struct pair_struct pair_struct;  /*!< The typedef that reflects a #pair_struct*/
 
 
-/*!A sructure that gathers the jobs to be executed by all the non static nodes. In the context of OMG, a job is either a move or a sleep */
+/*****************************************************************************
+!A sructure that gathers the jobs to be executed by all the non static nodes.
+In the context of OMG, a job is either a move or a sleep 
+*****************************************************************************/
 struct job_list_struct {
-	Pair pair; /*!< A variable of type #Pair. It represents a (Node, job-execution Time) peer */
+	pair_struct* pair; /*!< A variable of type #Pair. It represents a (Node, job-execution Time) peer */
 	struct job_list_struct *next; /*!< A pointer to the next element */
-}job_list_struct;
-typedef struct job_list_struct* Job_list;  /*!< The typedef that reflects a #job_list_struct*/
+};
+typedef struct job_list_struct job_list;  /*!< The typedef that reflects a #job_list_struct*/
 
-/*!A sructure that gathers the ultimate parameters needed to launch a simulation scenario */
-typedef struct omg_global_param{
+/****************************************************************************************
+!A sructure that gathers the ultimate parameters needed to launch a simulation scenario 
+***************************************************************************************/
+typedef struct{
 	int nodes; /*!< The total number of nodes */
-	double min_X; /*!< The minimum value that the X coordinate might take. In other words, the minimum boundary of the simulation area according to the X axis */
-	double max_X; /*!< The maximum value that the X coordinate might take, i.e the maximum boundary of the simulation area according to the X axis*/
-	double min_Y; /*!< The minimum value that the Y coordinate might take, i.e the minimum boundary of the simulation area according to the Y axis */
-	double max_Y; /*!< The minimum value that the Y coordinate might take, i.e the maximum boundary of the simulation area according to the Y axis */
-	bool user_fixed; /*!< Sets if the coordinates are user defined*/
-	double fixed_X; /*!< The user defined x value*/
-	double fixed_Y; /*!< The user defined y value*/
+        //int number_of_nodes[MAX_NUM_NODE_TYPES];
+	double min_x; /*!< The minimum value that the X coordinate might take. In other words, the minimum boundary of the simulation area according to the X axis */
+	double max_x; /*!< The maximum value that the X coordinate might take, i.e the maximum boundary of the simulation area according to the X axis*/
+	double min_y; /*!< The minimum value that the Y coordinate might take, i.e the minimum boundary of the simulation area according to the Y axis */
+	double max_y; /*!< The minimum value that the Y coordinate might take, i.e the maximum boundary of the simulation area according to the Y axis */
+  bool user_fixed; /*!< Sets if the coordinates are user defined*/
+	double fixed_x; /*!< The user defined x value*/
+	double fixed_y; /*!< The user defined y value*/
 	double min_speed; /*!< The minimum speed. It should be different than 0.0 in order to avoid instability*/ 
 	double max_speed; /*!< The maximum allowed speed */ 
 	double min_journey_time; /*!< The minimum allowed trip duration. It should be different than 0.0 in order to avoid instability and properly reflect the mobility model behavior */ 
@@ -133,7 +147,12 @@ typedef struct omg_global_param{
 	double min_sleep; /*!< The minimum allowed sleep duration. It should be different than 0.0 in order to avoid instability */
 	double max_sleep; /*!< The minimum allowed sleep duration*/
 	int mobility_type; /*!< The chosen mobility model for the nodes in question. It should be one of the types inumarated as #mobility_types*/
+	int rwp_type; /*!< The chosen RWP  mobility model for the nodes in question either RESTRICTED or CONNECTED_DOMAIN. */
 	int nodes_type; /*!< The type of the nodes in question. It should be one of the types inumarated as #node_types */
+        //int nodes_mob_type[MAX_NUM_NODE_TYPES];
+        int max_vertices; /*!<maximum number of verices in the grid>*/
+        int max_block_num; /*!<maximum number of blocks in the grid>*/
+
   	int seed; /*!< The seed used to generate the random positions*/
 	char* mobility_file; /*!< The mobility file name containing the mobility traces used by the TRACE model; DEFAULT: TRACE/example_trace.tr */
         char* sumo_command; /*!< The command to start SUMO; Either 'sumo' or 'sumo-gui' in case a GUI would be required; see SUMO for further details; DEFAULT: sumo */
@@ -145,13 +164,15 @@ typedef struct omg_global_param{
         int sumo_port; /*!< The port number attached to SUMO on the host DEFAULT: TBC */
 }omg_global_param;  
 
-/*!A string List structure */
+/******************************************************************************
+!A string List structure
+*******************************************************************************/
 struct string_list_struct {
 	char* string;  /*! a string */
 	struct string_list_struct *next; /*!< A pointer to the next string in the list */
-}string_list_struct;
+};
 
-typedef struct string_list_struct* String_list; /*!< The typedef that reflects a #string_list_struct*/
+typedef struct string_list_struct string_list; /*!< The typedef that reflects a #string_list_struct*/
 
 /* PROTOTYPES */
 
@@ -171,7 +192,7 @@ void update_node_vector(int mobility_type, double cur_time);
  * \param nID a variable of type int that represents the specific node's ID
  * \return a NodePtr structure that stores the updated information about the specific node ((X,Y) coordinates), speed, etc.)
  */
-NodePtr get_node_position(int node_type, int nID);
+node_struct* get_node_position(int node_type, int nid);
 
 
 /**
@@ -181,7 +202,7 @@ NodePtr get_node_position(int node_type, int nID);
  * \param Node_Vector a pointer of type Node_list that represents the Node_Vector storing all the nodes of the specified mobility type
  * \return the Node_list to which a new entry is added
  */
-Node_list add_entry(NodePtr node, Node_list Node_Vector);
+node_list* add_entry(node_struct* node, node_list* node_vector);
 
 /**
  * \fn Node_list remove_node_entry(NodePtr node, Node_list Node_Vector)
@@ -191,14 +212,14 @@ Node_list add_entry(NodePtr node, Node_list Node_Vector);
  * \param Node_Vector a pointer of type Node_list that represents the Node_Vector storing all the nodes of the specified mobility type
  * \return the Node_list to which a new entry is removed
  */
-Node_list remove_node_entry(NodePtr node, Node_list Node_Vector);
+node_list* remove_node_entry(node_struct* node, node_list* node_vector);
 
 /**
  * \fn void display_node_list(Node_list Node_Vector)
  * \brief Display the useful informaion about the specified Node_list (for instance the nodes IDs, their types (UE, eNB, etc.), their corresponding mobility models, their status (moving, sleeping) and  their current positions)
  * \param Node_Vector a pointer of type Node_list that represents the Node_list to be dispalyed
  */
-void display_node_list(Node_list Node_Vector);
+void display_node_list(node_list* node_vector);
 
 
 /**
@@ -209,7 +230,7 @@ void display_node_list(Node_list Node_Vector);
  * \param node_type an int that represents the type of the node to be removed from the Node_list
  * \return a pointer to the Node_list from which a new entry is removed
  */
-Node_list remove_node(Node_list list, int nID, int node_type);
+node_list* remove_node(node_list* list, int nid, int node_type);
 
 /**
  * \fn NodePtr find_node(Node_list list, int nID, int node_type)
@@ -219,21 +240,21 @@ Node_list remove_node(Node_list list, int nID, int node_type);
  * \param node_type an int that represents the type of the node to be located in the Node_list
  * \return a pointer to the Node
  */
-NodePtr find_node(Node_list list, int nID, int node_type);
+node_struct* find_node(node_list* list, int nid, int node_type);
 
 /**
  * \fn void delete_entry(Node_list Node_Vector)
  * \brief Delete a Node_list entry node; calls delete_node to subsequently delete the node; free the memory
  * \param list a pointer of type Node_list that represents the entry to be deleted
  */
-void delete_entry(Node_list Node_Vector);
+void delete_entry(node_list* node_vector);
 
 /**
  * \fn void delete_entry(NodePtr node)
  * \brief Delete a node, and all subsequent data in its structure; free the memory
  * \param node a pointer to the node that should be deleted
  */
-void delete_node(NodePtr node);
+void delete_node(node_struct* node);
 
 /**
  * \fn void clear node_List(Node_list list)
@@ -241,7 +262,7 @@ void delete_node(NodePtr node);
  * \param list a pointer of type Node_list that represents the list to be cleared
  * \return reference to the HEAD of the cleared Node_list
  */
-Node_list clear_node_List(Node_list list);
+node_list* clear_node_List(node_list* list);
 
 /**
  * \fn void init_node_list(Node_list list)
@@ -249,7 +270,7 @@ Node_list clear_node_List(Node_list list);
  * \param list a pointer of type Node_list that represents the list to be reset
  * \return reference to the HEAD of the reset Node_list
  */
-Node_list reset_node_list(Node_list list);
+node_list* reset_node_list(node_list* list);
 
 /**
  * \fn void display_node_position(int ID, int generator, int type, int mobile, double X, double Y)
@@ -261,7 +282,7 @@ Node_list reset_node_list(Node_list list);
  * \param X the node's current location according to the X axis 
  * \param Y the node's current location according to the Y axis
  */
-void display_node_position(int ID, int generator, int type, int mobile, double X, double Y);
+void display_node_position(int id, int generator, int type, int mobile, double x, double y);
 
 
 /**
@@ -271,7 +292,7 @@ void display_node_position(int ID, int generator, int type, int mobile, double X
  * \param node_type the desired type 
  * \return a pointer to a new Node_list which is the input Node_list after filtering 
  */
-Node_list filter(Node_list Vector, int node_type);
+node_list* filter(node_list* vector, int node_type);
 
 
 /**
@@ -281,7 +302,7 @@ Node_list filter(Node_list Vector, int node_type);
  * \param b upper limit
  * \return double: the generated random number
  */
-double randomGen(double a, double b);
+double randomgen(double a, double b);
 
 
 /**
@@ -289,7 +310,7 @@ double randomGen(double a, double b);
  * \brief Creates a new #NodePtr by allocating the needed memory space for it 
  * \return the created node structure
  */
-NodePtr create_node(void);
+node_struct* create_node(void);
 
 
 /**
@@ -297,7 +318,7 @@ NodePtr create_node(void);
  * \brief Creates a new #MobilityPtr by allocating the needed memory space for it 
  * \return the created mobility structure
  */
-MobilityPtr create_mobility(void);
+mobility_struct* create_mobility(void);
 
 
 /**
@@ -307,7 +328,8 @@ MobilityPtr create_mobility(void);
  * \param Job_Vector a variable #Job_list that represents the Job_list that stores all the scheduled jobs
  * \return the created mobility structure
  */
-Job_list add_job(Pair job, Job_list Job_Vector);
+job_list* add_job(pair_struct* job, job_list* job_vector);
+job_list* addjob(pair_struct* job, job_list* job_vector);
 
 
 /**
@@ -315,9 +337,11 @@ Job_list add_job(Pair job, Job_list Job_Vector);
  * \brief Traverse the Job_Vector to diplay its contents
  * \param Job_Vector the structure that stoks all the jobs
  */
-void display_job_list(Job_list Job_Vector);
-
-
+void display_job_list(double curr_t, job_list* job_vector);
+/**
+*time average of nodes speed
+*/
+unsigned int nodes_avgspeed(job_list* job_vector);
 /**
  * \fn Job_list job_list_sort (Job_list list, Job_list end)
  * \brief Called by the function Job_list quick_sort (Job_list list), it executes the quick sort
@@ -325,7 +349,7 @@ void display_job_list(Job_list Job_Vector);
  * \param end Job_list needed for intermediate computation
  * \return a Job_list that is used by Job_list quick_sort (Job_list list) to perform the sort operation
  */
-Job_list job_list_sort (Job_list list, Job_list end);
+job_list* job_list_sort (job_list* list, job_list* end);
 
 
 /**
@@ -334,7 +358,7 @@ Job_list job_list_sort (Job_list list, Job_list end);
  * \param list the structure that stoks all the jobs
  * \return the sorted list
  */
-Job_list quick_sort (Job_list list);
+job_list* quick_sort (job_list* list);
 
 
 /**
@@ -345,7 +369,7 @@ Job_list quick_sort (Job_list list);
  * \param node_type the type of the node whose job should be removed
  * \return the updated Job_list after removing the job in question 
  */
-Job_list remove_job(Job_list list, int nID, int node_type);
+job_list* remove_job(job_list* list, int nid, int node_type);
 
 /**
  * \fn int length(char* s)
@@ -361,7 +385,7 @@ int length(char* s);
  * \param list the String_list to be cleared; 
  * \return reference to the HEAD of the cleared String_list
  */
-String_list clear_String_list(String_list list);
+string_list* clear_string_list(string_list* list);
 
 /**
  * \fn void usage()
diff --git a/openair2/UTIL/OMG/grid.c b/openair2/UTIL/OMG/grid.c
new file mode 100644
index 0000000000000000000000000000000000000000..9101b142c1d92281cab6572d902bff9f1e80c4d4
--- /dev/null
+++ b/openair2/UTIL/OMG/grid.c
@@ -0,0 +1,242 @@
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2011 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.frm
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fsr/openairinterface
+  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
+
+*******************************************************************************/
+
+/*! \file grid.c
+* \brief 
+* \author S. Gashaw, N. Nikaein, J. Harri
+* \date 2014
+* \version 0.1
+* \company Eurecom
+* \email: 
+* \note
+* \warning 
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include "grid.h"
+#define   LEFT 0
+#define   RIGHT 1
+#define   UPPER 2
+#define   LOWER 3
+
+int
+max_vertices_ongrid (omg_global_param omg_param)
+{
+  return ((int) (omg_param.max_x / xloc_div + 1.0) *
+	  (int) (omg_param.max_y / yloc_div + 1.0)) - 1;
+}
+
+int
+max_connecteddomains_ongrid (omg_global_param omg_param)
+{
+  return ((int) (omg_param.max_x / xloc_div) *
+	  (int) (omg_param.max_y / yloc_div)) - 1;
+}
+
+double
+vertice_xpos (int loc_num, omg_global_param omg_param)
+{
+  int div, mod;
+  double x_pos;
+
+  div = (int) (omg_param.max_x / xloc_div + 1.0);
+  mod = (loc_num % div) * xloc_div;
+  x_pos = omg_param.min_x + (double) mod;
+  //LOG_D(OMG,"mod %d div %d x pos %.2f \n\n",mod,div,x_pos);
+  return x_pos;
+}
+
+double
+vertice_ypos (int loc_num, omg_global_param omg_param)
+{
+  //LOG_D(OMG,"y pos %.2f \n\n",omg_param.min_y + (double)yloc_div * (int)( loc_num / (int)(omg_param.max_x/xloc_div + 1.0) ));
+  return omg_param.min_y +
+    (double) yloc_div *(int) (loc_num /
+			      (int) (omg_param.max_x / xloc_div + 1.0));
+}
+
+double
+area_minx (int block_num, omg_global_param omg_param)
+{
+  return omg_param.min_x +
+    xloc_div * (block_num % (int) (omg_param.max_x / xloc_div));
+
+}
+
+double
+area_miny (int block_num, omg_global_param omg_param)
+{
+  return omg_param.min_y +
+    yloc_div * (int) (block_num / (int) (omg_param.max_x / xloc_div));
+}
+
+/*for connected domain that only move to the neighbor domains */
+
+unsigned int
+next_block (int current_bn, omg_global_param omg_param)
+{
+
+  double rnd = randomgen (0, 1);
+  unsigned int blk;
+  int div = (int) (omg_param.max_x / xloc_div);
+
+/*left border blocks*/
+  if ((current_bn % div) == 0)
+    {
+      /*case 1 for left upper and lower corners(only 2 neighbors) */
+      if ((int) (current_bn / div) == 0)
+	{
+	  if (rnd <= 0.5)
+	    blk = selected_blockn (current_bn, RIGHT, div);
+	  else
+	    blk = selected_blockn (current_bn, UPPER, div);
+	}
+      else if ((int) (current_bn / div) ==
+	       (int) (omg_param.max_y / yloc_div) - 1)
+	{
+	  if (rnd <= 0.5)
+	    blk = selected_blockn (current_bn, RIGHT, div);
+	  else
+	    blk = selected_blockn (current_bn, LOWER, div);
+	}
+      /*for 3 neighbor blocks */
+      else
+	{
+	  if (rnd <= 0.33)
+	    blk = selected_blockn (current_bn, RIGHT, div);
+	  else if (rnd > 0.33 && rnd <= 0.66)
+	    blk = selected_blockn (current_bn, UPPER, div);
+	  else
+	    blk = selected_blockn (current_bn, LOWER, div);
+	}
+
+    }
+/*right boredr blocks*/
+  else if ((current_bn % (int) (omg_param.max_x / xloc_div)) == div - 1)
+    {
+      /*case 1 for right upper and lower corners(only 2 neighbors) */
+      if ((int) (current_bn / div) == 0)
+	{
+	  if (rnd <= 0.5)
+	    blk = selected_blockn (current_bn, LEFT, div);
+	  else
+	    blk = selected_blockn (current_bn, UPPER, div);
+	}
+      else if ((int) (current_bn / div) ==
+	       (int) (omg_param.max_y / yloc_div) - 1)
+	{
+	  if (rnd <= 0.5)
+	    blk = selected_blockn (current_bn, LEFT, div);
+	  else
+	    blk = selected_blockn (current_bn, LOWER, div);
+	}
+      /*for 3 neighbor blocks */
+      else
+	{
+	  if (rnd <= 0.33)
+	    blk = selected_blockn (current_bn, LEFT, div);
+	  else if (rnd > 0.33 && rnd <= 0.66)
+	    blk = selected_blockn (current_bn, UPPER, div);
+	  else
+	    blk = selected_blockn (current_bn, LOWER, div);
+	}
+
+
+    }
+/*for 3 neighbor uper and lower borders*/
+  else if ((int) (current_bn / div) == 0
+	   || (int) (current_bn / div) ==
+	   (int) (omg_param.max_y / yloc_div) - 1)
+    {
+
+      if ((int) (current_bn / div) == 0)
+	{
+	  if (rnd <= 0.33)
+	    blk = selected_blockn (current_bn, LEFT, div);
+	  else if (rnd > 0.33 && rnd <= 0.66)
+	    blk = selected_blockn (current_bn, RIGHT, div);
+	  else
+	    blk = selected_blockn (current_bn, UPPER, div);
+	}
+
+      else
+	{
+	  if (rnd <= 0.33)
+	    blk = selected_blockn (current_bn, LEFT, div);
+	  else if (rnd > 0.33 && rnd <= 0.66)
+	    blk = selected_blockn (current_bn, RIGHT, div);
+	  else
+	    blk = selected_blockn (current_bn, LOWER, div);
+	}
+
+    }
+  else
+    {
+      if (rnd <= 0.25)
+	blk = selected_blockn (current_bn, LEFT, div);
+      else if (rnd > 0.25 && rnd <= 0.50)
+	blk = selected_blockn (current_bn, RIGHT, div);
+      else if (rnd > 0.50 && rnd <= 0.75)
+	blk = selected_blockn (current_bn, UPPER, div);
+      else
+	blk = selected_blockn (current_bn, LOWER, div);
+    }
+
+
+  return blk;
+
+}
+
+/*retun the block number of neighbor selected for next move */
+unsigned int
+selected_blockn (int block_n, int type, int div)
+{
+  unsigned int next_blk = 0;
+  switch (type)
+    {
+    case LEFT:
+      next_blk = block_n - 1;
+      break;
+    case RIGHT:
+      next_blk = block_n + 1;
+      break;
+    case UPPER:
+      next_blk = block_n + div;
+      break;
+    case LOWER:
+      next_blk = block_n - div;
+      break;
+    default:
+      LOG_E (OMG, "wrong type input\n");
+    }
+  return next_blk;
+
+}
diff --git a/openair2/UTIL/OMG/grid.h b/openair2/UTIL/OMG/grid.h
new file mode 100644
index 0000000000000000000000000000000000000000..a64b2f21a874bc599c27bc5d14c79cdec9b73998
--- /dev/null
+++ b/openair2/UTIL/OMG/grid.h
@@ -0,0 +1,60 @@
+
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2011 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.fr
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fsr/openairinterface
+  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
+
+*******************************************************************************/
+
+/**
+ * \file grid.h **/
+
+#ifndef GRID_H_
+#define GRID_H_
+
+#include "omg.h"
+
+int max_vertices_ongrid(omg_global_param omg_param);
+
+int max_connecteddomains_ongrid(omg_global_param omg_param);
+
+
+double vertice_xpos(int loc_num, omg_global_param omg_param);
+
+
+double vertice_ypos(int loc_num, omg_global_param omg_param);
+
+
+double area_minx(int block_num, omg_global_param omg_param);
+
+
+double area_miny(int block_num, omg_global_param omg_param);
+
+unsigned int next_block(int current_bn, omg_global_param omg_param);
+
+unsigned int selected_blockn(int block_n,int type,int div);
+
+#endif 
+
diff --git a/openair2/UTIL/OMG/job.c b/openair2/UTIL/OMG/job.c
index b1143ba363031c81fde6d272a557c49b83b92528..9d93e0a3c89f3cf0a8c2f7b066db1929e1540b7a 100644
--- a/openair2/UTIL/OMG/job.c
+++ b/openair2/UTIL/OMG/job.c
@@ -29,8 +29,8 @@
 
 /*! \file job.c
 * \brief handle jobs for future nodes' update
-* \author  M. Mahersi,  J. Harri, N. Nikaein,
-* \date 2011
+* \author  S. Gashaw, M. Mahersi,  J. Harri, N. Nikaein,
+* \date 2014
 * \version 0.1
 * \company Eurecom
 * \email: 
@@ -44,127 +44,172 @@
 
 #include "omg.h"
 
-Job_list add_job(Pair job, Job_list Job_Vector){
-    Job_list entry = malloc(sizeof(Job_list));
-    entry->pair = job;
-   
-    //LOG_D(OMG, "  Job_Vector_len %d", Job_Vector_len); 
-    entry->next = NULL;
-
-    if (Job_Vector == NULL) {
-      //LOG_D(OMG, "empty Job_Vector\n");
-      //LOG_D(OMG, "added elmt ID %d\n", entry->pair->b->ID);
-        return entry;
-    }
-    else {
-        Job_list tmp = Job_Vector;
-        while (tmp->next != NULL){
-            tmp = tmp->next;
-        }
-        tmp->next = entry;
-        //LOG_D(OMG, "non empty Job_Vector\n");
-	    //LOG_D(OMG, "dded elmt ID %d\n", entry->pair->b->ID);
-
-        return Job_Vector;
+job_list *
+add_job (pair_struct * job, job_list * job_vector)
+{
+
+  job_list *tmp;
+  job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct));
+  entry->pair = job;
+  entry->next = NULL;
+
+  if (job_vector != NULL)
+    {
+
+      tmp = job_vector;
+      tmp->next = entry;
     }
+
+  return entry;
+
 }
 
+//add_job2
+
+job_list *
+addjob (pair_struct * job, job_list * job_vector)
+{
+
+  job_list *tmp;
+  job_list *entry = (job_list *) malloc (sizeof (struct job_list_struct));
+  entry->pair = job;
+  entry->next = NULL;
+
+  if (job_vector == NULL)
+    {
+      return entry;
+    }
+  else
+    {
+      tmp = job_vector;
+      while (tmp->next != NULL)
+	{
+	  tmp = tmp->next;
+	}
+
+      tmp->next = entry;
+    }
+
+  return job_vector;
+
+
+}
 
 // display list of jobs
-void display_job_list(Job_list Job_Vector){
+void
+display_job_list (double curr_t, job_list * job_vector)
+{
+
+  job_list *tmp = job_vector;
+  if (tmp == NULL)
+    {
+      LOG_D (OMG, "Empty Job_list\n");
+    }
+  else
+    {
+      //LOG_D(OMG, "first_Job_time in Job_Vector %f\n", Job_Vector->pair->a);
+      while (tmp != NULL)
+	{
+	  if ((tmp->pair != NULL) /*&& tmp->pair->b->id==0 */ )
+	    //LOG_D(OMG, "%.2f %.2f \n",tmp->pair->b->x_pos, tmp->pair->b->y_pos);
+	    LOG_D (OMG, "%.2f  %d %d %.2f %.2f  %.2f\n", curr_t, tmp->pair->b->id,tmp->pair->b->gid,
+		   tmp->pair->b->x_pos, tmp->pair->b->y_pos,
+		   tmp->pair->b->mob->speed);
 
-    	Job_list tmp = Job_Vector;
-   if (tmp == NULL){LOG_D(OMG, "Empty Job_list\n");}
-   else{
-        //LOG_D(OMG, "first_Job_time in Job_Vector %f\n", Job_Vector->pair->a);
-     while (tmp != NULL){
-     	if ((tmp->pair != NULL))
-	  LOG_D(OMG, "node %d \ttime %.2f\n", tmp->pair->b->ID, tmp->pair->a);
 
-        tmp = tmp->next;
+	  tmp = tmp->next;
 
+	}
     }
- }
+}
+
+//average nodes speed for each mobility type
+unsigned int
+nodes_avgspeed (job_list * job_vector)
+{
+  job_list *tmp = job_vector;
+  unsigned int avg = 0, cnt = 0;
+  if (tmp == NULL)
+    {
+      LOG_D (OMG, "Empty Job_list\n");
+      return 0;
+    }
+  else
+    {
+      while (tmp != NULL)
+	{
+	  if ((tmp->pair != NULL))
+	    {
+	      avg += tmp->pair->b->mob->speed;
+	      cnt++;
+	    }
+	  tmp = tmp->next;
+	}
+    }
+  return avg / cnt;
 }
 
 // quick sort of the linked list
-Job_list job_list_sort (Job_list list, Job_list end){
-
-    Job_list pivot, tmp, next, before, after;
-    if ( list != end && list->next != end ){
-
-        pivot = list;
-	before = pivot;
-	after = end;
-        for ( tmp=list->next; tmp != end; tmp=next )
-        {
-            next = tmp->next;
-            if (tmp->pair->a > pivot->pair->a)
-                tmp->next = after, after = tmp;
-            else
-                tmp->next = before, before = tmp; 
-        }
-        
-        before = job_list_sort (before, pivot);
-        after = job_list_sort (after, end);
-        
-        pivot->next = after;
-        return before;
+job_list *
+job_list_sort (job_list * list, job_list * end)
+{
+
+  job_list *pivot, *tmp, *next, *before, *after;
+  if (list != end && list->next != end)
+    {
+
+      pivot = list;
+      before = pivot;
+      after = end;
+      for (tmp = list->next; tmp != end; tmp = next)
+	{
+	  next = tmp->next;
+	  if (tmp->pair->next_event_t > pivot->pair->next_event_t)
+	    tmp->next = after, after = tmp;
+	  else
+	    tmp->next = before, before = tmp;
+	}
+
+      before = job_list_sort (before, pivot);
+      after = job_list_sort (after, end);
+
+      pivot->next = after;
+      return before;
     }
-    return list;
+  return list;
 }
 
-Job_list quick_sort (Job_list list)
+job_list *
+quick_sort (job_list * list)
 {
-    return job_list_sort(list, NULL);
+  return job_list_sort (list, NULL);
 }
 
 
-Job_list remove_job(Job_list list, int nID, int node_type){
-
-  Job_list  current, previous;
-  //int cond=0;
-  int i=0;
-  if (list == NULL){
-    return NULL;
-  }
-  else{                             //start search
-    current = list;
-    if ((current != NULL) && (current->pair->b->ID == nID) && (current->pair->b->type == node_type )){LOG_D(OMG, "(current != NULL) && (current->pair->b->ID != nID) && (current->pair->b->type != node_type ");}
-    while ( (current != NULL) && ((current->pair->b->ID != nID) || (current->pair->b->type != node_type ))){
-      LOG_D(OMG, "current->pair->b->ID %d",current->pair->b->ID);
-      LOG_D(OMG, "nID %d",nID);
-      LOG_D(OMG, "current->pair->b->type  %d",current->pair->b->type ); // UE, eNB   1
-      LOG_D(OMG, "node_type  %d",node_type ); //UE, eNB  0
-      LOG_D(OMG, "current->pair->b->generator  %d",current->pair->b->generator );  //static
-      
-      LOG_D(OMG, "i = %d", i);
-      previous = current;        //  previous hobbles after
+job_list *
+remove_job (job_list * list, int nid, int node_type)
+{
+
+  job_list *current, *previous;
+
+  current = list;
+  previous = NULL;
+  while (current != NULL)
+    {
+      if (current->pair->b->id == nid && current->pair->b->type == node_type)
+	{
+	  if (current == list || previous == NULL)
+	    list = current->next;
+	  else
+	    previous->next = current->next;
+
+	  free (current);
+	  break;
+
+	}
+      previous = current;
       current = current->next;
-      i++;
-      if (current ==NULL){LOG_D(OMG, "current ==NULL");}
-      
     }
-    
-    
-    //if (current->pair->b->ID == nID){LOG_D(OMG, "current->pair->b->ID == nID");}
-    //if (current->pair->b->type == node_type){LOG_D(OMG, "current->pair->b->type == node_type");}
-    
-    if (current ==NULL) { 
-      LOG_D(OMG," Job to remove is not found\n "); //LOG_N 
-      return NULL;
-    }              //value not found
-    else{
-      if (current == list) {
-	list = current->next  ;
-	LOG_D(OMG,"Job to remove is found at the beginning\n");
-      }    
-      else {
-	previous->next = current->next;
-      }
-    }
-    return list;
-  }
-}
-
+  return list;
 
+}
diff --git a/openair2/UTIL/OMG/makefile_standalone b/openair2/UTIL/OMG/makefile_standalone
index 858c65cc912958274718c3a6d3bbd9fc39230128..68170543eedc73012c487ae70a3a9912485c9507 100644
--- a/openair2/UTIL/OMG/makefile_standalone
+++ b/openair2/UTIL/OMG/makefile_standalone
@@ -1,14 +1,14 @@
 CC= gcc
 
 OBJstatic = omg.c common.c static.c 
-OBJrwp = omg.c common.c job.c rwp.c 
+OBJrwp = omg.c common.c job.c rwp.c grid.c
 OBJrwalk = omg.c common.c job.c rwalk.c 
-OBJtrace = omg.c common.c job.c trace.c mobility_parser.c omg_hashtable.c 
+OBJtrace = omg.c common.c job.c trace.c mobility_parser.c hashtable.c 
 OBJsumo = omg.c common.c sumo.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c
 
-OBJ = omg.c common.c static.c job.c rwp.c rwalk.c trace.c sumo.c mobility_parser.c omg_hashtable.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c 
+OBJ = omg.c common.c static.c job.c rwp.c rwalk.c trace.c steadystaterwp.c sumo.c grid.c mobility_parser.c hashtable.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c 
 
-CFLAGS += -DSTANDALONE -DUSER_MODE
+CFLAGS += -DSTANDALONE -DUSER_MODE -g
 
 .PHONY: help staticOMG rwpOMG clean
 
diff --git a/openair2/UTIL/OMG/mobility_parser.c b/openair2/UTIL/OMG/mobility_parser.c
index fb1628ca34960f4b3cd0d3f550c43db829b6c06b..a97f38fa82967f58cc60b468dbb4ced405ee1845 100644
--- a/openair2/UTIL/OMG/mobility_parser.c
+++ b/openair2/UTIL/OMG/mobility_parser.c
@@ -29,11 +29,11 @@
 
 /*! \file mobility_parser.c
 * \brief A parser for trace-based mobility information (parsed from a file)
-* \author  S. Uppoor
-* \date 2011
+* \author  S. Gashaw, N. Nikaein,  J. Harri
+* \date 2014
 * \version 0.1
-* \company INRIA
-* \email: sandesh.uppoor@inria.fr
+* \company EURECOM
+* \email: 
 * \note
 * \warning
 */
@@ -42,442 +42,226 @@
 #include <string.h>
 #include <stdlib.h>
 #include "mobility_parser.h"
-#include "omg_hashtable.h"
 #include "omg.h"
+#include <math.h>
 
+extern hash_table_t **table;
+extern node_info **list_head;
 
-node_info* head_node_info =NULL;
-omg_hash_table_t* table=NULL;
+//read the mobility file and generates a hashtable of linked list
+void
+parse_data (char *trace_file, int node_type)
+{
+  FILE *fp;
+  char *pch, *p;
+  char str[128];
+  int fmt, id = 0, gid;
+  node_container *value;
 
-//need to be removed , used only once (old code)
-struct Exnode* gen_list(){
-  struct Exnode* head = NULL;
-  return head;
-}
+ //if(table==NULL)
+  create_new_table (node_type);
 
+  if(list_head ==NULL)
+      list_head = (node_info **) calloc (MAX_NUM_NODE_TYPES, sizeof (node_info*));
 
-//read the mobility file and generates a hashtable of linked list with key pointing to vehicle id
-void read_mobility_file(char* mobility_file[]){
-  FILE *fp;
-  char str[128],*p;
-  if (table == NULL){
-    table = hash_table_new(MODE_ALLREF);
-  }
-  
-  if((fp=fopen(mobility_file, "r"))==NULL) {
-    LOG_D(OMG,"Cannot open file %s\n", mobility_file);
-    exit(1);
-  }
-  Exnode* headRef;
-  static node_info* Node_info=NULL;
-  
-  int *keyholder[10];
-  int i=0;
-  
-  while(!feof(fp)) {
-    if(fgets(str, 126, fp)) { // happy go for small mobility file :-)
-      char * pch;
-      int fmt=0;
-      p=str;
-      while(*p==' ' || *p=='\t') p++; // skip whitespaces
-      if(*p=='\r') p++;
-      if (*p!='\n') {
-	pch = strtok (p," "); // the separator between the items in the list is a space
-	Exnode* node = malloc(sizeof(Exnode));
-	
-	while (pch != NULL){
-	  node->visit=0;
-	  switch(fmt){
-	  case 0:
-	    node->time=(atof(pch));
-	    break;
-	  case 1:
-	    node->vid =atoi(pch);
-	    break;
-	  case 2:
-	    node->x=atof(pch);
-	    break;
-	  case 3:
-	    node->y=atof(pch);
-	    break;
-	  case 4:
-	    node->speed=atof(pch);
-	    break;
-	  default:
-	    //need a log statement here
-	    break;
-	  }
-	  fmt +=1;
-	  pch = strtok (NULL, " ");
-	}
-	node->next=NULL;
-	
-	//check in the hash table if the key exist node->vid if exist ? initialize headRef
-	int *value = NULL;
-	value = (int *)HT_LOOKUP(table, &(node->vid));
-        
-	if (value==NULL){
-	  if (Node_info==NULL){
-	    Node_info=build_node_info(Node_info,node->vid,&(node->vid));
-	    head_node_info=Node_info;
-	  }
-	  else{
-	    Node_info=build_node_info(Node_info,node->vid,&(node->vid));
-	  }
-	  Node_info->next=NULL;
-	  //LOG_D(OMG,"[TRACE] build info for node %d %d head %p node %p next %p\n", 
-	  //      Node_info->vid, node->vid, head_node_info,  Node_info, Node_info->next);
-	  keyholder[i]=&node->vid;
-	  i++;
-	  hash_table_add(table, &(node->vid), sizeof(node->vid), node, sizeof(node));
-	  headRef=gen_list();
-	  
-	}
-	else{
-	  //puts("Yes node exist");
-	  headRef = (Exnode *)value;
-	  //printf("value returned %f\n",headRef->time);
-	  //printf("After from hash %p %d\n",headRef, headRef->vid );
-	}
-	if (headRef!=NULL){
-	  AppendNode(headRef, node);
-	}
-      }
+   if (list_head == NULL )
+    {
+      LOG_E (OMG, "-------node list table creation failed--------\n");
+      exit (-1);
     }
-  }
-  fclose(fp);
-  //return table;
-}
 
-//builds linked list with each node holding vehicle is and linked list pointer on the hastable
-node_info*  build_node_info(node_info* headRef, int vid, int *vid_addr){
-
-  node_info* newNode=malloc(sizeof(node_info));
-  newNode->vid=vid;
-  newNode->vid_addr=vid_addr;
-  if (headRef==NULL){
-    headRef=newNode;
-    return headRef;
-  }
-  while(headRef->next!=NULL){
-    headRef = headRef->next;
-  }
-  if (headRef->next==NULL ){
-    headRef->next = newNode;
-    
-  }
-  return headRef->next;
-}
 
-void AppendNode(struct Exnode* headRef, struct Exnode* newNode) {
-  
-  while(headRef->next!=NULL){
-    headRef = headRef->next;
-  }
-  if (headRef->next==NULL ){
-    headRef->next = newNode;
-  }
-}
+  if ((fp = fopen (trace_file, "r")) == NULL)
+    {
+      LOG_E (OMG, "[OMG]:Cannot open file %s\n", trace_file);
+      exit (1);
+    }
+
+
+  while (!feof (fp))
+    {
+      if (fgets (str, 126, fp))
+	{
+	  fmt = 0;
+	  p = str;
+
+	  while (*p == ' ' || *p == '\t' || *p == '\r')
+	    p++;		// skip whitespaces
+
+	  if (*p != '\n')	//escape empty line
+	    {
+	      pch = strtok (p, " ");	// the separator between the items in the list is a space
+	      node_data *node = (node_data *) calloc (1, sizeof (node_data));
+				node->type=-1;    
+
+	  while (pch != NULL)
+		{
+
+		  switch (fmt)
+		    {
+		    case 0:
+		      if (atof (pch) < 0)
+					LOG_E (OMG, "error: negative time input \n");
+		      node->time = fabs (atof (pch));
+          LOG_D (OMG, "%.2f \n",node->time);
+		      break;
+		    case 1:
+		      node->vid = atoi (pch);
+          LOG_D (OMG, "%d \n",node->vid);
+		      break;
+		    case 2:
+		      node->x_pos = atof (pch);
+          LOG_D (OMG, "%.2f \n",node->x_pos);
+		      break;
+		    case 3:
+		      node->y_pos = atof (pch);
+           LOG_D (OMG, "%.2f \n",node->y_pos);
+		      break;
+		    case 4:
+		      if (atof (pch) < 0)
+					LOG_D (OMG, "error: negative speed input");
+		      node->speed = fabs (atof (pch));
+          LOG_D (OMG, "speed %.2f \n",node->speed);
+		      break;
+       /*case 5:
+		      node->type = atof (pch);
+		      break;*/
+		    default:
+           LOG_E (OMG,
+			      "[Error in trance file]:incorrect data format \n");
+		      break;
+		    }
+
+		  fmt += 1;
+		  pch = strtok (NULL, " ");
+		}
+
+	      node->next = NULL;
+	      node->visit = 0;
+
+	      // look for node in node info
+	      gid = find_node_info (node->vid, node_type);
+       
+	  if (gid == -1)
+		{
+		  node->gid = id;
+		  add_node_info (node->vid, node->gid, node_type);
+		  //store node data in the table
+		  hash_table_add (table[node_type], node, NULL);
+		  id++;
+		}
+	  else
+		{
+		  node->gid = gid;
+		  value = hash_table_lookup (table[node_type], node->gid);
+		  hash_table_add (table[node_type], node, value);
+		}
+
+
+
+	   }
+	 }
+ }
+
+  fclose (fp);
 
-//Just used for testing, it prints a linked list given the head pointer
-void print_list(struct Exnode* head){
-    
-  while(head->next !=NULL)
-    head=head->next;
 }
 
-Exnode* get_next_position(omg_hash_table_t *table,int node_id){
-  node_info* head_node=head_node_info;
-  while(head_node->next!=NULL){
-    
-    if(head_node->vid==node_id){
-      int *value1 = NULL;
-      value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-      if (value1!=NULL){
-	Exnode* value2=(Exnode *)value1;
-	while(value2->next!=NULL){
-	  if (value2->visit==1) value2=value2->next;
-	  else {
-	    value2->visit=1;
-	    return value2;
-	  }
-	}
-	if (value2->visit!=1){
-	  value2->visit=1;
-	  return value2;
-	}
-      }
-    }
-    head_node=head_node->next;
-  }
-  // not to leave the last node with ->next=NULL
-  if(head_node->vid==node_id){
-    int *value1 = NULL;
-    value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-    if (value1!=NULL){
-      Exnode* value2=(Exnode *)value1;
-      while(value2->next!=NULL){
-	if (value2->visit==1) value2=value2->next;
-	else {
-	  value2->visit=1;
-	  return value2;
+//search for node given id if exist 
+
+int
+find_node_info (int vid, int node_type)
+{
+  node_info *search;
+  if (list_head[node_type] != NULL)
+    {
+      search = list_head[node_type];
+      while (search != NULL)
+	{
+	  if (search->vid == vid)
+	    return search->g_id;
+	  search = search->next;
 	}
-      }
-      if (value2->visit!=1){
-	value2->visit=1;
-	return value2;
-      }
     }
-  }
-  return NULL;
+
+  return -1;
 }
 
+//builds linked list with each node holding vehicle id read from file & given id
+void
+add_node_info (int nid, int n_gid, int node_type)
+{
+  node_info *new = (node_info *) malloc (sizeof (node_info));
+  if (new != NULL)
+    {
+      new->vid = nid;
+      new->g_id = n_gid;
+      new->next = NULL;
 
-void reset_visit_status(omg_hash_table_t *table,float time, int node_id){
-  node_info* head_node=head_node_info;
-  while(head_node->next!=NULL){
-    
-    if(head_node->vid==node_id){
-      int *value1 = NULL;
-      value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-      if (value1!=NULL){
-	Exnode* value2=(Exnode *)value1;
-	while(value2->next!=NULL){
-	  if (value2->time == time) {
-	    value2->visit=0;
-	  }
-	  value2=value2->next;
-	}
-	if (value2->time == time){
-	  value2->visit=0;
+      if (list_head[node_type] == NULL)
+	      list_head[node_type] = new;
+      else
+	{
+	  node_info *temp, *save;
+	  temp = list_head[node_type];
+	  while (temp != NULL)
+	    {
+	      save = temp;
+	      temp = temp->next;
+	    }
+
+	  save->next = new;
 	}
-      }
     }
-    head_node=head_node->next;
-  }
-  // not to leave the last node with ->next=NULL
-  if(head_node->vid==node_id){
-    int *value1 = NULL;
-    value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-    if (value1!=NULL){
-      Exnode* value2=(Exnode *)value1;
-      while(value2->next!=NULL){
-	if (value2->time==time) value2->visit=0;
-	value2=value2->next;
-      }
-      if (value2->time==time) value2->visit=0;
+  else
+    {
+      LOG_E (OMG, "node info  list creation failed\n");
+      exit (-1);
     }
-  }
-  
 }
 
-int get_num_nodes(){
-  int count=1; //Last node also need to be counted
-  node_info * head_node=head_node_info;
-  while (head_node->next!=NULL){
-    count += 1;
-    head_node=head_node->next;
-  }
-  return count;
-}
-void sort_veh_movement(omg_hash_table_t *table){
-  node_info* head_node=head_node_info;
-  while(head_node->next!=NULL){
-    int *value1 = NULL;
-    value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-    Exnode* head_veh_node = (Exnode *)value1;
-    Exnode* value2 = (Exnode *)value1;
-    while (value2->next!=NULL){
-      value2 = value2->next;
-    }
-    Exnode* tail_veh_node = (Exnode *)value2;
-    quicksortlist(head_veh_node, tail_veh_node);
-    head_node=head_node->next;
-  }
-  // come on !! use functions :-)
-  // last node with ->next == NULL
-  int *value1 = NULL;
-  value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-  Exnode* head_veh_node = (Exnode *)value1;
-  Exnode* value2 = (Exnode *)value1;
-  while (value2->next!=NULL){
-    value2 = value2->next;
-  }
-  Exnode* tail_veh_node = (Exnode *)value2;
-  quicksortlist(head_veh_node, tail_veh_node);
-}
 
-// quick sort list
-void quicksortlist(Exnode *pLeft, Exnode *pRight){
-  Exnode *pStart;
-  Exnode *pCurrent;
-  double swp_time;
-  int swp_vid;
-  double swp_x;
-  double swp_y;
-  double swp_speed;
-  int swp_visit;
-  
-  // If the left and right pointers are the same, then return
-  if (pLeft == pRight) return;
-  
-  // Set the Start and the Current item pointers
-  pStart = pLeft;
-  pCurrent = pStart->next;
-  // Loop forever (well until we get to the right)
-  while (1){
-    if (pStart->time > pCurrent->time){
-      // Swap the items,swapping address could be critical, head pointer change will disrupt
-      // so swapping values
-      swp_time = pCurrent->time;
-      swp_vid = pCurrent->vid;
-      swp_x = pCurrent->x;
-      swp_y = pCurrent->y;
-      swp_speed = pCurrent->speed;
-      swp_visit = pCurrent->visit;
-      
-      pCurrent->time = pStart->time;
-      pCurrent->vid = pStart->vid;
-      pCurrent->x = pStart->x;
-      pCurrent->y = pStart->y;
-      pCurrent->speed = pStart->speed;
-      pCurrent->visit = pStart->visit;
-      
-      pStart->time = swp_time;
-      pStart->vid = swp_vid;
-      pStart->x = swp_x;
-      pStart->y = swp_y;
-      pStart->speed = swp_speed;
-      pStart->visit = swp_visit;
-    }
-    
-    // Check if we have reached the end
-    if (pCurrent == pRight) break;
-    
-    // Move to the next item in the list
-    pCurrent = pCurrent->next;
-  }
-  quicksortlist(pStart->next,pCurrent);
-  
+
+int
+get_number_of_nodes (int node_type)
+{
+  return table[node_type]->key_count;
 }
 
-void clear_llist(){
-  
-  node_info* TempNode=NULL;
-  node_info* tmp=NULL;
-  TempNode=head_node_info;
-  
-  while(TempNode->next!=NULL){
-    int *value1 = NULL;
-    value1 = (int *) HT_LOOKUP(table, TempNode->vid_addr);
-    Exnode* TempMob = (Exnode *)value1;
-    
-    while (TempMob->next!=NULL){
-      Exnode* tmp=NULL;
-      tmp=TempMob;
-      TempMob=TempMob->next;
-      free(tmp);
-      tmp=NULL;
-    }
-    if (TempMob->next == NULL){
-      free(TempMob);
-      TempMob=NULL;
+node_data *
+get_next_data (hash_table_t * table, int vid, int flag)
+{
+  node_container *block = hash_table_lookup (table, vid);
+  node_data *links = NULL, *save = NULL;
+
+  if (block != NULL)
+    links = block->next;
+
+  if (links == NULL)
+    LOG_E (OMG, "ERROR in reading-: NO data for node %d in this block \n",
+	   vid);
+
+  while (links != NULL)
+    {
+      if (links->visit == 0)
+	break;
+      save = links;
+      links = links->next;
     }
-    tmp=TempNode;
-    TempNode=TempNode->next;
-    free(tmp);
-    tmp=NULL;
-  }
-  if (TempNode->next==NULL ){
-    free(TempNode);
-    TempNode=NULL;
-  }
-  hash_table_delete(table);
-}
-/*     
-
-int main(){
-        //char *mobility_file[50];
-	Exnode* next_loc=NULL;
-        //mobility_file = (char*) malloc(256);
-	//mobility_file=strtok("regular.tr");
-	omg_hash_table_t *table=read_mobility_file();
-	sort_veh_movement(table);
-	printf("Number of nodes --> %d \n",get_num_nodes());
-	next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-	//next_loc=NULL;
-	next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-	//next_loc=NULL;
-	next_loc=get_next_position(table,140392);
-	if (next_loc!=NULL){
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-	//next_loc=NULL;
-	}next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-	next_loc=get_next_position(table,140392);
-	//if (next_loc!=NULL){
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-	next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-	next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140392);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140396);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140396);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140396);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140396);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140396);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-        next_loc=get_next_position(table,140396);
-	printf("node details %d\n %lf %lf %lf %lf %d\n",next_loc->vid,next_loc->time,next_loc->x,next_loc->y,next_loc->speed,next_loc->vid);
-	//reset_visit_status(table,20.0,11);
-	node_info* head_node=head_node_info;
-
-	while(head_node->next!=NULL){
-
-		if(head_node->vid==140392){
-			int *value1 = NULL;
-			value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-			Exnode *value=(Exnode *)value1;
-			while(value->next!=NULL){
-					printf("checking reset %d\n",value->visit);
-					value=value->next;
-				}
-			printf("checking reset %d\n",value->visit);
 
-		}
-		head_node=head_node->next;
+  if (links != NULL)
+    {
+      if (flag == DATA_AND_STATUS_CHANGE)
+	{
+	  if (block->next != block->end)
+	    links->visit = 1;
+	  return links;
 	}
-	int *value1 = NULL;
-	value1 = (int *) HT_LOOKUP(table, head_node->vid_addr);
-				Exnode *value=(Exnode *)value1;
-				while(value->next!=NULL){
-						printf("checking reset %d %d\n",value->visit,value->vid);
-						value=value->next;
-					}
-				printf("checking reset %d %d\n",value->visit,value->vid);
-	return 0;
-}*/
+      else if (flag == DATA_ONLY)
+	{
+	  return save;
+	}
+    }
+  else
+    return links;
+}
diff --git a/openair2/UTIL/OMG/mobility_parser.h b/openair2/UTIL/OMG/mobility_parser.h
index 71aab536ae70a8cd76eb7b8dcf29c3b82f28ed82..71162a5977300335f871ef006416e97c92deebd9 100644
--- a/openair2/UTIL/OMG/mobility_parser.h
+++ b/openair2/UTIL/OMG/mobility_parser.h
@@ -41,62 +41,16 @@
 #ifndef MOBILITY_PARSER_H_
 #define MOBILITY_PARSER_H_
 
-#include "omg_hashtable.h"
+#include "trace_hashtable.h"
 
-/**
- * @struct Simple struct to hold only few information
- * @brief The entry in each node is a line from the external mobility file
- */
-typedef struct Exnode {
-	double time;
-	int vid;
-	double x;
-	double y;
-	double speed;
-	int visit;
-	struct Exnode* next;
-
-}Exnode;
-
-/**
- * @struct struct acts as gateway to hashtable
- * @brief holds vehicle id and initial pointer to the head of the linked list in hastable
- */
-typedef struct node_info {
-	int vid;
-	int *vid_addr;
-	struct node_info* next;
-	//struct node_info* prev;
-}node_info;
-// head pointer to a linked list containing vid,vid_addr
-
-
-
-/**
- * function just to initialize the head of the linked list to NULL, this can be removed later(check).
- */
-struct Exnode* gen_list();
 
-/**
- * Function to append the line content to build a linked list.
- * @param headRef is the pointer to the head of the existing list to which append has to be done
- * @param newNode , item to be appended
- */
-void AppendNode(struct Exnode* headRef, struct Exnode* newNode);
-
-/**
- * function just prints the linked list (need to be removed, used for testing)
- * @param pointer to the head of the linked list
- */
-void print_list(struct Exnode* head);
-
-/**
+/*
  * function reads each line and checks if vehicle has an entry in the hastable,
  * if so append append is called else a new linked list to the vehicle is created.
  * @param need mobility file to be given
  */
 
-void read_mobility_file(); // mobility file need to be given here, add in omg_param_list, get it from there
+void parse_data (char *trace_file, int node_type);	// mobility file need to be given here, add in omg_param_list, get it from there
 
 /**
  * function builds a linked list which holds vehicle id and its mapping pointer to
@@ -105,23 +59,16 @@ void read_mobility_file(); // mobility file need to be given here, add in omg_pa
  * @param vid is the vehicle id
  * @param pointer to the head of the linked list to the vehicle entry in the hash table
  */
-node_info*  build_node_info(node_info* headRef, int vid, int *vid_addr);
+void add_node_info (int nid,int n_gid, int node_type);
+int find_node_info (int vid, int node_type);
 
 /**
  * just counts the number of nodes in the mobility file
  */
-int get_num_nodes();
+int get_number_of_nodes (int node_type);
+
 
-/**
- * these function are used since there might be a possibility if user provides a mobility
- * discription which is out of order.
- * @param hashtable
- * @param starting pointer for the vehicles linked list
- * @param ending pointer of the vehicles linked list
- */
 
-void sort_veh_movement(omg_hash_table_t *table);
-void quicksortlist(Exnode *pLeft, Exnode *pRight);
 
 /**
  * function returns the node containing next position (just reads the linked list from the hashtable)
@@ -129,10 +76,8 @@ void quicksortlist(Exnode *pLeft, Exnode *pRight);
  * @param hashtable from which the node is to be looked
  * @param node_id is the nodes whose next location need to be retrieved from the linked list
  */
-Exnode* get_next_position(omg_hash_table_t *table,int node_id);
+node_data* get_next_data (hash_table_t* table, int vid, int flag);
 
-void reset_visit_status(omg_hash_table_t *table, float time, int node_id);
 
-void clear_llist();
 
 #endif /* MOBILITY_PARSER_H_ */
diff --git a/openair2/UTIL/OMG/omg.c b/openair2/UTIL/OMG/omg.c
index dc22f1458321442d1d9c4bab4105e9cfef981eb3..1cca0b38fabdc67f0d79ef9ea11a1841bcc08537 100644
--- a/openair2/UTIL/OMG/omg.c
+++ b/openair2/UTIL/OMG/omg.c
@@ -29,8 +29,8 @@
 
 /*! \file OMG.c
 * \brief Main function containing the OMG interface
-* \author  M. Mahersi, N. Nikaein, J. Harri
-* \date 2011
+* \author S. Gashaw, N. Nikaein, J. Harri
+* \date 2011 - 2014
 * \version 0.1
 * \company Eurecom
 * \email: 
@@ -51,738 +51,934 @@
 #include "rwp.h"
 #include "rwalk.h"
 #include "trace.h"
+#include "grid.h"
+#include "steadystaterwp.h"
 #include "sumo.h"
 #include "../OMV/structures.h"
 //#define STANDALONE
 
-int omv_write (int pfd,  Node_list ue_node_list, Data_Flow_Unit omv_data);
+float n_frames = 20.0;
+
+int omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data);
 void omv_end (int pfd, Data_Flow_Unit omv_data);
 int omv_enabled;
 
-void init_omg_global_params(void){ //if we want to re initialize all
-  int i = 0;
-  Job_Vector_len=0;
-  Job_Vector = NULL;
-  for (i=0; i<MAX_NUM_MOB_TYPES; i++){
-    Node_Vector[i] = NULL;
-    Node_Vector_len[i] = 0;
-    //Initial_Node_Vector_len[i] = 0;
-  }
+/*initialze global parameters*/
+void
+init_omg_global_params (void)
+{
+  int mob_t, node_t, i;
+  xloc_div = 10.0;
+  yloc_div = 10.0;
+  grid = 0;
+  for (mob_t = STATIC; mob_t < MAX_NUM_MOB_TYPES; mob_t++)
+    {
+      job_vector_len[mob_t] = 0;
+      job_vector[mob_t] = NULL;
+      job_vector_end[mob_t] = NULL;
+    }
+
+  for (node_t = eNB; node_t < MAX_NUM_MOB_TYPES; node_t++)
+    {
+      node_vector[node_t] = NULL;
+      node_vector_end[node_t] = NULL;
+      node_vector_len[node_t] = 0;
+    }
+  for (i = 0; i < 100; i++)
+    {
+      event_sum[i] = 0;
+      events[i] = 0;
+    }
 }
 
-// maybe remplace  'start_OMG(omg_global_param omg_param_list)
-// of course, add 'stop_OMG(), which calls recursively 
-// stop_XX_generator();
-//
-void init_mobility_generator(omg_global_param omg_param_list) {
-  switch (omg_param_list.mobility_type) {
+/*initiate mobility generator*/
+void
+init_mobility_generator (omg_global_param omg_param_list[])
+{
+  int node_t, mobility_t;
+
+  for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++)
+    {
+      
+	  mobility_t = omg_param_list[node_t].mobility_type;
+
+	  switch (mobility_t)
+	    {
+
+	    case STATIC:
+	      start_static_generator (omg_param_list[node_t]);
+	      break;
+
+	    case RWP:
+	      start_rwp_generator (omg_param_list[node_t]);
+	      break;
+
+	    case RWALK:
+	      start_rwalk_generator (omg_param_list[node_t]);
+	      break;
+
+	    case TRACE:
+	      start_trace_generator (omg_param_list[node_t]);
+	      break;
+
+	    case SUMO:
+	      start_sumo_generator (omg_param_list[node_t]);
+	      break;
+
+	    case STEADY_RWP:
+	      start_steadystaterwp_generator (omg_param_list[node_t]);
+	      break;
+
+	    default:
+	      LOG_N (OMG, "Unsupported generator\n");
+	    }
+
+	
+    }
 
-  case STATIC: 
-    start_static_generator(omg_param_list);
-    break;
-  
-  case RWP: 
-    start_rwp_generator(omg_param_list);
-    LOG_D(OMG," --------DISPLAY JOB LIST-------- \n"); 
-    display_job_list(Job_Vector);
-    Job_Vector = quick_sort (Job_Vector);
-    LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n"); 
-    display_job_list(Job_Vector);
-    break;   
-    
-  case RWALK: 
-    start_rwalk_generator(omg_param_list);
-    LOG_D(OMG," --------DISPLAY JOB LIST-------- \n"); 
-    display_job_list(Job_Vector);
-    Job_Vector = quick_sort (Job_Vector);
-    LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n"); 
-    display_job_list(Job_Vector);
-    break;
-
-  case TRACE:
-    start_trace_generator(omg_param_list);
-    LOG_D(OMG," --------DISPLAY JOB LIST-------- \n");
-    display_job_list(Job_Vector);
-    Job_Vector = quick_sort (Job_Vector);
-    LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n");
-    display_job_list(Job_Vector);
-    LOG_D(OMG," --------OMG will load static mobility traces from user specified file-------- \n");
-    
-    break; 
-
-  case SUMO: 
-    start_sumo_generator(omg_param_list);
-    //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n");
-    break;
-  
-  default:
-    LOG_N(OMG, "Unsupported generator %d \n", omg_param_list.mobility_type);
-  }
 }
 
-void stop_mobility_generator(int mobility_type) {
-  switch (mobility_type) {
-
-  case STATIC: 
-    break;
-  case RWP: 
-    break;
-  case RWALK: 
-    break;
-  case TRACE:
-    clear_llist();
-   break; 
-
-  case SUMO: 
-    stop_sumo_generator();
-    //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n");
-    break;
-  
-  default:
-    LOG_N(OMG, "Unsupported generator %d \n", omg_param_list.mobility_type);
-  }
+/**************************************************************************************/
+/*stop sumo mobiity generator*/
+void
+stop_mobility_generator (omg_global_param * omg_param_list)
+{
+  int i;
+  for (i = 0; i < MAX_NUM_NODE_TYPES; i++)
+    {
+      switch (omg_param_list[i].mobility_type)
+	{
+
+	case STATIC:
+	  break;
+	case RWP:
+	  break;
+	case RWALK:
+	  break;
+	case TRACE:
+	  clear_list ();
+	  break;
+	case STEADY_RWP:
+	  break;
+	case SUMO:
+	  stop_sumo_generator ();
+	  //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n");
+	  break;
+
+	default:
+	  LOG_N (OMG, "Unsupported generator\n");
+	}
+    }
+
 }
 
-void update_nodes(double cur_time){
+/*****************************************************************************/
+
+void
+update_nodes (double cur_time)
+{
 //LOG_D(OMG, "UPDATE NODES" );
-int i = 0;
-for (i=(STATIC+1); i<MAX_NUM_MOB_TYPES; i++){ 
-  if (Node_Vector[i] != NULL){
-    //printf(" Mob model to update is: %d \n ", i);
-    LOG_I(OMG, " Mob model to update is: %d \n ", i); 
-    update_node_vector(i, cur_time);
-  }
- }
- 
+  int i = 0;
+  for (i = (STATIC + 1); i < MAX_NUM_MOB_TYPES; i++)
+    {
+      if (job_vector[i] != NULL)
+	{
+	  update_node_vector (i, cur_time);
+	}
+    }
+
 }
 
 
-void update_node_vector(int mobility_type, double cur_time){
+void
+update_node_vector (int mobility_type, double cur_time)
+{
   //set_time(cur_time);
-  switch (mobility_type) {
-  case RWP:
-    update_rwp_nodes(cur_time);
-    break;
-  case RWALK:
-    update_rwalk_nodes(cur_time);
-    break;
-  case TRACE:
-    update_trace_nodes(cur_time);
-    break;     
-  case SUMO:  
-   // printf("in SUMO case \n");
-    update_sumo_nodes(cur_time);
-    break;
-
-  default:
-    //printf("STATIC or Unsupported generator %d \n", omg_param_list.mobility_type);
-    LOG_N(OMG, "STATIC or Unsupported generator %d \n", omg_param_list.mobility_type);
-  }
-}
-
-Node_list get_current_positions(int mobility_type, int node_type, double cur_time){
-  Node_list Vector = NULL;
-  if (Node_Vector[mobility_type] != NULL){
-    switch (mobility_type) {
-   case STATIC:
-     Vector = (Node_list)Node_Vector[STATIC];
-     LOG_T(OMG,"static vector %p is \n",Vector);
-     break; 
-   case RWP:
-      get_rwp_positions_updated(cur_time);
-      Vector = Node_Vector[RWP];
+  switch (mobility_type)
+    {
+    case RWP:
+      update_rwp_nodes (cur_time);
       break;
     case RWALK:
-      get_rwalk_positions_updated(cur_time);
-      Vector = Node_Vector[RWALK];
+      update_rwalk_nodes (cur_time);
       break;
     case TRACE:
-      get_trace_positions_updated(cur_time);
-      Vector = Node_Vector[TRACE];
-      break;   
+      update_trace_nodes (cur_time);
+      break;
     case SUMO:
-      LOG_I(OMG,"getting positions from SUMO\n");
-      //printf("getting positions from SUMO\n");
-      Vector = get_sumo_positions_updated(cur_time);
-     // Vector = Node_Vector[SUMO];
+      // printf("in SUMO case \n");
+      update_sumo_nodes (cur_time);
+      break;
+    case STEADY_RWP:
+      update_steadystaterwp_nodes (cur_time);
       break;
-    
     default:
-      Vector = NULL;
-      LOG_N(OMG, " Unsupported generator %c \n", omg_param_list.mobility_type);
+      //printf("STATIC or Unsupported generator %d \n", omg_param_list.mobility_type);
+      LOG_N (OMG, "STATIC or Unsupported generator\n");
     }
-    if (node_type != ALL){
-      Vector = filter(Vector, node_type);
-    }
-    return Vector;
-  }
-  else {
-  LOG_T( OMG, " No node of mobility type %d is available  \n",  mobility_type);
-  return NULL;
-  }
 }
 
+/*********************************************************************************/
 
-// get the position for a specific node 
-NodePtr get_node_position(int node_type, int nID){
-  int found = 0;  //not found
-  int i=0;
-  while ((i<MAX_NUM_MOB_TYPES) && (found == 0)){ 
-     	if (Node_Vector[i] != NULL){
-          Node_list tmp = Node_Vector[i];
-          while ((tmp != NULL) && (found == 0)){
-  	    if ((tmp->node->ID == nID) && (tmp->node->type == node_type)) {
-              LOG_T(OMG, "found a node vector %d node id %d with type %d\n",i, tmp->node->ID, tmp->node->type);	
-	      found = 1;   //found
-	      display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos );
-	      return tmp->node;
-            }
-	  tmp = tmp->next;
-          }
-       }
-       i++;
-  }
-  if (found == 0 ){
-    LOG_N(OMG, "Node does not exist\n");
-  }
-  return NULL;
+/*return updated node position for a given node type*/
+node_list *
+get_current_positions (int mobility_type, int node_type, double cur_time)
+{
+
+  
+      get_nodes_positions (mobility_type, cur_time);
+      return node_vector[node_type];
+   
 }
 
-/*NodePtr get_node_position(int mobility_type, int node_type, int nID){
-  if (Node_Vector[mobility_type] != NULL){
-    Node_list Vector = NULL;
-    int done =1;
-    switch (mobility_type) {
-    case RWP:
-      Vector = Node_Vector[RWP];
+/*update current position of nodes for specific mobility type*/
+void
+get_nodes_positions (int mobility_type, double cur_time)
+{
+  //printf("%d \n",mobility_type);
+
+  switch (mobility_type)
+    {
+     case STATIC:
       break;
-    case STATIC:
-      Vector = Node_Vector[STATIC];
+    case RWP:
+      get_rwp_positions_updated (cur_time);
       break;
     case RWALK:
-      Vector = Node_Vector[RWALK];
+      get_rwalk_positions_updated (cur_time);
+      break;
+    case TRACE:
+      get_trace_positions_updated (cur_time);
+      break;
+    case SUMO:
+      LOG_I (OMG, "getting positions from SUMO\n");
+      get_sumo_positions_updated (cur_time);
+      break;
+    case STEADY_RWP:
+      get_steadystaterwp_positions_updated (cur_time);
       break;
     default:
-      Vector = NULL;
-      LOG_E(OMG, "Static or Unsupported generator %c \n", omg_param_list.mobility_type);
+      LOG_E (OMG, " Unsupported generator \n");
     }
-    if (Vector == NULL){
-      LOG_D(OMG, "\n Vector == NULL"); 
-    }
-    while (Vector != NULL){
-      if (Vector->node->ID == nID && Vector->node->type == node_type){
-        done =0;
-		 
-		  display_node_position(Vector->node->ID, Vector->node->generator, Vector->node->type ,Vector->node->mobile, Vector->node->X_pos, Vector->node->Y_pos );
-  	 //   LOG_I(OMG, "Node number %d is in position: (%.2f, %.2f) with mobility_type: %d\n",Vector->node->ID,Vector->node->X_pos,Vector->node->Y_pos,Vector->node->mobile);
-        return Vector->node;
-      }
-      Vector = Vector->next;
+
+}
+
+/***************************************************************/
+
+// get the position for a specific node 
+
+node_struct *
+get_node_position (int node_type, int nid)
+{
+  node_list *tmp;
+
+  tmp = node_vector[node_type];
+  while (tmp != NULL)
+    {
+      if (tmp->node->id == nid)
+	return tmp->node;
+      tmp = tmp->next;
     }
-    if (done!= 0 ){LOG_N(OMG, "Node does not exist\n");}
-    return NULL;
-  }
-  else {
-    LOG_N( OMG, "No node of mobility type %d is available  \n",  mobility_type);
+
   return NULL;
-  }
-}*/
-
-
-
-void set_new_mob_type(int nID, int node_type, int new_mob, double cur_time){
-  double first_Job_time;
-  int err = 999;
-  int i = STATIC;
-  int old_mob = err;
-  int found = 0;  //not found
-  while ((i<MAX_NUM_MOB_TYPES) && (found == 0)){ 
-     if (Node_Vector[i] != NULL){
-        Node_list tmp = Node_Vector[i];
-        while ((tmp != NULL) && (found == 0)){
-  	  if ((tmp->node->ID == nID) && (tmp->node->type == node_type)) {
-             found = 1;   //found
-  	     old_mob = i;
-      	    LOG_D( OMG,"old mob %d\n", old_mob );  //LOG_N
-	    if (old_mob == new_mob){
-              LOG_D(OMG, "Nothing to change (%d == %d)\n",old_mob, new_mob);
-   	      return;
-  	    }
-	    else {
-               LOG_D(OMG,"Node_Vector[%d] != NULL\n", old_mob);
-   	       //int done = 1;
-               //Node_list Vector = Node_Vector[old_mob];
-               //NodePtr nd = NULL;
-	       NodePtr nd =  tmp->node;
-	       if (new_mob == STATIC) { //OKEY            // remove from Job_Vector
-          	 LOG_D(OMG, "new_mob == STATIC\n");
-	       	 nd->mobile = 0;
-	       	 nd->mob->speed = 0.0;
-
-  		 nd->mob->X_from = nd->X_pos;
-	       	 nd->mob->Y_from = nd->Y_pos;
-		 nd->mob->X_to = nd->X_pos;
-	         nd->mob->Y_to = nd->Y_pos;
-	       	 //nd->X_pos = nd->mob->X_to;
-	       	 //nd->Y_pos = nd->mob->Y_to;
-		 LOG_D(OMG, "Before remove");
-		 display_job_list( Job_Vector);
-
-		 if (Job_Vector != NULL){
-		   Job_Vector = remove_job(Job_Vector, nID, node_type);  //nd->ID
-		   //LOG_D(OMG, "After remove\n");
-	           Job_Vector_len--;
-                   LOG_D(OMG, "After remove\n");
-		   display_job_list( Job_Vector);
-                 }
-		 else {
-		   LOG_E(OMG, "ERROR, Job_Vector == NULL while there are mobile nodes");
-          	 }		  
-	       } 
-	    
-	       Node_Vector[old_mob] = remove_node(Node_Vector[old_mob], nID, node_type);
-	       Node_Vector_len[old_mob]--;
-	       nd->ID = nID; //Node_Vector_len[new_mob]; 
-	       LOG_D(OMG, "Node_Vector_len[new_mob]  %d\n", Node_Vector_len[new_mob]);
-	       LOG_D(OMG, "nd->ID  %d\n", nd->ID);
-      	       nd->generator = new_mob;    // ---> it is changed in Job_Vector if new_mob is RWP or RWALK
-
-	       Node_Vector[new_mob] = add_entry(nd, Node_Vector[new_mob]);
-	       Node_Vector_len[new_mob]++;
-
-	       if (old_mob == STATIC){		// add to Job_Vector , start by sleeping
-	         LOG_D(OMG, "old_mob == STATIC\n");
-		 
-                 if(Job_Vector == NULL){
-		   LOG_D(OMG, "Job_Vector == NULL\n");
-		   first_Job_time = cur_time; 
-	         }
-                 else {
-		   LOG_D(OMG, "Job_Vector != NULL\n");
-		   first_Job_time = Job_Vector->pair->a;
-	         }
-
-                 LOG_D(OMG, "-------------------------------------------------------------	first_Job_time %f\n", first_Job_time);
- 	         Pair pair = malloc(sizeof(Pair)) ;
-
-	         nd->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100;
-	         LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",nd->ID, nd->mob->sleep_duration);
-	         pair->a = first_Job_time + 1 + nd->mob->sleep_duration; //when to wake up    ????
-	         LOG_D(OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
-
-	         pair->b = nd;
-                 Job_Vector = add_job(pair, Job_Vector);
-	         Job_Vector_len++;
-	       }
-               LOG_D(OMG," --------DISPLAY JOB LIST-------- \n"); 
-	       display_job_list(Job_Vector);
-	       Job_Vector = quick_sort (Job_Vector);
-	       LOG_D(OMG,"--------DISPLAY JOB LIST AFTER SORTING--------\n"); 
-	       display_job_list(Job_Vector);
-
-				
-   	       LOG_D(OMG, "--------display Node_Vector[new_mob]--------\n");
-    	       display_node_list(Node_Vector[new_mob]);
-    	       LOG_D(OMG, "--------display Node_Vector[old_mob]--------\n");
-    	       display_node_list(Node_Vector[old_mob]);
-               return;
-            }
-	}
-        tmp = tmp->next;
-       } 
-     }
-   i++;
-  }
 }
 
-/*// openair emu will set this valut as a function of frame number
-void set_time(double time) {
-	m_time = time;
-}
 
-double get_time() {
-	return m_time;
-}*/
+/*set new mobility for a node*/
+void
+set_new_mob_type (int id, int node_t, int mob_t, double cur_time)
+{
+
+  int prev_mob;
+  node_list *tmp;
+  job_list *tmp2, *prev_job;
+  pair_struct *pair;
+  double pause_p;
+
+//find previous mobility type
+  tmp = node_vector[node_t];
+  while (tmp != NULL)
+    {
+      if (tmp->node->id == id && tmp->node->type == node_t)
+	{
+	  prev_mob = tmp->node->generator;
+	  break;
+	}
+      tmp = tmp->next;
+    }
+
+//end
+
+  if (tmp != NULL && prev_mob != mob_t)
+    {
+
+//initialize node position
+      if (mob_t == STATIC || mob_t == RWP || mob_t == RWALK || mob_t == STEADY_RWP)
+	{
+	  tmp->node->x_pos =
+	    (double) ((int)
+		      (randomgen
+		       (omg_param_list[node_t].min_x,
+			omg_param_list[node_t].max_x) * 100)) / 100;
+	  tmp->node->mob->x_from = tmp->node->x_pos;
+	  tmp->node->mob->x_to = tmp->node->x_pos;
+	  tmp->node->y_pos =
+	    (double) ((int)
+		      (randomgen
+		       (omg_param_list[node_t].min_y,
+			omg_param_list[node_t].max_y) * 100)) / 100;
+	  tmp->node->mob->y_from = tmp->node->y_pos;
+	  tmp->node->mob->y_to = tmp->node->y_pos;
+	  tmp->node->mob->speed = 0.0;
+	  tmp->node->generator = mob_t;
+	  if (prev_mob != STATIC)
+	    job_vector[prev_mob] =
+	      remove_job (job_vector[prev_mob], id, node_t);
+	}
+
+//end
+
+      switch (mob_t)
+	{
+
+	case STATIC:
+
+	  break;
+
+	case RWP:
+	  pair = (pair_struct *) malloc (sizeof (struct pair_struct));
+	  pair->b = tmp->node;
+	  sleep_rwp_node (pair, cur_time);
+	  job_vector[RWP] = addjob (pair, job_vector[RWP]);
+	  break;
+
+	case RWALK:
+	  pair = (pair_struct *) malloc (sizeof (struct pair_struct));
+	  pair->b = tmp->node;
+	  sleep_rwalk_node (pair, cur_time);
+	  job_vector[RWALK] = addjob (pair, job_vector[RWALK]);
+	  break;
+
+	case STEADY_RWP:
+	  tmp->node->event_num = 0;
+	  pair = (pair_struct *) malloc (sizeof (struct pair_struct));
+	  pair->b = tmp->node;
+	  pause_p = pause_probability (omg_param_list[node_t]);
+	  if (randomgen (0, 1) < pause_p)
+	    sleep_steadystaterwp_node (pair, cur_time);
+	  else
+	    move_steadystaterwp_node (pair, cur_time);
+	  break;
+
+	case SUMO:
+	  LOG_E (OMG, "not possible to change mobility type to sumo \n");
+	  break;
+
+	case TRACE:
+	  LOG_E (OMG, "not possible to change mobility type to trace \n");
+	  break;
+
+	default:
+	  LOG_E (OMG, " Unsupported generator \n");
+	}
+
+    }
+
+
+}
 
 #ifdef STANDALONE
-void usage(void){
-	fprintf(stderr, "\n\t-X: assign maximum width of the simulation area (X_max)"\
-		"\n\t-x: assign minimum width of the simulation area (X_min)"\
-		"\n\t-Y: assign maximum height of the simulation area (Y_max)"\
-		"\n\t-y: assign minimum height of the simulation area (Y_min)"\
-		"\n\t-N: assign number of nodes"\
-		"\n\t-n: assign number of frames"			\
-		"\n\t-B: assign maximum duration of sleep/pause time (max_break)"
-		"\n\t-b: assign minimum duration of sleep/pause time (min_break)"\
-		"\n\t-J: assign maximum duration of journey (max_journey_time)"\
-		"\n\t-j: assign minimum duration of journey (min_journey_time)"\
-		"\n\t-S: assign maximum speed "\
-		"\n\t-s: assign minimum speed"\
-		"\n\t-g: choose generator (STATIC: 0x00, RWP: 0x01, RWALK: 0x02, TRACE: 0x03 or SUMO: 0x04)\n"\
-		"\n\t-e: choose seed \n"\
-	);	
-	exit(0);
+
+/************************** get options ************************************/
+void
+usage (void)
+{
+  fprintf (stderr,
+	   "\n\t-X: assign maximum width of the simulation area for UE nodes(X_max)"
+	   "\n\t-x: assign minimum width of the simulation area for UE nodes(X_min)"
+	   "\n\t-C: assign maximum width of the simulation area for eNB nodes(X_max)"
+	   "\n\t-c: assign minimum width of the simulation area for eNB nodes(X_min)"
+	   "\n\t-B: assign maximum width of the simulation area for relay nodes(X_max)"
+	   "\n\t-b: assign minimum width of the simulation area for relay nodes(X_min)"
+	   "\n\t-Y: assign maximum height of the simulation area for UE nodes(Y_max)"
+	   "\n\t-y: assign minimum height of the simulation area for UE nodes (Y_min)"
+	   "\n\t-Z: assign maximum height of the simulation area for eNB nodes(Y_max)"
+	   "\n\t-z: assign minimum height of the simulation area for eNB nodes(Y_min)"
+	   "\n\t-W: assign maximum height of the simulation area for relay nodes(Y_max)"
+	   "\n\t-w: assign minimum height of the simulation area for relay nodes(Y_min)"
+	   //"\n\t-N: assign number of nodes" "\n\t-n: assign number of frames"
+	   "\n\t-S: assign maximum duration of sleep/pause time for UE nodes(max_break)"
+	   "\n\t-s: assign minimum duration of sleep/pause time for UE nodes(min_break)"
+	   "\n\t-L: assign maximum duration of sleep/pause time for eNB nodes(max_break)"
+	   "\n\t-l: assign minimum duration of sleep/pause time for eNB nodes(min_break)"
+	   "\n\t-P: assign maximum duration of sleep/pause time for relay nodes(max_break)"
+	   "\n\t-p: assign minimum duration of sleep/pause time for relay nodes(min_break)"
+	   "\n\t-J: assign maximum duration of journey for UE nodes(max_journey_time)"
+	   "\n\t-j: assign minimum duration of journey for UE nodes(min_journey_time)"
+	   "\n\t-J: assign maximum duration of journey for eNB nodes(max_journey_time)"
+	   "\n\t-j: assign minimum duration of journey for eNB nodes(min_journey_time)"
+	   "\n\t-J: assign maximum duration of journey for relay nodes(max_journey_time)"
+	   "\n\t-j: assign minimum duration of journey for relay nodes(min_journey_time)"
+	   "\n\t-D: assign maximum speed for UE nodes"
+	   "\n\t-d: assign minimum speed for UE nodes"
+	   "\n\t-I: assign maximum speed for eNB nodes"
+	   "\n\t-i: assign minimum speed for eNB nodes"
+	   "\n\t-A: assign maximum speed for relay nodes"
+	   "\n\t-a: assign minimum speed for relay nodes"
+	   //"\n\t-g: choose generator(STATIC: 0x00, RWP: 0x01, RWALK: 0x02,TRACE: 0x03 or SUMO:0x04, STEADY_RWP:0x05)\n"
+	   "\n\t-g: choose to use map for random mobility" "\n\t-h: help"
+	   "\n\t-U: specifiy number of UE nodes"
+	   "\n\t-E: specifiy number of eNB nodes"
+	   "\n\t-R: specifiy number of relay nodes"
+	   "\n\t-u: choose mobility generator for UE nodes"
+	   "\n\t-e: choose mobility generator for eNB nodes"
+	   "\n\t-r: choose mobility generator for relay nodes"
+	   "\n\t-f: choose seed \n");
+  exit (0);
 }
-float  n_frames=200.0;
-int get_options(int argc, char *argv[]){
-	char tag;
-	while ((tag = getopt(argc, argv, "vj:J:g:B:b:S:s:Y:y:X:x:n:N:he:t:")) != EOF) {
-
-
-		switch (tag) {
-
-		case 'N':
-			omg_param_list.nodes = atoi(optarg);
-			LOG_D(OMG, "Number of nodes : %d \n",omg_param_list.nodes);
-			break;
-		case 'n':
-			n_frames = atof(optarg);
-			LOG_D(OMG, "Number of frames : %f \n",n_frames );
-			break;
-		case 't':
-			omg_param_list.nodes_type = atoi(optarg);
-			LOG_D(OMG, "Type of nodes : %d \n",omg_param_list.nodes_type);
-			break;
-		case 'b':
-			omg_param_list.min_sleep = atof(optarg);
-			LOG_D(OMG, "min sleep : %.2f \n",omg_param_list.min_sleep);
-			break;
-
-		case 'B':
-			omg_param_list.max_sleep = atof(optarg);
-			LOG_D(OMG, "max_sleep : %.2f \n",omg_param_list.max_sleep);
-			break;
-
-		case 's':
-			omg_param_list.min_speed = atof(optarg);
-			LOG_D(OMG, "min_speed : %.2f \n",omg_param_list.min_speed);
-			break;
-
-		case 'S':
-			omg_param_list.max_speed = atof(optarg);
-			LOG_D(OMG, "max_speed : %.2f \n",omg_param_list.max_speed);
-			break;
-		case 'v':
-		  omv_enabled = 1;
-		  break;
-		case 'X':
-			omg_param_list.max_X = atof(optarg);
-			LOG_D(OMG, "X_max : %.2f \n",omg_param_list.max_X);
-			break;
-		case 'x':
-			omg_param_list.min_X = atof(optarg);
-			LOG_D(OMG, "X_min : %.2f \n",omg_param_list.min_X);
-			break;
-
-		case 'Y':
-			omg_param_list.max_Y = atof(optarg);
-			LOG_D(OMG, "Y_max : %.2f \n",omg_param_list.max_Y);
-			break;
-
-		case 'y':
-			omg_param_list.min_Y = atof(optarg);
-			LOG_D(OMG, "Y_min : %.2f \n",omg_param_list.min_Y);
-			break;
-
-		case 'J':
-			omg_param_list.max_journey_time = atof(optarg);
-			LOG_D(OMG, "Journey_time_max : %.2f \n",omg_param_list.max_journey_time);
-			break;
-
-
-		case 'j':
-			omg_param_list.min_journey_time = atof(optarg);
-			LOG_D(OMG, "Journey_time_min : %.2f \n",omg_param_list.min_journey_time);
-			break;
-
-		
-		case 'g':
-			omg_param_list.mobility_type = atoi(optarg);
-			LOG_D(OMG, "Mobility type is %d \n",omg_param_list.mobility_type);
-			break;
-
-		case 'e':
-			omg_param_list.seed = atoi(optarg);
-			LOG_D(OMG, "Seed is %d \n",omg_param_list.seed );
-			break;
-		case 'h':
-			usage();
-			break;
-
-		default:
-			usage();
-			exit(1);
-		}
+
+
+
+int
+get_options (int argc, char *argv[])
+{
+  int node_t;
+  char tag;
+  while ((tag =
+	  getopt (argc, argv,
+		  "U:u:E:e:R:r:A:a:B:b:C:c:D:d:f:g:hI:i:J:j:k:L:l:N:n:P:p:S:s:T:t:vW:w:X:x:Y:y:Z:z:"))
+	 != EOF)
+    {
+
+
+      switch (tag)
+	{
+
+	case 'U':
+	  if (atoi (optarg) < 0)
+	    {
+	      usage ();
+	      exit (1);
+	    }
+	  omg_param_list[UE].nodes = atoi (optarg);
+	  LOG_D (OMG, "#Number of UE nodes : %d \n",
+		 omg_param_list[UE].nodes);
+	  break;
+
+	case 'E':
+	  if (atoi (optarg) < 0)
+	    {
+	      usage ();
+	      exit (1);
+	    }
+	  omg_param_list[eNB].nodes = atoi (optarg);
+	  LOG_D (OMG, "#Number of eNB nodes : %d \n",
+		 omg_param_list[eNB].nodes);
+	  break;
+
+	case 'R':
+	  if (atoi (optarg) < 0)
+	    {
+	      usage ();
+	      exit (1);
+	    }
+	  omg_param_list[RELAY].nodes = atoi (optarg);
+	  LOG_D (OMG, "#Number of relay nodes : %d \n",
+		 omg_param_list[RELAY].nodes);
+	  break;
+
+	case 'k':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#Number of frames can not be negative \n");
+	  n_frames = abs (atof (optarg));
+	  LOG_D (OMG, "#Number of frames : %f \n", n_frames);
+	  break;
+
+	case 'u':
+	  if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES)
+	    {
+	      usage ();
+	      exit (1);
+	    }
+	  omg_param_list[UE].mobility_type = atoi (optarg);
+	  LOG_D (OMG, "#UE nodes mobility type: %d \n",
+		 omg_param_list[UE].mobility_type);
+	  break;
+
+	case 'e':
+	  if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES)
+	    {
+	      usage ();
+	      exit (1);
+	    }
+	  omg_param_list[eNB].mobility_type = atoi (optarg);
+	  LOG_D (OMG, "#eNB nodes mobility type: %d \n",
+		 omg_param_list[eNB].mobility_type);
+	  break;
+
+	case 'r':
+	  if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES)
+	    {
+	      usage ();
+	      exit (1);
+	    }
+	  omg_param_list[RELAY].mobility_type = atoi (optarg);
+	  LOG_D (OMG, "#relay nodes mobility type: %d \n",
+		 omg_param_list[RELAY].mobility_type);
+	  break;
+
+	case 's':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#min sleep can not be negative \n");
+	  omg_param_list[UE].min_sleep = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE min sleep is set to: %.2f \n",
+		 omg_param_list[UE].min_sleep);
+	  break;
+
+	case 'S':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#max_sleep can not be negative \n");
+	  omg_param_list[UE].max_sleep = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE max_sleep is set to : %.2f \n",
+		 omg_param_list[UE].max_sleep);
+	  break;
+
+	case 'l':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#min sleep can not be negative or zero \n");
+	  if (atof (optarg) != 0)
+	    omg_param_list[eNB].min_sleep = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB min sleep is set to : %.2f \n",
+		 omg_param_list[eNB].min_sleep);
+	  break;
+
+	case 'L':
+	  if (atof (optarg) <= 0)
+	    LOG_E (OMG, "#max_sleep can not be negative or zero \n");
+	  if (atof (optarg) != 0)
+	    omg_param_list[eNB].max_sleep = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB max_sleep is set to : %.2f \n",
+		 omg_param_list[eNB].max_sleep);
+	  break;
+
+	case 'p':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#min sleep can not be negative \n");
+	  omg_param_list[RELAY].min_sleep = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay min sleep is set to: %.2f \n",
+		 omg_param_list[RELAY].min_sleep);
+	  break;
+
+	case 'P':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#max_sleep can not be negative \n");
+	  omg_param_list[RELAY].max_sleep = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay max_sleep is set to : %.2f \n",
+		 omg_param_list[RELAY].max_sleep);
+	  break;
+
+	case 'd':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#min_speed  can not be negative \n");
+	  if (atof (optarg) != 0)
+	    omg_param_list[UE].min_speed = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE min_speed is set to: %.2f \n",
+		 omg_param_list[UE].min_speed);
+	  break;
+
+	case 'D':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#max_speed  can not be negative \n");
+	  omg_param_list[UE].max_speed = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE max_speed is set to: %.2f \n",
+		 omg_param_list[UE].max_speed);
+	  break;
+
+	case 'i':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#min_speed  can not be negative \n");
+	  if (atof (optarg) != 0)
+	    omg_param_list[eNB].min_speed = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB min_speed is set to: %.2f \n",
+		 omg_param_list[eNB].min_speed);
+	  break;
+
+	case 'I':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#max_speed  can not be negative \n");
+	  omg_param_list[eNB].max_speed = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB max_speed is set to : %.2f \n",
+		 omg_param_list[eNB].max_speed);
+	  break;
+
+	case 'a':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#min_speed  can not be negative \n");
+	  if (atof (optarg) != 0)
+	    omg_param_list[RELAY].min_speed = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay min_speed is set to : %.2f \n",
+		 omg_param_list[RELAY].min_speed);
+	  break;
+
+	case 'A':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#max_speed  can not be negative \n");
+	  omg_param_list[RELAY].max_speed = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay max_speed is set to: %.2f \n",
+		 omg_param_list[RELAY].max_speed);
+	  break;
+
+	case 'v':
+	  omv_enabled = 1;
+	  break;
+
+	case 'X':
+	  omg_param_list[UE].max_x = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE X_max : %.2f \n", omg_param_list[UE].max_x);
+	  break;
+
+	case 'x':
+	  omg_param_list[UE].min_x = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE X_min : %.2f \n", omg_param_list[UE].min_x);
+	  break;
+
+	case 'C':
+	  omg_param_list[eNB].max_x = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB X_max : %.2f \n", omg_param_list[eNB].max_x);
+	  break;
+
+	case 'c':
+	  omg_param_list[eNB].min_x = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB X_min : %.2f \n", omg_param_list[eNB].min_x);
+	  break;
+
+	case 'B':
+	  omg_param_list[RELAY].max_x = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay X_max : %.2f \n", omg_param_list[RELAY].max_x);
+	  break;
+
+	case 'b':
+	  omg_param_list[RELAY].min_x = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay X_min : %.2f \n", omg_param_list[RELAY].min_x);
+	  break;
+
+	case 'Y':
+	  omg_param_list[UE].max_y = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE Y_max : %.2f \n", omg_param_list[UE].max_y);
+	  break;
+
+	case 'y':
+	  omg_param_list[UE].min_y = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE Y_min : %.2f \n", omg_param_list[UE].min_y);
+	  break;
+
+	case 'Z':
+	  omg_param_list[eNB].max_y = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB Y_max : %.2f \n", omg_param_list[eNB].max_y);
+	  break;
+
+	case 'z':
+	  omg_param_list[eNB].min_y = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB Y_min : %.2f \n", omg_param_list[eNB].min_y);
+	  break;
+
+	case 'W':
+	  omg_param_list[RELAY].max_y = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay Y_max : %.2f \n", omg_param_list[RELAY].max_y);
+	  break;
+
+	case 'w':
+	  omg_param_list[RELAY].min_y = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay Y_min : %.2f \n", omg_param_list[RELAY].min_y);
+	  break;
+
+	case 'J':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#Journey_time_max can not be negative \n");
+	  omg_param_list[UE].max_journey_time = fabs (atof (optarg));
+	  LOG_D (OMG, "UE Journey_time_max : %.2f \n",
+		 omg_param_list[UE].max_journey_time);
+	  break;
+
+	case 'j':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#Journey_time_min can not be negative \n");
+	  omg_param_list[UE].min_journey_time = fabs (atof (optarg));
+	  LOG_D (OMG, "#UE Journey_time_min : %.2f \n",
+		 omg_param_list[UE].min_journey_time);
+	  break;
+
+	case 'T':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#Journey_time_max can not be negative \n");
+	  omg_param_list[eNB].max_journey_time = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB Journey_time_max : %.2f \n",
+		 omg_param_list[eNB].max_journey_time);
+	  break;
+
+	case 't':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#Journey_time_min can not be negative \n");
+	  omg_param_list[eNB].min_journey_time = fabs (atof (optarg));
+	  LOG_D (OMG, "#eNB Journey_time_min : %.2f \n",
+		 omg_param_list[eNB].min_journey_time);
+	  break;
+
+	case 'N':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#Journey_time_max can not be negative \n");
+	  omg_param_list[RELAY].max_journey_time = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay Journey_time_max : %.2f \n",
+		 omg_param_list[RELAY].max_journey_time);
+	  break;
+
+	case 'n':
+	  if (atof (optarg) < 0)
+	    LOG_E (OMG, "#Journey_time_min can not be negative \n");
+	  omg_param_list[RELAY].min_journey_time = fabs (atof (optarg));
+	  LOG_D (OMG, "#relay Journey_time_min : %.2f \n",
+		 omg_param_list[RELAY].min_journey_time);
+	  break;
+
+	case 'f':
+	  for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++)
+	    {
+	      omg_param_list[node_t].seed = atoi (optarg);
+	      LOG_D (OMG, "#Seed is %d \n", omg_param_list[node_t].seed);
+	    }
+	  break;
+	case 'g':
+	  if (atoi (optarg) < 1 || atoi (optarg) > 2)
+	    {
+	      LOG_E (OMG, "#value given for graph should be 1 or 2 \n");
+	      exit (-1);
+	    }
+	  grid = abs (atof (optarg));
+	  LOG_D (OMG, "#graph value is %d \n", grid);
+	  break;
+	case 'h':
+	  usage ();
+	  break;
+
+	default:
+	  usage ();
+	  exit (1);
 	}
-	return 0;
+    }
+  return 1;
 }
 
-int main(int argc, char *argv[]) {
-	int i;
-	double cur_time=0.0;
-	//srand(time(NULL));
-	double ms=0.0;
-	Node_list Current_positions = NULL;
-	NodePtr my_node = NULL;
- 	int my_ID = 0;
-        double emu_info_time;
-	//omv
- char full_name[200];
-  int pfd[2]; // fd for omv : fixme: this could be a local var
+/**************************** main **********************************/
+
+int
+main (int argc, char *argv[])
+{
+  int i, node_type;
+  double cur_time = 0.0;
+  double ms = 0.0;
+  node_list *current_positions = NULL;
+  node_struct *my_node = NULL;
+  int my_id = 0, time_s;
+  double emu_info_time;
+  char full_name[200];
+  int pfd[2];			// fd for omv : fixme: this could be a local var
   char fdstr[10];
   char frames[10];
   char num_enb[10];
   char num_ue[10];
   //area_x, area_y and area_z for omv
   char x_area[20];
-  char y_area[20];  
+  char y_area[20];
   char z_area[20];
-  char fname[64],vname[64];
-  Data_Flow_Unit omv_data ;
-  //float  n_frames=200.0;
-	omg_param_list.nodes = 200;
-	omg_param_list.min_X = 0;
-	omg_param_list.max_X = 1000;
-	omg_param_list.min_Y = 0;
-	omg_param_list.max_Y = 1000;
-	omg_param_list.min_speed = 0.1;
-	omg_param_list.max_speed = 20.0;
-	omg_param_list.min_journey_time = 0.1;
-	omg_param_list.max_journey_time = 10.0;
-	omg_param_list.min_azimuth = 0; 
-	omg_param_list.max_azimuth = 360; 
-	omg_param_list.min_sleep = 0.1;
-	omg_param_list.max_sleep = 5.0;
-	omg_param_list.mobility_file = "TRACE/example_trace.tr"; 
-        omg_param_list.sumo_command = "sumo-gui"; 
-        omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.scen.sumo.cfg";
-     //   omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg";
-	omg_param_list.sumo_start = 0;//25900; 
-        omg_param_list.sumo_end = 200;//26200; 
-        omg_param_list.sumo_step = 1; 
-        omg_param_list.sumo_host = "localhost"; 
-        omg_param_list.sumo_port = 8890; 
-	omg_param_list.mobility_type = STATIC;
-	omg_param_list.nodes_type = UE;
-        // overwrite the default params if defined
-	get_options(argc, argv);
-	
-	// check if we are out of range
-        if(omg_param_list.max_X == 0.0 || omg_param_list.max_Y == 0.0  ) {
-		usage();
-		exit(1);
-	}
+  char fname[64], vname[64];
+  Data_Flow_Unit omv_data;
+
+//default parameters
+  for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++)
+    {
+
+
+      if (node_type == UE)
+	omg_param_list[node_type].nodes = 5;
+      else
+	omg_param_list[node_type].nodes = 0;
+      omg_param_list[node_type].min_x = 0;
+      omg_param_list[node_type].max_x = 100;
+      omg_param_list[node_type].min_y = 0;
+      omg_param_list[node_type].max_y = 100;
+      omg_param_list[node_type].min_speed = 0.1;
+      omg_param_list[node_type].max_speed = 20.0;
+      omg_param_list[node_type].min_journey_time = 0.1;
+      omg_param_list[node_type].max_journey_time = 20.0;
+      omg_param_list[node_type].min_azimuth = 0;
+      omg_param_list[node_type].max_azimuth = 360;
+      omg_param_list[node_type].min_sleep = 0.1;
+      omg_param_list[node_type].max_sleep = 5.0;
+      omg_param_list[node_type].mobility_file = "TRACE/mobility_3ues.tr";
+      omg_param_list[node_type].mobility_type = STATIC;
+      omg_param_list[node_type].nodes_type = node_type;
+      //omg_param_list.sumo_config = "SUMO/SCENARIOS/traci.koln.sumo.cfg";
+      omg_param_list[node_type].sumo_command = "sumo-gui";
+      omg_param_list[node_type].sumo_config =
+	"SUMO/SCENARIOS/traci.scen.sumo.cfg";
+      omg_param_list[node_type].sumo_start = 0;	//25900; 
+      omg_param_list[node_type].sumo_end = 200;	//26200; 
+      omg_param_list[node_type].sumo_step = 1;
+      omg_param_list[node_type].sumo_host = "localhost";
+      omg_param_list[node_type].sumo_port = 8890;
+    }
 
-      
 
-//char sumo_line[300];
+  init_omg_global_params ();	//initialize global paramaters
 
-//printf("TEST %s \n", sumo_line);
+  get_options (argc, argv);	// overwrite the default params if any input parameter 
 
-//  sprintf(sumo_line, "%s -c %s  -b %d -e %d --remote-port %d --step-length %d -v ",omg_param_list.sumo_command, omg_param_list.sumo_config, omg_param_list.sumo_start, omg_param_list.sumo_end, omg_param_list.sumo_port, omg_param_list.sumo_step);
-  
-//printf("%s \n",sumo_line);
+  for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++)
+    {
+      omg_param_list[node_type].max_vertices =
+	max_vertices_ongrid (omg_param_list[node_type]);
 
-//pid_t pid;
-//pid_t cpid;
- // char *sumo_arg[] = { omg_param_list.sumo_command, sumo_line, NULL };
-//char *sumo_arg[] = { "ls -la", NULL };
-//  char *sumo_env[] = { NULL };
+      omg_param_list[node_type].max_block_num =
+	max_connecteddomains_ongrid (omg_param_list[node_type]);
 
-//printf("%s \n",omg_param_list.sumo_command);
+    }
 
-  //execve("ls -la",sumo_arg, sumo_env);
 
-  //execve(omg_param_list.sumo_command, sumo_arg, sumo_env);
-  //exec(omg_param_list.sumo_command);
-// if ( (pid = fork()) == 0)
-//  {
-    // Start SUMO in the child process
-   //execve(omg_param_list.sumo_command, sumo_arg, sumo_env);// starts SUMO in a child proces
-//        system("sumo-gui");
-        
-   //childs addresss space
-//  }
-//printf("%d \n",pid);
-//pid++;
-//pid++;
-//printf("%d \n",pid);
-//printf("%d \n",cpid);
 
+  init_mobility_generator (omg_param_list);	//initialize choosen mobility generator
 
-//char kill_line[300];
+  // ****************init omv********************
+  if (omv_enabled == 1)
+    {
+      if (pipe (pfd) == -1)
+	perror ("pipe error \n");
 
-//printf("TEST %s \n", sumo_line);
+      sprintf (full_name, "%s/UTIL/OMV/OMV", getenv ("OPENAIR2_DIR"));
+      LOG_I (EMU, "Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name,
+	     pfd[0], pfd[1]);
 
-//sprintf(kill_line, "kill(%d)",cpid);
-  
-//printf("%s \n",kill_line);
 
-//system(kill_line); 
 
-	init_omg_global_params(); //initialization de Node_Vector et Job_Vector
 
-	init_mobility_generator(omg_param_list); // initial positions + sleep  /// need to indicate time of initialization
-		//LOG_I(OMG, "*****DISPLAY NODE LIST********\n"); 
-		//display_node_list(Node_Vector[0]);
-		
-                /*LOG_T(OMG, "********DISPLAY JOB LIST********\n"); 
-		display_job_list(Job_Vector);
-		Job_Vector = quick_sort (Job_Vector);
-		LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n"); 
-		display_job_list(Job_Vector);
-*/
-	// omg_param_list.mobility_type = RWP;  
-	// omg_param_list.nodes_type = UE;
-	// init_mobility_generator(omg_param_list); // initial positions + sleep  /// need to indicate time of initialization
-
-
-	//omg_param_list.mobility_type = RWALK;  	
-	//omg_param_list.nodes_type = UE;
-	//init_mobility_generator(omg_param_list); // initial positions + sleep  /// need to indicate time of initialization
-
-
-	//omg_param_list.mobility_type = STATIC;
-	//omg_param_list.nodes_type = UE;
-	//init_mobility_generator(omg_param_list); // initial positions + sleep  /// need to indicate time of initialization
-  	
-		//LOG_I(OMG, "*****DISPLAY NODE LIST********\n"); 
-		//display_node_list(Node_Vector[0]);
-		/*LOG_T(OMG, "********DISPLAY JOB LIST********\n"); 
-		display_job_list(Job_Vector);
-		Job_Vector = quick_sort (Job_Vector);
-		LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n"); 
-		display_job_list(Job_Vector);*/
-	 
- 	/*init_omg_global_params();        //re-initialization de Node_Vector et Job_Vector
-  LOG_I(OMG, "*****DISPLAY NODE LIST********\n"); 
-  display_node_list(Node_Vector[0]);
-  LOG_T(OMG, "********DISPLAY JOB LIST********\n"); 
-  display_job_list(Job_Vector);
-  Job_Vector = quick_sort (Job_Vector);
-  LOG_T(OMG, "**********DISPLAY JOB LIST AFTER SORTING**********\n"); 
-  display_job_list(Job_Vector);*/
 
-	
-	/////////////// to call by OCG
-	// init omv
-	if (omv_enabled == 1) {
-	  if(pipe(pfd) == -1)
-	    perror("pipe error \n");
-	  
-	  sprintf(full_name, "%s/UTIL/OMV/OMV",getenv("OPENAIR2_DIR"));
-	  LOG_I(EMU,"Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, pfd[0],pfd[1]);
-	  
-	  switch(fork()) {
-	  case -1 :
-	    perror("fork failed \n");
-	    break;
-	  case 0 : 
-	    if(close(pfd[1]) == -1 ) 
-	      perror("close on write\n" );
-	    sprintf(fdstr, "%d", pfd[0] );
-	    sprintf(num_enb, "%d", 1);
-	    sprintf(num_ue, "%d", omg_param_list.nodes);
-	    sprintf(x_area, "%f", omg_param_list.max_X );
-	    sprintf(y_area, "%f", omg_param_list.max_Y);
-	    sprintf(z_area, "%f", 200.0 );
-	    sprintf(frames, "%d", (int) n_frames);
-	    
-	    execl(full_name,"OMV", fdstr, frames, num_enb, num_ue, x_area, y_area, z_area, NULL );
-	    perror( "error in execl the OMV" );
-	  }
-	  //parent
-	  if(close( pfd[0] ) == -1 ) 
-	    perror("close on read\n" );
+      switch (fork ())
+	{
+	case -1:
+	  perror ("fork failed \n");
+	  break;
+	case 0:
+	  if (close (pfd[1]) == -1)
+	    perror ("close on write\n");
+	  sprintf (fdstr, "%d", pfd[0]);
+	  sprintf (num_enb, "%d", 1);
+	  sprintf (num_ue, "%d", omg_param_list[UE].nodes);
+	  sprintf (x_area, "%f", omg_param_list[UE].max_x);
+	  sprintf (y_area, "%f", omg_param_list[UE].max_y);
+	  sprintf (z_area, "%f", 200.0);
+	  sprintf (frames, "%d", (int) n_frames);
+
+	  execl (full_name, "OMV", fdstr, frames, num_enb, num_ue, x_area,
+		 y_area, z_area, NULL);
+	  perror ("error in execl the OMV");
 	}
-	
- for (emu_info_time = 0.0 ; emu_info_time <= n_frames; emu_info_time+=0.1){
-	//printf("updating node positions\n");
-   //        update_nodes(emu_info_time*1000);  
-        update_nodes(emu_info_time);  
-  	//double emu_info.time += 1.0/100; // emu time in ms
-	/*   for (i=(STATIC+1); i<MAX_NUM_MOB_TYPES; i++){ //
-	       if (Node_Vector[i] != NULL){
-		  LOG_D(OMG, " mob model  %d \n ", i); 
-	          update_nodes(i ,emu_info_time);
-	       }
-	      else {LOG_D( "nodes are STATIC\n"); }
-	    }*/
-	printf(" **********asking for positions in %d **********\n ", omg_param_list.mobility_type);
-          Current_positions = get_current_positions(omg_param_list.mobility_type, 
-						    omg_param_list.nodes_type, 
-						    emu_info_time); // type: enb, ue, all
-	 
-         if(Current_positions !=NULL) {
-           printf(" **********Current_positions at time %f**********\n ",emu_info_time);
-            display_node_list(Current_positions);
-           printf(" **********DONE**********\n ");
-	   if (omv_enabled == 1) 
-	     omv_write(pfd[1], Current_positions, omv_data);
-         }	
-	 
-  }
-  stop_mobility_generator(omg_param_list.mobility_type);
-	
-	/*LOG_D(OMG, " **********DISPLAY JOB LIST**********\n "); 
-        display_job_list(Job_Vector);
-	emu_info_time = 10.0;*/
+      //parent
+      if (close (pfd[0]) == -1)
+	perror ("close on read\n");
+    }
+
+//******************************
+
+  for (emu_info_time = 0.0; emu_info_time <= n_frames; emu_info_time += 0.1)
+    {
+
+      update_nodes (emu_info_time);
+      time_s = round (emu_info_time * 1000.0);
+      //printf("%d \n",time_s);
+      for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++)
+	{
+	  current_positions =
+	    get_current_positions (omg_param_list[node_type].mobility_type,
+				   node_type, emu_info_time);
+
+	  if (current_positions != NULL)
+
+	    display_job_list (emu_info_time,
+			      job_vector[omg_param_list
+					 [node_type].mobility_type]);
+
+	  /*if(current_positions!= NULL && time_s %1000==0)
+	     LOG_D(OMG, "%.2f  %d\n",emu_info_time,
+	     nodes_avgspeed(job_vector[omg_param_list [node_type].mobility_type])); */
+	}
+
+
+      //display current postion of nodes
+      if (omv_enabled == 1)
+	omv_write (pfd[1], node_vector[SUMO], omv_data);
 
-	//Current_positions = get_current_positions(SUMO, emu_info_time); // type: enb, ue, all 
-	//LOG_D(OMG, " **********Current_positions**********\n "); 
-	//display_node_list(Current_positions);
-	//if (Current_positions == NULL)
-	//   {LOG_D(OMG, " Cur_pos == NULL\n");}
-	//my_node = (NodePtr) get_node_position( RWP, UE, my_ID);
-	//LOG_D(OMG, "********At %.2f, Node number %d is in position: (%.2f, %.2f) with mobility_type: %d\n",emu_info_time, my_ID,my_node->X_pos,my_node->Y_pos,my_node->mobile);
 
-  if (omv_enabled == 1 )
-    omv_end(pfd[1],omv_data);
+    }
+  /*LOG_I(OMG,"#-----event average-----\n");
+     for (i=0;i<100;i++)
+     {
+     if(events[i]!=0)
+     LOG_D(OMG,"%d %d \n",i,event_sum[i]/events[i]);
+     } */
+
+  stop_mobility_generator (omg_param_list);
+  if (omv_enabled == 1)
+    omv_end (pfd[1], omv_data);
 
+  //clear_mem();
 
   return 0;
 }
 
 
-int omv_write (int pfd, Node_list ue_node_list, Data_Flow_Unit omv_data){
-  int i=0,j;
-  omv_data.end=0;
+/**********************************sumo****************************/
+int
+omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data)
+{
+  int i = 0, j;
+  omv_data.end = 0;
   // enb 
   omv_data.geo[i].x = 0.0;
   omv_data.geo[i].y = 0.0;
   omv_data.geo[i].z = 1.0;
   omv_data.geo[i].mobility_type = 0;
-  omv_data.geo[i].node_type = 0; //eNB
-   omv_data.geo[i].Neighbors=0;
-
-  for (i=1;i<omg_param_list.nodes+1;i++) {
-    if (ue_node_list != NULL) {
-      omv_data.geo[i].x =(int) (ue_node_list->node->X_pos < 0.0) ? 0.0 : ue_node_list->node->X_pos;
-      omv_data.geo[i].y = (int) (ue_node_list->node->Y_pos < 0.0) ? 0.0 : ue_node_list->node->Y_pos;
-      omv_data.geo[i].z = 1.0;
-      omv_data.geo[i].mobility_type = omg_param_list.mobility_type;
-      omv_data.geo[i].node_type = 1; //UE
-      ue_node_list = ue_node_list->next;
-      omv_data.geo[i].Neighbors=0;
-      printf("node %d at (%d, %d)\n", i, omv_data.geo[i].x ,omv_data.geo[i].y );
+  omv_data.geo[i].node_type = 0;	//eNB
+  omv_data.geo[i].Neighbors = 0;
+
+  for (i = 1; i < omg_param_list[SUMO].nodes + 1; i++)
+    {
+      if (ue_node_list != NULL)
+	{
+	  omv_data.geo[i].x =
+	    (int) (ue_node_list->node->x_pos <
+		   0.0) ? 0.0 : ue_node_list->node->x_pos;
+	  omv_data.geo[i].y =
+	    (int) (ue_node_list->node->y_pos <
+		   0.0) ? 0.0 : ue_node_list->node->y_pos;
+	  omv_data.geo[i].z = 1.0;
+	  omv_data.geo[i].mobility_type = omg_param_list[SUMO].mobility_type;
+	  omv_data.geo[i].node_type = 1;	//UE
+	  ue_node_list = ue_node_list->next;
+	  omv_data.geo[i].Neighbors = 0;
+	  printf ("node %d at (%d, %d)\n", i, omv_data.geo[i].x,
+		  omv_data.geo[i].y);
+	}
     }
-  }
-  
-  if( write( pfd, &omv_data, sizeof(struct Data_Flow_Unit) ) == -1 )
-   perror( "write omv failed" );
+
+  if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1)
+    perror ("write omv failed");
   return 1;
 }
-void omv_end (int pfd, Data_Flow_Unit omv_data) {
-  omv_data.end=1;
-  if( write( pfd, &omv_data, sizeof(struct Data_Flow_Unit) ) == -1 )
-    perror( "write omv failed" );
-}
-#endif 
-
-
-
-
-
-
-
 
+void
+omv_end (int pfd, Data_Flow_Unit omv_data)
+{
+  omv_data.end = 1;
+  if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1)
+    perror ("write omv failed");
+}
+#endif
diff --git a/openair2/UTIL/OMG/omg.h b/openair2/UTIL/OMG/omg.h
index 5e7b978edbbe38b2c28dc598389af1e54a76127c..75274a06fc1defe324ca58728c920e116aa7d13e 100644
--- a/openair2/UTIL/OMG/omg.h
+++ b/openair2/UTIL/OMG/omg.h
@@ -30,7 +30,7 @@
 /*! \file OMG.h
 * \brief Prototypes of OMG functions that may be called by OCG
 * \author  M. Mahersi, N. Nikaein, J. Harri
-* \date 2011
+* \date 2011 - 2014
 * \version 0.1
 * \company Eurecom
 * \email: 
@@ -43,6 +43,7 @@
 #include "omg_constants.h"
 #include "defs.h"
 #include "omg_vars.h"
+
 #if STANDALONE
 	#define LOG_G(c, x...) printf(x)
 	#define LOG_A(c, x...) printf(x)
@@ -57,6 +58,8 @@
 
 #else
 	#include "UTIL/LOG/log.h"
+
+
 #endif 
 
 /** @defgroup _omg OpenAir Mobility Generation (OMG)
@@ -195,14 +198,14 @@ void init_omg_global_params(void);
  * \brief Assign initial positions to all the nodes. To do so, call the start_generator..... function corresponding to each requested mobility generator
  * \param omg_param_list a structure that contains the main parameters needed to establish the random positions distribution
  */
-void init_mobility_generator(omg_global_param omg_param_list);
+void init_mobility_generator(omg_global_param omg_param_list[]);
 
 /**
  * \fn void stop_mobility_generator(int mobility_type)
  * \brief Call the destructor for the respective mobility type.
  * \param int mobility_type to stop and call destructor
  */
-void stop_mobility_generator(int mobility_type);
+void stop_mobility_generator(omg_global_param* omg_param_list);
 
 /**
  * \fn void update_nodes(double cur_time)
@@ -220,9 +223,9 @@ void update_nodes(double cur_time);
  * \param cur_time a variable of type double that represents the current time
  * \return a Node_list structure that stores the basic information about the all the nodes of a given mobility model
  */
-Node_list get_current_positions(int mobility_type, int node_type, double cur_time);
-
+node_list* get_current_positions(int mobility_type, int node_type, double cur_time);
 
+void get_nodes_positions (int mobility_type, double cur_time);
 
 /**
  * \fn void set_new_mob_type(int nID, int node_type, int new_mob, double cur_time)
diff --git a/openair2/UTIL/OMG/omg_constants.h b/openair2/UTIL/OMG/omg_constants.h
index 63eb751d837d4fa5a11c16ab773809ec44199535..e1322c10298dd01e17851f6bba54c7d66b9952b3 100644
--- a/openair2/UTIL/OMG/omg_constants.h
+++ b/openair2/UTIL/OMG/omg_constants.h
@@ -45,14 +45,29 @@ RWP,  /*!< Random Way Point mobility model */
 RWALK, /*!< Random Walk mobility model */
 TRACE,  /*!< Trace-based Mobility description file */
 SUMO,  /*!< SUMO-based mobility model	 */
+STEADY_RWP, /*!steady state RWP*/
 MAX_NUM_MOB_TYPES /*!< The maximum number of mobility models. Used to adjust the length of the #Node_Vector */
 }mobility_types;
 
+/*
+ * this is a sub type of standard RWP (not steady_RWP)
+ */
+typedef enum { 
+MIN_RWP_TYPES=0,  /*!< STATIC mobility model */
+RESTIRICTED_RWP,  /*!< Random Way Point mobility model */
+CONNECTED_DOMAIN, /*!< Random Walk mobility model */
+MAX_RWP_TYPES /*!< The maximum number of mobility models. Used to adjust the length of the #Node_Vector */
+}omg_rwp_types;
+
+ //#define RESTIRICTED_RWP 1
+ //#define CONNECTED_DOMAIN 2
+
 /*! The available nodes types */
 typedef enum {
 eNB=0, /*!< enhanced Node B  */
 UE, /*!< User Equipement  */
-ALL /*!< All the types. Used to perform the same operations to all the types of nodes */
+RELAY,
+MAX_NUM_NODE_TYPES /*!< All the types. Used to perform the same operations to all the types of nodes */
 }node_types;
 
 
@@ -60,6 +75,11 @@ ALL /*!< All the types. Used to perform the same operations to all the types of
 /*! A constant used to compare two doubles */
 #define eps 0.10 //10.99
 
+#define SLEEP 1
+#define GET_DATA 0
+#define GET_DATA_UPDATE 1
+
+
 #endif /* __OMG_H_ */
 
 
diff --git a/openair2/UTIL/OMG/omg_vars.h b/openair2/UTIL/OMG/omg_vars.h
index 5b2b4a3b1038dec4d1b864b5d8cda30f5850f372..ea2c6a5e8463758e4d8e164a2654f2db94467441 100644
--- a/openair2/UTIL/OMG/omg_vars.h
+++ b/openair2/UTIL/OMG/omg_vars.h
@@ -39,21 +39,29 @@
 #include "omg.h"
 
 /*!A global variable used to store all the nodes information. It is an array in which every cell stocks the nodes information for a given mobility type. Its length is equal to the maximum number of mobility models that can exist in a single simulation scenario */
-Node_list Node_Vector[MAX_NUM_MOB_TYPES];
+node_list* node_vector[MAX_NUM_NODE_TYPES];
+node_list* node_vector_end[MAX_NUM_NODE_TYPES];
 
 /*! A global variable which represents the length of the Node_Vector */
-int Node_Vector_len[MAX_NUM_MOB_TYPES];
+int node_vector_len[MAX_NUM_NODE_TYPES];
+/*!a global veriable used for event average computation*/
+int event_sum[100];
+int events[100];
 
 /*!A global variable used to store the scheduled jobs, i.e (node, job_time) peers   */
-Job_list Job_Vector;
+job_list* job_vector[MAX_NUM_MOB_TYPES];
+job_list* job_vector_end[MAX_NUM_MOB_TYPES];
 
 /*! A global variable which represents the length of the Job_Vector */
-int Job_Vector_len;
+int job_vector_len[MAX_NUM_MOB_TYPES];
 
 /*! A global variable used gather the fondamental parameters needed to launch a simulation scenario*/
-omg_global_param omg_param_list;
+omg_global_param omg_param_list[MAX_NUM_NODE_TYPES];
 
 //double m_time;
 
-
+/*!A global variable used to store selected node position generation way*/
+int grid;
+double xloc_div;
+double yloc_div;
 #endif /*  __OMG_VARS_H__ */
diff --git a/openair2/UTIL/OMG/rwalk.c b/openair2/UTIL/OMG/rwalk.c
index 2dbddc2841d7f588d6662d198bf7217c6d6a17eb..918e34514c44997f3c21c7e113ec58286ab20ac2 100644
--- a/openair2/UTIL/OMG/rwalk.c
+++ b/openair2/UTIL/OMG/rwalk.c
@@ -29,8 +29,8 @@
 
 /*! \file rwalk.c
 * \brief random walk mobility generator 
-* \author  M. Mahersi,  J. Harri, N. Nikaein,
-* \date 2011
+* \author S. Gashaw, N. Nikaein, J. Harri, M. Mahersi
+* \date 2014
 * \version 0.1
 * \company Eurecom
 * \email: 
@@ -41,422 +41,478 @@
 #include <stdlib.h>
 #include <time.h>
 #include <math.h>
+
 #include "rwalk.h"
-#include "omg.h"
-
-
-int start_rwalk_generator(omg_global_param omg_param_list) { 
- 
-  int n_id=0;
-  //omg_omg_param_list.seed= time(NULL); 
-  srand(omg_param_list.seed + RWALK);
-   
-  double cur_time = 0.0; 
-  NodePtr node = NULL;
-  MobilityPtr mobility = NULL;
-  
-  if (omg_param_list.nodes <= 0){
-    LOG_W(OMG, "Number of nodes has not been set\n");
-    return(-1);
-  }
-  
-	if (omg_param_list.nodes_type == eNB) {
-		LOG_I(OMG, "Node type has been set to eNB\n");
-	} else if (omg_param_list.nodes_type == UE) {
-		LOG_I(OMG, "Node type has been set to UE\n");
-	}
- 	LOG_I(OMG, "Number of random walk nodes has been set to %d\n", omg_param_list.nodes);
-
-  
-  for (n_id = 0; n_id< omg_param_list.nodes; n_id++) {
-    
-    node = (NodePtr) create_node();
-    mobility = (MobilityPtr) create_mobility();
-    node->mobile = 0; // static for the moment
-    node->ID = n_id;
-    node->type = omg_param_list.nodes_type; 
-    node->generator = omg_param_list.mobility_type; 
-         
-    node->mob = mobility;
-    
-    place_rwalk_node(node);	//initial positions
-    
-    Pair pair = malloc (sizeof(Pair));
-    pair = (Pair) sleep_rwalk_node(node, cur_time); //sleep
-    
-    Job_Vector = add_job(pair, Job_Vector);
-    Job_Vector_len ++;
-
-    if (Job_Vector == NULL)
-      LOG_E(OMG, "Job Vector is NULL\n");
-  }
- return(0); 
-}
+#include "steadystaterwp.h"
+
+
+int
+start_rwalk_generator (omg_global_param omg_param_list)
+{
+
+  int id;
+  static int n_id = 0;
+  double cur_time = 0.0, pause_p, mean_pause, mean_travel;
+  node_struct *node = NULL;
+  mobility_struct *mobility = NULL;
+  pair_struct *pair = NULL;
+
+  srand (omg_param_list.seed + RWALK);
+
+  mean_pause = (omg_param_list.max_sleep - omg_param_list.min_sleep) / 2;
+  mean_travel =
+    (omg_param_list.max_journey_time - omg_param_list.min_journey_time) / 2;
+  pause_p = mean_pause / (mean_travel + mean_pause);
+
+  LOG_I (OMG, "#RWALK mobility model for %d %d nodes\n", omg_param_list.nodes,
+	 omg_param_list.nodes_type);
+
+  for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
+    {
+
+      node = create_node ();
+      mobility = create_mobility ();
 
+      node->id = id;
+      node->type = omg_param_list.nodes_type;
+      node->mob = mobility;
+      node->generator = RWALK;
+      node->event_num = 0;
+      place_rwalk_node (node);	//initial positions
 
-void place_rwalk_node(NodePtr node) {
+      pair = (pair_struct *) malloc (sizeof (struct pair_struct));
+      pair->b = node;
+      // sleep_rwalk_node (pair, cur_time); //sleep
+      //pause probability...some of the nodes start at pause & the other on move
 
-	node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
-	node->mob->X_from = node->X_pos;
-	node->mob->X_to = node->X_pos;
-	node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
-	node->mob->Y_from = node->Y_pos;
-	node->mob->Y_to = node->Y_pos;
+      if (randomgen (0, 1) < pause_p)
+	sleep_steadystaterwp_node (pair, cur_time);	//sleep
+      else
+	move_steadystaterwp_node (pair, cur_time);
 
-	node->mob->speed = 0.0;
-	node->mob->journey_time = 0.0;
 
-	LOG_D(OMG, " INITIALIZE RWALK NODE\n ");
-    LOG_I(OMG, "Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n", node->ID, node->type, node->X_pos, node->Y_pos);   
-	Node_Vector[RWALK] = (Node_list) add_entry(node, Node_Vector[RWALK]);
-   Node_Vector_len[RWALK]++;
-   //Initial_Node_Vector_len[RWALK]++;
+      job_vector_end[RWALK] = add_job (pair, job_vector_end[RWALK]);
+
+      if (job_vector[RWALK] == NULL)
+	job_vector[RWALK] = job_vector_end[RWALK];
+
+      job_vector_len[RWALK]++;
+    }
+
+  n_id += omg_param_list.nodes;
+
+
+
+  if (job_vector[RWALK] == NULL)
+    LOG_E (OMG, "[RWP] Job Vector is NULL\n");
+  return (0);
 }
 
 
-Pair sleep_rwalk_node(NodePtr node, double cur_time){
-	node->mobile = 0;
-	node->mob->speed = 0.0;
-	node->mob->X_from = node->mob->X_to;
-	node->mob->Y_from = node->mob->Y_to;
-	node->X_pos = node->mob->X_to;
-	node->Y_pos = node->mob->Y_to;
-	Pair pair = malloc(sizeof(Pair)) ;
+void
+place_rwalk_node (node_struct * node)
+{
+  node->x_pos =
+    (double) ((int)
+	      (randomgen
+	       (omg_param_list[node->type].min_x,
+		omg_param_list[node->type].max_x) * 100)) / 100;
+  node->mob->x_from = node->x_pos;
+  node->mob->x_to = node->x_pos;
+  node->y_pos =
+    (double) ((int)
+	      (randomgen
+	       (omg_param_list[node->type].min_y,
+		omg_param_list[node->type].max_y) * 100)) / 100;
+  node->mob->y_from = node->y_pos;
+  node->mob->y_to = node->y_pos;
+  node->mob->speed = 0.0;
+  node->mob->journey_time = 0.0;
+
+  // LOG_D (OMG, " INITIALIZE RWALK NODE\n ");
+  LOG_I (OMG,
+	 "#Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n",
+	 node->id, node->type, node->x_pos, node->y_pos);
+
+  node_vector_end[node->type] =
+    (node_list *) add_entry (node, node_vector_end[node->type]);
+
+  if (node_vector[node->type] == NULL)
+    node_vector[node->type] = node_vector_end[node->type];
+
+  node_vector_len[node->type]++;
+
+}
 
-	node->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100;
-	LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
 
-	node->mob->start_journey = cur_time;
-	pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up
-	LOG_D(OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
-	pair->b = node;
+void
+sleep_rwalk_node (pair_struct * pair, double cur_time)
+{
+  node_struct *node;
+  node = pair->b;
+  node->mobile = 0;
+  node->mob->speed = 0.0;
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
+  node->x_pos = node->mob->x_to;
+  node->y_pos = node->mob->y_to;
+  if (node->event_num == 0)
+    node->event_num++;
+
+  node->mob->sleep_duration =
+    (double) ((int)
+	      (randomgen
+	       (omg_param_list[node->type].min_sleep,
+		omg_param_list[node->type].max_sleep) * 100)) / 100;
+  // LOG_D (OMG, "node: %d \tsleep duration : %.2f\n", node->ID,
+//       node->mob->sleep_duration);
+  node->mob->start_journey = cur_time;
+  pair->next_event_t = cur_time + node->mob->sleep_duration;	//when to wake up
+  // LOG_D (OMG, "to wake up at time: cur_time + sleep_duration : %.2f\n",
+//       pair->a);
 
-	return pair;
 }
- 
-Pair move_rwalk_node(NodePtr node, double cur_time) {
-	Pair pair = malloc(sizeof(Pair));
-	LOG_D(OMG, "MOVE RWALK NODE ID: %d\n",node->ID);
-
-    node->X_pos = node->mob->X_to;
-	node->Y_pos = node->mob->Y_to;
-	node->mob->X_from = node->X_pos;
-	node->mob->Y_from = node->Y_pos;
-	node->mobile = 1; 
-	double speed_next = randomGen(omg_param_list.min_speed, omg_param_list.max_speed);
-	node->mob->speed = speed_next;
-    	LOG_D(OMG, "speed_next: %f\n", speed_next); //m/s
-
-	double azimuth_next = randomGen(omg_param_list.min_azimuth, omg_param_list.max_azimuth);
-	node->mob->azimuth = azimuth_next;
-    	LOG_D(OMG, "azimuth_next: %f\n", node->mob->azimuth); 
-
-	double journeyTime_next = randomGen(omg_param_list.min_journey_time, omg_param_list.max_journey_time);
-	node->mob->journey_time = journeyTime_next;
-    	LOG_D(OMG, "journey_time_next: %f\n", node->mob->journey_time); 
-
-	double distance = node->mob->speed * node->mob->journey_time;
-	LOG_D(OMG, "distance = speed * journey_time: %f\n", distance); 
-
-	double dX = distance * cos(node->mob->azimuth*M_PI/180);
-	LOG_D(OMG, "dX = distance * cos(azimuth): %f\n", dX); 
-	double dY = distance * sin(node->mob->azimuth*M_PI/180);
-	LOG_D(OMG, "dY = distance * sin(azimuth): %f\n", dY); 
-	
-	LOG_D(OMG, "from: (%.2f, %.2f)\n", node->X_pos, node->Y_pos);
-	double X_next = (double) ((int)((node->X_pos + dX) *100))/ 100;
-	double Y_next = (double) ((int)((node->X_pos + dY) *100))/ 100;
-	LOG_D(OMG, "theoritical_destination: (%f, %f)\n", X_next, Y_next);
-
-	/*if (X_next<param_list.min_X){   // first method
-		node->mob->X_to = param_list.min_X;  
+
+
+void
+move_rwalk_node (pair_struct * pair, double cur_time)
+{
+  double distance, x_next, y_next, journeytime_next;
+  int i = 0;
+  double dx, dy, x_now, y_now;
+  double alpha, distancex, distancey;
+  node_struct *node;
+  node = pair->b;
+  //LOG_D (OMG, "MOVE RWALK NODE ID: %d\n", node->ID);
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
+  node->x_pos = node->mob->x_to;
+  node->y_pos = node->mob->y_to;
+  node->mobile = 1;
+
+  node->mob->speed =
+    randomgen (omg_param_list[node->type].min_speed,
+	       omg_param_list[node->type].max_speed);
+
+  node->mob->azimuth =
+    randomgen (omg_param_list[node->type].min_azimuth,
+	       omg_param_list[node->type].max_azimuth);
+  if (node->event_num == 0)
+    {
+      node->mob->journey_time = residualtime (omg_param_list[node->type]);
+      node->event_num++;
+    }
+  else
+    {
+      node->mob->journey_time =
+	randomgen (omg_param_list[node->type].min_journey_time,
+		   omg_param_list[node->type].max_journey_time);
+    }
+  distance = node->mob->speed * node->mob->journey_time;
+
+  dx = distance * cos (node->mob->azimuth * M_PI / 180);
+
+  dy = distance * sin (node->mob->azimuth * M_PI / 180);
+
+  x_next = (double) ((int) ((node->mob->x_from + dx) * 100)) / 100;
+  y_next = (double) ((int) ((node->mob->y_from + dy) * 100)) / 100;
+  /* LOG_D(OMG,"#node %d X FROM %.2f x next %.2f Y FROM %.2f y next %.2f \n\n",node->id,node->mob->x_from,x_next,  node->mob->y_from,y_next); */
+
+  alpha = (node->mob->azimuth * M_PI / 180);	//in radian
+  x_now = node->mob->x_from;
+  y_now = node->mob->y_from;
+
+  while (true)
+    {
+
+      if (x_next < omg_param_list[node->type].min_x)
+	{
+	  distancex =
+	    (omg_param_list[node->type].min_x - x_now) / cos (alpha);
+
 	}
-	else if (X_next>param_list.max_X){
-		node->mob->X_to =  param_list.max_X;
+      else if (x_next > omg_param_list[node->type].max_x)
+	{
+	  distancex =
+	    (omg_param_list[node->type].max_x - x_now) / cos (alpha);
+
 	}
-	else {
-		node->mob->X_to = X_next;
+      else
+	{
+	  distancex = distance;
 	}
 
-	if (Y_next<param_list.min_Y){ 
-		node->mob->Y_to = param_list.min_Y;  
+      if (y_next < omg_param_list[node->type].min_y)
+	{
+	  distancey =
+	    (omg_param_list[node->type].min_y - y_now) / sin (alpha);
+
 	}
-	else if (Y_next>param_list.max_Y){
-		node->mob->Y_to =  param_list.max_Y;
+      else if (y_next > omg_param_list[node->type].max_y)
+	{
+	  distancey =
+	    (omg_param_list[node->type].max_y - y_now) / sin (alpha);
+
 	}
-	else {
-		node->mob->Y_to = Y_next;
-	}*/
-   if (X_next < omg_param_list.min_X){
-	  while (X_next < omg_param_list.min_X){ 
-	   	X_next = X_next + omg_param_list.max_X;  
-	  }
-    node->mob->X_to = X_next;
-   }
-	else if (X_next > omg_param_list.max_X){
-     while (X_next > omg_param_list.max_X){ 
-		 X_next =  X_next - omg_param_list.max_X;
-	  }
-    node->mob->X_to = X_next;
-   }
-	else {
-		node->mob->X_to = X_next;
+      else
+	{
+	  distancey = distance;
 	}
 
-	if (Y_next < omg_param_list.min_Y){ 
-     while (Y_next < omg_param_list.min_Y){
-		Y_next = Y_next + omg_param_list.max_Y;
-	  }
-     node->mob->Y_to = Y_next;
-   }
-	else if (Y_next > omg_param_list.max_Y){
-     while (Y_next > omg_param_list.max_Y){
-		Y_next =  Y_next - omg_param_list.max_Y;
-     }
-     node->mob->Y_to = Y_next;
+
+      if ((distancex == distance && distancey == distance))
+	break;
+
+
+
+      if (distancey < distancex)
+	{
+
+	  x_now = distancey * cos (alpha) + x_now;
+	  y_now = distancey * sin (alpha) + y_now;
+	  distance = distance - distancey;
+
+	  dx = distance * cos (2 * M_PI - alpha);
+	  dy = distance * sin (2 * M_PI - alpha);
+
+	  x_next = x_now + dx;
+	  y_next = y_now + dy;
+
+	  alpha = 2 * M_PI - alpha;
+
 	}
-	else {
-		node->mob->Y_to = Y_next;
+      else if (distancex < distancey)
+	{
+
+	  x_now = distancex * cos (alpha) + x_now;
+	  y_now = distancex * sin (alpha) + y_now;
+
+	  distance = distance - distancex;
+
+	  dx = distance * cos (M_PI - alpha);
+	  dy = distance * sin (M_PI - alpha);
+
+	  x_next = x_now + dx;
+	  y_next = y_now + dy;
+
+	  alpha = M_PI - alpha;
 	}
-	
-	LOG_I(OMG, "destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
-
-	node->mob->start_journey = cur_time;
-   	LOG_D(OMG, "start_journey %.2f\n", node->mob->start_journey );
-	
-	pair->a = (double) ((int) ( (node->mob->start_journey + journeyTime_next) *100))/ 100 ;
-	LOG_D(OMG, "pair->a= start journey + journeyTime_next next %.2f\n", pair->a);
-
-	pair->b = node;
-	return pair;
-	
-}
+      i++;
 
+    }
 
+  node->mob->x_to = x_next;
+  node->mob->y_to = y_next;
 
+  /*LOG_D(OMG,"#node %d x to %.2f y to %.2f \n\n",node->id,node->mob->x_to,node->mob->y_to);
+     node->mob->start_journey = cur_time; */
+  journeytime_next =
+    (double) ((int) (distance / node->mob->speed * 100)) / 100;
+  pair->next_event_t =
+    (double) ((int) ((node->mob->start_journey + journeytime_next) * 100)) /
+    100;
 
+  if (node->event_num < 100)
+    {
+      event_sum[node->event_num] += node->mob->speed;
+      events[node->event_num]++;
+      node->event_num++;
+    }
 
-void update_rwalk_nodes(double cur_time) {// need to implement an out-of-area check as well as a rebound function to stay in the area
-   LOG_D(OMG, "--------UPDATE--------\n");
-   Job_list tmp = Job_Vector;
-   int done = 0; //
-   while ((tmp != NULL) && (done == 0)){
-      //if 	(tmp->pair == NULL){LOG_E(OMG, "UPDATE RWALK : tmp->pair ==NULL\n" );}
-      //if 	(tmp->pair != NULL){LOG_E(OMG, "UPDATE RWALK : tmp->pair !=NULL\n" );}
-	   LOG_D(OMG, "cur_time %f\n", cur_time );
-		LOG_D(OMG, "tmp->pair->a  %f\n", tmp->pair->a  );
-
-      if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) { 
-		   if (tmp->pair->b->generator == RWALK){
-				LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
- 				LOG_D(OMG, " UPDATE RWALK \n ");
-				NodePtr my_node = (NodePtr)tmp->pair->b;
-				/*if(my_node->mobile == 1) {
- 					LOG_D(OMG, " stop node and let it sleep \n" );
-					my_node->mobile = 0;
-					Pair pair = malloc(sizeof(Pair));
-					pair = sleep_rwalk_node(my_node, cur_time);
-					tmp->pair = pair;
-					tmp = tmp->next;
-				}*/
-				if ((my_node->mobile ==0) || (my_node->mobile == 1)) {
-					LOG_D(OMG, " node %d...let's move again \n",  my_node->ID);
-					my_node->mobile = 1;
-					Pair pair = malloc(sizeof(Pair));
-					pair = move_rwalk_node(my_node, cur_time);
-					tmp->pair = pair;
-					tmp = tmp->next;
-				}
-				else{
-			  		LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
-					//exit(-1);
-				}
-         }
-         else {
-            LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWALK=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWALK );
-            tmp = tmp->next;
-         }
-      }
-		else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){  //&& (tmp->pair->b->generator == RWALK)
-		    LOG_D(OMG, " %.2f < %.2f \n",cur_time, tmp->pair->a);
-		    LOG_D(OMG, "Nothing to do\n");
-			 done = 1;  //quit the loop
-		}
-      else {
-			LOG_E(OMG, "\n %.2f > %.2f", cur_time,tmp->pair->a   );   //LOG_D(OMG, " (generator=%d) != (RWALK=%d) \n", tmp->pair->b->generator,  RWALK );
-		   done = 1;  //quit the loop
-         exit(-1);
-		}	
- }
-			//sorting the new entries
-			LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
-  			display_job_list(Job_Vector);
- 			Job_Vector = quick_sort (Job_Vector);///////////
-  			LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n"); 
- 			display_job_list(Job_Vector);
 }
 
-void get_rwalk_positions_updated(double cur_time){
-  
-  double X_now=0.0;
-  double Y_now=0.0;
-  LOG_D(OMG,"--------GET RWALK POSITIONS--------\n"); 
-  Pair my_pair = Job_Vector->pair;
-  if ( my_pair ==NULL) {
-    LOG_E(OMG, "my_pair ==NULL");
-  }
-  else if ( (my_pair !=NULL) && (cur_time <= my_pair->a ) ){
-      LOG_D(OMG," %.2f <= %.2f \n",cur_time, my_pair->a);
-      Job_list tmp = Job_Vector;
-      while (tmp != NULL){
-		  if (tmp->pair->b->generator == RWALK){
-			 if (tmp->pair->b->mobile == 0){ //node is sleeping
-			    LOG_T(OMG,"node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-			    LOG_T(OMG,"Nothing to do, node is sleeping\n");
-			 } 
-			else if (tmp->pair->b->mobile == 1){ //node is moving
-			    LOG_T(OMG,"Node_number %d\n", tmp->pair->b->ID);
-			    LOG_T(OMG, "destination not yet reached\tfrom (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n", tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-
-			    double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
-			    double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
-				  
-			    double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
-			    LOG_D(OMG,"len %f\tdx %f\tdy %f\n", len, dx, dy);
-			    if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
-				   X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
-			    }
-			    else{
-				   X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-			    }
-			    	
-			    if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){
-				   Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-			    }
-			    else{
-				   Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-			    }
-
-
-				    LOG_D(OMG,"X_now %f\tY_now %f\n", X_now, Y_now);
-
-            if (X_now < omg_param_list.min_X){
-	            while (X_now < omg_param_list.min_X){ 
-	   	        X_now = X_now + omg_param_list.max_X;  
-	            }
-             }
-	          else if (X_now > omg_param_list.max_X){
-               while (X_now > omg_param_list.max_X){ 
-	              X_now =  X_now - omg_param_list.max_X;
-	            }
-            }
-	         else {
-				   X_now = X_now;
-	         }
-
-	        if (Y_now < omg_param_list.min_Y){ 
-             while (Y_now < omg_param_list.min_Y){
-	            Y_now = Y_now + omg_param_list.max_Y;
-	          }
-           }
-	        else if (Y_now > omg_param_list.max_Y){
-             while (Y_now > omg_param_list.max_Y){
-	            Y_now =  Y_now - omg_param_list.max_Y;
-            }
-	       }
-	      else {
-		     Y_now = Y_now;
-	      }
-		LOG_D(OMG,"X_now %f\tY_now %f\n", X_now, Y_now);
-		
-		
-		tmp->pair->b->X_pos = (double) ((int) (X_now*100))/ 100;
-		tmp->pair->b->Y_pos = (double) ((int) (Y_now*100))/ 100;
-		//tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
-		//tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
-		//tmp->pair->b->mob->start_journey = cur_time;
-		LOG_D(OMG,"updated_position of node number %d is :(%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-			}
-			 
-			else{
-			  LOG_E(OMG,"update_generator: unsupported node state : %d \n", tmp->pair->b->mobile);
-			   return; 
-			}
-		 }
-		 tmp = tmp->next;
-		}
+double
+residualtime (omg_global_param omg_param)
+{
+  double u;
+  u = randomgen (0, 1);
+  if (u <
+      (2 * omg_param.min_sleep /
+       (omg_param.max_journey_time + omg_param.min_journey_time)))
+    return u * (omg_param.max_journey_time + omg_param.min_journey_time) / 2;
+  else
+    return omg_param.max_journey_time -
+      sqrtf ((1 - u) * (pow (omg_param.max_journey_time, 2) -
+			pow (omg_param.min_sleep, 2)));
+}
+
+
+void
+update_rwalk_nodes (double cur_time)
+{
+  int done = 0;
+  job_list *tmp = job_vector[RWALK];
+  node_struct *my_node;
+  while (tmp != NULL && done == 0)
+    {
+      my_node = (node_struct *) tmp->pair->b;
+
+      //case1:time to next event equals to current time    
+      if (tmp->pair != NULL
+	  && ((double) tmp->pair->next_event_t >= cur_time - eps)
+	  && ((double) tmp->pair->next_event_t <= cur_time + eps))
+	{
+	  if (my_node->mobile == 1)
+	    sleep_rwalk_node (tmp->pair, cur_time);
+	  else
+	    move_rwalk_node (tmp->pair, cur_time);
+
+	}
+      //case2: current time is greater than the time to next event
+
+      else if (tmp->pair != NULL
+	       && (cur_time - eps) > tmp->pair->next_event_t)
+	{
+
+	  while (cur_time >= tmp->pair->next_event_t)
+	    {
+	      if (my_node->mobile == 1)
+		sleep_rwalk_node (tmp->pair, cur_time);
+	      else
+		move_rwalk_node (tmp->pair, cur_time);
+
+	    }
 	}
-	else {
-  	   LOG_E(OMG,"ERROR current time %f > first job_time %f\n", cur_time,   my_pair->a);		
-  }	
+      //case3: current time less than the time to next event
+      else
+	{
+	  done = 1;		//quit the loop
+	}
+
+
+      tmp = tmp->next;
+    }
+  //sorting the new entries
+  // LOG_D (OMG, "--------DISPLAY JOB LIST--------\n");  //LOG_T
+  //display_job_list (Job_Vector);
+  job_vector[RWALK] = quick_sort (job_vector[RWALK]);	///////////
+  // LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
+  //display_job_list (job_vector[RWALK]);
 }
 
+void
+get_rwalk_positions_updated (double cur_time)
+{
+
+  double x_now = 0.0, y_now = 0.0;
+  double len, dx, dy;
+  double distancex, distancey, alpha;
+  double x_next, y_next;
+  job_list *tmp = job_vector[RWALK];
+
+  while (tmp != NULL)
+    {
 
-/*void update_rwalk_nodes(double cur_time) {// need to implement an out-of-area check as well as a rebound function to stay in the area
-
-	LOG_D(OMG,"--------UPDATE--------\n");
-	int l = 0;
-	
-	Job_list tmp = Job_Vector;
-	while (l < Job_Vector_len){
-		LOG_D(OMG,"l == %d \n", l); 
-		Pair my_pair = tmp->pair;
-		LOG_D(OMG,"%.2f\n ",my_pair->a);
-		if((my_pair !=NULL) && ( (double)my_pair->a >= cur_time - eps) && ( (double)my_pair->a <= cur_time + eps)) { 
-			LOG_D(OMG,"%.2f == %.2f \n ",my_pair->a, cur_time );
-         if (my_pair->b->generator == RWALK) {
- 				LOG_D(OMG," UPDATE RWALK \n ");
-			   NodePtr my_node= (NodePtr)my_pair->b;
-			//if(my_node->mobile == 1) {
- 			//	LOG_D(OMG," move again \n" );
-			//	// stop node and let it sleep
-			//	my_node->mobile = 0;
-			//	Pair pair = malloc(sizeof(Pair));
-			//	pair = sleep_rwalk_node(my_node, cur_time);
-			//	Job_Vector->pair = pair;
-			//}
-			   if ((my_node->mobile ==0) ||( my_node->mobile == 1)) {
-				  LOG_D(OMG," ...let's move again \n" );
-				  // ...let's move again
-				  my_node->mobile = 1;
-				  Pair pair = malloc(sizeof(Pair));
-				  pair = move_rwalk_node(my_node, cur_time);
-				  Job_Vector->pair = pair;
-			  }
-			  else{
-			    LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
-			  }
-			//sorting the new entries
-			LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
-  			display_job_list(Job_Vector);
-  			Job_Vector = quick_sort (Job_Vector); //////////
- 			LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n"); 
- 			display_job_list(Job_Vector);
-         tmp = tmp->next;
-			l++;
-		 }
-       else {
-			LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator %d) != (RWALK %d)\n ",my_pair->a, cur_time, my_pair->b->generator, RWALK );
-         tmp = tmp->next;
-         l++;
-       }
-      }
-		else if ( (my_pair !=NULL) && (cur_time < my_pair->a ) && (my_pair->b->generator == RWALK) ){
-		    LOG_D(OMG," %.2f < %.2f\n ",cur_time, my_pair->a);
-		    l = Job_Vector_len;
-		    LOG_D(OMG,"Nothing to do\n");
+      if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
+	{
+
+	  len =
+	    tmp->pair->b->mob->speed * (cur_time -
+					tmp->pair->b->mob->start_journey);
+
+	  dx = len * cos (tmp->pair->b->mob->azimuth * M_PI / 180);
+	  dy = len * sin (tmp->pair->b->mob->azimuth * M_PI / 180);
+
+	  x_next =
+	    (double) ((int) ((tmp->pair->b->mob->x_from + dx) * 100)) / 100;
+	  y_next =
+	    (double) ((int) ((tmp->pair->b->mob->y_from + dy) * 100)) / 100;
+
+
+	  alpha = (tmp->pair->b->mob->azimuth * M_PI / 180);	//in radian
+	  x_now = tmp->pair->b->mob->x_from;
+	  y_now = tmp->pair->b->mob->y_from;
+
+	  while (true)
+	    {
+
+	      if (x_next < omg_param_list[tmp->pair->b->type].min_x)
+		{
+		  distancex =
+		    (omg_param_list[tmp->pair->b->type].min_x -
+		     x_now) / cos (alpha);
+		}
+	      else if (x_next > omg_param_list[tmp->pair->b->type].max_x)
+		{
+		  distancex =
+		    (omg_param_list[tmp->pair->b->type].max_x -
+		     x_now) / cos (alpha);
+		}
+	      else
+		{
+		  distancex = len;
 		}
-		else {
-		    l = Job_Vector_len;
-		    //LOG_D(OMG,"(generator=%d) != (RWALK=%d)\n", my_pair->b->generator,  RWALK );
-			 LOG_E(OMG, " %.2f > %.2f \n", cur_time,my_pair->a);
-		}	
-}
-}*/
 
+	      if (y_next < omg_param_list[tmp->pair->b->type].min_y)
+		{
+		  distancey =
+		    (omg_param_list[tmp->pair->b->type].min_y -
+		     y_now) / sin (alpha);
+		}
+	      else if (y_next > omg_param_list[tmp->pair->b->type].max_y)
+		{
+		  distancey =
+		    (omg_param_list[tmp->pair->b->type].max_y -
+		     y_now) / sin (alpha);
+		}
+	      else
+		{
+		  distancey = len;
+		}
+
+	      if (distancex == len && distancey == len)
+		break;
 
 
+	      if (distancey < distancex)
+		{
+		  x_now = distancey * cos (alpha) + x_now;
+		  y_now = distancey * sin (alpha) + y_now;
+		  len = len - distancey;
 
+		  dx = len * cos (2 * M_PI - alpha);
+		  dy = len * sin (2 * M_PI - alpha);
 
+		  x_next = x_now + dx;
+		  y_next = y_now + dy;
+
+		  alpha = 2 * M_PI - alpha;
+
+		}
+	      else if (distancex < distancey)
+		{
+		  x_now = distancex * cos (alpha) + x_now;
+		  y_now = distancex * sin (alpha) + y_now;
+
+		  len = len - distancex;
+
+		  dx = len * cos (M_PI - alpha);
+		  dy = len * sin (M_PI - alpha);
+
+		  x_next = x_now + dx;
+		  y_next = y_now + dy;
+
+		  alpha = M_PI - alpha;
+		}
 
-		
+
+	    }
+
+	  tmp->pair->b->x_pos = (double) ((int) (x_next * 100)) / 100;
+	  tmp->pair->b->y_pos = (double) ((int) (y_next * 100)) / 100;
+
+
+	}
+      else
+	{
+	  tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
+	  tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
+	}
+
+      //if(tmp->pair->b->id==2 && ((int)(cur_time*1000)% 100)==0)
+      //LOG_D (OMG, "%d  %.2f %.2f \n\n",tmp->pair->b->id,tmp->pair->b->x_pos,tmp->pair->b->y_pos);   
+
+      tmp = tmp->next;
+
+    }
+}
diff --git a/openair2/UTIL/OMG/rwalk.h b/openair2/UTIL/OMG/rwalk.h
index a5ace929311ecb9255f923036383800843ed7b5b..86d199018211a47d49cb0541b86f6afd9134caef 100644
--- a/openair2/UTIL/OMG/rwalk.h
+++ b/openair2/UTIL/OMG/rwalk.h
@@ -49,7 +49,7 @@ int start_rwalk_generator(omg_global_param omg_param_list) ;
  * \brief Called by the function start_rwalk_generator(), it generates a random position ((X,Y) coordinates)  for a node and add it to the corresponding Node_Vector_Rwp 
  * \param node a pointer of type NodePtr that represents the node to which the random position is assigned
  */
-void place_rwalk_node(NodePtr node) ;
+void place_rwalk_node(node_struct* node) ;
 
 /**
  * \fn Pair sleep_rwalk_node(NodePtr node, double cur_time)
@@ -58,7 +58,7 @@ void place_rwalk_node(NodePtr node) ;
  * \param cur_time a variable of type double that represents the current time
  * \return A Pair structure containing the node and the time when it is reaching the destination
  */
-Pair sleep_rwalk_node(NodePtr node, double cur_time) ;
+void sleep_rwalk_node(pair_struct* pair, double cur_time) ;
 
 
 /**
@@ -68,7 +68,7 @@ Pair sleep_rwalk_node(NodePtr node, double cur_time) ;
  * \param cur_time a variable of type double that represents the current time
  * \return A Pair structure containing the node structure and the arrival time at the destination
  */
-Pair move_rwalk_node(NodePtr node, double cur_time) ;
+void move_rwalk_node(pair_struct* pair, double cur_time) ;
 
 /**
  * \fn void update_rwalk_nodes(double cur_time)
@@ -87,4 +87,7 @@ void update_rwalk_nodes(double cur_time) ; // need to implement an out-of-area c
  */
 void get_rwalk_positions_updated(double cur_time) ;
 
+/*for perfect simulation of random walk*/
+double residualtime(omg_global_param omg_param);
+
 #endif /* RWALK_H_ */
diff --git a/openair2/UTIL/OMG/rwp.c b/openair2/UTIL/OMG/rwp.c
index 57cde714a23cd458b065d504e13ebf9d65a4736f..8fa2507c106a439c0a9408877f839591da77525b 100644
--- a/openair2/UTIL/OMG/rwp.c
+++ b/openair2/UTIL/OMG/rwp.c
@@ -29,7 +29,7 @@
 
 /*! \file rwp.c
 * \brief random waypoint mobility generator 
-* \author  M. Mahersi,  J. Harri, N. Nikaein,
+* \author  M. Mahersi,  N. Nikaein,  J. Harri
 * \date 2011
 * \version 0.1
 * \company Eurecom
@@ -43,329 +43,405 @@
 #include <time.h>
 #include <math.h>
 #include "rwp.h"
-#include "omg.h"
-
-
-int start_rwp_generator(omg_global_param omg_param_list) { 
- 
-  int n_id=0;
-  //omg_omg_param_list.seed= time(NULL); 
-  srand(omg_param_list.seed + RWP);
-  
-  double cur_time = 0.0; 
-  NodePtr node = NULL;
-  MobilityPtr mobility = NULL;
-  
-  if (omg_param_list.nodes <= 0){
-    LOG_W(OMG,"[RWP] Number of nodes has not been set\n");
-    return(-1);
-  }
-
-	if (omg_param_list.nodes_type == eNB) {
-		LOG_I(OMG,"[RWP] Node type has been set to eNB\n");
-	} else if (omg_param_list.nodes_type == UE) {
-		LOG_I(OMG, "[RWP] Node type has been set to UE\n");
-	}
- 	LOG_I(OMG, "[RWP] Number of random waypoint nodes has been set to %d\n", omg_param_list.nodes);
-  
-  for (n_id = 0; n_id< omg_param_list.nodes; n_id++) {
-    
-    node = (NodePtr) create_node();
-    mobility = (MobilityPtr) create_mobility();
-    node->mobile = 0;  // static for the moment
-    node->ID = n_id;
-    node->type = omg_param_list.nodes_type; // UE eNB
-    node->generator = omg_param_list.mobility_type;   // STATIC, RWP...
-    node->mob = mobility;
-    
-    place_rwp_node(node);	//initial positions
-    
-    Pair pair = malloc (sizeof(Pair));
-    pair = sleep_rwp_node(node, cur_time); //sleep
-    
-    Job_Vector = add_job(pair, Job_Vector);
-    Job_Vector_len ++;
-
-    if (Job_Vector == NULL)
-      LOG_E(OMG, "[RWP] Job Vector is NULL\n");
-    // else
-    // LOG_T(OMG, "\nJob_Vector_Rwp->pair->b->ID %d\n", Job_Vector_Rwp->pair->b->ID);*/
-  }
-  return(0);
-}
 
 
-void place_rwp_node(NodePtr node) {
 
-	node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
-	node->mob->X_from = node->X_pos;
-	node->mob->X_to = node->X_pos;
-	node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
-	node->mob->Y_from = node->Y_pos;
-	node->mob->Y_to = node->Y_pos;
+int
+start_rwp_generator (omg_global_param omg_param_list)
+{
+  static int n_id = 0;
+  int id;
+  double cur_time = 0.0;
+  node_struct *node = NULL;
+  mobility_struct *mobility = NULL;
+  pair_struct *pair = NULL;
+
+  srand (omg_param_list.seed + RWP);
+
+  LOG_I (OMG, "# RWP mobility model for %d type %d nodes\n", omg_param_list.nodes,
+	 omg_param_list.nodes_type);
+  for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
+    {
+
+      node = create_node ();
+      mobility = create_mobility ();
+
+      node->id = id;
+      node->type = omg_param_list.nodes_type;
+      node->mob = mobility;
+      node->generator = RWP;
+      node->event_num = 0;
+      place_rwp_node (node);	//initial positions
+
+      pair = (pair_struct *) malloc (sizeof (struct pair_struct));
+      pair->b = node;
+      sleep_rwp_node (pair, cur_time);	//sleep
+
+      job_vector_end[RWP] = add_job (pair, job_vector_end[RWP]);
+      if (job_vector[RWP] == NULL)
+	job_vector[RWP] = job_vector_end[RWP];
+
+      job_vector_len[RWP]++;
+    }
+
+  n_id += omg_param_list.nodes;
+
 
-	node->mob->speed = 0.0;
-	node->mob->journey_time = 0.0;
 
-  	LOG_I(OMG, "[RWP] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n ", node->ID, node->type, node->X_pos, node->Y_pos);   
-	Node_Vector[RWP] = (Node_list) add_entry(node, Node_Vector[RWP]);
-   Node_Vector_len[RWP]++;
-	//Initial_Node_Vector_len[RWP]++;
+  if (job_vector[RWP] == NULL)
+    LOG_E (OMG, "[RWP] Job Vector is NULL\n");
+  return (0);
 }
 
 
-Pair sleep_rwp_node(NodePtr node, double cur_time){
-	node->mobile = 0;
-	node->mob->speed = 0.0;
-	node->mob->X_from = node->mob->X_to;
-	node->mob->Y_from = node->mob->Y_to;
-	node->X_pos = node->mob->X_to;
-	node->Y_pos = node->mob->Y_to;
-	Pair pair = malloc(sizeof(Pair)) ;
-	
-	node->mob->sleep_duration = (double) ((int) (randomGen(omg_param_list.min_sleep, omg_param_list.max_sleep)*100))/ 100;
-	LOG_D(OMG, "[RWP] node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
-
-	node->mob->start_journey = cur_time;
-	pair->a = node->mob->start_journey + node->mob->sleep_duration; //when to wake up
-	LOG_D(OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n", pair->a);
-	pair->b = node;
-
-	return pair;
+void
+place_rwp_node (node_struct * node)
+{
+
+  int loc_num;
+  double block_xmin, block_ymin;
+
+
+  if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
+    {
+      loc_num = (int) randomgen (0, omg_param_list[node->type].max_vertices);
+      node->x_pos =
+	(double) vertice_xpos (loc_num, omg_param_list[node->type]);
+      node->y_pos =
+	(double) vertice_ypos (loc_num, omg_param_list[node->type]);
+      //LOG_D(OMG,"location number %d x pos %.2f y pos %.2f \n\n",loc_num,node->x_pos,node->y_pos);
+    }
+  else if (omg_param_list[node->type].rwp_type == CONNECTED_DOMAIN)
+    {
+      node->block_num =
+	(int) randomgen (0, omg_param_list[node->type].max_block_num);
+      block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
+      block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
+
+      node->x_pos =
+	(double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
+	/ 100;
+
+      node->y_pos =
+	(double) ((int) (randomgen (block_ymin, yloc_div + block_ymin) * 100))
+	/ 100;
+
+    }
+  else
+    {
+      node->x_pos =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_x,
+		    omg_param_list[node->type].max_x) * 100)) / 100;
+
+      node->y_pos =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_y,
+		    omg_param_list[node->type].max_y) * 100)) / 100;
+    }
+  node->mob->x_from = node->x_pos;
+  node->mob->x_to = node->x_pos;
+  node->mob->y_from = node->y_pos;
+  node->mob->y_to = node->y_pos;
+  node->mob->speed = 0.0;
+  node->mob->journey_time = 0.0;
+  LOG_I (OMG,
+	 " #[RWP] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n ",
+	 node->id, node->type, node->x_pos, node->y_pos);
+
+  node_vector_end[node->type] =
+    (node_list *) add_entry (node, node_vector_end[node->type]);
+
+  if (node_vector[node->type] == NULL)
+    node_vector[node->type] = node_vector_end[node->type];
+
+  node_vector_len[node->type]++;
+  //Initial_Node_Vector_len[RWP]++;
 }
 
 
-Pair move_rwp_node(NodePtr node, double cur_time) {
-	
-	Pair pair = malloc(sizeof(Pair));
-	LOG_D(OMG, "[RWP] move node: %d\n",node->ID );
-	node->mob->X_from = node->X_pos;
-	node->mob->Y_from = node->Y_pos;
-	LOG_D(OMG, "[RWP] Current Position: (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
-
-	node->mobile = 0;
-	double X_next = (double) ((int)(randomGen(omg_param_list.min_X,omg_param_list.max_X)*100))/ 100;
-	node->mob->X_to = X_next;
-	double Y_next = (double) ((int)(randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
-	node->mob->Y_to = Y_next;
-	LOG_D(OMG, "[RWP] destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
-
-	double speed_next = (double) ((int)(randomGen(omg_param_list.min_speed, omg_param_list.max_speed)*100))/ 100;
-	node->mob->speed = speed_next;
-    	LOG_D(OMG, "[RWP] speed_next %.2f\n", speed_next); //m/s
-	double distance = (double) ((int)(sqrtf(pow(node->mob->X_from - X_next, 2) + pow(node->mob->Y_from - Y_next, 2))*100))/ 100;
-	LOG_D(OMG, "[RWP] distance %.2f\n", distance); //m
-
-	double journeyTime_next =  (double) ((int)(distance/speed_next*100))/ 100;   //duration to get to dest
-	////node->mob->journey_time = journeyTime_next;
-	node->mobile = 1;
-    	LOG_D(OMG, "[RWP] mob->journey_time_next %.2f\n",journeyTime_next );
-	
-	node->mob->start_journey = cur_time;
-   	LOG_D(OMG, "[RWP] start_journey %.2f\n", node->mob->start_journey );
-	pair->a = node->mob->start_journey + journeyTime_next;      //when to reach the destination
-	LOG_D(OMG, "[RWP] reaching the destination at time : start journey + journey_time next =%.2f\n", pair->a);
-
-	pair->b = node;
-	return pair;
+void
+sleep_rwp_node (pair_struct * pair, double cur_time)
+{
+  node_struct *node;
+  node = pair->b;
+  node->mobile = 0;
+  node->mob->speed = 0.0;
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
+  node->x_pos = node->mob->x_to;
+  node->y_pos = node->mob->y_to;
+
+  node->mob->sleep_duration =
+    (double) ((int)
+	      (randomgen
+	       (omg_param_list[node->type].min_sleep,
+		omg_param_list[node->type].max_sleep) * 100)) / 100;
+  /*LOG_D (OMG, "#[RWP] node: %d \tsleep duration : %.2f\n", node->id,
+     node->mob->sleep_duration); */
+
+  node->mob->start_journey = cur_time;
+  pair->next_event_t = cur_time + node->mob->sleep_duration;	//when to wake up
+  // LOG_D (OMG, "[RWP] wake up at time: cur_time + sleep_duration : %.2f\n",
+//       pair->a);
+
+
+
 }
-	
-
-
-void update_rwp_nodes(double cur_time) {
-  Job_list tmp = Job_Vector;
-   int done = 0; //
-   while ((tmp != NULL) && (done == 0)){
-     //  if 	(tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
-     //  if 	(tmp->pair != NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair !=NULL\n" );}
-     LOG_D(OMG, "[RWP] cur_time %f reaching the destination at %f\n", cur_time, tmp->pair->a  );
-          
-     if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) { 
-       if (tmp->pair->b->generator == RWP){
-	 LOG_D(OMG, "[RWP](first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
-	 NodePtr my_node = (NodePtr)tmp->pair->b;
-	 if(my_node->mobile == 1) {
-	   LOG_D(OMG, "[RWP] node %d goes to sleep\n", my_node->ID);
-	   my_node->mobile = 0;
-	   Pair pair = malloc(sizeof(Pair));
-	   pair = sleep_rwp_node(my_node, cur_time);
-	   tmp->pair = pair;
-	   tmp = tmp->next;
-	 }
-	 else if (my_node->mobile ==0) {
-	   LOG_D(OMG, "[RWP] node %d starts to move again \n",  my_node->ID);
-	   my_node->mobile = 1;
-	   Pair pair = malloc(sizeof(Pair));
-	   pair = move_rwp_node(my_node, cur_time);
-	   tmp->pair = pair;
-	   tmp = tmp->next;
-	 }
-	 else{
-	   LOG_E(OMG,"[RWP] update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
-	   exit(-1);
-	 }
-       }
-       else {
-	 LOG_D(OMG, "[RWP](first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWP=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWP );
-	 tmp = tmp->next;
-       }
-     }
-     else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){  //&& (tmp->pair->b->generator == RWP)
-       LOG_D(OMG, "[RWP] Nothing to do as current time %.2f is less than the time to reach the destination %.2f \n",cur_time, tmp->pair->a);
-       done = 1;  //quit the loop
-     }
-     else {
-       LOG_E(OMG,"[RWP] current time %.2f is %f greater than the time to reach the destination %.2f\n", cur_time, eps, tmp->pair->a );   
-       done = 1;  //quit the loop
-       // exit(-1);
-     }	
- }
-   //sorting the new entries
-   LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
-   display_job_list(Job_Vector);
-   Job_Vector = quick_sort (Job_Vector);///////////
-   LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n"); 
-   display_job_list(Job_Vector);
+
+
+void
+move_rwp_node (pair_struct * pair, double cur_time)
+{
+  int loc_num;
+  double distance, journeytime_next;
+  double pr, block_xmin, block_ymin;
+  //LOG_D (OMG, "[RWP] move node: %d\n", node->ID);
+  node_struct *node;
+  node = pair->b;
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
+  node->x_pos = node->mob->x_to;
+  node->y_pos = node->mob->y_to;
+  node->mobile = 1;
+
+
+  if (omg_param_list[node->type].rwp_type == RESTIRICTED_RWP)
+    {
+      do
+	{
+	  loc_num =
+	    (int) randomgen (0, omg_param_list[node->type].max_vertices);
+	  node->mob->x_to =
+	    (double) vertice_xpos (loc_num, omg_param_list[node->type]);
+	  node->mob->y_to =
+	    (double) vertice_ypos (loc_num, omg_param_list[node->type]);
+
+
+	}
+      while (node->mob->x_to == node->mob->x_from
+	     && node->mob->y_to == node->mob->y_from);
+
+      distance = fabs (node->mob->x_to - node->mob->x_from) +
+	fabs (node->mob->y_to - node->mob->y_from);
+
+      /* LOG_D(OMG,"#location number %d x pos to %.2f y pos to  %.2f x pos from %.2f y pos from  %.2f\n\n",loc_num,node->mob->x_to,node->mob->y_to,node->mob->x_from,node->mob->y_from); */
+
+    }
+  else if (omg_param_list[node->type].rwp_type == CONNECTED_DOMAIN)
+    {
+      pr = randomgen (0, 1);
+
+      if (pr <= 0.50)
+	/*node->block_num =
+	   (int) randomgen (0, omg_param_list[node->type].max_block_num); */
+	node->block_num =
+	  (int) next_block (node->block_num, omg_param_list[node->type]);
+
+      block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
+      block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
+
+      node->mob->x_to =
+	(double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
+	/ 100;
+
+      node->mob->y_to =
+	(double) ((int) (randomgen (block_ymin, yloc_div + block_ymin) * 100))
+	/ 100;
+
+      distance =
+	(double) ((int) (sqrtf
+			 (pow (node->mob->x_from - node->mob->x_to, 2) +
+			  pow (node->mob->y_from - node->mob->y_to,
+			       2)) * 100)) / 100;
+
+      node->mob->azimuth = atan2 (node->mob->y_to - node->mob->y_from, node->mob->x_to - node->mob->x_from);	//radian
+    }
+  else
+    {
+      node->mob->x_to =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_x,
+		    omg_param_list[node->type].max_x) * 100)) / 100;
+
+      node->mob->y_to =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_y,
+		    omg_param_list[node->type].max_y) * 100)) / 100;
+
+
+      distance =
+	(double) ((int) (sqrtf (pow (node->mob->x_from - node->mob->x_to, 2) +
+				pow (node->mob->y_from - node->mob->y_to,
+				     2)) * 100)) / 100;
+
+      node->mob->azimuth = atan2 (node->mob->y_to - node->mob->y_from, node->mob->x_to - node->mob->x_from);	//radian
+    }
+
+
+  node->mob->speed =
+    (double) ((int)
+	      (randomgen
+	       (omg_param_list[node->type].min_speed,
+		omg_param_list[node->type].max_speed) * 100)) / 100;
+  journeytime_next = (double) ((int) (distance / node->mob->speed * 100)) / 100;	//duration to get to dest
+
+  /* LOG_D (OMG, "#[RWP] %d mob->journey_time_next %.2f distance %.2f speed %.2f\n \n",node->id,    journeytime_next,   distance,node->mob->speed);
+   */
+  node->mob->start_journey = cur_time;
+  //LOG_D (OMG, "[RWP] start_journey %.2f\n", node->mob->start_journey);
+  pair->next_event_t = cur_time + journeytime_next;	//when to reach the destination
+  // LOG_D (OMG,
+  // "[RWP] reaching the destination at time : start journey + journey_time next =%.2f\n",
+  // pair->a);
+  /*
+		if (node->event_num < 100)
+    {
+      event_sum[node->event_num] += node->mob->speed;
+      events[node->event_num]++;
+      node->event_num++;
+    }
+   */
 }
 
-void get_rwp_positions_updated(double cur_time){
-  
-  double X_now=0.0;
-  double Y_now=0.0;
-  LOG_D(OMG, "--------GET RWP POSITIONS--------\n");
-  
-  Pair my_pair = Job_Vector->pair;
-  if ( (my_pair !=NULL) && (cur_time <= my_pair->a +eps)){
-    LOG_D(OMG, "[RWP] current time %.2f <= time when reaching the destination %.2f\n ",cur_time, my_pair->a);
-    Job_list tmp = Job_Vector;
-    while (tmp != NULL){
-      if (tmp->pair->b->generator == RWP){
-        if (tmp->pair->b->mobile == 0){ //node is sleeping
-          LOG_D(OMG, "[RWP] node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-	} 
-        else if (tmp->pair->b->mobile == 1){ //node is moving
-	  LOG_D(OMG, "[RWP] destination not yet reached for node %d from (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n",  
-		tmp->pair->b->ID, tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, 
-		tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-
-          double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
-          double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
-				  
-          double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
-          //LOG_D(OMG, "len %f\tdx %f\tdy %f\n", len, dx, dy);
-          if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
-            X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
-          }
-          else{
-            X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-          }
-			   
-          if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){
-            Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-          }
-          else{
-            Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-          }
- 
-          tmp->pair->b->X_pos = (double) ((int) (X_now*100))/ 100;
-          tmp->pair->b->Y_pos = (double) ((int) (Y_now*100))/ 100;
-          //tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
-          //tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
-	  //tmp->pair->b->mob->start_journey = cur_time;
-          LOG_D(OMG, "[RWP] Updated_position of node number %d is :(%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-        }	
-        else{
-          LOG_E(OMG, "[RWP] Update_generator: unsupported node state - mobile : %d \n", tmp->pair->b->mobile);
-          return; 
+
+/*update RWP nodes position*/
+
+void
+update_rwp_nodes (double cur_time)
+{
+
+  int done = 0;
+  job_list *tmp = job_vector[RWP];
+  node_struct *my_node;
+  while (tmp != NULL && done == 0)
+    {
+      my_node = (node_struct *) tmp->pair->b;
+
+      //case1:time to next event equals to current time    
+      if (tmp->pair != NULL
+	  && ((double) tmp->pair->next_event_t >= cur_time - eps)
+	  && ((double) tmp->pair->next_event_t <= cur_time + eps))
+	{
+	  if (my_node->mobile == 1)
+	    sleep_rwp_node (tmp->pair, cur_time);
+	  else
+	    move_rwp_node (tmp->pair, cur_time);
+
+	}
+      //case2: current time is greater than the time to next event
+
+      else if (tmp->pair != NULL
+	       && (cur_time - eps) > tmp->pair->next_event_t)
+	{
+
+	  while (cur_time >= tmp->pair->next_event_t)
+	    {
+	      if (my_node->mobile == 1)
+		sleep_rwp_node (tmp->pair, cur_time);
+	      else
+		move_rwp_node (tmp->pair, cur_time);
+
+	    }
+	}
+      //case3: current time less than the time to next event
+      else
+	{
+	  done = 1;		//quit the loop
 	}
-      }
+
+
       tmp = tmp->next;
     }
- }
- else {
-   LOG_E(OMG, "ERROR (current time) %f > %f (first job_time) \n", cur_time ,my_pair->a );
- }		
+
+  //sorting the new entries
+  //LOG_D (OMG, "--------DISPLAY JOB LIST--------\n");   //LOG_T
+  // display_job_list (job_vector);
+  job_vector[RWP] = quick_sort (job_vector[RWP]);	///////////
+  // LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
+  //display_job_list (job_vector[RWP]);
 }
 
 
-/*void update_rwp_nodes(double cur_time) {
-	LOG_D(OMG, "--------UPDATE--------\n");
-	int l = 0;
-	
-   Job_list tmp = Job_Vector;
-
-	while (l < Job_Vector_len){
-		LOG_D(OMG, "l == %d \n", l); 
-
-		//Pair my_pair = malloc (sizeof(Pair));
-      //my_pair = tmp->pair;
-
-      if 	(tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
-      if 	(tmp->pair != NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
-
-		LOG_D(OMG, "cur_time %f\n", cur_time );
-		LOG_D(OMG, "tmp->pair->a  %f\n", tmp->pair->a  );
-
-		if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) { 
-      	if (tmp->pair->b->generator == RWP){
-				LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
- 				LOG_D(OMG, " UPDATE RWP \n ");
-				NodePtr my_node = (NodePtr)tmp->pair->b;
-				if(my_node->mobile == 1) {
- 					LOG_D(OMG, " stop node and let it sleep \n" );
-					my_node->mobile = 0;
-					Pair pair = malloc(sizeof(Pair));
-					pair = sleep_rwp_node(my_node, cur_time);
-					tmp->pair = pair;
-				}
-				else if (my_node->mobile ==0) {
-					LOG_D(OMG, " node %d slept enough...let's move again \n",  my_node->ID);
-					my_node->mobile = 1;
-					Pair pair = malloc(sizeof(Pair));
-					pair = move_rwp_node(my_node, cur_time);
-					tmp->pair = pair;
-				}
-				else
-				{
-			  		LOG_D(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
-				}
-         
-			//sorting the new entries
-			LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
-  			display_job_list(Job_Vector);
- 			Job_Vector = quick_sort (Job_Vector);///////////
-  			LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n"); 
- 			display_job_list(Job_Vector);
-		LOG_D(OMG, "lgggggggggggggggggggggggggggggggggggggggggg\n"); 
-      if 	(tmp != NULL){LOG_E(OMG, "UPDATE RWP : tmp !=NULL\n" );}
-         tmp = tmp->next;
-      if 	(tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
-			l++;
-		 }
-       else {
-         LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (RWP=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, RWP );
-         tmp = tmp->next;
-       if 	(tmp->pair == NULL){LOG_E(OMG, "UPDATE RWP : tmp->pair ==NULL\n" );}
-         l++;
-      } 
-      }
-		else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){  //&& (tmp->pair->b->generator == RWP)
-		    LOG_D(OMG, " %.2f < %.2f \n",cur_time, tmp->pair->a);
-		    LOG_N(OMG, "Nothing to do\n");
-			 l = Job_Vector_len;
+void
+get_rwp_positions_updated (double cur_time)
+{
+
+  double x_now = 0.0, y_now = 0.0;
+  double len, dx, dy;
+  job_list *tmp = job_vector[RWP];
+
+  while (tmp != NULL)
+    {
+
+      if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
+	{
+
+	  if (omg_param_list[tmp->pair->b->type].rwp_type == RESTIRICTED_RWP)
+	    {
+	      len =
+		tmp->pair->b->mob->speed * (cur_time -
+					    tmp->pair->b->mob->start_journey);
+	      dx = fabs (tmp->pair->b->mob->x_from - tmp->pair->b->mob->x_to);
+
+	      if (dx < len)
+		{
+		  tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
+		  tmp->pair->b->y_pos =
+		    tmp->pair->b->mob->y_from + (len -
+						 dx) *
+		    ((tmp->pair->b->mob->y_to -
+		      tmp->pair->b->mob->y_from) /
+		     fabs (tmp->pair->b->mob->y_to -
+			   tmp->pair->b->mob->y_from));
+		}
+	      else
+		{
+		  tmp->pair->b->y_pos = tmp->pair->b->mob->y_from;
+		  tmp->pair->b->x_pos = tmp->pair->b->mob->x_from + len *
+		    ((tmp->pair->b->mob->x_to - tmp->pair->b->mob->x_from)
+		     / fabs (tmp->pair->b->mob->x_to -
+			     tmp->pair->b->mob->x_from));
 		}
-		else {
-			LOG_E(OMG, "\n %.2f > %.2f", cur_time,tmp->pair->a   );   //LOG_D(OMG, " (generator=%d) != (RWP=%d) \n", tmp->pair->b->generator,  RWP );
-		   l = Job_Vector_len;
-		}	
- }
-}*/
+
+	    }
+
+	  else
+	    {
+	      len =
+		tmp->pair->b->mob->speed * (cur_time -
+					    tmp->pair->b->mob->start_journey);
 
 
+	      dx = len * cos (tmp->pair->b->mob->azimuth);
+	      dy = len * sin (tmp->pair->b->mob->azimuth);
 
+	      x_now = tmp->pair->b->mob->x_from + dx;
+	      y_now = tmp->pair->b->mob->y_from + dy;
 
+	      tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
+	      tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
 
 
 
+	    }			//grid
 
 
+	}
+      else
+	{
+	  tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
+	  tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
+	}
+
+      /*if(tmp->pair->b->id==2 && ((int)(cur_time*1000)% 100)==0)
+         LOG_D (OMG, "# %d  %.2f %.2f \n\n",tmp->pair->b->id,tmp->pair->b->x_pos,tmp->pair->b->y_pos); */
+      tmp = tmp->next;
+
+    }
+
+}
diff --git a/openair2/UTIL/OMG/rwp.h b/openair2/UTIL/OMG/rwp.h
index 10649657abd8d81c5903a441d3d469eeeda47d14..dcbd0a4e837c5382d717e027fd8a24b49411d568 100644
--- a/openair2/UTIL/OMG/rwp.h
+++ b/openair2/UTIL/OMG/rwp.h
@@ -37,7 +37,7 @@
 #define RWP_H_
 
 #include "omg.h"
-
+#include "grid.h"
 
 /**
  * \fn void start_rwp_generator(omg_global_param omg_param_list)
@@ -51,7 +51,7 @@ int start_rwp_generator(omg_global_param omg_param_list) ;
  * \brief Called by the function start_rwp_generator(), it generates a random position ((X,Y) coordinates)  for a node and add it to the Node_Vector_Rwp 
  * \param node a pointer of type NodePtr that represents the node to which the random position is assigned
  */
-void place_rwp_node(NodePtr node);
+void place_rwp_node(node_struct* node);
 
 /**
  * \fn Pair sleep_rwp_node(NodePtr node, double cur_time)
@@ -61,7 +61,7 @@ void place_rwp_node(NodePtr node);
  * \param cur_time a variable of type double that represents the current time
  * \return A Pair structure containing the node and the time when it is reaching the destination
  */
-Pair sleep_rwp_node(NodePtr node, double cur_time) ;
+void sleep_rwp_node(pair_struct* pair, double cur_time) ;
 
 /**
  * \fn Pair move_rwp_node(NodePtr node, double cur_time)
@@ -71,7 +71,7 @@ Pair sleep_rwp_node(NodePtr node, double cur_time) ;
  * \param cur_time a variable of type double that represents the current time
  * \return A Pair structure containing the node structure and the arrival time at the destination
  */
-Pair move_rwp_node(NodePtr node, double cur_time) ;
+void move_rwp_node(pair_struct* pair, double cur_time);
 
 /**
  * \fn void update_rwp_nodes(double cur_time)
diff --git a/openair2/UTIL/OMG/socket_traci_OMG.h b/openair2/UTIL/OMG/socket_traci_OMG.h
index ffce4127858de59267c4cd96dd93da7c54fbc719..edca51c823fe87159f1eca38b2fb0e9588a1ec3b 100644
--- a/openair2/UTIL/OMG/socket_traci_OMG.h
+++ b/openair2/UTIL/OMG/socket_traci_OMG.h
@@ -77,17 +77,17 @@ int connection_(char *, int);
 void sendExact(int);
 
 /**
- * \fn  recieveExact();
+ * \fn  recieveExact(void);
  * \brief Pack the data to storage from buf after reading from socket
  * Returns storage pointer
  */     
-storage* receiveExact();
+storage* receiveExact(void);
 
 
 /**
- * \fn  close_connection();
+ * \fn  close_connection(void);
  * \brief close socket connection 
  */       
-void close_connection();
+void close_connection(void);
 
 #endif 
diff --git a/openair2/UTIL/OMG/static.c b/openair2/UTIL/OMG/static.c
index 85a14f33108831ed6d4da156a61cf5568e13784c..1275dacfbe19272fb26099452cdfbbf598727892 100644
--- a/openair2/UTIL/OMG/static.c
+++ b/openair2/UTIL/OMG/static.c
@@ -29,11 +29,11 @@
 
 /*! \file rwalk.c
 * \brief static  mobility generator 
-* \author  M. Mahersi,  J. Harri, N. Nikaein, Andre Gomes (One source)
+* \author  M. Mahersi, N. Nikaein, J. Harri
 * \date 2011
 * \version 0.1
 * \company Eurecom
-* \email: openair_tech@eurecom.fr
+* \email: 
 * \note
 * \warning
 */
@@ -41,79 +41,103 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "static.h"
+
+
+void
+start_static_generator (omg_global_param omg_param_list)
+{
+
+  int id;
+  static int n_id = 0;
+  node_struct *node = NULL;
+  mobility_struct *mobility = NULL;
+
+  srand (omg_param_list.seed + STATIC);
+
+  LOG_I (OMG, "Static mobility model for %d %d nodes\n", omg_param_list.nodes,
+	 omg_param_list.nodes_type);
+  for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
+    {
+
+      node = create_node ();
+      mobility = create_mobility ();
+
+      node->id = id;
+      node->type = omg_param_list.nodes_type;
+      node->mob = mobility;
+      node->generator = STATIC;
+      place_static_node (node);	//initial positions
+    }
+  n_id += omg_param_list.nodes;
+
 
-#include "omg.h"
-void place_static_node(NodePtr node);
-
-void start_static_generator(omg_global_param omg_param_list) {
-  
-  int n_id=0;
-  //  double cur_time = 1.0; 
-  NodePtr node = NULL;
-  MobilityPtr mobility = NULL;
-  
-  
-  if (omg_param_list.nodes <= 0){
-    LOG_W(OMG, "Number of static nodes has not been set\n");
-    return;
-  }
-  
-  srand(omg_param_list.seed + STATIC); 
-  // for (n_id = omg_param_list.first_ix; n_id< omg_param_list.first_ix + omg_param_list.nodes; n_id++){
-
-  if (omg_param_list.nodes_type == eNB) {
-    LOG_I(OMG, "Static mobility model for %d eNBs \n", omg_param_list.nodes);
-  } else if (omg_param_list.nodes_type == UE) {
-    LOG_I(OMG, "Static mobility model for %d UE\n",omg_param_list.nodes);
-  }
-    
-  for (n_id = 0; n_id< omg_param_list.nodes; n_id++) {
-    
-    node = (NodePtr) create_node();
-    mobility = (MobilityPtr) create_mobility();
-    
-    node->ID = n_id; 
-    node->generator = omg_param_list.mobility_type;
-    node->type =  omg_param_list.nodes_type;
-    node->mob = mobility;
-    node->generator = STATIC;
-
-    place_static_node(node);	//initial positions
-  }
 }
 
 
-void place_static_node(NodePtr node) {
-  if (omg_param_list.user_fixed && node->type == eNB) {
-    if (omg_param_list.fixed_X <= omg_param_list.max_X && omg_param_list.fixed_X >= omg_param_list.min_X)
-        node->X_pos = omg_param_list.fixed_X;
-    else
-        node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
-    node->mob->X_from = node->X_pos;
-    node->mob->X_to = node->X_pos;
-    if (omg_param_list.fixed_Y <= omg_param_list.max_Y && omg_param_list.fixed_Y >= omg_param_list.min_Y)
-        node->Y_pos = omg_param_list.fixed_Y;
-    else
-        node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
-    node->mob->Y_from = node->Y_pos;
-    node->mob->Y_to = node->Y_pos;
-  }
-  else {
-    node->X_pos = (double) ((int) (randomGen(omg_param_list.min_X, omg_param_list.max_X)*100))/ 100;
-    node->mob->X_from = node->X_pos;
-    node->mob->X_to = node->X_pos;
-    node->Y_pos = (double) ((int) (randomGen(omg_param_list.min_Y,omg_param_list.max_Y)*100))/ 100;
-    node->mob->Y_from = node->Y_pos;
-    node->mob->Y_to = node->Y_pos;
-  }
-  
+
+void
+place_static_node (node_struct * node)
+{
+  if (omg_param_list[node->type].user_fixed && node->type == eNB)
+    {
+      if (omg_param_list[node->type].fixed_x <=
+	  omg_param_list[node->type].max_x
+	  && omg_param_list[node->type].fixed_x >=
+	  omg_param_list[node->type].min_x)
+	node->x_pos = omg_param_list[node->type].fixed_x;
+      else
+	node->x_pos =
+	  (double) ((int)
+		    (randomgen
+		     (omg_param_list[node->type].min_x,
+		      omg_param_list[node->type].max_x) * 100)) / 100;
+      node->mob->x_from = node->x_pos;
+      node->mob->x_to = node->x_pos;
+      if (omg_param_list[node->type].fixed_y <=
+	  omg_param_list[node->type].max_y
+	  && omg_param_list[node->type].fixed_y >=
+	  omg_param_list[node->type].min_y)
+	node->y_pos = omg_param_list[node->type].fixed_y;
+      else
+	node->y_pos =
+	  (double) ((int)
+		    (randomgen
+		     (omg_param_list[node->type].min_y,
+		      omg_param_list[node->type].max_y) * 100)) / 100;
+      node->mob->y_from = node->y_pos;
+      node->mob->y_to = node->y_pos;
+    }
+  else
+    {
+
+      node->x_pos =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_x,
+		    omg_param_list[node->type].max_x) * 100)) / 100;
+      node->mob->x_from = node->x_pos;
+      node->mob->x_to = node->x_pos;
+      node->y_pos =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_y,
+		    omg_param_list[node->type].max_y) * 100)) / 100;
+      node->mob->y_from = node->y_pos;
+      node->mob->y_to = node->y_pos;
+    }
+
   node->mob->speed = 0.0;
   node->mob->journey_time = 0.0;
-  
-  LOG_I(OMG, "[STATIC] Initial position of node ID: %d type(UE, eNB): %d (X = %.2f, Y = %.2f) speed = 0.0\n", node->ID, node->type, node->X_pos, node->Y_pos);  
-  Node_Vector[STATIC] = (Node_list) add_entry(node, Node_Vector[STATIC]);
-  Node_Vector_len[STATIC]++;
-  //Initial_Node_Vector_len[STATIC]++;
-  
-}
 
+  LOG_I (OMG,
+	 "[STATIC] Initial position of node ID: %d type(%d):  (X = %.2f, Y = %.2f) speed = 0.0\n",
+	 node->id, node->type, node->x_pos, node->y_pos);
+  node_vector_end[node->type] =
+    (node_list *) add_entry (node, node_vector_end[node->type]);
+
+  if (node_vector[node->type] == NULL)
+    node_vector[node->type] = node_vector_end[node->type];
+
+  node_vector_len[node->type]++;
+}
diff --git a/openair2/UTIL/OMG/static.h b/openair2/UTIL/OMG/static.h
index 7323c3b2a2e0fa27b1cd9344bcb46ecf808ba961..7cb1ae7ea186da80f6fb38ef236b4c9f1fa503db 100644
--- a/openair2/UTIL/OMG/static.h
+++ b/openair2/UTIL/OMG/static.h
@@ -51,6 +51,6 @@ void start_static_generator(omg_global_param omg_param_list);
  * \brief Generates a random position ((X,Y) coordinates) and assign it to the node passed as argument. This latter node is then added to the Node_Vector[STATIC] 
  * \param node a pointer of type NodePtr that represents the node to which the random position is assigned
  */
-void place_static_node(NodePtr node);
+void place_static_node(node_struct* node);
 
 #endif /* STATIC_H_ */
diff --git a/openair2/UTIL/OMG/steadystaterwp.c b/openair2/UTIL/OMG/steadystaterwp.c
new file mode 100644
index 0000000000000000000000000000000000000000..c316114790b538a400264a623d73ec9db6bc09e5
--- /dev/null
+++ b/openair2/UTIL/OMG/steadystaterwp.c
@@ -0,0 +1,659 @@
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2011 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.fr
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fsr/openairinterface
+  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
+
+*******************************************************************************/
+
+/*! \file steadystaterwp.c
+* \brief random waypoint mobility generator 
+* \author  S. Gashaw,  J. Harri, N. Nikaein,
+* \date 2014
+* \version 0.1
+* \company Eurecom
+* \email: 
+* \note
+* \warning
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include "omg.h"
+#include "steadystaterwp.h"
+#include "rwp.h"
+#define RESTIRICTED_RWP 1
+#define CONNECTED_DOMAIN 2
+
+int
+start_steadystaterwp_generator (omg_global_param omg_param_list)
+{
+  static int n_id = 0;
+  int id;
+  double cur_time = 0.0, pause_p;
+  node_struct *node = NULL;
+  mobility_struct *mobility = NULL;
+  pair_struct *pair = NULL;
+
+  pause_p = pause_probability (omg_param_list);
+
+  srand (omg_param_list.seed + RWP);
+
+  LOG_I (OMG, "STEADY_RWP mobility model for %d %d nodes\n",
+	 omg_param_list.nodes, omg_param_list.nodes_type);
+  for (id = n_id; id < (omg_param_list.nodes + n_id); id++)
+    {
+
+      node = create_node ();
+      mobility = create_mobility ();
+
+      node->id = id;
+      node->type = omg_param_list.nodes_type;
+      node->mob = mobility;
+      node->generator = STEADY_RWP;
+      node->event_num = 0;
+      place_rwp_node (node);	//initial positions
+
+      pair = (pair_struct *) malloc (sizeof (struct pair_struct));
+      pair->b = node;
+      //pause probability...some of the nodes start at pause & the other on move
+
+      if (randomgen (0, 1) < pause_p)
+	sleep_steadystaterwp_node (pair, cur_time);	//sleep
+      else
+	move_steadystaterwp_node (pair, cur_time);
+
+      job_vector_end[STEADY_RWP] = add_job (pair, job_vector_end[STEADY_RWP]);
+
+      if (job_vector[STEADY_RWP] == NULL)
+	job_vector[STEADY_RWP] = job_vector_end[STEADY_RWP];
+
+      job_vector_len[STEADY_RWP]++;
+    }
+
+  n_id += omg_param_list.nodes;
+
+
+
+  if (job_vector[STEADY_RWP] == NULL)
+    LOG_E (OMG, "[STEADY_RWP] Job Vector is NULL\n");
+  return (0);
+}
+
+/*********************************xxxxxx************************************/
+
+void
+place_steadystaterwp_node (node_struct * node)
+{
+  int loc_num;
+  double block_xmin, block_ymin;
+
+
+  if (grid == RESTIRICTED_RWP)
+    {
+      loc_num = (int) randomgen (0, omg_param_list[node->type].max_vertices);
+      node->x_pos =
+	(double) vertice_xpos (loc_num, omg_param_list[node->type]);
+      node->y_pos =
+	(double) vertice_ypos (loc_num, omg_param_list[node->type]);
+      //LOG_D(OMG,"location number %d x pos %.2f y pos %.2f \n\n",loc_num,node->x_pos,node->y_pos);
+    }
+  else if (grid == CONNECTED_DOMAIN)
+    {
+      node->block_num =
+	(int) randomgen (0, omg_param_list[node->type].max_block_num);
+      block_xmin = area_minx (node->block_num, omg_param_list[node->type]);
+      block_ymin = area_miny (node->block_num, omg_param_list[node->type]);
+
+      node->x_pos =
+	(double) ((int) (randomgen (block_xmin, xloc_div + block_xmin) * 100))
+	/ 100;
+
+      node->y_pos =
+	(double) ((int) (randomgen (block_ymin, yloc_div + block_ymin) * 100))
+	/ 100;
+
+    }
+  else
+    {
+      node->x_pos =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_x,
+		    omg_param_list[node->type].max_x) * 100)) / 100;
+
+      node->y_pos =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_y,
+		    omg_param_list[node->type].max_y) * 100)) / 100;
+    }
+
+  node->mob->x_from = node->x_pos;
+  node->mob->x_to = node->x_pos;
+  node->mob->y_from = node->y_pos;
+  node->mob->speed = 0.0;
+  node->mob->journey_time = 0.0;
+  LOG_I (OMG,
+	 "#[STEADY_RWP] Initial position of node ID: %d type: %d X = %.2f, Y = %.2f\n ",
+	 node->id, node->type, node->x_pos, node->y_pos);
+
+  node_vector_end[node->type] =
+    (node_list *) add_entry (node, node_vector_end[node->type]);
+
+  if (node_vector[node->type] == NULL)
+    node_vector[node->type] = node_vector_end[node->type];
+
+  node_vector_len[node->type]++;
+  //Initial_Node_Vector_len[RWP]++;
+}
+
+
+/*********************************xxxxxx************************************/
+
+void
+sleep_steadystaterwp_node (pair_struct * pair, double cur_time)
+{
+  static int initial = 1;
+  node_struct *node;
+  node = pair->b;
+  node->mobile = 0;
+  node->mob->speed = 0.0;
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
+  node->x_pos = node->mob->x_to;
+  node->y_pos = node->mob->y_to;
+  if (node->event_num == 0)
+    {
+      node->mob->sleep_duration = initial_pause (omg_param_list[node->type]);
+      node->event_num++;
+    }
+  else
+    {
+      node->mob->sleep_duration =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_sleep,
+		    omg_param_list[node->type].max_sleep) * 100)) / 100;
+    }
+  // LOG_D (OMG, "[STEADY_RWP] node: %d \tsleep duration : %.2f\n", node->ID,
+//       node->mob->sleep_duration);
+
+  node->mob->start_journey = cur_time;
+  pair->next_event_t = cur_time + node->mob->sleep_duration;	//when to wake up
+  // LOG_D (OMG, "[STEADY_RWP] wake up at time: cur_time + sleep_duration : %.2f\n",
+//       pair->a);
+
+
+}
+
+
+void
+move_steadystaterwp_node (pair_struct * pair, double cur_time)
+{
+  static int initial = 1;
+  double distance, journeytime_next, max_distance;
+  double temp_x, temp_y, u1, u2;
+  int loc_num;
+  double pr, block_xmin, block_ymin;
+
+  //LOG_D (OMG, "[STEADY_RWP] move node: %d\n", node->ID);
+  node_struct *node;
+  node = pair->b;
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
+  node->x_pos = node->mob->x_to;
+  node->y_pos = node->mob->y_to;
+  node->mobile = 1;
+//initial move
+  if (node->event_num == 0)
+    {
+
+
+      if (grid == CONNECTED_DOMAIN)
+	{
+	  max_distance = 2 * yloc_div;
+	  /* sqrtf (pow
+	     (omg_param_list[node->type].max_x -
+	     omg_param_list[node->type].min_x,
+	     2) + pow (omg_param_list[node->type].max_y -
+	     omg_param_list[node->type].min_y, 2)); */
+	  while (true)
+	    {
+	      pr = randomgen (0, 1);
+
+	      if (pr <= 0.50)
+		/*node->block_num =
+		   (int) randomgen (0,
+		   omg_param_list[node->type].max_block_num); */
+		node->block_num =
+		  (int) next_block (node->block_num,
+				    omg_param_list[node->type]);
+
+	      block_xmin =
+		area_minx (node->block_num, omg_param_list[node->type]);
+	      block_ymin =
+		area_miny (node->block_num, omg_param_list[node->type]);
+
+	      node->mob->x_to =
+		(double) ((int)
+			  (randomgen (block_xmin, xloc_div + block_xmin) *
+			   100)) / 100;
+
+	      node->mob->y_to =
+		(double) ((int)
+			  (randomgen (block_ymin, yloc_div + block_ymin) *
+			   100)) / 100;
+	      pr = randomgen (0, 1);
+
+	      if (pr <= 0.50)
+		/*node->block_num =
+		   (int) randomgen (0,
+		   omg_param_list[node->type].max_block_num); */
+		node->block_num =
+		  (int) next_block (node->block_num,
+				    omg_param_list[node->type]);
+	      block_xmin =
+		area_minx (node->block_num, omg_param_list[node->type]);
+	      block_ymin =
+		area_miny (node->block_num, omg_param_list[node->type]);
+
+	      temp_x =
+		(double) ((int)
+			  (randomgen (block_xmin, xloc_div + block_xmin) *
+			   100)) / 100;
+
+	      temp_y =
+		(double) ((int)
+			  (randomgen (block_ymin, yloc_div + block_ymin) *
+			   100)) / 100;
+
+
+	      u1 = randomgen (0, 1);
+
+	      if (u1 <
+		  (sqrtf
+		   (pow (node->mob->x_to - temp_x, 2) +
+		    pow (node->mob->y_to - temp_y, 2)) / max_distance))
+		{
+		  u2 = randomgen (0, 1);
+		  distance =
+		    (double) ((int)
+			      (sqrtf (pow (temp_x - node->mob->x_to, 2) +
+				      pow (temp_y - node->mob->y_to,
+					   2)) * 100)) / 100;
+		  node->mob->azimuth = atan2 (node->mob->y_to - node->mob->y_from, node->mob->x_to - node->mob->x_from);	//radian
+		  node->mob->x_from =
+		    temp_x + u2 * distance * cos (node->mob->azimuth);
+		  node->mob->y_from =
+		    temp_y + u2 * distance * sin (node->mob->azimuth);
+		  break;
+		}
+	    }
+	}
+      else
+	{
+	  max_distance =
+	    sqrtf (pow
+		   (omg_param_list[node->type].max_x -
+		    omg_param_list[node->type].min_x,
+		    2) + pow (omg_param_list[node->type].max_y -
+			      omg_param_list[node->type].min_y, 2));
+	  while (true)
+	    {
+	      node->mob->x_to =
+		(double) ((int)
+			  (randomgen
+			   (omg_param_list[node->type].min_x,
+			    omg_param_list[node->type].max_x) * 100)) / 100;
+
+	      node->mob->y_to =
+		(double) ((int)
+			  (randomgen
+			   (omg_param_list[node->type].min_y,
+			    omg_param_list[node->type].max_y) * 100)) / 100;
+
+	      temp_x = (double) ((int)
+				 (randomgen
+				  (omg_param_list[node->type].min_x,
+				   omg_param_list[node->type].max_x) * 100)) /
+		100;
+
+	      temp_y = (double) ((int)
+				 (randomgen
+				  (omg_param_list[node->type].min_y,
+				   omg_param_list[node->type].max_y) * 100)) /
+		100;
+
+	      u1 = randomgen (0, 1);
+
+	      if (u1 <
+		  (sqrtf
+		   (pow (node->mob->x_to - temp_x, 2) +
+		    pow (node->mob->y_to - temp_y, 2)) / max_distance))
+		{
+		  u2 = randomgen (0, 1);
+		  node->mob->x_from =
+		    u2 * temp_x + (1 - u2) * node->mob->x_to;
+		  node->mob->y_from =
+		    u2 * temp_y + (1 - u2) * node->mob->y_to;
+		  break;
+		}
+	    }
+	}
+
+
+      node->mob->speed = initial_speed (omg_param_list[node->type]);
+      node->event_num++;
+      distance =
+	(double) ((int)
+		  (sqrtf (pow (node->mob->x_from - node->mob->x_to, 2) +
+			  pow (node->mob->y_from - node->mob->y_to,
+			       2)) * 100)) / 100;
+
+    }
+//for the next move
+  else
+    {
+
+      if (grid == CONNECTED_DOMAIN)
+	{
+	  pr = randomgen (0, 1);
+
+	  if (pr <= 0.50)
+	    /* node->block_num =
+	       (int) randomgen (0, omg_param_list[node->type].max_block_num); */
+	    node->block_num =
+	      (int) next_block (node->block_num, omg_param_list[node->type]);
+
+	  block_xmin =
+	    area_minx (node->block_num, omg_param_list[node->type]);
+	  block_ymin =
+	    area_miny (node->block_num, omg_param_list[node->type]);
+
+	  node->mob->x_to =
+	    (double) ((int)
+		      (randomgen (block_xmin, xloc_div + block_xmin) * 100)) /
+	    100;
+
+	  node->mob->y_to =
+	    (double) ((int)
+		      (randomgen (block_ymin, yloc_div + block_ymin) * 100)) /
+	    100;
+
+	  distance =
+	    (double) ((int) (sqrtf
+			     (pow (node->mob->x_from - node->mob->x_to, 2) +
+			      pow (node->mob->y_from - node->mob->y_to,
+				   2)) * 100)) / 100;
+
+	  node->mob->azimuth =
+	    atan2 (node->mob->y_to - node->mob->y_from,
+		   node->mob->x_to - node->mob->x_from);
+	}
+      else
+	{
+	  node->mob->x_to =
+	    (double) ((int)
+		      (randomgen
+		       (omg_param_list[node->type].min_x,
+			omg_param_list[node->type].max_x) * 100)) / 100;
+
+	  node->mob->y_to =
+	    (double) ((int)
+		      (randomgen
+		       (omg_param_list[node->type].min_y,
+			omg_param_list[node->type].max_y) * 100)) / 100;
+
+	  distance =
+	    (double) ((int)
+		      (sqrtf (pow (node->mob->x_from - node->mob->x_to, 2) +
+			      pow (node->mob->y_from - node->mob->y_to,
+				   2)) * 100)) / 100;
+
+
+	}
+
+      node->mob->speed =
+	(double) ((int)
+		  (randomgen
+		   (omg_param_list[node->type].min_speed,
+		    omg_param_list[node->type].max_speed) * 100)) / 100;
+      node->event_num++;
+
+    }
+
+  journeytime_next = (double) ((int) (distance / node->mob->speed * 100)) / 100;	//duration to get to dest
+
+  //LOG_D (OMG, "[STEADY_RWP] mob->journey_time_next %.2f\n", journeyTime_next);
+
+  node->mob->start_journey = cur_time;
+  //LOG_D (OMG, "[STEADY_RWP] start_journey %.2f\n", node->mob->start_journey);
+  pair->next_event_t = cur_time + journeytime_next;	//when to reach the destination
+  // LOG_D (OMG,
+  // "[STEADY_RWP] reaching the destination at time : start journey + journey_time next =%.2f\n",
+  // pair->a);
+
+  if (node->event_num < 100)
+    {
+      event_sum[node->event_num] += node->mob->speed;
+      events[node->event_num]++;
+      node->event_num++;
+    }
+
+}
+
+double
+pause_probability (omg_global_param omg_param)
+{
+
+  double alpha, delta;
+  alpha =
+    (omg_param.max_sleep + omg_param.min_sleep) * (omg_param.max_speed -
+						   omg_param.min_speed) / (2 *
+									   log
+									   (omg_param.
+									    max_speed
+									    /
+									    omg_param.
+									    min_speed));
+
+  delta =
+    sqrtf (pow (omg_param.max_x - omg_param.min_x, 2) +
+	   pow (omg_param.max_y - omg_param.min_y, 2));
+
+  return alpha / (alpha + delta);
+
+}
+
+double
+initial_pause (omg_global_param omg_param)
+{
+  double u;
+  u = randomgen (0, 1);
+  if (u <
+      (2 * omg_param.min_sleep / (omg_param.max_sleep + omg_param.min_sleep)))
+    return u * (omg_param.max_sleep + omg_param.min_sleep) / 2;
+
+  else
+    return omg_param.max_sleep -
+      sqrtf ((1 - u) * (pow (omg_param.max_sleep, 2) -
+			pow (omg_param.min_sleep, 2)));
+}
+
+double
+initial_speed (omg_global_param omg_param)
+{
+  double u;
+  u = randomgen (0, 1);
+
+  return pow (omg_param.max_speed, u) / pow (omg_param.min_speed, u - 1);
+
+}
+
+/*update RWP nodes position*/
+
+void
+update_steadystaterwp_nodes (double cur_time)
+{
+
+  int done = 0;
+  job_list *tmp = job_vector[STEADY_RWP];
+  node_struct *my_node;
+  while (tmp != NULL && done == 0)
+    {
+      my_node = (node_struct *) tmp->pair->b;
+
+      //case1:time to next event equals to current time    
+      if (tmp->pair != NULL
+	  && ((double) tmp->pair->next_event_t >= cur_time - eps)
+	  && ((double) tmp->pair->next_event_t <= cur_time + eps))
+	{
+	  if (my_node->mobile == 1)
+	    sleep_rwp_node (tmp->pair, cur_time);
+	  else
+	    move_rwp_node (tmp->pair, cur_time);
+
+	}
+      //case2: current time is greater than the time to next event
+
+      else if (tmp->pair != NULL
+	       && (cur_time - eps) > tmp->pair->next_event_t)
+	{
+
+	  while (cur_time >= tmp->pair->next_event_t)
+	    {
+	      if (my_node->mobile == 1)
+		sleep_rwp_node (tmp->pair, cur_time);
+	      else
+		move_rwp_node (tmp->pair, cur_time);
+
+	    }
+	}
+      //case3: current time less than the time to next event
+      else
+	{
+	  done = 1;		//quit the loop
+	}
+
+
+      tmp = tmp->next;
+    }
+
+  //sorting the new entries
+  //LOG_D (OMG, "--------DISPLAY JOB LIST--------\n");   //LOG_T
+  // display_job_list (job_vector);
+  job_vector[STEADY_RWP] = quick_sort (job_vector[STEADY_RWP]);	///////////
+  // LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
+  // display_job_list (job_vector[STEADY_RWP]);
+}
+
+
+void
+get_steadystaterwp_positions_updated (double cur_time)
+{
+
+  double x_now = 0.0, y_now = 0.0;
+  double len, dx, dy;
+  job_list *tmp = job_vector[STEADY_RWP];
+
+  while (tmp != NULL)
+    {
+
+      if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
+	{
+
+
+	  len =
+	    sqrtf (pow
+		   (tmp->pair->b->mob->x_from -
+		    tmp->pair->b->mob->x_to,
+		    2) + pow (tmp->pair->b->mob->y_from -
+			      tmp->pair->b->mob->y_to, 2));
+	  if (len != 0)
+	    {
+	      dx =
+		fabs (tmp->pair->b->mob->x_from -
+		      tmp->pair->b->mob->x_to) / len;
+	      dy =
+		fabs (tmp->pair->b->mob->y_from -
+		      tmp->pair->b->mob->y_to) / len;
+	      //x coordinate
+	      if (tmp->pair->b->mob->x_from < tmp->pair->b->mob->x_to)
+		{
+		  x_now =
+		    tmp->pair->b->mob->x_from +
+		    (dx *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+	      else
+		{
+		  x_now =
+		    tmp->pair->b->mob->x_from -
+		    (dx *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+
+	      //y coordinate
+	      if (tmp->pair->b->mob->y_from < tmp->pair->b->mob->y_to)
+		{
+		  y_now =
+		    tmp->pair->b->mob->y_from +
+		    (dy *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+	      else
+		{
+		  y_now =
+		    tmp->pair->b->mob->y_from -
+		    (dy *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+
+	      tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
+	      tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
+	      //len
+
+	    }
+
+
+	}
+      else
+	{
+	  tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
+	  tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
+	}
+
+
+      tmp = tmp->next;
+
+    }
+
+}
diff --git a/openair2/UTIL/OMG/steadystaterwp.h b/openair2/UTIL/OMG/steadystaterwp.h
new file mode 100644
index 0000000000000000000000000000000000000000..86269b252e83c4329ee55bd1c61d7037e8ab139c
--- /dev/null
+++ b/openair2/UTIL/OMG/steadystaterwp.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2011 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.fr
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fsr/openairinterface
+  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
+
+*******************************************************************************/
+
+/*! \file steadystaterwp.h
+* \brief random waypoint mobility generator 
+* \date 2014
+* \version 0.1
+* \company Eurecom
+* \email: 
+* \note
+* \warning
+*/
+#ifndef STEADYSTATERWP_H_
+#define STEADYSTATERWP_H_
+
+
+int start_steadystaterwp_generator (omg_global_param omg_param_list);
+
+void place_steadystaterwp_node (node_struct* node);
+
+void sleep_steadystaterwp_node (pair_struct* pair, double cur_time);
+
+void move_steadystaterwp_node (pair_struct* pair, double cur_time);
+
+double pause_probability(omg_global_param omg_param);
+
+
+double initial_pause(omg_global_param omg_param);
+
+double initial_speed(omg_global_param omg_param);
+
+void update_steadystaterwp_nodes (double cur_time);
+
+void get_steadystaterwp_positions_updated (double cur_time);
+
+#endif 
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openair2/UTIL/OMG/storage_traci_OMG.c b/openair2/UTIL/OMG/storage_traci_OMG.c
index d143ab841056e49be1fe6a75cde4c02d913e6013..5395d2f0111f09d1037d5b19880fca0100c1d36c 100644
--- a/openair2/UTIL/OMG/storage_traci_OMG.c
+++ b/openair2/UTIL/OMG/storage_traci_OMG.c
@@ -204,12 +204,12 @@ void writeString(char *s){
 
 }
 
-String_list readStringList(String_list vector){
+string_list* readStringList(string_list* vector){
 
    int i=0;
    int len = readInt();
    descLen = len;
-   String_list entry = NULL;
+   string_list* entry = NULL;
    
    for (; i < len; i++) {
       if (vector->string == NULL) {
@@ -218,14 +218,14 @@ String_list readStringList(String_list vector){
          vector->string = tmp;//readString();
       }
       else {
-        entry = (String_list)malloc(sizeof(String_list));
+        entry = (string_list*) malloc(sizeof(string_list));
         char *tmp = readString();
         //printf("OMG - SUMO ID: %s \n",tmp);
         entry->string = tmp;//readString();
         entry->next = NULL;
 
         if(vector !=NULL) {
-          String_list tmp = vector;
+          string_list* tmp = vector;
           while (tmp->next != NULL){
        	    tmp = tmp->next;
           }
@@ -238,11 +238,11 @@ String_list readStringList(String_list vector){
 }
 
 
-void writeStringList(String_list vector){
+void writeStringList(string_list* vector){
 	
 
         int count=0;
-        String_list tmp = vector;
+        string_list* tmp = vector;
         // JHNote: a better solution would be to save the pointer to the reference of this Int and replace the value with count at the end....
 	if (tmp->string !=NULL) 
 	   count++;
@@ -463,9 +463,9 @@ void freeStorage(storage * freePtr){
         freePtr = NULL;             // finally, mark as empty list.
 }
 
-void reset_String_list(String_list vector) {
-  String_list entry = vector;
-  String_list tmp;
+void reset_String_list(string_list* vector) {
+  string_list* entry = vector;
+  string_list* tmp;
 
   while (entry->next != NULL) {
      tmp = entry;     
diff --git a/openair2/UTIL/OMG/storage_traci_OMG.h b/openair2/UTIL/OMG/storage_traci_OMG.h
index 4cbdddb01fe9a76fe6cb5c6301dfe652eaa42e17..c83e6df1d1b6e66f50f8df2d2dd8195d37090590 100644
--- a/openair2/UTIL/OMG/storage_traci_OMG.h
+++ b/openair2/UTIL/OMG/storage_traci_OMG.h
@@ -58,7 +58,7 @@ union n{
      } un ;
 
 
-void check_endianness();
+void check_endianness(void);
 
 //----------------STORAGE------------------------------------
 struct Storage {
@@ -78,36 +78,36 @@ int descLen;
 
 extern int msgLength;
 
-	void reset();
+	void reset(void);
         int storageLength(storage *);
         
-        void rearange();
-        unsigned char readChar(); 
+        void rearange(void);
+        unsigned char readChar(void); 
 	void writeChar(unsigned char); 
 
-	int readByte() ;
+	int readByte(void) ;
 	void writeByte(int) ;
 
 
-	int readUnsignedByte(); 
+	int readUnsignedByte(void); 
 	void writeUnsignedByte(int); 
 
-	char * readString() ;
+	char * readString(void) ;
 	void writeString(char *);
 
-        String_list readStringList(String_list) ;
-	void writeStringList(String_list); 
+        string_list* readStringList(string_list*) ;
+	void writeStringList(string_list*); 
 
-	int readShort() ;
+	int readShort(void) ;
 	void writeShort(int); 
 
-	int readInt() ;
+	int readInt(void) ;
 	void writeInt(int); 
 
-	float readFloat() ;
+	float readFloat(void) ;
 	void writeFloat( float ); 
 
-        double readDouble() ;
+        double readDouble(void) ;
         void writeDouble( double ); 
 
 	storage* writePacket(unsigned char*, int);
diff --git a/openair2/UTIL/OMG/sumo.c b/openair2/UTIL/OMG/sumo.c
index 91e9c5bdfcac790163acbc5669c2fde8a2341b7d..c85624f83e92b4b3708d4a22ef019f685af43d1b 100644
--- a/openair2/UTIL/OMG/sumo.c
+++ b/openair2/UTIL/OMG/sumo.c
@@ -52,361 +52,443 @@
 #include "client_traci_OMG.h"
 
 
-int start_sumo_generator(omg_global_param omg_param_list) {
+int
+start_sumo_generator (omg_global_param omg_param_list)
+{
 
   char sumo_line[300];
+  int n_id;
+  static int id = 0;
 
 // sprintf(sumo_line, "%s -c %s  -b %d -e %d --remote-port %d --step-length %d -v ",omg_param_list.sumo_command, omg_param_list.sumo_config, omg_param_list.sumo_start, omg_param_list.sumo_end, omg_param_list.sumo_port, omg_param_list.sumo_step);
 
-sprintf(sumo_line, "%s -c %s ",omg_param_list.sumo_command, omg_param_list.sumo_config);
+  sprintf (sumo_line, "%s -c %s ", omg_param_list.sumo_command,
+	   omg_param_list.sumo_config);
+
+  printf ("%s\n", sumo_line);
+
+  if ((pid = fork ()) == 0)
+    {
+      // Start SUMO in the child process
+      system (sumo_line);
+      //childs addresss space
+    }
 
-  printf("%s\n",sumo_line);
-  if ( (pid = fork()) == 0)
-  {
-    // Start SUMO in the child process
-    system(sumo_line);
-   //childs addresss space
-  }
- 
   //still in the parent process
- 
+
   // Talk to SUMO 
 
   targetTime = 1;
-  
-  departed  = NULL;
+
+  departed = NULL;
   arrived = NULL;
 
 // switch on error to return to OAI
-  handshake(omg_param_list.sumo_host,omg_param_list.sumo_port);
-  
-  init(omg_param_list.sumo_end - omg_param_list.sumo_start);
-  
-  int max_node_SUMO = 100; //commandGetMaxSUMONodesVariable(); TODO method not implemented in TraCI server..must find another solution 
+  handshake (omg_param_list.sumo_host, omg_param_list.sumo_port);
+
+  init (omg_param_list.sumo_end - omg_param_list.sumo_start);
 
- // printf("received Number of nodes %d\n", max_node_SUMO);
+  int max_node_SUMO = 100;	//commandGetMaxSUMONodesVariable(); TODO method not implemented in TraCI server..must find another solution 
+
+  // printf("received Number of nodes %d\n", max_node_SUMO);
 
   // create the OAI/SUMO ID manager
-  id_manager = create_IDManager();
+  id_manager = create_IDManager ();
+
+  node_struct *node = NULL;
+  mobility_struct *mobility = NULL;
 
-  NodePtr node = NULL;
-  MobilityPtr mobility = NULL;
-  
-  active_nodes = NULL;  // container to return a subset of only ACTIVE OAI nodes in SUMO
+  active_nodes = NULL;		// container to return a subset of only ACTIVE OAI nodes in SUMO
 
   last_update_time = 0.0;
 
   // just check for faulty values
-  if (omg_param_list.nodes <= 0){
-    #ifdef STANDALONE 
-      printf("Number of nodes has not been set\n");
-    #else
-      LOG_W(OMG, "Number of nodes has not been set\n");
-    #endif
-    return(-1);
-  }
-  #ifdef STANDALONE 
-  printf("Number of OAI-equipped nodes in SUMO has been set to %d\n", omg_param_list.nodes);
-  printf("Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO);
-  #else 
-    LOG_I(OMG, "Number of OAI-equipped nodes in SUMO has been set to %d\n", omg_param_list.nodes);
-    LOG_I(OMG, "Number of SUMO simulated nodes has been set to %d\n", max_node_SUMO);
-  #endif
+  if (omg_param_list.nodes <= 0)
+    {
+#ifdef STANDALONE
+      printf ("Number of nodes has not been set\n");
+#else
+      LOG_W (OMG, "Number of nodes has not been set\n");
+#endif
+      return (-1);
+    }
+#ifdef STANDALONE
+  printf ("Number of OAI-equipped nodes in SUMO has been set to %d\n",
+	  omg_param_list.nodes);
+  printf ("Number of SUMO simulated nodes has been set to %d\n",
+	  max_node_SUMO);
+#else
+  LOG_I (OMG, "Number of OAI-equipped nodes in SUMO has been set to %d\n",
+	 omg_param_list.nodes);
+  LOG_I (OMG, "Number of SUMO simulated nodes has been set to %d\n",
+	 max_node_SUMO);
+#endif
   // check and match number of nodes in mobility file provided
-  if (omg_param_list.nodes > max_node_SUMO){
-    #ifdef STANDALONE 
-      printf("Not all OAI nodes will be moving according to SUMO.\n");
-    #else
-      LOG_I(OMG, "Not all OAI nodes will be moving according to SUMO.\n");
-    #endif
-  }
-  else {
-    #ifdef STANDALONE 
-      printf("OAI nodes will be mapped to a subset of SUMO nodes\n");
-    #else
-      LOG_I(OMG, "OAI nodes will be mapped to a subset of SUMO nodes\n");
-    #endif
-  }
-
-  if (omg_param_list.nodes_type == eNB) {
-    #ifdef STANDALONE 
-     printf("Node type has been set to eNB\n");
-    #else 
-     LOG_I(OMG, "Node type has been set to eNB\n");
-    #endif
-  } 
-  else if (omg_param_list.nodes_type == UE) {
-    
-     #ifdef STANDALONE 
-       printf("Node type has been set to UE\n");
-     #else 
-       LOG_I(OMG, "Node type has been set to UE\n");
-     #endif
-  }
-  
-  int n_id = 0;
-  for ( n_id = 0; n_id< omg_param_list.nodes; n_id++) {
-    
-    node = (NodePtr) create_node();
-    mobility = (MobilityPtr) create_mobility();
-    node->mobile = 0; // 0 means inactive in SUMO; 1 means active in SUMO; as long as a mapping between OAI-SUMO has not been created, nodes are inactive and do not move
-    node->ID = n_id; // this is OAI ID, not SUMO
-    node->type = omg_param_list.nodes_type; // UE eNB...
-    node->generator = omg_param_list.mobility_type; // SUMO
-    node->mob = mobility;
-
-    Node_Vector[SUMO] = (Node_list) add_entry(node, Node_Vector[SUMO]);     
-  }
-  
-  update_IDs();  // update the mapping between departed and arrived nodes in SUMO.
-
-  return(0);
+  if (omg_param_list.nodes > max_node_SUMO)
+    {
+#ifdef STANDALONE
+      printf ("Not all OAI nodes will be moving according to SUMO.\n");
+#else
+      LOG_I (OMG, "Not all OAI nodes will be moving according to SUMO.\n");
+#endif
+    }
+  else
+    {
+#ifdef STANDALONE
+      printf ("OAI nodes will be mapped to a subset of SUMO nodes\n");
+#else
+      LOG_I (OMG, "OAI nodes will be mapped to a subset of SUMO nodes\n");
+#endif
+    }
+
+  if (omg_param_list.nodes_type == eNB)
+    {
+#ifdef STANDALONE
+      printf ("Node type has been set to eNB\n");
+#else
+      LOG_I (OMG, "Node type has been set to eNB\n");
+#endif
+    }
+  else if (omg_param_list.nodes_type == UE)
+    {
+
+#ifdef STANDALONE
+      printf ("Node type has been set to UE\n");
+#else
+      LOG_I (OMG, "Node type has been set to UE\n");
+#endif
+    }
+
+  for (n_id = id; n_id < omg_param_list.nodes + id; n_id++)
+    {
+
+      node = create_node ();
+      mobility = create_mobility ();
+      node->mobile = 0;		// 0 means inactive in SUMO; 1 means active in SUMO; as long as a mapping between OAI-SUMO has not been created, nodes are inactive and do not move
+      node->id = n_id;		// this is OAI ID, not SUMO
+      node->type = omg_param_list.nodes_type;	// UE eNB...
+      node->generator = SUMO;	// SUMO
+      node->mob = mobility;
+
+      node_vector_end[SUMO] =
+	(node_list *) add_entry (node, node_vector_end[SUMO]);
+
+      if (node_vector[SUMO] == NULL)
+	node_vector[SUMO] = node_vector_end[SUMO];
+    }
+
+  id += omg_param_list.nodes;
+
+  update_IDs ();		// update the mapping between departed and arrived nodes in SUMO.
+
+  return (0);
 }
 
-void update_IDs() {
-  #ifdef STANDALONE 
-  printf("Updating the ID mapping between SUMO and OAI\n");
-  #else
-    LOG_D(OMG, "Updating the ID mapping between SUMO and OAI\n"); 
-  #endif 
-  String_list tmp_arrived, tmp_departed;
-  
-  if(arrived == NULL) {
-     printf("arrived vehicles is NULL \n"); 
-     return;
-  }
+void
+update_IDs (void)
+{
+#ifdef STANDALONE
+  printf ("Updating the ID mapping between SUMO and OAI\n");
+#else
+  LOG_D (OMG, "Updating the ID mapping between SUMO and OAI\n");
+#endif
+  string_list *tmp_arrived, *tmp_departed;
+
+  if (arrived == NULL)
+    {
+      printf ("arrived vehicles is NULL \n");
+      return;
+    }
 
   tmp_arrived = arrived;
   tmp_departed = departed;
 
-  if(departed == NULL) {
-     printf("departed vehicles is NULL \n"); 
-     return;
-  }
-
-  if(tmp_departed->string !=NULL) {
-    char * tmp_string = malloc(sizeof(strlen(tmp_departed->string)));     
-    strcpy(tmp_string, tmp_departed->string);
-    //printf("OMG - 2 head is not null and value is: %s\n",tmp_string);
-    int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager);
-    if (OAI_ID ==-1) {
-      if (!activate_and_map(tmp_string)) {
-	 // printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
-         // LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
-        return;  // stopping mapping as the maximum of OAI nodes has been reached;
-      }
-      
+  if (departed == NULL)
+    {
+      printf ("departed vehicles is NULL \n");
+      return;
+    }
+
+  if (tmp_departed->string != NULL)
+    {
+      char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
+      strcpy (tmp_string, tmp_departed->string);
+      //printf("OMG - 2 head is not null and value is: %s\n",tmp_string);
+      int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
+      if (OAI_ID == -1)
+	{
+	  if (!activate_and_map (tmp_string))
+	    {
+	      // printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
+	      // LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
+	      return;		// stopping mapping as the maximum of OAI nodes has been reached;
+	    }
+
+	}
     }
-  }
-  while (tmp_departed->next != NULL) {
-   // printf("OMG - 2 main is not null \n");
-    //char tmp_string [strlen(tmp_departed->string)];
-    char * tmp_string = malloc(sizeof(strlen(tmp_departed->string)));
-    strcpy(tmp_string, tmp_departed->string);
-    //char *tmp_string = tmp_departed->string;
-    int OAI_ID = get_oaiID_by_SUMO(tmp_string, id_manager);
-    if (OAI_ID ==-1) {
-      if (!activate_and_map(tmp_string)) {
-        //printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
-        //LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
-        return;  // stopping mapping as the maximum of OAI nodes has been reached;
-      }  
+  while (tmp_departed->next != NULL)
+    {
+      // printf("OMG - 2 main is not null \n");
+      //char tmp_string [strlen(tmp_departed->string)];
+      char *tmp_string = malloc (sizeof (strlen (tmp_departed->string)));
+      strcpy (tmp_string, tmp_departed->string);
+      //char *tmp_string = tmp_departed->string;
+      int OAI_ID = get_oaiID_by_SUMO (tmp_string, id_manager);
+      if (OAI_ID == -1)
+	{
+	  if (!activate_and_map (tmp_string))
+	    {
+	      //printf("Reached the Maximum of OAI nodes to be mapped to SUMO\n");
+	      //LOG_I(OMG, "Reached the Maximum of OAI nodes to be mapped to SUMO\n");
+	      return;		// stopping mapping as the maximum of OAI nodes has been reached;
+	    }
+	}
+      tmp_departed = tmp_departed->next;
     }
-    tmp_departed = tmp_departed->next;
-  }
-
-  departed = clear_String_list(departed);
-
-  if(tmp_arrived->string !=NULL) {
-    char *tmp_string = tmp_arrived->string;
-    //printf("OMG - 3 head is not null and value is: %s\n",tmp_arrived->string); 
-    
-    if(!desactivate_and_unmap(tmp_string)) {
-      printf("Could not locate the OAI node ID %s \n", tmp_string);
-      //LOG_I(OMG, "Could not locate the OAI node ID %s \n", tmp_string);
+
+  departed = clear_string_list (departed);
+
+  if (tmp_arrived->string != NULL)
+    {
+      char *tmp_string = tmp_arrived->string;
+      //printf("OMG - 3 head is not null and value is: %s\n",tmp_arrived->string); 
+
+      if (!desactivate_and_unmap (tmp_string))
+	{
+	  printf ("Could not locate the OAI node ID %s \n", tmp_string);
+	  //LOG_I(OMG, "Could not locate the OAI node ID %s \n", tmp_string);
+	}
+
     }
-    
-  }
-  while (tmp_arrived->next != NULL) {
-    char *tmp_string = tmp_arrived->string;
-    if(!desactivate_and_unmap(tmp_string)) {
-       printf("Could not locate the OAI node\n");
-      // LOG_I(OMG, "Could not locate the OAI node\n");
+  while (tmp_arrived->next != NULL)
+    {
+      char *tmp_string = tmp_arrived->string;
+      if (!desactivate_and_unmap (tmp_string))
+	{
+	  printf ("Could not locate the OAI node\n");
+	  // LOG_I(OMG, "Could not locate the OAI node\n");
+	}
+      tmp_arrived = tmp_arrived->next;
     }
-    tmp_arrived = tmp_arrived->next;  
-  }
-  arrived = clear_String_list(arrived);
+  arrived = clear_string_list (arrived);
 
 }
 
-bool desactivate_and_unmap(char *sumo_id) {
-  #ifdef STANDALONE 
-    printf("desactivating node %s \n",sumo_id);
-  #else
-    LOG_I(OMG, "desactivating node %s \n",sumo_id);
-  #endif	
-  int OAI_ID = get_oaiID_by_SUMO(sumo_id, id_manager);
-  remove_oaiID_by_SUMO(sumo_id, id_manager);
-  if (OAI_ID !=-1) {
+bool
+desactivate_and_unmap (char *sumo_id)
+{
+#ifdef STANDALONE
+  printf ("desactivating node %s \n", sumo_id);
+#else
+  LOG_I (OMG, "desactivating node %s \n", sumo_id);
+#endif
+  int OAI_ID = get_oaiID_by_SUMO (sumo_id, id_manager);
+  remove_oaiID_by_SUMO (sumo_id, id_manager);
+  if (OAI_ID != -1)
+    {
       //TODO generalize to UE and eNB (must change the method)
-      NodePtr node = find_node(Node_Vector[SUMO], OAI_ID, UE);
-      if (node == NULL) 
-         node = find_node(Node_Vector[SUMO], OAI_ID, eNB);
-
-      if(node !=NULL) {
-        node->mobile = 0; // this node is now inactive;
-        active_nodes = remove_node_entry(node, active_nodes);
-        return true;
-      }
-      
-  }
-
-   #ifdef STANDALONE  
-    printf("Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n", sumo_id);
-   #else
-     LOG_I(OMG, "Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n", sumo_id); 
-   #endif
-
-   return false;
+      node_struct *node = find_node (node_vector[SUMO], OAI_ID, UE);
+      if (node == NULL)
+	node = find_node (node_vector[SUMO], OAI_ID, eNB);
+
+      if (node != NULL)
+	{
+	  node->mobile = 0;	// this node is now inactive;
+	  active_nodes = remove_node_entry (node, active_nodes);
+	  return true;
+	}
+
+    }
+
+#ifdef STANDALONE
+  printf
+    ("Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n",
+     sumo_id);
+#else
+  LOG_I (OMG,
+	 "Could not desactive an OAI node, as the SUMO-OAI mapping could not be found for the SUMO node ID %s \n",
+	 sumo_id);
+#endif
+
+  return false;
 }
 
 
-bool activate_and_map(char *sumo_id) {
-  MapPtr map = create_map();
-  #ifdef STANDALONE 
-    printf("activating node %s \n",sumo_id);
-  #else
-    LOG_I(OMG, "activating node %s \n",sumo_id);
-  #endif	 
-  // TODO: So far, only UE can be SUMO mobile, but could change	
-  NodePtr active_node = get_first_inactive_OAI_node(Node_Vector[SUMO], UE);
-  if(active_node != NULL) {  // found an inactive OAI node; will be mapped to SUMO
-    active_node->mobile = 1; // now node is active in SUMO
-
-    active_nodes = add_entry(active_node, active_nodes);
-   
-    map->oai_id = active_node->ID;
-    map->sumo_id = malloc(sizeof((int)strlen(sumo_id)));
-    strcpy(map->sumo_id, sumo_id);
-     
-     #ifdef STANDALONE  
-      printf("added a mapping between oai ID:  %d and SUMO ID: %s \n",map->oai_id, map->sumo_id); 
-     #else
-       LOG_I(OMG, "added a mapping between oai ID:  %d and SUMO ID: %s \n",map->oai_id, map->sumo_id); 
-     #endif
-    
-   // TODO fusion the two lists...leads to data inconsistency
-    id_manager->map_sumo2oai = add_map_entry(map, id_manager->map_sumo2oai);
-  
-    id_manager->map_oai2sumo = add_map_entry(map, id_manager->map_oai2sumo); //map_sumo2oai
+bool
+activate_and_map (char *sumo_id)
+{
+  MapPtr map = create_map ();
+#ifdef STANDALONE
+  printf ("activating node %s \n", sumo_id);
+#else
+  LOG_I (OMG, "activating node %s \n", sumo_id);
+#endif
+  // TODO: So far, only UE can be SUMO mobile, but could change 
+  node_struct *active_node =
+    get_first_inactive_OAI_node (node_vector[SUMO], UE);
+  if (active_node != NULL)
+    {				// found an inactive OAI node; will be mapped to SUMO
+      active_node->mobile = 1;	// now node is active in SUMO
+
+      active_nodes = add_entry (active_node, active_nodes);
+
+      map->oai_id = active_node->id;
+      map->sumo_id = malloc (sizeof ((int) strlen (sumo_id)));
+      strcpy (map->sumo_id, sumo_id);
+
+#ifdef STANDALONE
+      printf ("added a mapping between oai ID:  %d and SUMO ID: %s \n",
+	      map->oai_id, map->sumo_id);
+#else
+      LOG_I (OMG, "added a mapping between oai ID:  %d and SUMO ID: %s \n",
+	     map->oai_id, map->sumo_id);
+#endif
+
+      // TODO fusion the two lists...leads to data inconsistency
+      id_manager->map_sumo2oai =
+	add_map_entry (map, id_manager->map_sumo2oai);
+
+      id_manager->map_oai2sumo = add_map_entry (map, id_manager->map_oai2sumo);	//map_sumo2oai
+
+      return true;
 
-  return true;
+    }
 
-  }
+  else
+    {
+#ifdef STANDALONE
+      printf
+	("All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n");
+#else
+      LOG_I (OMG,
+	     "All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n");
+#endif
+      return false;
+    }
+}
 
-  else {
-     #ifdef STANDALONE  
-      printf("All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n");
-     #else
-      LOG_I(OMG, "All OAI Nodes are already active in SUMO; cannot control this SUMO node in OAI\n"); 
-     #endif
-    return false;
-  }
-}  
 
+void
+update_sumo_nodes (double cur_time)
+{
+  if ((cur_time - last_update_time) < MIN_SUMO_STEP)
+    {				// the min time interval for SUMO must be 100ms or more
+      printf ("--------Update Step too small--------\n");
+      return;
+    }
 
-void update_sumo_nodes(double cur_time) {
-   if((cur_time - last_update_time) < MIN_SUMO_STEP)  { // the min time interval for SUMO must be 100ms or more
-     printf("--------Update Step too small--------\n"); 
-     return;
-   }
-	
-   last_update_time = cur_time;  // keeps track of the last update time to get the update interval
+  last_update_time = cur_time;	// keeps track of the last update time to get the update interval
 
   // commandSimulationStep(1.0);// Advance the SUMO simulation by cur_time units
-  
-  
-   commandSimulationStep(cur_time);// Advance the SUMO simulation by cur_time units
-   
-   LOG_I(OMG, "--------Updated SUMO positions by %f [ms]--------\n",cur_time);
-   update_IDs();  // both are in the  traCI client
+
+
+  commandSimulationStep (cur_time);	// Advance the SUMO simulation by cur_time units
+
+  LOG_I (OMG, "--------Updated SUMO positions by %f [ms]--------\n",
+	 cur_time);
+  update_IDs ();		// both are in the  traCI client
 
 
 }
 
-void update_sumo_positions(NodePtr node){
-
-  
- 
-   #ifdef STANDALONE  
-    printf("--------GET SUMO Mobility for a single node--------\n");
-   #else
-    LOG_D(OMG, "--------GET SUMO Mobility for a single node--------\n");
-   #endif
-  
-  Map_list tmp =  id_manager->map_oai2sumo;
-  char *sumo_id = get_sumo_entry(node->ID, tmp);
-  
-  if(sumo_id !=NULL) {  
-     //printf(" OAI ID is: %d and SUMO ID is %s \n",node->ID, sumo_id);    
-    GetPosition(node, sumo_id);
-    GetSpeed(node, sumo_id);
-  }
+void
+update_sumo_positions (node_struct * node)
+{
+
+
+
+#ifdef STANDALONE
+  printf ("--------GET SUMO Mobility for a single node--------\n");
+#else
+  LOG_D (OMG, "--------GET SUMO Mobility for a single node--------\n");
+#endif
+
+  Map_list tmp = id_manager->map_oai2sumo;
+  char *sumo_id = get_sumo_entry (node->id, tmp);
+
+  if (sumo_id != NULL)
+    {
+      //printf(" OAI ID is: %d and SUMO ID is %s \n",node->ID, sumo_id);    
+      GetPosition (node, sumo_id);
+      GetSpeed (node, sumo_id);
+    }
 }
 
-Node_list get_sumo_positions_updated(double cur_time) {
-  
- 
-   #ifdef STANDALONE  
-     printf("--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
-   #else
-     LOG_I(OMG, "--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
-   #endif
- 
-  if (Node_Vector[SUMO] != NULL){
-    Node_list tmp = Node_Vector[SUMO];
-    while (tmp != NULL){
-      if ((tmp->node->generator == SUMO) && (tmp->node->mobile == 1)) {  // OAI node MUST be active
-        LOG_I(OMG, "found an active node with id %d \n", tmp->node->ID);
-	LOG_I(OMG, "Old Positions \n");		
-	//printf("Old Positions \n");
-        display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos );
-
-        update_sumo_positions(tmp->node);
-	
-        //printf("New Positions \n");
-        LOG_I(OMG, "New Positions \n");		
-	display_node_position(tmp->node->ID, tmp->node->generator, tmp->node->type ,tmp->node->mobile, tmp->node->X_pos, tmp->node->Y_pos );
-      }
-      tmp = tmp->next;
+node_list *
+get_sumo_positions_updated (double cur_time)
+{
+
+
+#ifdef STANDALONE
+  printf
+    ("--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
+#else
+  LOG_I (OMG,
+	 "--------GET SUMO Mobility for a group of ACTIVE OAI nodes--------\n");
+#endif
+
+  if (node_vector[SUMO] != NULL)
+    {
+      node_list *tmp = node_vector[SUMO];
+      while (tmp != NULL)
+	{
+	  if ((tmp->node->generator == SUMO) && (tmp->node->mobile == 1))
+	    {			// OAI node MUST be active
+	      LOG_I (OMG, "found an active node with id %d \n",
+		     tmp->node->id);
+	      LOG_I (OMG, "Old Positions \n");
+	      //printf("Old Positions \n");
+	      display_node_position (tmp->node->id, tmp->node->generator,
+				     tmp->node->type, tmp->node->mobile,
+				     tmp->node->x_pos, tmp->node->y_pos);
+
+	      update_sumo_positions (tmp->node);
+
+	      //printf("New Positions \n");
+	      LOG_I (OMG, "New Positions \n");
+	      display_node_position (tmp->node->id, tmp->node->generator,
+				     tmp->node->type, tmp->node->mobile,
+				     tmp->node->x_pos, tmp->node->y_pos);
+	    }
+	  tmp = tmp->next;
+	}
     }
-  }
   return active_nodes;
 }
 
-NodePtr get_first_inactive_OAI_node(Node_list list, int node_type) {
-  Node_list  current;
-
-  if (list !=NULL) {                             //start search
-    current = list;
-    while (current->next != NULL) {
-      if((current->node->mobile == 0) && (current->node->type == node_type)) {
-        return current->node;
-      }
-      current = current->next;
+node_struct *
+get_first_inactive_OAI_node (node_list * list, int node_type)
+{
+  node_list *current;
+
+  if (list != NULL)
+    {				//start search
+      current = list;
+      while (current->next != NULL)
+	{
+	  if ((current->node->mobile == 0)
+	      && (current->node->type == node_type))
+	    {
+	      return current->node;
+	    }
+	  current = current->next;
+	}
     }
-  }
-  return NULL;  // all nodes are active already..reached the maximum number of OAI nodes 
+  return NULL;			// all nodes are active already..reached the maximum number of OAI nodes 
 }
 
-bool stop_sumo_generator() {
-  #ifdef STANDALONE  
-    printf(" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
-  #else
-     LOG_I(OMG, " --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
-  #endif
-  commandClose(); // closing the connection with SUMO via TraCI
-  close_connection(); // closing the socket connection
-  kill(pid,SIGKILL); // killing SUMO in case it could not close by itself
+bool
+stop_sumo_generator (void)
+{
+#ifdef STANDALONE
+  printf
+    (" --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
+#else
+  LOG_I (OMG,
+	 " --------Destructor for SUMO: closing the TraCI socket and killing SUMO ---- \n");
+#endif
+  commandClose ();		// closing the connection with SUMO via TraCI
+  close_connection ();		// closing the socket connection
+  kill (pid, SIGKILL);		// killing SUMO in case it could not close by itself
   return true;
 }
diff --git a/openair2/UTIL/OMG/sumo.h b/openair2/UTIL/OMG/sumo.h
index 55f770c50f80a88eccb1bff414d0e05ba643a0b7..240a6a2b1d8e90f955b3b24e7fd155df15ba85a8 100644
--- a/openair2/UTIL/OMG/sumo.h
+++ b/openair2/UTIL/OMG/sumo.h
@@ -50,11 +50,11 @@
 /*! A global variable used to store the SUMO process ID to later kill it smoothly when OAI askes OMG to stop SUMO*/
 pid_t pid;
 
-/*! A sumo global variable representing the OMG-SUMO ID manager. It is created at the start_sumo_generator() and keep a mapping between SUMO and OAI IDs.  */
+/*! A sumo global variable representing the OMG-SUMO ID manager. It is created at the start_sumo_generator(void) and keep a mapping between SUMO and OAI IDs.  */
 IDManagerPtr id_manager;
 
 /*! A Node_list intended to contain the list of OAI 'active' nodes in SUMO. replaces the return of the full Node_Vector when OAI requests the new positions of its nodes. The list is reset at each use, but the pointer to the respective nodes is just set to NULL*/
-Node_list active_nodes;
+node_list* active_nodes;
 
 /*! A global variable keeping track of the last update time of SUMO, to be used to get the update interval when update_sumo_nodes(cur_time) is called */
 double last_update_time; 
@@ -79,7 +79,7 @@ void update_sumo_nodes(double cur_time) ;
  * \brief Get the current position and speed of a node from SUMO. Invokes TraCI
  * \param node the pointer to a node we want to synch with SUMO.
  */
-void update_sumo_positions(NodePtr node);
+void update_sumo_positions(node_struct* node);
 
 /**
  * \fn Node_list get_sumo_positions_updated(double cur_time);
@@ -87,7 +87,7 @@ void update_sumo_positions(NodePtr node);
  * \param cur_time a variable of type double that represents the current time
  * \return the list of ACTIVE OAI nodes, which positions have been updated by SUMO
  */
-Node_list get_sumo_positions_updated(double cur_time);
+node_list* get_sumo_positions_updated(double cur_time);
 
 /**
  * \fn NodePtr get_first_inactive_OAI_node(Node_list list, int node_type)
@@ -96,13 +96,13 @@ Node_list get_sumo_positions_updated(double cur_time);
  * \param node_type the type of node we would like to locate (here: SUMO)
  * \return the reference to the first inactive OAI node; returns NULL is none could be found (all OAI nodes are currently active)
  */
-NodePtr get_first_inactive_OAI_node(Node_list list, int node_type);
+node_struct* get_first_inactive_OAI_node(node_list* list, int node_type);
 
 /**
  * \fn void update_IDs(String_list *departed, String_list *arrived)
  * \brief Updates the mapping between SUMO and OAI nodes; Once a node departs in SUMO, it is mapped to a inactive OAI node. If none are found, the SUMO node will not have any mapping. Once a node arrives, the mapping is removed and the OAI node becomes inactive again. When an OAI node is inactive, it mobility parameters are invalid and MUST NOT be used/requested by OAI.
  */
-void update_IDs();
+void update_IDs(void);
 
 /**
  * \fn bool desactive_and_unmap(char *sumo_id)
@@ -122,10 +122,10 @@ bool desactivate_and_unmap(char *sumo_id);
 bool activate_and_map(char *sumo_id);
 
 /**
- * \fn int stop_sumo_generator()
+ * \fn int stop_sumo_generator(void)
  * \brief stops SUMO, stop the socket and kills SUMO process in the child domain.
  * \return true in case of success; false otherwise
  */
-bool stop_sumo_generator();
+bool stop_sumo_generator(void);
 
 #endif /* SUMO_H_ */
diff --git a/openair2/UTIL/OMG/trace.c b/openair2/UTIL/OMG/trace.c
index fe9a8732740908637405263fbfb8c7d8be17f87a..2631442a7c0f84a1810aeff6413ee6c55c2e8e8a 100644
--- a/openair2/UTIL/OMG/trace.c
+++ b/openair2/UTIL/OMG/trace.c
@@ -29,11 +29,11 @@
 
 /*! \file trace.c
 * \brief The trace-based mobility model for OMG/OAI (mobility is statically imported from a file)
-* \author  S. Uppoor and Navid Nikaein
-* \date 2011
+* \author  S. Gashaw, N. Nikaein, J. Harri
+* \date 2014
 * \version 0.1
-* \company INRIA
-* \email: sandesh.uppoor@inria.fr
+* \company EURECOM
+* \email: 
 * \note
 * \warning
 */
@@ -41,443 +41,515 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
-#include <math.h> 
+#include <math.h>
 #include "trace.h"
-#include "omg.h"
-
-extern node_info* head_node_info;
-extern hash_table_t* table;
-
-int start_trace_generator(omg_global_param omg_param_list) {
-
-  // MobilityPtr mobility = NULL;
-  
-  //read the mobility file here
-  read_mobility_file(omg_param_list.mobility_file); // JHNOTE: in order to debug, please give and change name here...
-  LOG_I(OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table );
-  
-  sort_veh_movement(table);
-  
-  if (omg_param_list.nodes <= 0){
-    LOG_W(OMG, "Number of nodes has not been set\n");
-    return(-1);
-  }
-  
-  // check and match number of nodes in mobility file provided
-  if (omg_param_list.nodes != get_num_nodes()){
-    LOG_W(OMG, "Make sure all nodes have mobility description in mobility file (%d,%d)\n", 
-	  omg_param_list.nodes, get_num_nodes());
-      //return(-1);
-  }
-
-  if (omg_param_list.nodes_type == eNB) {
-    LOG_I(OMG, "Start trace driven mobility gen for %d eNBs\n",omg_param_list.nodes);
-  } else if (omg_param_list.nodes_type == UE) {
-    LOG_I(OMG, "Start trace driven mobility gen for %d UEs\n",omg_param_list.nodes);
-  }
-    
-  deploy_nodes();
-return(0);
-  }
-
-int deploy_nodes() {
-    
-    NodePtr node = NULL;
-
-//     int count = 0;
-    node_info * head_node = head_node_info;
-    while (head_node!=NULL){
-    
-    //if (count<omg_param_list.nodes){
-      create_trace_node(node,head_node);
-      //count++;
-      head_node=head_node->next;
-    //}else
-    //  break;
-    
-  }
-  //if (count!=omg_param_list.nodes)
-  //  create_trace_node(node,head_node);
-  
-  return(0);
-}
+#define FIXED 1
+#define MOVING 0
+
+extern hash_table_t **table;
+extern node_info **list_head;
+//check if the next input data is the same as the previous
+
+
+
+int
+start_trace_generator (omg_global_param omg_param_list)
+{
+  double cur_time = 0.0;
+  int immobile = 0;
+  int node_number;
+  node_struct *node = NULL;
+  mobility_struct *mobility = NULL;
+  pair_struct *pair = NULL;
+  node_info *temp;
+
+  parse_data (omg_param_list.mobility_file, omg_param_list.nodes_type);	//read mobility file
+
+  //LOG_I (OMG, "mobility file %s put in the table %p\n",omg_param_list.mobility_file, table);
+
+  node_number = get_number_of_nodes (omg_param_list.nodes_type);
+
+  if (node_number == 0)
+      LOG_E (OMG, "[TRACE] empty input file \n");
+   
+
+  LOG_I (OMG, "TRACE mobility model for %d %d nodes\n", node_number,
+	 omg_param_list.nodes_type);
+  temp = list_head[omg_param_list.nodes_type];
+
+  while (temp != NULL)
+    {
+      node_data *this_node =
+	get_next_data (table[omg_param_list.nodes_type], temp->g_id, DATA_AND_STATUS_CHANGE);
+
+      if (this_node == NULL)
+	{
+	  LOG_E (OMG, "[TRACE] Unexpected empty data  entry\n");
+	  exit (-1);
+	}
+
+
+      node = create_node ();
+      mobility = create_mobility ();
+      node->id = temp->vid;
+      node->gid = temp->g_id;
+
+     /* if(this_node->type == -1)  //if node type is given in the file set the defualt type UE
+        node->type = UE;	*/
+      node->type = omg_param_list.nodes_type;
+	    node->generator = TRACE;	
+      node->mob = mobility;
+
+      place_trace_node (node, this_node);	//initial positions 
+
+
+
+      if (this_node->visit == 1)
+	{
+
+	  pair = (pair_struct *) malloc (sizeof (struct pair_struct));
+	  pair->b = node;
+
+	  if (this_node->time > cur_time)
+	    {
+	      schedule_trace_node (pair, this_node, cur_time);
+	    }
+	  else
+	    {
+	      if (this_node->x_pos == this_node->next->x_pos &&
+		  this_node->y_pos == this_node->next->y_pos)
+
+		sleep_trace_node (pair, this_node, cur_time);
+
+	      else
+
+		move_trace_node (pair, this_node, cur_time);	//move
+
+	    }
+
+	  //LOG_I (OMG,
+	  //"[TRACE] position of node ID: %d %d\n ",node->id, node->type);
+	}
+      else
+	{
+	  temp = temp->next;
+	  continue;
+	}
+
+      job_vector_end[TRACE] = add_job (pair, job_vector_end[TRACE]);
+
+      if (job_vector[TRACE] == NULL)
+	job_vector[TRACE] = job_vector_end[TRACE];
+
+      job_vector_len[TRACE]++;
+
+      temp = temp->next;
+    }
+
+
+  if (job_vector[TRACE] == NULL)
+    LOG_I (OMG, "[TRACE] Job Vector is NULL\n");
 
-int create_trace_node(NodePtr node,node_info *head_node){
-	
-  double cur_time = 0.0; 
-  MobilityPtr mobility = NULL;
-  node = (NodePtr) create_node();
-  mobility = (MobilityPtr) create_mobility();
-  node->mobile = 0;  // static for the moment
-  node->ID = head_node->vid;
-  node->type = omg_param_list.nodes_type; // UE eNB
-  node->generator = omg_param_list.mobility_type;   // STATIC, RWP...
-  node->mob = mobility;
-  
-  place_trace_node(node);	//initial positions
-  
-  Pair pair = malloc (sizeof(Pair));
-  Exnode* next_loc=NULL;
-  next_loc=get_next_position(table,node->ID);
-  
-  // put to awake node is initial position is given if not till the next given time
-  if (next_loc->time == 0)
-    pair = keep_awake_trace_node(node,cur_time,(0.11-eps),1);
-  else 
-    pair = keep_awake_trace_node(node,cur_time,(next_loc->time-cur_time),1);
-  
-  //just to fetch the target time and speed
-  next_loc=NULL;
-  next_loc=get_next_position(table,node->ID);
-  if (next_loc != NULL){
-    node->mob->target_time=next_loc->time;
-    node->mob->target_speed=next_loc->speed;
-    reset_visit_status(table,next_loc->time,node->ID);
-    LOG_D(OMG, "reset %d \n",node->ID);
-  }else{ // if only few discriptions are available
-    node->mob->target_time=9999.0;
-    node->mob->target_speed=0.0;
-    
-  }
-  
-  Job_Vector = add_job(pair, Job_Vector);
-  Job_Vector_len ++;
-  
-  if (Job_Vector == NULL)
-    LOG_E(OMG, "Job Vector is NULL\n");
   return 0;
 }
 
-void place_trace_node(NodePtr node) {
-	Exnode* next_loc=NULL ;
-	next_loc=get_next_position(table,node->ID);
-        
-	node->X_pos = next_loc->x;
-	node->mob->X_from = node->X_pos;
-	node->mob->X_to = node->X_pos;
-	node->Y_pos = next_loc->y;
-	node->mob->Y_from = node->Y_pos;
-	node->mob->Y_to = node->Y_pos;
-       
-	node->mob->speed = next_loc->speed;
-	node->mob->journey_time = 0.0;
-        reset_visit_status(table,next_loc->time,node->ID);
-        
-
-	LOG_D(OMG,"--------INITIALIZE TRACE NODE-------- \n ");
-  	LOG_I(OMG,"Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %d\n ", node->ID, node->type, node->X_pos, node->Y_pos, node->mob->speed);
-	Node_Vector[TRACE] = (Node_list) add_entry(node, Node_Vector[TRACE]);
-    	Node_Vector_len[TRACE]++;
-	
-}
+void
+place_trace_node (node_struct * node, node_data * n)
+{
+  node_data *n_ptr = n;
+  node->x_pos = (double) n_ptr->x_pos;
+  node->mob->x_from = node->x_pos;
+  node->mob->x_to = node->x_pos;
+
+  node->y_pos = (double) n_ptr->y_pos;
+  node->mob->y_from = node->y_pos;
+  node->mob->y_to = node->y_pos;
 
-// [NO MORE USED] sleep just after creation and after mobility description is over 
-Pair sleep_trace_node(NodePtr node, double cur_time,float sleep_duration){
-        
-	node->mobile = 0;
-	node->mob->speed = 0.0;
-	node->mob->X_from = node->mob->X_to;
-	node->mob->Y_from = node->mob->Y_to;
-	node->X_pos = node->mob->X_to;
-	node->Y_pos = node->mob->Y_to;
-	Pair pair = malloc(sizeof(Pair)) ;
+  node->mob->speed = n_ptr->speed;
+  node->mob->journey_time = 0.0;
+  // node->start_journey=(double) n_ptr->time;      //time of initial position
+  // node->mob->target_time=(double) n_ptr->next->time;  //time of next destination
+  LOG_I (OMG,
+	 "[TRACE] Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %.2f \n ",
+	 node->id, node->type, node->x_pos, node->y_pos, node->mob->speed);
 
-	node->mob->sleep_duration = sleep_duration ;
-	LOG_D(OMG, "node: %d \tsleep duration : %.2f\n",node->ID, node->mob->sleep_duration);
+  node_vector_end[node->type] =
+    (node_list *) add_entry (node, node_vector_end[node->type]);
 
-	node->mob->start_journey = cur_time;
-        
-        pair->a =(node->mob->start_journey + node->mob->sleep_duration);
+  if (node_vector[node->type] == NULL)
+    node_vector[node->type] = node_vector_end[node->type];
 
-	LOG_D(OMG, "to wake up at time: cur_time %f + sleep_duration : %.2f\n", cur_time,pair->a);
-	pair->b = node;
+  node_vector_len[node->type]++;
 
-	return pair;
 }
 
-Pair keep_awake_trace_node(NodePtr node, double cur_time,float duration,int jump){
-        
+void
+move_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
+{
+  node_struct *node;
+  node = pair->b;
+  double cdistance, journeytime, speed;
+  double journeytime_next, distance;
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
   node->mobile = 1;
-  
-  node->mob->speed = 0.0;
-  
-  // jump is used to displace node to strictly follow mobility discription
-  if (jump== 1){ 
-    node->X_pos = node->mob->X_to;
-    node->Y_pos = node->mob->Y_to;
-  }else{
-    node->mob->X_to = node->X_pos;
-    node->mob->Y_to = node->Y_pos;
-  }
-  node->mob->X_from = node->mob->X_to;
-  node->mob->Y_from = node->mob->Y_to;
-  Pair pair = malloc(sizeof(Pair)) ;
-  LOG_D(OMG, "Node: %d \tawake duration : %.2f\n",node->ID, duration);
+  node->mob->speed = n_data->speed;
+  node->mob->x_to = (double) n_data->next->x_pos;
+  node->mob->y_to = (double) n_data->next->y_pos;
+  node->mob->target_time = (double) n_data->next->time;
+
+//if speed equals to zero compute the speed(i.e node was on sleep move it)
+  if (node->mob->speed == 0)
+    {
+      cdistance =
+	(double)
+	sqrtf
+	(pow (node->mob->x_from - node->mob->x_to, 2) +
+	 pow (node->mob->y_from - node->mob->y_to, 2));
+      journeytime = node->mob->target_time - n_data->time;
+      speed = (double) cdistance / journeytime;
+      node->mob->speed = speed;
+    }
+
+
+  distance =
+    (double)
+    sqrtf
+    (pow (node->mob->x_from - node->mob->x_to, 2) +
+     pow (node->mob->y_from - node->mob->y_to, 2));
+
+
+  journeytime_next = (double) distance / node->mob->speed;	//time to get to destination
+
+ /* LOG_D (OMG,
+	 "[TRACE] mob->journey_time_next  %.2f target time %.2f next time %.2f speed %.2f\n",
+	 journeytime_next, node->mob->target_time, n_data->time,
+	 node->mob->speed);*/
+
+  node->mob->start_journey = cur_time;
+  pair->next_event_t = cur_time + journeytime_next;	//when to reach the destination
+
+}
+
+void
+schedule_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
+{
+  node_struct *node = pair->b;
+  node->mobile = 3;
   node->mob->start_journey = cur_time;
-        
-  //node->mob->target_time= 9999.;
-  pair->a = node->mob->start_journey + duration;
-  LOG_D(OMG, "To start up at time: cur_time + awake_duration : %.2f\n", pair->a);
-  pair->b = node;
-  LOG_D(OMG, "Current Position in awake : (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);     
-  return pair; 
+  pair->next_event_t = n_data->time;	//when to move this node
+  //LOG_D (OMG, "[TRACE] Node will wake up at time: %.2f\n", pair->next_event_t);
 }
 
 
-Pair move_trace_node(NodePtr node, double cur_time) {
-        
-  Exnode* next_loc=NULL;
-  next_loc=get_next_position(table,node->ID);
-  
-  if (next_loc==NULL) {//Option 1 : no job, I am awake 
-    LOG_D(OMG, "NULL detected\n");
-    return keep_awake_trace_node(node,cur_time,9999,1);                
-  }
-  else{ // location discription available
-//     Job_list tmp1 = Job_Vector;
-    LOG_D(OMG, "Location fetch : (%.2f, %.2f)\n", next_loc->x, next_loc->y);
-    
-    double X_next;
-    double Y_next;
-    double journeyTime_next;
-    
-    // This was used to remove duplicate entries, vehicle stays in the same position
-    //while((next_loc->x==tmp1->pair->b->mob->X_to && next_loc->y==tmp1->pair->b->mob->Y_to) )//|| next_loc->speed==0)
-    //      next_loc=get_next_position(table,node->ID);  
-        
-    //Trace defined time varies with current time so keep the node awake till the next trip discription time.
-    if (( node->mob->target_time - cur_time) >= eps && node->mob->speed !=0.0){
-      reset_visit_status(table,next_loc->time,node->ID);
-      float awake_duration=(node->mob->target_time-cur_time);
-      return keep_awake_trace_node(node,cur_time,awake_duration,1); 
+void
+sleep_trace_node (pair_struct * pair, node_data * n_data, double cur_time)
+{
+  double journeytime, distance;
+  node_struct *node = pair->b;
+  node->mobile = 0;
+  node->mob->speed = 0.0;
+  node->mob->x_from = node->mob->x_to;
+  node->mob->y_from = node->mob->y_to;
+  node->x_pos = node->mob->x_to;
+  node->y_pos = node->mob->y_to;
+//sleep duration
+
+  if (n_data->x_pos == n_data->next->x_pos &&
+      n_data->y_pos == n_data->next->y_pos)
+    {
+      node->mob->sleep_duration = n_data->next->time - n_data->time;
+
     }
-    
-    Pair pair = malloc(sizeof(Pair));
-    LOG_D(OMG, "MOVE TRACE NODE\n");
-    LOG_D(OMG, "node: %d\n",node->ID );
-    node->mob->X_from = node->X_pos;
-    node->mob->Y_from = node->Y_pos;
-    LOG_D(OMG, "Current Position: (%.2f, %.2f)\n", node->mob->X_from, node->mob->Y_from);
-    
-    if (!(next_loc->x==node->X_pos && next_loc->y==node->Y_pos) && (next_loc->speed==0. && node->mob->speed==0.0) ){
-      node->mob->X_to = node->X_pos;
-      node->mob->Y_to = node->Y_pos;
-      node->mob->speed = next_loc->speed;
-      journeyTime_next = next_loc->time-cur_time;
-      reset_visit_status(table,next_loc->time,node->ID);
-      LOG_D(OMG, "Location fetch reset: (%.2f, %.2f)\n", next_loc->x, next_loc->y);
-    }else{
-      X_next = next_loc->x;
-      node->mob->X_to = X_next;
-      Y_next = next_loc->y;
-      node->mob->Y_to = Y_next;
-      LOG_I(OMG, "destination: (%.2f, %.2f)\n", node->mob->X_to, node->mob->Y_to);
-      
-      double target_time;
-      target_time = next_loc->time;
-      node->mob->target_time= target_time;
-      
-      double speed_next;
-      speed_next = next_loc->speed; 
-      node->mob->speed = speed_next;
-      
-      LOG_D(OMG, "speed_next %.2f\n", speed_next); //m/s
-      
-      double distance = (double) ((int)(sqrtf(pow(node->mob->X_from - X_next, 2) + pow(node->mob->Y_from - Y_next, 2))*100))/ 100;
-      LOG_D(OMG, "distance %.2f\n", distance); //m
-      
-      
-      LOG_D(OMG,"next_loc->time %f",next_loc->time);
-      
-      journeyTime_next =  (double) ((int)(distance/speed_next*100))/ 100;  
-    } //duration to get to dest ;
-    
-    node->mobile = 1;
-    LOG_D(OMG, "mob->journey_time_next %.2f\n",journeyTime_next );
-    
-    node->mob->start_journey = cur_time;
-    LOG_D(OMG, "start_journey %.2f\n", node->mob->start_journey );
-    
-    pair->a = node->mob->start_journey + journeyTime_next;      //when to reach the destination
-    LOG_D(OMG, "when to reach the destination: pair->a= start journey + journey_time next =%.2f\n", pair->a);
-    
-    pair->b = node;
-    
-    
-    return pair;
-  }
+  else
+    {				//sleep case 2
+      node->mob->target_time - (journeytime + node->mob->start_journey);
+
+    }
+
+  node->mob->start_journey = cur_time;
+  pair->next_event_t = cur_time + node->mob->sleep_duration;	//when to wake up
+  /*LOG_D (OMG, "#[TRACE] node: %d \tsleep duration : %.2f\n", node->id,
+	 node->mob->sleep_duration);*/
+
 }
 
-void update_trace_nodes(double cur_time) {
-   
-   LOG_D(OMG, "--------UPDATE--------\n");
-   Job_list tmp = Job_Vector;
-   int done = 0; //
-   
-   display_job_list(Job_Vector);
-   while ((tmp != NULL) && (done == 0)){
-     //  if 	(tmp->pair == NULL){LOG_E(OMG, "UPDATE TRACE : tmp->pair ==NULL\n" );}
-     //  if 	(tmp->pair != NULL){LOG_E(OMG, "UPDATE TRACE : tmp->pair !=NULL\n" );}
-     LOG_D(OMG, "cur_time %f\n", cur_time );
-     LOG_D(OMG, "tmp->pair->a  %f %f %f\n", tmp->pair->a , cur_time - eps,cur_time + eps);
-
-     if((tmp->pair !=NULL) && ( (double)tmp->pair->a >= cur_time - eps) && ( (double)tmp->pair->a <= cur_time + eps) ) {
-       if (tmp->pair->b->generator == TRACE){
-	 LOG_D(OMG, " (first_job_time) %.2f == %.2f (cur_time) \n ",tmp->pair->a, cur_time );
-         
-         // update to a new location
-         /*if((tmp->pair->b->mob->speed == 0.0) && (tmp->pair->b->mobile == 1) && (tmp->pair->b->mob->target_speed==0.0)){
-                        Exnode* next_loc=NULL;
-                        
-                        next_loc=get_next_position(table,tmp->pair->b->ID);
-                        if (next_loc !=NULL){
-                        tmp->pair->b->X_pos = next_loc->x ;
-                        tmp->pair->b->Y_pos = next_loc->y ;
-                        }  
-         } */
-	 LOG_D(OMG, " UPDATE TRACE \n ");
-	 NodePtr my_node = (NodePtr)tmp->pair->b;
-
-	 if (my_node->mobile == 1 || my_node->mobile == 0) { //only move no stop , put to sleep in move_trace_node() only for disconnected mobility
-	   LOG_D(OMG, " node %d ready to move to next destination \n",  my_node->ID);
-           
-	   //my_node->mobile = 1;
-	   Pair pair = malloc(sizeof(Pair));
-	   pair = move_trace_node(my_node, cur_time);
-           
-	   tmp->pair = pair;
-	   tmp = tmp->next;
-	 }
-	 else{
-	   LOG_E(OMG, "update_generator: unsupported node state - mobile : %d \n", my_node->mobile);
-	   exit(-1);
-	 }
-       }
-       else {
-	 LOG_D(OMG, " (first_job_time) %.2f == %.2f(cur_time) but (generator=%d) != (TRACE=%d)\n ",tmp->pair->a, cur_time, tmp->pair->b->generator, TRACE );
-	 tmp = tmp->next;
-       }
-        
-     }
-     else if ( (tmp->pair != NULL) && (cur_time < tmp->pair->a ) ){  //&& (tmp->pair->b->generator == RWP)
-       LOG_D(OMG, "%.2f < %.2f \n",cur_time, tmp->pair->a);
-       if ((cur_time >= tmp->pair->b->mob->target_time-eps) && (cur_time<=tmp->pair->b->mob->target_time + eps)){
-        
-        tmp->pair->b->X_pos = tmp->pair->b->mob->X_to;
-	tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to;
-        Pair pair = malloc(sizeof(Pair));
-        //pair = keep_awake_trace_node(tmp->pair->b,cur_time,awake_duration,1);
-        pair = move_trace_node(tmp->pair->b, cur_time);
-	tmp->pair = pair;
-        }
-       tmp = tmp->next;  
-     }
-     else {
-       LOG_E(OMG, "%.2f > %.2f\n", cur_time,tmp->pair->a   );   //LOG_D(OMG, " (generator=%d) != (RWP=%d) \n", tmp->pair->b->generator,  RWP );
-       done = 1;  //quit the loop
-       exit(-1);
-     }
- }
-   //sorting the new entries
-   LOG_D(OMG, "--------DISPLAY JOB LIST--------\n"); //LOG_T
-   display_job_list(Job_Vector);
-   Job_Vector = quick_sort (Job_Vector);///////////
-   LOG_D(OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
-   display_job_list(Job_Vector);
-   
+
+void
+update_trace_nodes (double cur_time)
+{
+  job_list *tmp;
+  int done = 0;
+  node_data *node_n;
+  node_struct *my_node;
+
+
+  tmp = job_vector[TRACE];
+  if (tmp == NULL)
+    LOG_D (OMG, "[TRACE] last data for all nodes\n");
+
+  while (tmp != NULL && done != 1)
+    {				//1
+      my_node = tmp->pair->b;
+      node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
+
+      if (node_n->next->next == NULL)
+	{
+	  tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
+	  tmp->pair->b->mob->x_from = tmp->pair->b->x_pos;
+	  tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
+	  tmp->pair->b->mob->y_from = tmp->pair->b->y_pos;
+          tmp->pair->b->mobile = 0;
+          tmp->pair->b->mob->speed = 0.0;           
+	  // LOG_D (OMG, "[TRACE] last data for all nodes\n");
+	  tmp = tmp->next;
+	  continue;
+	}
+
+
+
+      //case1:time to next event equals to current time      
+      if (tmp->pair != NULL && tmp->pair->next_event_t >= cur_time - eps
+	  && tmp->pair->next_event_t <= cur_time + eps)
+	{
+	  //LOG_D (OMG, "[TRACE] last data for all nodes\n");
+	  if (my_node->mobile == 1)
+	    {
+	      if (my_node->mob->target_time > tmp->pair->next_event_t)	//sleep node
+		{
+		  sleep_trace_node (tmp->pair, node_n, cur_time);
+		}
+	      else
+		{
+		  node_n =
+		    get_next_data (table[my_node->type], my_node->gid,
+				   DATA_AND_STATUS_CHANGE);
+
+
+		  if (node_n->x_pos == node_n->next->x_pos &&
+		      node_n->y_pos == node_n->next->y_pos)
+
+		    sleep_trace_node (tmp->pair, node_n, cur_time);
+
+		  else
+		    move_trace_node (tmp->pair, node_n, cur_time);
+		}
+
+	    }
+	  else if (my_node->mobile == 0)
+	    {
+	      node_n =
+		get_next_data (table[my_node->type], my_node->gid, DATA_AND_STATUS_CHANGE);
+
+	      if (node_n->x_pos == node_n->next->x_pos &&
+		  node_n->y_pos == node_n->next->y_pos)
+
+		sleep_trace_node (tmp->pair, node_n, cur_time);
+
+	      else
+		move_trace_node (tmp->pair, node_n, cur_time);
+
+	    }
+	  else
+	    {
+	      node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
+	      if (node_n->x_pos == node_n->next->x_pos &&
+		  node_n->y_pos == node_n->next->y_pos)
+
+		sleep_trace_node (tmp->pair, node_n, cur_time);
+
+	      else
+		move_trace_node (tmp->pair, node_n, cur_time);
+
+	    }
+
+
+	}
+
+      //case2: current time is greater than the time to next event
+      else if (tmp->pair != NULL && cur_time - eps > tmp->pair->next_event_t)
+	{
+	  while (cur_time >= tmp->pair->next_event_t)
+	    {
+
+
+	      if (node_n->next->next == NULL)
+		{
+		  tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
+		  tmp->pair->b->mob->x_from = tmp->pair->b->x_pos;
+		  tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
+		  tmp->pair->b->mob->y_from = tmp->pair->b->y_pos;
+		  break;
+		}
+
+	      if (my_node->mobile == 1)
+		{
+		  if (my_node->mob->target_time > tmp->pair->next_event_t)	//sleep node
+		    {
+		      sleep_trace_node (tmp->pair, node_n, cur_time);
+		    }
+		  else
+		    {
+		      node_n =
+			get_next_data (table[my_node->type], my_node->gid,
+				       DATA_AND_STATUS_CHANGE);
+
+
+		      if (node_n->x_pos == node_n->next->x_pos &&
+			  node_n->y_pos == node_n->next->y_pos)
+
+			sleep_trace_node (tmp->pair, node_n, cur_time);
+
+		      else
+			move_trace_node (tmp->pair, node_n, cur_time);
+		    }
+
+		}
+	      else if (my_node->mobile == 0)
+		{
+		  node_n =
+		    get_next_data (table[my_node->type], my_node->gid,
+				   DATA_AND_STATUS_CHANGE);
+
+		  if (node_n->x_pos == node_n->next->x_pos &&
+		      node_n->y_pos == node_n->next->y_pos)
+
+		    sleep_trace_node (tmp->pair, node_n, cur_time);
+
+		  else
+		    move_trace_node (tmp->pair, node_n, cur_time);
+
+		}
+	      else
+		{
+		  node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
+		  if (node_n->x_pos == node_n->next->x_pos &&
+		      node_n->y_pos == node_n->next->y_pos)
+
+		    sleep_trace_node (tmp->pair, node_n, cur_time);
+
+		  else
+		    move_trace_node (tmp->pair, node_n, cur_time);
+
+		}
+
+	      node_n = get_next_data (table[my_node->type], my_node->gid, DATA_ONLY);
+
+	      if (node_n == NULL || node_n->next == NULL)
+		{
+		  break;
+		}
+
+	    }			//2
+	}
+      //case3: current time less than the time to next event
+      else
+	{
+	  done = 1;		//quit the loop
+	}
+
+
+      tmp = tmp->next;
+
+    }				//1
+
+  //sorting the new entries
+  //LOG_D (OMG, "--------DISPLAY JOB LIST--------\n");  //LOG_T
+  // display_job_list (Job_Vector);
+  job_vector[TRACE] = quick_sort (job_vector[TRACE]);	///////////
+  //LOG_D (OMG, "--------DISPLAY JOB LIST AFTER SORTING--------\n");
+  // display_job_list( job_vector[TRACE]);
 }
 
-void get_trace_positions_updated(double cur_time){
-  
-  double X_now=0.0;
-  double Y_now=0.0;
-  //LOG_D(OMG, "--------GET TRACE POSITIONS--------\n");
-
-  Pair my_pair = Job_Vector->pair;
-  
-  if ( (my_pair !=NULL) && (cur_time <= my_pair->a )){
-    // LOG_D(OMG, "%.2f <= %.2f\n ",cur_time, my_pair->a);
-    Job_list tmp = Job_Vector;
-    
-    
-    while (tmp != NULL){
-      if (tmp->pair->b->generator == TRACE){
-        
-        if (tmp->pair->b->mobile == 0){ //node is sleeping
-          LOG_T(OMG, "node number %d is sleeping at location: (%.2f, %.2f)\n", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-          LOG_T(OMG, "nothing to do\n");
-        }
-        else if (tmp->pair->b->mobile == 1){ //node is moving
-          LOG_D(OMG,"Node  %d is mobile at %f\n", tmp->pair->b->ID,cur_time);
-          LOG_T(OMG, "Node_number %d\n", tmp->pair->b->ID);
-          LOG_D(OMG, "destination not yet reached\tfrom (%.2f, %.2f)\tto (%.2f, %.2f)\tspeed %.2f\t(X_pos %.2f\tY_pos %.2f)\n", tmp->pair->b->mob->X_from, tmp->pair->b->mob->Y_from,tmp->pair->b->mob->X_to, tmp->pair->b->mob->Y_to,tmp->pair->b->mob->speed, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-          
-          double step=0.10;
-          
-          if (tmp->pair->b->mob->speed == 0.0 ){
-                
-                if (tmp->pair->b->mob->target_speed == 0.0 ){
-                     
-                     if ((cur_time >= (tmp->pair->b->mob->target_time-step)-eps) && (cur_time<=(tmp->pair->b->mob->target_time + step)+eps)) {
-                        
-                        Exnode* next_loc=NULL;
-                        next_loc=get_next_position(table,tmp->pair->b->ID);
-
-                        if (next_loc !=NULL){
-                        tmp->pair->b->X_pos = next_loc->x ;
-                        tmp->pair->b->Y_pos = next_loc->y ;
-                        //tmp->pair->b->X_pos = tmp->pair->b->mob->X_to;
-	                //tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_to;
-                        }  
-                     }   
-                }       
-                // needed ?
-                //tmp->pair->b->X_pos = tmp->pair->b->mob->X_from + 0.0;
-                //tmp->pair->b->Y_pos = tmp->pair->b->mob->Y_from + 0.0;
-                
-                }
-          else {
-           
-          double len = sqrtf(pow(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to,2)+pow(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to,2));
-          double dx = fabs(tmp->pair->b->mob->X_from - tmp->pair->b->mob->X_to) / len;
-
-          double dy = fabs(tmp->pair->b->mob->Y_from - tmp->pair->b->mob->Y_to) / len;
-          
-          if (tmp->pair->b->mob->X_from < tmp->pair->b->mob->X_to ){
-            X_now = tmp->pair->b->mob->X_from + (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey) ) );
-          }
-          else{
-            X_now = tmp->pair->b->mob->X_from - (dx * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-          }
-
-          if (tmp->pair->b->mob->Y_from < tmp->pair->b->mob->Y_to ){
-            Y_now = tmp->pair->b->mob->Y_from + (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-          }
-          else{
-            Y_now = tmp->pair->b->mob->Y_from - (dy * (tmp->pair->b->mob->speed * (cur_time - tmp->pair->b->mob->start_journey)));
-          }
-
-          LOG_D(OMG, "X_now %f\tY_now %f\n", X_now, Y_now);
-          tmp->pair->b->X_pos = (double) ((int) (X_now*100))/ 100;
-          tmp->pair->b->Y_pos = (double) ((int) (Y_now*100))/ 100;
-          //tmp->pair->b->mob->X_from = tmp->pair->b->X_pos;
-          //tmp->pair->b->mob->Y_from = tmp->pair->b->Y_pos;
-	  //tmp->pair->b->mob->start_journey = cur_time;
-        }
-          LOG_D(OMG, "Updated_position of %s id %d to :(%.2f, %.2f)\n", (tmp->pair->b->type == 0) ? "eNB" : "UE", tmp->pair->b->ID, tmp->pair->b->X_pos, tmp->pair->b->Y_pos);
-        }
-        else{
-          LOG_E(OMG, "Update_generator: unsupported node state - mobile : %d \n", tmp->pair->b->mobile);
-          return;
+
+void
+get_trace_positions_updated (double cur_time)
+{
+  double x_now = 0.0, y_now = 0.0;
+  double len, dx, dy;
+  job_list *tmp = job_vector[TRACE];
+
+  while (tmp != NULL)
+    {
+
+      if (tmp->pair->b->mobile == 1 && tmp->pair->next_event_t >= cur_time)
+	{
+
+	  //printf("hiiiiiiiiiii \n");
+	  len =
+	    sqrtf (pow
+		   (tmp->pair->b->mob->x_from -
+		    tmp->pair->b->mob->x_to,
+		    2) + pow (tmp->pair->b->mob->y_from -
+			      tmp->pair->b->mob->y_to, 2));
+	  if (len != 0)
+	    {
+	      dx =
+		fabs (tmp->pair->b->mob->x_from -
+		      tmp->pair->b->mob->x_to) / len;
+	      dy =
+		fabs (tmp->pair->b->mob->y_from -
+		      tmp->pair->b->mob->y_to) / len;
+	      //x coordinate
+	      if (tmp->pair->b->mob->x_from < tmp->pair->b->mob->x_to)
+		{
+		  x_now =
+		    tmp->pair->b->mob->x_from +
+		    (dx *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+	      else
+		{
+		  x_now =
+		    tmp->pair->b->mob->x_from -
+		    (dx *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+
+	      //y coordinate
+	      if (tmp->pair->b->mob->y_from < tmp->pair->b->mob->y_to)
+		{
+		  y_now =
+		    tmp->pair->b->mob->y_from +
+		    (dy *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+	      else
+		{
+		  y_now =
+		    tmp->pair->b->mob->y_from -
+		    (dy *
+		     (tmp->pair->b->mob->speed *
+		      (cur_time - tmp->pair->b->mob->start_journey)));
+		}
+
+	      tmp->pair->b->x_pos = (double) ((int) (x_now * 100)) / 100;
+	      tmp->pair->b->y_pos = (double) ((int) (y_now * 100)) / 100;
+
+
+
+	    }
+	  else
+	    {
+	      tmp->pair->b->x_pos = tmp->pair->b->mob->x_to;
+	      tmp->pair->b->y_pos = tmp->pair->b->mob->y_to;
+	    }
+
 	}
-      }
       tmp = tmp->next;
+
     }
-    
- }
- else {
-   LOG_E(OMG, "ERROR (current time) %f > %f (first job_time) \n", cur_time ,my_pair->a );
- }
+
 
 }
 
+
+void
+clear_list (void)
+{
+
+
+}
diff --git a/openair2/UTIL/OMG/trace.h b/openair2/UTIL/OMG/trace.h
index b95ff5b0d564a283bdd843a0ec042243eb220c6f..acc61825be0d90d7512f68a495351d87ec1e1c11 100644
--- a/openair2/UTIL/OMG/trace.h
+++ b/openair2/UTIL/OMG/trace.h
@@ -42,65 +42,22 @@
 #define TRACE_H_
 //#include "defs.h"
 #include "omg.h"
-#include "hashtable.h"
+#include "trace_hashtable.h"
 #include "mobility_parser.h"
 
+int start_trace_generator (omg_global_param omg_param_list);
 
-/**
- * \fn void start_trace_generator(omg_global_param omg_param_list)
- * \brief Start the TRACE model by setting the initial positions of each node then letting it sleep for a random duration and adding this job to the Job_Vector
- * \param omg_param_list a structure that contains the main parameters needed to establish the random positions distribution
- */
-int start_trace_generator(omg_global_param omg_param_list) ;
-
-/**
- * \fn int create_trace_node(node_info *head_node)
- * \brief Called by the function start_trace_generator(), it assigns position ((X,Y) coordinates)  for a node from mobility file and add it to the Node_Vector_Rwp
- * \param node a pointer of type NodePtr that represents the node to which the random position is assigned
- */
-int create_trace_node(NodePtr node,node_info *head_node) ;
-/**
- * \fn void place_rwp_node(NodePtr node)
- * \brief Called by the function start_rwp_generator(), it generates a random position ((X,Y) coordinates)  for a node and add it to the Node_Vector_Rwp
- * \param node a pointer of type NodePtr that represents the node to which the random position is assigned
- */
-void place_trace_node(NodePtr node) ;
-int deploy_nodes();
-/**
- * \fn Pair sleep_rwp_node(NodePtr node, double cur_time)
- * \brief Called by the function start_rwp_generator(omg_global_param omg_param_list) and update_rwp_nodes(double cur_time), it allows the node to sleep for a random duration starting
- * 	from the current time
- * \param node a pointer of type NodePtr that represents the node to which the random sleep duration is assigned
- * \param cur_time a variable of type double that represents the current time
- * \return A Pair structure containing the node and the time when it is reaching the destination
- */
-Pair sleep_trace_node(NodePtr node, double cur_time,float sleep_duration) ;
-Pair keep_awake_trace_node(NodePtr node, double cur_time,float duration,int jump);
-/**
- * \fn Pair move_rwp_node(NodePtr node, double cur_time)
- * \brief Called by the function update_rwp_nodes(double cur_time), it computes the next destination of a node ((X,Y) coordinates and the arrival
- *	 time at the destination)
- * \param node a variable of type NodePtr that represents the node that has to move
- * \param cur_time a variable of type double that represents the current time
- * \return A Pair structure containing the node structure and the arrival time at the destination
- */
-Pair move_trace_node(NodePtr node, double cur_time) ;
-
-/**
- * \fn void update_rwp_nodes(double cur_time)
- * \brief Update the positions of the nodes. After comparing the current time to the first job_time, it is decided wether to start
- * \	a new job or to keep the current job
- * \param cur_time a variable of type double that represents the current time
- */
-void update_trace_nodes(double cur_time) ;
-
-/**
- * \fn void get_rwp_positions_updated(double cur_time)
- * \brief Compute the positions of the nodes at a given time in case they are moving (intermediate positions). Otherwise, generate a message saying that
- * 	the nodes are still sleeping
- * \param cur_time a variable of type double that represents the current time
- */
-void get_trace_positions_updated(double cur_time);
+void place_trace_node (node_struct* node, node_data* n);
 
+void move_trace_node (pair_struct* pair, node_data* n_data, double cur_time);
+
+void schedule_trace_node ( pair_struct* pair, node_data* n_data, double cur_time);
+
+void sleep_trace_node ( pair_struct* pair, node_data* n_data, double cur_time);
+
+void update_trace_nodes (double cur_time);
+
+void get_trace_positions_updated (double cur_time);
+void clear_list (void);
 
 #endif /* TRACE_H_ */
diff --git a/openair2/UTIL/OMG/trace_hashtable.c b/openair2/UTIL/OMG/trace_hashtable.c
new file mode 100644
index 0000000000000000000000000000000000000000..016cae3c07f3f832e4f139bf58357d6870cb38fe
--- /dev/null
+++ b/openair2/UTIL/OMG/trace_hashtable.c
@@ -0,0 +1,250 @@
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2011 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.fr
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fsr/openairinterface
+  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
+
+*******************************************************************************/
+
+/*! \file hashtable.c
+* \brief A 'C' implementation of a hashtable
+* \author S. Gashaw,  N. Nikaein, J. Harri
+* \date 2014
+* \version 0.1
+* \company EURECOM
+* \email: 
+* \note
+* \warning
+*/
+
+#include <stdio.h>
+#include "trace_hashtable.h"
+#include <stdlib.h>
+#include <string.h>
+#include "omg.h"
+
+/*Global variables*/
+node_info **list_head;
+hash_table_t **table;
+
+// hash table operations
+/**
+ * Fuction to create a new hash table
+ * @param mode hash_table_mode which the hash table should follow
+ * @returns hash_table_t object which references the hash table
+ * @returns NULL when no memory
+ */
+void
+create_new_table (int node_type)
+{
+  int i;
+  if(table==NULL)
+    table = (hash_table_t **) calloc (MAX_NUM_NODE_TYPES, sizeof (hash_table_t*));
+
+    table[node_type]=(hash_table_t *) calloc (MAX_NUM_NODE_TYPES, sizeof (hash_table_t));
+
+  if (table == NULL || table[node_type]==NULL)
+    {
+      LOG_E (OMG, "--------table creation failed--------\n");
+      exit (-1);
+    }
+  table[node_type]->key_len = LEN;
+  table[node_type]->key_count = 0;
+  table[node_type]->ratio = RATIO;
+
+  table[node_type]->data_store =
+    (node_container **) calloc (LEN, sizeof (node_container *));
+  if (table[node_type]->data_store == NULL)
+    {
+      free (table[node_type]);
+      LOG_E (OMG, "table creation failed \n");
+      exit (-1);
+    }
+
+  //for (i = 0; i < LEN; i++)
+  // table->data_store[i] = NULL;
+}
+
+
+
+
+/**
+ * Function to add a key - value pair to the hash table, use HT_ADD macro
+ * @param table hash table to add element to
+ * @param key pointer to the key for the hash table
+ * @param key_len length of the key in bytes
+ * @param value pointer to the value to be added against the key
+ * @param value_len length of the value in bytes
+ * @returns 0 on sucess
+ * @returns -1 when no memory
+ */
+void
+hash_table_add (hash_table_t * t_table, node_data * node,
+		node_container * value)
+{
+  hash_table_t *my_table = t_table;
+  node_data *new_node = node;
+  int key = new_node->gid;
+  int hash_val = hash (&key, my_table->key_len);
+
+//resize check
+
+  if (value == NULL)
+    {				//create new container for this node
+
+      my_table->key_count++;
+
+      node_container *new_c =
+	(node_container *) calloc (1, sizeof (node_container));
+
+      if (!new_c)
+	{
+	  LOG_E (OMG, "node block creation failed\n");
+	  exit (-1);
+	}
+
+      new_c->gid = new_node->gid;
+      new_c->next = new_node;
+      new_c->end = new_c->next;
+      new_c->next_c = NULL;
+
+      if (my_table->data_store[hash_val] == NULL)
+	       my_table->data_store[hash_val] = new_c;
+      else
+	{
+	  node_container *temp1, *save;
+	  temp1 = my_table->data_store[hash_val];
+	  while (temp1 != NULL)
+	    {
+	      save = temp1;
+	      temp1 = temp1->next_c;
+	    }
+	  save->next_c = new_c;
+	}
+
+    }
+  else
+    {
+      node_container *my_c = value;
+      //put node data according to time
+      if (my_c->gid == new_node->gid)
+	{
+	  if (my_c->next->time > new_node->time)
+	    {
+	      new_node->next = my_c->next;
+	      my_c->next = new_node;
+	      return;
+	    }
+
+	  if (my_c->end->time <= new_node->time)
+	    {
+	      my_c->end->next = new_node;
+	      my_c->end = new_node;
+	      return;
+	    }
+
+	  node_data *temp = my_c->next;
+	  node_data *ptr = temp->next;
+	  while (ptr != NULL && ptr->time <= new_node->time)
+	    {
+	      temp = ptr;
+	      ptr = ptr->next;
+	    }
+	  temp->next = new_node;
+	  new_node->next = ptr;
+	}
+    }
+
+
+}
+
+/**
+ * Function to lookup a key in a particular table
+ * @param table table to look key in
+ * @param key pointer to key to be looked for
+ * @param key_len size of the key to be searched
+ * @returns NULL when key is not found in the hash table
+ * @returns void* pointer to the value in the table
+ */
+node_container *
+hash_table_lookup (hash_table_t * table, int id)
+{
+  hash_table_t *my_table = table;
+  int key = id;
+  int hash_value_of_id = hash (&key, my_table->key_len);
+  if (my_table->data_store[hash_value_of_id] == NULL)
+    return NULL;
+
+  node_container *temp = my_table->data_store[hash_value_of_id];
+
+  while (temp != NULL)
+    {
+      if (temp->gid == id)
+	break;
+      temp = temp->next_c;
+    }
+
+  return temp;
+}
+
+
+
+
+
+/**
+ * Function that returns a hash value for a given key and key_len
+ * @param key pointer to the key
+ * @param key_len length of the key
+ * @param max_key max value of the hash to be returned by the function
+ * @returns hash value belonging to [0, max_key)
+ */
+uint16_t
+hash (int *key, int len)
+{
+  uint16_t *ptr = (uint16_t *) key;
+  uint16_t hash = 0xbabe;	// WHY NOT
+  size_t i = 0;
+  for (; i < (sizeof (key) / 2); i++)
+    {
+      hash ^= (i << 4 ^ *ptr << 8 ^ *ptr);
+      ptr++;
+    }
+  hash = hash % len;
+  return hash;
+}
+
+
+/**
+ * Function to resize the hash table store house
+ * @param table hash table to be resized
+ * @param len new length of the hash table
+ * @returns -1 when no elements in hash table
+ * @returns -2 when no emmory for new store house
+ * @returns 0 when sucess
+ */
+int
+hash_table_resize ()
+{
+
+}
diff --git a/openair2/UTIL/OMG/trace_hashtable.h b/openair2/UTIL/OMG/trace_hashtable.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a0464b04f4729d509fbc4522a82fc340476e56e
--- /dev/null
+++ b/openair2/UTIL/OMG/trace_hashtable.h
@@ -0,0 +1,173 @@
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2011 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.fr
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fsr/openairinterface
+  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
+
+*******************************************************************************/
+
+/*! \file trace_hashtable.h
+* \brief A 'C' implementation of a hashtable
+* \author  S. Uppoor
+* \date 2011
+* \version 0.1
+* \company INRIA
+* \email: sandesh.uppor@inria.fr
+* \note
+* \warning
+*/
+
+#ifndef _TRACE_HASHTABLE_H
+#define _TRACE_HASHTABLE_H
+#define LEN 1
+#define RATIO 4
+#include<sys/types.h>
+#include<stdint.h>
+#define DATA_ONLY 0
+#define DATA_AND_STATUS_CHANGE 1
+
+/**
+ * @struct Simple struct to hold only few information
+ * @brief The entry in each node is a line from the external mobility file
+ */
+ 
+
+
+
+typedef struct parsed_data
+{
+  int vid;
+  int gid;
+  int type;
+  double time;
+  double x_pos;
+  double y_pos;
+  double speed;
+  int visit;
+  struct parsed_data* next;
+}node_data;
+
+
+
+/**
+ * @struct hash_table_element "hashtable.h"
+ * @brief stores an hash table element for use in the hash table
+ */
+
+ 
+typedef struct container
+{
+  int flag;
+  int gid;
+  node_data* next;
+  node_data* end;
+  struct container* next_c;
+}node_container;
+
+
+/**
+ * @struct hash_table "hashtable.h"
+ * @brief identifies the hashtable for which operations are to be performed
+ */
+ 
+typedef struct hash_table
+{
+  int key_len;
+  int key_count;
+  int ratio;
+  node_container **data_store;
+}hash_table_t;
+
+
+
+/**
+ * @struct struct acts as gateway to hashtable
+ * @brief holds vehicle id and initial pointer to the head of the linked list in hastable
+ */
+ 
+
+typedef struct nodeinfo
+{
+  int vid;
+  int g_id;
+  struct nodeinfo* next;
+}node_info;
+
+
+
+
+/**
+ * Function that returns a hash value for a given key and key_len
+ * @param key pointer to the key
+ * @param key_len length of the key
+ *f @param max_key max value of the hash to be returned by the function 
+ * @returns hash value belonging to [0, max_key)
+ */
+uint16_t hash (int *key, int len);
+
+// hash table operations
+/**
+ * Fuction to create a new hash table
+ * @param mode hash_table_mode which the hash table should follow
+ * @returns hash_table_t object which references the hash table
+ * @returns NULL when no memory
+ */
+void create_new_table (int node_type);
+
+/**
+ * Function to add a key - value pair to the hash table, use HT_ADD macro
+ * @param table hash table to add element to
+ * @param key pointer to the key for the hash table
+ * @param key_len length of the key in bytes
+ * @param value pointer to the value to be added against the key
+ * @param value_len length of the value in bytes
+ * @returns 0 on sucess
+ * @returns -1 when no memory
+ */
+void hash_table_add (hash_table_t* t_table, node_data* node, node_container* value);
+
+
+/**
+ * Function to lookup a key in a particular table
+ * @note use this macro when size of key and/or value can be given by sizeof
+ * @param table table to look key in
+ * @param key pointer to key to be looked for
+ * @param key_len size of the key to be searched
+ * @returns NULL when key is not found in the hash table
+ * @returns void* pointer to the value in the table
+ */
+node_container* hash_table_lookup (hash_table_t* table, int id);
+
+
+
+/**
+ * Function to resize the hash table store house
+ * @param table hash table to be resized
+ * @param len new length of the hash table
+ * @returns -1 when no elements in hash table
+ * @returns -2 when no emmory for new store house
+ * @returns 0 when sucess
+ */
+int hash_table_resize (void);
+#endif