EMANE  1.0.1
nemmanagerimpl.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2016 - 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::uint8_t>("otamanagerttl",
92  {1},
93  "OTA channel multicast message TTL.");
94 
95 
96  configRegistrar.registerNumeric<bool>("otamanagerloopback",
98  {false},
99  "Enable multicast loopback on the OTA channel multicast channel.");
100 
101  configRegistrar.registerNumeric<bool>("otamanagerchannelenable",
103  {true},
104  "Enable OTA channel multicast communication.");
105 
106 
107  configRegistrar.registerNonNumeric<INETAddr>("controlportendpoint",
109  {INETAddr{"0.0.0.0",47000 }},
110  "IPv4 or IPv6 control port endpoint.");
111 
112  configRegistrar.registerNonNumeric<std::string>("antennaprofilemanifesturi",
114  {},
115  "Absolute URI of the antenna profile manifest to load."
116  " The antenna profile manifest contains a list of"
117  " antenna profile entries. Each entry contains a unique"
118  " profile identifier, an antenna pattern URI and an"
119  " antenna blockage URI. This parameter is required when"
120  " antennaprofileenable is on or if any other NEM"
121  " participating in the emulation has antennaprofileenable"
122  " set on, even in the case where antennaprofileenable is"
123  " off locally.");
124 
125  configRegistrar.registerNumeric<std::uint32_t>("stats.ota.maxpacketcountrows",
127  {0},
128  "OTA channel max packet count table rows.");
129 
130  configRegistrar.registerNumeric<std::uint32_t>("stats.ota.maxeventcountrows",
132  {0},
133  "OTA channel max event count table rows.");
134 
135  configRegistrar.registerNumeric<std::uint32_t>("stats.event.maxeventcountrows",
137  {0},
138  "Event channel max event count table rows.");
139 
140 }
141 
143 {
144  for(const auto & item : update)
145  {
146  if(item.first == "otamanagergroup")
147  {
148  OTAManagerGroupAddr_ = item.second[0].asINETAddr();
149 
151  INFO_LEVEL,
152  "NEMManagerImpl::configure OTA Manager Channel Group: %s",
153  OTAManagerGroupAddr_.str().c_str());
154 
155  }
156  else if(item.first == "otamanagerdevice")
157  {
158  sOTAManagerGroupDevice_ = item.second[0].asString();
159 
161  INFO_LEVEL,
162  "NEMManagerImpl::configure %s: %s",
163  item.first.c_str(),
164  sOTAManagerGroupDevice_.c_str());
165 
166  }
167  else if(item.first == "otamanagerttl")
168  {
169  u8OTAManagerTTL_ = item.second[0].asUINT8();
170 
172  INFO_LEVEL,
173  "NEMManagerImpl::configure %s: %hhu",
174  item.first.c_str(),
175  u8OTAManagerTTL_);
176  }
177  else if(item.first == "otamanagerloopback")
178  {
179  bOTAManagerChannelLoopback_ = item.second[0].asBool();
180 
182  INFO_LEVEL,
183  "NEMManagerImpl::configure %s: %s",
184  item.first.c_str(),
185  bOTAManagerChannelLoopback_ ? "on" : "off");
186  }
187  else if(item.first == "otamanagerchannelenable")
188  {
189  bOTAManagerChannelEnable_ = item.second[0].asBool();
190 
192  INFO_LEVEL,
193  "NEMManagerImpl::configure %s: %s",
194  item.first.c_str(),
195  bOTAManagerChannelEnable_ ? "on" : "off");
196  }
197  else if(item.first == "eventservicegroup")
198  {
199  eventServiceGroupAddr_ = item.second[0].asINETAddr();
200 
202  INFO_LEVEL,
203  "NEMManagerImpl::configure %s: %s",
204  item.first.c_str(),
205  eventServiceGroupAddr_.str().c_str());
206 
207  }
208  else if(item.first == "eventservicedevice")
209  {
210  sEventServiceDevice_ = item.second[0].asString();
211 
213  INFO_LEVEL,
214  "NEMManagerImpl::configure %s: %s",
215  item.first.c_str(),
216  sEventServiceDevice_.c_str());
217 
218  }
219  else if(item.first == "eventservicettl")
220  {
221  u8EventServiceTTL_ = item.second[0].asUINT8();
222 
224  INFO_LEVEL,
225  "NEMManagerImpl::configure %s: %hhu",
226  item.first.c_str(),
227  u8EventServiceTTL_);
228  }
229  else if(item.first == "controlportendpoint")
230  {
231  controlPortAddr_ = item.second[0].asINETAddr();
232 
234  INFO_LEVEL,
235  "NEMManagerImpl::configure %s: %s",
236  item.first.c_str(),
237  controlPortAddr_.str().c_str());
238  }
239 
240  else if(item.first == "antennaprofilemanifesturi")
241  {
242  sAntennaProfileManifestURI_ = item.second[0].asString();
243 
245  INFO_LEVEL,
246  "NEMManagerImpl::configure %s: %s",
247  item.first.c_str(),
248  sAntennaProfileManifestURI_.c_str());
249 
250  }
251  else if(item.first == "stats.ota.maxpacketcountrows")
252  {
253  std::uint32_t u32OTAMaxPacketCountRows = item.second[0].asUINT32();
254 
256  INFO_LEVEL,
257  "NEMManagerImpl::configure %s: %u",
258  item.first.c_str(),
259  u32OTAMaxPacketCountRows);
260 
262  setStatPacketCountRowLimit(u32OTAMaxPacketCountRows);
263  }
264  else if(item.first == "stats.ota.maxeventcountrows")
265  {
266  std::uint32_t u32OTAMaxEventCountRows = item.second[0].asUINT32();
267 
269  INFO_LEVEL,
270  "NEMManagerImpl::configure %s: %u",
271  item.first.c_str(),
272  u32OTAMaxEventCountRows);
273 
275  setStatEventCountRowLimit(u32OTAMaxEventCountRows);
276  }
277  else if(item.first == "stats.event.maxeventcountrows")
278  {
279  std::uint32_t u32EventMaxEventCountRows = item.second[0].asUINT32();
280 
282  INFO_LEVEL,
283  "NEMManagerImpl::configure %s: %u",
284  item.first.c_str(),
285  u32EventMaxEventCountRows);
286 
288  setStatEventCountRowLimit(u32EventMaxEventCountRows);
289  }
290  else
291  {
292  throw makeException<ConfigureException>("NEMManagerImpl: "
293  "Unexpected configuration item %s",
294  item.first.c_str());
295  }
296  }
297 
298 
299  if(!sAntennaProfileManifestURI_.empty())
300  {
301  AntennaProfileManifest::instance()->load(sAntennaProfileManifestURI_);
302  }
303 
304 }
305 
307 {
308  if(bOTAManagerChannelEnable_)
309  {
310  try
311  {
312  OTAManagerSingleton::instance()->open(OTAManagerGroupAddr_,
313  sOTAManagerGroupDevice_,
314  bOTAManagerChannelLoopback_,
315  u8OTAManagerTTL_,
316  uuid_);
317  }
318  catch(OTAException & exp)
319  {
320  throw StartException(exp.what());
321  }
322  }
323 
324  try
325  {
326  EMANE::EventServiceSingleton::instance()->open(eventServiceGroupAddr_,
327  sEventServiceDevice_,
328  u8EventServiceTTL_,
329  true,
330  uuid_);
331  }
332  catch(EventServiceException & e)
333  {
334  throw StartException(e.what());
335  }
336 
337  controlPortService_.open(controlPortAddr_);
338 
339  std::for_each(platformNEMMap_.begin(),
340  platformNEMMap_.end(),
341  std::bind(&Component::start,
342  std::bind(&PlatformNEMMap::value_type::second,
343  std::placeholders::_1)));
344 }
345 
347 {
348  std::for_each(platformNEMMap_.begin(),
349  platformNEMMap_.end(),
350  std::bind(&Component::postStart,
351  std::bind(&PlatformNEMMap::value_type::second,
352  std::placeholders::_1)));
353 }
354 
356 {
357  controlPortService_.close();
358 
359  std::for_each(platformNEMMap_.begin(),
360  platformNEMMap_.end(),
361  std::bind(&Component::stop,
362  std::bind(&PlatformNEMMap::value_type::second,
363  std::placeholders::_1)));
364 }
365 
367  throw()
368 {
369  std::for_each(platformNEMMap_.begin(),
370  platformNEMMap_.end(),
371  std::bind(&Component::destroy,
372  std::bind(&PlatformNEMMap::value_type::second,
373  std::placeholders::_1)));
374 }
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
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
void open(const INETAddr &otaGroupAddress, const std::string &sDevice, bool bLoopback, int iTTL, const uuid_t &uuid)
Definition: otamanager.cc:292
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.