Jacques
Jacques

Reputation: 13

Omnet++ connect compound modules; gates are all connected, no gate left for '++' operator

I am new omnet++ and I'm having trouble with using compound modules and gates. I want to create a network where a message passes through three stages (for now, plan on building a similar network that goes through more stages).

In each stage, there are two or three actions to perform; the first and last stage have two actions to perform and the middle stages has three actions to perform. Since these actions are somewhat similar at each stage, I opted to use compound module. Here is what I have so far;

My simple modules

simple baseSimpleModule
{
    gates:
        inout ioGates[];
}

simple ActionA extends baseSimpleModule
{
    @class(ActionA);
}

simple ActionB extends baseSimpleModule
{
    @class(ActionB);
}

simple ActionC extends baseSimpleModule
{
    @class(ActionC);
}

My two types of compound modules

module baseModule
{
    gates:
        inout ioGates[];
    submodules:
        actionA: ActionA;
        actionB: ActionB;
    connections:
        actionA.ioGates++ <--> ioGates++;
        actionB.ioGates++ <--> ioGates++;
}

module type1Module extends baseModule
{
    connections:
        actionA.ioGates++ <--> actionB.ioGates++;
}

module type2Module extends baseModule
{
    submodules:
        actionC: ActionC;
    connections:
        actionA.ioGates++ <--> actionC.ioGates++;
        actionC.ioGates++ <--> actionB.ioGates++;
}

Lastly, I have a simple network as follows;

network firstModel
{
    submodules:
        firstStop: type1Module;
        secondStop: type2Module;
        thirdStop: type1Module;
    connections allowunconnected:
        firstStop.ioGates++ <--> secondStop.ioGates++;
        secondStop.ioGates++ <--> thirdStop.ioGates++;
}

I keep getting the error ioGates[] gates are all connected, no gate left for '++' operator.

The trajectory I'm expecting is for the message to start at firstStop, go through each of its submodules, jump to secondStop, go through each of its submodule and so on. I'm I not using compound modules for their intended use case or is the issue with the way my gates are configured?

Thanks in advance!

Upvotes: 0

Views: 745

Answers (1)

Rudi
Rudi

Reputation: 6681

This is a somewhat suspicious/underdeveloped example and that's why you are struggling to model it in NED. Once you would start implementing the various actions/stages you would realize that your inheritance chain is not correct. A few issues:

  • in your 'network' your packets would travel in a certain well defined direction however your NED topology uses bi-directional connections. This is really confusing as you would have a hard time figuring out where to send a message once received and processed.
  • Certain actions that you model with the same module type are behaving very differently. For example firstStop and thirdStop are modeled both with type1Module, however they behave differently. The first action of the firstStop stage should be a message generator with only an output gate, while the first action of the thirdStop must do some processing and it must have both an input and an output gate as it is connected to the secondStep
  • Your actions would need a definite number of gates (either 1 or 2), and they should be in a definite role (like receiving or sending data or both). Modeling this with a gate array is confusing... (should I send out my message on gate[0] or gate[1]???). Its much better to have explicitly named gates in these cases.
  • In OMNeT++, networks/modules are built from outside -> inside direction. i.e. first you build the network with all submodules and connections. Once that is done, the number of gates on inner submodules are specified (either explictly or implicitly by the number of ++ invokations on the gate). At this point, gate and submodule vector sizes are specified. Only after this, will OMNeT++ start to visit and build up the internals of all submodules, so inside the submodules you should not use ++ on gate vectors, as the gate size was already specified by the outside module.

Long story short, here is how your goal could be achieved: There is a clever trick also (working with OMNeT++ 5.6 and later) by specifying the @reconnect property on a connection defined in a subclass. This allows reconnecting a gate that was already connected in the superclass. This means that you can insert additional modules in a sublcass between any other modules defined and connected in the superclass. In this example it inserts actionB between actionA and actionC. The gates are unidirectional and explicitly named.

NOTE: I strongly recommend to take a look at the queuenet sample in OMNeT++, because that sample does exactly like what you want to achieve. Take some architectural hints from the implementation.

module Source {
    gates:
        output o;
    connections allowunconnected: // not needed if this is a simple module
}

module Sink {
    gates:
        input i;
    connections allowunconnected: // not needed if this is a simple module
}

module ActionBase {
    gates:
        input i;
        output o;
    connections:
        i --> o;  // dummy shortcut. not needed if this is a simple module
}

module ActionA extends ActionBase { }

module ActionB extends ActionBase { }

module ActionC extends ActionBase { }

module twoActionModule {
    gates:
        input i;
        output o;
    submodules:
        actionA: ActionA;
        actionC: ActionC;
    connections:
        i --> actionA.i;
        actionA.o --> actionC.i;
        actionC.o --> o;
}

module threeActionModule extends twoActionModule {
    submodules:
        actionB: ActionB;
    connections:
        actionA.o --> { @reconnect; } --> actionB.i; // breaks the connection between A and C
        actionB.o --> actionC.i;
}

network net {
    submodules:
        source: Source;
        twoActionStage: twoActionModule;
        threeActionStage: threeActionModule;
        sink: Sink;
    connections:
        source.o --> twoActionStage.i;
        twoActionStage.o --> threeActionStage.i;
        threeActionStage.o --> sink.i;
}

Upvotes: 0

Related Questions