Using QualNet – Part II
Adding a Custom Protocol
QualNet’s Directory Structure
Directory
addons
bin
contributed
data
documentation
gui
include
interfaces
kernel
lib
libraries
license_dir
main
scenarios
Contains
Components developed as custom addons for specific customers
Executable and other runtime files such as DLLs
Models contributed by QualNet customers.
Data files for the Wireless library: antenna configurations, modulation schemes and sample terrain
User Guide, release notes, etc.
Graphical components including icons, Java class files, and GUI configuration.
QualNet kernel header files.
Code to interface QualNet to 3rd party tools or external networks, such as HLA, STK, or IP
networks.
QualNet kernel objects used during the build process.
Q
g
j
p
3rd party software libraries used during the build process.
Source code for model libraries such as Developer, Multimedia & Enterprise, & Wireless.
License files and license libraries required for the build process.
Kernel source files and Makefiles.
Sample scenarios.
2
QualNet Layered Architecture
The simulation is a collection of network nodes, each
with its own protocol stack parameters and statistics
accessible from the “Node” structure
accessible from the Node structure
File include/node.h
General node’s info
Struct Node {
:
:
:
:
};
nodeId; /* the user-specified node identifier */
NodeAddress
Int32 globalSeed; /* seed for random number generator */
Int32 numNodes; /* number of nodes in the simulation */
/* Layer-specific information for the node. */
MacData** macData; // MAC layer
M D t **
MacSwitch* switchData; // MAC switch
NetworkData
TransportData
AppData
:
networkData; // network layer
transportData; // transport layer
appData; // application layer
// MAC l
D t
Layer-specific info
3
Messages, Packets, and Timers
A message is a unit defining an interaction
between protocols and between nodes
File include/message.h
Two types of messages
Packets (data or control) – used for
communication between nodes
Timers – allow protocols to schedule events in
Timers
allow protocols to schedule events in
a future time
4
Message-Related API Functions
MESSAGE_Alloc()
MESSAGE_InfoAlloc()
MESSAGE_PacketAlloc()
MESSAGE_AddHeader()
MESSAGE_RemoveHeader()
Allocate a message and provide it with standard
event, layer, protocol info
Allocate additional user-specified space for
optional information about the event
optional information about the event
Allocate space for the packet within the message
Add a header to the packet (usually called by
each layer in the protocol stack)
Remove a header from the packet
MESSAGE_AddVirtualPayload() Add virtual payload to a Message (increase tx
MESSAGE Duplicate()
MESSAGE_Duplicate()
MESSAGE_Send()
MESSAGE_Free()
delay without increasing array size)
Copy the message including its packet and
Copy the message, including its packet and
user-specified space (info field)
Send the message as an event to the specified
layer and protocol
Free the message, once it has reached its final
destination
5
Packet Life Cycle
Application
MESSAGE_Alloc(…)
MESSAGE_PacketAlloc(…)
MESSAGE_Send(…)
Transport
MESSAGE_AddHeader()
MESSAGE_Send(…)
Application
MESSAGE_Free(…)
Transport
MESSAGE_RemoveHeader()
MESSAGE_Send(…)
Routing
IP
MESSAGE_AddHeader()
MESSAGE_Send(…)
Routing
MAC
MESSAGE_AddHeader()
MESSAGE_Send(…)
IP
MAC
IP
MESSAGE_RemoveHeader()
MESSAGE_Send(…)
MAC
MESSAGE_RemoveHeader()
MESSAGE_Send(…)
Channel
Channel
Channel
6
Creating Messages
Message*
MESSAGE_Alloc(
Node *node
Node *node,
int layerType,
int protocol,
int eventType);
A pointer to the node creating
the message
The stack layer at which this message
will be processed next
e.g., NETWORK_LAYER
The specific protocol at the layer
which will process this message
e.g., ROUTING_PROTOCOL_DSR
The event that this message represents
e.g., MSG_NETWORK_FlushTables
g
p
Message Processing
Handling function
for FlushTables
event
newMsg
FlushTables
CheckReplied
RouteTimeout
Check eventType field
Check eventType field
AODV…
IP
DSR
Check protocolType field
Radio
MAC
Network
Transport
App
Check layerType field
Event queue
msg
7
8
QualNet’s Protocol Modeling
Initialization Function
• Allocate memory for each node’s
local variables
• Initialize local variables
• Process configuration file(s)
• Process configuration file(s)
• Schedule the first event
Packet arrival or
timer expiration
Idle
Finalization Function
• Output statistics
Message (packet or timer)
processing function
• Modify state variables
• Update local statistics
k t
• Generate/forward packets
t /f
G
d
f
f
Adding a Protocol to QualNet
Determine what layer your protocol will
operate at
Implement four/five main functions
Initialization function
Packet/event handling functions
Router function (for routing protocol)
Finalization function
Hook up the above functions to the
protocol dispatching functions of the
corresponding layer
f
9
10
Example: Adding a New Routing Protocol
Simplified Routing Information Protocol
(SRIP)
Table-driven, distance vector protocol
Using periodic route update, no triggered
update, no split horizon
Working properly in static networks with only
)
a small number of nodes (no node failure)
(
Supporting only one interface (wireless) per
node
Distributed Bellman-Ford Algorithm
What local information is maintained by each node?
Routing Table
Destination Next hop
Cost
:
:
:
Initial routing table for A
Destination Next hop
Cost
A
B
:
A
-
-
0
∞
∞
What information is exchanged between neighboring
nodes?
Route Advertisement
Destination
Destination
Cost
Cost
:
:
How a node processes a route advertisement?
Node Aupdates its entry for destination Donly when the
advertised cost to Dis lower than its current cost
11
12
SRIP Header File (routing_srip.h)
#ifndef _SRIP_H_
#define _SRIP_H_
#define SRIP_INFINITY 16
typedef struct srip_table_entry
{
destination;
NodeAddress
NodeAddress
nextHop;
unsigned int distance;
} SripTableEntry;
typedef struct srip_str
{
updateInterval;
clocktype
SripTableEntry* routingTable;
/* statistic */
unsigned int numRouteUpdatesBroadcast;
Routing table entry
Local SRIP variables per nodes
} SripData;
void SripInit(Node* node, SripData** sripPtr,
void SripHandleProtocolEvent(Node* node, Message* msg);
void SripHandleProtocolPacket(Node* node, Message* msg,
void SripFinalize(Node *node);
void SripRouterFunction(Node* node, Message* msg, NodeAddress destAddr,
const NodeInput* nodeInput, int interfaceIndex);
NodeAddress sourceAddress);
NodeAddress previousHopAddress, BOOL* packetWasRouted);
Function prototypes to be recognized
by QualNet’s network layer (IP)
#endif
13
SRIP Initialization Function
Called when each node is initialized by QualNet
void SripInit(Node* node,
SripData** sripPtr,
const NodeInput* nodeInput
const NodeInput nodeInput,
int
interfaceIndex)
{
int i; BOOL retVal;
Message* newMsg;
SripData* srip;
if (MAC_IsWiredNetwork(node, interfaceIndex))
ERROR_ReportError("SRIP supports only wireless interfaces");
if (node->numberInterfaces > 1)
ERROR_ReportError("SRIP only supports one interface of node");
Make sure the node has exactly
one wireless interface
/* allocate memory for SRIP's variables for this node */
srip = (SripData*) MEM_malloc(sizeof(SripData));
(*sripPtr) = srip;
( sripPtr) = srip;
Allocate memory for local SRIP
variables within each node
/* read parameter from the configuration file */
IO_ReadTime(node->nodeId,
ANY_ADDRESS,
nodeInput,
"SRIP-UPDATE-INTERVAL",
&retVal,
&(srip->updateInterval));
if (retVal == FALSE)
ERROR_ReportError("SRIP-UPDATE-INTERVAL not specified!");
Read SRIP parameter
from the main config file
(to be continued)
14
SRIP Initialization Function
(continued)
/* allocate and initialize the routing table for this node */
/* Note: (n+1) entries are allocated for convenience */
srip->routingTable = (SripTableEntry*)
for (i = 1; i <= node->numNodes; i++) {
for (i
1; i < node >numNodes; i++) {
MEM_malloc(sizeof(SripTableEntry)*(node->numNodes+1));
srip->routingTable[i].destination = i;
srip->routingTable[i].nextHop
srip->routingTable[i].distance = SRIP_INFINITY;
= INVALID_ADDRESS;
}
srip->routingTable[node->nodeId].nextHop
srip->routingTable[node->nodeId].distance = 0;
= node->nodeId;
/* Initialize statistic */
srip->numRouteUpdatesBroadcast = 0;
/* Tell IP to use our function to route packets */
NetworkIpSetRouterFunction(node,
&SripRouterFunction,
interfaceIndex);
ROUTING_PROTOCOL_SRIP, MSG_NETWORK_RTBroadcastAlarm);
/* schedule the very first route update broadcast */
/* after a random delay of 0 ~ srip->updateInterval-1 */
newMsg = MESSAGE_Alloc(node, NETWORK_LAYER,
RandomSeed startupSeed;
RANDOM_SetSeed(startupSeed, node->globalSeed, node->nodeId,
clocktype delay = RANDOM_nrand(startupSeed)%srip->updateInterval;
MESSAGE_Send(node, newMsg, pc_nrand(node->seed)%srip->updateInterval);
ROUTING_PROTOCOL_SRIP, interface);
}
Initialize routing table
Initialize statistic
Register router
function with IP
Schedule the first route
advertisement timer
15
SRIP Event Handling Function
Called when a node’s timer expires
void SripHandleProtocolEvent(Node* node, Message* msg)
{{
int i, numEntries = 0, pktSize;
Message* newMsg;
char* pktPtr;
/* Obtain a pointer to the local variable space */
SripData* srip = (SripData*)
NetworkIpGetRoutingProtocol(node, ROUTING_PROTOCOL_SRIP);
Obtain pointer to local
variable space
for (i = 1; i <= node->numNodes; i++) {
if (srip->routingTable[i].distance < SRIP_INFINITY)
numEntries++;
Count the number of
valid entries
}
newMsg = MESSAGE_Alloc(node, 0, 0, 0);
pktSize = sizeof(unsigned int) + sizeof(SripTableEntry)*numEntries;
pktSize
sizeof(unsigned int) + sizeof(SripTableEntry) numEntries;
MESSAGE_PacketAlloc(node, newMsg, pktSize, TRACE_ANY_PROTOCOL);
pktPtr = newMsg->packet;
memcpy(pktPtr, &numEntries, sizeof(unsigned int)); /* number of entries */
pktPtr += sizeof(unsigned int);
/* Fill the packet with the valid table entries */
for (i = 1; i <= node->numNodes; i++) {
if (srip->routingTable[i].distance < SRIP_INFINITY) {
memcpy(pktPtr, &(srip->routingTable[i]), sizeof(SripTableEntry));
pktPtr += sizeof(SripTableEntry);
}
}
Prepare a route
advertisement packet
(to be continued)
16