how to set a node to sleep in ns2
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).
There could be other files including the protocol but the main is protocolname.cc
.
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.