Veins教程05 - 再学OMNet++

Learn more about OMNet++

对Veins有了一些基础的了解之后,在修改/搭建自己项目之前,回头再深入学习一些Omnet++的知识

Messages

OMNet++中Messages的相关知识。Message的对应.cc类文件为omnetpp/include/omnetpp/cmessage.cc。cMessage类的构造函数包括name和kind,前者可以用于标识、debug等,后者接受一个非零数(通常为定义的枚举类型),负数预留给仿真内核使用。

cMessage * msg3 =newcMessage("timeout", KIND_TIMEOUT);

属性基本都是字面意思,特殊的是timestamp,这个是可以自由定义,做任何用处的属性。

函数dup()克隆Message,除ID以外完全一致。克隆的Message与原Message的TreeID一致。

函数getCreationTime()返回的是创建时间。需要注意的是,通过克隆的Message使用此函数返回的是原Message的创建时间而非克隆时间。

函数setControlInfo()可以附一个控制体给Message,以此来包含特殊信息。比如IP消息中包含接收方的MAC地址。

setControlInfo() 意义不明

Message内有一个cArray储存cObject,可以用于附加各种参数或对象到Message。

1
2
3
4
5
6
7
8
9
10
// sender:
cHistogram * histogram =newcHistogram("histogram");
msg->addObject(histogram);

// receiver:
if(msg->hasObject("histogram")) {
cObject * obj = msg->getObject("histogram");
cHistogram * histogram = check_and_cast<cHistogram *>(obj);
...
}

Message Definitions

OMNet++提供一个方便的方法定义Message。我们可以创建.msg文件,编译器会帮我们创建对应的.h.cc文件。比如veins/src/modules/messages*_m.h*_m.cc文件为编译器根据对应的.msg文件创建的。

如果定义中使用的类型包含在其他特定c++文件中,需要引用。例如veins/src/modules/messages/BaseFrame1609_4.msg中使用了SimpleAddress.h中定义的LAddress类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cplusplus {{
#include "veins/base/utils/SimpleAddress.h"
}}

namespace veins;

class LAddress::L2Type extends void;

packet BaseFrame1609_4 {
//Channel Number on which this packet was sent
int channelNumber;
//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;
//Recipient of frame (-1 for any)
LAddress::L2Type recipientAddress = -1;
}

cplusplus内可以直接使用C++的引用和预定义代码。需要注意的是,引用了头文件后,还需要手动定义该类,如上例的class LAddress::L2Type extends void;所示,其空继承等于class noncobject LAddress::L2Type。如果没有写明extends则会自动继承cOwnedObject以确保错误在编译时出现而不是留到运行时。

Customized Message

编译器自动生成的c文件可能无法很好的实现我们所需的功能,直接修改生成的c文件无效,因为编译器会根据.msg文件重新生成覆盖。我们可以添加@customize(true)来自定义功能。具体的逻辑是:编译器会自动生成*_Base类,然后我们手动编写c文件并继承_Base类,然后实现功能。

Using STL

两种方式在Message中使用类似std::vectorstd::stack的标准库:

  1. .msg中引入并声明类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    cplusplus{{
    #include <vector>
    typedef std::vector<int> IntVector;
    }}

    class noncobjectIntVector;

    packetFooPacket {
    IntVector addresses;
    };
  2. .msg中使用abstract定义参数

    1
    2
    3
    4
    5
    packetFooPacket{
    @customize(true);
    abstract intfoo[];
    std::vector<int>abstract intbar[]
    }

方法二中编译器生成c++文件时会只生成纯虚函数。

评论