📄 asyncsnreval.cc
字号:
/* -*- mode:c++ -*- ********************************************************
* file: AsyncSnrEval.cc
*
* author: Yupeng.hu
*
* copyright: (C) 2006 HUNAN Universtiy, ChangSha China
*
***************************************************************************
* part of: Async Simulation
* description: - Async Description
*
***************************************************************************
* changelog: $Revision$
* last modified: $Date: 2006-7-3 12:53 $
* by: $Author: Yupeng.hu $
***************************************************************************/
#include "AsyncSnrEval.h"
#include <FWMath.h>
#define EV (ev.disabled()||!debug) ? (std::ostream&)ev : ev << logName() << "::AsyncSnrEval: "
Define_Module( AsyncSnrEval);
/**
* All values not present in the ned file will be read from the
* ChannelControl module or assigned default values.
**/
void AsyncSnrEval::initialize(int stage)
{
BasicSnrEval::initialize(stage);
if(stage==0)
{
if(hasPar("thermalNoise"))
thermalNoise=FWMath::dBm2mW(par("thermalNoise"));
else
thermalNoise=FWMath::dBm2mW(-100);
if(hasPar("carrierFrequency"))
carrierFrequency=par("carrierFrequency");
else
carrierFrequency=cc->par("carrierFrequency");
if(hasPar("sensitivity"))
sensitivity=FWMath::dBm2mW(par("sensitivity"));
else
sensitivity=FWMath::dBm2mW(-90);
if(hasPar("pathLossAlpha"))
{
pathLossAlpha=par("pathLossAlpha");
//if( pathLossAlpha < (double)(cc->par("alpha")) )
// error("AsyncSnrEval::initialize() pathLossAlpha can't be smaller than in ChannelControl. Please adjust your omnetpp.ini file accordingly");
}
else
pathLossAlpha=cc->par("alpha");
// initialize noiseLevel
noiseLevel = thermalNoise;
EV <<"Initialized channel with noise: "<<noiseLevel<<" sensitivity: "<<sensitivity<<endl;
// initialize the pointer of the snrInfo with NULL to indicate
// that currently no message is received
snrInfo.ptr = NULL;
// Initialize radio state
rs = new RadioState(RadioState::SLEEP);
bbRs = blackboard()->publish( "RadioState", rs );
colliscount=0;//collision packet counter
WATCH(colliscount);
}
}
/**
* delete the RadioState
**/
void AsyncSnrEval::finish()
{
BasicSnrEval::finish();
EV<<"The total collision packets is:"<<colliscount<<endl;
delete rs;
}
/**
* If a message is already beeing send the newly arrived one is
* deletetd and a warning is printed.
*
* Otherwise the RadioState is set to SEND and a timer is
* started. When this timer expires the RadioState is set back to RECV
* (or SLEEP respectively) again.
*
* If the host is receiving a packet this packet is from now on only
* considered as noise.
*/
void AsyncSnrEval::handleUpperMsg(AirFrame *frame)
{
if(rs->getState()==RadioState::SEND)
{
ev<<logName()<< " AsyncSnrEval: WARNING!!!!! Trying to send a message ";
ev<<"although already sending! This case is not properly handled, because the ";
ev<<"MAC should take care that this cannot happen!!! The newly arrived frame ";
ev<<"is deleted!!!\n";
delete frame;
//colliscount+=1;
return;
}
// if a packet was beeing received, it is corrupteed now (treated as
// noise)! print a warning!
if(snrInfo.ptr != NULL){
ev<<logName()<< " AsyncSnrEval: WARNING: Sending a message while receiving ";
ev<<"another. The received one is now corrupted/deleted!!!! The MAC layer should ";
ev<<"take care that this cannot occur!\n";
EV <<"Blackboard state: "<<rs->getState()<<" pointer: "<<snrInfo.ptr<<endl;
// remove the snr inforamtion stored for the currently beeing
// received message. This message is treated as noise now and the
// receive power has to be added to the noiseLevel
// delete the pointer to indicate that no message is beeing
// received
snrInfo.ptr = NULL;
// clear the snr list
snrInfo.sList.clear();
// add the receive power to the noise level
//noiseLevel += snrInfo.rcvdPower; //?
//colliscount+=1;
}
// now we are done with all the exception handling and can take care
// about the "real" stuff
//change radio status on the Blackboard
rs->setState(RadioState::SEND);
EV <<"sending, changing RadioState to SEND\n";
blackboard()->changed(bbRs, rs);
cMessage *timer = new cMessage(NULL,TRANSM_OVER);
scheduleAt(simTime()+frame->getDuration(),timer);
sendDown(frame);
}
/**
* The only self message that can arrive is a timer to indicate that
* sending of a message is completed.
*
* The RadioState has to be changed based on the noise level on the
* channel. If the noise level is bigger than the sensitivity switch
* to receive mode otherwise to sleep mode.
**/
void AsyncSnrEval::handleSelfMsg(cMessage *msg)
{
if(msg->kind()==TRANSM_OVER){
if(noiseLevel < sensitivity){
// set the RadioState to SLEEP
rs->setState(RadioState::SLEEP);
EV <<"transmission over, switch to sleep mode (state:sleep)\n";
blackboard()->changed(bbRs, rs);
}
else{
// set the RadioState to RECV 是否导致一直处于接收状态?RECV is combined into the SLEEP
rs->setState(RadioState::RECV);
EV <<"transmission over but noise level to high, switch to recv mode (state:RECV)\n";
blackboard()->changed(bbRs, rs);
//error("noise level to high!!! .....");
}
//delete the timer
delete msg;
}
else
error("unknown selfMsg .....");
}
/**
* This function is called right after a packet arrived, i.e. right
* before it is buffered for 'transmission time'.
*
* First the receive power of the packet has to be calculated and is
* stored in the recvBuff. Afterwards it has to be decided whether the
* packet is just noise or a "real" packet that needs to be received.
*
* The message is not treated as noise if all of the follwoing
* conditions apply:
*
* -# the power of the received signal is higher than the
* sensitivity.
* -# the host is currently not sending a message
* -# no other packet is already beeing received
*
* If all conditions apply a new SnrList is created and the RadioState
* is changed to RECV.
*
* If the packet is just noise the receive power is added to the noise
* Level of the channel. Additionally the snr information of the
* currently beeing received message (if any) has to be updated as
* well as the RadioState.
**/
void AsyncSnrEval::handleLowerMsgStart(AirFrame *frame)
{
// Calculate the receive power of the message
// get my position
Coord myPos = (Coord) cc->getNicPos(parentModule()->id());
//get Position of the sending node
Coord framePos = (Coord) cc->getNicPos(frame->getId());
//calculate distance and receive power
double distance = myPos.distance(framePos);
double rcvdPower = calcRcvdPower(frame->getPSend(), distance);
// store the receive power in the recvBuff
//recvBuff[frame] = rcvdPower;//?
//ev<<logName()<<":: The recvBuff[frame] ="<<recvBuff[frame]<<endl;
// if receive power is bigger than sensitivity and if not sending
// and currently not receiving another message
ev<<"rcvdPower="<<rcvdPower<<endl;
ev<<"sensitivity="<<sensitivity<<endl;
if(rcvdPower>=sensitivity )
{
if( rs->getState()!=RadioState::SEND && snrInfo.ptr==NULL)
{EV <<"receiving frame from"<<getSenderName(frame)<<endl;
// Put frame and related SnrList in receive buffer
SnrList snrList; //defined in SnrList.h!!
snrInfo.ptr = frame;
snrInfo.rcvdPower = rcvdPower;
snrInfo.sList = snrList;
// add initial snr value
addNewSnr();
if(rs->getState()!=RadioState::RECV)
{
// publish new RadioState
rs->setState(RadioState::RECV);
EV <<"publish new RadioState:RECV\n";
blackboard()->changed(bbRs, rs);
}
}
else
{
colliscount+=1;
EV <<"frame from "<<getSenderName(frame)<<"is just a collision frame\n";
}
}
// receive power is too low or another message is beeing sent or received
else
{
EV <<"frame from "<<getSenderName(frame)<<"is just noise\n";
//add receive power to the noise level
//noiseLevel += rcvdPower;
//if (rcvdPower>noiseLevel)
//{
// noiseLevel=rcvdPower;
//}
// if a message is beeing received add a new snr value
if(snrInfo.ptr!=NULL){
// update snr info for currently beeing received message
EV <<"add new snr value to snr list of message beeing received\n";
addNewSnr();
}
// update the RadioState if the noiseLevel exceeded the threshold
// and the radio is currently not in receive or in send mode
//if( noiseLevel>=sensitivity && rs->getState()==RadioState::SLEEP ){
// // publish new RadioState
// rs->setState(RadioState::RECV);
// EV <<"publish new RadioState:RECV\n";
// blackboard()->changed(bbRs, rs);
//}
}
}
/**
* This function is called right after the transmission is over,
* i.e. right after unbuffering. The noise level of the channel and
* the snr information of the buffered messages have to be updated.
*
* Additionally the RadioState has to be updated.
*
* If the corresponding AirFrame was not only noise the corresponding
* SnrList and the AirFrame are sent to the decider.
**/
void AsyncSnrEval::handleLowerMsgEnd(AirFrame *frame)
{
// check if message has to be send to the decider
if(snrInfo.ptr == frame)
{
EV <<"reception of frame over, preparing to send packet to upper layer\n";
// get Packet and list out of the receive buffer:
SnrList list;
list=snrInfo.sList;
// delete the pointer to indicate that no message is currently
// beeing received and clear the list
snrInfo.ptr = NULL;
snrInfo.sList.clear();
// delete the frame from the recvBuff
//recvBuff.erase(frame);
//Don't forget to send:
sendUp(frame, list);
EV <<"packet sent to the decider\n";
}
// all other messages are noise
else
{
EV <<"reception of noise message over, removing recvdPower from noiseLevel....\n";
// get the rcvdPower and subtract it from the noiseLevel
//noiseLevel -= recvBuff[frame];
// delete message from the recvBuff
//recvBuff.erase(frame);
// update snr info for message currently being received if any
if(snrInfo.ptr != NULL)
{
addNewSnr();
}
// message should be deleted
delete frame;
EV <<"message deleted\n";
}
// check the RadioState and update if necessary
// change to sleep if noiseLevel smaller than threshold and state was
// not sleep before
// do not change state if currently sending or receiving a message!!!
if( noiseLevel<sensitivity && rs->getState()==RadioState::RECV && snrInfo.ptr==NULL )
{
// publish the new RadioState:
EV <<"new RadioState is SLEEP\n";
rs->setState(RadioState::SLEEP);
blackboard()->changed(bbRs, rs);
}
}
/**
* The Snr information of the buffered message is updated....
**/
void AsyncSnrEval::addNewSnr()
{
SnrListEntry listEntry; //create a new entry
listEntry.time=simTime();
listEntry.snr= snrInfo.rcvdPower/noiseLevel;// 计算信噪比 snrInfo.sList.push_back(listEntry);
EV<<"New Snr added: "<<snrInfo.rcvdPower<<" / "<<noiseLevel<<endl;
EV<<"New Snr added: "<<listEntry.snr<<" at time:"<<simTime()<<endl;
}
/**
* This function simply calculates with how much power the signal
* arrives "here". If a different way of computing the path loss is
* required this function can be redefined.
**/
double AsyncSnrEval::calcRcvdPower(double pSend, double distance)
{
double speedOfLight = 300000000.0;
double waveLength = speedOfLight/carrierFrequency;
return (pSend*waveLength*waveLength / (16*M_PI*M_PI*pow(distance,pathLossAlpha)));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -