EMANE  1.2.1
nembuilder.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014,2016 - Adjacent Link LLC, Bridgewater,
3  * New Jersey
4  * Copyright (c) 2008-2009-2010 - DRS CenGen, LLC, Columbia, Maryland
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * * Neither the name of DRS CenGen, LLC nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 #include "nemmanagerimpl.h"
36 #include "emane/buildexception.h"
37 #include "timerserviceproxy.h"
38 #include "maclayer.h"
39 #include "phylayer.h"
40 #include "shimlayer.h"
41 #include "transportlayer.h"
42 #include "nemstatefullayer.h"
43 #include "nemimpl.h"
44 #include "buildidservice.h"
45 #include "layerfactorymanager.h"
47 #include "logservice.h"
48 #include "eventservice.h"
49 #include "nemplatformservice.h"
50 #include "registrarproxy.h"
51 #include "frameworkphy.h"
52 #include "radioservice.h"
53 #include "spectrummonitor.h"
54 
55 class EMANE::Application::NEMBuilder::NEMBuilderImpl
56 {
57 public:
58  SpectrumMonitor * getSpectrumMonitor(NEMId id)
59  {
60  auto iter = spectrumMonitorCache_.find(id);
61 
62  if(iter != spectrumMonitorCache_.end())
63  {
64  return iter->second;
65  }
66  else
67  {
68  SpectrumMonitor * pSpectrumMonitor{new SpectrumMonitor};
69 
70  spectrumMonitorCache_.insert(std::make_pair(id,pSpectrumMonitor));
71 
72  return pSpectrumMonitor;
73  }
74  }
75 
76 private:
77  using SpectrumMonitorCache = std::map<NEMId,SpectrumMonitor *>;
78  SpectrumMonitorCache spectrumMonitorCache_;
79 };
80 
82  pImpl_{new NEMBuilderImpl}{}
83 
85 
86 std::unique_ptr<EMANE::NEMLayer>
88  const std::string & sLibraryFile,
89  const ConfigurationUpdateRequest & request,
90  bool bSkipConfigure)
91 {
92  std::string sNativeLibraryFile = "lib" +
93  sLibraryFile +
94  ".so";
95 
96  // new platform service
97  NEMPlatformService * pPlatformService{new NEMPlatformService{}};
98 
99  PHYLayerImplementor * pImpl{};
100 
101  std::string sRegistrationName{};
102 
103  // no library specification implies the framework phy implementation
104  // should be used
105  if(sLibraryFile.empty())
106  {
107  pImpl = new FrameworkPHY{id, pPlatformService, pImpl_->getSpectrumMonitor(id)};
108 
109  sRegistrationName = "emanephy";
110  }
111  else
112  {
113  const PHYLayerFactory & phyLayerFactory =
115 
116  // create plugin
117  pImpl = phyLayerFactory.createLayer(id, pPlatformService);
118 
119  sRegistrationName = sLibraryFile;
120  }
121 
122 
123  std::unique_ptr<NEMQueuedLayer> pNEMLayer{new PHYLayer{id,
124  new NEMStatefulLayer{id,
125  pImpl,
126  pPlatformService},
127  pPlatformService}};
128 
131  sRegistrationName)};
132 
134  pNEMLayer.get());
135 
136  pPlatformService->setNEMLayer(buildId,
137  pNEMLayer.get());
138 
139  // register event service handler with event service
141  pNEMLayer.get(),
142  id);
143 
144  RegistrarProxy registrarProxy{buildId};
145 
146  // initialize
147  pNEMLayer->initialize(registrarProxy);
148 
149  if(!bSkipConfigure)
150  {
151  pNEMLayer->configure(ConfigurationServiceSingleton::instance()->buildUpdates(buildId,
152  request));
153  }
154 
155  return std::unique_ptr<NEMLayer>(pNEMLayer.release());
156 }
157 
158 std::unique_ptr<EMANE::NEMLayer>
160  const std::string & sLibraryFile,
161  const ConfigurationUpdateRequest & request,
162  bool bSkipConfigure)
163 {
164  std::string sNativeLibraryFile = "lib" +
165  sLibraryFile +
166  ".so";
167 
168  const MACLayerFactory & macLayerFactory =
170 
171  // new platform service
172  NEMPlatformService * pPlatformService{new NEMPlatformService{}};
173 
174  // new radio service
175  RadioService * pRadioService{new RadioService{pImpl_->getSpectrumMonitor(id)}};
176 
177  // create plugin
178  MACLayerImplementor * pImpl =
179  macLayerFactory.createLayer(id, pPlatformService,pRadioService);
180 
181  std::unique_ptr<NEMQueuedLayer> pNEMLayer{new MACLayer{id,
182  new NEMStatefulLayer{id,
183  pImpl,
184  pPlatformService},
185  pPlatformService}};
186 
187  // register to the component map
190  sLibraryFile)};
191 
193  pNEMLayer.get());
194 
195  // pass nem layer to platform service
196  pPlatformService->setNEMLayer(buildId,
197  pNEMLayer.get());
198 
199  // register event service handler with event service
201  pNEMLayer.get(),
202  id);
203 
204  RegistrarProxy registrarProxy{buildId};
205 
206  // initialize
207  pNEMLayer->initialize(registrarProxy);
208 
209  if(!bSkipConfigure)
210  {
211  pNEMLayer->configure(ConfigurationServiceSingleton::instance()->buildUpdates(buildId,
212  request));
213  }
214 
215  return std::unique_ptr<EMANE::NEMLayer>(pNEMLayer.release());
216 }
217 
218 
219 std::unique_ptr<EMANE::NEMLayer>
221  const std::string & sLibraryFile,
222  const ConfigurationUpdateRequest & request,
223  bool bSkipConfigure)
224 {
225  std::string sNativeLibraryFile = "lib" +
226  sLibraryFile +
227  ".so";
228 
229  const ShimLayerFactory & shimLayerFactory =
231 
232  // new platform service
233  NEMPlatformService * pPlatformService{new NEMPlatformService{}};
234 
235  // new radio service
236  RadioService * pRadioService{new RadioService{pImpl_->getSpectrumMonitor(id)}};
237 
238  // create plugin
239  ShimLayerImplementor * pImpl =
240  shimLayerFactory.createLayer(id, pPlatformService,pRadioService);
241 
242  std::unique_ptr<NEMQueuedLayer> pNEMLayer{new ShimLayer{id,
243  new NEMStatefulLayer{id,
244  pImpl,
245  pPlatformService},
246  pPlatformService}};
247 
248  // register to the component map
251  sLibraryFile)};
252 
254  pNEMLayer.get());
255 
256  // pass nem layer to platform service
257  pPlatformService->setNEMLayer(buildId,
258  pNEMLayer.get());
259 
260  // register event service handler with event service
262  pNEMLayer.get(),
263  id);
264 
265  RegistrarProxy registrarProxy{buildId};
266 
267  // initialize
268  pNEMLayer->initialize(registrarProxy);
269 
270  if(!bSkipConfigure)
271  {
272  pNEMLayer->configure(ConfigurationServiceSingleton::instance()->buildUpdates(buildId,
273  request));
274  }
275 
276  return std::unique_ptr<EMANE::NEMLayer>(pNEMLayer.release());
277 }
278 
279 
280 std::unique_ptr<EMANE::Application::NEM>
282  NEMLayers & layers,
283  const ConfigurationUpdateRequest & request,
284  bool bExternalTransport)
285 {
286  std::unique_ptr<NEMLayerStack> pLayerStack{new NEMLayerStack};
287 
288  if(layers.empty())
289  {
290  throw BuildException("Trying to build a NEM without NEMLayers.");
291  }
292 
293  std::vector<BuildId> nemBuildIds;
294  for(auto & pLayer : layers)
295  {
296  if(pLayer->getNEMId() != id)
297  {
298 
299  throw makeException<BuildException>("NEMId mismatch: NEMLayer (%hu) NEM (%hu)",
300  pLayer->getNEMId(),
301  id);
302  }
303 
304  pLayerStack->addLayer(pLayer);
305  }
306 
307  std::unique_ptr<NEM> pNEM{new NEMImpl{id,pLayerStack,bExternalTransport}};
308 
309  // register to the component map
311 
312  RegistrarProxy registrarProxy{buildId};
313 
314  pNEM->initialize(registrarProxy);
315 
316  pNEM->configure(ConfigurationServiceSingleton::instance()->buildUpdates(buildId,
317  request));
318 
319  return pNEM;
320 }
321 
322 
323 std::unique_ptr<EMANE::Application::NEMManager>
325  NEMs & nems,
326  const ConfigurationUpdateRequest & request)
327 {
328  if(nems.empty())
329  {
330  throw BuildException("Trying to build an NEM Manager without any NEMs.");
331  }
332 
333  std::unique_ptr<Application::NEMManager> pPlatform{new NEMManagerImpl{uuid}};
334 
335  BuildId buildId{0};
336 
337  RegistrarProxy registrarProxy{buildId};
338 
339  pPlatform->initialize(registrarProxy);
340 
341  pPlatform->configure(ConfigurationServiceSingleton::instance()->buildUpdates(buildId,
342  request));
343 
344  std::for_each(nems.begin(),
345  nems.end(),
346  [&pPlatform](std::unique_ptr<NEM> & pNEM)
347  {
348  pPlatform->add(pNEM);
349  });
350 
351  return pPlatform;
352 }
353 
354 std::unique_ptr<EMANE::NEMLayer>
356  const std::string & sLibraryFile,
357  const ConfigurationUpdateRequest & request,
358  bool bSkipConfigure)
359 {
360  std::string sNativeLibraryFile = "lib" +
361  sLibraryFile +
362  ".so";
363 
364  const TransportFactory & transportLayerFactory =
366 
367  // new platform service
368  NEMPlatformService * pPlatformService{new NEMPlatformService{}};
369 
370  // create plugin
371  Transport * pImpl =
372  transportLayerFactory.createTransport(id, pPlatformService);
373 
374  std::unique_ptr<NEMQueuedLayer> pNEMLayer{new TransportLayer{id,
375  new NEMStatefulLayer{id,
376  pImpl,
377  pPlatformService},
378  pPlatformService}};
379 
380  // register to the component map
383  sLibraryFile)};
384 
386  pNEMLayer.get());
387 
388  // pass nem layer to platform service
389  pPlatformService->setNEMLayer(buildId,
390  pNEMLayer.get());
391 
392  // register event service handler with event service
394  pNEMLayer.get(),
395  id);
396 
397  RegistrarProxy registrarProxy{buildId};
398 
399  // initialize
400  pNEMLayer->initialize(registrarProxy);
401 
402  if(!bSkipConfigure)
403  {
404  pNEMLayer->configure(ConfigurationServiceSingleton::instance()->buildUpdates(buildId,
405  request));
406  }
407 
408  return std::unique_ptr<EMANE::NEMLayer>(pNEMLayer.release());
409 }
Bridge for the PHY NEM layer. Decouples a PHYLayerImplementor implementation from the NEM to allow fo...
std::list< std::unique_ptr< NEMLayer > > NEMLayers
Definition: nembuilder.h:51
std::unique_ptr< NEMManager > buildNEMManager(const uuid_t &uuid, NEMs &nems, const ConfigurationUpdateRequest &request)
Definition: nembuilder.cc:324
Implementation of the Network emulation module consisting of NEM components, OTA Adapater and network...
Definition: nemimpl.h:58
std::unique_ptr< NEMLayer > buildMACLayer(NEMId id, const std::string &sLibraryFile, const ConfigurationUpdateRequest &request, bool bSkipConfigure=false)
Definition: nembuilder.cc:159
Base class for all transports.
Definition: transport.h:49
const MACLayerFactory & getMACLayerFactory(const std::string &sLibraryFile)
Interface used to create a PHY layer plugin implementation.
Definition: phylayerimpl.h:53
const TransportFactory & getTransportFactory(const std::string &sLibraryFile)
Implementation of Platform interface. Contains and manages NEMs.
PHYLayerImplementor * createLayer(NEMId nemId, PlatformServiceProvider *pPlatformServiceProvider) const
Bridge for a shim NEM layer. Decouples a ShimLayerImplementor implementation from the NEM to allow fo...
Exception thrown by builders when constructing and assembling application objects and containers...
std::unique_ptr< NEMLayer > buildPHYLayer(NEMId id, const std::string &sLibraryFile, const ConfigurationUpdateRequest &request, bool bSkipConfigure=false)
Definition: nembuilder.cc:87
radio service interface
Definition: radioservice.h:45
Interface used to create a Shim layer plugin implementation.
Definition: shimlayerimpl.h:47
Bridge for the MAC NEM layer. Decouples a MACLayerImplementor implementation from the NEM to allow fo...
void registerRunningStateMutable(BuildId buildId, RunningStateMutable *pRunningStateMutable)
Transport * createTransport(NEMId nemId, PlatformServiceProvider *pPlatformService) const
BuildId registerBuildable(Application::NEMManager *pNEMManager)
std::uint16_t NEMId
Definition: types.h:52
const ShimLayerFactory & getShimLayerFactory(const std::string &sLibraryFile)
Bridge for the Transport NEM layer. Decouples a TransportLayerImplementor implementation from the NEM...
Factory for creating Transports. The factory manages the DLL allowing for the creation of multiple tr...
std::unique_ptr< NEM > buildNEM(NEMId id, NEMLayers &layers, const ConfigurationUpdateRequest &request, bool bHasExternalTransport)
Definition: nembuilder.cc:281
std::list< std::unique_ptr< NEM > > NEMs
Definition: nembuilder.h:52
std::vector< ConfigurationNameStringValues > ConfigurationUpdateRequest
A stack of NEM layers. Allows ownership and connection of NEM layers in a non layer specific manner...
Definition: nemlayerstack.h:51
T * createLayer(NEMId nemId, PlatformServiceProvider *pPlatformService, RadioServiceProvider *pRadioServiceProvider) const
const PHYLayerFactory & getPHYLayerFactory(const std::string &sLibraryFile)
std::unique_ptr< NEMLayer > buildTransportLayer(NEMId id, const std::string &sLibraryFile, const ConfigurationUpdateRequest &request, bool bSkipConfigure=false)
Definition: nembuilder.cc:355
Factory for creating T layers . The factory manages the DLL allowing for the creation of layers of th...
Definition: layerfactory.h:53
void registerEventServiceUser(BuildId buildId, EventServiceUser *pEventServiceUser, NEMId=0)
Definition: eventservice.cc:85
A layer stack that enforces component state transition rules. The stateful layer is not a fully funct...
static LayerFactoryManager * instance()
Definition: singleton.h:56
std::uint32_t BuildId
Definition: types.h:60
std::unique_ptr< NEMLayer > buildShimLayer(NEMId id, const std::string &sLibraryFile, const ConfigurationUpdateRequest &request, bool bSkipConfigure=false)
Definition: nembuilder.cc:220
NEM platform service.
Interface used to create a MAC layer plugin implementation.
Definition: maclayerimpl.h:48