EMANE  1.2.1
nemmanagerimpl.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2017 - Adjacent Link LLC, Bridgewater, New Jersey
3  * Copyright (c) 2011 - DRS CenGen, LLC, Columbia, Maryland
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of DRS CenGen, LLC nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "nemmanagerimpl.h"
35 #include "logservice.h"
36 #include "otamanager.h"
37 #include "timerservice.h"
38 #include "eventservice.h"
39 #include "eventserviceexception.h"
42 #include "emane/startexception.h"
43 #include "otaexception.h"
44 #include "antennaprofilemanifest.h"
45 
47  NEMManager{uuid}{}
48 
50 
51 void EMANE::Application::NEMManagerImpl::add(std::unique_ptr<Application::NEM> & pNEM)
52 {
53  if(!platformNEMMap_.insert(std::make_pair(pNEM->getNEMId(),std::move(pNEM))).second)
54  {
55  throw makeException<PlatformException>("NEMManagerImpl: Multiple NEMs with id"
56  " %hu detected",
57  pNEM->getNEMId());
58  }
59 }
60 
62 {
63  auto & configRegistrar = registrar.configurationRegistrar();
64 
65  configRegistrar.registerNonNumeric<INETAddr>("eventservicegroup",
67  {},
68  "IPv4 or IPv6 Event Service channel multicast endpoint.");
69 
70  configRegistrar.registerNonNumeric<std::string>("eventservicedevice",
72  {},
73  "Device to associate with the Event Service channel multicast endpoint.");
74 
75  configRegistrar.registerNumeric<std::uint8_t>("eventservicettl",
77  {1},
78  "Device to associate with the Event Service channel multicast endpoint.");
79 
80  configRegistrar.registerNonNumeric<INETAddr>("otamanagergroup",
82  {},
83  "IPv4 or IPv6 Event Service OTA channel endpoint.");
84 
85  configRegistrar.registerNonNumeric<std::string>("otamanagerdevice",
87  {},
88  "Device to associate with the OTA channel multicast endpoint.");
89 
90  configRegistrar.registerNumeric<std::uint32_t>("otamanagermtu",
92  {0},
93  "OTA channel MTU.");
94 
95  configRegistrar.registerNumeric<std::uint16_t>("otamanagerpartcheckthreshold",
97  {2},
98  "Defines the rate in seconds a check is performed to see if any OTA packet"
99  " part reassembly efforts should be abandoned.");
100 
101  configRegistrar.registerNumeric<std::uint16_t>("otamanagerparttimeoutthreshold",
103  {5},
104  "Defines the threshold in seconds to wait for another OTA packet part"
105  " for an existing reassembly effort before abandoning the effort.");
106 
107  configRegistrar.registerNumeric<std::uint8_t>("otamanagerttl",
109  {1},
110  "OTA channel multicast message TTL.");
111 
112  configRegistrar.registerNumeric<bool>("otamanagerloopback",
114  {false},
115  "Enable multicast loopback on the OTA channel multicast channel.");
116 
117  configRegistrar.registerNumeric<bool>("otamanagerchannelenable",
119  {true},
120  "Enable OTA channel multicast communication.");
121 
122 
123  configRegistrar.registerNonNumeric<INETAddr>("controlportendpoint",
125  {INETAddr{"0.0.0.0",47000 }},
126  "IPv4 or IPv6 control port endpoint.");
127 
128  configRegistrar.registerNonNumeric<std::string>("antennaprofilemanifesturi",
130  {},
131  "URI of the antenna profile manifest to load."
132  " The antenna profile manifest contains a list of"
133  " antenna profile entries. Each entry contains a unique"
134  " profile identifier, an antenna pattern URI and an"
135  " antenna blockage URI. This parameter is required when"
136  " antennaprofileenable is on or if any other NEM"
137  " participating in the emulation has antennaprofileenable"
138  " set on, even in the case where antennaprofileenable is"
139  " off locally.");
140 
141  configRegistrar.registerNumeric<std::uint32_t>("stats.ota.maxpacketcountrows",
143  {0},
144  "OTA channel max packet count table rows.");
145 
146  configRegistrar.registerNumeric<std::uint32_t>("stats.ota.maxeventcountrows",
148  {0},
149  "OTA channel max event count table rows.");
150 
151  configRegistrar.registerNumeric<std::uint32_t>("stats.event.maxeventcountrows",
153  {0},
154  "Event channel max event count table rows.");
155 
156 }
157 
159 {
160  for(const auto & item : update)
161  {
162  if(item.first == "otamanagergroup")
163  {
164  OTAManagerGroupAddr_ = item.second[0].asINETAddr();
165 
167  INFO_LEVEL,
168  "NEMManagerImpl::configure %s: %s",
169  item.first.c_str(),
170  OTAManagerGroupAddr_.str().c_str());
171 
172  }
173  else if(item.first == "otamanagerdevice")
174  {
175  sOTAManagerGroupDevice_ = item.second[0].asString();
176 
178  INFO_LEVEL,
179  "NEMManagerImpl::configure %s: %s",
180  item.first.c_str(),
181  sOTAManagerGroupDevice_.c_str());
182 
183  }
184  else if(item.first == "otamanagerttl")
185  {
186  u8OTAManagerTTL_ = item.second[0].asUINT8();
187 
189  INFO_LEVEL,
190  "NEMManagerImpl::configure %s: %hhu",
191  item.first.c_str(),
192  u8OTAManagerTTL_);
193  }
194  else if(item.first == "otamanagermtu")
195  {
196  u32OTAManagerMTU_ = item.second[0].asUINT32();
197 
199  INFO_LEVEL,
200  "NEMManagerImpl::configure %s: %u",
201  item.first.c_str(),
202  u32OTAManagerMTU_);
203  }
204  else if(item.first == "otamanagerpartcheckthreshold")
205  {
206  OTAManagerPartCheckThreshold_= EMANE::Seconds{item.second[0].asUINT16()};
207 
209  INFO_LEVEL,
210  "NEMManagerImpl::configure %s = %lu",
211  item.first.c_str(),
212  OTAManagerPartCheckThreshold_.count());
213  }
214  else if(item.first == "otamanagerparttimeoutthreshold")
215  {
216  OTAManagerPartTimeoutThreshold_ = EMANE::Seconds{item.second[0].asUINT16()};
217 
219  INFO_LEVEL,
220  "NEMManagerImpl::configure %s = %lu",
221  item.first.c_str(),
222  OTAManagerPartTimeoutThreshold_.count());
223  }
224  else if(item.first == "otamanagerloopback")
225  {
226  bOTAManagerChannelLoopback_ = item.second[0].asBool();
227 
229  INFO_LEVEL,
230  "NEMManagerImpl::configure %s: %s",
231  item.first.c_str(),
232  bOTAManagerChannelLoopback_ ? "on" : "off");
233  }
234  else if(item.first == "otamanagerchannelenable")
235  {
236  bOTAManagerChannelEnable_ = item.second[0].asBool();
237 
239  INFO_LEVEL,
240  "NEMManagerImpl::configure %s: %s",
241  item.first.c_str(),
242  bOTAManagerChannelEnable_ ? "on" : "off");
243  }
244  else if(item.first == "eventservicegroup")
245  {
246  eventServiceGroupAddr_ = item.second[0].asINETAddr();
247 
249  INFO_LEVEL,
250  "NEMManagerImpl::configure %s: %s",
251  item.first.c_str(),
252  eventServiceGroupAddr_.str().c_str());
253 
254  }
255  else if(item.first == "eventservicedevice")
256  {
257  sEventServiceDevice_ = item.second[0].asString();
258 
260  INFO_LEVEL,
261  "NEMManagerImpl::configure %s: %s",
262  item.first.c_str(),
263  sEventServiceDevice_.c_str());
264 
265  }
266  else if(item.first == "eventservicettl")
267  {
268  u8EventServiceTTL_ = item.second[0].asUINT8();
269 
271  INFO_LEVEL,
272  "NEMManagerImpl::configure %s: %hhu",
273  item.first.c_str(),
274  u8EventServiceTTL_);
275  }
276  else if(item.first == "controlportendpoint")
277  {
278  controlPortAddr_ = item.second[0].asINETAddr();
279 
281  INFO_LEVEL,
282  "NEMManagerImpl::configure %s: %s",
283  item.first.c_str(),
284  controlPortAddr_.str().c_str());
285  }
286 
287  else if(item.first == "antennaprofilemanifesturi")
288  {
289  sAntennaProfileManifestURI_ = item.second[0].asString();
290 
292  INFO_LEVEL,
293  "NEMManagerImpl::configure %s: %s",
294  item.first.c_str(),
295  sAntennaProfileManifestURI_.c_str());
296 
297  }
298  else if(item.first == "stats.ota.maxpacketcountrows")
299  {
300  std::uint32_t u32OTAMaxPacketCountRows = item.second[0].asUINT32();
301 
303  INFO_LEVEL,
304  "NEMManagerImpl::configure %s: %u",
305  item.first.c_str(),
306  u32OTAMaxPacketCountRows);
307 
309  setStatPacketCountRowLimit(u32OTAMaxPacketCountRows);
310  }
311  else if(item.first == "stats.ota.maxeventcountrows")
312  {
313  std::uint32_t u32OTAMaxEventCountRows = item.second[0].asUINT32();
314 
316  INFO_LEVEL,
317  "NEMManagerImpl::configure %s: %u",
318  item.first.c_str(),
319  u32OTAMaxEventCountRows);
320 
322  setStatEventCountRowLimit(u32OTAMaxEventCountRows);
323  }
324  else if(item.first == "stats.event.maxeventcountrows")
325  {
326  std::uint32_t u32EventMaxEventCountRows = item.second[0].asUINT32();
327 
329  INFO_LEVEL,
330  "NEMManagerImpl::configure %s: %u",
331  item.first.c_str(),
332  u32EventMaxEventCountRows);
333 
335  setStatEventCountRowLimit(u32EventMaxEventCountRows);
336  }
337  else
338  {
339  throw makeException<ConfigureException>("NEMManagerImpl: "
340  "Unexpected configuration item %s",
341  item.first.c_str());
342  }
343  }
344 
345 
346  if(!sAntennaProfileManifestURI_.empty())
347  {
348  AntennaProfileManifest::instance()->load(sAntennaProfileManifestURI_);
349  }
350 
351 }
352 
354 {
355  if(bOTAManagerChannelEnable_)
356  {
357  try
358  {
359  OTAManagerSingleton::instance()->open(OTAManagerGroupAddr_,
360  sOTAManagerGroupDevice_,
361  bOTAManagerChannelLoopback_,
362  u8OTAManagerTTL_,
363  uuid_,
364  u32OTAManagerMTU_,
365  OTAManagerPartCheckThreshold_,
366  OTAManagerPartTimeoutThreshold_);
367  }
368  catch(OTAException & exp)
369  {
370  throw StartException(exp.what());
371  }
372  }
373 
374  try
375  {
376  EMANE::EventServiceSingleton::instance()->open(eventServiceGroupAddr_,
377  sEventServiceDevice_,
378  u8EventServiceTTL_,
379  true,
380  uuid_);
381  }
382  catch(EventServiceException & e)
383  {
384  throw StartException(e.what());
385  }
386 
387  controlPortService_.open(controlPortAddr_);
388 
389  std::for_each(platformNEMMap_.begin(),
390  platformNEMMap_.end(),
391  std::bind(&Component::start,
392  std::bind(&PlatformNEMMap::value_type::second,
393  std::placeholders::_1)));
394 }
395 
397 {
398  std::for_each(platformNEMMap_.begin(),
399  platformNEMMap_.end(),
400  std::bind(&Component::postStart,
401  std::bind(&PlatformNEMMap::value_type::second,
402  std::placeholders::_1)));
403 }
404 
406 {
407  controlPortService_.close();
408 
409  std::for_each(platformNEMMap_.begin(),
410  platformNEMMap_.end(),
411  std::bind(&Component::stop,
412  std::bind(&PlatformNEMMap::value_type::second,
413  std::placeholders::_1)));
414 }
415 
417  throw()
418 {
419  std::for_each(platformNEMMap_.begin(),
420  platformNEMMap_.end(),
421  std::bind(&Component::destroy,
422  std::bind(&PlatformNEMMap::value_type::second,
423  std::placeholders::_1)));
424 }
void load(const std::string &sAntennaProfileURI)
The Registrar interface provides access to all of the emulator registrars.
Definition: registrar.h:50
virtual ConfigurationRegistrar & configurationRegistrar()=0
void open(const INETAddr &endpoint)
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={})
Exception thrown when registering or unregistering OTAUsers.
Definition: otaexception.h:46
virtual void postStart()
Definition: component.h:119
std::chrono::seconds Seconds
Definition: types.h:43
virtual void stop()=0
const char * what() const
Definition: exception.h:62
Contains and manages NEM instances.
Definition: nemmanager.h:54
void open(const INETAddr &eventChannelAddress, const std::string &sDevice, int iTTL, bool loopbackEnable, const uuid_t &uuid)
Definition: eventservice.cc:92
std::string str(bool bWithPort=true) const
Definition: inetaddr.cc:409
void add(std::unique_ptr< NEM > &pNEM) override
void configure(const ConfigurationUpdate &update) override
Component start exception is used to indicate an exception during transition to the start state...
std::vector< ConfigurationNameAnyValues > ConfigurationUpdate
void initialize(Registrar &registrar) override
virtual void destroy()=0
virtual void start()=0
#define LOGGER_STANDARD_LOGGING(logger, level, fmt, args...)
static LogService * instance()
Definition: singleton.h:56
Exception thrown during open/establishment of the event service communication channel.
void open(const INETAddr &otaGroupAddress, const std::string &sDevice, bool bLoopback, int iTTL, const uuid_t &uuid, size_t otaMTU, Seconds partCheckThreshold, Seconds partTimeoutThreshold)
Definition: otamanager.cc:431