5 – Oversim NED definitions

All Oversim modules (overlay or application) start with a NED definition. Module definitions define:

  1. What the simulation parameters are
  2. What gates should be made available by the OMNet++ simulation for message passing
  3. How other modules will connect to the specified module

As an example, let us take a look at the DHT NED specification in the src/applications/dht/DHT.ned file. The NED file is shown below, with the exception of one module:

simple DHT extends BaseApp
{
    parameters:
        @class(DHT);
        int numReplica;  // number of replica for stored data records
        int numGetRequests; // number of queried replica for get requests
        double ratioIdentical; // ratio of identical replica needed for a valid result
        bool secureMaintenance; // use a secure maintenance algorithm based on majority decisions
        bool invalidDataAttack; // if node is malicious, it tries a invalidData attack
        bool maintenanceAttack; // if node is malicious, it tries a maintenance attack
}
module DHTModules like ITier
{
    parameters:
        @display("i=block/segm");
    gates:
        input udpIn;    // gate from the UDP layer
        input from_lowerTier;    // gate from the lower tier
        input from_upperTier;    // gate from the upper tier
        input tcpIn;    // gate from the TCP layer
        output tcpOut;    // gate to the TCP layer
        output udpOut;    // gate to the UDP layer
        output to_lowerTier;    // gate to the lower tier
        output to_upperTier;    // gate to the upper tier
    submodules:
        dht: DHT;
        dhtDataStorage: DHTDataStorage;
    connections allowunconnected:
        from_lowerTier --> dht.from_lowerTier;
        to_lowerTier <-- dht.to_lowerTier;
        from_upperTier --> dht.from_upperTier;
        to_upperTier <-- dht.to_upperTier;
}

This NED file contains one simple module and one compound module. In OMNet++ all simple modules have to be contained in compound modules to mean anything. The reader will understand why, shortly. Let's first look at the simple module, defined by the line: simple DHT extends BaseApp

It specifies that a simple module definition will follow and it extends the BaseApp simple module definition, defined in a NED file somewhere else. The reason for extending the BaseApp module, is to define a common interface across which all OverSim applications may communicate with their counterparts. Specifically, the BaseApp module defines the gates:

        input udpIn;             // gate from the UDP layer
        input from_lowerTier;    // gate from the lower tier
        input from_upperTier;    // gate from the upper tier
        input direct_in;         // gate for sendDirect
        input trace_in;          // gate for trace file commands
        input tcpIn;             // gate from the TCP layer
        output tcpOut;           // gate to the TCP layer
        output udpOut;           // gate to the UDP layer
        output to_lowerTier;     // gate to the lower tier
        output to_upperTier;     // gate to the upper tier
        input overlayIn;         // gate from the TCP layer
        output overlayOut;       // gate to the TCP layer

There exists UDP and TCP "in" and "out" gates, to send messages to a specific IP and port of a node in the simulation. There are gates to send and receive messages from the higher layers (tier 2 or tier 3, depending on what layer we are in), as well as the lower layers (tier 2, tier 1 or the overlay, depending in what layer we are in). There also exists a dedicated overlay gate, which allows any tier to communicate with the overlay. The second last gate is a "direct_in" gate, for direct messages sent to the module, without the need for a specified connection in the NED definition. And the last gate is a "trace_in" gate for statistics collection. All these gates allow an OverSim application to function and allows the developer ease of use when wanting to communicate with other modules or layers.

Every simple module can exist out of two parts parameters and gates. Parameters usually specify experimental parameters. These are the types of values that someone running the simulation might want to regularly change to obtain different simulation results (e.g., size of routing table and cache capacity). The most important part to note is the class. This specifies the name of the C++ class that implements the functionality of the simple module. Gates are how modules in OMNet connect and communicate. At the core, an OMNet module is a C++ class, but this class needs to be able to communicate with other classes to enable the message passing, which is achieved through gates. While the DHT simple module does not specify any gates, remember that it extends BaseApp which does. The simple DHT module, therefore inherits the gates specified in the BaseApp module.

The next module, the compound module DHTModule implements the ITier interface. The ITier interface merely specifies that the compound module that implements it, should have all the gates of the BaseApp simple module. Compound modules enable us to connect multiple simple modules to perform a more complex function. A compound module may have four sections parameters, gates, submodules, and connections. Think of a compound module containing instances of all simple modules specified in its submodules section, while itself being an abstract module. The gates and parameters section; therefore, specify the properties of the larger abstract module and how it will communicate with the outside world.

The submodules section specifies what simple modules the compound module contains. One should note that instances of types of simple modules are specified. So it is possible to have more than one simple module of the same type contained in a single compound module, as long as the names used for instantiation are different. In the case of our DHT example, the compound module contains two simple module, the above discussed DHT module as well as the dhtDataStorage module that is also declared in the NED file.

The connections section specifies how the different internal modules are connected, as well as which of the internal gates are connected to the external gates of the compound module. For further details on NED language and modules please refer to the Omnet++ documentation.

As can be seen from this DHT example, not all external gates have to be connected to internal gates (Just remember the "allowunconnected" keyword in the title of the "connections" section.). You only have to connect the ones you will be using for communication with other modules. In our example, no connections are specified for dhtDataStorage, because the module is handled as just another C++ class inside the DHT class (something we will get to later). The only connections specified are how the simple DHT module will communicate with the outside world. It is specified that we can receive data from the lower tier, send data to the lower tier, receive data from the upper tier and send data to the upper tier.

Next, we will see how we can use the module in our compound module and the gates that we specified to send messages and do some useful work.