⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asyncsnreval.cc

📁 基于omnet++开发的Mf框架下的802.11协议仿真。
💻 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 + -