55 const std::string QUEUEMANAGER_PREFIX{
"queue."};
56 const std::string SCHEDULER_PREFIX{
"scheduler."};
67 pScheduler_{pScheduler},
68 pQueueManager_{pQueueManager},
69 pRadioModel_{pRadioModel},
70 bFlowControlEnable_{},
71 u16FlowControlTokens_{},
73 transmitTimedEventId_{},
74 nextMultiFrameTime_{},
81 packetStatusPublisher_{},
82 neighborMetricManager_{
id},
85 &pPlatformServiceProvider->logService(),
86 pRadioServiceProvider,
88 &packetStatusPublisher_,
89 &neighborMetricManager_},
90 flowControlManager_{*pRadioModel},
103 "MACI %03hu TDMA::BaseModel::%s",
113 "Defines whether promiscuous mode is enabled or not." 114 " If promiscuous mode is enabled, all received packets" 115 " (intended for the given node or not) that pass the" 116 " probability of reception check are sent upstream to" 120 configRegistrar.registerNumeric<
bool>(
"flowcontrolenable",
123 "Defines whether flow control is enabled. Flow control only works" 124 " with the virtual transport and the setting must match the setting" 125 " within the virtual transport configuration.");
127 configRegistrar.registerNumeric<std::uint16_t>(
"flowcontroltokens",
130 "Defines the maximum number of flow control tokens" 131 " (packet transmission units) that can be processed from the" 132 " virtual transport without being refreshed. The number of" 133 " available tokens at any given time is coordinated with the" 134 " virtual transport and when the token count reaches zero, no" 135 " further packets are transmitted causing application socket" 136 " queues to backup.");
138 configRegistrar.registerNonNumeric<std::string>(
"pcrcurveuri",
141 "Defines the URI of the Packet Completion Rate (PCR) curve" 142 " file. The PCR curve file contains probability of reception curves" 143 " as a function of Signal to Interference plus Noise Ratio (SINR).");
146 configRegistrar.registerNumeric<std::uint16_t>(
"fragmentcheckthreshold",
149 "Defines the rate in seconds a check is performed to see if any packet" 150 " fragment reassembly efforts should be abandoned.");
152 configRegistrar.registerNumeric<std::uint16_t>(
"fragmenttimeoutthreshold",
155 "Defines the threshold in seconds to wait for another packet fragment" 156 " for an existing reassembly effort before abandoning the effort.");
158 configRegistrar.registerNumeric<
float>(
"neighbormetricdeletetime",
159 ConfigurationProperties::DEFAULT |
162 "Defines the time in seconds of no RF receptions from a given neighbor" 163 " before it is removed from the neighbor table.",
168 configRegistrar.registerNumeric<
float>(
"neighbormetricupdateinterval",
171 "Defines the neighbor table update interval in seconds.",
185 pQueueManager_->setPacketStatusPublisher(&packetStatusPublisher_);
187 pQueueManager_->initialize(registrar);
189 pScheduler_->initialize(registrar);
199 "MACI %03hu TDMA::BaseModel::%s",
206 for(
const auto & item : update)
208 if(item.first ==
"enablepromiscuousmode")
210 bool bPromiscuousMode{item.second[0].asBool()};
214 "MACI %03hu TDMA::BaseModel::%s: %s = %s",
218 bPromiscuousMode ?
"on" :
"off");
222 else if(item.first ==
"flowcontrolenable")
224 bFlowControlEnable_ = item.second[0].asBool();
228 "MACI %03hu TDMA::BaseModel::%s: %s = %s",
232 bFlowControlEnable_ ?
"on" :
"off");
234 else if(item.first ==
"flowcontroltokens")
236 u16FlowControlTokens_ = item.second[0].asUINT16();
240 "MACI %03hu TDMA::BaseModel::%s: %s = %hu",
244 u16FlowControlTokens_);
246 else if(item.first ==
"pcrcurveuri")
248 sPCRCurveURI_ = item.second[0].asString();
252 "MACI %03hu TDMA::BaseModel::%s: %s = %s",
256 sPCRCurveURI_.c_str());
260 else if(item.first ==
"fragmentcheckthreshold")
262 std::chrono::seconds fragmentCheckThreshold{item.second[0].asUINT16()};
266 "MACI %03hu TDMA::BaseModel::%s: %s = %lu",
270 fragmentCheckThreshold.count());
274 else if(item.first ==
"fragmenttimeoutthreshold")
276 std::chrono::seconds fragmentTimeoutThreshold{item.second[0].asUINT16()};
280 "MACI %03hu TDMA::BaseModel::%s: %s = %lu",
284 fragmentTimeoutThreshold.count());
288 else if(item.first ==
"neighbormetricdeletetime")
298 "MACI %03hu TDMA::BaseModel::%s %s = %lf",
302 std::chrono::duration_cast<
DoubleSeconds>(neighborMetricDeleteTimeMicroseconds).count());
304 else if(item.first ==
"neighbormetricupdateinterval")
306 neighborMetricUpdateInterval_ =
311 "MACI %03hu TDMA::BaseModel::%s %s = %lf",
315 std::chrono::duration_cast<
DoubleSeconds>(neighborMetricUpdateInterval_).count());
319 if(!item.first.compare(0,SCHEDULER_PREFIX.size(),SCHEDULER_PREFIX))
321 schedulerConfiguration.push_back(item);
323 else if(!item.first.compare(0,QUEUEMANAGER_PREFIX.size(),QUEUEMANAGER_PREFIX))
325 queueManagerConfiguration.push_back(item);
329 throw makeException<ConfigureException>(
"TDMA::BaseModel: " 330 "Ambiguous configuration item %s.",
336 pQueueManager_->configure(queueManagerConfiguration);
338 pScheduler_->configure(schedulerConfiguration);
346 "MACI %03hu TDMA::BaseModel::%s",
350 pQueueManager_->start();
352 pScheduler_->start();
361 "MACI %03hu TDMA::BaseModel::%s",
365 pQueueManager_->postStart();
367 pScheduler_->postStart();
370 if(bFlowControlEnable_)
373 flowControlManager_.
start(u16FlowControlTokens_);
377 "MACI %03hu TDMA::BaseModel::%s sent a flow control token update," 378 " a handshake response is required to process packets",
385 &neighborMetricManager_),
386 Clock::now() + neighborMetricUpdateInterval_,
387 neighborMetricUpdateInterval_);
396 "MACI %03hu TDMA::BaseModel::%s",
401 if(bFlowControlEnable_)
404 flowControlManager_.
stop();
407 pQueueManager_->stop();
420 "MACI %03hu TDMA::BaseModel::%s",
424 pQueueManager_->destroy();
426 pScheduler_->destroy();
433 "MACI %03hu TDMA::BaseModel::%s",
444 auto now = Clock::now();
448 "MACI %03hu TDMA::BaseModel::%s",
459 "MACI %03hu TDMA::BaseModel::%s: MAC Registration Id %hu does not match our Id %hu, drop.",
466 packetStatusPublisher_.
inbound(pktInfo.getSource(),
468 pktInfo.getPriority(),
478 if(len && pkt.
length() >= len)
487 for(
auto & pControlMessage : msgs)
489 switch(pControlMessage->getId())
493 pReceivePropertiesControlMessage =
499 "MACI %03hu TDMA::BaseModel::%s Receiver Properties Control Message",
507 pFrequencyControlMessage =
513 "MACI %03hu TDMA::BaseModel::%s Frequency Control Message",
523 if(!pReceivePropertiesControlMessage || !pFrequencyControlMessage ||
524 pFrequencyControlMessage->getFrequencySegments().empty())
528 "MACI %03hu TDMA::BaseModel::%s: phy control " 529 "message not provided from src %hu, drop",
532 pktInfo.getSource());
534 packetStatusPublisher_.
inbound(pktInfo.getSource(),
535 baseModelMessage.getMessages(),
542 const auto & frequencySegments = pFrequencyControlMessage->getFrequencySegments();
546 TimePoint startOfReception{pReceivePropertiesControlMessage->getTxTime() +
547 pReceivePropertiesControlMessage->getPropagationDelay() +
552 auto eorSlotInfo = pScheduler_->getSlotInfo(startOfReception +
553 frequencySegment.getDuration());
556 if(eorSlotInfo.u64AbsoluteSlotIndex_ != baseModelMessage.getAbsoluteSlotIndex())
559 auto slotInfo = pScheduler_->getSlotInfo(now);
561 slotStatusTablePublisher_.
update(slotInfo.u32RelativeIndex_,
562 slotInfo.u32RelativeFrameIndex_,
563 slotInfo.u32RelativeSlotIndex_,
565 slotPortionRatio(now,slotInfo.timePoint_));
567 packetStatusPublisher_.
inbound(pktInfo.getSource(),
568 baseModelMessage.getMessages(),
574 "MACI %03hu TDMA::BaseModel::%s eor rx slot:" 575 " %zu does not match sot slot: %zu, drop long",
578 eorSlotInfo.u64AbsoluteSlotIndex_,
579 baseModelMessage.getAbsoluteSlotIndex());
586 auto nowSlotInfoEntry = pScheduler_->getRxSlotInfo(now);
588 if(nowSlotInfoEntry.first.u64AbsoluteSlotIndex_ == baseModelMessage.getAbsoluteSlotIndex())
590 if(nowSlotInfoEntry.second)
592 if(nowSlotInfoEntry.first.u64FrequencyHz_ == frequencySegment.getFrequencyHz())
594 Microseconds span{pReceivePropertiesControlMessage->getSpan()};
596 if(receiveManager_.
enqueue(std::move(baseModelMessage),
608 nowSlotInfoEntry.first.u64AbsoluteSlotIndex_+1),
609 nowSlotInfoEntry.first.timePoint_+ slotDuration_);
612 slotStatusTablePublisher_.
update(nowSlotInfoEntry.first.u32RelativeIndex_,
613 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
614 nowSlotInfoEntry.first.u32RelativeSlotIndex_,
616 slotPortionRatio(now,
617 nowSlotInfoEntry.first.timePoint_));
626 slotStatusTablePublisher_.
update(nowSlotInfoEntry.first.u32RelativeIndex_,
627 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
628 nowSlotInfoEntry.first.u32RelativeSlotIndex_,
630 slotPortionRatio(now,
631 nowSlotInfoEntry.first.timePoint_));
636 slotStatusTablePublisher_.
update(nowSlotInfoEntry.first.u32RelativeIndex_,
637 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
638 nowSlotInfoEntry.first.u32RelativeSlotIndex_,
640 slotPortionRatio(now,
641 nowSlotInfoEntry.first.timePoint_));
643 packetStatusPublisher_.
inbound(pktInfo.getSource(),
644 baseModelMessage.getMessages(),
649 "MACI %03hu TDMA::BaseModel::%s drop reason rx slot correct" 650 " rframe: %u rslot: %u but frequency mismatch expected: %zu got: %zu",
653 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
654 nowSlotInfoEntry.first.u32RelativeSlotIndex_,
655 nowSlotInfoEntry.first.u64FrequencyHz_,
656 frequencySegment.getFrequencyHz());
665 auto slotInfo = pScheduler_->getSlotInfo(nowSlotInfoEntry.first.u64AbsoluteSlotIndex_);
667 slotStatusTablePublisher_.
update(nowSlotInfoEntry.first.u32RelativeIndex_,
668 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
669 nowSlotInfoEntry.first.u32RelativeSlotIndex_,
673 slotPortionRatio(now,
674 nowSlotInfoEntry.first.timePoint_));
676 packetStatusPublisher_.
inbound(pktInfo.getSource(),
677 baseModelMessage.getMessages(),
683 "MACI %03hu TDMA::BaseModel::%s drop reason rx slot correct but %s rframe: %u rslot: %u",
688 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
689 nowSlotInfoEntry.first.u32RelativeSlotIndex_);
698 auto slotInfo = pScheduler_->getSlotInfo(baseModelMessage.getAbsoluteSlotIndex());
703 slotStatusTablePublisher_.
update(nowSlotInfoEntry.first.u32RelativeIndex_,
704 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
705 nowSlotInfoEntry.first.u32RelativeSlotIndex_,
707 slotPortionRatio(now,
708 slotInfo.timePoint_));
710 packetStatusPublisher_.
inbound(pktInfo.getSource(),
711 baseModelMessage.getMessages(),
716 "MACI %03hu TDMA::BaseModel::%s drop reason slot mismatch pkt: %zu now: %zu ",
719 baseModelMessage.getAbsoluteSlotIndex(),
720 nowSlotInfoEntry.first.u64AbsoluteSlotIndex_);
727 slotStatusTablePublisher_.
update(nowSlotInfoEntry.first.u32RelativeIndex_,
728 nowSlotInfoEntry.first.u32RelativeFrameIndex_,
729 nowSlotInfoEntry.first.u32RelativeSlotIndex_,
733 slotPortionRatio(now,
734 slotInfo.timePoint_));
736 packetStatusPublisher_.
inbound(pktInfo.getSource(),
737 baseModelMessage.getMessages(),
743 "MACI %03hu TDMA::BaseModel::%s drop reason slot mismatch but %s pkt: %zu now: %zu ",
748 baseModelMessage.getAbsoluteSlotIndex(),
749 nowSlotInfoEntry.first.u64AbsoluteSlotIndex_);
760 "MACI %03hu TDMA::BaseModel::%s Packet payload length %zu does not match length prefix %zu",
772 "MACI %03hu TDMA::BaseModel::%s",
776 for(
const auto & pMessage : msgs)
780 "MACI %03hu TDMA::BaseModel::%s downstream control message id %hu",
785 switch(pMessage->getId())
789 const auto pFlowControlControlMessage =
792 if(bFlowControlEnable_)
796 "MACI %03hu TDMA::BaseModel::%s received a flow control token request/response",
806 "MACI %03hu TDMA::BaseModel::%s received a flow control token request but" 807 " flow control is not enabled",
816 const auto pSerializedControlMessage =
819 switch(pSerializedControlMessage->getSerializedId())
823 std::unique_ptr<Controls::FlowControlControlMessage>
824 pFlowControlControlMessage{
827 if(bFlowControlEnable_)
835 "MACI %03hu TDMA::BaseModel::%s received a flow control token request but" 836 " flow control is not enabled",
854 "MACI %03hu TDMA::BaseModel::%s",
860 if(bFlowControlEnable_)
864 if(status.second ==
false)
868 "MACI %03hu TDMA::BaseModel::%s: failed to remove token, drop packet (tokens:%hu)",
875 packetStatusPublisher_.
outbound(pktInfo.getSource(),
877 pktInfo.getPriority(),
888 size_t packetsDropped{pQueueManager_->enqueue(u8Queue,std::move(pkt))};
891 if(bFlowControlEnable_)
893 for(
size_t i = 0; i < packetsDropped; ++i)
895 auto status = flowControlManager_.
addToken();
901 "MACI %03hu TDMA::BaseModel:::%s: failed to add token (tokens:%hu)",
916 "MACI %03hu TDMA::BaseModel::%s",
920 pScheduler_->processEvent(eventId,serialization);
929 "MACI %03hu TDMA::BaseModel::%s",
936 for(
const auto & item : update)
938 if(item.first ==
"enablepromiscuousmode")
940 bool bPromiscuousMode{item.second[0].asBool()};
944 "MACI %03hu TDMA::BaseModel::%s: %s = %s",
948 bPromiscuousMode ?
"on" :
"off");
954 schedulerConfiguration.push_back(item);
958 pScheduler_->configure(schedulerConfiguration);
962 std::uint64_t u64BandwidthHz,
968 "MACI %03hu TDMA::BaseModel::%s",
975 if(transmitTimedEventId_)
978 transmitTimedEventId_ = 0;
981 if(u64BandwidthHz_ != u64BandwidthHz || frequencies != frequencies_)
986 frequencies_ = frequencies;
988 u64BandwidthHz_ = u64BandwidthHz;
991 slotDuration_ = slotDuration;
993 slotOverhead_ = slotOverhead;
995 slotStatusTablePublisher_.
clear();
997 std::tie(txSlotInfos_,
998 nextMultiFrameTime_) =
999 pScheduler_->getTxSlotInfo(Clock::now(),1);
1004 "MACI %03hu TDMA::BaseModel::%s TX Slot Info",
1010 if(!txSlotInfos_.empty())
1012 pendingTxSlotInfo_ = *txSlotInfos_.begin();
1014 txSlotInfos_.pop_front();
1016 transmitTimedEventId_ =
1018 schedule(std::bind(&Implementation::processTxOpportunity,
1029 "MACI %03hu TDMA::BaseModel::%s",
1034 pQueueManager_->enqueue(4,std::move(pkt));
1042 "MACI %03hu TDMA::BaseModel::%s",
1054 "MACI %03hu TDMA::BaseModel::%s",
1058 return pQueueManager_->getPacketQueueInfo();
1061 void EMANE::Models::TDMA::BaseModel::Implementation::sendDownstreamPacket(
double dSlotPortionRatio)
1064 size_t bytesAvailable =
1065 (slotDuration_.count() - slotOverhead_.count()) / 1000000.0 * pendingTxSlotInfo_.
u64DataRatebps_ / 8.0;
1067 auto entry = pQueueManager_->dequeue(pendingTxSlotInfo_.
u8QueueId_,
1072 size_t totalSize{std::get<1>(entry)};
1076 if(totalSize <= bytesAvailable)
1078 float fSeconds{totalSize * 8.0f / pendingTxSlotInfo_.
u64DataRatebps_};
1083 if(duration >= slotDuration_)
1089 size_t completedPackets{};
1093 for(
const auto & component : components)
1095 completedPackets += !component.isMoreFragments();
1100 dst = component.getDestination();
1107 if(
dst != component.getDestination())
1117 "MACI %03hu TDMA::BaseModel::%s sending downstream to %03hu components: %zu",
1124 if(bFlowControlEnable_ && completedPackets)
1126 auto status = flowControlManager_.
addToken(completedPackets);
1132 "MACI %03hu TDMA::BaseModel::%s: failed to add token (tokens:%hu)",
1140 aggregationStatusPublisher_.
update(components);
1144 std::move(components)};
1148 auto now = Clock::now();
1176 "MACI %03hu TDMA::BaseModel::%s queue dequeue returning %zu bytes than slot has available %zu",
1195 void EMANE::Models::TDMA::BaseModel::Implementation::processTxOpportunity(std::uint64_t u64ScheduleIndex)
1198 if(u64ScheduleIndex != u64ScheduleIndex_)
1202 "MACI %03hu TDMA::BaseModel::%s old schedule tx opportunity found" 1203 " scheduled index: %zu current index: %zu",
1211 auto now = Clock::now();
1213 auto nowSlotInfo = pScheduler_->getSlotInfo(now);
1218 sendDownstreamPacket(slotPortionRatio(now,
1227 slotPortionRatio(now,
1233 if(txSlotInfos_.empty())
1236 std::tie(txSlotInfos_,
1237 nextMultiFrameTime_) =
1238 pScheduler_->getTxSlotInfo(nextMultiFrameTime_,1);
1241 bool bFoundTXSlot = {};
1244 while(!txSlotInfos_.empty() && !bFoundTXSlot)
1248 while(!txSlotInfos_.empty())
1250 pendingTxSlotInfo_ = *txSlotInfos_.begin();
1252 txSlotInfos_.pop_front();
1258 transmitTimedEventId_ =
1260 schedule(std::bind(&Implementation::processTxOpportunity,
1265 bFoundTXSlot =
true;
1275 slotPortionRatio(now,
1281 sendDownstreamPacket(slotPortionRatio(now,
1287 if(txSlotInfos_.empty())
1290 std::tie(txSlotInfos_,
1291 nextMultiFrameTime_) =
1292 pScheduler_->getTxSlotInfo(nextMultiFrameTime_,1);
1299 double EMANE::Models::TDMA::BaseModel::Implementation::slotPortionRatio(
const TimePoint & current,
1305 return delta.count() /
static_cast<double>(slotDuration_.count());
void processSchedulerPacket(DownstreamPacket &pkt) override
std::string Serialization
A Packet class that allows upstream processing to strip layer headers as the packet travels up the st...
const PacketInfo & getPacketInfo() const
void updateNeighborStatus()
The Registrar interface provides access to all of the emulator registrars.
std::uint64_t u64AbsoluteSlotIndex_
A Serialized Control Message is used to encapsulate Serializable control messages as they traverse pr...
void outbound(NEMId src, NEMId dst, Priority priority, size_t size, OutboundAction action) override
Implementation(NEMId id, PlatformServiceProvider *pPlatformServiceProvider, RadioServiceProvider *pRadioServiceProvider, Scheduler *pScheduler, QueueManager *pQueueManager, MACLayerImplementor *pRadioModel)
virtual ConfigurationRegistrar & configurationRegistrar()=0
void registerStatistics(StatisticRegistrar ®istrar)
void inbound(NEMId src, const MessageComponent &component, InboundAction action) override
void process(std::uint64_t u64AbsoluteSlotIndex)
std::uint32_t u32RelativeFrameIndex_
Message class used to serialize and deserialize TDMA radio model messages.
virtual StatisticRegistrar & statisticRegistrar()=0
Recieve Properties Control Message is sent from the emulator physical layer with every upstream packe...
Holds the frequency, offset and duration of a frequency segment.
void update(const MessageComponents &components)
static TransmitterControlMessage * create(const Transmitters &transmitters)
std::list< const ControlMessage * > ControlMessages
std::pair< std::uint16_t, bool > addToken(std::uint16_t u16Tokens=1)
std::uint32_t u32RelativeSlotIndex_
static TimeStampControlMessage * create(const TimePoint ×tamp)
std::uint16_t stripLengthPrefixFraming()
constexpr NEMId NEM_BROADCAST_MAC_ADDRESS
void sendDownstreamControl(const ControlMessages &msgs)
void setPromiscuousMode(bool bEnable)
void start(std::uint16_t u16TotalTokensAvailable)
void initialize(Registrar ®istrar) override
static FlowControlControlMessage * create(const Serialization &serialization)
std::uint32_t u32RelativeIndex_
void updateNeighborTxMetric(NEMId dst, std::uint64_t u64DataRatebps, const TimePoint &txTime)
Store source, destination, creation time and priority information for a packet.
static FrequencyControlMessage * create(std::uint64_t u64BandwidthHz, const FrequencySegments &frequencySegments)
void processConfiguration(const ConfigurationUpdate &update) override
The Frequency Control Message is sent to the emulator physical layer to specify the frequency segment...
std::vector< QueueInfo > QueueInfos
void processDownstreamPacket(DownstreamPacket &pkt, const ControlMessages &msgs) override
void processFlowControlMessage(const Controls::FlowControlControlMessage *pMsg)
#define LOGGER_VERBOSE_LOGGING_FN_VARGS(logger, level, fn, fmt, args...)
const PacketInfo & getPacketInfo() const
void setFragmentTimeoutThreshold(const std::chrono::seconds &threshold)
Specialized packet the allows downstream processing to add layer specific headers as the packet trave...
void update(std::uint32_t u32RelativeIndex, std::uint32_t u32RelativeFrameIndex, std::uint32_t u32RelativeSlotIndex, Status status, double dSlotRemainingRatio)
std::list< MessageComponent > MessageComponents
std::set< std::uint64_t > Frequencies
void registerStatistics(StatisticRegistrar ®istrar)
std::chrono::microseconds Microseconds
void loadCurves(const std::string &sPCRFileName)
std::chrono::duration< double > DoubleSeconds
const Microseconds & getOffset() const
void postStart() override
Flow Control Control Messages are sent between a MAC layer and a transport in order to communicate da...
The RadioServiceProvider interface provides access to radio (RF) model specific services.
void processDownstreamControl(const ControlMessages &msgs) override
void sendDownstreamPacket(const CommonMACHeader &hdr, DownstreamPacket &pkt, const ControlMessages &msgs=DownstreamTransport::empty)
std::uint64_t u64DataRatebps_
Scheduler interface used by BaseModel to communicate with a scheduler module.
static FrequencyOfInterestControlMessage * create(std::uint64_t u64BandwidthHz, const FrequencySet &frequencySet)
void setFragmentCheckThreshold(const std::chrono::seconds &threshold)
void registerStatistics(StatisticRegistrar &statisticRegistrar)
void setNeighborDeleteTimeMicroseconds(const Microseconds &ageMicroseconds)
Priority getPriority() const
void configure(const ConfigurationUpdate &update) override
Queue management interface used by BaseModel
std::vector< ConfigurationNameAnyValues > ConfigurationUpdate
void notifyScheduleChange(const Frequencies &frequencies, std::uint64_t u64BandwidthHz, const Microseconds &slotDuration, const Microseconds &slotOverhead) override
std::pair< std::uint16_t, bool > removeToken()
void registerStatistics(StatisticRegistrar ®istrar)
std::uint8_t priorityToQueue(Priority priority)
void registerNumeric(const std::string &sName, const ConfigurationProperties &properties=ConfigurationProperties::NONE, const std::initializer_list< T > &values={}, const std::string &sUsage="", T minValue=std::numeric_limits< T >::lowest(), T maxValue=std::numeric_limits< T >::max(), std::size_t minOccurs=1, std::size_t maxOccurs=1, const std::string &sRegexPattern={})
void processSchedulerControl(const ControlMessages &msgs) override
QueueInfos getPacketQueueInfo() const override
Clock::time_point TimePoint
virtual bool cancelTimedEvent(TimerEventId eventId)=0
void prependLengthPrefixFraming(std::uint16_t u16Length)
#define LOGGER_STANDARD_LOGGING(logger, level, fmt, args...)
void processUpstreamPacket(const CommonMACHeader &hdr, UpstreamPacket &pkt, const ControlMessages &msgs) override
bool enqueue(BaseModelMessage &&baseModelMessage, const PacketInfo &pktInfo, size_t length, const TimePoint &startOfReception, const FrequencySegments &frequencySegments, const Microseconds &span, const TimePoint &beginTime, std::uint64_t u64PacketSequence)
std::uint64_t u64FrequencyHz_
const RegistrationId REGISTERED_EMANE_MAC_TDMA
void processUpstreamControl(const ControlMessages &msgs) override
void processEvent(const EventId &, const Serialization &) override
Interface used to create a MAC layer plugin implementation.