change network delay in ned file as a parameter - omnet++

is it possible to change the delay value of delay from being something static in the ned file (like it currently is) to some parameter set in the omnetpp.ini file?
this is my .ned file (mainly the tictoc8 from the omnet++ tutorial).
simple Ping8
{
parameters:
#display("i=device/pc");
gates:
input in;
output out;
}
simple Pong8
{
parameters:
#display("i=device/pc");
//double d = default(0.5);
gates:
input in;
output out;
}
network PingPong8
{
#display("bgb=540,253");
submodules:
ping: Ping8 {
parameters:
#display("i=,cyan;p=32,145");
}
pong: Pong8 {
parameters:
#display("i=,gold;p=499,145");
}
connections:
ping.out --> { delay = 50ms; } --> pong.in;
ping.in <-- { delay = 50ms; } <-- pong.out;
}
I want to change the value in the PingPong8 connections delay value to something I set in the omnetpp.ini file.

Sure. Create a parameter at network level and use that parameter to set delay in the connections section. Top level networks behave exactly like any other compound module, except they don't have gates.

Related

Statistics collection related values do not increase in OMNeT++

In order to measure the packet transmission/reception count, I declared a scalar variable and wrote a function related to record. It looks like this:
A.h
class VEINS_API A : public DemoBaseApplLayer
{
private:
long StaticsFrsaPacketCount;
cOutVector frsaPacketCountVector;
...
}
A.cc
void A::initialize(int stage)
{
DemoBaseApplLayer::initialize(stage);
if(stage == 0)
{
StaticsFrsaPacketCount = 0;
frsaPacketCountVector.setName("fR_SA packet count");
...
}
}
void A::finish()
{
recordScalar("fR_SA Packet", StaticsFrsaPacketCount);
...
}
void A::handleSelfMsg(cMessage* msg)
{
switch(msg -> getKind())
{
case SEND_FRSA_EVT:
{
...
StaticsFrsaPacketCount++;
frsaPacketCountVector.record(StaticsFrsaPacketCount);
...
sendDelayedDown(wsm, uniform(0.01, 0.50));
}
...
}
}
I wrote the code by referring to the statistics written in the official OMNeT++ Tictoc tutorial. However, the result of the scalar value through the generated .anf file after the simulation is finished is as shown in the image below.
In other words, it seems that the value is incremented 1 time and not incremented after that. What is the cause?
(this part) of your code looks fine. The most likely reason why you have 1 in the result because really just one packet was sent. The statistics are showing what is actually happening. If you expect several packets to be sent, I suggest to start the app in Qtenv and step over the simulation and make sure that it works as you expect.

Evaluating an hcl.Expression which expected value is a Go interface

I am writing a HCL-based configuration language where some types of blocks can reference other blocks using expressions, as follows:
source "my_source" {
// some blocks and attributes...
to = destination.my_kafka_topic
}
destination "kafka" "my_kafka_topic" {
// some blocks and attributes...
}
destination "elasticsearch" "my_es_index" {
// some blocks and attributes...
}
(The goal is the model the flow of events in a messaging system, and then materialize the actual system in terms of infrastructure.)
During parsing, I simply perform a partial decoding of the static attributes and blocks and ensure "to" hcl.Attributes can be interpreted as hcl.Traversals, but don't evaluate them (yet).
type Source struct {
Name string // first HCL tag
/* ... */
To hcl.Traversal
}
type Destination struct {
Type string // first HCL tag
Name string // second HCL tag
/* ... */
}
Later, referenceable blocks (e.g. destination in the example above) are associated with a certain Go type based on their Type label, and this Go type always implements an interface called Referenceable.
type Referenceable interface {
AsReference() *Destination
}
type Destination struct {
// fields that represent the destination in terms of address, protocol, etc.
}
At that stage, I know how to build a map of referenceables map[string]Referenceable where the key is <block_type>.<block_name> (e.g. "destination.my_kafka_topic"), but I am unsure how to leverage that in an hcl.EvalContext in order to evaluate the variables to Go Referenceables.
What I would like to know is: how to express a Go interface in the cty type system used by hcl.EvalContext? Is is even possible? If not, is it advised to inject instances of *Destination in the hcl.EvalContext instead?

How to apply ascending ID parameter to thousands of multiple module types

