Decider implementation which decides a signals correctness by checking its SNR against a threshold. More...
#include <SNRThresholdDecider.h>
Inherits BaseDecider.
Public Member Functions | |
SNRThresholdDecider (DeciderToPhyInterface *phy, double snrThreshold, double sensitivity, double busyThreshold, int myIndex=-1, bool debug=false) | |
Initializes a new SNRThresholdDecider. | |
virtual ChannelState | getChannelState () |
A function that returns information about the channel state. | |
Protected Member Functions | |
virtual bool | checkIfAboveThreshold (Mapping *map, simtime_t start, simtime_t end) |
Checks a mapping against a specific threshold (element-wise). | |
virtual simtime_t | processNewSignal (AirFrame *frame) |
Processes a new Signal. Returns the time it wants to handle the signal again. | |
virtual simtime_t | processSignalEnd (AirFrame *frame) |
Processes a received AirFrame. | |
virtual simtime_t | canAnswerCSR (const CSRInfo &requestInfo) |
Returns point in time when the ChannelSenseRequest of the passed CSRInfo can be answered (e.g. because channel state changed or timeout is reached). | |
virtual void | answerCSR (CSRInfo &requestInfo) |
Answers the ChannelSenseRequest (CSR) from the passed CSRInfo. | |
bool | isIdleRSSI (double rssi) const |
Returns whether the passed rssi value indicates a idle channel. | |
Protected Attributes | |
double | snrThreshold |
Threshold value for checking a SNR-map (SNR-threshold). | |
double | busyThreshold |
The threshold rssi level above which the channel is considered busy. |
Decider implementation which decides a signals correctness by checking its SNR against a threshold.
SNRThresholdDecider decides the channel state (idle/busy) at hand of the current received total power level (independent from signal or noise). If its above the threshold defined by the "busyThreshold" parameter it considers the channel busy. The RSSI value returned by this Decider for a ChannelSenseRequest over time is always the RSSI value at the end of the sense.
SNRThresholdDecider implements only instantaneous channel sensing therefore it can only handle "UNTIL_IDLE" and "UNTIL_BUSY" ChannelSenseRequests but not "UNTIL_TIMEOUT".
Instantaneous channel sensing means SNRThresholdDecider is simplified in the way that the channel does not has to be below the threshold for a certain amount of time to be considered idle (how it would be in reality), but immediately after the RSSI drops below the threshold the channel is considered idle. This means "UNTIL_IDLE" and "UNTIL_BUSY" request are also answered at the first moment the channel drops below or raises above the threshold. SNRThresholdDecider does not support "UNTIL_TIMEOUT" requests because they are used to calculate the channel state over a time period (by averaging over it for example) which is not consistent with using instantaneous idle/busy changes.
Definition at line 35 of file SNRThresholdDecider.h.
SNRThresholdDecider::SNRThresholdDecider | ( | DeciderToPhyInterface * | phy, | |
double | snrThreshold, | |||
double | sensitivity, | |||
double | busyThreshold, | |||
int | myIndex = -1 , |
|||
bool | debug = false | |||
) | [inline] |
Initializes a new SNRThresholdDecider.
phy | - pointer to the deciders phy layer | |
snrThreshold | - the threshold (as fraction) above which a signal is received correctly | |
sensitivity | - the sensitivity (in mW) of the physical layer | |
busyThreshold | - the rssi threshold (in mW) above which the channel is considered idle | |
myIndex | - the index of the host of this deciders phy (for debugging output) | |
debug | - should debug messages be displayed? |
Definition at line 118 of file SNRThresholdDecider.h.
: BaseDecider(phy, sensitivity, myIndex, debug), snrThreshold(snrThreshold), busyThreshold(busyThreshold) {}
void SNRThresholdDecider::answerCSR | ( | CSRInfo & | requestInfo | ) | [protected, virtual] |
Answers the ChannelSenseRequest (CSR) from the passed CSRInfo.
Calculates the rssi value and the channel idle state and sends the CSR together with the result back to the mac layer.
Reimplemented from BaseDecider.
Definition at line 104 of file SNRThresholdDecider.cc.
References getChannelState(), Decider::phy, and DeciderToPhyInterface::sendControlMsg().
{ // put the sensing-result to the request and // send it to the Mac-Layer as Control-message (via Interface) requestInfo.first->setResult( getChannelState() ); phy->sendControlMsg(requestInfo.first); requestInfo.first = 0; requestInfo.second = -1; requestInfo.canAnswerAt = -1; }
bool SNRThresholdDecider::checkIfAboveThreshold | ( | Mapping * | map, | |
simtime_t | start, | |||
simtime_t | end | |||
) | [protected, virtual] |
Checks a mapping against a specific threshold (element-wise).
Definition at line 48 of file SNRThresholdDecider.cc.
References Mapping::createConstIterator(), BaseDecider::debug, ConstMappingIterator::getNextPosition(), ConstMappingIterator::getPosition(), Argument::getTime(), ConstMappingIterator::getValue(), ConstMappingIterator::hasNext(), ConstMappingIterator::iterateTo(), ConstMappingIterator::next(), and snrThreshold.
Referenced by processSignalEnd().
{ assert(map); if(debug){ deciderEV << "Checking if SNR is above Threshold of " << snrThreshold << endl; } // check every entry in the mapping against threshold value ConstMappingIterator* it = map->createConstIterator(Argument(start)); // check if values at start-time fulfill snrThreshold-criterion if(debug){ deciderEV << "SNR at time " << start << " is " << it->getValue() << endl; } if ( it->getValue() <= snrThreshold ){ delete it; return false; } while ( it->hasNext() && it->getNextPosition().getTime() < end) { it->next(); if(debug){ deciderEV << "SNR at time " << it->getPosition().getTime() << " is " << it->getValue() << endl; } // perform the check for smaller entry if ( it->getValue() <= snrThreshold) { delete it; return false; } } it->iterateTo(Argument(end)); if(debug){ deciderEV << "SNR at time " << end << " is " << it->getValue() << endl; } if ( it->getValue() <= snrThreshold ){ delete it; return false; } delete it; return true; }
ChannelState SNRThresholdDecider::getChannelState | ( | ) | [virtual] |
A function that returns information about the channel state.
It is an alternative for the MACLayer in order to obtain information immediately (in contrast to sending a ChannelSenseRequest, i.e. sending a cMessage over the OMNeT-control-channel)
Reimplemented from BaseDecider.
Definition at line 96 of file SNRThresholdDecider.cc.
References BaseDecider::calcChannelSenseRSSI(), DeciderToPhyInterface::getSimTime(), isIdleRSSI(), and Decider::phy.
Referenced by answerCSR().
{ simtime_t now = phy->getSimTime(); double rssiValue = calcChannelSenseRSSI(now, now); return ChannelState(isIdleRSSI(rssiValue), rssiValue); }
bool SNRThresholdDecider::isIdleRSSI | ( | double | rssi | ) | const [inline, protected] |
Returns whether the passed rssi value indicates a idle channel.
rssi | the channels rssi value to evaluate |
Definition at line 99 of file SNRThresholdDecider.h.
References busyThreshold.
Referenced by canAnswerCSR(), and getChannelState().
{ return rssi <= busyThreshold; }
simtime_t SNRThresholdDecider::processNewSignal | ( | AirFrame * | frame | ) | [protected, virtual] |
Processes a new Signal. Returns the time it wants to handle the signal again.
Checks if the signals receiving power is above the sensitivity of the radio and we are not already trying to receive another AirFrame. If thats the case it waits for the end of the signal.
Also checks if the new AirFrame changed the power level in the way that we can answer an ongoing channel sense request.
Reimplemented from BaseDecider.
Definition at line 3 of file SNRThresholdDecider.cc.
References BaseDecider::channelStateChanged(), BaseDecider::currentSignal, Signal::getReceivingPower(), Signal::getSignalLength(), Signal::getSignalStart(), Decider::notAgain, MappingUtils::post(), and BaseDecider::sensitivity.
{ //the rssi level changes therefore we need to check if we can //answer an ongoing ChannelSenseRequest now channelStateChanged(); if(currentSignal.first != 0) { deciderEV << "Already receiving another AirFrame!" << endl; return notAgain; } //get the receiving power of the Signal //Note: We assume the transmission power is represented by a rectangular function //which discontinuities (at start and end of the signal) are represented //by two key entries with different values very close to each other (see //MappingUtils "addDiscontinuity" method for details). This means //the transmission- and therefore also the receiving-power-mapping is still zero //at the exact start of the signal and not till one time step after the start its //at its actual transmission(/receiving) power. //Therefore we use MappingUtils "post"-method to ask for the receiving power //at the correct position. Signal& signal = frame->getSignal(); simtime_t receivingStart = MappingUtils::post(signal.getSignalStart()); double recvPower = signal.getReceivingPower()->getValue(Argument(receivingStart)); // check whether signal is strong enough to receive if ( recvPower < sensitivity ) { deciderEV << "Signal is to weak (" << recvPower << " < " << sensitivity << ") -> do not receive." << endl; // Signal too weak, we can't receive it, tell PhyLayer that we don't want it again return notAgain; } // Signal is strong enough, receive this Signal and schedule it deciderEV << "Signal is strong enough (" << recvPower << " > " << sensitivity << ") -> Trying to receive AirFrame." << endl; currentSignal.first = frame; currentSignal.second = EXPECT_END; return ( signal.getSignalStart() + signal.getSignalLength() ); }
simtime_t SNRThresholdDecider::processSignalEnd | ( | AirFrame * | frame | ) | [protected, virtual] |
Processes a received AirFrame.
The SNR-mapping for the Signal is created and checked against the Deciders SNR-threshold. Depending on that the received AirFrame is either sent up to the MAC-Layer or dropped.
Reimplemented from BaseDecider.
Definition at line 167 of file SNRThresholdDecider.cc.
References BaseDecider::calculateSnrMapping(), checkIfAboveThreshold(), BaseDecider::currentSignal, Signal::getSignalLength(), Signal::getSignalStart(), Decider::notAgain, Decider::phy, MappingUtils::post(), MappingUtils::pre(), DeciderToPhyInterface::sendUp(), and snrThreshold.
{ assert(frame == currentSignal.first); // here the Signal is finally processed // first collect all necessary information Mapping* snrMap = calculateSnrMapping(frame); assert(snrMap); const Signal& signal = frame->getSignal(); simtime_t start = signal.getSignalStart(); simtime_t end = start + signal.getSignalLength(); // NOTE: Since this decider does not consider the amount of time when the signal's SNR is // below the threshold even the smallest (normally insignificant) drop causes this decider // to reject reception of the signal. // Since the default MiXiM-signal is still zero at its exact start and end, these points // are ignored in the interval passed to the following method. bool aboveThreshold = checkIfAboveThreshold(snrMap, MappingUtils::post(start), MappingUtils::pre(end)); // check if the snrMapping is above the Decider's specific threshold, // i.e. the Decider has received it correctly if (aboveThreshold) { deciderEV << "SNR is above threshold("<<snrThreshold<<") -> sending up." << endl; // go on with processing this AirFrame, send it to the Mac-Layer phy->sendUp(frame, new DeciderResult(true)); } else { deciderEV << "SNR is below threshold("<<snrThreshold<<") -> dropped." << endl; } delete snrMap; snrMap = 0; // we have processed this AirFrame and we prepare to receive the next one currentSignal.first = 0; return notAgain; }