上一节中,网络中添加了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。