Skip to main content

Adding New Agent in NS2 | OLSR Protocol Changes | NS2 Basics | Lecture 8

In this post, you can learn 

  • Create a new packet structure that may be attached to the agent

  • Create a new packet queue

  • Know the Optimised Link State Routing (OLSR) protocol for wireless networks


8.1 - Introduction

NS2 can simulate almost all the wired and wireless networks. Also, it has the capacity to simulate other networks like satellite networks, multicasting, etc. This chapter will make the readers to write a new packet structure and add it to an agent and test the packet in a wireless network.


8.2 – Adding a New Agent

Creation of an agent in NS2 needs an understanding of the OTCL and C++ linkages that are described in previous posts.  Creation of a packet also involves the linkages between Otcl and C++. The following source code tells about the creation of a new agent along with a new packet.


Listing 8.1 shows the code of a declaration of TSPAgent, which inherits the Agent class. It also has the inner class TSPTimer to deal with timeouts during an Event timeout interval.


Listing 8.1 – Creation of TSPAgent

//filename: tspagent.h

#ifndef TSPAGENT_H_

#define TSPAGENT_H_


#include "agent.h"

#include "timer-handler.h"


//declaration of class TSPAgent inherits the Agent class

class TSPAgent: public Agent {

public:

TSPAgent();  //constructor

int command(int argc, const char*const* argv);

int value_;


void recv(Packet* p, Handler*);


void myTimeout();

//Inner class that handles the Time out event for the agent

class TSPTimer: public TimerHandler {  

public:

TSPTimer(TSPAgent &a) : agent(a) {}

void expire(Event *e) { //agent.myTimeout();

}

TSPAgent &agent;

} TSPTimer;


};


#endif /*CLUSTERINGAGENT_H_*/



Listing 8.2 shows the implementation of TSPAgent and implements the agent that acts upon the PT_TSP packet that will be introduced shortly in the next section of code.

This agent also has a binding variable value_ that has to be set in the ns-default.tcl file.

A PT_TSP packet will be sent if the Otcl command is “sendTo”  and if the Otcl command is Hello, the C++ file will report as “Your Message is received”

Listing 8.2 – Implementation of TSPAgent

//Filename:TSPAgent.cc

#include "TSPAgent.h"

#include "TSPPacket.h"

#include "ip.h"

#include <cstdlib>


//a static class which will be called before instantiating any object for this class

static class TSPAgentClass: public TclClass {

public:

TSPAgentClass() : TclClass("Agent/TSPAgent") {} //name of the agent in OTcl

TclObject* create(int, const char*const*) {

return (new TSPAgent());

}

} class_TSPAgent;



//Constructor of TSPAgent, which acts upon the PT_TSP packet, which will be implemented shortly.

TSPAgent::TSPAgent() : Agent(PT_TSP),TSPTimer(*this) {

bind("value_",&value_);  //contains a variable value_

}


//recv() function

void TSPAgent::recv(Packet* p, Handler*) {

hdr_ip *ip = hdr_ip::access(p);

hdr_TSPHeader* tsp=  hdr_TSPHeader::access(p);

printf("Agent %d receives packet with value %d from Agent %d\n",addr(),tsp->myData, ip->saddr() );

Packet::free(p);

}


//command function that controls the Otcl commands

int TSPAgent::command(int argc, const char*const* argv) {

if (argc == 3) {

if (strcmp(argv[1], "sendTo") == 0) {


Packet* p = allocpkt();

hdr_ip *ip = hdr_ip::access(p);

hdr_cmn* cmn = hdr_cmn::access(p);

hdr_TSPHeader* tsp=  hdr_TSPHeader::access(p);

tsp->myData=1000;

cmn->size()= 4;

cmn->ptype() = PT_TSP;

ip->daddr()= atoi(argv[2]);

ip->dport()= here_.port_;

send(p, 0);

return (TCL_OK);

}

}


if (argc == 2) {

if (strcmp(argv[1], "Hello") == 0) {

printf("Your Message is received \n");

return (TCL_OK);

}

}

return (Agent::command(argc, argv));

}


void myTimeout() {

}



8.3 – Addition of New Packet

