INET Framework for OMNeT++/OMNEST
Decider80211.cc
Go to the documentation of this file.
00001 /***************************************************************************
00002  * file:        Decider80211.cc
00003  *
00004  * authors:     David Raguin / Marc Loebbers
00005  *
00006  * copyright:   (C) 2004 Telecommunication Networks Group (TKN) at
00007  *              Technische Universitaet Berlin, Germany.
00008  *
00009  *              This program is free software; you can redistribute it
00010  *              and/or modify it under the terms of the GNU General Public
00011  *              License as published by the Free Software Foundation; either
00012  *              version 2 of the License, or (at your option) any later
00013  *              version.
00014  *              For further information see file COPYING
00015  *              in the top level directory
00016  ***************************************************************************
00017  * part of:     framework implementation developed by tkn
00018  ***************************************************************************/
00019 
00020 
00021 #include "Decider80211.h"
00022 #include "Consts80211.h"
00023 
00024 
00025 Define_Module(Decider80211);
00026 
00034 void Decider80211::initialize(int stage)
00035 {
00036     BasicDecider::initialize(stage);
00037 
00038     if (stage == 0)
00039     {
00040         EV << "initializing stage 0\n";
00041         bitrate = par("bitrate");
00042         if (bitrate != 1E+6 && bitrate != 2E+6 && bitrate != 5.5E+6 && bitrate != 11E+6)
00043             error("Wrong bitrate!! Please chose 1E+6, 2E+6, 5.5E+6 or 11E+6 as bitrate!!");
00044         snirThreshold = dB2fraction(par("snirThreshold"));
00045     }
00046 }
00047 
00048 
00056 void Decider80211::handleLowerMsg(AirFrame *af, SnrList& receivedList)
00057 {
00058 
00059     double snirMin;
00060 
00061     //initialize snirMin:
00062     snirMin = receivedList.begin()->snr;
00063 
00064     for (SnrList::iterator iter = receivedList.begin(); iter != receivedList.end(); iter++)
00065     {
00066         if (iter->snr < snirMin)
00067             snirMin = iter->snr;
00068     }
00069     cMessage *fr = af->getEncapsulatedPacket();
00070     EV << "packet (" << fr->getClassName() << ")" << fr->getName() << " (" << fr->info() << ") snrMin=" << snirMin << endl;
00071 
00072     //if snir is big enough so that packet can be recognized at all
00073     if (snirMin > snirThreshold)
00074     {
00075         if (isPacketOK(snirMin, af->getEncapsulatedPacket()->getBitLength()))
00076         {
00077             EV << "packet was received correctly, it is now handed to upper layer...\n";
00078             sendUp(af);
00079         }
00080         else
00081         {
00082             EV << "Packet has BIT ERRORS! It is lost!\n";
00083             af->setName("ERROR");
00084             af->getEncapsulatedPacket()->setKind(BITERROR);
00085             sendUp(af);
00086         }
00087     }
00088     else
00089     {
00090         EV << "COLLISION! Packet got lost\n";
00091         af->setName("COLLISION");
00092         af->getEncapsulatedPacket()->setKind(COLLISION);
00093         sendUp(af);
00094     }
00095 }
00096 
00097 
00098 bool Decider80211::isPacketOK(double snirMin, int lengthMPDU)
00099 {
00100     double berHeader, berMPDU;
00101 
00102     berHeader = 0.5 * exp(-snirMin * BANDWIDTH / BITRATE_HEADER);
00103     //if PSK modulation
00104     if (bitrate == 1E+6 || bitrate == 2E+6)
00105         berMPDU = 0.5 * exp(-snirMin * BANDWIDTH / bitrate);
00106     //if CCK modulation (modeled with 16-QAM)
00107     else if (bitrate == 5.5E+6)
00108         berMPDU = 0.5 * (1 - 1 / sqrt(pow(2.0, 4))) * erfc(snirMin * BANDWIDTH / bitrate);
00109     else                        // CCK, modelled with 256-QAM
00110         berMPDU = 0.25 * (1 - 1 / sqrt(pow(2.0, 8))) * erfc(snirMin * BANDWIDTH / bitrate);
00111     //probability of no bit error in the PLCP header
00112     double headerNoError = pow(1.0 - berHeader, HEADER_WITHOUT_PREAMBLE);
00113 
00114     //probability of no bit error in the MPDU
00115     double MpduNoError = pow(1.0 - berMPDU, lengthMPDU);
00116     EV << "berHeader: " << berHeader << " berMPDU: " << berMPDU << endl;
00117     double rand = dblrand();
00118 
00119     //if error in header
00120     if (rand > headerNoError)
00121         return (false);
00122     else
00123     {
00124         rand = dblrand();
00125 
00126         //if error in MPDU
00127         if (rand > MpduNoError)
00128             return (false);
00129         //if no error
00130         else
00131             return (true);
00132     }
00133 }
00134 
00135 double Decider80211::dB2fraction(double dB)
00136 {
00137     return pow(10.0, (dB / 10));
00138 }