00001 #include "SNRThresholdDecider.h" 00002 00003 simtime_t SNRThresholdDecider::processNewSignal(AirFrame* frame) 00004 { 00005 //the rssi level changes therefore we need to check if we can 00006 //answer an ongoing ChannelSenseRequest now 00007 channelStateChanged(); 00008 00009 if(currentSignal.first != 0) { 00010 deciderEV << "Already receiving another AirFrame!" << endl; 00011 return notAgain; 00012 } 00013 00014 //get the receiving power of the Signal 00015 //Note: We assume the transmission power is represented by a rectangular function 00016 //which discontinuities (at start and end of the signal) are represented 00017 //by two key entries with different values very close to each other (see 00018 //MappingUtils "addDiscontinuity" method for details). This means 00019 //the transmission- and therefore also the receiving-power-mapping is still zero 00020 //at the exact start of the signal and not till one time step after the start its 00021 //at its actual transmission(/receiving) power. 00022 //Therefore we use MappingUtils "post"-method to ask for the receiving power 00023 //at the correct position. 00024 Signal& signal = frame->getSignal(); 00025 simtime_t receivingStart = MappingUtils::post(signal.getSignalStart()); 00026 double recvPower = signal.getReceivingPower()->getValue(Argument(receivingStart)); 00027 00028 // check whether signal is strong enough to receive 00029 if ( recvPower < sensitivity ) 00030 { 00031 deciderEV << "Signal is to weak (" << recvPower << " < " << sensitivity 00032 << ") -> do not receive." << endl; 00033 // Signal too weak, we can't receive it, tell PhyLayer that we don't want it again 00034 return notAgain; 00035 } 00036 00037 // Signal is strong enough, receive this Signal and schedule it 00038 deciderEV << "Signal is strong enough (" << recvPower << " > " << sensitivity 00039 << ") -> Trying to receive AirFrame." << endl; 00040 00041 currentSignal.first = frame; 00042 currentSignal.second = EXPECT_END; 00043 00044 return ( signal.getSignalStart() + signal.getSignalLength() ); 00045 } 00046 00047 // TODO: for now we check a larger mapping within an interval 00048 bool SNRThresholdDecider::checkIfAboveThreshold(Mapping* map, simtime_t start, simtime_t end) 00049 { 00050 assert(map); 00051 00052 if(debug){ 00053 deciderEV << "Checking if SNR is above Threshold of " << snrThreshold << endl; 00054 } 00055 00056 // check every entry in the mapping against threshold value 00057 ConstMappingIterator* it = map->createConstIterator(Argument(start)); 00058 // check if values at start-time fulfill snrThreshold-criterion 00059 if(debug){ 00060 deciderEV << "SNR at time " << start << " is " << it->getValue() << endl; 00061 } 00062 if ( it->getValue() <= snrThreshold ){ 00063 delete it; 00064 return false; 00065 } 00066 00067 while ( it->hasNext() && it->getNextPosition().getTime() < end) 00068 { 00069 it->next(); 00070 00071 if(debug){ 00072 deciderEV << "SNR at time " << it->getPosition().getTime() << " is " << it->getValue() << endl; 00073 } 00074 00075 // perform the check for smaller entry 00076 if ( it->getValue() <= snrThreshold) { 00077 delete it; 00078 return false; 00079 } 00080 } 00081 00082 it->iterateTo(Argument(end)); 00083 if(debug){ 00084 deciderEV << "SNR at time " << end << " is " << it->getValue() << endl; 00085 } 00086 00087 if ( it->getValue() <= snrThreshold ){ 00088 delete it; 00089 return false; 00090 } 00091 00092 delete it; 00093 return true; 00094 } 00095 00096 ChannelState SNRThresholdDecider::getChannelState() { 00097 00098 simtime_t now = phy->getSimTime(); 00099 double rssiValue = calcChannelSenseRSSI(now, now); 00100 00101 return ChannelState(isIdleRSSI(rssiValue), rssiValue); 00102 } 00103 00104 void SNRThresholdDecider::answerCSR(CSRInfo& requestInfo) 00105 { 00106 // put the sensing-result to the request and 00107 // send it to the Mac-Layer as Control-message (via Interface) 00108 requestInfo.first->setResult( getChannelState() ); 00109 phy->sendControlMsg(requestInfo.first); 00110 00111 requestInfo.first = 0; 00112 requestInfo.second = -1; 00113 requestInfo.canAnswerAt = -1; 00114 } 00115 00116 simtime_t SNRThresholdDecider::canAnswerCSR(const CSRInfo& requestInfo) { 00117 const ChannelSenseRequest* request = requestInfo.getRequest(); 00118 assert(request); 00119 00120 if(request->getSenseMode() == UNTIL_TIMEOUT) { 00121 opp_error("SNRThresholdDecider received an UNTIL_TIMEOUT ChannelSenseRequest.\n" 00122 "SNRThresholdDecider can only handle UNTIL_IDLE or UNTIL_BUSY requests because it " 00123 "implements only instantaneous sensing where UNTIL_TIMEOUT requests " 00124 "don't make sense. Please refer to ChannelSenseRequests documentation " 00125 "for details."); 00126 } 00127 00128 simtime_t requestTimeout = requestInfo.getSenseStart() + request->getSenseTimeout(); 00129 00130 simtime_t now = phy->getSimTime(); 00131 00132 ConstMapping* rssiMapping = calculateRSSIMapping(now, requestTimeout); 00133 00134 //this Decider only works for time-only signals 00135 assert(rssiMapping->getDimensionSet() == DimensionSet::timeDomain); 00136 00137 ConstMappingIterator* it = rssiMapping->createConstIterator(Argument(now)); 00138 00139 assert(request->getSenseMode() == UNTIL_IDLE 00140 || request->getSenseMode() == UNTIL_BUSY); 00141 bool untilIdle = request->getSenseMode() == UNTIL_IDLE; 00142 00143 simtime_t answerTime = requestTimeout; 00144 //check if the current rssi value enables us to answer the request 00145 if(isIdleRSSI(it->getValue()) == untilIdle) { 00146 answerTime = now; 00147 } 00148 else { 00149 //iterate through request interval to check when the rssi level 00150 //changes such that the request can be answered 00151 while(it->hasNext() && it->getNextPosition().getTime() < requestTimeout) { 00152 it->next(); 00153 00154 if(isIdleRSSI(it->getValue()) == untilIdle) { 00155 answerTime = it->getPosition().getTime(); 00156 break; 00157 } 00158 } 00159 } 00160 00161 delete it; 00162 delete rssiMapping; 00163 00164 return answerTime; 00165 } 00166 00167 simtime_t SNRThresholdDecider::processSignalEnd(AirFrame* frame) 00168 { 00169 assert(frame == currentSignal.first); 00170 // here the Signal is finally processed 00171 00172 // first collect all necessary information 00173 Mapping* snrMap = calculateSnrMapping(frame); 00174 assert(snrMap); 00175 00176 const Signal& signal = frame->getSignal(); 00177 simtime_t start = signal.getSignalStart(); 00178 simtime_t end = start + signal.getSignalLength(); 00179 00180 // NOTE: Since this decider does not consider the amount of time when the signal's SNR is 00181 // below the threshold even the smallest (normally insignificant) drop causes this decider 00182 // to reject reception of the signal. 00183 // Since the default MiXiM-signal is still zero at its exact start and end, these points 00184 // are ignored in the interval passed to the following method. 00185 bool aboveThreshold = checkIfAboveThreshold(snrMap, 00186 MappingUtils::post(start), 00187 MappingUtils::pre(end)); 00188 00189 // check if the snrMapping is above the Decider's specific threshold, 00190 // i.e. the Decider has received it correctly 00191 if (aboveThreshold) 00192 { 00193 deciderEV << "SNR is above threshold("<<snrThreshold<<") -> sending up." << endl; 00194 // go on with processing this AirFrame, send it to the Mac-Layer 00195 phy->sendUp(frame, new DeciderResult(true)); 00196 } else 00197 { 00198 deciderEV << "SNR is below threshold("<<snrThreshold<<") -> dropped." << endl; 00199 } 00200 00201 delete snrMap; 00202 snrMap = 0; 00203 00204 00205 // we have processed this AirFrame and we prepare to receive the next one 00206 currentSignal.first = 0; 00207 00208 return notAgain; 00209 } 00210