BaseDecider.cc

00001 /*
00002  * BaseDecider.cc
00003  *
00004  *  Created on: 24.02.2009
00005  *      Author: karl
00006  */
00007 
00008 #include "BaseDecider.h"
00009 
00010 simtime_t BaseDecider::processSignal(AirFrame* frame) {
00011 
00012   assert(frame);
00013   deciderEV << "Processing AirFrame..." << endl;
00014 
00015   switch(getSignalState(frame)) {
00016   case NEW:
00017     return processNewSignal(frame);
00018   case EXPECT_HEADER:
00019     return processSignalHeader(frame);
00020   case EXPECT_END:
00021     return processSignalEnd(frame);
00022   default:
00023     return processUnknownSignal(frame);
00024   }
00025 }
00026 
00027 simtime_t BaseDecider::processNewSignal(AirFrame* frame) {
00028   if(currentSignal.first != 0) {
00029     deciderEV << "Already receiving another AirFrame!" << endl;
00030     return notAgain;
00031   }
00032 
00033   // get the receiving power of the Signal at start-time
00034   Signal& signal = frame->getSignal();
00035   double recvPower = signal.getReceivingPower()->getValue(Argument(signal.getSignalStart()));
00036 
00037   // check whether signal is strong enough to receive
00038   if ( recvPower < sensitivity )
00039   {
00040     deciderEV << "Signal is to weak (" << recvPower << " < " << sensitivity
00041         << ") -> do not receive." << endl;
00042     // Signal too weak, we can't receive it, tell PhyLayer that we don't want it again
00043     return notAgain;
00044   }
00045 
00046   // Signal is strong enough, receive this Signal and schedule it
00047   deciderEV << "Signal is strong enough (" << recvPower << " > " << sensitivity
00048       << ") -> Trying to receive AirFrame." << endl;
00049 
00050   currentSignal.first = frame;
00051   currentSignal.second = EXPECT_END;
00052 
00053   //channel turned busy
00054   setChannelIdleStatus(false);
00055 
00056   return ( signal.getSignalStart() + signal.getSignalLength() );
00057 }
00058 
00059 simtime_t BaseDecider::processSignalEnd(AirFrame* frame) {
00060   deciderEV << "packet was received correctly, it is now handed to upper layer...\n";
00061   phy->sendUp(frame, new DeciderResult(true));
00062 
00063   // we have processed this AirFrame and we prepare to receive the next one
00064   currentSignal.first = 0;
00065 
00066   //channel is idle now
00067   setChannelIdleStatus(true);
00068 
00069   return notAgain;
00070 }
00071 
00072 ChannelState BaseDecider::getChannelState() {
00073 
00074   simtime_t now = phy->getSimTime();
00075   double rssiValue = calcChannelSenseRSSI(now, now);
00076 
00077   return ChannelState(isChannelIdle, rssiValue);
00078 }
00079 
00080 
00081 simtime_t BaseDecider::handleChannelSenseRequest(ChannelSenseRequest* request) {
00082 
00083   assert(request);
00084 
00085   if (currentChannelSenseRequest.first == 0)
00086   {
00087     return handleNewSenseRequest(request);
00088   }
00089 
00090   if (currentChannelSenseRequest.first != request) {
00091     opp_error("Got a new ChannelSenseRequest while already handling another one!");
00092     return notAgain;
00093   }
00094 
00095   handleSenseRequestEnd(currentChannelSenseRequest);
00096 
00097   // say that we don't want to have it again
00098   return notAgain;
00099 }
00100 
00101 simtime_t BaseDecider::handleNewSenseRequest(ChannelSenseRequest* request)
00102 {
00103   // no request handled at the moment, handling the new one
00104   simtime_t now = phy->getSimTime();
00105 
00106   // saving the pointer to the request and its start-time (now)
00107   currentChannelSenseRequest.setRequest(request);
00108   currentChannelSenseRequest.setSenseStart(now);
00109 
00110   //get point in time when we can answer the request (as far as we
00111   //know at this point in time)
00112   currentChannelSenseRequest.canAnswerAt = canAnswerCSR(currentChannelSenseRequest);
00113 
00114   //check if we can already answer the request
00115   if(now == currentChannelSenseRequest.canAnswerAt)
00116   {
00117     answerCSR(currentChannelSenseRequest);
00118     return notAgain;
00119   }
00120 
00121   return currentChannelSenseRequest.canAnswerAt;
00122 }
00123 
00124 void BaseDecider::handleSenseRequestEnd(CSRInfo& requestInfo) {
00125   assert(canAnswerCSR(requestInfo) == phy->getSimTime());
00126   answerCSR(requestInfo);
00127 }
00128 
00129 int BaseDecider::getSignalState(AirFrame* frame) {
00130   if(frame == currentSignal.first)
00131     return currentSignal.second;
00132 
00133   return NEW;
00134 }
00135 
00136 void BaseDecider::channelStateChanged()
00137 {
00138   if(!currentChannelSenseRequest.getRequest())
00139     return;
00140 
00141   //check if the point in time when we can answer the request has changed
00142   simtime_t canAnswerAt = canAnswerCSR(currentChannelSenseRequest);
00143 
00144   //check if answer time has changed
00145   if(canAnswerAt != currentChannelSenseRequest.canAnswerAt) {
00146     //can we answer it now?
00147     if(canAnswerAt == phy->getSimTime()) {
00148       phy->cancelScheduledMessage(currentChannelSenseRequest.getRequest());
00149       answerCSR(currentChannelSenseRequest);
00150     } else {
00151       phy->rescheduleMessage(currentChannelSenseRequest.getRequest(),
00152                    canAnswerAt);
00153       currentChannelSenseRequest.canAnswerAt = canAnswerAt;
00154     }
00155   }
00156 }
00157 
00158 void BaseDecider::setChannelIdleStatus(bool isIdle) {
00159   isChannelIdle = isIdle;
00160 
00161   channelStateChanged();
00162 }
00163 
00164 simtime_t BaseDecider::canAnswerCSR(const CSRInfo& requestInfo)
00165 {
00166   assert(requestInfo.first);
00167 
00168   bool modeFulfilled = false;
00169 
00170   switch(requestInfo.first->getSenseMode())
00171   {
00172   case UNTIL_IDLE:
00173     modeFulfilled = isChannelIdle;
00174     break;
00175   case UNTIL_BUSY:
00176     modeFulfilled = !isChannelIdle;
00177     break;
00178   }
00179 
00180   if(modeFulfilled) {
00181     return phy->getSimTime();
00182   }
00183 
00184   //return point in time when time out is reached
00185   return requestInfo.second + requestInfo.first->getSenseTimeout();
00186 }
00187 
00188 double BaseDecider::calcChannelSenseRSSI(simtime_t start, simtime_t end) {
00189   Mapping* rssiMap = calculateRSSIMapping(start, end);
00190 
00191   // the sensed RSSI-value is the maximum value between (and including) the interval-borders
00192   double rssi = MappingUtils::findMax(*rssiMap, Argument(start), Argument(end));
00193 
00194   //"findMax()" returns "-DBL_MAX" on empty mappings
00195   if (rssi < 0)
00196     rssi = 0;
00197 
00198   delete rssiMap;
00199 
00200   return rssi;
00201 }
00202 
00203 void BaseDecider::answerCSR(CSRInfo& requestInfo) {
00204 
00205   double rssiValue = calcChannelSenseRSSI(requestInfo.second, phy->getSimTime());
00206 
00207   // put the sensing-result to the request and
00208   // send it to the Mac-Layer as Control-message (via Interface)
00209   requestInfo.first->setResult( ChannelState(isChannelIdle, rssiValue) );
00210   phy->sendControlMsg(requestInfo.first);
00211 
00212   requestInfo.first = 0;
00213   requestInfo.second = -1;
00214   requestInfo.canAnswerAt = -1;
00215 }
00216 
00217 Mapping* BaseDecider::calculateSnrMapping(AirFrame* frame)
00218 {
00219   /* calculate Noise-Strength-Mapping */
00220   Signal& signal = frame->getSignal();
00221 
00222   simtime_t start = signal.getSignalStart();
00223   simtime_t end = start + signal.getSignalLength();
00224 
00225   Mapping* noiseMap = calculateRSSIMapping(start, end, frame);
00226   assert(noiseMap);
00227   ConstMapping* recvPowerMap = signal.getReceivingPower();
00228   assert(recvPowerMap);
00229 
00230   //TODO: handle noise of zero (must not devide with zero!)
00231   Mapping* snrMap = MappingUtils::divide( *recvPowerMap, *noiseMap, 0.0 );
00232 
00233   delete noiseMap;
00234   noiseMap = 0;
00235 
00236   return snrMap;
00237 }
00238 
00239 void BaseDecider::getChannelInfo(simtime_t start, simtime_t end,
00240                  AirFrameVector& out)
00241 {
00242   phy->getChannelInfo(start, end, out);
00243 }
00244 
00245 Mapping* BaseDecider::calculateRSSIMapping( simtime_t start,
00246                     simtime_t end,
00247                     AirFrame* exclude)
00248 {
00249   if(exclude)
00250     deciderEV << "Creating RSSI map excluding AirFrame with id " << exclude->getId() << endl;
00251   else
00252     deciderEV << "Creating RSSI map." << endl;
00253 
00254   AirFrameVector airFrames;
00255 
00256   // collect all AirFrames that intersect with [start, end]
00257   getChannelInfo(start, end, airFrames);
00258 
00259   //TODO: create a "MappingUtils:createMappingFrom()"-method and use it here instead
00260   //of abusing the add method
00261   // create an empty mapping
00262   Mapping* resultMap = MappingUtils::createMapping(0.0, DimensionSet::timeDomain);
00263 
00264   //add thermal noise
00265   ConstMapping* thermalNoise = phy->getThermalNoise(start, end);
00266   if(thermalNoise) {
00267     Mapping* tmp = resultMap;
00268     resultMap = MappingUtils::add(*resultMap, *thermalNoise);
00269     delete tmp;
00270   }
00271 
00272   // otherwise, iterate over all AirFrames (except exclude)
00273   // and sum up their receiving-power-mappings
00274   AirFrameVector::iterator it;
00275   for (it = airFrames.begin(); it != airFrames.end(); it++)
00276   {
00277     // the vector should not contain pointers to 0
00278     assert (*it != 0);
00279 
00280     // if iterator points to exclude (that includes the default-case 'exclude == 0')
00281     // then skip this AirFrame
00282     if ( *it == exclude ) continue;
00283 
00284     // otherwise get the Signal and its receiving-power-mapping
00285     Signal& signal = (*it)->getSignal();
00286 
00287     // backup pointer to result map
00288     // Mapping* resultMapOld = resultMap;
00289 
00290     // TODO1.1: for testing purposes, for now we don't specify an interval
00291     // and add the Signal's receiving-power-mapping to resultMap in [start, end],
00292     // the operation Mapping::add returns a pointer to a new Mapping
00293 
00294     ConstMapping* recvPowerMap = signal.getReceivingPower();
00295     assert(recvPowerMap);
00296 
00297     // Mapping* resultMapNew = Mapping::add( *(signal.getReceivingPower()), *resultMap, start, end );
00298 
00299     deciderEV << "Adding mapping of Airframe with ID " << (*it)->getId()
00300         << ". Starts at " << signal.getSignalStart()
00301         << " and ends at " << signal.getSignalStart() + signal.getSignalLength() << endl;
00302 
00303     Mapping* resultMapNew = MappingUtils::add( *recvPowerMap, *resultMap, 0.0 );
00304 
00305     // discard old mapping
00306     delete resultMap;
00307     resultMap = resultMapNew;
00308     resultMapNew = 0;
00309   }
00310 
00311   return resultMap;
00312 }
00313