package org.car2x.veins.nodes; import org.car2x.veins.base.modules.*; import org.car2x.veins.modules.nic.Nic80211p; module Car { parameters: string applType; //type of the application layer string nicType = default("Nic80211p"); // type of network interface card string veinsmobilityType = default("org.car2x.veins.modules.mobility.traci.TraCIMobility"); //type of the mobility module gates: input veinsradioIn; // gate for sendDirect submodules: appl: <applType> like org.car2x.veins.base.modules.IBaseApplLayer { parameters: @display("p=60,50"); } nic: <nicType> like org.car2x.veins.modules.nic.INic80211p { parameters: @display("p=60,166"); } veinsmobility: <veinsmobilityType> like org.car2x.veins.base.modules.IMobility { parameters: @display("p=130,172;i=block/cogwheel"); } connections: nic.upperLayerOut --> appl.lowerLayerIn; nic.upperLayerIn <-- appl.lowerLayerOut; nic.upperControlOut --> appl.lowerControlIn; nic.upperControlIn <-- appl.lowerControlOut; veinsradioIn --> nic.radioIn; }
时间: 2024-02-15 07:28:54 浏览: 24
这段代码是一个 Veins仿真场景中的一个节点模块的定义。节点是指网络中的一个设备,例如车辆、基站等等。这个模块的实现使用了 Veins仿真工具中的模块化特性,即将节点分解为多个子模块,每个子模块负责不同的功能。
这个模块的名称为 "Car",包含了三个子模块:
1. `appl`:应用层模块,负责处理应用层的逻辑,例如数据传输、协议处理等等。这个模块的类型由 `applType` 参数指定。
2. `nic`:网络接口卡模块,负责处理数据包在网络中的传输。这个模块的类型由 `nicType` 参数指定。
3. `veinsmobility`:移动性模块,负责处理节点的移动逻辑,例如节点的位置、速度等等。这个模块的类型由 `veinsmobilityType` 参数指定。
这些子模块之间通过输入输出门(gates)连接起来,用于数据的传输。例如,节点的无线电模块接收到的数据可以通过 `veinsradioIn` 输入门传输到 `nic` 模块的 `radioIn` 输入门。另外,子模块之间的参数定义可以通过 `parameters` 关键字实现。
相关问题
veins/modules/application/ieee80211p/ChannelAccess.cc的源码
由于篇幅较长,无法在此处完整展示源代码,以下是 ChannelAccess.cc 的部分源代码,供你参考:
```
#include "ChannelAccess.h"
#include "veins/modules/messages/WaveShortMessage_m.h"
#define CW_MIN 15
#define CW_MAX 1023
#define SLOT_TIME 0.00001
#define SIFS 0.00001
#define DIFS (2 * SIFS + SLOT_TIME)
#define BACKOFF_PERIOD 0.00001
#define MAX_RETRIES 7
Define_Module(ChannelAccess);
ChannelAccess::ChannelAccess() {
_channelIdle = true;
_waitingForSIFS = false;
_currentPacket = nullptr;
}
bool ChannelAccess::isIdle() {
return _channelIdle;
}
void ChannelAccess::sendPacket(Packet* packet) {
_currentPacket = packet;
if (_channelIdle) {
startTransmission();
} else {
_backoffCounter = uniform(CW_MIN, CW_MAX);
_backoffPeriod = _backoffCounter * SLOT_TIME;
}
}
void ChannelAccess::receivePacket(Packet* packet) {
if (_channelIdle) {
handlePacketReceived(packet);
} else {
delete packet;
}
}
void ChannelAccess::handleChannelIdle() {
if (!_channelIdle) {
if (_waitingForSIFS) {
handlePacketSent();
} else {
_backoffPeriod -= simTime() - _lastInteractionTime;
if (_backoffPeriod <= 0) {
if (_retries <= MAX_RETRIES) {
_backoffCounter *= 2;
if (_backoffCounter > CW_MAX) {
_backoffCounter = CW_MAX;
}
_backoffPeriod = _backoffCounter * SLOT_TIME;
_retries++;
startTransmission();
} else {
delete _currentPacket;
_currentPacket = nullptr;
_channelIdle = true;
}
} else {
scheduleAt(simTime() + _backoffPeriod, new cMessage("Backoff"));
}
}
}
}
void ChannelAccess::handleChannelBusy() {
if (!_channelIdle) {
_backoffPeriod -= simTime() - _lastInteractionTime;
if (_backoffPeriod <= 0) {
_backoffCounter = uniform(CW_MIN, CW_MAX);
_backoffPeriod = _backoffCounter * SLOT_TIME;
}
scheduleAt(simTime() + _backoffPeriod, new cMessage("Backoff"));
}
}
void ChannelAccess::startTransmission() {
_waitingForSIFS = true;
_retries = 0;
_channelIdle = false;
send(_currentPacket, "out");
scheduleAt(simTime() + SIFS, new cMessage("SIFS"));
}
void ChannelAccess::handlePacketSent() {
_channelIdle = true;
_waitingForSIFS = false;
delete _currentPacket;
_currentPacket = nullptr;
}
void ChannelAccess::handlePacketReceived(Packet* packet) {
if (_currentPacket && packet->getKind() == _currentPacket->getKind()) {
if (packet->getSenderAddress() != _currentPacket->getSenderAddress()) {
delete packet;
handleTimeout();
}
} else {
delete packet;
}
}
void ChannelAccess::handleTimeout() {
if (_retries <= MAX_RETRIES) {
_backoffCounter *= 2;
if (_backoffCounter > CW_MAX) {
_backoffCounter = CW_MAX;
}
_backoffPeriod = _backoffCounter * SLOT_TIME;
_retries++;
startTransmission();
} else {
_channelIdle = true;
_currentPacket = nullptr;
}
}
void ChannelAccess::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
_channelIdle = true;
_waitingForSIFS = false;
_currentPacket = nullptr;
}
}
void ChannelAccess::handleMessageWhenUp(cMessage* message) {
_lastInteractionTime = simTime();
if (message->isSelfMessage()) {
if (strcmp(message->getName(), "Backoff") == 0) {
handleChannelIdle();
} else if (strcmp(message->getName(), "SIFS") == 0) {
handlePacketSent();
} else if (strcmp(message->getName(), "Timeout") == 0) {
handleTimeout();
}
delete message;
} else {
auto packet = check_and_cast<WaveShortMessage*>(message);
if (_channelIdle) {
handlePacketReceived(new Packet(packet));
} else {
delete packet;
}
}
}
```
以上代码仅供参考,完整的 Veins 模拟器源代码可以在官方网站上下载。
veins中的ChannelControl的引入,需要什么.h文件
在Veins中使用ChannelControl模块,需要在源代码中引入以下头文件:
```c++
#include "veins/modules/application/ieee80211p/DemoBaseApplLayer.h"
#include "veins/modules/mobility/traci/TraCIMobility.h"
#include "veins/modules/application/ieee80211p/ChannelAccess.h"
#include "veins/modules/application/ieee80211p/WaveShortMessage.h"
#include "veins/modules/application/ieee80211p/BaseWaveApplLayer.h"
#include "veins/modules/phy/Decider80211p.h"
#include "veins/modules/phy/Packet80211p_m.h"
#include "veins/modules/application/ieee80211p/DemoBaseApplLayer.h"
```
其中,DemoBaseApplLayer.h、TraCIMobility.h、ChannelAccess.h、WaveShortMessage.h、BaseWaveApplLayer.h、Decider80211p.h、Packet80211p_m.h这些头文件是Veins中的其他模块所需要的头文件,如果您的程序中已经包含了这些头文件,则不必重复引入。