|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2006 Andras Varga 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 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 General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 00020 #include "GenericRadioModel.h" 00021 #include "Modulation.h" 00022 #include "FWMath.h" 00023 00024 00025 Register_Class(GenericRadioModel); 00026 00027 GenericRadioModel::GenericRadioModel() 00028 { 00029 modulation = NULL; 00030 } 00031 00032 GenericRadioModel::~GenericRadioModel() 00033 { 00034 delete modulation; 00035 } 00036 00037 void GenericRadioModel::initializeFrom(cModule *radioModule) 00038 { 00039 snirThreshold = dB2fraction(radioModule->par("snirThreshold")); 00040 headerLengthBits = radioModule->par("headerLengthBits"); 00041 bandwidth = radioModule->par("bandwidth"); 00042 00043 const char *modulationName = radioModule->par("modulation"); 00044 if (strcmp(modulationName, "null")==0) 00045 modulation = new NullModulation(); 00046 else if (strcmp(modulationName, "BPSK")==0) 00047 modulation = new BPSKModulation(); 00048 else if (strcmp(modulationName, "16-QAM")==0) 00049 modulation = new QAM16Modulation(); 00050 else if (strcmp(modulationName, "256-QAM")==0) 00051 modulation = new QAM256Modulation(); 00052 else 00053 opp_error("unrecognized modulation '%s'", modulationName); 00054 } 00055 00056 00057 double GenericRadioModel::calculateDuration(AirFrame *airframe) 00058 { 00059 return (airframe->getBitLength()+headerLengthBits) / airframe->getBitrate(); 00060 } 00061 00062 00063 bool GenericRadioModel::isReceivedCorrectly(AirFrame *airframe, const SnrList& receivedList) 00064 { 00065 // calculate snirMin 00066 double snirMin = receivedList.begin()->snr; 00067 for (SnrList::const_iterator iter = receivedList.begin(); iter != receivedList.end(); iter++) 00068 if (iter->snr < snirMin) 00069 snirMin = iter->snr; 00070 00071 if (snirMin <= snirThreshold) 00072 { 00073 // if snir is too low for the packet to be recognized 00074 EV << "COLLISION! Packet got lost\n"; 00075 return false; 00076 } 00077 else if (isPacketOK(snirMin, airframe->getBitLength()+headerLengthBits, airframe->getBitrate())) 00078 { 00079 EV << "packet was received correctly, it is now handed to upper layer...\n"; 00080 return true; 00081 } 00082 else 00083 { 00084 EV << "Packet has BIT ERRORS! It is lost!\n"; 00085 return false; 00086 } 00087 } 00088 00089 00090 bool GenericRadioModel::isPacketOK(double snirMin, int length, double bitrate) 00091 { 00092 double ber = modulation->calculateBER(snirMin, bandwidth, bitrate); 00093 00094 if (ber==0.0) 00095 return true; 00096 00097 double probNoError = pow(1.0 - ber, length); // probability of no bit error 00098 00099 if (dblrand() > probNoError) 00100 return false; // error in MPDU 00101 else 00102 return true; // no error 00103 } 00104 00105 double GenericRadioModel::dB2fraction(double dB) 00106 { 00107 return pow(10.0, (dB / 10)); 00108 } 00109 00110