Create a WSM inherented message - omnet++

I would like to make a new message type called wsm_info.
In this message type, I want to include a vehicle structure, as it follows:
struct vehicle{
int vehicle_id;
Coord vehicle_pos;
float speed;
};
In the veins example there is a function called: prepareWSM that's declared in BaseWaveApplLayer.h. This function is a virtual WaveShortMessage* type.
If the wsm_info was inherented from WaveShortMessage I wouldn't need to write and declare a new prepareWSM for wsm_info, right?
So how can I make this wsm_info message inherented of WaveShortMessage?
I tried to write like this in the wsm_info.h:
class wsm_info : public WaveShortMessage
Instead of, that was written previously:
class wsm_info : public ::omnetpp::cPacket
But the error that I get is the following one:
cannot initialize a variable of type wsm_info * with an rvalue of type WaveShortMessage
The full code of my msg_info is below:
cplusplus {{
#include "veins/base/utils/Coord.h"
#include "veins/modules/messages/WaveShortMessage_m.h"
}}
class noncobject Coord;
class WaveShortMessage;
struct vehicle {
int vehicle_id;
Coord vehicle_pos;
float speed;
};
message wsm_info extends WaveShortMessage {
//Version of the Wave Short Message
int wsmVersion = 0;
//Determine which security mechanism was used
int securityType = 0;
//Channel Number on which this packet was sent
int channelNumber;
//Data rate with which this packet was sent
int dataRate = 1;
//Power Level with which this packet was sent
int priority = 3;
//Unique number to identify the service
int psid = 0;
//Provider Service Context
string psc = "Service with some Data";
//Length of Wave Short Message
int wsmLength;
vehicle data;
int senderAddress = 0;
int recipientAddress = -1;
int serial = 0;
Coord senderPos;
simtime_t timestamp = 0;
}
Can anyone take a look on my code and point me where is wrong and why? Thanks!

The msg_info.msg should have the following content:
cplusplus {{
#include "veins/modules/messages/WaveShortMessage_m.h"
}}
class noncobject Coord;
struct vehicle {
int vehicle_id;
Coord vehicle_pos;
float speed;
};
class WaveShortMessage;
packet wsm_info extends WaveShortMessage {
vehicle data;
}
You cannot use prepareWSM() because it creates a WaveShortMessage object which cannot be cast to wsm_info. Instead you may write a new method, for example:
In /veins/src/veins/modules/application/ieee80211p/BaseWaveApplLayer.h add:
#include "veins/modules/messages/wsm_info_m.h"
and in the class add the declaration:
wsm_info* prepare_wsm_info(std::string name, int dataLengthBits, t_channel channel, int priority, int rcvId, int serial=0);
In /veins/src/veins/modules/application/ieee80211p/BaseWaveApplLayer.cc add:
wsm_info* BaseWaveApplLayer::prepare_wsm_info(std::string name, int lengthBits, t_channel channel, int priority, int rcvId, int serial) {
wsm_info* wsm = new wsm_info(name.c_str());
// ... content similar to prepareWSM()
}
In order to set vehicle structure you can just write:
wsm_info* info = prepare_wsm_info(/* parameters */);
vehicle veh;
veh.speed = 60;
veh.vehicle_id = 3;
// ...
info->setData(veh);
Alternatively you can add parameters for vehicle in the definition of prepare_wsm_info().

If i get you right, you want to extend your wsm_info.msg, is that correct?
According to THIS question, you can modify your wsm_info.msg in the following way:
cplusplus {{
#include "veins/modules/messages/WaveShortMessage_m.h"
}}
class WaveShortMessage;
message wsm_info extends WaveShortMessage {
int vehicle_id;
Coord vehicle_pos;
float speed;
}

where must be declare wsm_info.msg ?in which folder?

Related

The MAC address value isn't recognized by other node messages

