|
INET Framework for OMNeT++/OMNEST
|
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