diff --git a/src/veins/modules/messages/AckTimeOutMessage_m.cc b/src/veins/modules/messages/AckTimeOutMessage_m.cc
new file mode 100644
index 0000000..3029f40
--- /dev/null
+++ b/src/veins/modules/messages/AckTimeOutMessage_m.cc
@@ -0,0 +1,480 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/AckTimeOutMessage.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "AckTimeOutMessage_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(AckTimeOutMessage)
+
+AckTimeOutMessage::AckTimeOutMessage(const char *name, short kind) : ::omnetpp::cMessage(name,kind)
+{
+    this->wsmId = -1;
+    this->ac = -1;
+}
+
+AckTimeOutMessage::AckTimeOutMessage(const AckTimeOutMessage& other) : ::omnetpp::cMessage(other)
+{
+    copy(other);
+}
+
+AckTimeOutMessage::~AckTimeOutMessage()
+{
+}
+
+AckTimeOutMessage& AckTimeOutMessage::operator=(const AckTimeOutMessage& other)
+{
+    if (this==&other) return *this;
+    ::omnetpp::cMessage::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void AckTimeOutMessage::copy(const AckTimeOutMessage& other)
+{
+    this->wsmId = other.wsmId;
+    this->ac = other.ac;
+}
+
+void AckTimeOutMessage::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::omnetpp::cMessage::parsimPack(b);
+    doParsimPacking(b,this->wsmId);
+    doParsimPacking(b,this->ac);
+}
+
+void AckTimeOutMessage::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::omnetpp::cMessage::parsimUnpack(b);
+    doParsimUnpacking(b,this->wsmId);
+    doParsimUnpacking(b,this->ac);
+}
+
+unsigned long AckTimeOutMessage::getWsmId() const
+{
+    return this->wsmId;
+}
+
+void AckTimeOutMessage::setWsmId(unsigned long wsmId)
+{
+    this->wsmId = wsmId;
+}
+
+int AckTimeOutMessage::getAc() const
+{
+    return this->ac;
+}
+
+void AckTimeOutMessage::setAc(int ac)
+{
+    this->ac = ac;
+}
+
+class AckTimeOutMessageDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    AckTimeOutMessageDescriptor();
+    virtual ~AckTimeOutMessageDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(AckTimeOutMessageDescriptor)
+
+AckTimeOutMessageDescriptor::AckTimeOutMessageDescriptor() : omnetpp::cClassDescriptor("AckTimeOutMessage", "omnetpp::cMessage")
+{
+    propertynames = nullptr;
+}
+
+AckTimeOutMessageDescriptor::~AckTimeOutMessageDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool AckTimeOutMessageDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<AckTimeOutMessage *>(obj)!=nullptr;
+}
+
+const char **AckTimeOutMessageDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *AckTimeOutMessageDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int AckTimeOutMessageDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 2+basedesc->getFieldCount() : 2;
+}
+
+unsigned int AckTimeOutMessageDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<2) ? fieldTypeFlags[field] : 0;
+}
+
+const char *AckTimeOutMessageDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "wsmId",
+        "ac",
+    };
+    return (field>=0 && field<2) ? fieldNames[field] : nullptr;
+}
+
+int AckTimeOutMessageDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='w' && strcmp(fieldName, "wsmId")==0) return base+0;
+    if (fieldName[0]=='a' && strcmp(fieldName, "ac")==0) return base+1;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *AckTimeOutMessageDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "unsigned long",
+        "int",
+    };
+    return (field>=0 && field<2) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **AckTimeOutMessageDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *AckTimeOutMessageDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int AckTimeOutMessageDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    AckTimeOutMessage *pp = (AckTimeOutMessage *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *AckTimeOutMessageDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    AckTimeOutMessage *pp = (AckTimeOutMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string AckTimeOutMessageDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    AckTimeOutMessage *pp = (AckTimeOutMessage *)object; (void)pp;
+    switch (field) {
+        case 0: return ulong2string(pp->getWsmId());
+        case 1: return long2string(pp->getAc());
+        default: return "";
+    }
+}
+
+bool AckTimeOutMessageDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    AckTimeOutMessage *pp = (AckTimeOutMessage *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setWsmId(string2ulong(value)); return true;
+        case 1: pp->setAc(string2long(value)); return true;
+        default: return false;
+    }
+}
+
+const char *AckTimeOutMessageDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *AckTimeOutMessageDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    AckTimeOutMessage *pp = (AckTimeOutMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/AckTimeOutMessage_m.h b/src/veins/modules/messages/AckTimeOutMessage_m.h
new file mode 100644
index 0000000..8319da4
--- /dev/null
+++ b/src/veins/modules/messages/AckTimeOutMessage_m.h
@@ -0,0 +1,67 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/AckTimeOutMessage.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __ACKTIMEOUTMESSAGE_M_H
+#define __ACKTIMEOUTMESSAGE_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+/**
+ * Class generated from <tt>veins/modules/messages/AckTimeOutMessage.msg:21</tt> by nedtool.
+ * <pre>
+ * message AckTimeOutMessage
+ * {
+ *     // The corresponding WSM's tree id
+ *     unsigned long wsmId = -1;
+ *     // Access category on which the AckTimer is set
+ *     int ac = -1;
+ * }
+ * </pre>
+ */
+class AckTimeOutMessage : public ::omnetpp::cMessage
+{
+  protected:
+    unsigned long wsmId;
+    int ac;
+
+  private:
+    void copy(const AckTimeOutMessage& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const AckTimeOutMessage&);
+
+  public:
+    AckTimeOutMessage(const char *name=nullptr, short kind=0);
+    AckTimeOutMessage(const AckTimeOutMessage& other);
+    virtual ~AckTimeOutMessage();
+    AckTimeOutMessage& operator=(const AckTimeOutMessage& other);
+    virtual AckTimeOutMessage *dup() const override {return new AckTimeOutMessage(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual unsigned long getWsmId() const;
+    virtual void setWsmId(unsigned long wsmId);
+    virtual int getAc() const;
+    virtual void setAc(int ac);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const AckTimeOutMessage& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, AckTimeOutMessage& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __ACKTIMEOUTMESSAGE_M_H
+
diff --git a/src/veins/modules/messages/AirFrame11p_m.cc b/src/veins/modules/messages/AirFrame11p_m.cc
new file mode 100644
index 0000000..a6d6aef
--- /dev/null
+++ b/src/veins/modules/messages/AirFrame11p_m.cc
@@ -0,0 +1,480 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/AirFrame11p.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "AirFrame11p_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(AirFrame11p)
+
+AirFrame11p::AirFrame11p(const char *name, short kind) : ::AirFrame(name,kind)
+{
+    this->underSensitivity = false;
+    this->wasTransmitting = false;
+}
+
+AirFrame11p::AirFrame11p(const AirFrame11p& other) : ::AirFrame(other)
+{
+    copy(other);
+}
+
+AirFrame11p::~AirFrame11p()
+{
+}
+
+AirFrame11p& AirFrame11p::operator=(const AirFrame11p& other)
+{
+    if (this==&other) return *this;
+    ::AirFrame::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void AirFrame11p::copy(const AirFrame11p& other)
+{
+    this->underSensitivity = other.underSensitivity;
+    this->wasTransmitting = other.wasTransmitting;
+}
+
+void AirFrame11p::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::AirFrame::parsimPack(b);
+    doParsimPacking(b,this->underSensitivity);
+    doParsimPacking(b,this->wasTransmitting);
+}
+
+void AirFrame11p::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::AirFrame::parsimUnpack(b);
+    doParsimUnpacking(b,this->underSensitivity);
+    doParsimUnpacking(b,this->wasTransmitting);
+}
+
+bool AirFrame11p::getUnderSensitivity() const
+{
+    return this->underSensitivity;
+}
+
+void AirFrame11p::setUnderSensitivity(bool underSensitivity)
+{
+    this->underSensitivity = underSensitivity;
+}
+
+bool AirFrame11p::getWasTransmitting() const
+{
+    return this->wasTransmitting;
+}
+
+void AirFrame11p::setWasTransmitting(bool wasTransmitting)
+{
+    this->wasTransmitting = wasTransmitting;
+}
+
+class AirFrame11pDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    AirFrame11pDescriptor();
+    virtual ~AirFrame11pDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(AirFrame11pDescriptor)
+
+AirFrame11pDescriptor::AirFrame11pDescriptor() : omnetpp::cClassDescriptor("AirFrame11p", "AirFrame")
+{
+    propertynames = nullptr;
+}
+
+AirFrame11pDescriptor::~AirFrame11pDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool AirFrame11pDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<AirFrame11p *>(obj)!=nullptr;
+}
+
+const char **AirFrame11pDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *AirFrame11pDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int AirFrame11pDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 2+basedesc->getFieldCount() : 2;
+}
+
+unsigned int AirFrame11pDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<2) ? fieldTypeFlags[field] : 0;
+}
+
+const char *AirFrame11pDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "underSensitivity",
+        "wasTransmitting",
+    };
+    return (field>=0 && field<2) ? fieldNames[field] : nullptr;
+}
+
+int AirFrame11pDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='u' && strcmp(fieldName, "underSensitivity")==0) return base+0;
+    if (fieldName[0]=='w' && strcmp(fieldName, "wasTransmitting")==0) return base+1;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *AirFrame11pDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "bool",
+        "bool",
+    };
+    return (field>=0 && field<2) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **AirFrame11pDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *AirFrame11pDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int AirFrame11pDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    AirFrame11p *pp = (AirFrame11p *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *AirFrame11pDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    AirFrame11p *pp = (AirFrame11p *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string AirFrame11pDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    AirFrame11p *pp = (AirFrame11p *)object; (void)pp;
+    switch (field) {
+        case 0: return bool2string(pp->getUnderSensitivity());
+        case 1: return bool2string(pp->getWasTransmitting());
+        default: return "";
+    }
+}
+
+bool AirFrame11pDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    AirFrame11p *pp = (AirFrame11p *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setUnderSensitivity(string2bool(value)); return true;
+        case 1: pp->setWasTransmitting(string2bool(value)); return true;
+        default: return false;
+    }
+}
+
+const char *AirFrame11pDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *AirFrame11pDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    AirFrame11p *pp = (AirFrame11p *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/AirFrame11p_m.h b/src/veins/modules/messages/AirFrame11p_m.h
new file mode 100644
index 0000000..86c9859
--- /dev/null
+++ b/src/veins/modules/messages/AirFrame11p_m.h
@@ -0,0 +1,73 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/AirFrame11p.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __AIRFRAME11P_M_H
+#define __AIRFRAME11P_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+// cplusplus {{
+#include "veins/base/messages/AirFrame_m.h"
+using Veins::AirFrame;
+// }}
+
+/**
+ * Class generated from <tt>veins/modules/messages/AirFrame11p.msg:25</tt> by nedtool.
+ * <pre>
+ * //
+ * // Extension of base AirFrame message to have the underSensitivity field
+ * //
+ * message AirFrame11p extends AirFrame
+ * {
+ *     bool underSensitivity = false;
+ *     bool wasTransmitting = false;
+ * }
+ * </pre>
+ */
+class AirFrame11p : public ::AirFrame
+{
+  protected:
+    bool underSensitivity;
+    bool wasTransmitting;
+
+  private:
+    void copy(const AirFrame11p& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const AirFrame11p&);
+
+  public:
+    AirFrame11p(const char *name=nullptr, short kind=0);
+    AirFrame11p(const AirFrame11p& other);
+    virtual ~AirFrame11p();
+    AirFrame11p& operator=(const AirFrame11p& other);
+    virtual AirFrame11p *dup() const override {return new AirFrame11p(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual bool getUnderSensitivity() const;
+    virtual void setUnderSensitivity(bool underSensitivity);
+    virtual bool getWasTransmitting() const;
+    virtual void setWasTransmitting(bool wasTransmitting);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const AirFrame11p& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, AirFrame11p& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __AIRFRAME11P_M_H
+
diff --git a/src/veins/modules/messages/BasicSafetyMessage_m.cc b/src/veins/modules/messages/BasicSafetyMessage_m.cc
new file mode 100644
index 0000000..936e46b
--- /dev/null
+++ b/src/veins/modules/messages/BasicSafetyMessage_m.cc
@@ -0,0 +1,480 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/BasicSafetyMessage.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "BasicSafetyMessage_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(BasicSafetyMessage)
+
+BasicSafetyMessage::BasicSafetyMessage(const char *name, short kind) : ::WaveShortMessage(name,kind)
+{
+}
+
+BasicSafetyMessage::BasicSafetyMessage(const BasicSafetyMessage& other) : ::WaveShortMessage(other)
+{
+    copy(other);
+}
+
+BasicSafetyMessage::~BasicSafetyMessage()
+{
+}
+
+BasicSafetyMessage& BasicSafetyMessage::operator=(const BasicSafetyMessage& other)
+{
+    if (this==&other) return *this;
+    ::WaveShortMessage::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void BasicSafetyMessage::copy(const BasicSafetyMessage& other)
+{
+    this->senderPos = other.senderPos;
+    this->senderSpeed = other.senderSpeed;
+}
+
+void BasicSafetyMessage::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::WaveShortMessage::parsimPack(b);
+    doParsimPacking(b,this->senderPos);
+    doParsimPacking(b,this->senderSpeed);
+}
+
+void BasicSafetyMessage::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::WaveShortMessage::parsimUnpack(b);
+    doParsimUnpacking(b,this->senderPos);
+    doParsimUnpacking(b,this->senderSpeed);
+}
+
+Coord& BasicSafetyMessage::getSenderPos()
+{
+    return this->senderPos;
+}
+
+void BasicSafetyMessage::setSenderPos(const Coord& senderPos)
+{
+    this->senderPos = senderPos;
+}
+
+Coord& BasicSafetyMessage::getSenderSpeed()
+{
+    return this->senderSpeed;
+}
+
+void BasicSafetyMessage::setSenderSpeed(const Coord& senderSpeed)
+{
+    this->senderSpeed = senderSpeed;
+}
+
+class BasicSafetyMessageDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    BasicSafetyMessageDescriptor();
+    virtual ~BasicSafetyMessageDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(BasicSafetyMessageDescriptor)
+
+BasicSafetyMessageDescriptor::BasicSafetyMessageDescriptor() : omnetpp::cClassDescriptor("BasicSafetyMessage", "WaveShortMessage")
+{
+    propertynames = nullptr;
+}
+
+BasicSafetyMessageDescriptor::~BasicSafetyMessageDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool BasicSafetyMessageDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<BasicSafetyMessage *>(obj)!=nullptr;
+}
+
+const char **BasicSafetyMessageDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *BasicSafetyMessageDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int BasicSafetyMessageDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 2+basedesc->getFieldCount() : 2;
+}
+
+unsigned int BasicSafetyMessageDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISCOMPOUND,
+        FD_ISCOMPOUND,
+    };
+    return (field>=0 && field<2) ? fieldTypeFlags[field] : 0;
+}
+
+const char *BasicSafetyMessageDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "senderPos",
+        "senderSpeed",
+    };
+    return (field>=0 && field<2) ? fieldNames[field] : nullptr;
+}
+
+int BasicSafetyMessageDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='s' && strcmp(fieldName, "senderPos")==0) return base+0;
+    if (fieldName[0]=='s' && strcmp(fieldName, "senderSpeed")==0) return base+1;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *BasicSafetyMessageDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "Coord",
+        "Coord",
+    };
+    return (field>=0 && field<2) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **BasicSafetyMessageDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *BasicSafetyMessageDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int BasicSafetyMessageDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    BasicSafetyMessage *pp = (BasicSafetyMessage *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *BasicSafetyMessageDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    BasicSafetyMessage *pp = (BasicSafetyMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string BasicSafetyMessageDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    BasicSafetyMessage *pp = (BasicSafetyMessage *)object; (void)pp;
+    switch (field) {
+        case 0: {std::stringstream out; out << pp->getSenderPos(); return out.str();}
+        case 1: {std::stringstream out; out << pp->getSenderSpeed(); return out.str();}
+        default: return "";
+    }
+}
+
+bool BasicSafetyMessageDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    BasicSafetyMessage *pp = (BasicSafetyMessage *)object; (void)pp;
+    switch (field) {
+        default: return false;
+    }
+}
+
+const char *BasicSafetyMessageDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        case 0: return omnetpp::opp_typename(typeid(Coord));
+        case 1: return omnetpp::opp_typename(typeid(Coord));
+        default: return nullptr;
+    };
+}
+
+void *BasicSafetyMessageDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    BasicSafetyMessage *pp = (BasicSafetyMessage *)object; (void)pp;
+    switch (field) {
+        case 0: return (void *)(&pp->getSenderPos()); break;
+        case 1: return (void *)(&pp->getSenderSpeed()); break;
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/BasicSafetyMessage_m.h b/src/veins/modules/messages/BasicSafetyMessage_m.h
new file mode 100644
index 0000000..6c9cea2
--- /dev/null
+++ b/src/veins/modules/messages/BasicSafetyMessage_m.h
@@ -0,0 +1,72 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/BasicSafetyMessage.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __BASICSAFETYMESSAGE_M_H
+#define __BASICSAFETYMESSAGE_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+// cplusplus {{
+#include "veins/base/utils/Coord.h"
+#include "veins/modules/messages/WaveShortMessage_m.h"
+// }}
+
+/**
+ * Class generated from <tt>veins/modules/messages/BasicSafetyMessage.msg:29</tt> by nedtool.
+ * <pre>
+ * packet BasicSafetyMessage extends WaveShortMessage
+ * {
+ *     Coord senderPos;
+ *     Coord senderSpeed;
+ * }
+ * </pre>
+ */
+class BasicSafetyMessage : public ::WaveShortMessage
+{
+  protected:
+    Coord senderPos;
+    Coord senderSpeed;
+
+  private:
+    void copy(const BasicSafetyMessage& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const BasicSafetyMessage&);
+
+  public:
+    BasicSafetyMessage(const char *name=nullptr, short kind=0);
+    BasicSafetyMessage(const BasicSafetyMessage& other);
+    virtual ~BasicSafetyMessage();
+    BasicSafetyMessage& operator=(const BasicSafetyMessage& other);
+    virtual BasicSafetyMessage *dup() const override {return new BasicSafetyMessage(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual Coord& getSenderPos();
+    virtual const Coord& getSenderPos() const {return const_cast<BasicSafetyMessage*>(this)->getSenderPos();}
+    virtual void setSenderPos(const Coord& senderPos);
+    virtual Coord& getSenderSpeed();
+    virtual const Coord& getSenderSpeed() const {return const_cast<BasicSafetyMessage*>(this)->getSenderSpeed();}
+    virtual void setSenderSpeed(const Coord& senderSpeed);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const BasicSafetyMessage& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, BasicSafetyMessage& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __BASICSAFETYMESSAGE_M_H
+
diff --git a/src/veins/modules/messages/Mac80211Ack_m.cc b/src/veins/modules/messages/Mac80211Ack_m.cc
new file mode 100644
index 0000000..933583a
--- /dev/null
+++ b/src/veins/modules/messages/Mac80211Ack_m.cc
@@ -0,0 +1,460 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/Mac80211Ack.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "Mac80211Ack_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(Mac80211Ack)
+
+Mac80211Ack::Mac80211Ack(const char *name, short kind) : ::Mac80211Pkt(name,kind)
+{
+    this->messageId = 0;
+}
+
+Mac80211Ack::Mac80211Ack(const Mac80211Ack& other) : ::Mac80211Pkt(other)
+{
+    copy(other);
+}
+
+Mac80211Ack::~Mac80211Ack()
+{
+}
+
+Mac80211Ack& Mac80211Ack::operator=(const Mac80211Ack& other)
+{
+    if (this==&other) return *this;
+    ::Mac80211Pkt::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void Mac80211Ack::copy(const Mac80211Ack& other)
+{
+    this->messageId = other.messageId;
+}
+
+void Mac80211Ack::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::Mac80211Pkt::parsimPack(b);
+    doParsimPacking(b,this->messageId);
+}
+
+void Mac80211Ack::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::Mac80211Pkt::parsimUnpack(b);
+    doParsimUnpacking(b,this->messageId);
+}
+
+unsigned long Mac80211Ack::getMessageId() const
+{
+    return this->messageId;
+}
+
+void Mac80211Ack::setMessageId(unsigned long messageId)
+{
+    this->messageId = messageId;
+}
+
+class Mac80211AckDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    Mac80211AckDescriptor();
+    virtual ~Mac80211AckDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(Mac80211AckDescriptor)
+
+Mac80211AckDescriptor::Mac80211AckDescriptor() : omnetpp::cClassDescriptor("Mac80211Ack", "Mac80211Pkt")
+{
+    propertynames = nullptr;
+}
+
+Mac80211AckDescriptor::~Mac80211AckDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool Mac80211AckDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<Mac80211Ack *>(obj)!=nullptr;
+}
+
+const char **Mac80211AckDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *Mac80211AckDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int Mac80211AckDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 1+basedesc->getFieldCount() : 1;
+}
+
+unsigned int Mac80211AckDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<1) ? fieldTypeFlags[field] : 0;
+}
+
+const char *Mac80211AckDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "messageId",
+    };
+    return (field>=0 && field<1) ? fieldNames[field] : nullptr;
+}
+
+int Mac80211AckDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='m' && strcmp(fieldName, "messageId")==0) return base+0;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *Mac80211AckDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "unsigned long",
+    };
+    return (field>=0 && field<1) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **Mac80211AckDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *Mac80211AckDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int Mac80211AckDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Ack *pp = (Mac80211Ack *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *Mac80211AckDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Ack *pp = (Mac80211Ack *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string Mac80211AckDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Ack *pp = (Mac80211Ack *)object; (void)pp;
+    switch (field) {
+        case 0: return ulong2string(pp->getMessageId());
+        default: return "";
+    }
+}
+
+bool Mac80211AckDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Ack *pp = (Mac80211Ack *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setMessageId(string2ulong(value)); return true;
+        default: return false;
+    }
+}
+
+const char *Mac80211AckDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *Mac80211AckDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Ack *pp = (Mac80211Ack *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/Mac80211Ack_m.h b/src/veins/modules/messages/Mac80211Ack_m.h
new file mode 100644
index 0000000..ed5c583
--- /dev/null
+++ b/src/veins/modules/messages/Mac80211Ack_m.h
@@ -0,0 +1,65 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/Mac80211Ack.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __MAC80211ACK_M_H
+#define __MAC80211ACK_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+// cplusplus {{
+	#include "veins/modules/messages/Mac80211Pkt_m.h"
+// }}
+
+/**
+ * Class generated from <tt>veins/modules/messages/Mac80211Ack.msg:26</tt> by nedtool.
+ * <pre>
+ * packet Mac80211Ack extends Mac80211Pkt
+ * {
+ *     unsigned long messageId; // The ID of the aknowledged packet
+ * }
+ * </pre>
+ */
+class Mac80211Ack : public ::Mac80211Pkt
+{
+  protected:
+    unsigned long messageId;
+
+  private:
+    void copy(const Mac80211Ack& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const Mac80211Ack&);
+
+  public:
+    Mac80211Ack(const char *name=nullptr, short kind=0);
+    Mac80211Ack(const Mac80211Ack& other);
+    virtual ~Mac80211Ack();
+    Mac80211Ack& operator=(const Mac80211Ack& other);
+    virtual Mac80211Ack *dup() const override {return new Mac80211Ack(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual unsigned long getMessageId() const;
+    virtual void setMessageId(unsigned long messageId);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const Mac80211Ack& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, Mac80211Ack& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __MAC80211ACK_M_H
+
diff --git a/src/veins/modules/messages/Mac80211Pkt_m.cc b/src/veins/modules/messages/Mac80211Pkt_m.cc
new file mode 100644
index 0000000..23d0a48
--- /dev/null
+++ b/src/veins/modules/messages/Mac80211Pkt_m.cc
@@ -0,0 +1,580 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/Mac80211Pkt.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "Mac80211Pkt_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(Mac80211Pkt)
+
+Mac80211Pkt::Mac80211Pkt(const char *name, short kind) : ::MacPkt(name,kind)
+{
+    this->address3 = 0;
+    this->address4 = 0;
+    this->fragmentation = 0;
+    this->informationDS = 0;
+    this->sequenceControl = 0;
+    this->retry = false;
+    this->duration = 0;
+}
+
+Mac80211Pkt::Mac80211Pkt(const Mac80211Pkt& other) : ::MacPkt(other)
+{
+    copy(other);
+}
+
+Mac80211Pkt::~Mac80211Pkt()
+{
+}
+
+Mac80211Pkt& Mac80211Pkt::operator=(const Mac80211Pkt& other)
+{
+    if (this==&other) return *this;
+    ::MacPkt::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void Mac80211Pkt::copy(const Mac80211Pkt& other)
+{
+    this->address3 = other.address3;
+    this->address4 = other.address4;
+    this->fragmentation = other.fragmentation;
+    this->informationDS = other.informationDS;
+    this->sequenceControl = other.sequenceControl;
+    this->retry = other.retry;
+    this->duration = other.duration;
+}
+
+void Mac80211Pkt::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::MacPkt::parsimPack(b);
+    doParsimPacking(b,this->address3);
+    doParsimPacking(b,this->address4);
+    doParsimPacking(b,this->fragmentation);
+    doParsimPacking(b,this->informationDS);
+    doParsimPacking(b,this->sequenceControl);
+    doParsimPacking(b,this->retry);
+    doParsimPacking(b,this->duration);
+}
+
+void Mac80211Pkt::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::MacPkt::parsimUnpack(b);
+    doParsimUnpacking(b,this->address3);
+    doParsimUnpacking(b,this->address4);
+    doParsimUnpacking(b,this->fragmentation);
+    doParsimUnpacking(b,this->informationDS);
+    doParsimUnpacking(b,this->sequenceControl);
+    doParsimUnpacking(b,this->retry);
+    doParsimUnpacking(b,this->duration);
+}
+
+int Mac80211Pkt::getAddress3() const
+{
+    return this->address3;
+}
+
+void Mac80211Pkt::setAddress3(int address3)
+{
+    this->address3 = address3;
+}
+
+int Mac80211Pkt::getAddress4() const
+{
+    return this->address4;
+}
+
+void Mac80211Pkt::setAddress4(int address4)
+{
+    this->address4 = address4;
+}
+
+int Mac80211Pkt::getFragmentation() const
+{
+    return this->fragmentation;
+}
+
+void Mac80211Pkt::setFragmentation(int fragmentation)
+{
+    this->fragmentation = fragmentation;
+}
+
+int Mac80211Pkt::getInformationDS() const
+{
+    return this->informationDS;
+}
+
+void Mac80211Pkt::setInformationDS(int informationDS)
+{
+    this->informationDS = informationDS;
+}
+
+int Mac80211Pkt::getSequenceControl() const
+{
+    return this->sequenceControl;
+}
+
+void Mac80211Pkt::setSequenceControl(int sequenceControl)
+{
+    this->sequenceControl = sequenceControl;
+}
+
+bool Mac80211Pkt::getRetry() const
+{
+    return this->retry;
+}
+
+void Mac80211Pkt::setRetry(bool retry)
+{
+    this->retry = retry;
+}
+
+::omnetpp::simtime_t Mac80211Pkt::getDuration() const
+{
+    return this->duration;
+}
+
+void Mac80211Pkt::setDuration(::omnetpp::simtime_t duration)
+{
+    this->duration = duration;
+}
+
+class Mac80211PktDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    Mac80211PktDescriptor();
+    virtual ~Mac80211PktDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(Mac80211PktDescriptor)
+
+Mac80211PktDescriptor::Mac80211PktDescriptor() : omnetpp::cClassDescriptor("Mac80211Pkt", "MacPkt")
+{
+    propertynames = nullptr;
+}
+
+Mac80211PktDescriptor::~Mac80211PktDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool Mac80211PktDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<Mac80211Pkt *>(obj)!=nullptr;
+}
+
+const char **Mac80211PktDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *Mac80211PktDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int Mac80211PktDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 7+basedesc->getFieldCount() : 7;
+}
+
+unsigned int Mac80211PktDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<7) ? fieldTypeFlags[field] : 0;
+}
+
+const char *Mac80211PktDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "address3",
+        "address4",
+        "fragmentation",
+        "informationDS",
+        "sequenceControl",
+        "retry",
+        "duration",
+    };
+    return (field>=0 && field<7) ? fieldNames[field] : nullptr;
+}
+
+int Mac80211PktDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='a' && strcmp(fieldName, "address3")==0) return base+0;
+    if (fieldName[0]=='a' && strcmp(fieldName, "address4")==0) return base+1;
+    if (fieldName[0]=='f' && strcmp(fieldName, "fragmentation")==0) return base+2;
+    if (fieldName[0]=='i' && strcmp(fieldName, "informationDS")==0) return base+3;
+    if (fieldName[0]=='s' && strcmp(fieldName, "sequenceControl")==0) return base+4;
+    if (fieldName[0]=='r' && strcmp(fieldName, "retry")==0) return base+5;
+    if (fieldName[0]=='d' && strcmp(fieldName, "duration")==0) return base+6;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *Mac80211PktDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "int",
+        "int",
+        "int",
+        "int",
+        "int",
+        "bool",
+        "simtime_t",
+    };
+    return (field>=0 && field<7) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **Mac80211PktDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *Mac80211PktDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int Mac80211PktDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Pkt *pp = (Mac80211Pkt *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *Mac80211PktDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Pkt *pp = (Mac80211Pkt *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string Mac80211PktDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Pkt *pp = (Mac80211Pkt *)object; (void)pp;
+    switch (field) {
+        case 0: return long2string(pp->getAddress3());
+        case 1: return long2string(pp->getAddress4());
+        case 2: return long2string(pp->getFragmentation());
+        case 3: return long2string(pp->getInformationDS());
+        case 4: return long2string(pp->getSequenceControl());
+        case 5: return bool2string(pp->getRetry());
+        case 6: return simtime2string(pp->getDuration());
+        default: return "";
+    }
+}
+
+bool Mac80211PktDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Pkt *pp = (Mac80211Pkt *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setAddress3(string2long(value)); return true;
+        case 1: pp->setAddress4(string2long(value)); return true;
+        case 2: pp->setFragmentation(string2long(value)); return true;
+        case 3: pp->setInformationDS(string2long(value)); return true;
+        case 4: pp->setSequenceControl(string2long(value)); return true;
+        case 5: pp->setRetry(string2bool(value)); return true;
+        case 6: pp->setDuration(string2simtime(value)); return true;
+        default: return false;
+    }
+}
+
+const char *Mac80211PktDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *Mac80211PktDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    Mac80211Pkt *pp = (Mac80211Pkt *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/Mac80211Pkt_m.h b/src/veins/modules/messages/Mac80211Pkt_m.h
new file mode 100644
index 0000000..1fbdf4b
--- /dev/null
+++ b/src/veins/modules/messages/Mac80211Pkt_m.h
@@ -0,0 +1,92 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/Mac80211Pkt.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __MAC80211PKT_M_H
+#define __MAC80211PKT_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+// cplusplus {{
+#include "veins/base/messages/MacPkt_m.h"
+// }}
+
+/**
+ * Class generated from <tt>veins/modules/messages/Mac80211Pkt.msg:24</tt> by nedtool.
+ * <pre>
+ * //
+ * // Defines all fields of an 802.11 MAC frame
+ * //
+ * packet Mac80211Pkt extends MacPkt
+ * {
+ *     int address3;
+ *     int address4;
+ *     int fragmentation; //part of the Frame Control field
+ *     int informationDS; //part of the Frame Control field
+ *     int sequenceControl;
+ *     bool retry;
+ *     simtime_t duration; 	//the expected remaining duration the current transaction 
+ * }
+ * </pre>
+ */
+class Mac80211Pkt : public ::MacPkt
+{
+  protected:
+    int address3;
+    int address4;
+    int fragmentation;
+    int informationDS;
+    int sequenceControl;
+    bool retry;
+    ::omnetpp::simtime_t duration;
+
+  private:
+    void copy(const Mac80211Pkt& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const Mac80211Pkt&);
+
+  public:
+    Mac80211Pkt(const char *name=nullptr, short kind=0);
+    Mac80211Pkt(const Mac80211Pkt& other);
+    virtual ~Mac80211Pkt();
+    Mac80211Pkt& operator=(const Mac80211Pkt& other);
+    virtual Mac80211Pkt *dup() const override {return new Mac80211Pkt(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual int getAddress3() const;
+    virtual void setAddress3(int address3);
+    virtual int getAddress4() const;
+    virtual void setAddress4(int address4);
+    virtual int getFragmentation() const;
+    virtual void setFragmentation(int fragmentation);
+    virtual int getInformationDS() const;
+    virtual void setInformationDS(int informationDS);
+    virtual int getSequenceControl() const;
+    virtual void setSequenceControl(int sequenceControl);
+    virtual bool getRetry() const;
+    virtual void setRetry(bool retry);
+    virtual ::omnetpp::simtime_t getDuration() const;
+    virtual void setDuration(::omnetpp::simtime_t duration);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const Mac80211Pkt& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, Mac80211Pkt& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __MAC80211PKT_M_H
+
diff --git a/src/veins/modules/messages/PhyControlMessage_m.cc b/src/veins/modules/messages/PhyControlMessage_m.cc
new file mode 100644
index 0000000..39c3914
--- /dev/null
+++ b/src/veins/modules/messages/PhyControlMessage_m.cc
@@ -0,0 +1,480 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/PhyControlMessage.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "PhyControlMessage_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(PhyControlMessage)
+
+PhyControlMessage::PhyControlMessage(const char *name, short kind) : ::omnetpp::cMessage(name,kind)
+{
+    this->mcs = -1;
+    this->txPower_mW = -1;
+}
+
+PhyControlMessage::PhyControlMessage(const PhyControlMessage& other) : ::omnetpp::cMessage(other)
+{
+    copy(other);
+}
+
+PhyControlMessage::~PhyControlMessage()
+{
+}
+
+PhyControlMessage& PhyControlMessage::operator=(const PhyControlMessage& other)
+{
+    if (this==&other) return *this;
+    ::omnetpp::cMessage::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void PhyControlMessage::copy(const PhyControlMessage& other)
+{
+    this->mcs = other.mcs;
+    this->txPower_mW = other.txPower_mW;
+}
+
+void PhyControlMessage::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::omnetpp::cMessage::parsimPack(b);
+    doParsimPacking(b,this->mcs);
+    doParsimPacking(b,this->txPower_mW);
+}
+
+void PhyControlMessage::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::omnetpp::cMessage::parsimUnpack(b);
+    doParsimUnpacking(b,this->mcs);
+    doParsimUnpacking(b,this->txPower_mW);
+}
+
+int PhyControlMessage::getMcs() const
+{
+    return this->mcs;
+}
+
+void PhyControlMessage::setMcs(int mcs)
+{
+    this->mcs = mcs;
+}
+
+double PhyControlMessage::getTxPower_mW() const
+{
+    return this->txPower_mW;
+}
+
+void PhyControlMessage::setTxPower_mW(double txPower_mW)
+{
+    this->txPower_mW = txPower_mW;
+}
+
+class PhyControlMessageDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    PhyControlMessageDescriptor();
+    virtual ~PhyControlMessageDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(PhyControlMessageDescriptor)
+
+PhyControlMessageDescriptor::PhyControlMessageDescriptor() : omnetpp::cClassDescriptor("PhyControlMessage", "omnetpp::cMessage")
+{
+    propertynames = nullptr;
+}
+
+PhyControlMessageDescriptor::~PhyControlMessageDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool PhyControlMessageDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<PhyControlMessage *>(obj)!=nullptr;
+}
+
+const char **PhyControlMessageDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *PhyControlMessageDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int PhyControlMessageDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 2+basedesc->getFieldCount() : 2;
+}
+
+unsigned int PhyControlMessageDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<2) ? fieldTypeFlags[field] : 0;
+}
+
+const char *PhyControlMessageDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "mcs",
+        "txPower_mW",
+    };
+    return (field>=0 && field<2) ? fieldNames[field] : nullptr;
+}
+
+int PhyControlMessageDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='m' && strcmp(fieldName, "mcs")==0) return base+0;
+    if (fieldName[0]=='t' && strcmp(fieldName, "txPower_mW")==0) return base+1;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *PhyControlMessageDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "int",
+        "double",
+    };
+    return (field>=0 && field<2) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **PhyControlMessageDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *PhyControlMessageDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int PhyControlMessageDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    PhyControlMessage *pp = (PhyControlMessage *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *PhyControlMessageDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    PhyControlMessage *pp = (PhyControlMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string PhyControlMessageDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    PhyControlMessage *pp = (PhyControlMessage *)object; (void)pp;
+    switch (field) {
+        case 0: return long2string(pp->getMcs());
+        case 1: return double2string(pp->getTxPower_mW());
+        default: return "";
+    }
+}
+
+bool PhyControlMessageDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    PhyControlMessage *pp = (PhyControlMessage *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setMcs(string2long(value)); return true;
+        case 1: pp->setTxPower_mW(string2double(value)); return true;
+        default: return false;
+    }
+}
+
+const char *PhyControlMessageDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *PhyControlMessageDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    PhyControlMessage *pp = (PhyControlMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/PhyControlMessage_m.h b/src/veins/modules/messages/PhyControlMessage_m.h
new file mode 100644
index 0000000..47cbad3
--- /dev/null
+++ b/src/veins/modules/messages/PhyControlMessage_m.h
@@ -0,0 +1,71 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/PhyControlMessage.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __PHYCONTROLMESSAGE_M_H
+#define __PHYCONTROLMESSAGE_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+/**
+ * Class generated from <tt>veins/modules/messages/PhyControlMessage.msg:22</tt> by nedtool.
+ * <pre>
+ * //
+ * // Defines a control message that can be associated with a MAC frame to set
+ * // transmission power and datarate on a per packet basis
+ * //
+ * message PhyControlMessage
+ * {
+ *     //modulation and coding scheme to be used (see enum TxMCS in ConstsPhy.h)
+ *     int mcs = -1;
+ *     //transmission power to be used in mW
+ *     double txPower_mW = -1;
+ * }
+ * </pre>
+ */
+class PhyControlMessage : public ::omnetpp::cMessage
+{
+  protected:
+    int mcs;
+    double txPower_mW;
+
+  private:
+    void copy(const PhyControlMessage& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const PhyControlMessage&);
+
+  public:
+    PhyControlMessage(const char *name=nullptr, short kind=0);
+    PhyControlMessage(const PhyControlMessage& other);
+    virtual ~PhyControlMessage();
+    PhyControlMessage& operator=(const PhyControlMessage& other);
+    virtual PhyControlMessage *dup() const override {return new PhyControlMessage(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual int getMcs() const;
+    virtual void setMcs(int mcs);
+    virtual double getTxPower_mW() const;
+    virtual void setTxPower_mW(double txPower_mW);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const PhyControlMessage& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, PhyControlMessage& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __PHYCONTROLMESSAGE_M_H
+
diff --git a/src/veins/modules/messages/TraCITrafficLightMessage_m.cc b/src/veins/modules/messages/TraCITrafficLightMessage_m.cc
new file mode 100644
index 0000000..dd71139
--- /dev/null
+++ b/src/veins/modules/messages/TraCITrafficLightMessage_m.cc
@@ -0,0 +1,570 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/TraCITrafficLightMessage.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "TraCITrafficLightMessage_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+EXECUTE_ON_STARTUP(
+    omnetpp::cEnum *e = omnetpp::cEnum::find("TrafficLightAtrributeType");
+    if (!e) omnetpp::enums.getInstance()->add(e = new omnetpp::cEnum("TrafficLightAtrributeType"));
+    e->insert(NONE, "NONE");
+    e->insert(LOGICID, "LOGICID");
+    e->insert(PHASEID, "PHASEID");
+    e->insert(SWITCHTIME, "SWITCHTIME");
+    e->insert(STATE, "STATE");
+)
+
+EXECUTE_ON_STARTUP(
+    omnetpp::cEnum *e = omnetpp::cEnum::find("TrafficLightChangeSource");
+    if (!e) omnetpp::enums.getInstance()->add(e = new omnetpp::cEnum("TrafficLightChangeSource"));
+    e->insert(UNKNOWN, "UNKNOWN");
+    e->insert(SUMO, "SUMO");
+    e->insert(LOGIC, "LOGIC");
+    e->insert(RSU, "RSU");
+)
+
+Register_Class(TraCITrafficLightMessage)
+
+TraCITrafficLightMessage::TraCITrafficLightMessage(const char *name, short kind) : ::omnetpp::cMessage(name,kind)
+{
+    this->changedAttribute = 0;
+    this->changeSource = 0;
+}
+
+TraCITrafficLightMessage::TraCITrafficLightMessage(const TraCITrafficLightMessage& other) : ::omnetpp::cMessage(other)
+{
+    copy(other);
+}
+
+TraCITrafficLightMessage::~TraCITrafficLightMessage()
+{
+}
+
+TraCITrafficLightMessage& TraCITrafficLightMessage::operator=(const TraCITrafficLightMessage& other)
+{
+    if (this==&other) return *this;
+    ::omnetpp::cMessage::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void TraCITrafficLightMessage::copy(const TraCITrafficLightMessage& other)
+{
+    this->tlId = other.tlId;
+    this->changedAttribute = other.changedAttribute;
+    this->oldValue = other.oldValue;
+    this->newValue = other.newValue;
+    this->changeSource = other.changeSource;
+}
+
+void TraCITrafficLightMessage::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::omnetpp::cMessage::parsimPack(b);
+    doParsimPacking(b,this->tlId);
+    doParsimPacking(b,this->changedAttribute);
+    doParsimPacking(b,this->oldValue);
+    doParsimPacking(b,this->newValue);
+    doParsimPacking(b,this->changeSource);
+}
+
+void TraCITrafficLightMessage::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::omnetpp::cMessage::parsimUnpack(b);
+    doParsimUnpacking(b,this->tlId);
+    doParsimUnpacking(b,this->changedAttribute);
+    doParsimUnpacking(b,this->oldValue);
+    doParsimUnpacking(b,this->newValue);
+    doParsimUnpacking(b,this->changeSource);
+}
+
+const char * TraCITrafficLightMessage::getTlId() const
+{
+    return this->tlId.c_str();
+}
+
+void TraCITrafficLightMessage::setTlId(const char * tlId)
+{
+    this->tlId = tlId;
+}
+
+int TraCITrafficLightMessage::getChangedAttribute() const
+{
+    return this->changedAttribute;
+}
+
+void TraCITrafficLightMessage::setChangedAttribute(int changedAttribute)
+{
+    this->changedAttribute = changedAttribute;
+}
+
+const char * TraCITrafficLightMessage::getOldValue() const
+{
+    return this->oldValue.c_str();
+}
+
+void TraCITrafficLightMessage::setOldValue(const char * oldValue)
+{
+    this->oldValue = oldValue;
+}
+
+const char * TraCITrafficLightMessage::getNewValue() const
+{
+    return this->newValue.c_str();
+}
+
+void TraCITrafficLightMessage::setNewValue(const char * newValue)
+{
+    this->newValue = newValue;
+}
+
+int TraCITrafficLightMessage::getChangeSource() const
+{
+    return this->changeSource;
+}
+
+void TraCITrafficLightMessage::setChangeSource(int changeSource)
+{
+    this->changeSource = changeSource;
+}
+
+class TraCITrafficLightMessageDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    TraCITrafficLightMessageDescriptor();
+    virtual ~TraCITrafficLightMessageDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(TraCITrafficLightMessageDescriptor)
+
+TraCITrafficLightMessageDescriptor::TraCITrafficLightMessageDescriptor() : omnetpp::cClassDescriptor("TraCITrafficLightMessage", "omnetpp::cMessage")
+{
+    propertynames = nullptr;
+}
+
+TraCITrafficLightMessageDescriptor::~TraCITrafficLightMessageDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool TraCITrafficLightMessageDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<TraCITrafficLightMessage *>(obj)!=nullptr;
+}
+
+const char **TraCITrafficLightMessageDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *TraCITrafficLightMessageDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int TraCITrafficLightMessageDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 5+basedesc->getFieldCount() : 5;
+}
+
+unsigned int TraCITrafficLightMessageDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<5) ? fieldTypeFlags[field] : 0;
+}
+
+const char *TraCITrafficLightMessageDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "tlId",
+        "changedAttribute",
+        "oldValue",
+        "newValue",
+        "changeSource",
+    };
+    return (field>=0 && field<5) ? fieldNames[field] : nullptr;
+}
+
+int TraCITrafficLightMessageDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='t' && strcmp(fieldName, "tlId")==0) return base+0;
+    if (fieldName[0]=='c' && strcmp(fieldName, "changedAttribute")==0) return base+1;
+    if (fieldName[0]=='o' && strcmp(fieldName, "oldValue")==0) return base+2;
+    if (fieldName[0]=='n' && strcmp(fieldName, "newValue")==0) return base+3;
+    if (fieldName[0]=='c' && strcmp(fieldName, "changeSource")==0) return base+4;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *TraCITrafficLightMessageDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "string",
+        "int",
+        "string",
+        "string",
+        "int",
+    };
+    return (field>=0 && field<5) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **TraCITrafficLightMessageDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        case 1: {
+            static const char *names[] = { "enum",  nullptr };
+            return names;
+        }
+        case 4: {
+            static const char *names[] = { "enum",  nullptr };
+            return names;
+        }
+        default: return nullptr;
+    }
+}
+
+const char *TraCITrafficLightMessageDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        case 1:
+            if (!strcmp(propertyname,"enum")) return "TrafficLightAtrributeType";
+            return nullptr;
+        case 4:
+            if (!strcmp(propertyname,"enum")) return "TrafficLightChangeSource";
+            return nullptr;
+        default: return nullptr;
+    }
+}
+
+int TraCITrafficLightMessageDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    TraCITrafficLightMessage *pp = (TraCITrafficLightMessage *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *TraCITrafficLightMessageDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    TraCITrafficLightMessage *pp = (TraCITrafficLightMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string TraCITrafficLightMessageDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    TraCITrafficLightMessage *pp = (TraCITrafficLightMessage *)object; (void)pp;
+    switch (field) {
+        case 0: return oppstring2string(pp->getTlId());
+        case 1: return enum2string(pp->getChangedAttribute(), "TrafficLightAtrributeType");
+        case 2: return oppstring2string(pp->getOldValue());
+        case 3: return oppstring2string(pp->getNewValue());
+        case 4: return enum2string(pp->getChangeSource(), "TrafficLightChangeSource");
+        default: return "";
+    }
+}
+
+bool TraCITrafficLightMessageDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    TraCITrafficLightMessage *pp = (TraCITrafficLightMessage *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setTlId((value)); return true;
+        case 1: pp->setChangedAttribute((TrafficLightAtrributeType)string2enum(value, "TrafficLightAtrributeType")); return true;
+        case 2: pp->setOldValue((value)); return true;
+        case 3: pp->setNewValue((value)); return true;
+        case 4: pp->setChangeSource((TrafficLightChangeSource)string2enum(value, "TrafficLightChangeSource")); return true;
+        default: return false;
+    }
+}
+
+const char *TraCITrafficLightMessageDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *TraCITrafficLightMessageDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    TraCITrafficLightMessage *pp = (TraCITrafficLightMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/TraCITrafficLightMessage_m.h b/src/veins/modules/messages/TraCITrafficLightMessage_m.h
new file mode 100644
index 0000000..5532d3b
--- /dev/null
+++ b/src/veins/modules/messages/TraCITrafficLightMessage_m.h
@@ -0,0 +1,123 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/TraCITrafficLightMessage.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __TRACITRAFFICLIGHTMESSAGE_M_H
+#define __TRACITRAFFICLIGHTMESSAGE_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+/**
+ * Enum generated from <tt>veins/modules/messages/TraCITrafficLightMessage.msg:22</tt> by nedtool.
+ * <pre>
+ * enum TrafficLightAtrributeType
+ * {
+ *     NONE = 0;
+ *     LOGICID = 1;
+ *     PHASEID = 2;
+ *     SWITCHTIME = 3;
+ *     STATE = 4;
+ * }
+ * </pre>
+ */
+enum TrafficLightAtrributeType {
+    NONE = 0,
+    LOGICID = 1,
+    PHASEID = 2,
+    SWITCHTIME = 3,
+    STATE = 4
+};
+
+/**
+ * Enum generated from <tt>veins/modules/messages/TraCITrafficLightMessage.msg:30</tt> by nedtool.
+ * <pre>
+ * enum TrafficLightChangeSource
+ * {
+ *     UNKNOWN = 0;
+ *     SUMO = 1;
+ *     LOGIC = 2;
+ *     RSU = 3;//If an RSU tries to change the values
+ * }
+ * </pre>
+ */
+enum TrafficLightChangeSource {
+    UNKNOWN = 0,
+    SUMO = 1,
+    LOGIC = 2,
+    RSU = 3
+};
+
+/**
+ * Class generated from <tt>veins/modules/messages/TraCITrafficLightMessage.msg:38</tt> by nedtool.
+ * <pre>
+ * // NOTE: Currently only supports changes of the IDs (due to variation in field types)
+ * message TraCITrafficLightMessage
+ * {
+ *     // traffic light id
+ *     string tlId;
+ *     // what field/attrbute of the traffic light changed?
+ *     int changedAttribute \@enum(TrafficLightAtrributeType);
+ *     // value before the change
+ *     string oldValue;
+ *     // value that is to be set / was newly set
+ *     string newValue;
+ *     // where did the change originate
+ *     int changeSource \@enum(TrafficLightChangeSource);
+ * }
+ * </pre>
+ */
+class TraCITrafficLightMessage : public ::omnetpp::cMessage
+{
+  protected:
+    ::omnetpp::opp_string tlId;
+    int changedAttribute;
+    ::omnetpp::opp_string oldValue;
+    ::omnetpp::opp_string newValue;
+    int changeSource;
+
+  private:
+    void copy(const TraCITrafficLightMessage& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const TraCITrafficLightMessage&);
+
+  public:
+    TraCITrafficLightMessage(const char *name=nullptr, short kind=0);
+    TraCITrafficLightMessage(const TraCITrafficLightMessage& other);
+    virtual ~TraCITrafficLightMessage();
+    TraCITrafficLightMessage& operator=(const TraCITrafficLightMessage& other);
+    virtual TraCITrafficLightMessage *dup() const override {return new TraCITrafficLightMessage(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual const char * getTlId() const;
+    virtual void setTlId(const char * tlId);
+    virtual int getChangedAttribute() const;
+    virtual void setChangedAttribute(int changedAttribute);
+    virtual const char * getOldValue() const;
+    virtual void setOldValue(const char * oldValue);
+    virtual const char * getNewValue() const;
+    virtual void setNewValue(const char * newValue);
+    virtual int getChangeSource() const;
+    virtual void setChangeSource(int changeSource);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const TraCITrafficLightMessage& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, TraCITrafficLightMessage& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __TRACITRAFFICLIGHTMESSAGE_M_H
+
diff --git a/src/veins/modules/messages/WaveServiceAdvertisement_m.cc b/src/veins/modules/messages/WaveServiceAdvertisement_m.cc
new file mode 100644
index 0000000..287a7cb
--- /dev/null
+++ b/src/veins/modules/messages/WaveServiceAdvertisement_m.cc
@@ -0,0 +1,489 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/WaveServiceAdvertisement.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "WaveServiceAdvertisement_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(WaveServiceAdvertisment)
+
+WaveServiceAdvertisment::WaveServiceAdvertisment(const char *name, short kind) : ::WaveShortMessage(name,kind)
+{
+    this->targetChannel = 0;
+}
+
+WaveServiceAdvertisment::WaveServiceAdvertisment(const WaveServiceAdvertisment& other) : ::WaveShortMessage(other)
+{
+    copy(other);
+}
+
+WaveServiceAdvertisment::~WaveServiceAdvertisment()
+{
+}
+
+WaveServiceAdvertisment& WaveServiceAdvertisment::operator=(const WaveServiceAdvertisment& other)
+{
+    if (this==&other) return *this;
+    ::WaveShortMessage::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void WaveServiceAdvertisment::copy(const WaveServiceAdvertisment& other)
+{
+    this->targetChannel = other.targetChannel;
+    this->serviceDescription = other.serviceDescription;
+}
+
+void WaveServiceAdvertisment::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::WaveShortMessage::parsimPack(b);
+    doParsimPacking(b,this->targetChannel);
+    doParsimPacking(b,this->serviceDescription);
+}
+
+void WaveServiceAdvertisment::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::WaveShortMessage::parsimUnpack(b);
+    doParsimUnpacking(b,this->targetChannel);
+    doParsimUnpacking(b,this->serviceDescription);
+}
+
+int WaveServiceAdvertisment::getTargetChannel() const
+{
+    return this->targetChannel;
+}
+
+void WaveServiceAdvertisment::setTargetChannel(int targetChannel)
+{
+    this->targetChannel = targetChannel;
+}
+
+double WaveServiceAdvertisment::getQF(int Id)
+{
+    return  this->QF1[Id];
+}
+
+void WaveServiceAdvertisment::setQF(double QFa, int Id)
+{
+    this->QF1[Id] = QFa;
+}
+
+const char * WaveServiceAdvertisment::getServiceDescription() const
+{
+    return this->serviceDescription.c_str();
+}
+
+void WaveServiceAdvertisment::setServiceDescription(const char * serviceDescription)
+{
+    this->serviceDescription = serviceDescription;
+}
+
+class WaveServiceAdvertismentDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    WaveServiceAdvertismentDescriptor();
+    virtual ~WaveServiceAdvertismentDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(WaveServiceAdvertismentDescriptor)
+
+WaveServiceAdvertismentDescriptor::WaveServiceAdvertismentDescriptor() : omnetpp::cClassDescriptor("WaveServiceAdvertisment", "WaveShortMessage")
+{
+    propertynames = nullptr;
+}
+
+WaveServiceAdvertismentDescriptor::~WaveServiceAdvertismentDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool WaveServiceAdvertismentDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<WaveServiceAdvertisment *>(obj)!=nullptr;
+}
+
+const char **WaveServiceAdvertismentDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *WaveServiceAdvertismentDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int WaveServiceAdvertismentDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 2+basedesc->getFieldCount() : 2;
+}
+
+unsigned int WaveServiceAdvertismentDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<2) ? fieldTypeFlags[field] : 0;
+}
+
+const char *WaveServiceAdvertismentDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "targetChannel",
+        "serviceDescription",
+    };
+    return (field>=0 && field<2) ? fieldNames[field] : nullptr;
+}
+
+int WaveServiceAdvertismentDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='t' && strcmp(fieldName, "targetChannel")==0) return base+0;
+    if (fieldName[0]=='s' && strcmp(fieldName, "serviceDescription")==0) return base+1;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *WaveServiceAdvertismentDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "int",
+        "string",
+    };
+    return (field>=0 && field<2) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **WaveServiceAdvertismentDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *WaveServiceAdvertismentDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int WaveServiceAdvertismentDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    WaveServiceAdvertisment *pp = (WaveServiceAdvertisment *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *WaveServiceAdvertismentDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    WaveServiceAdvertisment *pp = (WaveServiceAdvertisment *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string WaveServiceAdvertismentDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    WaveServiceAdvertisment *pp = (WaveServiceAdvertisment *)object; (void)pp;
+    switch (field) {
+        case 0: return long2string(pp->getTargetChannel());
+        case 1: return oppstring2string(pp->getServiceDescription());
+        default: return "";
+    }
+}
+
+bool WaveServiceAdvertismentDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    WaveServiceAdvertisment *pp = (WaveServiceAdvertisment *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setTargetChannel(string2long(value)); return true;
+        case 1: pp->setServiceDescription((value)); return true;
+        default: return false;
+    }
+}
+
+const char *WaveServiceAdvertismentDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *WaveServiceAdvertismentDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    WaveServiceAdvertisment *pp = (WaveServiceAdvertisment *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/WaveServiceAdvertisement_m.h b/src/veins/modules/messages/WaveServiceAdvertisement_m.h
new file mode 100644
index 0000000..01c1fa7
--- /dev/null
+++ b/src/veins/modules/messages/WaveServiceAdvertisement_m.h
@@ -0,0 +1,74 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/WaveServiceAdvertisement.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __WAVESERVICEADVERTISEMENT_M_H
+#define __WAVESERVICEADVERTISEMENT_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+// cplusplus {{
+#include "veins/base/utils/Coord.h"
+#include "veins/modules/messages/WaveShortMessage_m.h"
+// }}
+
+/**
+ * Class generated from <tt>veins/modules/messages/WaveServiceAdvertisement.msg:29</tt> by nedtool.
+ * <pre>
+ * packet WaveServiceAdvertisment extends WaveShortMessage
+ * {
+ *     int targetChannel;
+ *     string serviceDescription;
+ * }
+ * </pre>
+ */
+class WaveServiceAdvertisment : public ::WaveShortMessage
+{
+  protected:
+    int targetChannel;
+    ::omnetpp::opp_string serviceDescription;
+
+  private:
+    void copy(const WaveServiceAdvertisment& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const WaveServiceAdvertisment&);
+
+  public:
+    WaveServiceAdvertisment(const char *name=nullptr, short kind=0);
+    WaveServiceAdvertisment(const WaveServiceAdvertisment& other);
+    virtual ~WaveServiceAdvertisment();
+    WaveServiceAdvertisment& operator=(const WaveServiceAdvertisment& other);
+    virtual WaveServiceAdvertisment *dup() const override {return new WaveServiceAdvertisment(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual int getTargetChannel() const;
+    virtual void setTargetChannel(int targetChannel);
+    virtual double getQF(int Id);
+    virtual void setQF(double QFa, int Id);
+    virtual const char * getServiceDescription() const;
+    virtual void setServiceDescription(const char * serviceDescription);
+
+    double QF1[500];
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const WaveServiceAdvertisment& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, WaveServiceAdvertisment& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __WAVESERVICEADVERTISEMENT_M_H
+
diff --git a/src/veins/modules/messages/WaveShortMessage_m.cc b/src/veins/modules/messages/WaveShortMessage_m.cc
new file mode 100644
index 0000000..23f6161
--- /dev/null
+++ b/src/veins/modules/messages/WaveShortMessage_m.cc
@@ -0,0 +1,700 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/WaveShortMessage.msg.
+//
+
+// Disable warnings about unused variables, empty switch stmts, etc:
+#ifdef _MSC_VER
+#  pragma warning(disable:4101)
+#  pragma warning(disable:4065)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wshadow"
+#  pragma clang diagnostic ignored "-Wconversion"
+#  pragma clang diagnostic ignored "-Wunused-parameter"
+#  pragma clang diagnostic ignored "-Wc++98-compat"
+#  pragma clang diagnostic ignored "-Wunreachable-code-break"
+#  pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined(__GNUC__)
+#  pragma GCC diagnostic ignored "-Wshadow"
+#  pragma GCC diagnostic ignored "-Wconversion"
+#  pragma GCC diagnostic ignored "-Wunused-parameter"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#  pragma GCC diagnostic ignored "-Wfloat-conversion"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include "WaveShortMessage_m.h"
+
+namespace omnetpp {
+
+// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
+// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
+
+// Packing/unpacking an std::vector
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
+{
+    int n = v.size();
+    doParsimPacking(buffer, n);
+    for (int i = 0; i < n; i++)
+        doParsimPacking(buffer, v[i]);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    v.resize(n);
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(buffer, v[i]);
+}
+
+// Packing/unpacking an std::list
+template<typename T, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
+{
+    doParsimPacking(buffer, (int)l.size());
+    for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
+        doParsimPacking(buffer, (T&)*it);
+}
+
+template<typename T, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        l.push_back(T());
+        doParsimUnpacking(buffer, l.back());
+    }
+}
+
+// Packing/unpacking an std::set
+template<typename T, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
+{
+    doParsimPacking(buffer, (int)s.size());
+    for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
+        doParsimPacking(buffer, *it);
+}
+
+template<typename T, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        T x;
+        doParsimUnpacking(buffer, x);
+        s.insert(x);
+    }
+}
+
+// Packing/unpacking an std::map
+template<typename K, typename V, typename Tr, typename A>
+void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
+{
+    doParsimPacking(buffer, (int)m.size());
+    for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
+        doParsimPacking(buffer, it->first);
+        doParsimPacking(buffer, it->second);
+    }
+}
+
+template<typename K, typename V, typename Tr, typename A>
+void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
+{
+    int n;
+    doParsimUnpacking(buffer, n);
+    for (int i=0; i<n; i++) {
+        K k; V v;
+        doParsimUnpacking(buffer, k);
+        doParsimUnpacking(buffer, v);
+        m[k] = v;
+    }
+}
+
+// Default pack/unpack function for arrays
+template<typename T>
+void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimPacking(b, t[i]);
+}
+
+template<typename T>
+void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
+{
+    for (int i = 0; i < n; i++)
+        doParsimUnpacking(b, t[i]);
+}
+
+// Default rule to prevent compiler from choosing base class' doParsimPacking() function
+template<typename T>
+void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+template<typename T>
+void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
+{
+    throw omnetpp::cRuntimeError("Parsim error: No doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
+}
+
+}  // namespace omnetpp
+
+
+// forward
+template<typename T, typename A>
+std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
+
+// Template rule which fires if a struct or class doesn't have operator<<
+template<typename T>
+inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
+
+// operator<< for std::vector<T>
+template<typename T, typename A>
+inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
+{
+    out.put('{');
+    for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
+    {
+        if (it != vec.begin()) {
+            out.put(','); out.put(' ');
+        }
+        out << *it;
+    }
+    out.put('}');
+    
+    char buf[32];
+    sprintf(buf, " (size=%u)", (unsigned int)vec.size());
+    out.write(buf, strlen(buf));
+    return out;
+}
+
+Register_Class(WaveShortMessage)
+
+WaveShortMessage::WaveShortMessage(const char *name, short kind) : ::omnetpp::cPacket(name,kind)
+{
+    this->wsmVersion = 0;
+    this->securityType = 0;
+    this->channelNumber = 0;
+    this->dataRate = 1;
+    this->userPriority = 7;
+    this->psid = 0;
+    this->psc = "Service with some Data";
+    this->wsmLength = 0;
+    this->wsmData = "Some Data";
+    this->senderAddress = 0;
+    this->recipientAddress = -1;
+    this->serial = 0;
+    this->timestamp = 0;
+}
+
+WaveShortMessage::WaveShortMessage(const WaveShortMessage& other) : ::omnetpp::cPacket(other)
+{
+    copy(other);
+}
+
+WaveShortMessage::~WaveShortMessage()
+{
+}
+
+WaveShortMessage& WaveShortMessage::operator=(const WaveShortMessage& other)
+{
+    if (this==&other) return *this;
+    ::omnetpp::cPacket::operator=(other);
+    copy(other);
+    return *this;
+}
+
+void WaveShortMessage::copy(const WaveShortMessage& other)
+{
+    this->wsmVersion = other.wsmVersion;
+    this->securityType = other.securityType;
+    this->channelNumber = other.channelNumber;
+    this->dataRate = other.dataRate;
+    this->userPriority = other.userPriority;
+    this->psid = other.psid;
+    this->psc = other.psc;
+    this->wsmLength = other.wsmLength;
+    this->wsmData = other.wsmData;
+    this->senderAddress = other.senderAddress;
+    this->recipientAddress = other.recipientAddress;
+    this->serial = other.serial;
+    this->timestamp = other.timestamp;
+}
+
+void WaveShortMessage::parsimPack(omnetpp::cCommBuffer *b) const
+{
+    ::omnetpp::cPacket::parsimPack(b);
+    doParsimPacking(b,this->wsmVersion);
+    doParsimPacking(b,this->securityType);
+    doParsimPacking(b,this->channelNumber);
+    doParsimPacking(b,this->dataRate);
+    doParsimPacking(b,this->userPriority);
+    doParsimPacking(b,this->psid);
+    doParsimPacking(b,this->psc);
+    doParsimPacking(b,this->wsmLength);
+    doParsimPacking(b,this->wsmData);
+    doParsimPacking(b,this->senderAddress);
+    doParsimPacking(b,this->recipientAddress);
+    doParsimPacking(b,this->serial);
+    doParsimPacking(b,this->timestamp);
+}
+
+void WaveShortMessage::parsimUnpack(omnetpp::cCommBuffer *b)
+{
+    ::omnetpp::cPacket::parsimUnpack(b);
+    doParsimUnpacking(b,this->wsmVersion);
+    doParsimUnpacking(b,this->securityType);
+    doParsimUnpacking(b,this->channelNumber);
+    doParsimUnpacking(b,this->dataRate);
+    doParsimUnpacking(b,this->userPriority);
+    doParsimUnpacking(b,this->psid);
+    doParsimUnpacking(b,this->psc);
+    doParsimUnpacking(b,this->wsmLength);
+    doParsimUnpacking(b,this->wsmData);
+    doParsimUnpacking(b,this->senderAddress);
+    doParsimUnpacking(b,this->recipientAddress);
+    doParsimUnpacking(b,this->serial);
+    doParsimUnpacking(b,this->timestamp);
+}
+
+int WaveShortMessage::getWsmVersion() const
+{
+    return this->wsmVersion;
+}
+
+void WaveShortMessage::setWsmVersion(int wsmVersion)
+{
+    this->wsmVersion = wsmVersion;
+}
+
+int WaveShortMessage::getSecurityType() const
+{
+    return this->securityType;
+}
+
+void WaveShortMessage::setSecurityType(int securityType)
+{
+    this->securityType = securityType;
+}
+
+int WaveShortMessage::getChannelNumber() const
+{
+    return this->channelNumber;
+}
+
+void WaveShortMessage::setChannelNumber(int channelNumber)
+{
+    this->channelNumber = channelNumber;
+}
+
+int WaveShortMessage::getDataRate() const
+{
+    return this->dataRate;
+}
+
+void WaveShortMessage::setDataRate(int dataRate)
+{
+    this->dataRate = dataRate;
+}
+
+int WaveShortMessage::getUserPriority() const
+{
+    return this->userPriority;
+}
+
+void WaveShortMessage::setUserPriority(int userPriority)
+{
+    this->userPriority = userPriority;
+}
+
+int WaveShortMessage::getPsid() const
+{
+    return this->psid;
+}
+
+void WaveShortMessage::setPsid(int psid)
+{
+    this->psid = psid;
+}
+
+const char * WaveShortMessage::getPsc() const
+{
+    return this->psc.c_str();
+}
+
+void WaveShortMessage::setPsc(const char * psc)
+{
+    this->psc = psc;
+}
+
+int WaveShortMessage::getWsmLength() const
+{
+    return this->wsmLength;
+}
+
+void WaveShortMessage::setWsmLength(int wsmLength)
+{
+    this->wsmLength = wsmLength;
+}
+
+const char * WaveShortMessage::getWsmData() const
+{
+    return this->wsmData.c_str();
+}
+
+void WaveShortMessage::setWsmData(const char * wsmData)
+{
+    this->wsmData = wsmData;
+}
+
+int WaveShortMessage::getSenderAddress() const
+{
+    return this->senderAddress;
+}
+
+void WaveShortMessage::setSenderAddress(int senderAddress)
+{
+    this->senderAddress = senderAddress;
+}
+
+int WaveShortMessage::getRecipientAddress() const
+{
+    return this->recipientAddress;
+}
+
+void WaveShortMessage::setRecipientAddress(int recipientAddress)
+{
+    this->recipientAddress = recipientAddress;
+}
+
+int WaveShortMessage::getSerial() const
+{
+    return this->serial;
+}
+
+void WaveShortMessage::setSerial(int serial)
+{
+    this->serial = serial;
+}
+
+::omnetpp::simtime_t WaveShortMessage::getTimestamp() const
+{
+    return this->timestamp;
+}
+
+void WaveShortMessage::setTimestamp(::omnetpp::simtime_t timestamp)
+{
+    this->timestamp = timestamp;
+}
+
+class WaveShortMessageDescriptor : public omnetpp::cClassDescriptor
+{
+  private:
+    mutable const char **propertynames;
+  public:
+    WaveShortMessageDescriptor();
+    virtual ~WaveShortMessageDescriptor();
+
+    virtual bool doesSupport(omnetpp::cObject *obj) const override;
+    virtual const char **getPropertyNames() const override;
+    virtual const char *getProperty(const char *propertyname) const override;
+    virtual int getFieldCount() const override;
+    virtual const char *getFieldName(int field) const override;
+    virtual int findField(const char *fieldName) const override;
+    virtual unsigned int getFieldTypeFlags(int field) const override;
+    virtual const char *getFieldTypeString(int field) const override;
+    virtual const char **getFieldPropertyNames(int field) const override;
+    virtual const char *getFieldProperty(int field, const char *propertyname) const override;
+    virtual int getFieldArraySize(void *object, int field) const override;
+
+    virtual const char *getFieldDynamicTypeString(void *object, int field, int i) const override;
+    virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
+    virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
+
+    virtual const char *getFieldStructName(int field) const override;
+    virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
+};
+
+Register_ClassDescriptor(WaveShortMessageDescriptor)
+
+WaveShortMessageDescriptor::WaveShortMessageDescriptor() : omnetpp::cClassDescriptor("WaveShortMessage", "omnetpp::cPacket")
+{
+    propertynames = nullptr;
+}
+
+WaveShortMessageDescriptor::~WaveShortMessageDescriptor()
+{
+    delete[] propertynames;
+}
+
+bool WaveShortMessageDescriptor::doesSupport(omnetpp::cObject *obj) const
+{
+    return dynamic_cast<WaveShortMessage *>(obj)!=nullptr;
+}
+
+const char **WaveShortMessageDescriptor::getPropertyNames() const
+{
+    if (!propertynames) {
+        static const char *names[] = {  nullptr };
+        omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+        const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
+        propertynames = mergeLists(basenames, names);
+    }
+    return propertynames;
+}
+
+const char *WaveShortMessageDescriptor::getProperty(const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? basedesc->getProperty(propertyname) : nullptr;
+}
+
+int WaveShortMessageDescriptor::getFieldCount() const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    return basedesc ? 13+basedesc->getFieldCount() : 13;
+}
+
+unsigned int WaveShortMessageDescriptor::getFieldTypeFlags(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeFlags(field);
+        field -= basedesc->getFieldCount();
+    }
+    static unsigned int fieldTypeFlags[] = {
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+        FD_ISEDITABLE,
+    };
+    return (field>=0 && field<13) ? fieldTypeFlags[field] : 0;
+}
+
+const char *WaveShortMessageDescriptor::getFieldName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldName(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldNames[] = {
+        "wsmVersion",
+        "securityType",
+        "channelNumber",
+        "dataRate",
+        "userPriority",
+        "psid",
+        "psc",
+        "wsmLength",
+        "wsmData",
+        "senderAddress",
+        "recipientAddress",
+        "serial",
+        "timestamp",
+    };
+    return (field>=0 && field<13) ? fieldNames[field] : nullptr;
+}
+
+int WaveShortMessageDescriptor::findField(const char *fieldName) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    int base = basedesc ? basedesc->getFieldCount() : 0;
+    if (fieldName[0]=='w' && strcmp(fieldName, "wsmVersion")==0) return base+0;
+    if (fieldName[0]=='s' && strcmp(fieldName, "securityType")==0) return base+1;
+    if (fieldName[0]=='c' && strcmp(fieldName, "channelNumber")==0) return base+2;
+    if (fieldName[0]=='d' && strcmp(fieldName, "dataRate")==0) return base+3;
+    if (fieldName[0]=='u' && strcmp(fieldName, "userPriority")==0) return base+4;
+    if (fieldName[0]=='p' && strcmp(fieldName, "psid")==0) return base+5;
+    if (fieldName[0]=='p' && strcmp(fieldName, "psc")==0) return base+6;
+    if (fieldName[0]=='w' && strcmp(fieldName, "wsmLength")==0) return base+7;
+    if (fieldName[0]=='w' && strcmp(fieldName, "wsmData")==0) return base+8;
+    if (fieldName[0]=='s' && strcmp(fieldName, "senderAddress")==0) return base+9;
+    if (fieldName[0]=='r' && strcmp(fieldName, "recipientAddress")==0) return base+10;
+    if (fieldName[0]=='s' && strcmp(fieldName, "serial")==0) return base+11;
+    if (fieldName[0]=='t' && strcmp(fieldName, "timestamp")==0) return base+12;
+    return basedesc ? basedesc->findField(fieldName) : -1;
+}
+
+const char *WaveShortMessageDescriptor::getFieldTypeString(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldTypeString(field);
+        field -= basedesc->getFieldCount();
+    }
+    static const char *fieldTypeStrings[] = {
+        "int",
+        "int",
+        "int",
+        "int",
+        "int",
+        "int",
+        "string",
+        "int",
+        "string",
+        "int",
+        "int",
+        "int",
+        "simtime_t",
+    };
+    return (field>=0 && field<13) ? fieldTypeStrings[field] : nullptr;
+}
+
+const char **WaveShortMessageDescriptor::getFieldPropertyNames(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldPropertyNames(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+const char *WaveShortMessageDescriptor::getFieldProperty(int field, const char *propertyname) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldProperty(field, propertyname);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+int WaveShortMessageDescriptor::getFieldArraySize(void *object, int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldArraySize(object, field);
+        field -= basedesc->getFieldCount();
+    }
+    WaveShortMessage *pp = (WaveShortMessage *)object; (void)pp;
+    switch (field) {
+        default: return 0;
+    }
+}
+
+const char *WaveShortMessageDescriptor::getFieldDynamicTypeString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldDynamicTypeString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    WaveShortMessage *pp = (WaveShortMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+std::string WaveShortMessageDescriptor::getFieldValueAsString(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldValueAsString(object,field,i);
+        field -= basedesc->getFieldCount();
+    }
+    WaveShortMessage *pp = (WaveShortMessage *)object; (void)pp;
+    switch (field) {
+        case 0: return long2string(pp->getWsmVersion());
+        case 1: return long2string(pp->getSecurityType());
+        case 2: return long2string(pp->getChannelNumber());
+        case 3: return long2string(pp->getDataRate());
+        case 4: return long2string(pp->getUserPriority());
+        case 5: return long2string(pp->getPsid());
+        case 6: return oppstring2string(pp->getPsc());
+        case 7: return long2string(pp->getWsmLength());
+        case 8: return oppstring2string(pp->getWsmData());
+        case 9: return long2string(pp->getSenderAddress());
+        case 10: return long2string(pp->getRecipientAddress());
+        case 11: return long2string(pp->getSerial());
+        case 12: return simtime2string(pp->getTimestamp());
+        default: return "";
+    }
+}
+
+bool WaveShortMessageDescriptor::setFieldValueAsString(void *object, int field, int i, const char *value) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->setFieldValueAsString(object,field,i,value);
+        field -= basedesc->getFieldCount();
+    }
+    WaveShortMessage *pp = (WaveShortMessage *)object; (void)pp;
+    switch (field) {
+        case 0: pp->setWsmVersion(string2long(value)); return true;
+        case 1: pp->setSecurityType(string2long(value)); return true;
+        case 2: pp->setChannelNumber(string2long(value)); return true;
+        case 3: pp->setDataRate(string2long(value)); return true;
+        case 4: pp->setUserPriority(string2long(value)); return true;
+        case 5: pp->setPsid(string2long(value)); return true;
+        case 6: pp->setPsc((value)); return true;
+        case 7: pp->setWsmLength(string2long(value)); return true;
+        case 8: pp->setWsmData((value)); return true;
+        case 9: pp->setSenderAddress(string2long(value)); return true;
+        case 10: pp->setRecipientAddress(string2long(value)); return true;
+        case 11: pp->setSerial(string2long(value)); return true;
+        case 12: pp->setTimestamp(string2simtime(value)); return true;
+        default: return false;
+    }
+}
+
+const char *WaveShortMessageDescriptor::getFieldStructName(int field) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructName(field);
+        field -= basedesc->getFieldCount();
+    }
+    switch (field) {
+        default: return nullptr;
+    };
+}
+
+void *WaveShortMessageDescriptor::getFieldStructValuePointer(void *object, int field, int i) const
+{
+    omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
+    if (basedesc) {
+        if (field < basedesc->getFieldCount())
+            return basedesc->getFieldStructValuePointer(object, field, i);
+        field -= basedesc->getFieldCount();
+    }
+    WaveShortMessage *pp = (WaveShortMessage *)object; (void)pp;
+    switch (field) {
+        default: return nullptr;
+    }
+}
+
+
diff --git a/src/veins/modules/messages/WaveShortMessage_m.h b/src/veins/modules/messages/WaveShortMessage_m.h
new file mode 100644
index 0000000..adc4858
--- /dev/null
+++ b/src/veins/modules/messages/WaveShortMessage_m.h
@@ -0,0 +1,119 @@
+//
+// Generated file, do not edit! Created by nedtool 5.4 from veins/modules/messages/WaveShortMessage.msg.
+//
+
+#if defined(__clang__)
+#  pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifndef __WAVESHORTMESSAGE_M_H
+#define __WAVESHORTMESSAGE_M_H
+
+#include <omnetpp.h>
+
+// nedtool version check
+#define MSGC_VERSION 0x0504
+#if (MSGC_VERSION!=OMNETPP_VERSION)
+#    error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
+#endif
+
+
+
+/**
+ * Class generated from <tt>veins/modules/messages/WaveShortMessage.msg:21</tt> by nedtool.
+ * <pre>
+ * packet 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;
+ *     //User priority with which this packet was sent (note the AC mapping rules in Mac1609_4::mapUserPriority)
+ *     int userPriority = 7;
+ *     //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;
+ *     //Data of Wave Short Message
+ *     string wsmData = "Some Data";
+ * 
+ *     int senderAddress = 0;
+ *     int recipientAddress = -1;
+ *     int serial = 0;
+ *     simtime_t timestamp = 0;
+ * }
+ * </pre>
+ */
+class WaveShortMessage : public ::omnetpp::cPacket
+{
+  protected:
+    int wsmVersion;
+    int securityType;
+    int channelNumber;
+    int dataRate;
+    int userPriority;
+    int psid;
+    ::omnetpp::opp_string psc;
+    int wsmLength;
+    ::omnetpp::opp_string wsmData;
+    int senderAddress;
+    int recipientAddress;
+    int serial;
+    ::omnetpp::simtime_t timestamp;
+
+  private:
+    void copy(const WaveShortMessage& other);
+
+  protected:
+    // protected and unimplemented operator==(), to prevent accidental usage
+    bool operator==(const WaveShortMessage&);
+
+  public:
+    WaveShortMessage(const char *name=nullptr, short kind=0);
+    WaveShortMessage(const WaveShortMessage& other);
+    virtual ~WaveShortMessage();
+    WaveShortMessage& operator=(const WaveShortMessage& other);
+    virtual WaveShortMessage *dup() const override {return new WaveShortMessage(*this);}
+    virtual void parsimPack(omnetpp::cCommBuffer *b) const override;
+    virtual void parsimUnpack(omnetpp::cCommBuffer *b) override;
+
+    // field getter/setter methods
+    virtual int getWsmVersion() const;
+    virtual void setWsmVersion(int wsmVersion);
+    virtual int getSecurityType() const;
+    virtual void setSecurityType(int securityType);
+    virtual int getChannelNumber() const;
+    virtual void setChannelNumber(int channelNumber);
+    virtual int getDataRate() const;
+    virtual void setDataRate(int dataRate);
+    virtual int getUserPriority() const;
+    virtual void setUserPriority(int userPriority);
+    virtual int getPsid() const;
+    virtual void setPsid(int psid);
+    virtual const char * getPsc() const;
+    virtual void setPsc(const char * psc);
+    virtual int getWsmLength() const;
+    virtual void setWsmLength(int wsmLength);
+    virtual const char * getWsmData() const;
+    virtual void setWsmData(const char * wsmData);
+    virtual int getSenderAddress() const;
+    virtual void setSenderAddress(int senderAddress);
+    virtual int getRecipientAddress() const;
+    virtual void setRecipientAddress(int recipientAddress);
+    virtual int getSerial() const;
+    virtual void setSerial(int serial);
+    virtual ::omnetpp::simtime_t getTimestamp() const;
+    virtual void setTimestamp(::omnetpp::simtime_t timestamp);
+};
+
+inline void doParsimPacking(omnetpp::cCommBuffer *b, const WaveShortMessage& obj) {obj.parsimPack(b);}
+inline void doParsimUnpacking(omnetpp::cCommBuffer *b, WaveShortMessage& obj) {obj.parsimUnpack(b);}
+
+
+#endif // ifndef __WAVESHORTMESSAGE_M_H
+