I'm using Veins 5.0. Here is the code I've written:
NodeMsg.msg
cplusplus{{
#import "veins/base/utils/Coord.h"
#import "veins/modules/utility/Consts80211p.h"
#include "veins/modules/messages/BaseFrame1609_4_m.h"
#include "veins/base/utils/SimpleAddress.h"
}};
namespace veins;
class noncobject Coord;
class BaseFrame1609_4;
class noncobject LAddress::L2Type;
packet mR_SA extends BaseFrame1609_4
{
int isWlan; // IEEE 80211p and LTE classification variables
int mrsuId;
int type;
int status;
int remainingCapacity;
int neighborVehiclesCount;
int checksum;
double direction;
double velocity;
double posX; // longitude
double posY; // latitude
simtime_t timestamp = 0;
LAddress::L2Type macId; // MAC address
}
Node.h
#include "veins/modules/mac/ieee80211p/DemoBaseApplLayerToMac1609_4Interface.h"
...
class VEINS_API Node : public DemoBaseApplLayer
{
...
public:
LAddress::L2Type nodeMacId = 0;
}
Node.cc
...
else if(stage == 1)
{
mac = FindModule<DemoBaseApplLayerToMac1609_4Interface*>::findSubModule(getParentModule());
ASSERT(mac);
nodeMacId = mac -> getMACAddress();
}
...
void Node::handleSelfMsg(cMessage* msg)
{
...
mR_SA* mr_sa = new mR_SA();
...
mr_sa -> setMacId(nodeMacId);
BaseFrame1609_4* wsm = new BaseFrame1609_4();
wsm -> encapsulate(mr_sa);
populateWSM(wsm);
sendDelayedDown(wsm, uniform(0.01, 0.50));
}
AnotherNode.cc
...
mR_SA* mr_sa = new mR_SA();
LAddress::L2Type nodeMacId = mr_sa -> getMacId();
EV_TRACE << "MAC address: " << nodeMacId << std::endl;
...
The log is displayed as the MAC address value obtained from Node is 326. However, the MAC address value received from the message by another node is 0. Why does this happen?
There are no errors at all when running the current code in simulation form after building. I suspected that a different type was the cause, so I did a cast to a long type, but the result was the same.
AnotherNode.cc is creating a fresh mR_SA using new, but is expecting to find the sending node's mac address in there. This will not work. Rather, you would need to cast the received cMessage to this type and use member accessors to get the mac address.

Accessing Base class variable inside Derived class

I have a public inheritance, Derived struct inheriting from Base. The Base has a data member int i initialized to 5.
Now I have two codes.
Code 1 : Compiles fine
#include <iostream>
using namespace std;
struct Base{
int i = 5;
};
struct Derived: public Base{
int j = i; // Derived class able to use variable i from Base
Derived(){
i = 10; // Constructor of Derived able to access i from Base
}
};
int main()
{
Derived dobj;
cout << dobj.i;
return 0;
}
Code 2 : Gives error
#include <iostream>
using namespace std;
struct Base{
int i = 5;
};
struct Derived: public Base{
int j = i; //Still works
i = 10; // Error here " main.cpp:15:3: error: ā€˜iā€™ does not name a type"
Derived() = default;
};
int main()
{
Derived dobj;
cout<<dobj.i;
return 0;
}
Why is it that i can be used to assign and be assigned inside constructor body (as in code 1), but not used directly in Derived class (as in code 2). Also what does the error mean?
I was under the impression that the scope of Derived is nested inside Base, so shouldn't it be able to see the data members inside Base scope?
This has nothing to do with base and derived classes but with scope. Your code is illegal for the same reason that this code is illegal:
struct X
{
int i;
i = 20; // error
};
https://godbolt.org/z/60zPb-
int i; or int i = 10; are declarations. i = 20; is a statement. Statements can only appear in function bodies, not at class (or namespace) scope.

Can a method of an class (in a shared_ptr) be tied to a static function in a traits class?

