上一节中,网络中添加了50个node。这这node就是mixim框架中的host802154_2400Mhz结点。在design模式下,双击网络中的node结点,进入host802154_2400Mhz模块的design视图。
从图中可以看出,这是一个复合模块,它是由一些简单模块(simple module)组成。上图node包含了无线网络仿真所需的应用层、网络层、物理层以及电池等简单模块(simple module)。
module Host802154_2400MHz extends WirelessNodeBatteryPlusTran
{
parameters:
int numHosts; // total number of hosts in the network
applicationType = default("SensorApplLayer");
transportType = default("Aggregation");
nicType = default("Nic802154_TI_CC2420"); //type of used nic
arpType = default("org.mixim.modules.netw.ArpHost");
batteryStats.detail = default(false);
batteryStats.timeSeries = default(false);
battery.nominal = default(1000 mAh);
battery.capacity = default(battery.nominal);
battery.voltage = default(3 V);
battery.resolution = default(60 s);
battery.publishDelta = default(1);
battery.publishTime = default(battery.resolution);
battery.numDevices = default(1);
}
simple SensorApplLayer like IBaseApplLayer
{
parameters:
bool debug = default(false); // debug switch
bool stats = default(true); // stats generation switch
bool trace = default(false); // activates detailed logging (per source latencies and vector logging). stats must be true.
bool broadcastPackets = default(false); // send packets in broadcast mode
double nbPackets = default(0);
int destAddr = default(0);
string trafficType = default("periodic"); // Can be one of: periodic, uniform or exponential
double trafficParam @unit(s) = default(1 s); // the mean time between two packets
double initializationTime @unit(s) = default(1 min); // minimum time before generation of the first packet,一分钟之后才会产生第一个数据包
int headerLength @unit(byte) = default(2 byte);
bool notAffectedByHostState = default(true);
gates:
input lowerLayerIn; // from network layer
input lowerControlIn;
output lowerLayerOut; // to network layer
output lowerControlOut;
}
应用层的主要任务是周期性地产生流量包,最终转发到sink结点上。这些功能由上面定义的simple模块实现。参数nbpackets代表产生数据包的个数,默认值为0,。参数destaddr代表数据包的目的地址,默认0。参数traffictype表示数据产生的周期类型,periodic值表示固定周期。参数headerlength代表数据包的大小,默认2字节。在仿真的时候这些参数可以在omnetpp.ini文件中从新赋值,仿真以omnetpp.ini文件为准。例如:
**.node[0].appl.nbPackets = 0
**.node[*].appl.nbPackets = 10 #产生10个数据包
**.node[*].appl.destAddr = 0 #目的结点0
**.node[*].appl.trafficType = "periodic" #产生数据包时间间隔固定为periodic
**.node[*].appl.trafficParam = 30 s # each node sends 1 packet every 30 seconds
**.node[*].appl.initializationTime = 30 s #30s后产生第一个数据包
**.node[*].appl.headerLength = 50 byte #数据包大小50字节
下面是applayer层发送数据包的源码:
void SensorApplLayer::sendData() {
ApplPkt *pkt = new ApplPkt("Data", DATA_MESSAGE);
if(broadcastPackets) {
pkt->setDestAddr(LAddress::L3BROADCAST);
} else {
pkt->setDestAddr(destAddr);
}
pkt->setSrcAddr(myAppAddr);
pkt->setByteLength(headerLength);
// set the control info to tell the network layer the layer 3 address
NetwControlInfo::setControlInfo(pkt, pkt->getDestAddr());
debugEV<< "Sending data packet!\n";
sendDown(pkt);
nbPacketsSent++;
packet.setPacketSent(true);
packet.setNbPacketsSent(1);
packet.setNbPacketsReceived(0);
packet.setHost(myAppAddr);
emit(BaseLayer::catPacketSignal, &packet);
sentPackets++;
scheduleNextPacket();
}
ApplPkt *pkt = new ApplPkt("Data", DATA_MESSAGE);
if(broadcastPackets) {
pkt->setDestAddr(LAddress::L3BROADCAST);
} else {
pkt->setDestAddr(destAddr);
}
生成数据包以及设置数据包的目的地址。broadcastpackets在sensorapplayer.ned文件中定义为FALSE,destAddr定义为0,即0号node是sink结点。
sendDown(pkt);
将数据包向下发送到网络层
下面是周期性产生流量的方法:
void SensorApplLayer::scheduleNextPacket() {
if (nbPackets > sentPackets && trafficType != 0) { // We must generate packets
simtime_t waitTime = SIMTIME_ZERO;
switch (trafficType) {
case PERIODIC:
waitTime = trafficParam;
debugEV<< "Periodic traffic, waitTime=" << waitTime << endl;
break;
case UNIFORM:
waitTime = uniform(0, trafficParam);
debugEV << "Uniform traffic, waitTime=" << waitTime << endl;
break;
case EXPONENTIAL:
waitTime = exponential(trafficParam);
debugEV << "Exponential traffic, waitTime=" << waitTime << endl;
break;
case UNKNOWN:
default:
EV <<
"Cannot generate requested traffic type (unimplemented or unknown)."
<< endl;
return; // don not schedule
break;
}
debugEV << "Start timer for a new packet in " << waitTime << " seconds." <<
endl;
scheduleAt(simTime() + waitTime, delayTimer);
debugEV << "...timer rescheduled." << endl;
} else {
debugEV << "All packets sent.\n";
}
}
switch (trafficType) {
case PERIODIC:
waitTime = trafficParam;
traffictype是流量类型。有四种可能,其中PERIODIC表示固定时间间隔,故产生流量的时间间隔waittime=固定值trafficparam。