Decider802154Narrow.cc

00001 /*
00002  * Decider802154Narrow.cc
00003  *
00004  *  Created on: 11.02.2009
00005  *      Author: karl wessel
00006  */
00007 
00008 #include "Decider802154Narrow.h"
00009 #include "DeciderResult802154Narrow.h"
00010 #include <MacPkt_m.h>
00011 #include <PhyToMacControlInfo.h>
00012 #include <cmath>
00013 
00014 bool Decider802154Narrow::syncOnSFD(AirFrame* frame) {
00015   double BER;
00016   double sfdErrorProbability;
00017 
00018   BER = evalBER(frame);
00019   sfdErrorProbability = 1.0 - pow((1.0 - BER), sfdLength);
00020 
00021   return sfdErrorProbability < uniform(0, 1, 0);
00022 }
00023 
00024 double Decider802154Narrow::evalBER(AirFrame* frame) {
00025   Signal& signal = frame->getSignal();
00026 
00027   simtime_t time = MappingUtils::post(phy->getSimTime());
00028   double rcvPower = signal.getReceivingPower()->getValue(Argument(time));
00029 
00030   ConstMapping* noise = calculateRSSIMapping(time, time, frame);
00031 
00032   Argument argStart(time);
00033   double noiseLevel = noise->getValue(argStart);
00034 
00035   delete noise;
00036 
00037   return getBERFromSNR(rcvPower/noiseLevel); //std::max(0.5 * exp(-rcvPower / (2 * noiseLevel)), DEFAULT_BER_LOWER_BOUND);
00038 }
00039 
00040 simtime_t Decider802154Narrow::processNewSignal(AirFrame* frame) {
00041   //if we are already receiving another signal this is noise
00042   if(currentSignal.first != 0) {
00043     return notAgain;
00044   }
00045 
00046   if(frame->getChannel() != phy->getCurrentRadioChannel()) {
00047     // we cannot synchronize on a frame on another channel.
00048     return notAgain;
00049   }
00050 
00051   currentSignal.first = frame;
00052   currentSignal.second = EXPECT_HEADER;
00053   Signal& s = frame->getSignal();
00054   double bitrate = s.getBitrate()->getValue(Argument(s.getSignalStart()));
00055   simtime_t phyHeaderDuration = ((double) phyHeaderLength)/bitrate;
00056   return s.getSignalStart() + phyHeaderDuration;
00057 
00058 }
00059 
00060 simtime_t Decider802154Narrow::processSignalHeader(AirFrame* frame)
00061 {
00062   if (!syncOnSFD(frame)) {
00063     currentSignal.first = 0;
00064     //channel is back idle
00065     setChannelIdleStatus(true);
00066     return notAgain;
00067   }
00068 
00069   // store this frame as signal to receive and set state
00070 //  currentSignal.first = frame;
00071   currentSignal.second = EXPECT_END;
00072 
00073   //channel is busy now
00074   setChannelIdleStatus(false);
00075 
00076   //TODO: publish rssi and channel state
00077   // Inform the MAC that we started receiving a frame
00078   phy->sendControlMsg(new cMessage("start_rx",RECEPTION_STARTED));
00079   Signal& s = frame->getSignal();
00080   return s.getSignalStart() + s.getSignalLength();
00081 }
00082 
00083 simtime_t Decider802154Narrow::processSignalEnd(AirFrame* frame)
00084 {
00085   ConstMapping* snrMapping = calculateSnrMapping(frame);
00086 
00087   Signal& s = frame->getSignal();
00088   simtime_t start = s.getSignalStart();
00089   simtime_t end = start + s.getSignalLength();
00090 
00091   AirFrameVector channel;
00092   phy->getChannelInfo(start, end, channel);
00093   bool hasInterference = channel.size() > 1;
00094 
00095   if(hasInterference) {
00096     nbFramesWithInterference++;
00097   } else {
00098     nbFramesWithoutInterference++;
00099   }
00100 
00101   double bitrate = s.getBitrate()->getValue(Argument(start));
00102 
00103   double avgBER = 0;
00104   double bestBER = 0.5;
00105   double snirAvg = 0;
00106   bool noErrors = true;
00107   double ber;
00108   double errorProbability;
00109 
00110   simtime_t receivingStart = MappingUtils::post(start);
00111   Argument argStart(receivingStart);
00112   ConstMappingIterator* iter = snrMapping->createConstIterator(argStart);
00113   double snirMin = iter->getValue();
00114   // Evaluate bit errors for each snr value
00115   // and stops as soon as we have an error.
00116   // TODO: add error correction code.
00117 
00118   simtime_t curTime = iter->getPosition().getTime();
00119   simtime_t snrDuration;
00120   while(curTime < end) {
00121     //get SNR for this interval
00122     double snr = iter->getValue();
00123 
00124     //determine end of this interval
00125     simtime_t nextTime = end; //either the end of the signal...
00126     if(iter->hasNext()) {   //or the position of the next entry
00127       const Argument& argNext = iter->getNextPosition();
00128       nextTime = std::min(argNext.getTime(), nextTime);
00129       iter->next(); //the iterator will already point to the next entry
00130     }
00131 
00132     if (noErrors) {
00133       snrDuration = nextTime - curTime;
00134 
00135       int nbBits = int (snrDuration.dbl() * bitrate);
00136 
00137       // non-coherent detection of m-ary orthogonal signals in an AWGN
00138       // Channel
00139       // Digital Communications, John G. Proakis, section 4.3.2
00140       // p. 212, (4.3.32)
00141       //  Pm = sum(n=1,n=M-1){(-1)^(n+1)choose(M-1,n) 1/(n+1) exp(-nkgamma/(n+1))}
00142       // Pb = 2^(k-1)/(2^k - 1) Pm
00143 
00144 
00145       ber = std::max(getBERFromSNR(snr), BER_LOWER_BOUND);
00146       avgBER = ber*nbBits;
00147       snirAvg = snirAvg + snr*snrDuration.dbl();
00148 
00149       if(ber < bestBER) {
00150         bestBER = ber;
00151       }
00152       errorProbability = 1.0 - pow((1.0 - ber), nbBits);
00153       noErrors = errorProbability < uniform(0, 1);
00154     }
00155     if (snr < snirMin)
00156       snirMin = snr;
00157 
00158     curTime = nextTime;
00159   }
00160   delete iter;
00161   delete snrMapping;
00162 
00163   avgBER = avgBER / frame->getBitLength();
00164   snirAvg = snirAvg / (end - start);
00165   //double rssi = 10*log10(snirAvg);
00166   double rssi = calcChannelSenseRSSI(start, end);
00167   if (noErrors)
00168   {
00169     phy->sendUp(frame,
00170           new DeciderResult802154Narrow(true, bitrate, snirMin, avgBER, rssi));
00171     if(recordStats) {
00172       snirReceived.record(10*log10(snirMin));  // in dB
00173     }
00174   } else {
00175     MacPkt* mac = static_cast<MacPkt*> (frame->decapsulate());
00176     mac->setName("BIT_ERRORS");
00177     mac->setKind(PACKET_DROPPED);
00178 
00179     DeciderResult802154Narrow* result =
00180       new DeciderResult802154Narrow(false, bitrate, snirMin, avgBER, rssi);
00181     PhyToMacControlInfo* cInfo = new PhyToMacControlInfo(result);
00182     mac->setControlInfo(cInfo);
00183     phy->sendControlMsg(mac);
00184     if(recordStats) {
00185       snirDropped.record(10*log10(snirMin));  // in dB
00186     }
00187     if(hasInterference) {
00188       nbFramesWithInterferenceDropped++;
00189     } else {
00190       nbFramesWithoutInterferenceDropped++;
00191     }
00192   }
00193 
00194   //decoding is done
00195   currentSignal.first = 0;
00196 
00197   //channel is back idle
00198   setChannelIdleStatus(true);
00199 
00200   //TODO: publish rssi and channel state
00201   return notAgain;
00202 }
00203 
00204 double Decider802154Narrow::n_choose_k(int n, int k) {
00205   double res = 1;
00206   for(int i = 1; i <= k; i++) {
00207     res = res * (n-k+i) / i;
00208   }
00209   return res;
00210 }
00211 
00212 double Decider802154Narrow::getBERFromSNR(double snr) {
00213   double ber = BER_LOWER_BOUND;
00214   double sum_k = 0;
00215   if(modulation == "msk") {
00216     // valid for IEEE 802.15.4 868 MHz BPSK modulation
00217     ber = 0.5 *  erfc(sqrt(snr));
00218   } else if (modulation == "oqpsk16") {
00219     // valid for IEEE 802.15.4 2.45 GHz OQPSK modulation
00220     for (int k = 2; k <= 16; k++) {
00221       sum_k = sum_k + pow(-1.0, k) * n_choose_k(16, k) * exp(20 * snr * (1.0 / k - 1.0));
00222     }
00223     ber = (8.0 / 15) * (1.0 / 16) * sum_k;
00224   } else if(modulation == "gfsk") {
00225     // valid for Bluetooth 4.0 PHY mandatory base rate 1 Mbps
00226     // Please note that this is not the correct expression for
00227     // the enhanced data rates (EDR), which uses another modulation.
00228     ber = 0.5 * erfc(sqrt(0.5 * snr));
00229   } else {
00230     opp_error("The selected modulation is not supported.");
00231   }
00232   if(recordStats) {
00233     berlog.record(ber);
00234     snrlog.record(10*log10(snr));
00235   }
00236   return std::max(ber, BER_LOWER_BOUND);
00237 }
00238 
00239 void Decider802154Narrow::channelChanged(int newChannel) {
00240   //TODO: stop receiving
00241   ;
00242 }
00243 
00244 void Decider802154Narrow::finish() {
00245 
00246   // record scalars through the interface to the PHY-Layer
00247   phy->recordScalar("nbFramesWithInterference", nbFramesWithInterference);
00248   phy->recordScalar("nbFramesWithoutInterference", nbFramesWithoutInterference);
00249   phy->recordScalar("nbFramesWithInterferenceDropped", nbFramesWithInterferenceDropped);
00250   phy->recordScalar("nbFramesWithoutInterferenceDropped", nbFramesWithoutInterferenceDropped);
00251 }