Listing 8.3 shows the declaration of a new packet type, “TSPPacket” that can be implemented in NS as PT_TSP.  It defines the Packet header, which contains the data to be received or sent and an offset.


Listing 8.3 – Declaration of TSPPacket.

//Filename: tsppacket.h

#ifndef TSPPACKET_H_

#define TSPPACKET_H_


#include "packet.h"

//Structure to define the packet header

struct hdr_TSPHeader {

int myData;

int &getMyData() { return myData; }


// necessary for access the data

static int offset_;

inline static int& offset() { return offset_; }

inline static hdr_TSPHeader* access(const Packet* p) {

return (hdr_TSPHeader*) p->access(offset_);

}

};


#endif /*CLUSTERINGPACKET_H_*/



Listing 8.4 implements the packet structure and implements the functions that can access the data.

 

Listing 8.4 – Implementation of Packet Structure

//filename: TSPPacket.cc

#include "TSPPacket.h"

static class TSPHeaderClass : public PacketHeaderClass {

public:

TSPHeaderClass() :

//the name of the header that is supplied as OTCL command

PacketHeaderClass("PacketHeader/TSPHeader",sizeof(hdr_TSPHeader)) {

bind_offset(&hdr_TSPHeader::offset_);

}

} classTSPHeader;


int hdr_TSPHeader::offset_;


To compile all the above files in NS2

  • Put all the files in ~ns-2.35/newpkt/

  • Open the ~ns-2.35/Makefile.in and make an entry in the OBJ_CC variable as given below

    • newpkt/TSPAgent.o newpkt/TSPPacket.o \

  • Make an entry in the ~ns-2.35/common/packet.h about the packet type as given below.

    • static const packet_t PT_TSP = 73;

    • static packet_t       PT_NTYPE = 74; // This MUST be the LAST one

    • There are total 73 packet types that are already supported in ns2 and if we want to add a new packet it has to be added at the end with a number incremented. So, after adding our packet, the last packet value is 74. Older NS2 version different syntax for adding the new packet types. Refer [1] for more information.

    • name_[PT_TSP]="TSPHeader";

    • name_[PT_NTYPE]= "undefined";

  • Also, there is a binding variable called value_, the value of value_ has to be set in the ~ns-2.35/tcl/lib/ns-default.tcl, go to the end of the line and paste this line

    • Agent/TSPAgent set value_ 0  (if this line is not set, then a warning will be reported during the interpretation of Tcl)

  • Open the terminal and go to ~ns-2.35/  and execute the following for recompiling ns2

    • ./configure

    • make

Once make is done, the codes above will be compiled and generate the object files and now its time to test our code (new agent and new packet)


Listing 8.5 – Otcl script to test the TSPAgent

set myAgent_ [new "Agent/TSPAgent"]

$myAgent_ set value_ 42

puts [$myAgent_ set value_ ]

puts Hello

$myAgent_ ping


The output of the above script will be

42

Hello

Your Message is Received


The following Listing 8.6 shows the Otcl code to test the new Packet and new Agent by testing it on a Wireless adhoc network


Listing 8.6 – Otcl code to test the TSPPacket and TSPAgent

set val(chan)           Channel/WirelessChannel

set val(prop)           Propagation/TwoRayGround

set val(netif)          Phy/WirelessPhy

set val(ant)            Antenna/OmniAntenna

set val(macLayer)       Mac ; #Medium Access Control

set val(ifq)            Queue/DropTail

set val(lenIfq)         50

set val(linkLayer)      LL

set val(routing)        DSDV ; //Routing protocol

set val(agent) Agent/TSPAgent ; #Calling new Agent

set val(nn) 50  //Number of nodes

set val(x) 500

set val(y) 500


#creation of New Simulator with a wireless channel

set ns         [new Simulator]

set chan [new $val(chan)]

set topo [new Topography]


#Open file for tracing

set tracefd     [open "trace.tr" w]

$ns trace-all $tracefd


#open file for animation

set namtrace [open "nam.nam" w]

$ns namtrace-all-wireless $namtrace $val(x) $val(y)


#create god object

set god [create-god $val(nn)]


