To implement the ODMRP (On-Demand Multicast Routing Protocol) in OMNeT++, we have to simulate a models that replicates the actions of ODMRP. Efficient and robust multicast routing is supported by wireless ad-hoc network which is implemented by ODMRP.
Here’s a step-by-step guide to help you implement the ODMRP protocol in OMNeT++ using the INET framework.
Step-by-Step Implementation:
Step 1: Set Up OMNeT++ and INET Framework
Step 2: Define the ODMRP Protocol
Generate the necessary .ned and C++ files for the ODMRP protocol module.
Define the Module in .ned File
For ODMRP module, we have create a .ned file.
simple ODMRP
{
parameters:
@display(“i=block/cogwheel”);
double queryInterval @unit(s) = default(10s); // Interval for sending join query messages
double routeLifetime @unit(s) = default(30s); // Lifetime for routes
gates:
input fromNetworkLayer;
output toNetworkLayer;
input fromMacLayer;
output toMacLayer;
}
Implement the Module in C++
Create the corresponding .cc and .h files.
ODMRP.h
#ifndef __ODMRP_H_
#define __ODMRP_H_
#include <omnetpp.h>
#include <map>
#include <set>
#include “inet/common/INETDefs.h”
#include “inet/networklayer/contract/IRoutingTable.h”
#include “inet/networklayer/contract/IInterfaceTable.h”
#include “inet/networklayer/common/L3Address.h”
#include “inet/networklayer/common/L3AddressResolver.h”
using namespace omnetpp;
using namespace inet;
class ODMRP : public cSimpleModule
{
private:
double queryInterval;
double routeLifetime;
IRoutingTable *routingTable;
IInterfaceTable *interfaceTable;
cMessage *queryMsg;
std::map<L3Address, simtime_t> multicastGroupTable; // Stores multicast group information
std::set<L3Address> forwarderTable; // Stores forwarder nodes
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
void sendJoinQuery();
void processJoinQuery(cPacket *packet);
void processJoinReply(cPacket *packet);
void handleUpperLayerPacket(cPacket *packet);
void handleLowerLayerPacket(cPacket *packet);
public:
ODMRP();
virtual ~ODMRP();
};
#endif
ODMRP.cc
#include “ODMRP.h”
Define_Module(ODMRP);
ODMRP::ODMRP()
{
queryMsg = nullptr;
}
ODMRP::~ODMRP()
{
cancelAndDelete(queryMsg);
}
void ODMRP::initialize()
{
queryInterval = par(“queryInterval”);
routeLifetime = par(“routeLifetime”);
routingTable = getModuleFromPar<IRoutingTable>(par(“routingTableModule”), this);
interfaceTable = getModuleFromPar<IInterfaceTable>(par(“interfaceTableModule”), this);
queryMsg = new cMessage(“sendJoinQuery”);
scheduleAt(simTime() + queryInterval, queryMsg);
}
void ODMRP::handleMessage(cMessage *msg)
{
if (msg == queryMsg)
{
sendJoinQuery();
scheduleAt(simTime() + queryInterval, queryMsg);
}
else if (msg->arrivedOn(“fromNetworkLayer”))
{
handleUpperLayerPacket(check_and_cast<cPacket *>(msg));
}
else if (msg->arrivedOn(“fromMacLayer”))
{
cPacket *packet = check_and_cast<cPacket *>(msg);
if (strcmp(packet->getName(), “JoinQuery”) == 0)
{
processJoinQuery(packet);
}
else if (strcmp(packet->getName(), “JoinReply”) == 0)
{
processJoinReply(packet);
}
else
{
handleLowerLayerPacket(packet);
}
}
else
{
delete msg;
}
}
void ODMRP::sendJoinQuery()
{
cPacket *queryPacket = new cPacket(“JoinQuery”);
queryPacket->addPar(“srcAddr”) = interfaceTable->getInterface(0)->getIpv4Address().str().c_str();
send(queryPacket, “toMacLayer”);
}
void ODMRP::processJoinQuery(cPacket *packet)
{
L3Address srcAddr = L3AddressResolver().resolve(packet->par(“srcAddr”).stringValue());
if (forwarderTable.find(srcAddr) == forwarderTable.end())
{
forwarderTable.insert(srcAddr);
cPacket *replyPacket = new cPacket(“JoinReply”);
replyPacket->addPar(“srcAddr”) = srcAddr.str().c_str();
send(replyPacket, “toMacLayer”);
}
delete packet;
}
void ODMRP::processJoinReply(cPacket *packet)
{
L3Address srcAddr = L3AddressResolver().resolve(packet->par(“srcAddr”).stringValue());
multicastGroupTable[srcAddr] = simTime() + routeLifetime;
delete packet;
}
void ODMRP::handleUpperLayerPacket(cPacket *packet)
{
L3Address destAddr = L3AddressResolver().resolve(packet->par(“destAddr”).stringValue());
if (multicastGroupTable.find(destAddr) != multicastGroupTable.end())
{
send(packet, “toMacLayer”);
}
else
{
delete packet;
}
}
void ODMRP::handleLowerLayerPacket(cPacket *packet)
{
L3Address destAddr = L3AddressResolver().resolve(packet->par(“destAddr”).stringValue());
if (multicastGroupTable.find(destAddr) != multicastGroupTable.end())
{
send(packet, “toNetworkLayer”);
}
else
{
delete packet;
}
}
Step 3: Integrate with Simulation Model
In the network simulation model, we have to integrate the ODMRP module.
Network Configuration .ned File
Create a .ned file to state the network topology.
network ODMRPNetwork
{
parameters:
@display(“bgb=600,400”);
submodules:
node1: StandardHost {
parameters:
@display(“p=100,200”);
}
node2: StandardHost {
parameters:
@display(“p=300,200”);
}
node3: StandardHost {
parameters:
@display(“p=500,200”);
}
connections:
node1.pppg++ <–> Eth10M <–> node2.pppg++;
node2.pppg++ <–> Eth10M <–> node3.pppg++;
node1.pppg++ <–> Eth10M <–> node3.pppg++;
}
Step 4: Configure the Simulation
Configure the simulation parameters in the omnetpp.ini file.
network = ODMRPNetwork
*.node*.pppg[*].queue.typename = “DropTailQueue”
*.node*.ipv4.routingTable = “inet.networklayer.routing.manet.Router”
*.node*.networkLayer.networkProtocol.typename = “Ipv4NetworkLayer”
*.node*.transportLayer.tcp.typename = “Tcp”
*.node*.transportLayer.udp.typename = “Udp”
*.node*.application[*].typename = “UdpBasicApp”
*.node*.application[*].destAddresses = “node1” // Set destination as needed
*.node*.application[*].destPort = 2000
*.node*.application[*].startTime = uniform(0s, 10s)
*.node*.application[*].sendInterval = uniform(1s, 2s)
*.node*.application[*].packetLength = 512B
*.node1.app[0].typename = “ODMRP”
*.node2.app[0].typename = “ODMRP”
*.node3.app[0].typename = “ODMRP”
Step 5: Test and Debug
In this demonstration, we can utterly understood the basic set up and how to implement the ODMRP protocols in OMNeT++ using the INET framework. We will provide any additional implementation of this topic, if needed for your research.