Ubuntu: how to set a node to sleep in ns2


I just want to set a node to sleep in "ns-2" and i have searched in protocols and i found a lot of objects and functions about sleep but i couldn't use them in other protocols to set a node to sleep.
When i use them i get Segmentation fault or Floating point and i know what these errors mean but i can't find a way to solve them.
Like when i use sleep() function from "SMAC".
I have searched in google and after a week i still didn't find any solution...! could you guys please help me here...?


I have found the solution months ago but i saw this question of mine so i said let's answer it so, people like me that couldn't find the answer until going through all that trouble, could easily find out how to solve it...

Well first of all let me introduce you to protocol's codes in ns2.
A protocol has been created with 2 main files(there is some protocols with only one file too but i'm talking about the most of them) in ns2 that one of them has .cc type that contains the protocol's name(like AODV.cc) for definition and the other one has the .h type for declaration and it also contains the protocols name(like AODV.h).

enter image description here

There could be other files including the protocol but the main is protocolname.cc.

enter image description here

We need to change/add some functions in the protocolname.cc so we could simulate our own protocol.

For example :
We need to use clustering for our protocol :
AODV.h :

public:      AODV();      void CLUSTERING();      ...  

AODV.cc :

void AODV::CLUSTERING(){      if(current_){           while(numberofNodes){                 // Selecting clusters           }      }  }  

Now we know how the mechanism of ns2 works.so let's get started with sleep nodes.
First of all there is 4 functions in ns2 for turning a node to 'off', 'on', 'sleep', 'idle'. The difference between these are not so big.
As you know the 'off' function turns a node to off but it still broadcasts something based on your protocol.

$ns_ at 7.0 "$node(2) off"  

And you can turn it on like :

$ns_ at 7.0 "$node(2) on"  

The base is :

$simulator at $time "$Node_($number) off"  

I don't know how to set a node to sleep in scenario.tcl but you can do that in your protocol's codes.
Now, to set a node to sleep we could do several things...

  • setting nodes to sleep from energy model
  • setting nodes to sleep from wireless physics

First we'll try energymodel.cc and if it didn't work we'll use the other one.
To set a node to sleep from energymodel.cc we can use this code in void Mac802_11::recv function in ns-2.35/mac/mac-802_11.cc :

if(index_ == myNode){      EnergyModel *em = netif_->node()->energy_model();      if (em && em->sleep()) {          em->set_node_sleep(1);          //em->set_node_state(EnergyModel::INROUTE);      }  }  

Replace myNode with the number of the interface you want to set it to off.
If you are not using MultiInterface for your simulation so the number of interfaces will be equal to the number of your nodes.

example :
Normal :

            node ---- > interface ----> channel  

MultiInterface :

                         ---- > interface[0] -----|                          |                          ---------|                          |                                   v              node -------|---- > interface[1] --------- > channel                          |                                   ^                          |                         ----------|                           ---- > interface[2] -----|  

Open a terminal and cd to your ns2 directory, for example if you have ns-allinone-2.35, cd to /ns-allinone-2.35/ns-2.35/ and now type make and inter. After it finished try to simulate your scenario.tcl.

Now if your simulation start and you see the nam file, when the nodes get the first packet, the shape of them must change from balck circle to black circle blue hexagon.
From then on the nodes must not send or receive any data packet.

If this way didn't work now it's the time to use the other option.
Go to /ns-2.35/mac/ and open wireless-phy.cc.
You'll see that at the end of the file it contains our 4 function that we need.
we can simply use those function on the wireless-phy.cc to set a node to sleep or off by just calling those functions.But we may need to use them in another layer like in mac.
To use those functions in mac-802_11.cc simply use the below code anywhere you want in mac-802_11.cc and add wireless-phy.cc to your mac headers:

 #include "wireless-phy.h" // at the header of mac-802_11.cc  
 /*    * Use the below code in any function you want in mac    */   Phy *p;   p=netif_;   ((WirelessPhy *)p)->node_sleep();  

And to use another one of those 4 function just change the function's name like ->node_sleep(); to ->node_wakeup();.


A node can be "Off" and "On" by invoking WirelessPhy::command(int argc, const char*const* argv) of WirelessPhy.cc from Tcl script. To do this, say for Node_(0), once the node is defined in Tcl script, do:

set        Netif_0        [$Node_(0) set netif_(0)]  

Note that the variable netif_ is an array and hence we use netif_(0) to get the handle for the first Network Interface. netif_(1) and netif(2)... can be similarly used for Second and Third Network Interfaces, if the node was configured with multiple interfaces.

Once the handles are brought to local scope, we can use any command that is defined in WirelessPhy and we can use $Netif_0 NodeOff to switch off the node to deactivate the Network Interface.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »