EMANE  1.2.1
eelloadercommeffect.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - Adjacent Link LLC, Bridgewater, New Jersey
3  * Copyright (c) 2012 - 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 
35 #include "eelloadercommeffect.h"
39 
40 #include <vector>
41 #include <cstring>
42 
44 {}
45 
47 {}
48 
50  const ModuleId & moduleId,
51  const EventType & ,
52  const InputArguments & args)
53 {
54  if(moduleType == "nem")
55  {
56  if(args.size() < 1)
57  {
58  throw FormatException("LoaderCommEffect expects at least 1 argument");
59  }
60  else
61  {
62  InputArguments::const_iterator iterArg = args.begin();
63 
64  // parse the individual commeffect entry params
65  for(; iterArg != args.end(); ++iterArg)
66  {
67  InputArguments params;
68 
69  size_t posStart = 0;
70  size_t posEnd = 0;
71 
72  // build a parameters vector holding all the
73  // comma separeted elements
74  // <dstModuleID>,<latency seconds>,<jitter seconds>,
75  // <loss>,<duplicates>,<unicast bps>,<broadcast bps> ...
76  while(posEnd != std::string::npos)
77  {
78  posEnd = iterArg->find_first_of(",",posStart);
79 
80  params.push_back( iterArg->substr(posStart, posEnd - posStart));
81 
82  posStart = posEnd + 1;
83  }
84 
85  // you must at least specify a destination and commeffect
86  if(params.size() != 7)
87  {
88  throw FormatException("LoaderCommEffect expects 7 parameters "
89  "<dstModuleID>,<latency seconds>,<jitter seconds>, "
90  "<loss>,<duplicates>,<unicast bps>,<broadcast bps>");
91  }
92  else
93  {
94  NEMId srcNEM{moduleId};
95  NEMId dstNEM{};
96  float fLatencySeconds{};
97  float fJitterSeconds{};
98  float fProbabilityLoss{};
99  float fProbabilityDuplicate{};
100  std::uint64_t u64UnicastBitRate{};
101  std::uint64_t u64BroadcastBitRate{};
102 
103  // convert the strings into the appropriate types
104  for(size_t i = 0; i < params.size(); ++i)
105  {
106  try
107  {
108  switch(i)
109  {
110  case 0:
111  // <dstModuleID> which must be nem:UINT16
112  {
113  size_t pos = params[i].find(':');
114 
115  if(pos != std::string::npos)
116  {
117  if(params[i].substr(0,pos) == "nem")
118  {
119  dstNEM =
120  Utils::ParameterConvert(params[i].substr(pos + 1)).toUINT16();
121  }
122  else
123  {
124  std::stringstream sstream;
125  throw FormatException("LoaderCommEffect only supports 'nem' module type");
126  }
127  }
128  }
129  break;
130 
131  case 1:
132  fLatencySeconds = Utils::ParameterConvert(params[i]).toFloat();
133  break;
134 
135  case 2:
136  fJitterSeconds= Utils::ParameterConvert(params[i]).toFloat();
137  break;
138 
139  case 3:
140  fProbabilityLoss = Utils::ParameterConvert(params[i]).toFloat();
141  break;
142 
143  case 4:
144  fProbabilityDuplicate = Utils::ParameterConvert(params[i]).toFloat();
145  break;
146 
147  case 5:
148  u64UnicastBitRate = Utils::ParameterConvert(params[i]).toUINT64();
149  break;
150 
151  case 6:
152  u64BroadcastBitRate = Utils::ParameterConvert(params[i]).toUINT64();
153  break;
154 
155  default:
156  throw FormatException("LoaderCommEffect loader too many parameters");
157  break;
158  }
159  }
161  {
162  std::stringstream sstream;
163  sstream<<"LoaderCommEffect loader: Parameter conversion error. "<<exp.what()<<std::ends;
164  throw FormatException(sstream.str());
165  }
166  }
167 
168  Events::CommEffect commEffect{srcNEM,
169  std::chrono::duration_cast<Microseconds>(DoubleSeconds{fLatencySeconds}),
170  std::chrono::duration_cast<Microseconds>(DoubleSeconds{fJitterSeconds}),
171  fProbabilityLoss,
172  fProbabilityDuplicate,
173  u64UnicastBitRate,
174  u64BroadcastBitRate};
175 
176  // load the full commeffect cache
177  loadCommEffectCache(dstNEM,commEffect,commeffectEntryCache_);
178 
179  // load the delta update cache
180  loadCommEffectCache(dstNEM,commEffect,commeffectDeltaEntryCache_);
181  }
182  }
183  }
184  }
185 }
186 
188 {
189  EventInfoList eventInfoList;
190 
191  CommEffectEntryCache * pCache = 0;
192 
193  if(mode == DELTA)
194  {
195  // in DELTA mode events *only* contain entries that have
196  // changes since the last update
197  pCache = &commeffectDeltaEntryCache_;
198  }
199  else
200  {
201  // in FULL mode events contain all the entries regardless
202  // of whether they contain updated data since the last
203  // getEvents() call
204  pCache = &commeffectEntryCache_;
205  }
206 
207  Events::CommEffects commEffects;
208 
209  CommEffectEntryCache::iterator iter = pCache->begin();
210 
211  for(;iter != pCache->end(); ++iter)
212  {
213  CommEffectEntryMap::iterator iterEntry = iter->second.begin();
214 
215  for(; iterEntry != iter->second.end(); ++iterEntry)
216  {
217  commEffects.push_back(iterEntry->second);
218  }
219 
220  if(!commEffects.empty())
221  {
222  eventInfoList.push_back({iter->first,
224  Events::CommEffectEvent(commEffects).serialize()});
225 
226  }
227 
228  commEffects.clear();
229  }
230 
231  commeffectDeltaEntryCache_.clear();
232 
233  return eventInfoList;
234 }
235 
236 void EMANE::Generators::EEL::LoaderCommEffect::loadCommEffectCache(NEMId dstNEM,
237  const Events::CommEffect & commEffect,
238  CommEffectEntryCache & cache)
239 {
240  CommEffectEntryCache::iterator iter = cache.end();
241 
242  if((iter = cache.find(dstNEM)) != cache.end())
243  {
244  std::pair<CommEffectEntryMap::iterator,bool> ret =
245  iter->second.insert(std::make_pair(commEffect.getNEMId(),commEffect));
246 
247  if(!ret.second)
248  {
249  ret.first->second = commEffect;
250  }
251  }
252  else
253  {
254  CommEffectEntryMap entryMap;
255  entryMap.insert(std::make_pair(commEffect.getNEMId(),commEffect));
256  cache.insert(std::make_pair(dstNEM,entryMap));
257  }
258 
259 }
260 
void load(const ModuleType &modelType, const ModuleId &moduleId, const EventType &eventType, const InputArguments &args) override
std::vector< std::string > InputArguments
#define DECLARE_EEL_LOADER_PLUGIN(X)
Definition: loaderplugin.h:91
Parameter conversion exception class.
std::uint16_t toUINT16(std::uint16_t u16Min=std::numeric_limits< std::uint16_t >::min(), std::uint16_t u16Max=std::numeric_limits< std::uint16_t >::max()) const
float toFloat(float fMin=std::numeric_limits< float >::lowest(), float fMax=std::numeric_limits< float >::max()) const
std::uint64_t toUINT64(std::uint64_t u64Min=std::numeric_limits< std::uint64_t >::min(), std::uint64_t u64Max=std::numeric_limits< std::uint64_t >::max()) const
const char * what() const
Definition: exception.h:62
std::list< CommEffect > CommEffects
Definition: commeffect.h:131
std::chrono::microseconds Microseconds
Definition: types.h:45
std::chrono::duration< double > DoubleSeconds
Definition: types.h:47
std::uint16_t NEMId
Definition: types.h:52
A CommEffect entry holds the NEM Id of a transmitter and the link effects to apply to received transm...
Definition: commeffect.h:52
EventInfoList getEvents(EventPublishMode mode) override
std::list< EventInfo > EventInfoList
Parameter conversion class with range checks.