Suppose I have a simple module Client defined in Client.ned along with two subclassed simple modules:
simple Client
{
parameters:
volatile int clientId;
}
simple ClientA extends Client
{
}
simple ClientB extends Client
{
}
Now what I wish to do is define a network Network with 1000 ClientA instances and 1000 Client 2 instances as its submodules. I would like each instantiation to have a clientId one bigger than the last, i.e I would like the clientId parameter to ascend with each instantiation. For example, suppose we have the following Network.ned file:
network Network
{
submodules:
clientA[1000]: ClientA {
clientId = index;
};
clientB[1000]: ClientB {
clientId = 1000 + index;
}
}
What I'm looking for is a general approach, where we don't know the number of clients that are to be instantiated beforehand or even the number of client subclasses, just that if there is an instantiated Client of some sort, it should have a clientId parameter one larger than the last instantiation.
Remove volatile from clientId declaration in Client.ned and your solution will work properly.
The main purpose of using volatile is to guarantee returning a "fresh" value of a parameter when it is reading several times. In your network the clientId is constant, so the volatile is not necessary. The side-effect of using volatile is problem with using index, and parentIndex.
Beside the above, one should be aware that using omnetpp.ini is a very convenient method of control the simulation. For example, your NED files may look like:
simple Client {
parameters:
int clientId;
}
simple ClientA extends Client { }
simple ClientB extends Client { }
network Network {
submodules:
clientA[1000]: ClientA;
clientB[1000]: ClientB;
}
And the parameters may be set in omnetpp.ini:
**.clientA[*].clientId = index()
**.clientB[*].clientId = 1000 + index()
EDIT
When the number of clients is not known sizeof() method may be used to determine this number:
**.clientA[*].clientId = index()
**.clientB[*].clientId = sizeof(clientA) + index()
Since OMNeT++'s simulator assigns an ascending ID's to every module and submodule, utilizing getId(), getIndex(), getVectorSize(), and getParentModule() allows me to access this info for each module.

InvalidProtocolBufferException in Java client when deserializing protobuf data from C++ server

