Omnet/Inet access to custom application in C++

83 views Asked by At

I have a custom application which is setup and working. I can make chances to the application values using the onmetpp.ini which is subsequently applied after starting the simulation. What I'm looking to do is make changes to values in the application file (for example the messageLength parameter). Here is my setup:

  1. Omnetpp.ini file (section with the app defined)
...
*.drone[*].**.bitrate = 10Mbps
*.drone[*].ipv4.arp.typename = "GlobalArp"
*.drone[*].numApps = 1
*.drone[*].app[0].typename = "MyApp"
*.drone[*].app[0].destAddresses = "server"
*.drone[*].app[0].destPort = 5000
*.drone[*].app[0].messageLength = 30000B
*.drone[*].app[0].sendInterval = exponential(120ms)
*.drone[*].app[0].packetName = "myUDPData"
*.drone[*].wlan[0].typename = "AckingWirelessInterface"
*.drone[*].wlan[0].mac.useAck = false
*.drone[*].wlan[0].mac.fullDuplex = false
*.drone[*].wlan[0].radio.transmitter.communicationRange = 50000m
*.drone[*].wlan[0].radio.receiver.ignoreInterference = true
*.drone[*].wlan[0].mac.headerLength = 23B
...
  1. Ned file for the network where the node for the drone is defined
import inet.node.contract.INetworkNode;
import inet.physicallayer.wireless.common.contract.packetlevel.IRadioMedium;
import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator;

network myNetwork {
...
    submodules:
        drone[numDrones]: <default("ganetwork.DroneNode")> like INetworkNode {
            @display("p=400,150;i=device/drone;is=vs");
        }
...
  1. The MyApp header file
#include "inet/applications/base/ApplicationBase.h"
#include "inet/common/clock/ClockUserModuleMixin.h"
#include "inet/transportlayer/contract/udp/UdpSocket.h"

class INET_API MyApp : public inet::ClockUserModuleMixin<inet::ApplicationBase>, public inet::UdpSocket::ICallback {
public:
        void setMessageLength() {messageLength = 1234;};
protected:
        enum SelfMsgKinds { START = 1, SEND, STOP };

        // parameters
        std::vector<inet::L3Address> destAddresses;
        std::vector<std::string> destAddressStr;
        int localPort = -1, destPort = -1;
        inet::clocktime_t startTime;
        inet::clocktime_t stopTime;
        bool dontFragment = false;
        const char *packetName = nullptr;
        int messageLength = 0;

...
}
  1. droneNode.cc file (this is where I want to change the message length from the application MyApp.cc. There is an instance of this class for every drone so I'm trying to use getModuleByPath() to access a specific one(?). When I do this, there is no access to an existing instance of MyApp to allow me to change the messagelength.
    Note: I do not want to create an instance of MyApp here, it is already created by the simulator based on the omnetpp.ini file.

    The below code give me the following compile issue even though the debugger can see members and variables on breakpoint.

droneNode.cc:56:11: error: no member named 'setMessageLength' in 'omnetpp::cModule'

...
#include "droneNode.h"
#include "myApp.h"

Define_Module(DroneNode);

DroneNode::DroneNode() {}
DroneNode::~DroneNode() {}

void DroneNode::initialize(int stage) {'some init code in here'}
void DroneNode::move() {
    char buf2[20] = "app";
    cModule *mod2 = (MyApp*)getSubmodule(buf2, 0); //magic numbers until I get this working!
    mod2->setMessageLength(); //<--- this give me compile issue  
}
...

Note: My network and setup is based on the on the following two tutorials:

  1. https://inet.omnetpp.org/docs/tutorials/wireless/doc/index.html
  2. osg-earth include with omnetpp-6.0

Environment: OMNeT++ Integrated Development Environment, Version: 6.0, Build id: 220413-71d8fab425 Copyright (C) 2005-2022 OpenSim Ltd.
Library inet-4.5.0-3833582230

Thanks for any help, let me know if there is any missing details in my question.

2

There are 2 answers

0
Jerzy D. On

In your code mod2 is a pointer to an instance of cModule not MyApp. cModule does not have setMessageLength() therefore the compiler shows the above mentioned error. You should cast that pointer to the pointer to MyApp, for example using the following code:

char buf2[20] = "app";
cModule *mod2 = getSubmodule(buf2, 0); 
if (mod2) {
  MyApp * mod3 = dynamic_cast<MyApp*>(mod2);
  if (mod3) {
    mod3->setMessageLength();
  }
}
0
abc def On

I was able to get this working based on the following reference...

Simulation Manual (version 6.x), section 4.12 Direct Method Calls Between Modules

This section of the simulation manual describes "how to get a pointer to the object representing the module" when a sub-module is encapsulated within a parent module. Here we get a pointer to the module based on cModule using getParentModule() in conjunction with getSubmodule; where getSubmodule "Finds a direct submodule with the given name and index, and returns its pointer." In my case, the following lines of code from the simulation manual were referenced to support my simulation model.

cModule *targetModule = getParentModule()->getSubmodule("foo");
Foo *target = check_and_cast<Foo *>(targetModule);
target->doSomething();

This code was generalized to the following (not including error correction or refinement; I'll do this later in my code do de-clutter the response ;).
Note: the <check_and_cast<>() serves to cast a pointer to a specified pointer type.

char buf2[20] = "app";

cModule *targetModule = getSubmodule(buf2,0); // 0 is the first app
MyApp *myTarget = check_and_cast<MyApp *>(targetModule);
myTarget->setMessageLength();

This bit of code gave me access to the methods within the MyApp instance for the specific node.