EMANE  1.2.1
packetstatuspublisherimpl.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2016 - 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 
34 #include "priority.h"
35 
36 namespace
37 {
38  const EMANE::StatisticTableLabels PacketAcceptLabels =
39  {
40  "NEM",
41  "Num Bytes Tx",
42  "Num Bytes Rx"
43  };
44 
46  {
47  ACCEPT_COLUMN_NEM = 0,
48  ACCEPT_COLUMN_NUM_BYTES_TX = 1,
49  ACCEPT_COLUMN_NUM_BYTES_RX = 2,
50  };
51 
52  const EMANE::StatisticTableLabels PacketDropLabels =
53  {
54  "NEM",
55  "SINR",
56  "Reg Id",
57  "Dst MAC",
58  "Queue Overflow",
59  "Bad Control",
60  "Bad Spectrum Query",
61  "Flow Control",
62  "Big",
63  "Long",
64  "Freq",
65  "Slot Error",
66  "Miss Fragment"
67  };
68 
70  {
71  DROP_COLUMN_NEM = 0,
72  DROP_COLUMN_SINR = 1,
73  DROP_COLUMN_REG_ID = 2,
74  DROP_COLUMN_DST_MAC = 3,
75  DROP_COLUMN_QUEUE_OVERFLOW = 4,
76  DROP_COLUMN_BAD_CONTROL = 5,
77  DROP_COLUMN_BAD_SPECTRUM_QUERY = 6,
78  DROP_COLUMN_FLOW_CONTROL = 7,
79  DROP_COLUMN_TOO_BIG = 8,
80  DROP_COLUMN_TOO_LONG = 9,
81  DROP_COLUMN_FREQUENCY = 10,
82  DROP_COLUMN_SLOT_ERROR = 11,
83  DROP_COLUMN_MISS_FRAGMENT = 12
84  };
85 
86 }
88 
90 
92 {
93  for(int queueIndex = 0; queueIndex < QUEUE_COUNT; ++queueIndex)
94  {
95  broadcastAcceptTables_[queueIndex] =
96  statisticRegistrar.registerTable<NEMId>("BroadcastByteAcceptTable" + std::to_string(queueIndex),
97  PacketAcceptLabels,
98  [this,queueIndex](StatisticTablePublisher * pTable)
99  {
100  std::lock_guard<std::mutex> m(mutexBroadcastPacketAcceptTable_);
101  broadcastAcceptInfos_[queueIndex].clear();
102  pTable->clear();
103  },
104  "Broadcast bytes accepted");
105 
106  unicastAcceptTables_[queueIndex] =
107  statisticRegistrar.registerTable<NEMId>("UnicastByteAcceptTable" + std::to_string(queueIndex),
108  PacketAcceptLabels,
109  [this,queueIndex](StatisticTablePublisher * pTable)
110  {
111  std::lock_guard<std::mutex> m(mutexUnicastPacketAcceptTable_);
112  unicastAcceptInfos_[queueIndex].clear();
113  pTable->clear();
114  },
115  "Unicast bytes accepted");
116 
117  broadcastDropTables_[queueIndex] =
118  statisticRegistrar.registerTable<NEMId>("BroadcastByteDropTable" + std::to_string(queueIndex),
119  PacketDropLabels,
120  [this,queueIndex](StatisticTablePublisher * pTable)
121  {
122  std::lock_guard<std::mutex> m(mutexBroadcastPacketDropTable_);
123  broadcastDropInfos_[queueIndex].clear();
124  pTable->clear();
125  },
126  "Broadcast bytes dropped");
127 
128  unicastDropTables_[queueIndex] =
129  statisticRegistrar.registerTable<NEMId>("UnicastByteDropTable" + std::to_string(queueIndex),
130  PacketDropLabels,
131  [this,queueIndex](StatisticTablePublisher * pTable)
132  {
133  std::lock_guard<std::mutex> m(mutexUnicastPacketDropTable_);
134  unicastDropInfos_[queueIndex].clear();
135  pTable->clear();
136  },
137  "Unicast bytes dropped");
138  }
139 }
140 
142  const MessageComponent & component,
143  InboundAction action)
144 {
145  inbound(src,
146  component.getDestination(),
147  component.getPriority(),
148  component.getData().size(),
149  action);
150 }
151 
153  const MessageComponents & components,
154  InboundAction action)
155 {
156  for(const auto & component : components)
157  {
158  inbound(src,
159  component.getDestination(),
160  component.getPriority(),
161  component.getData().size(),
162  action);
163  }
164 }
165 
166 
167 
169  NEMId dst,
170  Priority priority,
171  size_t size,
172  InboundAction action)
173 {
174  TableArray * pAcceptTables{};
175  TableArray * pDropTables{};
176 
177  AcceptInfoArrary * pAcceptInfos{};
178  DropInfoArrary * pDropInfos{};
179 
180  std::mutex * pMutexAcceptTable = {};
181  std::mutex * pMutexDropTable = {};
182 
183  if(dst == NEM_BROADCAST_MAC_ADDRESS)
184  {
185  pAcceptTables = &broadcastAcceptTables_;
186  pDropTables = &broadcastDropTables_;
187 
188  pAcceptInfos = &broadcastAcceptInfos_;
189  pDropInfos = &broadcastDropInfos_;
190 
191  pMutexAcceptTable = &mutexBroadcastPacketAcceptTable_;
192  pMutexDropTable = &mutexBroadcastPacketDropTable_;
193  }
194  else
195  {
196  pAcceptTables = &unicastAcceptTables_;
197  pDropTables = &unicastDropTables_;
198 
199  pAcceptInfos = &unicastAcceptInfos_;
200  pDropInfos = &unicastDropInfos_;
201 
202  pMutexAcceptTable = &mutexUnicastPacketAcceptTable_;
203  pMutexDropTable = &mutexUnicastPacketDropTable_;
204  }
205 
206  // detetmine the relevant queue based on priority
207  std::uint8_t u8QueueIndex{priorityToQueue(priority)};
208 
209  if(action == InboundAction::ACCEPT_GOOD)
210  {
211  std::lock_guard<std::mutex> m(*pMutexAcceptTable);
212 
213  auto iter = (*pAcceptInfos)[u8QueueIndex].find(src);
214 
215  if(iter == (*pAcceptInfos)[u8QueueIndex].end())
216  {
217  iter = (*pAcceptInfos)[u8QueueIndex].insert({src,{}}).first;
218 
219 
220  (*pAcceptTables)[u8QueueIndex]->addRow(src,
221  {Any{src},
222  Any{0L},
223  Any{0L}});
224  }
225 
226  auto & bytes = std::get<ACCEPT_COLUMN_NUM_BYTES_RX-1>(iter->second);
227 
228  bytes += size;
229 
230  (*pAcceptTables)[u8QueueIndex]->setCell(src,
231  ACCEPT_COLUMN_NUM_BYTES_RX,
232  Any{bytes});
233  }
234  else
235  {
236  std::lock_guard<std::mutex> m(*pMutexDropTable);
237 
238  auto iter = (*pDropInfos)[u8QueueIndex].find(src);
239 
240  if(iter == (*pDropInfos)[u8QueueIndex].end())
241  {
242  iter = (*pDropInfos)[u8QueueIndex].insert({src,{}}).first;
243 
244  (*pDropTables)[u8QueueIndex]->addRow(src,
245  {Any{src},
246  Any{0L},
247  Any{0L},
248  Any{0L},
249  Any{0L},
250  Any{0L},
251  Any{0L},
252  Any{0L},
253  Any{0L},
254  Any{0L},
255  Any{0L},
256  Any{0L},
257  Any{0L}});
258  }
259 
260  switch(action)
261  {
263  {
264  auto & bytes = std::get<DROP_COLUMN_BAD_CONTROL-1>(iter->second);
265 
266  bytes += size;
267 
268  (*pDropTables)[u8QueueIndex]->setCell(src,
269  DROP_COLUMN_BAD_CONTROL,
270  Any{bytes});
271  }
272  break;
273 
276  {
277  auto & bytes = std::get<DROP_COLUMN_SLOT_ERROR-1>(iter->second);
278 
279  bytes += size;
280 
281  (*pDropTables)[u8QueueIndex]->setCell(src,
282  DROP_COLUMN_SLOT_ERROR,
283  Any{bytes});
284  }
285  break;
286 
288  {
289  auto & bytes = std::get<DROP_COLUMN_MISS_FRAGMENT-1>(iter->second);
290 
291  bytes += size;
292 
293  (*pDropTables)[u8QueueIndex]->setCell(src,
294  DROP_COLUMN_MISS_FRAGMENT,
295  Any{bytes});
296  }
297  break;
298 
300  {
301  auto & bytes = std::get<DROP_COLUMN_BAD_SPECTRUM_QUERY-1>(iter->second);
302 
303  bytes += size;
304 
305  (*pDropTables)[u8QueueIndex]->setCell(src,
306  DROP_COLUMN_BAD_SPECTRUM_QUERY,
307  Any{bytes});
308  }
309  break;
310 
312  {
313  auto & bytes = std::get<DROP_COLUMN_SINR-1>(iter->second);
314 
315  bytes += size;
316 
317  (*pDropTables)[u8QueueIndex]->setCell(src,
318  DROP_COLUMN_SINR,
319  Any{bytes});
320  }
321  break;
322 
324  {
325  auto & bytes = std::get<DROP_COLUMN_REG_ID-1>(iter->second);
326 
327  bytes += size;
328 
329  (*pDropTables)[u8QueueIndex]->setCell(src,
330  DROP_COLUMN_REG_ID,
331  Any{bytes});
332  }
333  break;
334 
336  {
337  auto & bytes = std::get<DROP_COLUMN_DST_MAC-1>(iter->second);
338 
339  bytes += size;
340 
341  (*pDropTables)[u8QueueIndex]->setCell(src,
342  DROP_COLUMN_DST_MAC,
343  Any{bytes});
344  }
345  break;
347  {
348  auto & bytes = std::get<DROP_COLUMN_TOO_LONG-1>(iter->second);
349 
350  bytes += size;
351 
352  (*pDropTables)[u8QueueIndex]->setCell(src,
353  DROP_COLUMN_TOO_LONG,
354  Any{bytes});
355  }
356  break;
358  {
359  auto & bytes = std::get<DROP_COLUMN_FREQUENCY-1>(iter->second);
360 
361  bytes += size;
362 
363  (*pDropTables)[u8QueueIndex]->setCell(src,
364  DROP_COLUMN_FREQUENCY,
365  Any{bytes});
366  }
367  break;
368 
369  default:
370  break;
371  }
372  }
373 }
374 
375 
377  NEMId dst,
378  Priority priority,
379  size_t size,
380  OutboundAction action)
381 {
382  TableArray * pAcceptTables{};
383  TableArray * pDropTables{};
384 
385  AcceptInfoArrary * pAcceptInfos{};
386  DropInfoArrary * pDropInfos{};
387 
388  std::mutex * pMutexAcceptTable = {};
389  std::mutex * pMutexDropTable = {};
390 
391  if(dst == NEM_BROADCAST_MAC_ADDRESS)
392  {
393  pAcceptTables = &broadcastAcceptTables_;
394  pDropTables = &broadcastDropTables_;
395 
396  pAcceptInfos = &broadcastAcceptInfos_;
397  pDropInfos = &broadcastDropInfos_;
398 
399  pMutexAcceptTable = &mutexBroadcastPacketAcceptTable_;
400  pMutexDropTable = &mutexBroadcastPacketDropTable_;
401  }
402  else
403  {
404  pAcceptTables = &unicastAcceptTables_;
405  pDropTables = &unicastDropTables_;
406 
407  pAcceptInfos = &unicastAcceptInfos_;
408  pDropInfos = &unicastDropInfos_;
409 
410  pMutexAcceptTable = &mutexUnicastPacketAcceptTable_;
411  pMutexDropTable = &mutexUnicastPacketDropTable_;
412  }
413 
414  // detetmine the relevant queue based on priority
415  std::uint8_t u8QueueIndex{priorityToQueue(priority)};
416 
417 
418  if(action == OutboundAction::ACCEPT_GOOD)
419  {
420  std::lock_guard<std::mutex> m(*pMutexAcceptTable);
421 
422  auto iter = (*pAcceptInfos)[u8QueueIndex].find(src);
423 
424  if(iter == (*pAcceptInfos)[u8QueueIndex].end())
425  {
426  iter = (*pAcceptInfos)[u8QueueIndex].insert({src,{}}).first;
427 
428 
429  (*pAcceptTables)[u8QueueIndex]->addRow(src,
430  {Any{src},
431  Any{0L},
432  Any{0L}});
433  }
434 
435  auto & bytes = std::get<ACCEPT_COLUMN_NUM_BYTES_TX-1>(iter->second);
436 
437  bytes += size;
438 
439  (*pAcceptTables)[u8QueueIndex]->setCell(src,
440  ACCEPT_COLUMN_NUM_BYTES_TX,
441  Any{bytes});
442  }
443  else
444  {
445  std::lock_guard<std::mutex> m(*pMutexDropTable);
446 
447  auto iter = (*pDropInfos)[u8QueueIndex].find(src);
448 
449  if(iter == (*pDropInfos)[u8QueueIndex].end())
450  {
451  iter = (*pDropInfos)[u8QueueIndex].insert({src,{}}).first;
452 
453  (*pDropTables)[u8QueueIndex]->addRow(src,
454  {Any{src},
455  Any{0L},
456  Any{0L},
457  Any{0L},
458  Any{0L},
459  Any{0L},
460  Any{0L},
461  Any{0L},
462  Any{0L},
463  Any{0L},
464  Any{0L},
465  Any{0L},
466  Any{0L}});
467  }
468 
469  switch(action)
470  {
472  {
473  auto & bytes = std::get<DROP_COLUMN_TOO_BIG-1>(iter->second);
474 
475  bytes += size;
476 
477  (*pDropTables)[u8QueueIndex]->setCell(src,
478  DROP_COLUMN_TOO_BIG,
479  Any{bytes});
480  }
481  break;
483  {
484  auto & bytes = std::get<DROP_COLUMN_QUEUE_OVERFLOW-1>(iter->second);
485 
486  bytes += size;
487 
488  (*pDropTables)[u8QueueIndex]->setCell(src,
489  DROP_COLUMN_QUEUE_OVERFLOW,
490  Any{bytes});
491  }
492  break;
494  {
495  auto & bytes = std::get<DROP_COLUMN_FLOW_CONTROL-1>(iter->second);
496 
497  bytes += size;
498 
499  (*pDropTables)[u8QueueIndex]->setCell(src,
500  DROP_COLUMN_FLOW_CONTROL,
501  Any{bytes});
502  }
503  break;
504 
505  default:
506  break;
507  }
508  }
509 }
510 
512  const MessageComponents & components,
513  OutboundAction action)
514 {
515  for(const auto & component : components)
516  {
517  outbound(src,
518  component.getDestination(),
519  component.getPriority(),
520  component.getData().size(),
521  action);
522  }
523 }
void outbound(NEMId src, NEMId dst, Priority priority, size_t size, OutboundAction action) override
void inbound(NEMId src, const MessageComponent &component, InboundAction action) override
A StatisticTablePublisher produces two dimensional tables of Anys.
constexpr NEMId NEM_BROADCAST_MAC_ADDRESS
Definition: types.h:69
union EtherAddr dst
Definition: netutils.h:390
std::uint8_t Priority
Definition: types.h:64
struct EtherAddrBytes bytes
Definition: netutils.h:390
The StatisticRegistrar allows NEM layers to register statistics and statistic tables. Statistics and Statistic tables are owned by the emulator framework and a borrowed reference is returned to the registering NEM layer.
std::vector< std::string > StatisticTableLabels
std::list< MessageComponent > MessageComponents
StatisticTable< Key, Compare, scolumn > * registerTable(const std::string &sName, const StatisticTableLabels &labels, const StatisticProperties &properties=StatisticProperties::NONE, const std::string &sDescription="")
std::uint16_t NEMId
Definition: types.h:52
union EtherAddr src
Definition: netutils.h:391
void registerStatistics(StatisticRegistrar &registrar)
std::uint8_t priorityToQueue(Priority priority)
Definition: priority.h:53
The Any class can contain an instance of one of any type in its support type set. ...
Definition: any.h:49
Holds a message component that may be all or part of a data or control message.