I have a protobuf message like this:
message Update {
Path path = 1; // The path (key) for the update.
Value value = 2 [deprecated=true]; // The value (value) for the update.
TypedValue val = 3; // The explicitly typed update value.
}
// TypedValue is used to encode a value being sent between the client and
// target (originated by either entity).
message TypedValue {
oneof value {
string string_val = 1; // String value.
int64 int_val = 2; // Integer
....
google.protobuf.Any any_val = 9; // protobuf.Any encoded bytes.
....
}
}
On the server side (C++), we are setting this field as follows (LLDP is the outer class and Interfaces is inside that):
openconfig_lldp::Lldp out;
GetLldpProto(&out);
update->mutable_val()->mutable_any_val()->PackFrom(out.interfaces());
On the client side (Java), we are extracting this field like this:
OpenconfigLldp.Lldp.Interfaces interfaces = update.getVal().getAnyVal().unpack(OpenconfigLldp.Lldp.Interfaces.class);
This is throwing a InvalidProtocolBufferException exception. When I dump the "update" in my Java client, I see this:
path {
elem {
name: "lldp"
}
elem {
name: "interfaces"
}
}
val {
any_val {
type_url: "type.googleapis.com/openconfig_lldp.Lldp.Interfaces"
value: "\212\207\237\334\v\374\001\022\371\001\262\211\267l\031\342\367\304\260\002\v\n\tEth 1/1/1\242\340\247\230\017\002\b\001\352\316\234\250\017\324\001\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh1\342\253\214\353\001\v\n\tEth 1/1/1\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh2\342\253\214\353\001\v\n\tEth 1/1/2\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh3\342\253\214\353\001\v\n\tEth 1/1/3\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh4\342\253\214\353\001\v\n\tEth 1/1/4\242\364\301\261\a\002\b\n\212\207\237\334\v\374\001\022\371\001\262\211\267l\031\342\367\304\260\002\v\n\tEth 1/1/2\242\340\247\230\017\002\b\001\352\316\234\250\017\324\001\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh1\342\253\214\353\001\v\n\tEth 1/1/1\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh2\342\253\214\353\001\v\n\tEth 1/1/2\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh3\342\253\214\353\001\v\n\tEth 1/1/3\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh4\342\253\214\353\001\v\n\tEth 1/1/4\242\364\301\261\a\002\b\n\212\207\237\334\v\374\001\022\371\001\262\211\267l\031\342\367\304\260\002\v\n\tEth 1/1/3\242\340\247\230\017\002\b\001\352\316\234\250\017\324\001\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh1\342\253\214\353\001\v\n\tEth 1/1/1\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh2\342\253\214\353\001\v\n\tEth 1/1/2\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh3\342\253\214\353\001\v\n\tEth 1/1/3\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh4\342\253\214\353\001\v\n\tEth 1/1/4\242\364\301\261\a\002\b\n\212\207\237\334\v\374\001\022\371\001\262\211\267l\031\342\367\304\260\002\v\n\tEth 1/1/4\242\340\247\230\017\002\b\001\352\316\234\250\017\324\001\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh1\342\253\214\353\001\v\n\tEth 1/1/1\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh2\342\253\214\353\001\v\n\tEth 1/1/2\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh3\342\253\214\353\001\v\n\tEth 1/1/3\242\364\301\261\a\002\b\n\262\217\304\272\017/\022-\302\340\317\247\001\'\202\225\377\302\001\b\n\006Neigh4\342\253\214\353\001\v\n\tEth 1/1/4\242\364\301\261\a\002\b\n"
}
}
The type_url seems correct to me. What am I doing wrong here?
Thanks for your time.
EDIT #1:
I looked at the exception string. It is "Type of the Any message does not match the given class."
The same proto file is used for C++ and Java, but I see "openconfig_lldp.Lldp.Interfaces" in C++, where as, it is "OpenconfigLldp.Lldp.Interfaces" in Java. Need to find out why..
EDIT #2:
The same .proto file is used. In this case, it is:
openconfig_lldp.proto
---------------------
syntax = "proto3";
package openconfig.openconfig_lldp;
message Lldp {
message Config {
....
....
}
....
....
}
In case of Java, I see the parent class as OpenconfigLldp in a package called openconfig_lldp.
package openconfig.openconfig_lldp;
public final class OpenconfigLldp {
private OpenconfigLldp() {}
....
....
/**
* Protobuf type {#code openconfig.openconfig_lldp.Lldp}
*/
public static final class Lldp extends com.google.protobuf.GeneratedMessageV3 implements
// ##protoc_insertion_point(message_implements:openconfig.openconfig_lldp.Lldp)
....
....
}
In C++, I don't see any class called "OpenconfigLldp" generated. Instead it is just "Lldp"
So, the type_url in the Any.protobuf is a mismatch. C++ side puts it as
type_url: "type.googleapis.com/openconfig_lldp.Lldp.Interfaces"
While in the Java side I use:
OpenconfigLldp.Lldp.Interfaces interfaces = update.getVal().getAnyVal().unpack(OpenconfigLldp.Lldp.Interfaces.class);
Anyone has thoughts on why there is a wrapper class in Java protoc output?
EDIT #3
Apparently looks like it is because of the "outer_class_name". In the Java code, I have an outer class "OpenconfigLldp".
The type_url format is:
type.googleapis.com/packagename.messagename
So, C++ code sets this to openconfig_lldp.Lldp.Interfaces.
But, this maps to OpenconfigLldp.Lldp.Interfaces in Java.
How could I work around this?
FINAL EDIT and FINAL QUESTION
After some digging around, this is what I found out.
By default, type_url is:
type_url: "type.googleapis.com/openconfig_lldp.Lldp.Interfaces"
On the Java side, I looked at the Any implementation. It tries to compare this with:
openconfig.openconfig_lldp.Lldp.Interfaces
I found this out by printing:
Lldp.Interfaces defaultInstance = (Lldp.Interfaces)Internal.getDefaultInstance(Lldp.Interfaces.class);
logger.info("full descriptor name: " + defaultInstance.getDescriptorForType().getFullName());
So, I hacked the C++ side to send:
update->mutable_val()->mutable_any_val()->set_type_url(std::string("type.googleapis.com/openconfig.openconfig_lldp.Lldp.Interfaces"));
So, I think I know what is happening here!
Thanks for reading through all the edits.
I am not sure if I understand correctly what's going wrong -- ideally the qualified names would be in protocol buffer namespaces -- language specific mappings shouldn't matter.
If the question is still open, I'd recommend to move the core of it to the top, preserving the edits as "what I have done so far".
Perhaps this is some kind of bug that could be worked around with on of these options:
java_multiple_files
java_outer_classname
More details about these options can be found here:
https://developers.google.com/protocol-buffers/docs/proto3

Omnet++ simple wireless node