Historically, I've been using trait classes to hold information and apply that into a "generic" function that runs the same "algorithm." Only differed by the trait class. For example: https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
I'm not sure how to create "generic" algorithms this when dealing with polymorphic classes.
For example: https://onlinegdb.com/S1hFLGC7V
Below I have created an inherited class hierarchy. In this example I have a base catch-all example that defaults all the parameters to something (0 in this case). And then each derived class sets overrides specific methods.
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
Here I created a simple factory, not elegant but for illustrative purposes
// example simple factory
std::shared_ptr<Base> get_class(const int input) {
switch(input)
{
case 0:
return std::shared_ptr<Base>(std::make_shared<A>());
break;
case 1:
return std::shared_ptr<Base>(std::make_shared<B>());
break;
default:
assert(false);
break;
}
}
So this is the class of interest. It is a class does "something" with the data from the classes above. The methods below are a simple addition example but imagine a more complicated algorithm that is very similar for every method.
// class that uses the shared_ptr
class setter {
private:
std::shared_ptr<Base> l_ptr;
public:
setter(const std::shared_ptr<Base>& input):l_ptr(input)
{}
int get_thing_a()
{
return l_ptr->get_thing_one() + l_ptr->get_thing_two();
}
int get_thing_b()
{
return l_ptr->get_thing_three() + l_ptr->get_thing_four();
}
};
int main()
{
constexpr int select = 0;
std::shared_ptr<Base> example = get_class(select);
setter l_setter(example);
std::cout << l_setter.get_thing_a() << std::endl;
std::cout << l_setter.get_thing_b() << std::endl;
return 0;
}
How can I make the "boilerplate" inside the setter class more generic? I can't use traits as I did in the example above because I can't tie static functions with an object. So is there a way to make the boilerplate example more common?
Somewhere along the lines of having a selector, say
enum thing_select { THINGA, THINGB, };
template < thing_select T >
struct thing_traits;
template <>
struct thing_traits<THINGA>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_one' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_two' method
}
template <>
struct thing_traits<THINGB>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_three' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_four' method
}
// generic function I'd like to create
template < thing_select T, typename TT = thing_traits<T> >
int perform_action(...)
{
return TT::first_function(..) + TT::second_function(..);
}
I ideally would like to modify the class above to something along the lines of
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
The answer is, maybe I can't, and I need to pass int the shared_ptr as a parameter and call the specific methods I need instead of trying to tie a shared_ptr method to a static function (in hindsight, that doesn't sound like a good idea...but I wanted to bounce my idea)
Whoever makes the actual call will need a reference of the object, one way or the other. Therefore, assuming you want perform_action to perform the actual call, you will have to pass the parameter.
Now, if you really want to store which function of Base to call as a static in thing_traits without passing a parameter, you can leverage pointer to member functions:
template <>
struct thing_traits<THINGA>
{
static constexpr int (Base::*first_function)() = &Base::get_thing_one;
...
}
template < thing_select T, typename TT = thing_traits<T>>
int perform_action(Base & b)
{
return (b.*TT::first_function)() + ...;
}
You can also play instead with returning a function object that does the call for you (and the inner function takes the parameter).
It all depends on who you need to make the call and what information/dependencies you assume you have available in each class/template.

Hash table of templated functor

