Implementing OSI layer protocol in ns3 requires to follow several steps like we used in implementing other protocols in ns3. These steps incorporate defining the protocol, integrating the protocol with ns3 frame work and testing it.
Now let’s dive into the steps for implementing a generic OSI protocol layer in ns3.
Steps to implement OSI protocol layer in ns3
- Set up your environment
Make sure that ns3 is installed in the computer. If not, install it from the official ns3 website. Navigate to the src directory where you want to add your protocol.
- Create a new protocol class
Add two files named my-osi-protocol.h and my-osi-protocol.cc in the new directory of your protocol (eg., src/my-osi-protocol/).
my-osi-protocol.h header file defines the structure and methods of your protocol class.
#ifndef MY_OSI_PROTOCOL_H
#define MY_OSI_PROTOCOL_H
#include “ns3/application.h”
#include “ns3/address.h”
#include “ns3/socket.h”
#include “ns3/event-id.h”
#include “ns3/traced-callback.h”
namespace ns3 {
class MyOsiProtocol : public Application {
public:
static TypeId GetTypeId (void);
MyOsiProtocol ();
virtual ~MyOsiProtocol ();
protected:
virtual void StartApplication (void); // Called at time specified by Start
virtual void StopApplication (void); // Called at time specified by Stop
private:
void HandleRead (Ptr<Socket> socket);
Ptr<Socket> m_socket;
Address m_peerAddress;
uint16_t m_peerPort;
EventId m_sendEvent;
bool m_running;
uint32_t m_packetSize;
uint32_t m_nPackets;
uint32_t m_packetsSent;
};
} // namespace ns3
#endif // MY_OSI_PROTOCOL_H
my-osi-protocol.cc
This implementation file defines the behavior of your protocol class.
#include “my-osi-protocol.h”
#include “ns3/log.h”
#include “ns3/simulator.h”
#include “ns3/uinteger.h”
#include “ns3/packet.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“MyOsiProtocol”);
NS_OBJECT_ENSURE_REGISTERED (MyOsiProtocol);
TypeId
MyOsiProtocol::GetTypeId (void)
{
static TypeId tid = TypeId (“ns3::MyOsiProtocol”)
.SetParent<Application> ()
.SetGroupName(“Tutorial”)
.AddConstructor<MyOsiProtocol> ()
.AddAttribute (“PeerAddress”, “The destination Address of the outbound packets”,
AddressValue (),
MakeAddressAccessor (&MyOsiProtocol::m_peerAddress),
MakeAddressChecker ())
.AddAttribute (“PeerPort”, “The destination port of the outbound packets”,
UintegerValue (9),
MakeUintegerAccessor (&MyOsiProtocol::m_peerPort),
MakeUintegerChecker<uint16_t> ())
.AddAttribute (“PacketSize”, “Size of packets generated”,
UintegerValue (1024),
MakeUintegerAccessor (&MyOsiProtocol::m_packetSize),
MakeUintegerChecker<uint32_t> ())
.AddAttribute (“NPackets”, “Number of packets generated”,
UintegerValue (1),
MakeUintegerAccessor (&MyOsiProtocol::m_nPackets),
MakeUintegerChecker<uint32_t> ())
.AddAttribute (“Interval”, “Time between packets”,
TimeValue (Seconds (1.0)),
MakeTimeAccessor (&MyOsiProtocol::m_interval),
MakeTimeChecker ());
return tid;
}
MyOsiProtocol::MyOsiProtocol ()
: m_socket (0),
m_peerAddress (),
m_peerPort (0),
m_sendEvent (),
m_running (false),
m_packetSize (0),
m_nPackets (0),
m_packetsSent (0)
{
NS_LOG_FUNCTION (this);
}
MyOsiProtocol::~MyOsiProtocol ()
{
NS_LOG_FUNCTION (this);
m_socket = 0;
}
void
MyOsiProtocol::StartApplication (void)
{
NS_LOG_FUNCTION (this);
m_running = true;
m_packetsSent = 0;
m_socket = Socket::CreateSocket (GetNode (), TypeId::LookupByName (“ns3::UdpSocketFactory”));
m_socket->Bind ();
m_socket->Connect (InetSocketAddress (Ipv4Address::ConvertFrom(m_peerAddress), m_peerPort));
m_socket->SetRecvCallback (MakeCallback (&MyOsiProtocol::HandleRead, this));
SendPacket ();
}
void
MyOsiProtocol::StopApplication (void)
{
NS_LOG_FUNCTION (this);
m_running = false;
if (m_sendEvent.IsRunning ())
{
Simulator::Cancel (m_sendEvent);
}
if (m_socket)
{
m_socket->Close ();
}
}
void
MyOsiProtocol::SendPacket (void)
{
NS_LOG_FUNCTION (this);
Ptr<Packet> packet = Create<Packet> (m_packetSize);
m_socket->Send (packet);
if (++m_packetsSent < m_nPackets)
{
ScheduleTx ();
}
}
void
MyOsiProtocol::ScheduleTx (void)
{
NS_LOG_FUNCTION (this);
if (m_running)
{
m_sendEvent = Simulator::Schedule (Seconds (1.0), &MyOsiProtocol::SendPacket, this);
}
}
void
MyOsiProtocol::HandleRead (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this);
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom (from)))
{
if (packet->GetSize () == 0)
{ // EOF
break;
}
NS_LOG_INFO (“At time ” << Simulator::Now ().GetSeconds () << “s packet received from ” << InetSocketAddress::ConvertFrom (from).GetIpv4 ());
}
}
} // namespace ns3
- Integrate with ns3
To include your new protocol, modify the wscript in the src directory and to ensure that your new files are compiled, add the following lines :
wscript
def build(bld):
…
bld.ns3_add_library(‘my-osi-protocol’,
[‘my-osi-protocol.cc’])
…
- Testing and validation
In the scratch directory, create a simulation script to test your new protocol :
scratch/test-my-osi-protocol.cc
#include “ns3/core-module.h”
#include “ns3/network-module.h”
#include “ns3/internet-module.h”
#include “ns3/point-to-point-module.h”
#include “ns3/my-osi-protocol.h”
using namespace ns3;
int main (int argc, char *argv[]) {
CommandLine cmd;
cmd.Parse (argc, argv);
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));
pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase (“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer interfaces = address.Assign (devices);
uint16_t port = 9;
Address serverAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
Ptr<MyOsiProtocol> serverApp = CreateObject<MyOsiProtocol> ();
serverApp->SetAttribute (“PeerAddress”, AddressValue (Ipv4Address (“10.1.1.2”)));
serverApp->SetAttribute (“PeerPort”, UintegerValue (port));
nodes.Get (0)->AddApplication (serverApp);
serverApp->SetStartTime (Seconds (1.0));
serverApp->SetStopTime (Seconds (10.0));
Ptr<MyOsiProtocol> clientApp = CreateObject<MyOsiProtocol> ();
clientApp->SetAttribute (“PeerAddress”, AddressValue (Ipv4Address (“10.1.1.1”)));
clientApp->SetAttribute (“PeerPort”, UintegerValue (port));
nodes.Get (1)->AddApplication (clientApp);
clientApp->SetStartTime (Seconds (2.0));
clientApp->SetStopTime (Seconds (10.0));
Simulator::Stop (Seconds (10.0));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
- Build and run the simulation
Build and run your script after writing.
./waf configure
./waf build
./waf –run scratch/ test-my-osi-protocol
Explanation of the code
- Header file (my-osi-protocol.h) :
The MyOsiProtocol class is defined by inheriting from Application.
For starting and stopping the application, sending packets, scheduling transmissions, and handling received packets, it declares methods.
- Implementation file (my-osi-protocol.cc) :
The constructor and destructor are implemented.
For type identification, implements the GetTypeId method.
For starting and stopping the application, sending packets, scheduling transmissions, and handling received packets, it declares methods.
- Testing script (test–my-osi-protocol.cc) :
Sets up a basic network with two nodes connected by a point-to-point link.
Internet stacks are installed.
To the interfaces, IP addresses are assigned.
The custom protocol are configured as both a server and a client on different nodes and schedules the simulation to run for 10 seconds.
Overall, we had learned on implementing OSI layer protocol in ns3 by defining the protocol, integrating it with the ns-3 framework, and testing it. Also, we provide more related information on OSI protocol.
Some may find hard in implementing a generic OSI protocol layer in ns3 if you face tough times then get in touch with us.