Establish connection to module at runtime in Omnet++ - omnet++

Good Morning!
I'm implementing a simulation for a dynamic distributed storage network, which requires at certain points, that the connections between the modules vary. (e.g. client connects to a node (establishes a new connection) and wants to work with his data, stored on different nodes).
Is there is possibility to establish connections between unconnected but existing gates of two nodes at runtime?
For example:
simple node1 {
parameters:
#display(...);
gates:
input in #loose;
output out #loose;
}
simple node2 {
parameters:
#display(...);
gates:
input in #loose;
output out #loose;
}
Afterwards there would be a boring network definition with no connections. (Don't know if it is possible to have a completely blank definition, but for the minimal example we assume it)
In the C++ file for the modules I wish to create a connection between these nodes depending on a certain condition like (pseudo code):
if(condition){
node1->setConnection(ownGate("out"),node2->getGates("in"),true);
}else{
node1->setConnection(ownGate("out"),node2->getGates("in"),false);
}
I've read the simulation manual of Omnet++ but really can't figure out what to do here ...
Is it possible at all to do this? And how?
Thanks for any help here!

Yes, it is possible to dynamically create a connection between two modules. One may use connectTo() method to do it.
Assuming that the network contains two nodes of both types from your question:
network Test1 {
submodules:
n1 : node1;
n2 : node2;
}
the following code may be used to connect n1 to n2 using bidirectional connection:
// code of n1
if(condition) {
cModule * dest = getModuleByPath("n2");
cGate * destGateIn = dest->gate("in");
cGate * thisGateOut = gate("out");
thisGateOut->connectTo(destGateIn); // forward direction
cGate * destGateOut = dest->gate("out");
cGate * thisGateIn = gate("in");
destGateOut->connectTo(thisGateIn); // reverse direction
}

Related

Query on yang deviation

I am new to yang deviations. I wrote a deviation like below but I am not sure if the deviation is effective. Is it possible to print a text(value of xpath) in must statement for debugging purposes? Please help.
deviation "/ns:direction" {
description "Deviation to restrict if the direction is left.";
deviate add
{
must "(<function to print current()>) " {
error-message "Direction is not left.";
description "Direction is not left." ;
}
}
}
A typical way to check whether your deviation works would be to feed your module set to a YANG schema aware validator and simply validate an instance document which ensures that your expression evaluates in a desired way. If you tailor the document so that your particular constraint fails, you'd expect the "Direction is not left." error message during validation of said document. I guess you could call that a YANG instance document test case for your YANG schema.
module b {
yang-version 1.1;
namespace "b:uri";
prefix b;
container top {
leaf direction {
type enumeration {
enum left;
enum right;
}
}
}
}
module c {
yang-version 1.1;
namespace "c:uri";
prefix "c";
import b {
prefix b;
}
deviation "/b:top/b:direction" {
deviate add {
must ". = 'left'" {
error-message "Direction is not left.";
description "Direction is not left." ;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<b:top xmlns:b="b:uri">
<b:direction>right</b:direction>
</b:top>
</config>
Error at (4:5): failed assert at "/nc:config/b:top/b:direction": Direction is not left.
Must statements are assertions about instantiated data nodes so the only way to "debug" those is to throw them against an instance document, configuration + operational state of a device, datastore contents, etc.
It should not matter if the actual constraint is introduced in the original module or later via a deviation. Deviations are just quick and dirty patches of an existing model. You won't find any in modules published by the IETF. You usually resort to them if certain hardware cannot support the requirements of a published model (hard resource limits) or if you implement a big model in several stages, tagging some things as "not-supported" (yet). There are several caveats to them; the order in which they are applied matters for example, you should avoid deviating the same object in several places, you should only define them in specialized modules that only contain deviations (deviation modules), you should consider them to be temporary, etc.

RunnableGraph to wait for multiple response from source

I am using Akka in Play Controller and performing ask() to a actor by name publish , and internal publish actor performs ask to multiple actors and passes reference of sender. The controller actor needs to wait for response from multiple actors and create a list of response.
Please find the code below. but this code is only waiting for 1 response and latter terminating. Please suggest
// Performs ask to publish actor
Source<Object,NotUsed> inAsk = Source.fromFuture(ask(publishActor,service.getOfferVerifyRequest(request).getPayloadData(),1000));
final Sink<String, CompletionStage<String>> sink = Sink.head();
final Flow<Object, String, NotUsed> f3 = Flow.of(Object.class).map(elem -> {
log.info("Data in Graph is " +elem.toString());
return elem.toString();
});
RunnableGraph<CompletionStage<String>> result = RunnableGraph.fromGraph(
GraphDSL.create(
sink , (builder , out) ->{
final Outlet<Object> source = builder.add(inAsk).out();
builder
.from(source)
.via(builder.add(f3))
.to(out); // to() expects a SinkShape
return ClosedShape.getInstance();
}
));
ActorMaterializer mat = ActorMaterializer.create(aSystem);
CompletionStage<String> fin = result.run(mat);
fin.toCompletableFuture().thenApply(a->{
log.info("Data is "+a);
return true;
});
log.info("COMPLETED CONTROLLER ");
If you have several responses ask won't cut it, that is only for a single request-response where the response ends up in a Future/CompletionStage.
There are a few different strategies to wait for all answers:
One is to create an intermediate actor whose only job is to collect all answers and then when all partial responses has arrived respond to the original requestor, that way you could use ask to get a single aggregate response back.
Another option would be to use Source.actorRef to get an ActorRef that you could use as sender together with tell (and skip using ask). Inside the stream you would then take elements until some criteria is met (time has passed or elements have been seen). You may have to add an operator to mimic the ask response timeout to make sure the stream fails if the actor never responds.
There are some other issues with the code shared, one is creating a materializer on each request, these have a lifecycle and will fill up your heap over time, you should rather get a materializer injected from play.
With the given logic there is no need whatsoever to use the GraphDSL, that is only needed for complex streams with multiple inputs and outputs or cycles. You should be able to compose operators using the Flow API alone (see for example https://doc.akka.io/docs/akka/current/stream/stream-flows-and-basics.html#defining-and-running-streams )

open62541 browsing nodes an using its methods

I want to browse a specific node on my OPC UA Server and use its method.
I use the open62541 stack and i want to use a selfmade client. My Client connects to the Server and then i use the given example to browse some Objects. It shows me the first layer of nodes after the root-folder-
How can i find a specific node? Or have i to browse to this point? Is there an example file in the open62541 project which i don't see that would open my eyes?
I also find the Method "Service_TranslateBrowsePathsToNodeIds" but i'm not quite sure how to use it the right way and which part is interesting for me.
As an example:
I want to browse the Node "FileSystem", which is in a deeper layer than the root-folder, and want to use its Method createFile.
To call a method, you need two node ids:
Object node id which contains the method
Method node id
If you already have these node ids, you can call the method right away. If not,
OPC UA in general supports two options to get these node ids:
Start at the root node (ns=0;i=84) and recursively browse all the child nodes until you find the node with the specific browse name.
https://github.com/open62541/open62541/blob/58bd161557111847d068650eff5ad670a9aa0395/examples/client.c#L61
Use the TranslateBrowsePathsToNodeIds Service if you have a browse path. I.e., give /Objects/MyDevice/FileSystem/UploadFile (concatenation of browse names) with start node Root (ns=0;i=84) and the server will return you the node id of that specific node if it exists. This service is taking relative paths, therefore you can also use other nodes as start nodes
https://github.com/open62541/open62541/blob/58bd161557111847d068650eff5ad670a9aa0395/examples/client_async.c#L183
After some trial and error I found the 'magic' bits to get it working with nodes that are in the server namespace, e.g. of real devices and not pre-defined UA nodes like timestamp or server status as shown in all examples. The code below is derived from the corpus_generator.c and check_services_view.c files of Open62541 with 2 key differences:
You do not have to specify the referenceTypeId.
When creating the strings, place them in the server namespace, not UA namespace (see UA_QUALIFIEDNAME_ALLOC below).
The function below will take a pointer to UA_Client and a vector of browsenames that form the path to the node, starting at the Objects folder in OPC-UA.
Node::Node (UA_Client *client, const std::vector<std::string> &browse_path)
: m_client (client)
{
m_id = UA_NODEID_NULL;
// Search for ID in client
UA_BrowsePath browsePath;
UA_BrowsePath_init (&browsePath);
browsePath.startingNode = UA_NODEID_NUMERIC (0, UA_NS0ID_OBJECTSFOLDER);
browsePath.relativePath.elements = (UA_RelativePathElement *)UA_Array_new (browse_path.size (), &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]);
browsePath.relativePath.elementsSize = browse_path.size ();
for (int i = 0; i < browse_path.size (); i++)
{
UA_RelativePathElement *elem = &browsePath.relativePath.elements[i];
elem->targetName = UA_QUALIFIEDNAME_ALLOC (1, browse_path.at (i).c_str ()); // Create in server namespace (1), not UA namespace (0)!
}
UA_TranslateBrowsePathsToNodeIdsRequest request;
UA_TranslateBrowsePathsToNodeIdsRequest_init (&request);
request.browsePaths = &browsePath;
request.browsePathsSize = 1;
UA_TranslateBrowsePathsToNodeIdsResponse response;
response = UA_Client_Service_translateBrowsePathsToNodeIds (m_client, request);
if (UA_STATUSCODE_GOOD == response.responseHeader.serviceResult && response.resultsSize > 0)
{
UA_BrowsePathResult *first = response.results;
if (first->targetsSize >= 1)
{
m_id = first->targets[0].targetId.nodeId;
std::cout << "Found ID";
}
else
{
std::cout << "OK response but no results";
}
}
else
{
std::cout << "Error in translate browsename";
}
UA_BrowsePath_deleteMembers (&browsePath); // Marked as deprecated, but UA_BrowsePath_delete() expects a heap-allocated pointer.
UA_TranslateBrowsePathsToNodeIdsResponse_deleteMembers (&response); // Idem
}

Can't find RoutingAccessTable.h?

I am simulating a Flying Ad Hoc Network using aodv routing protocol. I want to get the list of neighbor's node to send random numbers to these neighbors. I found this code in google omnet++ forum :
#include "IRoutingTable.h"
#include "RoutingTableAccess.h"
vector<IPAddress> neigh;
IRoutingTable *inet_rt = RoutingTableAccess().get();
neigh.clear();
for (int i=0;i<inet_rt->getNumRoutes(); ++i)
{
const IPRoute *e = inet_rt->getRoute(i);
if (e->getMetric()==1)
{
neigh.push_back(e->getHost());
}
}
But when i try to use it, i can't find the file "RoutingTableAccess.h" in the inet directory? Is there any other method to get the list of neighbors in Mobile Ad hod Network using aodv?
Many Thanks.
Since INET 4.0 every host has the parameter routingTableModule that indicates the name of routing table's module.
The following method may be used to obtain an access to routing table:
IRoutingTable *routingTable;
routingTable = getModuleFromPar<IRoutingTable>(par("routingTableModule"), this);

protobuffer file with many sub messages - one big file or imports?

We recently started using protobuffers in the company I work for, i was wondering what was the best practice regarding a message that holds other messages as fields.
Is it common to write everything in one big proto file or is it better to separate the different messages to different files and import the messages you need in the main file?
For example:
Option 1:
message A {
message B {
required int id = 1;
}
repeated B ids = 1;
}
Option 2:
import B.proto;
message A {
repeated B ids = 1;
}
And in a different file:
message B {
required int id = 1;
}
It depends on your dataset and the usage.
if your data set is small, you should prefer option 1. It leeds to less coding for serialization and deserialization.
if your data set is big, you should prefer option 2. If the file is too big, you can't load it completely into memory. And it will be very slow, if you need only one information and you read all the information of the file.
Maybe this is helpful.

Resources