OMNeT++ - Tutorial 3
Brian RicksWireless Network Security
Spring 2014
Where we left off
● Creating / running a simulation– Batch simulations
● More analysis● Chuck Norris
What Now?
● Chuck Norris● Write your own protocol!
– Simple modules● Backing C++● NED
– Passing parameters
– Emitting new statistics
● And a Demo!!
What Now?
● Is this important for HW3?– Yep, and very helpful for HW4
– And for your projects
● Why Chuck Norris?– He scares the bugs
away from Inet
Lets Get Started
Writing a Simple Module
● In the first tutorial, some C++ code was shown for simple modules
● Here, I will go over some stuff you need to know to write your own simple modules
● Then, I will go step by step through some awesome demo code– Chuck Norris is afraid of this code, that is how
awesome it is
First Steps
● Create a new, blank project– Link it with the Inet project
● Create an empty header and source (.cc) files
Creating the header
● All OMNeT++ simple modules inherit cSimpleModule
● Remember to #include <omnetpp.h> and any Inet headers you may need– Inet headers you say?
Inet Developer Laziness
● Why does the Inet source #includes not include the path to headers?– Laziness
● Isn't this sloppy coding?– Yes
Including Inet headers
● Can I also be lazy with my #includes?– Sure, why not?
● How does the compiler know where the headers are when the path is excluded?– opp_makemake –deep
● In terms of Inet, this is run at <inet_root>, with –deep, which tells the makefile maker to make stuff in all child folders
– This also adds to the include path, all these child folders
Including My Own headers
● Can I also be lazy with my #includes?– Sure
– When building from the IDE, --deep is also used, so your own headers can be anywhere within your project folder hierarchy
–
Finding location of Inet headers
● In the IDE, at the #include line:– Double-click the header name
– Right-click, and select 'open declaration'
● Inet source:– <omnet-root>/samples/inet/src
Implementing the class
● Make sure to register your class with OMNeT++ using the following macro:– Define_Module(module_name);
● Notice that module_name is not in quotes
Class Declaration
● In addition to constructor/destructor, you need the following methods (protected):– Initialize();
● This is called when your module is initialized before the simulation starts
– virtual void handleMessage(cMessage *msg);● This is called when a message arrives on some input port
for your module
Implementing the class
● Passing in parameters– This is done in the initialization() method of your
module
– par("address").stringValue()● This will return a const char* of the parameter defined in
the NED as 'address'– These are defined as you would any other parameter, either in a
NED file or the omnetpp.ini
Implementing the class
● Type casting– Use check_and_cast<>
● OMNeT++ wrapper for dynamic_cast<>● If the cast fails, a nice dialog is popped up
– Easier to debug casting issues (and these issues are plentiful if writing your own protocols)
Implementing the class
● Type casting– Too lazy to figure out which message type a higher
layer protocol needs?● Awesome! So am I● Just guess, and when check_and_cast<> fails, the dialog
will tell you the correct type
Implementing the class
● Sending messages– There are two ways to send a message which you
will use often:● send(cMessage *msg, const char* gate_name)
– This will send a message named msg to the output gate specified by gate_name
● scheduleAt (simtime_t t, cMessage *msg)– This will send a self message. This message is put in the
eventqueue and is popped back to the module which send it after t time (simtime).
– These are used to simulate timers and such
Implementing the class
● Messages in general– cMessage contains lots of goodies, such as
timestamp of arrival, which gate it arrived on, whether it is a self message, and many others.
– cPacket is a child of cMessage, and more often than not the message types you will receive when working with Inet will be further subclassed from cPacket
Implementing the class
● Messages in general– When I receive a message through
handleMessage(), who owns it?● You● This means, if you don't plan to send it back out, then
delete it before your method returns.
Implementing the class
● Messages in general– What if I don't want to delete it?
● OMNeT++ will be very angry with you
– Is this a huge deal?● Not really, though you won't be considered a 1337
memory management h4x0r
Implementing the class
● Self messages– What if I need to cancel a self message after
sending it?● cancelEvent(cMessage *msg)
– Make sure you have a pointer to the self message you sent● cancelAndDelete (cMessage *msg)
– This will also delete the message after removing it from the eventqueue
Implementing the class
● Self messages– What if my simulation ends when I have a self
message in the queue, or a self message allocated in general?
● You need to delete that message, or OMNeT++ will be very very angry at you
● Delete the self message using cancelAndDelete()– This way OMNeT++ can remove it from the eventqueue if its
there
Some Runtime Issues
● I'm getting errors about an unconnected gate– This means some module is trying to send a
message on a gate which is unconnected
– The dialog will tell you which module and which gate is not connected.
● Gate connections are done in the NED
Some Runtime Issues
● My simulation says my gate doesn't exist!– That's cause it doesn't :-)
– But no worries, this is usually due to the name of the gate being different in the NED as opposed to what you typed as the send() parameter.
● Either rename the gate in the NED, or rename the parameter you give to send()
Emitting Statistics
● Tutorial went over some basics● The demo will show how simple it is to emit
scalars
Emitting Statistics
● This is not the same thing as the WATCH() macro– WATCH() allows Tkenv to monitor a variable, so
you can check it during GUI-based simulation.
– Emitting statistics allows you to plot stuff after your simulation
Emitting Statistics
● On the C++ side, you register and emit signals● On the NED side, you specify which signals you
want statistics from, and what kind of statistics
Emitting Statistics
● On the NED side:– @statistic[rcvdPk](title="packets received";
record=count,"sum(packetBytes)");● RcvdPk is the name of the signal from the C++ side● title is used for visualization, for example when plotting
(doesn't always work)● record specifies what statistics we want from the signal.
These are given as built-in filters– Here, we want two things:– count, which counts each time the signal is emitted– sum(packetBytes), which is actually two filters, sum and
packetBytes. packetBytes returns the byte length of a message, and sum sums up all packetByte lengths received
Emitting Statistics
● Another way to emit scalars without using NED code:– recordScalar("variable_name", variable);
– Here, you must calculate what you want output at the end of the simulation
– You call this method in your module's finish() method
● Remember what Patrick told you about always calling finish()?
Demo Time!
Triangulation without angles