DeciderUWBIRED.cc

00001 #include "DeciderUWBIRED.h"
00002 #include "PhyLayerUWBIR.h"
00003 #include "AirFrameUWBIR_m.h"
00004 
00005 simtime_t DeciderUWBIRED::processSignal(AirFrame* frame) {
00006   Signal* s = &frame->getSignal();
00007   map<Signal*, int>::iterator it = currentSignals.find(s);
00008 
00009   if (it == currentSignals.end()) {
00010     return handleNewSignal(s);
00011   } else {
00012     switch (it->second) {
00013     case HEADER_OVER:
00014       return handleHeaderOver(it);
00015     case SIGNAL_OVER:
00016       return handleSignalOver(it, frame);
00017     default:
00018       break;
00019     }
00020   }
00021   //we should never get here!
00022   assert(false);
00023   return 0;
00024 }
00025 
00026 simtime_t DeciderUWBIRED::handleNewSignal(Signal* s) {
00027 
00028   int currState = uwbiface->getRadioState();
00029   if (tracking == 0 && currState == RadioUWBIR::SYNC) {
00030       simtime_t endOfHeader = s->getSignalStart()
00031         + IEEE802154A::mandatory_preambleLength;
00032       currentSignals[s] = HEADER_OVER;
00033       assert(endOfHeader> 0);
00034       return endOfHeader;
00035   } else {
00036     // we are already tracking an airframe, this is noise
00037     // or we are transmitting, switching, or sleeping
00038     currentSignals[s] = SIGNAL_OVER;
00039     simtime_t endOfSignal = s->getSignalStart() + s->getSignalLength();
00040     assert(endOfSignal> 0);
00041     return endOfSignal;
00042   }
00043 
00044 }
00045 
00046 
00047 // We just left reception state ; we must update our information on this frame accordingly
00048 
00049 void DeciderUWBIRED::cancelReception() {
00050   if(tracking != NULL) {
00051       tracking = NULL;
00052       synced = false;
00053   }
00054   nbCancelReceptions++;
00055 }
00056 
00057 simtime_t DeciderUWBIRED::handleHeaderOver(map<Signal*, int>::iterator& it) {
00058 
00059   int currState = uwbiface->getRadioState();
00060   Signal* s = it->first;
00061 
00062   if (tracking == 0 && currState == RadioUWBIR::SYNC) {
00063     // We are not tracking a signal currently.
00064     // Can we synchronize on this one ?
00065 
00066     bool isSyncSignalHigherThanThreshold;
00067     if(syncAlwaysSucceeds) {
00068       isSyncSignalHigherThanThreshold = true;
00069     } else {
00070       isSyncSignalHigherThanThreshold = attemptSync(s);
00071     }
00072 
00073     packet.setNbSyncAttempts(packet.getNbSyncAttempts() + 1);
00074 
00075     if(isSyncSignalHigherThanThreshold) {
00076       nbSuccessfulSyncs = nbSuccessfulSyncs + 1;
00077       tracking = s;
00078       synced = true;
00079       currentSignals[s] = SIGNAL_OVER;
00080       uwbiface->switchRadioToRX();
00081       packet.setNbSyncSuccesses(packet.getNbSyncSuccesses() + 1);
00082       // notify MAC layer through PHY layer
00083       cMessage* syncSuccessfulNotification = new cMessage("Ctrl_PHY2MAC_Sync_Success", SYNC_SUCCESS);
00084       phy->sendControlMsg(syncSuccessfulNotification);
00085     } else {
00086       nbFailedSyncs = nbFailedSyncs + 1;
00087       cMessage* syncFailureNotification = new cMessage("Ctrl_PHY2MAC_Sync_Failure", SYNC_FAILURE);
00088       phy->sendControlMsg(syncFailureNotification);
00089 
00090     }
00091     utility->publishBBItem(catUWBIRPacket, &packet, -1); // scope = all == host
00092 
00093   }
00094   // in any case, look at that frame again when it is finished
00095   it->second = SIGNAL_OVER;
00096   simtime_t startOfSignal = it->first->getSignalStart();
00097   simtime_t lengthOfSignal = it->first->getSignalLength();
00098   simtime_t endOfSignal = startOfSignal + lengthOfSignal;
00099   assert(endOfSignal> 0);
00100   return endOfSignal;
00101 }
00102 
00103 bool DeciderUWBIRED::attemptSync(Signal* s) {
00104   double snrValue;
00105   ConstMapping* power = s->getReceivingPower();
00106   ConstMappingIterator* mIt = power->createConstIterator();
00107 
00108   AirFrameVector syncVector;
00109   // Retrieve all potentially colliding airFrames
00110   phy->getChannelInfo(s->getSignalStart(), simTime(), syncVector);
00111 
00112   if(syncVector.size() > 1) {
00113     // do not accept interferers
00114     return false;
00115   }
00116   Argument posFirstPulse(IEEE802154A::tFirstSyncPulseMax + s->getSignalStart());
00117   mIt->jumpTo(posFirstPulse);
00118   snrValue = std::abs(mIt->getValue()/getNoiseValue());
00119     syncThresholds.record(snrValue);
00120     if(snrValue > syncThreshold) {
00121       return true;
00122     } else {
00123       return false;
00124     }
00125 }
00126 
00127 simtime_t DeciderUWBIRED::handleSignalOver(map<Signal*, int>::iterator& it, AirFrame* frame) {
00128   if (it->first == tracking) {
00129     nbFinishTrackingFrames++;
00130     vector<bool>* receivedBits = new vector<bool>();
00131     AirFrameUWBIR* frameuwb = check_and_cast<AirFrameUWBIR*>(frame);
00132     cfg = frameuwb->getCfg();
00133     bool isCorrect = decodePacket(it->first, receivedBits);
00134     // we cannot compute bit error rate here
00135     // so we send the packet to the MAC layer which will compare receivedBits
00136     // with the actual bits sent (stored in the encapsulated UWBIRMacPkt object).
00137     DeciderResultUWBIR * result = new DeciderResultUWBIR(isCorrect, receivedBits, snrLastPacket);
00138     if(isCorrect) {
00139       phy->sendUp(frame, result);
00140     } else {
00141       delete frame;
00142       delete result;
00143     }
00144     currentSignals.erase(it);
00145     tracking = 0;
00146     synced = false;
00147     uwbiface->switchRadioToSync();
00148     return -1;
00149   } else {
00150     // reached end of noisy signal
00151     currentSignals.erase(it);
00152     return -1;
00153   }
00154 }
00155 
00156 /*
00157  * @brief Returns false if the packet is incorrect. If true,
00158  * the MAC layer must still compare bit values to validate the frame.
00159  */
00160 bool DeciderUWBIRED::decodePacket(Signal* signal,
00161     vector<bool> * receivedBits) {
00162 
00163   simtime_t now, offset;
00164   simtime_t aSymbol, shift, burst;
00165 
00166   packetSNIR = 0;
00167   packetNoise = 0;
00168   packetSignal = 0;
00169   packetSamples = 0;
00170 
00171   // Retrieve all potentially colliding airFrames
00172   phy->getChannelInfo(signal->getSignalStart(), signal->getSignalStart()
00173       + signal->getSignalLength(), airFrameVector);
00174 
00175   for (airFrameIter = airFrameVector.begin(); airFrameIter
00176       != airFrameVector.end(); ++airFrameIter) {
00177     Signal & aSignal = (*airFrameIter)->getSignal();
00178     offsets.push_back(signal->getSignalStart() - aSignal.getSignalStart());
00179     ConstMapping* currPower = aSignal.getReceivingPower();
00180     receivingPowers.push_back(currPower);
00181     if (aSignal.getSignalStart() == signal->getSignalStart()
00182         && aSignal.getSignalLength() == signal->getSignalLength()) {
00183       signalPower = currPower;
00184     }
00185   }
00186 
00187   bool hasInterference = (airFrameVector.size() > 1);
00188   if(hasInterference) {
00189     nbFramesWithInterference++;
00190   } else {
00191     nbFramesWithoutInterference++;
00192   }
00193 
00194   // times are absolute
00195   offset = signal->getSignalStart() + cfg.preambleLength;
00196   shift = cfg.shift_duration;
00197   aSymbol = cfg.data_symbol_duration;
00198   burst = cfg.burst_duration;
00199   now = offset + cfg.pulse_duration / 2;
00200   std::pair<double, double> energyZero, energyOne;
00201   IEEE802154A::setConfig(cfg);
00202   epulseAggregate = 0;
00203   enoiseAggregate = 0;
00204 
00205   // debugging information (start)
00206   if (trace) {
00207     ConstMappingIterator* iteratorDbg = signalPower->createConstIterator();
00208     iteratorDbg->jumpToBegin();
00209     while (iteratorDbg->hasNext()) {
00210       iteratorDbg->next();
00211       receivedPulses.recordWithTimestamp(
00212         iteratorDbg->getPosition().getTime(),
00213         signalPower->getValue(iteratorDbg->getPosition())
00214       );
00215     }
00216     delete iteratorDbg;
00217   }
00218   // debugging information (end)
00219 
00220   int symbol;
00221   // Loop to decode each bit value
00222   for (symbol = 0; cfg.preambleLength + symbol
00223       * aSymbol < signal->getSignalLength(); symbol++) {
00224 
00225 //    int hoppingPos = IEEE802154A::getHoppingPos(symbol);
00226     int decodedBit;
00227 
00228     if (stats) {
00229       nbSymbols = nbSymbols + 1;
00230     }
00231 
00232     // sample in window zero
00233     now = now + IEEE802154A::getHoppingPos(symbol)*cfg.burst_duration;
00234     energyZero = integrateWindow(symbol, now, burst, signal);
00235     // sample in window one
00236     now = now + shift;
00237     energyOne = integrateWindow(symbol, now, burst, signal);
00238 
00239     if (energyZero.second > energyOne.second) {
00240       decodedBit = 0;
00241       packetSNIR = packetSNIR + energyZero.first;
00242       } else {
00243         decodedBit = 1;
00244       packetSNIR = packetSNIR + energyOne.first;
00245       }
00246 
00247 
00248     receivedBits->push_back(static_cast<bool>(decodedBit));
00249     //packetSamples = packetSamples + 16; // 16 EbN0 evaluations per bit
00250 
00251     now = offset + (symbol + 1) * aSymbol + cfg.pulse_duration / 2;
00252 
00253   }
00254     symbol = symbol + 1;
00255 
00256   bool isCorrect = true;
00257   if(airFrameVector.size() > 1 && alwaysFailOnDataInterference) {
00258     isCorrect = false;
00259   }
00260   packetSNIR = packetSNIR / symbol;
00261   snrLastPacket = 10*log10(packetSNIR);  // convert to dB
00262   airFrameVector.clear();
00263   receivingPowers.clear();
00264   offsets.clear();
00265 
00266   return isCorrect;
00267 }
00268 
00269 /*
00270  * @brief Returns a pair with as first value the SNIR (if the signal is not nul in this window, and 0 otherwise)
00271  * and as second value a "score" associated to this window. This score is equals to the sum for all
00272  * 16 pulse peak positions of the voltage measured by the receiver ADC.
00273  */
00274 pair<double, double> DeciderUWBIRED::integrateWindow(int symbol,
00275     simtime_t now, simtime_t burst, Signal* signal) {
00276   std::pair<double, double> energy;
00277   energy.first = 0; // stores SNIR
00278   energy.second = 0; // stores total captured window energy
00279   vector<ConstMapping*>::iterator mappingIter;
00280   Argument arg;
00281   simtime_t windowEnd = now + burst;
00282 
00283   double burstsnr = 0;
00284   // Triangular baseband pulses
00285   // we sample at each pulse peak
00286   // get the interpolated values of amplitude for each interferer
00287   // and add these to the peak with a random phase
00288 
00289   // we sample one point per pulse
00290   // caller has already set our time reference ("now") at the peak of the pulse
00291   for (; now < windowEnd; now += cfg.pulse_duration) {
00292     double signalValue = 0; // electric field from tracked signal [V/m²]
00293     double resPower = 0;    // electric field at antenna = combination of all arriving electric fields [V/m²]
00294     double vEfield = 0;   // voltage at antenna caused by electric field Efield [V]
00295     double vmeasured = 0; // voltage measured by energy-detector [V], including thermal noise
00296     double vmeasured_square = 0; // to the square [V²]
00297     double vsignal_square = 0;  // square of the voltage that would be induced on the antenna if there were no interferers (Efield=signalValue)
00298     double vnoise_square = 0; // (thermal noise + interferers noise)²
00299     double snir = 0;      // burst SNIR estimate
00300     double vThermalNoise = 0; // thermal noise realization
00301     arg.setTime(now);   // loop variable: begin by considering the first pulse
00302     int currSig = 0;
00303 
00304     // consider all interferers at this point in time
00305     for (airFrameIter = airFrameVector.begin(); airFrameIter
00306         != airFrameVector.end(); ++airFrameIter) {
00307       Signal & aSignal = (*airFrameIter)->getSignal();
00308       ConstMapping* currPower = aSignal.getReceivingPower();
00309       double measure = currPower->getValue(arg)*peakPulsePower; //TODO: de-normalize (peakPulsePower should be in AirFrame or in Signal, to be set at run-time)
00310 //      measure = measure * uniform(0, +1); // random point of Efield at sampling (due to pulse waveform and self interference)
00311       if (currPower == signalPower) {
00312         signalValue = measure*0.5; // we capture half of the maximum possible pulse energy to account for self  interference
00313         resPower = resPower + signalValue;
00314       } else {
00315         // take a random point within pulse envelope for interferer
00316         resPower = resPower + measure * uniform(-1, +1);
00317       }
00318       ++currSig;
00319     }
00320 
00321 //    double attenuatedPower = resPower / 10; // 10 dB = 6 dB implementation loss + 5 dB noise factor
00322     vEfield = sqrt(50*resPower); // P=V²/R
00323     // add thermal noise realization
00324     vThermalNoise = getNoiseValue();
00325     vnoise2 = pow(vThermalNoise, 2);    // for convenience
00326     vmeasured = vEfield + vThermalNoise;
00327     vmeasured_square = pow(vmeasured, 2);
00328     // signal + interference + noise
00329     energy.second = energy.second + vmeasured_square;  // collect this contribution
00330 
00331     // Now evaluates signal to noise ratio
00332     // signal converted to antenna voltage squared
00333     vsignal_square = 50*signalValue;
00334     vnoise_square = pow(sqrt(vmeasured_square) - sqrt(vsignal_square), 2); // everything - signal = noise + interfence
00335     snir = signalValue / 2.0217E-12;
00336     epulseAggregate = epulseAggregate + pow(vEfield, 2);
00337     enoiseAggregate = enoiseAggregate + vnoise2;
00338     packetSignal = packetSignal + vsignal_square;
00339     packetNoise = packetNoise + vnoise_square;
00340     snirs = snirs + snir;
00341     snirEvals = snirEvals + 1;
00342     if(signalValue > 0) {
00343       double pulseSnr = signalValue / (vnoise_square/50);
00344       burstsnr = burstsnr + pulseSnr;
00345     }
00346     energy.first = energy.first + snir;
00347 
00348   } // consider next point in time
00349   return energy;
00350 }
00351 
00352 simtime_t DeciderUWBIRED::handleChannelSenseRequest(ChannelSenseRequest* request) {
00353   if (channelSensing) {
00354     // send back the channel state
00355     request->setResult(new ChannelState(synced, 0)); // bogus rssi value (0)
00356     phy->sendControlMsg(request);
00357     channelSensing = false;
00358     return -1; // do not call me back ; I have finished
00359   } else {
00360     channelSensing = true;
00361     return -1; //phy->getSimTime() + request->getSenseDuration();
00362   }
00363 }
00364 
00365 ChannelState DeciderUWBIRED::getChannelState() {
00366   return ChannelState(true, 0);  // channel is always "sensed" free
00367 }
00368 
00369 void DeciderUWBIRED::finish() {
00370   phy->recordScalar("nbFramesWithInterference", nbFramesWithInterference);
00371   phy->recordScalar("nbFramesWithoutInterference", nbFramesWithoutInterference);
00372   phy->recordScalar("nbRandomBits", nbRandomBits);
00373   phy->recordScalar("avgThreshold", getAvgThreshold());
00374   phy->recordScalar("nbSuccessfulSyncs", nbSuccessfulSyncs);
00375   phy->recordScalar("nbFailedSyncs", nbFailedSyncs);
00376   phy->recordScalar("nbCancelReceptions", nbCancelReceptions);
00377   phy->recordScalar("nbFinishTrackingFrames", nbFinishTrackingFrames);
00378   phy->recordScalar("nbFinishNoiseFrames", nbFinishNoiseFrames);
00379 }