# create topology object

$topo load_flatgrid $val(x) $val(y)


# node configuration as per the initial values set in the beginning

$ns node-config \

-adhocRouting $val(routing) \

-llType $val(linkLayer) \

-macType $val(macLayer) \

-ifqType $val(ifq) \

-ifqLen $val(lenIfq) \

-antType $val(ant) \

-propType $val(prop) \

-phyType $val(netif) \

-topoInstance $topo \

-channel $chan \

-agentTrace OFF \

-routerTrace OFF \

-macTrace OFF \

-movementTrace OFF


//Creation of nodes

for {set i 0} {$i < $val(nn)} {incr i} {

set node_($i) [$ns node]


# disable random motion

$node_($i) random-motion 0


# register node.

$god new_node $node_($i)


# initial node position

$ns initial_node_pos $node_($i) 10


# init agent

set agent_($i) [new $val(agent)]

# attach agent to node.

$node_($i) attach $agent_($i)

}

 

#creation of random location of nodes.

set rand [new RNG]

for {set j 0} {$j < $val(nn) } {incr j} {

set randX [$rand uniform 0 $val(x)];

set randY [$rand uniform 0 $val(y)];

$node_($j) set X_ $randX

$node_($j) set Y_ $randY

$node_($j) set Z_ 0.000000000000

}


# schedule

$ns at 20 "$agent_(0) sendTo -1"  ;# at 20.0 the sendTo Command is sent.

$ns at 40 "$ns halt"


# start simulation

$ns run;


$ns flush-trace

close $tracefd


The output for the above script is given below

num_nodes is set 50

INITIALIZE THE LIST xListHead

channel.cc:sendUp - Calc highestAntennaZ_ and distCST_

highestAntennaZ_ = 1.5,  distCST_ = 550.0

SORTING LISTS ...DONE!

Agent 45 receives packet with value 75 from Agent 0

Agent 38 receives packet with value 75 from Agent 0

Agent 26 receives packet with value 75 from Agent 0

Agent 9 receives packet with value 75 from Agent 0

Agent 20 receives packet with value 75 from Agent 0

Agent 16 receives packet with value 75 from Agent 0

Agent 40 receives packet with value 75 from Agent 0

Agent 12 receives packet with value 75 from Agent 0

Agent 47 receives packet with value 75 from Agent 0

Agent 31 receives packet with value 75 from Agent 0

Agent 7 receives packet with value 75 from Agent 0

Agent 13 receives packet with value 75 from Agent 0

Agent 39 receives packet with value 75 from Agent 0

Agent 48 receives packet with value 75 from Agent 0

Agent 41 receives packet with value 75 from Agent 0

Agent 27 receives packet with value 75 from Agent 0

Agent 46 receives packet with value 75 from Agent 0

Agent 43 receives packet with value 75 from Agent 0


8.4 Adding a New Protocol

NS2 by default supports a huge number of routing protocols, network protocols, power-aware protocols, etc. But at times, we may need our own protocol to be implemented and tested in a simulator. NS2 supports the addition of a new protocol.


The addition of a new protocol in NS2 involves the following.

  • Implementation of a specific packet type in which the protocol is defined,

  • actual protocol implementation

  • any other information like logs, routing table, etc.

The following case study implements the OLSR (Optimised Link State Routing) protocol as applicable to wireless networks in NS2.

The readers are advised to learn more about the OLSR through the www.ietf.org

This topic is intended for the addition of any protocol (in case we take it as OLSR) and not the discussion of the OLSR protocol. However, here are the features of the OLSR protocol

  • It is a wireless network protocol

  • Proactive & Table-driven

  • Link State Routing

  • Utilises a technique to reduce message flooding using MultiPoint Relaying (MPR)

  • Each node

    • expands a spanning tree

    • can obtain the whole network topology

    • periodically updates the status of its links

    • Re-broadcasts link-state information received from its neighbours

    • Keeps track of link state information received from other nodes

    • uses the above information to determine the next hope for each destination


