00001
00002
00003
00004
00005
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);
00038 }
00039
00040 simtime_t Decider802154Narrow::processNewSignal(AirFrame* frame) {
00041
00042 if(currentSignal.first != 0) {
00043 return notAgain;
00044 }
00045
00046 if(frame->getChannel() != phy->getCurrentRadioChannel()) {
00047
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
00065 setChannelIdleStatus(true);
00066 return notAgain;
00067 }
00068
00069
00070
00071 currentSignal.second = EXPECT_END;
00072
00073
00074 setChannelIdleStatus(false);
00075
00076
00077
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
00115
00116
00117
00118 simtime_t curTime = iter->getPosition().getTime();
00119 simtime_t snrDuration;
00120 while(curTime < end) {
00121
00122 double snr = iter->getValue();
00123
00124
00125 simtime_t nextTime = end;
00126 if(iter->hasNext()) {
00127 const Argument& argNext = iter->getNextPosition();
00128 nextTime = std::min(argNext.getTime(), nextTime);
00129 iter->next();
00130 }
00131
00132 if (noErrors) {
00133 snrDuration = nextTime - curTime;
00134
00135 int nbBits = int (snrDuration.dbl() * bitrate);
00136
00137
00138
00139
00140
00141
00142
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
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));
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));
00186 }
00187 if(hasInterference) {
00188 nbFramesWithInterferenceDropped++;
00189 } else {
00190 nbFramesWithoutInterferenceDropped++;
00191 }
00192 }
00193
00194
00195 currentSignal.first = 0;
00196
00197
00198 setChannelIdleStatus(true);
00199
00200
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
00217 ber = 0.5 * erfc(sqrt(snr));
00218 } else if (modulation == "oqpsk16") {
00219
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
00226
00227
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
00241 ;
00242 }
00243
00244 void Decider802154Narrow::finish() {
00245
00246
00247 phy->recordScalar("nbFramesWithInterference", nbFramesWithInterference);
00248 phy->recordScalar("nbFramesWithoutInterference", nbFramesWithoutInterference);
00249 phy->recordScalar("nbFramesWithInterferenceDropped", nbFramesWithInterferenceDropped);
00250 phy->recordScalar("nbFramesWithoutInterferenceDropped", nbFramesWithoutInterferenceDropped);
00251 }