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