![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WiFiMac * 00003 * This file is part of openWNS (open Wireless Network Simulator) 00004 * _____________________________________________________________________________ 00005 * 00006 * Copyright (C) 2004-2007 00007 * Chair of Communication Networks (ComNets) 00008 * Kopernikusstr. 16, D-52074 Aachen, Germany 00009 * phone: ++49-241-80-27910, 00010 * fax: ++49-241-80-22242 00011 * email: info@openwns.org 00012 * www: http://www.openwns.org 00013 * _____________________________________________________________________________ 00014 * 00015 * openWNS is free software; you can redistribute it and/or modify it under the 00016 * terms of the GNU Lesser General Public License version 2 as published by the 00017 * Free Software Foundation; 00018 * 00019 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00021 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00022 * details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public License 00025 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00026 * 00027 ******************************************************************************/ 00028 00029 #include <WIFIMAC/convergence/PhyMode.hpp> 00030 00031 #include <WNS/Assure.hpp> 00032 #include <WNS/Exception.hpp> 00033 00034 using namespace wifimac::convergence; 00035 00036 MCS::MCS(): 00037 modulation("ERROR"), 00038 codingRate("ERROR"), 00039 minSINR(), 00040 index(0), 00041 nominator(0), 00042 denominator(1) 00043 {} 00044 00045 MCS::MCS(const MCS& other): 00046 modulation(other.modulation), 00047 codingRate(other.codingRate), 00048 nominator(other.nominator), 00049 denominator(other.denominator), 00050 index(other.index), 00051 minSINR(other.minSINR) 00052 {} 00053 00054 MCS::MCS(const wns::pyconfig::View& config) : 00055 modulation(config.get<std::string>("modulation")), 00056 codingRate(config.get<std::string>("codingRate")), 00057 minSINR(config.get<wns::Ratio>("minSINR")), 00058 index(0), 00059 nominator(1), 00060 denominator(1) 00061 { 00062 this->setMCS(modulation, codingRate); 00063 } 00064 00065 MCS::MCS(const wifimac::management::protocolCalculatorPlugins::ConfigGetter& config): 00066 modulation(config.get<char*>("modulation", "s")), 00067 codingRate(config.get<char*>("codingRate", "s")), 00068 minSINR(wns::Ratio::from_dB(0.0)), 00069 index(0), 00070 nominator(1), 00071 denominator(1) 00072 { 00073 std::istringstream os(config.get<char*>("minSINR", "s")); 00074 os >> minSINR; 00075 00076 this->setMCS(modulation, codingRate); 00077 } 00078 00079 std::string MCS::getModulation() const 00080 { 00081 return this->modulation; 00082 } 00083 00084 std::string MCS::getRate() const 00085 { 00086 return this->codingRate; 00087 } 00088 00089 void MCS::setMCS(const std::string& newModulation, const std::string& newCodingRate) 00090 { 00091 assure(newModulation == "BPSK" or 00092 newModulation == "QPSK" or 00093 newModulation == "QAM16" or 00094 newModulation == "QAM64", 00095 "Unknown new modulation" << newModulation); 00096 assure(newCodingRate == "1/2" or 00097 newCodingRate == "2/3" or 00098 newCodingRate == "3/4" or 00099 newCodingRate == "5/6", 00100 "Unknown new coding rate" << newCodingRate); 00101 00102 codingRate = newCodingRate; 00103 modulation = newModulation; 00104 00105 if(modulation == "BSPK") 00106 { 00107 nominator = 1; 00108 } 00109 else if(modulation == "QPSK") 00110 { 00111 nominator = 2; 00112 } 00113 else if(modulation == "QAM16") 00114 { 00115 nominator = 4; 00116 } 00117 else if(modulation == "QAM64") 00118 { 00119 nominator = 6; 00120 } 00121 00122 if(codingRate == "1/2") 00123 { 00124 denominator = 2; 00125 } 00126 else if(codingRate == "2/3") 00127 { 00128 nominator *= 2; 00129 denominator = 3; 00130 } 00131 else if(codingRate == "3/4") 00132 { 00133 nominator *= 3; 00134 denominator = 4; 00135 } 00136 else if(codingRate == "5/6") 00137 { 00138 nominator *= 5; 00139 denominator = 6; 00140 } 00141 } 00142 00143 00144 bool MCS::operator <(const MCS& rhs) const 00145 { 00146 return(minSINR < rhs.minSINR); 00147 } 00148 00149 bool MCS::operator ==(const MCS& rhs) const 00150 { 00151 return(minSINR == rhs.minSINR and 00152 nominator == rhs.nominator and 00153 denominator == rhs.denominator); 00154 } 00155 00156 bool MCS::operator !=(const MCS& rhs) const 00157 { 00158 return(minSINR != rhs.minSINR or 00159 nominator != rhs.nominator or 00160 denominator != rhs.denominator); 00161 } 00162 00163 PhyMode::PhyMode(): 00164 spatialStreams(), 00165 numberOfDataSubcarriers(0), 00166 plcpMode("ERROR"), 00167 guardIntervalDuration(0) 00168 {} 00169 00170 PhyMode::PhyMode(const wns::pyconfig::View& config) : 00171 spatialStreams(), 00172 numberOfDataSubcarriers(config.get<unsigned int>("numberOfDataSubcarriers")), 00173 plcpMode(config.get<std::string>("plcpMode")), 00174 guardIntervalDuration(config.get<wns::simulator::Time>("guardIntervalDuration")) 00175 { 00176 assure(config.get<int>("len(spatialStreams)") > 0, 00177 "cannot have less than 1 spatial stream"); 00178 assure(plcpMode == "Basic" or plcpMode == "HT-Mix" or plcpMode == "HT-GF", 00179 "Unknown plcpMode"); 00180 assure(guardIntervalDuration == 0.8e-6 or guardIntervalDuration == 0.4e-6, 00181 "Unknown guard interval"); 00182 assure(numberOfDataSubcarriers > 0, 00183 "cannot have less than 1 data subcarriers"); 00184 00185 for (int i = 0; i < config.get<int>("len(spatialStreams)"); ++i) 00186 { 00187 std::string s = "spatialStreams[" + wns::Ttos(i) + "]"; 00188 spatialStreams.push_back(MCS(config.get(s))); 00189 } 00190 } 00191 00192 PhyMode::PhyMode(const wifimac::management::protocolCalculatorPlugins::ConfigGetter& config) : 00193 spatialStreams(), 00194 numberOfDataSubcarriers(config.get<unsigned int>("numberOfDataSubcarriers", "I")), 00195 plcpMode(config.get<char*>("plcpMode", "s")), 00196 guardIntervalDuration(config.get<wns::simulator::Time>("guardIntervalDuration", "d")) 00197 { 00198 assure(config.length("spatialStreams") > 0, 00199 "cannot have less than 1 spatial stream"); 00200 assure(plcpMode == "Basic" or plcpMode == "HT-Mix" or plcpMode == "HT-GF", 00201 "Unknown plcpMode"); 00202 assure(guardIntervalDuration == 0.8e-6 or guardIntervalDuration == 0.4e-6, 00203 "Unknown guard interval"); 00204 assure(numberOfDataSubcarriers > 0, 00205 "cannot have less than 1 data subcarriers"); 00206 00207 int len = config.length("spatialStreams"); 00208 for (int i = 0; i < len; ++i) 00209 { 00210 MCS m(config.get("spatialStreams", i)); 00211 spatialStreams.push_back(m); 00212 } 00213 } 00214 00215 Bit PhyMode::getDataBitsPerSymbol() const 00216 { 00217 unsigned int dbps = 0; 00218 if((spatialStreams.size() == 0) or (numberOfDataSubcarriers == 0)) 00219 { 00220 return 0; 00221 } 00222 00223 for (std::vector<MCS>::const_iterator it = spatialStreams.begin(); 00224 it != spatialStreams.end(); 00225 ++it) 00226 { 00227 dbps += (numberOfDataSubcarriers * it->nominator / it->denominator); 00228 } 00229 return(dbps); 00230 } 00231 00232 void PhyMode::setUniformMCS(const MCS& mcs, unsigned int numSS) 00233 { 00234 this->spatialStreams.assign(numSS, mcs); 00235 } 00236 00237 void PhyMode::setSpatialStreams(const std::vector<MCS>& ss) 00238 { 00239 assure(ss.size() > 0, "ERROR: No spatial streams"); 00240 00241 this->spatialStreams.clear(); 00242 for(std::vector<MCS>::const_iterator it = ss.begin(); 00243 it != ss.end(); 00244 ++it) 00245 { 00246 this->spatialStreams.push_back(*it); 00247 } 00248 } 00249 00250 bool PhyMode::operator <(const PhyMode& rhs) const 00251 { 00252 return(this->getDataBitsPerSymbol() < rhs.getDataBitsPerSymbol()); 00253 } 00254 00255 bool PhyMode::operator ==(const PhyMode& rhs) const 00256 { 00257 assure(spatialStreams.size() > 0, "number of spatial streams not set in lhs"); 00258 assure(numberOfDataSubcarriers > 0, "number of DataSubcarriers not set in lhs"); 00259 assure(plcpMode != "ERROR", "plcpMode not set in lhs"); 00260 00261 assure(rhs.spatialStreams.size() > 0, "number of spatial streams not set in rhs"); 00262 assure(rhs.numberOfDataSubcarriers > 0, "number of DataSubcarriers not set in rhs"); 00263 assure(rhs.plcpMode != "ERROR", "plcpMode not set in rhs"); 00264 00265 if(spatialStreams.size() != rhs.spatialStreams.size()) 00266 { 00267 return false; 00268 } 00269 00270 std::vector<MCS>::const_iterator it = spatialStreams.begin(); 00271 std::vector<MCS>::const_iterator itRHS = rhs.spatialStreams.begin(); 00272 for(; 00273 (it != spatialStreams.end()) and (itRHS != rhs.spatialStreams.end()); 00274 ++it, ++itRHS) 00275 { 00276 if((*it) != (*itRHS)) 00277 { 00278 return false; 00279 } 00280 } 00281 return((numberOfDataSubcarriers == rhs.numberOfDataSubcarriers) and 00282 (plcpMode == rhs.plcpMode)); 00283 } 00284 00285 bool PhyMode::operator !=(const PhyMode& rhs) const 00286 { 00287 return(not this->operator==(rhs)); 00288 }
1.5.5