There are three main modules

  • Neighbour/link sensing

    • Provide topology information up to two hops

    • MPR selector information notification

      • (“A select B as A’s MPR” in HELLO message to B)

    • Multi-point Relaying (MPR) is a technique

      • Every node keeps a table of routes to all known destinations through its MPR nodes

      • Every node periodically broadcasts a list of its MPR Selectors (instead of the whole list of neighbours).

      • Upon receipt of MPR information, each node recalculates and updates routes to each known destination

  • Optimised flooding/forwarding

    • MPR set to cover all the two-hop neighbours

    • MPR selector set: a set of nodes that select me as one of their MPR set

    • OLSR messages from the MPR selector set are to be forwarded

  • Link-State messaging and route calculation

    • Topology table

    • Route table

      • Each node maintains a routing table to all known destinations in the network

      • The routing table is calculated from the Topological Table, taking the connected pairs

      • Routing table:

        • Destination address

        • Next Hop address

        • Distance

    • Routing Table is recalculated after every change in neighbourhood table or in topological table


Implementation of OLSR

List of Files. (The CD associated with this book carries the Code; readers are asked to download it also from [10]).

The header files

  • OLSR.h (contains the agent related declaration)

  • OLSR_pkt.h,  (packet level classes)

  • OLSR_printer.h (printer related functions)

  • OLSR_repositories.h  (related data structures)

  • OLSR_rtable.h  (Routing Table)

  • OLSR_state.h (consists of the state of the node)

The C Source Files (the actual implementation of the OLSR protocol)

  • OLSR.cc (implementation of the agent and other related classes)

  • OLSR_printer.cc

  • OLSR_rtable.cc

  • OLSR_state.cc


The OLSR Agent Otcl Class

Listing 8.7 – snapshot of an OLSR Agent

static class OLSRClass: public TclClass {

public:

OLSRClass() : TclClass("Agent/OLSR") {}

TclObject* create(int argc, const char*const* argv) {

assert(argc == 5);

return new OLSR((nsaddr_t)Address::instance().str2addr(argv[4]));

}

} class_rtProtoOLSR;


Listing 8.8 – OLSR OTCL Example

set opt(chan) Channel/WirelessChannel ; # Wireless Channel type

set opt(prop) Propagation/TwoRayGround ; # radio-propagation model

set opt(netif) Phy/WirelessPhy ; # network interface type

set opt(mac) Mac/802_11 ; # MAC type

set opt(ifq) Queue/DropTail/PriQueue ; # interface queue type

set opt(ll) LL ; # link layer type

set opt(ant) Antenna/OmniAntenna ; # antenna model

set opt(ifqlen) 50 ; # max packet in queue

set opt(nn) 5 ; # number of mobilenodes

set opt(adhocRouting) OLSR ; # OLSR protocol

set opt(cp) "" ; # no connection pattern file

set opt(sc) "" ; # No node movement file.

set opt(x) 500 ; # 500m x axis

set opt(y) 500 ; # 500m y axis

set opt(seed) 0.0 ; # seed value

set opt(stop) 45 ; # stopping the simulation

set opt(cbr-start) 30.0


# check for random seed

if {$opt(seed) > 0} {

puts "Seeding Random number generator with $opt(seed)\n"

ns-random $opt(seed)

}


#create a new simulator

set ns_ [new Simulator]


#

#Setting the OLSR default parameters, this value can also be set at ns-default.tcl

Agent/OLSR set use_mac_ true


#opening a file for tracing and nam trace

set tracefd [open olsr.tr w]

set namtrace [open olsr.nam w]

$ns_ trace-all $tracefd

$ns_ namtrace-all-wireless $namtrace $opt(x) $opt(y)


#create topology in flatgrid

set topo [new Topography]

$topo load_flatgrid $opt(x) $opt(y)

create-god $opt(nn)


#create a new wireless channel

set chan_1_ [new $opt(chan)]


#node configuration

$ns_ node-config -adhocRouting $opt(adhocRouting) \

-llType $opt(ll) \

-macType $opt(mac) \

-ifqType $opt(ifq) \

-ifqLen $opt(ifqlen) \

-antType $opt(ant) \

-propType $opt(prop) \

-phyType $opt(netif) \

-channel $chan_1_ \

-topoInstance $topo \