Iam trying to create simple wireless node for MANET network which can send messages to other nodes in range. Solutions implemented in INET also contains other layers like IP, transport, application which i dont need.
Iam new to omnet++ so iam struggling a bit. I was thinking of creating whole own node with RadioIn input, but i dont know how to implement only in range communication and i will also need node mobility.
Other solutions would be to use only Radiomedium from INET framework but i dont know how to do it.
Can someone please give me some begginer tips how to achieve my goal? As i said i simply need to create mobile host which can send a defined message to all other hosts in range.
EDIT: I tried to take IdealRadioMedium and create my simple module and connect to it. Here is the NED File.
import inet.physicallayer.common.packetlevel.Radio;
import inet.common.figures.DelegateSignalConfigurator;
import inet.networklayer.configurator.ipv4.IPv4NetworkConfigurator;
import inet.node.inet.INetworkNode;
import inet.node.inet.WirelessHost;
import inet.physicallayer.contract.packetlevel.IRadioMedium;
import inet.visualizer.integrated.IntegratedCanvasVisualizer;
import inet.linklayer.contract.IWirelessNic;
import inet.networklayer.common.InterfaceTable;
simple Txc1
{
gates:
input in;
output out;
}
module Pokusny
{
parameters:
#display("i=device/wifilaptop");
int numRadios = default(1);
#networkNode;
gates:
input radioIn[numRadios] #directIn;
submodules:
mynode: Txc1;
wlan[numRadios]: <default("Ieee80211Nic")> like IWirelessNic {
parameters:
#display("p=216,406,row,60;q=queue");
}
interfaceTable: InterfaceTable {
parameters:
#display("p=53,300;is=s");
}
connections allowunconnected:
for i=0..sizeof(radioIn)-1 {
radioIn[i] --> { #display("m=s"); } --> wlan[i].radioIn;
wlan[i].upperLayerOut --> mynode.in;
wlan[i].upperLayerIn <-- mynode.out;
}
}
network WirelessC
{
parameters:
string hostType = default("WirelessHost");
string mediumType = default("IdealRadioMedium");
#display("bgb=650,500;bgg=100,1,grey95");
#figure[title](type=label; pos=0,-1; anchor=sw; color=darkblue);
#figure[rcvdPkText](type=indicatorText; pos=420,20; anchor=w; font=,20; textFormat="packets received: %g"; initialValue=0);
#statistic[rcvdPk](source=hostB_rcvdPk; record=figure(count); targetFigure=rcvdPkText);
#signal[hostB_rcvdPk];
#delegatesignal[rcvdPk](source=hostB.udpApp[0].rcvdPk; target=hostB_rcvdPk);
submodules:
visualizer: IntegratedCanvasVisualizer {
#display("p=580,125");
}
configurator: IPv4NetworkConfigurator {
#display("p=580,200");
}
radioMedium: <mediumType> like IRadioMedium {
#display("p=580,275");
}
//figureHelper: DelegateSignalConfigurator {
// #display("p=580,350");
//}
hostA: Pokusny {
#display("p=50,325");
}
hostB: Pokusny {
#display("p=450,325");
}
}
Txc1.cc
class Txc1 : public cSimpleModule
{
protected:
// The following redefined virtual function holds the algorithm.
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
// The module class needs to be registered with OMNeT++
Define_Module(Txc1);
void Txc1::initialize()
{
cMessage *msg = new cMessage("tictocMsg");
send(msg, "out");
}
void Txc1::handleMessage(cMessage *msg)
{
send(msg, "out"); // send out the message
}
And .ini file
network = WirelessC
sim-time-limit = 25s
*.host*.wlan[0].typename = "IdealWirelessNic"
*.host*.wlan[0].mac.useAck = false
*.host*.wlan[0].mac.fullDuplex = false
*.host*.wlan[0].radio.transmitter.communicationRange = 500m
*.host*.wlan[0].radio.receiver.ignoreInterference = true
*.host*.**.bitrate = 1Mbps
When i run the simulation it asks for Interfacetable parameter which i dont know what to type there becuse i havent found it in traversing functioning code ( I had to add it because it throws error that is missing if its not as submodule). Now iam getting
getCointainingNode() node module not found it should have a property name networkNode for module WirelessC.interfaceTable in module .... durint network initialization
EDIT: I added networknode as parameter and now i got Module not found on path '.mobility' defined by par WirelessC.hostA.wlan[0].radio.antenna.Mobilitymodule in module inte::physicallayer:IsotropicAntenna during network initialization
I'd like to point you to the wireless tutorial for INET: https://omnetpp.org/doc/inet/api-current/tutorials/wireless/
It starts with exactly your problem. The only thing left, is to replace the standard UDP host with a host using no protocol at all, maybe even implementing your own. The whole wireless part is explained in the tutorial.
If you want to check the source files for the used modules you need to walk down the chain of dependency since every compound NED module will (at one point) contain simple modules implemented in C++.
E.g. the module which is responsible for distributing the signals is IdealRadioMedium using RadioMedium. Now you need to find the Node implementation directly communicating with this module.
Starting with the WirelessHost used in the tutorial the underlying modules are
StandardHost -> ApplicationLayerNodeBase -> LinkLayerNodeBase with the later being the first one using actually implemented submodules.
The network adapter used is configured in the omnet.ini with *.host*.wlan[0].typename = "IdealWirelessNic". This module relies on Radio.
With all that found out you just need to look for API calls from Radio.cc made to RadioMedium.cc and you found the actual code responsible for sending data.
Understanding that chain of inheritance you can even hook in with your custom module at a level you find fitting. For example just implementing your own LinklayerNodeBase module.
If you are going for wireless communication and mobility, INET will still be the best framework to use.
Check out the INET Wireless Tutorial. It basically covers all the steps that you need to build a small scenario with moving nodes that communicate wirelessly.

Resources