EMANE  1.2.1
fadingmanager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "fadingmanager.h"
35 
37  PlatformServiceProvider * pPlatformService,
38  const std::string & sPrefix):
39  id_{id},
40  pPlatformService_{pPlatformService},
41  sPrefix_{sPrefix},
42  bFading_{},
43  pFadingAlgorithmForAll_{}
44 {
45  fadingModels_.insert(std::make_pair("nakagami",
46  std::unique_ptr<FadingAlgorithm>(new NakagamiFadingAlgorithm{id,
47  pPlatformService,
48  sPrefix})));
49 }
50 
52 {
53  auto & configRegistrar = registrar.configurationRegistrar();
54 
55  std::string sModelDescription{"Defines the fading model:"
56  " none, event"};
57 
58  std::string sModelsRegex{"^(none|event"};
59 
60  for(const auto & entry : fadingModels_)
61  {
62  sModelsRegex += "|" + entry.second->name();
63  sModelDescription += ", " + entry.second->name();
64  }
65 
66  sModelsRegex += ")$";
67  sModelDescription += ".";
68 
69  configRegistrar.registerNonNumeric<std::string>(sPrefix_ + "model",
72  {"none"},
73  sModelDescription,
74  1,
75  1,
76  sModelsRegex);
77 
78  for(const auto & entry : fadingModels_)
79  {
80  entry.second->initialize(registrar);
81  }
82 
83 }
84 
86 {
87  configure_i(update,
89 }
90 
92 {
93  configure_i(update,
95 }
96 
97 void EMANE::FadingManager::configure_i(const ConfigurationUpdate & update,
98  void (FadingAlgorithm::*process)(const ConfigurationUpdate&))
99 {
100  std::map<std::string,std::tuple<ConfigurationUpdate,FadingAlgorithm*>> configurations{};
101 
102  for(const auto & entry : fadingModels_)
103  {
104  std::string sConfigName{sPrefix_ + entry.second->name() + "."};
105  configurations.insert(std::make_pair(sConfigName,
106  std::make_tuple(ConfigurationUpdate{},
107  entry.second.get())));
108  }
109 
110  for(const auto & item : update)
111  {
112  if(item.first == sPrefix_ + "model")
113  {
114  std::string sType{item.second[0].asString()};
115 
116  LOGGER_STANDARD_LOGGING(pPlatformService_->logService(),
117  INFO_LEVEL,
118  "PHYI %03hu FrameworkPHY::FadingManager::%s: %s = %s",
119  id_,
120  __func__,
121  item.first.c_str(),
122  sType.c_str());
123 
124  if(sType == "none")
125  {
126  bFading_ = false;
127  }
128  else if(sType == "event")
129  {
130  bFading_ = true;
131  pFadingAlgorithmForAll_ = nullptr;
132  }
133  else
134  {
135  bFading_ = true;
136  auto iter = fadingModels_.find(sType);
137 
138  if(iter != fadingModels_.end())
139  {
140  pFadingAlgorithmForAll_ = iter->second.get();
141  }
142  }
143  }
144  else
145  {
146  auto pos1 = std::string::npos;
147  auto pos2 = std::string::npos;
148 
149  pos1 = item.first.find_first_of('.');
150 
151  if(pos1 != std::string::npos)
152  {
153  pos2 = item.first.find_first_of('.',pos1+1);
154 
155  if(pos2 != std::string::npos)
156  {
157  std::string sKey{item.first.substr(0,pos2+1)};
158 
159  auto iter = configurations.find(sKey);
160 
161  if(iter != configurations.end())
162  {
163  std::get<0>(iter->second).push_back(item);
164  }
165  }
166  }
167 
168  if(pos1 == std::string::npos || pos2 == std::string::npos)
169  {
170  throw makeException<ConfigurationException>("FrameworkPHY::FadingManager Unexpected"
171  " configuration item %s",
172  item.first.c_str());
173  }
174  }
175  }
176 
177  for(const auto & entry : configurations)
178  {
179  //std::get<1>(entry.second)->configure(std::get<0>(entry.second));
180  (std::get<1>(entry.second)->*process)(std::get<0>(entry.second));
181 
182  }
183 }
184 
185 std::pair<double,EMANE::FadingManager::FadingStatus>
187  double dPowerdBm,
188  const std::pair<LocationInfo,bool> & location)
189 {
190 
191  double dOutPowerdBm{};
193 
194  if(!bFading_)
195  {
196  dOutPowerdBm = dPowerdBm;
197  status = FadingStatus::SUCCESS;
198  }
199  else if(pFadingAlgorithmForAll_)
200  {
201  // only calculate if lcoation is known
202  if(location.second)
203  {
204  dOutPowerdBm = (*pFadingAlgorithmForAll_)(dPowerdBm,
205  location.first.getDistanceMeters());
206  status = FadingStatus::SUCCESS;
207  }
208  }
209  else
210  {
211  auto iter = TxNEMFadingSelections_.find(txNEMId);
212 
213  if(iter != TxNEMFadingSelections_.end())
214  {
215  if(iter->second)
216  {
217  // only calculate if location is known
218  if(location.second)
219  {
220  dOutPowerdBm = (*iter->second)(dPowerdBm,
221  location.first.getDistanceMeters());
222 
223  status = FadingStatus::SUCCESS;
224  }
225  }
226  else
227  {
228  // null algorithm indicates no fading in use from src
229  dOutPowerdBm = dPowerdBm;
230 
231  status = FadingStatus::SUCCESS;
232  }
233  }
234  else
235  {
236  // unknown fading algorithm selection for source
238  }
239  }
240 
241  return {dOutPowerdBm,status};
242 }
243 
245 {
246  for(const auto & selection : fadingSelections)
247  {
248  switch(selection.getFadingModel())
249  {
251  TxNEMFadingSelections_[selection.getNEMId()] = nullptr;
252  break;
254  TxNEMFadingSelections_[selection.getNEMId()] = fadingModels_["nakagami"].get();
255  break;
256  default:
257  LOGGER_STANDARD_LOGGING(pPlatformService_->logService(),
258  ERROR_LEVEL,
259  "PHYI %03hu FadingManager::%s: unknown fading model"
260  " selection for NEM %hu",
261  id_,
262  __func__,
263  selection.getNEMId());
264  break;
265  }
266  }
267 }
The Registrar interface provides access to all of the emulator registrars.
Definition: registrar.h:50
virtual ConfigurationRegistrar & configurationRegistrar()=0
void registerNonNumeric(const std::string &sName, const ConfigurationProperties &properties=ConfigurationProperties::NONE, const std::initializer_list< T > &values={}, const std::string &sUsage="", std::size_t minOccurs=1, std::size_t maxOccurs=1, const std::string &sRegexPattern={})
void initialize(Registrar &registrar)
The PlatformServiceProvider interface provides access to emulator services.
virtual void configure(const ConfigurationUpdate &update)=0
void update(const Events::FadingSelections &fadingSelections)
std::uint16_t NEMId
Definition: types.h:52
void configure(const ConfigurationUpdate &update)
std::pair< double, FadingStatus > calculate(NEMId txNEMId, double dPowerdBm, const std::pair< LocationInfo, bool > &location)
virtual LogServiceProvider & logService()=0
std::vector< ConfigurationNameAnyValues > ConfigurationUpdate
FadingManager(NEMId id, PlatformServiceProvider *pPlatformService, const std::string &sPrefix)
virtual void modify(const ConfigurationUpdate &update)=0
std::list< FadingSelection > FadingSelections
#define LOGGER_STANDARD_LOGGING(logger, level, fmt, args...)
void modify(const ConfigurationUpdate &update)