-wiredRouting OFF \

-agentTrace ON \

-routerTrace ON \

-macTrace OFF

#creating the nodes

for {set i 0} {$i < $opt(nn)} {incr i} {

set node_($i) [$ns_ node]

}


# Setting the size of the node

for {set i 0} {$i < $opt(nn)} {incr i} {

$ns_ initial_node_pos $node_($i) 20

}


#initial position of the nodes

$node_(0) set X_ 350.0

$node_(0) set Y_ 200.0

$node_(0) set Z_ 0.0

$node_(1) set X_ 200.0

$node_(1) set Y_ 350.0

$node_(1) set Z_ 0.0

$node_(2) set X_ 200.0

$node_(2) set Y_ 550.0

$node_(2) set Z_ 0.0

$node_(3) set X_ 50.0

$node_(3) set Y_ 200.0

$node_(3) set Z_ 0.0

$node_(4) set X_ 200.0

$node_(4) set Y_ 50.0

$node_(4) set Z_ 0.0


# setup UDP connection

set udp [new Agent/UDP]

set null [new Agent/Null]

$ns_ attach-agent $node_(0) $udp

$ns_ attach-agent $node_(2) $null

$ns_ connect $udp $null

set cbr [new Application/Traffic/CBR]

$cbr set packetSize_ 512

$cbr set rate_ 20Kb

$cbr attach-agent $udp

$ns_ at $opt(cbr-start) "$cbr start"


#

# print (in the trace file) routing table and other internal data structures on a per-node basis

# The following node (0) and prints the parameters in the trace file.


$ns_ at 10.0 "[$node_(0) agent 255] print_rtable"

$ns_ at 15.0 "[$node_(0) agent 255] print_linkset"

$ns_ at 20.0 "[$node_(0) agent 255] print_nbset"

$ns_ at 25.0 "[$node_(0) agent 255] print_nb2hopset"

$ns_ at 30.0 "[$node_(0) agent 255] print_mprset"

$ns_ at 35.0 "[$node_(0) agent 255] print_mprselset"

$ns_ at 40.0 "[$node_(0) agent 255] print_topologyset"

#

# source connection-pattern and node-movement scripts

#

if { $opt(cp) == "" } {

puts "*** NOTE: no connection pattern specified."

set opt(cp) "none"

} else {

puts "Loading connection pattern..."

source $opt(cp)

}

if { $opt(sc) == "" } {

puts "*** NOTE: no scenario file specified."

set opt(sc) "none"

} else {

puts "Loading scenario file..."

source $opt(sc)

puts "Load complete..."

}



# Tell all nodes when the simulation ends


for {set i 0} {$i < $opt(nn) } {incr i} {

$ns_ at $opt(stop) "$node_($i) reset";

}

$ns_ at $opt(stop) "puts \"NS EXITING...\" ; $ns_ halt"

$ns_ at $opt(stop) "stop"


proc stop {} {

global ns_ tracefd namtrace

$ns_ flush-trace

close $tracefd

close $namtrace

}

puts "Starting Simulation..."

$ns_ run


The output can be verified in the trace file generated, Node (0)  details

Routing Table

P 10.000000 _0_ Routing Table

P dest next iface dist

P 1 1 0 1

P 2 1 0 2

P 3 4 0 2

P 4 4 0 1


Link Set

P 15.000000 _0_ Link Set

P local nb sym asym lost time

P 0 1 20.671089 20.671089 0.000000 26.671089

P 0 4 19.445169 19.445169 0.000000 25.445169


Neighbor Set

P 20.000000 _0_ Neighbor Set

P nb status willingness

P 1 1 3

P 4 1 3


Neighbor2hop Set

P 25.000000 _0_ Neighbor2hop Set

P nb nb2hop time

P 1 2 29.610521

P 1 3 29.610521

P 4 3 30.091939


MPR Set

P 30.000000 _0_ MPR Set

P nb

P 1


MPR Selector Set

P 35.000000 _0_ MPR Selector Set

P nb time

P 1 40.008076

P 4 40.165949


Topology Set

P 40.000000 _0_ Topology Set

P dest last seq time

P 0 1 2 52.864873

