INET Framework for OMNeT++/OMNEST
Ieee80211RadioModel.cc
Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Andras Varga, Levente Meszaros
00003 // Based on the Mobility Framework's SnrEval by Marc Loebbers
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00017 //
00018 
00019 
00020 #include "Ieee80211RadioModel.h"
00021 #include "Ieee80211Consts.h"
00022 #include "FWMath.h"
00023 
00024 
00025 Register_Class(Ieee80211RadioModel);
00026 
00027 
00028 void Ieee80211RadioModel::initializeFrom(cModule *radioModule)
00029 {
00030     snirThreshold = dB2fraction(radioModule->par("snirThreshold"));
00031 }
00032 
00033 double Ieee80211RadioModel::calculateDuration(AirFrame *airframe)
00034 {
00035     // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate
00036     return airframe->getBitLength()/airframe->getBitrate() + PHY_HEADER_LENGTH/BITRATE_HEADER;
00037 }
00038 
00039 
00040 bool Ieee80211RadioModel::isReceivedCorrectly(AirFrame *airframe, const SnrList& receivedList)
00041 {
00042     // calculate snirMin
00043     double snirMin = receivedList.begin()->snr;
00044     for (SnrList::const_iterator iter = receivedList.begin(); iter != receivedList.end(); iter++)
00045         if (iter->snr < snirMin)
00046             snirMin = iter->snr;
00047 
00048     cPacket *frame = airframe->getEncapsulatedPacket();
00049     EV << "packet (" << frame->getClassName() << ")" << frame->getName() << " (" << frame->info() << ") snrMin=" << snirMin << endl;
00050 
00051     if (snirMin <= snirThreshold)
00052     {
00053         // if snir is too low for the packet to be recognized
00054         EV << "COLLISION! Packet got lost\n";
00055         return false;
00056     }
00057     else if (isPacketOK(snirMin, airframe->getEncapsulatedPacket()->getBitLength(), airframe->getBitrate()))
00058     {
00059         EV << "packet was received correctly, it is now handed to upper layer...\n";
00060         return true;
00061     }
00062     else
00063     {
00064         EV << "Packet has BIT ERRORS! It is lost!\n";
00065         return false;
00066     }
00067 }
00068 
00069 
00070 bool Ieee80211RadioModel::isPacketOK(double snirMin, int lengthMPDU, double bitrate)
00071 {
00072     double berHeader, berMPDU;
00073 
00074     berHeader = 0.5 * exp(-snirMin * BANDWIDTH / BITRATE_HEADER);
00075 
00076     // if PSK modulation
00077     if (bitrate == 1E+6 || bitrate == 2E+6)
00078         berMPDU = 0.5 * exp(-snirMin * BANDWIDTH / bitrate);
00079     // if CCK modulation (modeled with 16-QAM)
00080     else if (bitrate == 5.5E+6)
00081         berMPDU = 0.5 * (1 - 1 / sqrt(pow(2.0, 4))) * erfc(snirMin * BANDWIDTH / bitrate);
00082     else                        // CCK, modelled with 256-QAM
00083         berMPDU = 0.25 * (1 - 1 / sqrt(pow(2.0, 8))) * erfc(snirMin * BANDWIDTH / bitrate);
00084 
00085     // probability of no bit error in the PLCP header
00086     double headerNoError = pow(1.0 - berHeader, HEADER_WITHOUT_PREAMBLE);
00087 
00088     // probability of no bit error in the MPDU
00089     double MpduNoError = pow(1.0 - berMPDU, lengthMPDU);
00090     EV << "berHeader: " << berHeader << " berMPDU: " << berMPDU << endl;
00091     double rand = dblrand();
00092 
00093     if (rand > headerNoError)
00094         return false; // error in header
00095     else if (dblrand() > MpduNoError)
00096         return false;  // error in MPDU
00097     else
00098         return true; // no error
00099 }
00100 
00101 double Ieee80211RadioModel::dB2fraction(double dB)
00102 {
00103     return pow(10.0, (dB / 10));
00104 }
00105 
00106