45 const char * pzLayerName {
"NeighborManager"};
53 pPlatformService_{pPlatformService},
54 pMACLayer_{pMACLayer},
55 wmmManager_{id, pPlatformService, pMACLayer},
56 nbrTimeOutMicroseconds_{},
57 lastOneHopNbrListTxTime_{},
58 RNDZeroToOne_{0.0f, 1.0f},
84 auto nbrEntry = oneHopNbrMap_.find(src);
88 if(nbrEntry != oneHopNbrMap_.end())
90 fResult = nbrEntry->second.getHiddenChannelActivity();
102 auto nbrEntry = oneHopNbrMap_.find(src);
106 if(nbrEntry != oneHopNbrMap_.end())
108 fResult = nbrEntry->second.getEstimatedNumCommonNeighbors();
119 auto nbrEntry = oneHopNbrMap_.find(src);
123 if(nbrEntry != oneHopNbrMap_.end())
126 fResult = fEstimatedNumOneHopNeighbors_ - nbrEntry->second.getEstimatedNumCommonNeighbors();
144 auto nbrEntry = oneHopNbrMap_.find(src);
146 if(nbrEntry != oneHopNbrMap_.end())
152 return Microseconds::zero();
161 return fEstimatedNumOneHopNeighbors_;
169 return fEstimatedNumTwoHopNeighbors_;
177 return totalOneHopUtilizationMicroseconds_;
185 return totalTwoHopUtilizationMicroseconds_;
193 return averageMessageDurationMicroseconds_;
202 return fLocalNodeTx_;
210 return numTotalActiveOneHopNeighbors_;
218 return fAverageRxPowerPerMessageMilliWatts_;
226 if(sumHiddenPackets_ > 0)
228 return fHiddenRxPowerMilliWatts_ / sumHiddenPackets_;
241 if(sumCommonPackets_ > 0)
243 return fCommonRxPowerMilliWatts_ / sumCommonPackets_;
257 const float fRandom{RNDZeroToOne_()};
260 const float fResult{getRandomRxPowerMilliWatts_i(src, fRandom, commonProbabilityMapMap_, commonNbrAvgRxPowerMwMap_)};
264 "MACI %03hu %s::%s: src %hu, random %5.4f, result %5.4f",
281 const float fRandom{RNDZeroToOne_()};
284 const float fResult{getRandomRxPowerMilliWatts_i(src,
286 hiddenProbabilityMapMap_,
287 hiddenNbrAvgRxPowerMwMap_)};
291 "MACI %03hu %s::%s: src %hu, random %5.4f, result %6.4f mW",
306 EMANE::Models::IEEE80211ABG::NeighborManager::getRandomRxPowerMilliWatts_i(
NEMId src,
308 const ProbabilityPairMapMap & pmap,
309 const RxPowerMap & rmap)
const 315 auto pmmiter = pmap.find(
src);
318 if(pmmiter != pmap.end())
321 for(
auto & piter : pmmiter->second)
324 if((fRandom >= piter.second.first) && (fRandom <= piter.second.second))
327 auto riter = rmap.find(piter.first);
330 if(riter != rmap.end())
333 fResult = riter->second;
344 "MACI %03hu %s::%s: src %hu, random %5.4f, result %6.4f",
360 return lastOneHopNbrListTxTime_;
368 nbrTimeOutMicroseconds_ = timeOutMicroseconds;
374 lastResetTime_ = Clock::now();
381 const TimePoint currentTime{Clock::now()};
386 if(nbrTimeOutMicroseconds_ != Microseconds::zero())
389 if(flushOneHopNeighbors_i(currentTime, nbrTimeOutMicroseconds_) ==
true)
392 sendOneHopNbrListEvent_i();
396 if(flushTwoHopNeighbors_i(currentTime, nbrTimeOutMicroseconds_) ==
true)
403 for(
auto & nbrEntry :oneHopNbrMap_)
406 nbrEntry.second.storeUtilization();
410 calculateBwUtilization_i(deltaTMicroseconds);
413 for(
auto & nbr2Entry : twoHopNbrMap_)
416 nbr2Entry.second.resetUtilization();
422 lastResetTime_ = currentTime;
432 float fRxPowerMilliWatts,
435 std::uint8_t u8Category)
440 auto nbrResult = addOneHopNeighbor_i(src);
443 if(nbrResult.second ==
true)
450 nbrResult.first->second.updateChannelActivity(durationMicroseconds, type, timePoint, fRxPowerMilliWatts);
466 sendOneHopNbrListEvent_i();
477 float fRxPowerMilliWatts,
480 std::uint8_t u8Category)
488 if(oneHopNbrMap_.find(origin) == oneHopNbrMap_.end())
491 auto nbr2Result = addTwoHopNeighbor_i(origin);
494 nbr2Result.first->second.updateChannelActivity(durationMicroseconds, timePoint);
499 auto nbrResult = addOneHopNeighbor_i(src);
502 if(nbrResult.second ==
true)
509 nbrResult.first->second.updateChannelActivity(Microseconds::zero(), type, timePoint, fRxPowerMilliWatts);
524 sendOneHopNbrListEvent_i();
540 NEMId eventSource{
event.getEventSource()};
546 auto nbrEntry = oneHopNbrMap_.find(eventSource);
549 if(nbrEntry != oneHopNbrMap_.end())
553 "MACI %03hu %s::%s: update 1hop_nbr_list for nbr %hu, %zd entries",
561 nbrEntry->second.setOneHopNeighbors(nbrSet);
567 "MACI %03hu %s::%s: unknown nbr %hu, 1hop_nbr_list with %zd entries will be cached",
577 auto iter = cachedOneHopNbrSetMap_.find(eventSource);
580 if(iter == cachedOneHopNbrSetMap_.end())
583 cachedOneHopNbrSetMap_[eventSource] = nbrSet;
587 "MACI %03hu %s::%s: added event cache 1hop_nbr_list for nbr %hu, %zd entries",
597 iter->second = nbrSet;
601 "MACI %03hu %s::%s: updated event cache 1hop_nbr_list for nbr %hu, %zd entries",
614 "MACI %03hu %s::%s: 1hop neighbors event error %s",
629 return utilizationRatioVector_;
636 EMANE::Models::IEEE80211ABG::NeighborManager::calculateBwUtilization_i(
const Microseconds & deltaTMicroseconds)
644 for(
auto & nbrEntry : oneHopNbrMap_)
650 if(utilizationMicroseconds > Microseconds::zero())
653 totalOneHopUtilizationMicroseconds_ += utilizationMicroseconds;
656 oneHopUtilizationMap_[nbrEntry.first] = utilizationMicroseconds;
660 "MACI %03hu %s::%s: 1hop_nbr %hu, 1hop_bw %lf, total_1hop_bw %lf",
665 std::chrono::duration_cast<
DoubleSeconds>(utilizationMicroseconds).count(),
666 std::chrono::duration_cast<
DoubleSeconds>(totalOneHopUtilizationMicroseconds_).count());
669 if(nbrEntry.first == id_)
672 utilizationThisNEMMicroseconds_ = utilizationMicroseconds;
687 if(totalOneHopUtilizationMicroseconds_ != Microseconds::zero())
689 fLocalNodeTx_ =
getRatio(utilizationThisNEMMicroseconds_, totalOneHopUtilizationMicroseconds_);
696 #ifdef VERY_VERBOSE_LOGGING 699 "MACI %03hu %s::%s: %zd active 1hop_nbrs, " 700 "1hop_total_bw %lf, total_1hop_pkts %zd, total_1hop_pwr %5.4f mW, local tx %5.4f",
704 oneHopUtilizationMap_.size(),
705 std::chrono::duration_cast<
DoubleSeconds>(totalOneHopUtilizationMicroseconds_).count(),
706 totalOneHopNumPackets_,
707 fTotalRxPowerMilliWatts_,
712 for(
const auto & nbr2Entry : twoHopNbrMap_)
716 const Microseconds utilizationMicroseconds{nbr2Entry.second.getUtilizationMicroseconds()};
719 if(utilizationMicroseconds > Microseconds::zero())
722 twoHopUtilizationMap_[nbr2Entry.first] = utilizationMicroseconds;
725 totalTwoHopUtilizationMicroseconds_ += utilizationMicroseconds;
728 totalTwoHopNumPackets_ += nbr2Entry.second.getNumberOfPackets();
732 "MACI %03hu %s::%s: 2hop_nbr %hu, 2hop_bw %lf, total_2hop_bw %lf",
737 std::chrono::duration_cast<
DoubleSeconds>(utilizationMicroseconds).count(),
738 std::chrono::duration_cast<
DoubleSeconds>(totalTwoHopUtilizationMicroseconds_).count());
743 #ifdef VERY_VERBOSE_LOGGING 746 "MACI %03hu %s::%s: %zd active 2hop_nbrs, total_2hop_bw %lf, total_pkts %zd",
750 twoHopUtilizationMap_.size(),
751 std::chrono::duration_cast<
DoubleSeconds>(totalTwoHopUtilizationMicroseconds_).count(),
752 totalTwoHopNumPackets_);
756 if(totalTwoHopNumPackets_ > 0)
762 averageUtilizationPerTwoHopNbrMicroseconds_ =
767 for(
const auto & twoHopUtilization : twoHopUtilizationMap_)
770 const float A = getA_i(twoHopUtilization.second, averageUtilizationPerTwoHopNbrMicroseconds_);
777 "MACI %03hu %s::%s: 2hop A = %5.4f, B = %5.4f",
785 fEstimatedNumTwoHopNeighbors_ = round(B);
790 if(totalOneHopNumPackets_ > 0)
793 numTotalActiveOneHopNeighbors_ = oneHopUtilizationMap_.size();
796 averageUtilizationPerOneHopNbrMicroseconds_ =
801 fAverageRxPowerPerMessageMilliWatts_ = fTotalRxPowerMilliWatts_ / totalOneHopNumPackets_;
804 averageMessageDurationMicroseconds_ =
805 std::chrono::duration_cast<Microseconds>(
DoubleSeconds{(((totalOneHopUtilizationMicroseconds_.count() -
806 utilizationThisNEMMicroseconds_.count()) * (1.0f / totalOneHopNumPackets_)) /
USEC_PER_SEC_F)});
808 float A1{}, A2{}, B1{};
811 for(
auto & nbrEntry1 : oneHopNbrMap_)
818 averageUtilizationPerOneHopNbrMicroseconds_);
820 B1 += powf(A1, 2.0f);
823 if(nbrEntry1.first != id_)
828 Microseconds hiddenUtilizationMicroseconds{};
831 float fCommonRxPowerMilliWatts{};
834 float fHiddenRxPowerMilliWatts{};
837 size_t numCommonPackets{};
840 size_t numHiddenPackets{};
843 const NbrSet nbrOneHopNbrSet = nbrEntry1.second.getOneHopNeighbors();
845 #ifdef VERBOSE_LOGGIN 846 std::stringstream ss;
849 for(
auto & nbr : nbrOneHopNbrSet)
851 if(nbr == nbrOneHopNbrSet.begin())
863 "MACI %03hu %s::%s: nbr %hu has %zu 1hop_nbrs: %s",
868 nbrOneHopNbrSet.size(),
879 for(
auto & nbrEntry2 : oneHopNbrMap_)
882 if(nbrOneHopNbrSet.find(nbrEntry2.first) != nbrOneHopNbrSet.end())
887 A2 = getA_i(nbrEntry2.second.getUtilizationMicroseconds(typeMask),
888 averageUtilizationPerOneHopNbrMicroseconds_);
893 const float fRxPowermW{nbrEntry2.second.getRxPowerMilliWatts(typeMask)};
896 const size_t numPackets{nbrEntry2.second.getNumberOfPackets(typeMask)};
900 "MACI %03hu %s::%s: our nbr %hu is common with nbr %hu, pkts %zd, rxpwr %6.4f mW",
910 commonNbrs.insert(nbrEntry2.first);
913 commonNbrAvgRxPowerMwMap_[nbrEntry2.first] = numPackets > 0 ? fRxPowermW / numPackets : 0;
916 fCommonRxPowerMilliWatts += fRxPowermW;
919 numCommonPackets += numPackets;
928 hiddenUtilizationMicroseconds += nbrEntry2.second.getUtilizationMicroseconds(typeMask);
931 const float fRxPowermW{nbrEntry2.second.getRxPowerMilliWatts(typeMask)};
934 const size_t numPackets{nbrEntry2.second.getNumberOfPackets(typeMask)};
938 "MACI %03hu %s::%s: nbr %hu is hidden from nbr %hu, pkts %zd, rxpwr %6.4f mW",
948 hiddenNbrs.insert(nbrEntry2.first);
951 hiddenNbrAvgRxPowerMwMap_[nbrEntry2.first] = numPackets > 0 ? fRxPowermW / numPackets : 0;
954 fHiddenRxPowerMilliWatts += fRxPowermW;
957 numHiddenPackets += numPackets;
962 nbrEntry1.second.setCommonNeighbors(commonNbrs);
965 nbrEntry1.second.setHiddenNeighbors(hiddenNbrs);
968 const float H{getH_i(hiddenUtilizationMicroseconds, deltaTMicroseconds)};
972 "MACI %03hu %s::%s: 1hop_nbr %hu, A1 = %5.4f, A2 = %5.4f, B1 = %5.4f, B2 = %5.4f, H = %5.4f",
980 nbrEntry1.second.setEstimatedNumCommonNeighbors(round(B2));
983 nbrEntry1.second.setAverageCommonRxPowerMilliWatts(numCommonPackets > 0.0f ?
984 fCommonRxPowerMilliWatts / numCommonPackets : 0.0f);
987 nbrEntry1.second.setHiddenChannelActivity(H);
990 nbrEntry1.second.setAverageHiddenRxPowerMilliWatts(numHiddenPackets > 0.0f ?
991 fHiddenRxPowerMilliWatts / numHiddenPackets : 0.0f);
994 sumCommonPackets_ += numCommonPackets;
997 sumHiddenPackets_ += numHiddenPackets;
1000 fCommonRxPowerMilliWatts_ += fCommonRxPowerMilliWatts;
1003 fHiddenRxPowerMilliWatts_ += fHiddenRxPowerMilliWatts;
1009 setCommonAndHiddenProbability_i();
1012 fEstimatedNumOneHopNeighbors_ = round(B1);
1016 "MACI %03hu %s::%s: est nbrs [1hop %5.4f, 2hop %5.4f], active nbrs %zd, elapsed time %lf",
1020 fEstimatedNumOneHopNeighbors_,
1021 fEstimatedNumTwoHopNeighbors_,
1022 numTotalActiveOneHopNeighbors_,
1023 std::chrono::duration_cast<
DoubleSeconds>(deltaTMicroseconds).count());
1030 EMANE::Models::IEEE80211ABG::NeighborManager::resetCounters_i()
1034 fLocalNodeTx_ = 0.0f;
1036 totalOneHopNumPackets_ = 0;
1038 totalTwoHopNumPackets_ = 0;
1040 sumCommonPackets_ = 0;
1042 sumHiddenPackets_ = 0;
1044 numTotalActiveOneHopNeighbors_ = 0;
1046 fTotalRxPowerMilliWatts_ = 0.0f;
1048 fEstimatedNumOneHopNeighbors_ = 0.0f;
1050 fEstimatedNumTwoHopNeighbors_ = 0.0f;
1052 fAverageRxPowerPerMessageMilliWatts_ = 0.0f;
1054 fHiddenRxPowerMilliWatts_ = 0.0f;
1056 fCommonRxPowerMilliWatts_ = 0.0f;
1058 averageMessageDurationMicroseconds_ = Microseconds::zero();
1060 totalOneHopUtilizationMicroseconds_ = Microseconds::zero();
1062 totalTwoHopUtilizationMicroseconds_ = Microseconds::zero();
1064 averageUtilizationPerOneHopNbrMicroseconds_ = Microseconds::zero();
1066 averageUtilizationPerTwoHopNbrMicroseconds_ = Microseconds::zero();
1068 utilizationThisNEMMicroseconds_ = Microseconds::zero();
1070 oneHopUtilizationMap_.clear();
1072 twoHopUtilizationMap_.clear();
1078 EMANE::Models::IEEE80211ABG::NeighborManager::flushOneHopNeighbors_i(
const TimePoint & currentTime,
1084 size_t numExpired{};
1086 for(NeighborEntryMap::iterator iter = oneHopNbrMap_.begin(); iter != oneHopNbrMap_.end(); )
1090 std::chrono::duration_cast<
Microseconds>(currentTime - iter->second.getLastActivityTime());
1093 if(ageMicroseconds > timeOutMicroseconds)
1098 "MACI %03hu %s::%s: remove 1hop_nbr %hu, age %lf, %zd nbrs remaining",
1103 std::chrono::duration_cast<
DoubleSeconds>(ageMicroseconds).count(),
1104 oneHopNbrMap_.size() - 1);
1106 pStatisticOneHopNbrTable_->
deleteRow(iter->first);
1109 oneHopNbrMap_.erase(iter++);
1122 return numExpired != 0;
1128 EMANE::Models::IEEE80211ABG::NeighborManager::flushTwoHopNeighbors_i(
const TimePoint & currentTime,
1134 size_t numExpired{};
1137 for(Neighbor2HopEntryMap::iterator iter = twoHopNbrMap_.begin(); iter != twoHopNbrMap_.end(); )
1141 std::chrono::duration_cast<
Microseconds>(currentTime - iter->second.getLastActivityTime());
1144 if(ageMicroseconds > timeOutMicroseconds)
1149 "MACI %03hu %s::%s: remove 2hop_nbr %hu, age %lf, %zd nbrs remaining",
1154 std::chrono::duration_cast<
DoubleSeconds>(ageMicroseconds).count(),
1155 twoHopNbrMap_.size() - 1);
1157 pStatisticTwoHopNbrTable_->
deleteRow(iter->first);
1160 twoHopNbrMap_.erase(iter++);
1174 return numExpired != 0;
1181 EMANE::Models::IEEE80211ABG::NeighborManager::sendOneHopNbrListEvent_i()
1188 for(
auto & nbrEntry : oneHopNbrMap_)
1190 nbrSet.insert(nbrEntry.first);
1197 "MACI %03hu %s::%s: sending list of %zd 1hop_nbrs",
1211 lastOneHopNbrListTxTime_ = Clock::now();
1219 EMANE::Models::IEEE80211ABG::NeighborManager::NeighborEntryInsertResult
1220 EMANE::Models::IEEE80211ABG::NeighborManager::addOneHopNeighbor_i(
NEMId src)
1225 auto nbrResult = oneHopNbrMap_.insert(std::make_pair(src,
NeighborEntry()));
1227 if(nbrResult.second ==
true)
1231 "MACI %03hu %s::%s: added 1hop_nbr %hu, %zd total nbrs",
1236 oneHopNbrMap_.size());
1238 pStatisticOneHopNbrTable_->
addRow(src,{
Any{src}});
1244 auto iter = cachedOneHopNbrSetMap_.find(src);
1246 if(iter != cachedOneHopNbrSetMap_.end())
1250 "MACI %03hu %s::%s: copied 1hop_nbr_list from cache for nbr %hu, has %zd total nbrs",
1255 iter->second.size());
1258 nbrResult.first->second.setOneHopNeighbors(iter->second);
1264 "MACI %03hu %s::%s: no 1hop_nbr_list cache for nbr %hu, must wait for event update",
1275 "MACI %03hu %s::%s: existing 1hop_nbr %hu, keep existing 1hop_nbr_list",
1287 EMANE::Models::IEEE80211ABG::NeighborManager::Neighbor2HopEntryInsertResult
1288 EMANE::Models::IEEE80211ABG::NeighborManager::addTwoHopNeighbor_i(
NEMId src)
1293 auto nbr2Result = twoHopNbrMap_.insert(std::make_pair(src,
Neighbor2HopEntry()));
1295 if(nbr2Result.second ==
true)
1299 "MACI %03hu %s::%s: added 2hop_nbr %hu, %zd total nbrs",
1304 twoHopNbrMap_.size());
1306 pStatisticTwoHopNbrTable_->
addRow(src,{
Any{src}});
1315 "MACI %03hu %s::%s: existing 2hop_nbr %hu, %zd total nbrs",
1320 twoHopNbrMap_.size());
1330 EMANE::Models::IEEE80211ABG::NeighborManager::getA_i(
const Microseconds & utilizationMicroseconds,
1335 const float A{getChannelActivity_i(utilizationMicroseconds, avgUtilizationMicroseconds)};
1351 EMANE::Models::IEEE80211ABG::NeighborManager::getC_i(
const Microseconds & utilizationMicroseconds,
1356 const float C{getChannelActivity_i(utilizationMicroseconds, deltaTMicroseconds)};
1372 EMANE::Models::IEEE80211ABG::NeighborManager::getH_i(
const Microseconds & utilizationMicroseconds,
1377 const float H{getChannelActivity_i(utilizationMicroseconds, deltaTMicroseconds)};
1393 EMANE::Models::IEEE80211ABG::NeighborManager::getChannelActivity_i(
const Microseconds & utilizationMicroseconds,
1399 if(deltaTMicroseconds == Microseconds::zero())
1405 return getRatio(utilizationMicroseconds, deltaTMicroseconds);
1411 EMANE::Models::IEEE80211ABG::NeighborManager::setCommonAndHiddenProbability_i()
1414 for(
auto & oneHopUtilization : oneHopUtilizationMap_)
1417 if(oneHopUtilization.first != id_)
1421 totalOneHopUtilizationMicroseconds_ -
1422 utilizationThisNEMMicroseconds_ -
1423 oneHopUtilization.second};
1426 if(adjustedUtililizationMicroseconds > Microseconds::zero())
1429 auto niter = oneHopNbrMap_.find(oneHopUtilization.first);
1431 if(niter != oneHopNbrMap_.end())
1434 const NbrSet commonNbrs = niter->second.getCommonNeighbors();
1437 const NbrSet hiddenNbrs = niter->second.getHiddenNeighbors();
1440 NbrUtilizationMap adjustedUtilzationMap = oneHopUtilizationMap_;
1443 adjustedUtilzationMap.erase(id_);
1446 adjustedUtilzationMap.erase(oneHopUtilization.first);
1449 commonProbabilityMapMap_[oneHopUtilization.first] = setProbability_i(oneHopUtilization.first,
1450 adjustedUtilzationMap,
1451 adjustedUtililizationMicroseconds,
1456 hiddenProbabilityMapMap_[oneHopUtilization.first] = setProbability_i(oneHopUtilization.first,
1457 adjustedUtilzationMap,
1458 adjustedUtililizationMicroseconds,
1469 EMANE::Models::IEEE80211ABG::NeighborManager::ProbabilityPairMap
1471 const NbrUtilizationMap & map,
1476 ProbabilityPairMap probabilityMap;
1478 NbrUtilizationMap adjustedUtilizationMap;
1480 Microseconds utilizationMicroseconds{rUtilizationMicroseconds};
1482 for(
auto & utilization : map)
1484 if(nbrSet.find(utilization.first) != nbrSet.end())
1488 "MACI %03hu %s::%s_%s: src %hu, is %s w/r to nbr %hu",
1498 adjustedUtilizationMap[utilization.first] = utilization.second;
1504 "MACI %03hu %s::%s_%s: src %hu, is not %s w/r to nbr %hu, ignore",
1514 utilizationMicroseconds -= utilization.second;
1519 if(utilizationMicroseconds > Microseconds::zero())
1524 size_t num{adjustedUtilizationMap.size()};
1527 for(NbrUtilizationMap::iterator iter = adjustedUtilizationMap.begin(); iter != adjustedUtilizationMap.end(); ++iter, --num)
1533 p2 +=
getRatio(iter->second, utilizationMicroseconds);
1544 "MACI %03hu %s::%s_%s: src %hu, nbr %hu, p1 %5.4f, p2 %5.4f",
1555 probabilityMap[iter->first] = ProbabilityPair(p1, p2);
1562 return probabilityMap;
1569 pStatisticOneHopNbrTable_ = statisticRegistrar.
registerTable<
NEMId>(
"OneHopNeighborTable",
1572 "Current One Hop Neighbors");
1574 pStatisticTwoHopNbrTable_ = statisticRegistrar.
registerTable<
NEMId>(
"TwoHopNeighborTable",
1577 "Current Two Hop Neighbors");
void updateTwoHopNbrHighWaterMark(size_t num)
set the two hop nbr high water mark
float getLocalNodeTx() const
size_t getTotalActiveOneHopNeighbors() const
std::string Serialization
float getAverageRxPowerPerMessageMilliWatts() const
void incrementRxOneHopNbrListEventCount()
increment number rx one hop nbr list events
void handleOneHopNeighborsEvent(const Serialization &serialization)
SerializationException is thrown when an exception occurs during serialization or deserialization of ...
UtilizationRatioVector getUtilizationRatios(const Microseconds &deltaTMicroseconds)
#define LOGGER_VERBOSE_LOGGING(logger, level, fmt, args...)
void registerStatistics(StatisticRegistrar &statisticRegistrar)
void setNeighborTimeoutMicroseconds(const Microseconds &timeOutMicroseconds)
void incrementTxOneHopNbrListEventCount()
increment number tx one hop nbr list events
Defines a 1 hop nbr and its bandwidth utilization.
float getNumberOfEstimatedTwoHopNeighbors() const
std::vector< UtilizationRatioPair > UtilizationRatioVector
Microseconds getAllUtilizationMicroseconds(NEMId src) const
const std::uint8_t MSG_TYPE_MASK_BROADCAST
const std::uint8_t MSG_TYPE_MASK_ALL_DATA
float getHiddenChannelActivity(NEMId src) const
void updateLocalActivity(std::uint8_t u8Category, const Microseconds &durationMicroseconds)
float getAverageRxPowerPerMessageCommonNodesMilliWatts() const
EMANE::NetworkAdapterException __attribute__
float getNumberOfEstimatedCommonNeighbors(NEMId src) const
void updateCtrlChannelActivity(NEMId src, NEMId origin, std::uint8_t type, float fRxPowerMilliWatts, const TimePoint &tvTime, const Microseconds &duration, std::uint8_t u8Category)
const char * what() const
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.
StatisticTable< Key, Compare, scolumn > * registerTable(const std::string &sName, const StatisticTableLabels &labels, const StatisticProperties &properties=StatisticProperties::NONE, const std::string &sDescription="")
void updateOneHopNbrHighWaterMark(size_t num)
set the one hop nbr high water mark
float getRandomRxPowerCommonNodesMilliWatts(NEMId src)
void setCategories(std::uint8_t u8NumCategories)
std::chrono::microseconds Microseconds
std::chrono::duration< double > DoubleSeconds
Microseconds getTotalOneHopUtilizationMicroseconds() const
const NbrSet & getNeighbors() const
NeighborManager(NEMId id, PlatformServiceProvider *pPlatformService, MACLayer *pMgr)
float getRatio(const EMANE::Microseconds &d1, const EMANE::Microseconds d2)
float getNumberOfEstimatedHiddenNeighbors(NEMId src) const
void setNumCategories(const std::uint8_t u8NumCategories)
const float USEC_PER_SEC_F
std::set< EMANE::NEMId > NbrSet
void addRow(const Key &key, const std::vector< Any > &anys={})
float getNumberOfEstimatedOneHopNeighbors() const
Microseconds getTotalTwoHopUtilizationMicroseconds() const
void deleteRow(const Key &key)
float getRandomRxPowerHiddenNodesMilliWatts(NEMId src)
const std::uint8_t MSG_TYPE_MASK_UNICAST
Defines a 2 hop nbr and its bandwidth utilization.
Microseconds getAverageMessageDurationMicroseconds() const
Clock::time_point TimePoint
void updateDataChannelActivity(NEMId src, std::uint8_t type, float fRxPowerMilliWatts, const TimePoint &timePoint, const Microseconds &duration, std::uint8_t u8Category)
MACStatistics & getStatistics()
TimePoint getLastOneHopNbrListTxTime() const
#define LOGGER_STANDARD_LOGGING(logger, level, fmt, args...)
The Any class can contain an instance of one of any type in its support type set. ...
virtual void sendEvent(NEMId nemId, const Event &event)=0
void incrementRxOneHopNbrListInvalidEventCount()
increment number rx one hop nbr list invalid events
void updateTotalActivity(std::uint8_t u8Category, const Microseconds &durationMicroseconds)
float getAverageRxPowerPerMessageHiddenNodesMilliWatts() const
IEEE 80211 ABG MAC implementation.
WMMManager::UtilizationRatioVector getUtilizationRatios()