I want to create a hastable to member templated functor, I explain.
Here is my exemple which does'nt work:
#include <iostream>
#include <unordered_map>
using namespace std;
class MyFirstClass
{
int i_;
public:
MyFirstClass(): i_(0) {}
void setI(int i) { i_ = i; }
int getI() { return i_; }
};
class MySecondClass
{
bool b_;
public:
MySecondClass(): b_(0) {}
void setB(bool b) { b_ = b; }
bool getB() { return b_; }
};
template<class X, void (X::*p)()>
class MyFunctor
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()() const { (_x.*p)(); }
};
int main(int argc, char *argv[])
{
unordered_map<string,MyFunctor> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = first::setI;
myHashTable["bool"] = second::setB;
//
string key = "bool";
int value = 1;
myHashTable[key](value);
return 0;
}
I have multiple class with their own setter . I would like to be able thanks to the has table and a command {string,int} change the value of the corresponding class.
The previous code is not working for the moment and I am stuck.
There are a few problems with your code, as it stands.
Firstly, from your example unordered_map<string,MyFunctor> doesn't name a type, because MyFunctor doesn't name a type. You could create a non-template base class with a virtual operator(), and then have MyFunctor inherit from it.
Second, you aren't using compatible method pointers, MyFirstClass::setI and MySecondClass::setB both take a parameter.
Third, related to the first, you have to specify the template parameters when constructing an object from a class template. (until c++17's class template deduction guides). You also have ungrammatical syntax that I assume is trying to specify the object argument to the MyFunctor constructor alongside the method-pointer template argument.
You would have something like
class MyFunctorBase {
virtual void operator()(void * i) const = 0;
}
template<class T, class X, void (X::*p)(T)>
class MyFunctor : public MyFunctorBase
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()(void * i) const override { (_x.*p)(*static_cast<T*>(i)); }
};
int main(int argc, char *argv[])
{
unordered_map<string,shared_ptr<MyFunctorBase>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = make_shared<MyFunctor<int, MyFirstClass, &MyFirstClass::setI>>(first);
myHashTable["bool"] = make_shared<MyFunctor<bool, MySecondClass, &MySecondClass::setB>>(second);
//
string key = "bool";
bool value = true;
(*myHashTable[key])(static_cast<void *>(&value));
return 0;
}
Or, much more easily, use the existing std::function, which does that for you
int main(int argc, char *argv[])
{
unordered_map<string,function<void(void *)>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = [first](void * i) { first.setI(*static_cast<int *>(i)); };
myHashTable["bool"] = [second](void * i) { second.setB(*static_cast<bool *>(i)); };
//
string key = "bool";
bool value = true;
myHashTable[key](static_cast<void *>(&value));
return 0;
}

Deserialize Protocol Buffers using boost::mpl

I create my RPC Protocol with PB like:
enum EMessages {
E_MSG_METHOD_CONNECT = 0x8001,
E_MSG_EVENT_CONNECT = 0xA001,
...
}
struct MsgHeader {
required int32 sessionRef = 1;
required int32 transactionId = 2;
required int32 status = 3;
}
struct MSG_METHOD_CONNECT {
optional Messages opCode = 1 [default = E_MSG_METHOD_CONNECT];
required MsgHeader header = 2;
.. other fields ..
}
Now, I defined an interface and a template class to add a level of indirection:
class IMessage {
virtual INT getOpCode() = 0;
virtual STRING getName() = 0;
virtual size_t getSize() = 0;
virtual INT SerializeToString(STRING& out) = 0;
virtual INT ParseFromString(STRING& in) = 0;
....
}
template<class MESSAGE>
class IMessageImpl : public IMessage {
protected:
MESSAGE m_Message; ///< The Message Implementation
public:
virtual MESSAGE& getMessage() = 0;
};
And I will use it as:
IMessageImpl<MSG_METHOD_CONNECT> MsgConnect;
Now, when I receive the data from an endpoint I need, of course, to deserialize it according with the message opCode.
Reading this article I'm thinking to use a type map like boost::mpl::map but, since I never use it, I'm searching for some suggestions.
<< ------------------------ [EDIT] ------------------------ >>
Regarding the code above, I try to code it in the following way:
template<class MESSAGE>
class PBMessage : public IMessageImpl<MESSAGE>
{
public:
PBMessage() {};
/* ... other methods ... */
};
// Map of types. The key is the Message opCode
typedef typename mpl::map< mpl::pair<mpl::int_[100], PBMessage<MSG_METHOD_CONNECT> >,
mpl::pair<mpl::int_[101], PBMessage<MSG_EVENT_CONNECT> >,
> TMessageMap;
// The Message type
template < typename MessageMap, int opCode >
typedef typename mpl::at<MessageMap, mpl::int_<opCode> >::type::value TMessage;
And, to create a message from a received buffer I try to code (take it as pseudo-code):
class PBMessageFactory : public IMessageFactory {
public:
IMessage* createMessage(CHAR* buff, UINT size) {
int opCode = buff[0];
TMessage<TMessageMap, opCode> msg;
msg.ParseFromString( STRING(buff) );
}
};
But with no success...Is there someone could give me some suggestions how to retrieve types from a mpl::map?
Thanks,
Daniele.

Resources