P 2 1 2 52.864873

P 3 1 2 52.864873


Installation of OLSR protocol in NS2.

Step 1: Copy all the files in the ~ns-2.35/olsr folder

Step 2: Make an entry in the ~ns-2.35/Makefile.in as given below in the OBJ_CC variable

olsr/OLSR.o olsr/OLSR_state.o olsr/OLSR_rtable.o olsr/OLSR_printer.o \

Step 3: Apply the patch file to the corresponding NS version, using the command given below

patch -p1 < olsr/um-olsr_ns-2.35_v1.0.patch  

(For the patch to work successfully, patch it when a fresh installation of the ns-allinone-2.35 package is installed)

Step 4: Once the patching is done, execute the following commands

./configure

make

If the patch is not working, refer to the website http://www.nsnam.com for more detailed instructions.


Conclusion

This chapter deals with the simulation of various other protocols, agents, applications, etc. This chapter implements the addition of a new agent, a new protocol, a new packet and their application to run under a wireless network. This also briefs and describes the OLSR (Optimised Link State Routing) protocol to measure the routing performance metrics using a trace file.


Comments

Popular posts from this blog

Installing ns3 in Ubuntu 22.04 | Complete Instructions

In this post, we are going to see how to install ns-3.36.1 in Ubuntu 22.04. You can follow the video for complete details Tools used in this simulation: NS3 version ns-3.36.1  OS Used: Ubuntu 22.04 LTS Installation of NS3 (ns-3.36.1) There are some changes in the ns3 installation procedure and the dependencies. So open a terminal and issue the following commands Step 1:  Prerequisites $ sudo apt update In the following packages, all the required dependencies are taken care and you can install all these packages for the complete use of ns3. $ sudo apt install g++ python3 python3-dev pkg-config sqlite3 cmake python3-setuptools git qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython3 openmpi-bin openmpi-common openmpi-doc libopenmpi-dev autoconf cvs bzr unrar gsl-bin libgsl-dev libgslcblas0 wireshark tcpdump sqlite sqlite3 libsqlite3-dev  libxml2 libxml2-dev libc6-dev libc6-dev-i386 libc...

Installation of NS2 in Ubuntu 22.04 | NS2 Tutorial 2

NS-2.35 installation in Ubuntu 22.04 This post shows how to install ns-2.35 in Ubuntu 22.04 Operating System Since ns-2.35 is too old, it needs the following packages gcc-4.8 g++-4.8 gawk and some more libraries Follow the video for more instructions So, here are the steps to install this software: To download and extract the ns2 software Download the software from the following link http://sourceforge.net/projects/nsnam/files/allinone/ns-allinone-2.35/ns-allinone-2.35.tar.gz/download Extract it to home folder and in my case its /home/pradeepkumar (I recommend to install it under your home folder) $ tar zxvf ns-allinone-2.35.tar.gz or Right click over the file and click extract here and select the home folder. $ sudo apt update $ sudo apt install build-essential autoconf automake libxmu-dev gawk To install gcc-4.8 and g++-4.8 $ sudo gedit /etc/apt/sources.list make an entry in the above file deb http://in.archive.ubuntu.com/ubuntu/ bionic main universe $ sudo apt update Since, it...

Simulation of URDF, Gazebo and Rviz | ROS Noetic Tutorial 8

Design a User-defined robot of your choice (or you can use the URDF file) and enable the LIDAR Scanner so that any obstacle placed on the path of the light scan will cut the light rays. Visualize the robot in the Gazebo workspace, and also show the demonstration in RViz.   (NB: Gain knowledge on wiring URDF file and .launch file for enabling any user-defined robot to get launched in the gazebo platform.) SLAM : One of the most popular applications of ROS is SLAM(Simultaneous Localization and Mapping). The objective of the SLAM in mobile robotics is to construct and update the map of an unexplored environment with the help of the available sensors attached to the robot which will be used for exploring. URDF: Unified Robotics Description Format, URDF, is an XML specification used in academia and industry to model multibody systems such as robotic manipulator arms for manufacturing assembly lines and animatronic robots for amusement parks. URDF is especially popular with users of the ...