67 const std::uint16_t DROP_CODE_OUT_OF_BAND = 1;
68 const std::uint16_t DROP_CODE_RX_SENSITIVITY = 2;
69 const std::uint16_t DROP_CODE_PROPAGATIONMODEL = 3;
70 const std::uint16_t DROP_CODE_GAINMANAGER_LOCATION = 4;
71 const std::uint16_t DROP_CODE_GAINMANAGER_HORIZON = 5;
72 const std::uint16_t DROP_CODE_GAINMANAGER_ANTENNAPROFILE = 6;
73 const std::uint16_t DROP_CODE_NOT_FOI = 7;
74 const std::uint16_t DROP_CODE_SPECTRUM_CLAMP = 8;
90 pSpectrumMonitor_{pSpectrumMonitor},
96 dReceiverSensitivitydBm_{},
99 u16TxSequenceNumber_{},
100 commonLayerStatistics_{STATISTIC_TABLE_LABELS,{},
"0"},
101 eventTablePublisher_{
id},
104 maxMessagePropagation_{},
105 maxSegmentDuration_{},
106 timeSyncThreshold_{},
108 dSystemNoiseFiguredB_{}{}
120 "Defines the antenna gain in dBi and is valid only when" 121 " fixedantennagainenable is enabled.");
123 configRegistrar.registerNumeric<
bool>(
"fixedantennagainenable",
126 "Defines whether fixed antenna gain is used or whether" 127 " antenna profiles are in use.");
129 configRegistrar.registerNumeric<std::uint64_t>(
"bandwidth",
132 "Defines receiver bandwidth in Hz and also serves as the" 133 " default bandwidth for OTA transmissions when not provided" 137 configRegistrar.registerNumeric<std::uint64_t>(
"frequency",
140 "Defines the default transmit center frequency in Hz when not" 141 " provided by the MAC. This value is included in the Common PHY" 142 " Header of all transmitted OTA packets.",
145 configRegistrar.registerNumeric<std::uint64_t>(
"frequencyofinterest",
148 "Defines a set of center frequencies in Hz that are monitored" 149 " for reception as either in-band or out-of-band.",
150 std::numeric_limits<std::uint64_t>::min(),
151 std::numeric_limits<std::uint64_t>::max(),
153 std::numeric_limits<std::size_t>::max());
155 configRegistrar.registerNonNumeric<std::string>(
"noisemode",
158 "Defines the noise processing mode of operation:" 159 " none, all or outofband.",
162 "^(none|all|outofband)$");
165 configRegistrar.registerNumeric<std::uint64_t>(
"noisebinsize",
168 "Defines the noise bin size in microseconds and translates" 169 " into timing accuracy associated with aligning the start and" 170 " end of reception times of multiple packets for modeling of" 171 " interference effects.",
174 configRegistrar.registerNumeric<
bool>(
"noisemaxclampenable",
177 "Defines whether segment offset, segment duration and message" 178 " propagation associated with a received packet will be clamped" 179 " to their respective maximums defined by noisemaxsegmentoffset," 180 " noisemaxsegmentduration and noisemaxmessagepropagation. When" 181 " disabled, any packet with an above max value will be dropped.");
184 configRegistrar.registerNumeric<std::uint64_t>(
"noisemaxsegmentoffset",
187 "Noise maximum segment offset in microseconds.",
190 configRegistrar.registerNumeric<std::uint64_t>(
"noisemaxmessagepropagation",
193 "Noise maximum message propagation in microseconds.",
196 configRegistrar.registerNumeric<std::uint64_t>(
"noisemaxsegmentduration",
199 "Noise maximum segment duration in microseconds.",
202 configRegistrar.registerNumeric<std::uint64_t>(
"timesyncthreshold",
205 "Defines the time sync detection threshold in microseconds." 206 " If a received OTA message is more than this threshold, the" 207 " message reception time will be used as the source transmission" 208 " time instead of the time contained in the Common PHY Header." 209 " This allows the emulator to be used across distributed nodes" 210 " without time sync.",
213 configRegistrar.registerNonNumeric<std::string>(
"propagationmodel",
216 "Defines the pathloss mode of operation:" 217 " precomputed, 2ray or freespace.",
220 "^(precomputed|2ray|freespace)$");
222 configRegistrar.registerNumeric<
double>(
"systemnoisefigure",
225 "Defines the system noise figure in dB and is used to determine the" 226 " receiver sensitivity.");
228 configRegistrar.registerNumeric<std::uint16_t>(
"subid",
231 "Defines the emulator PHY subid used by multiple NEM" 232 " definitions. Once instantiated, these NEMs may be using the" 233 " same frequency. In order to differentiate between emulator" 234 " PHY instances for different waveforms, the subid is used as" 235 " part of the unique waveform identifying tuple: PHY Layer" 236 " Registration Id, emulator PHY subid and packet center" 240 configRegistrar.registerNumeric<
double>(
"txpower",
241 EMANE::ConfigurationProperties::DEFAULT |
244 "Defines the transmit power in dBm.");
263 pTimeSyncThresholdRewrite_ =
264 statisticRegistrar.registerNumeric<std::uint64_t>(
"numTimeSyncThresholdRewrite",
272 for(
const auto & item : update)
274 if(item.first ==
"bandwidth")
276 u64BandwidthHz_ = item.second[0].asUINT64();
280 "PHYI %03hu FrameworkPHY::%s: %s = %ju Hz",
286 else if(item.first ==
"fixedantennagain")
288 optionalFixedAntennaGaindBi_.first = item.second[0].asDouble();
292 "PHYI %03hu FrameworkPHY::%s: %s = %3.2f dBi",
296 optionalFixedAntennaGaindBi_.first);
299 else if(item.first ==
"fixedantennagainenable")
301 optionalFixedAntennaGaindBi_.second = item.second[0].asBool();
305 "PHYI %03hu FrameworkPHY::%s: %s = %s",
309 optionalFixedAntennaGaindBi_.second ?
"on" :
"off");
311 else if(item.first ==
"propagationmodel")
313 std::string sPropagationModel{item.second[0].asString()};
316 if(sPropagationModel ==
"precomputed")
320 else if(sPropagationModel ==
"2ray")
331 "PHYI %03hu FrameworkPHY::%s: %s = %s",
335 sPropagationModel.c_str());
337 else if(item.first ==
"noisemode")
339 std::string sNoiseMode{item.second[0].asString()};
342 if(sNoiseMode ==
"all")
346 else if(sNoiseMode ==
"none")
357 "PHYI %03hu FrameworkPHY::%s: %s = %s",
363 else if(item.first ==
"noisebinsize")
365 noiseBinSize_ =
Microseconds{item.second[0].asUINT64()};
369 "PHYI %03hu FrameworkPHY::%s: %s = %ju usec",
373 noiseBinSize_.count());
375 else if(item.first ==
"noisemaxclampenable")
377 bNoiseMaxClamp_ = item.second[0].asBool();
381 "PHYI %03hu FrameworkPHY::%s: %s = %s",
385 bNoiseMaxClamp_ ?
"on" :
"off");
387 else if(item.first ==
"noisemaxsegmentoffset")
389 maxSegmentOffset_ =
Microseconds{item.second[0].asUINT64()};
393 "PHYI %03hu FrameworkPHY::%s: %s = %ju usec",
397 maxSegmentOffset_.count());
399 else if(item.first ==
"noisemaxmessagepropagation")
401 maxMessagePropagation_ =
Microseconds{item.second[0].asUINT64()};
405 "PHYI %03hu FrameworkPHY::%s: %s = %ju usec",
409 maxMessagePropagation_.count());
411 else if(item.first ==
"noisemaxsegmentduration")
413 maxSegmentDuration_ =
Microseconds{item.second[0].asUINT64()};
417 "PHYI %03hu FrameworkPHY::%s: %s = %ju usec",
421 maxSegmentDuration_.count());
423 else if(item.first ==
"timesyncthreshold")
425 timeSyncThreshold_ =
Microseconds{item.second[0].asUINT64()};
429 "PHYI %03hu FrameworkPHY::%s: %s = %ju usec",
433 timeSyncThreshold_.count());
435 else if(item.first ==
"systemnoisefigure")
437 dSystemNoiseFiguredB_ = item.second[0].asDouble();
441 "PHYI %03hu FrameworkPHY::%s: %s = %3.2f dB",
445 dSystemNoiseFiguredB_);
448 else if(item.first ==
"frequencyofinterest")
450 for(
const auto & any : item.second)
452 std::uint64_t u64Value{any.asUINT64()};
455 if(foi.insert(u64Value).second)
459 "PHYI %03hu FrameworkPHY::%s: %s = %ju Hz",
467 throw makeException<ConfigureException>(
"FrameworkPHY duplicate frequency of interest found: %ju",
475 else if(item.first ==
"txpower")
477 dTxPowerdBm_ = item.second[0].asDouble();
481 "PHYI %03hu FrameworkPHY::%s: %s = %3.2f dBm",
488 else if(item.first ==
"frequency")
490 u64TxFrequencyHz_ = item.second[0].asUINT64();
494 "PHYI %03hu FrameworkPHY::%s: %s = %ju Hz",
500 else if(item.first ==
"subid")
502 u16SubId_ = item.second[0].asUINT16();
506 "PHYI %03hu FrameworkPHY::%s: %s = %hu",
514 throw makeException<ConfigureException>(
"FrameworkPHY: Unexpected configuration item %s",
519 dReceiverSensitivitydBm_ =
THERMAL_NOISE_DB + dSystemNoiseFiguredB_ + 10.0 * log10(u64BandwidthHz_);
521 if((maxSegmentOffset_ + maxMessagePropagation_ + 2 * maxSegmentDuration_) % noiseBinSize_ !=
522 Microseconds::zero())
524 throw makeException<ConfigureException>(
"noisemaxsegmentoffset + noisemaxmessagepropagation" 525 " + 2 * noisemaxsegmentduration not evenly divisible by the" 535 maxMessagePropagation_,
545 "PHYI %03hu FrameworkPHY::%s",
554 "PHYI %03hu FrameworkPHY::%s",
563 "PHYI %03hu FrameworkPHY::%s",
571 for(
const auto & item : update)
573 if(item.first ==
"fixedantennagain")
575 optionalFixedAntennaGaindBi_.first = item.second[0].asDouble();
579 "PHYI %03hu FrameworkPHY::%s: %s = %3.2f dBi",
583 optionalFixedAntennaGaindBi_.first);
586 else if(item.first ==
"txpower")
588 dTxPowerdBm_ = item.second[0].asDouble();
592 "PHYI %03hu FrameworkPHY::%s: %s = %3.2f dBm",
605 "PHYI %03hu FrameworkPHY::%s",
609 for(
const auto & pMessage : msgs)
611 switch(pMessage->getId())
615 const auto pAntennaProfileControlMessage =
620 pAntennaProfileControlMessage->getAntennaProfileId(),
621 pAntennaProfileControlMessage->getAntennaAzimuthDegrees(),
622 pAntennaProfileControlMessage->getAntennaElevationDegrees()}};
624 gainManager_.
update(profiles);
633 const auto pFrequencyOfInterestControlMessage =
639 "PHYI %03hu FrameworkPHY::%s Frequency of Interest Control Message",
643 u64BandwidthHz_ = pFrequencyOfInterestControlMessage->getBandwidthHz();
645 dReceiverSensitivitydBm_ =
648 pSpectrumMonitor_->
initialize(pFrequencyOfInterestControlMessage->getFrequencySet(),
654 maxMessagePropagation_,
666 "PHYI %03hu FrameworkPHY::%s, unexpected contoll message, ignore",
676 auto now = Clock::now();
682 "PHYI %03hu FrameworkPHY::%s src %hu, dst %hu",
686 pktInfo.getDestination());
691 std::uint64_t u64BandwidthHz{u64BandwidthHz_};
703 for(
const auto & pMessage : msgs)
705 switch(pMessage->getId())
709 const auto pTransmitterControlMessage =
716 "PHYI %03hu FrameworkPHY::%s Transmitter Control Message",
720 transmitters = pTransmitterControlMessage->getTransmitters();
723 std::for_each(transmitters.begin(),
725 [&otaTransmitters](
const Transmitter & transmitter)
727 otaTransmitters.insert(transmitter.getNEMId());
735 const auto pFrequencyControlMessage =
739 frequencySegments.clear();
741 for(
const auto & segment : pFrequencyControlMessage->getFrequencySegments())
745 if(segment.getFrequencyHz() == 0)
747 if(segment.getPowerdBm().second)
749 frequencySegments.push_back({u64TxFrequencyHz_,
750 segment.getPowerdBm().first,
751 segment.getDuration(),
752 segment.getOffset()});
756 frequencySegments.push_back({u64TxFrequencyHz_,
757 segment.getDuration(),
758 segment.getOffset()});
763 frequencySegments.push_back(segment);
769 if(pFrequencyControlMessage->getBandwidthHz() != 0)
777 "PHYI %03hu FrameworkPHY::%s Frequency Control Message",
786 const auto pAntennaProfileControlMessage =
791 "PHYI %03hu FrameworkPHY::%s Antenna Profile Control Message " 792 "profile %hu azimuth %lf elevation %lf",
795 pAntennaProfileControlMessage->getAntennaProfileId(),
796 pAntennaProfileControlMessage->getAntennaAzimuthDegrees(),
797 pAntennaProfileControlMessage->getAntennaElevationDegrees());
801 pAntennaProfileControlMessage->getAntennaProfileId(),
802 pAntennaProfileControlMessage->getAntennaAzimuthDegrees(),
803 pAntennaProfileControlMessage->getAntennaElevationDegrees()}};
805 gainManager_.
update(profiles);
815 const auto pTimestampControlMessage =
823 "PHYI %03hu FrameworkPHY::%s Time Stamp Control Message " 827 std::chrono::duration_cast<
DoubleSeconds>(txTimeStamp.time_since_epoch()).count());
834 const auto pFrequencyOfInterestControlMessage =
840 "PHYI %03hu FrameworkPHY::%s Frequency of Interest Control Message",
844 u64BandwidthHz_ = pFrequencyOfInterestControlMessage->getBandwidthHz();
846 dReceiverSensitivitydBm_ =
849 pSpectrumMonitor_->
initialize(pFrequencyOfInterestControlMessage->getFrequencySet(),
855 maxMessagePropagation_,
869 if(std::find_if(transmitters.begin(),
873 return transmitter.getNEMId() == this->
id_;
874 }) == transmitters.end())
876 transmitters.push_back({
id_,dTxPowerdBm_});
882 u16TxSequenceNumber_++,
887 optionalFixedAntennaGaindBi_};
892 "PHYI %03hu FrameworkPHY::%s Common PHY Header",
898 if(!otaTransmitters.empty())
900 downstreamControlMessages.
905 std::chrono::duration_cast<Microseconds>(Clock::now() - now));
927 "PHYI %03hu FrameworkPHY::%s Common PHY Header",
936 u16SubId_ == commonPHYHeader.
getSubId()};
946 std::vector<double> rxPowerSegments(frequencySegments.size(),0);
950 bool bHavePropagationDelay{};
952 std::vector<NEMId> transmitters{};
956 transmitters.push_back(transmitter.getNEMId());
959 auto locationPairInfoRet = locationManager_.
getLocationInfo(transmitter.getNEMId());
962 auto pathlossInfo = (*pPropagationModelAlgorithm_)(transmitter.getNEMId(),
963 locationPairInfoRet.first,
967 if(pathlossInfo.second)
972 auto gainInfodBi = gainManager_.
determineGain(transmitter.getNEMId(),
973 locationPairInfoRet.first,
974 optionalFixedAntennaGaindBi_,
980 using ReceivePowerPubisherUpdate = std::tuple<NEMId,std::uint64_t,double>;
984 std::set<ReceivePowerPubisherUpdate> receivePowerTableUpdate{};
988 FrequencySegments::const_iterator freqIter{frequencySegments.begin()};
993 for(
const auto & dPathlossdB : pathlossInfo.first)
995 auto optionalSegmentPowerdBm = freqIter->getPowerdBm();
997 double powerdBm{(optionalSegmentPowerdBm.second ?
998 optionalSegmentPowerdBm.first :
999 transmitter.getPowerdBm()) +
1003 receivePowerTableUpdate.insert(ReceivePowerPubisherUpdate{transmitter.getNEMId(),
1004 freqIter->getFrequencyHz(),
1013 for(
const auto & entry : receivePowerTableUpdate)
1015 receivePowerTablePublisher_.
update(std::get<0>(entry),
1026 if(locationPairInfoRet.second && !bHavePropagationDelay)
1028 if(locationPairInfoRet.first.getDistanceMeters() > 0.0)
1031 Microseconds{
static_cast<std::uint64_t
>(std::round(locationPairInfoRet.first.getDistanceMeters() /
SOL_MPS * 1000000))};
1034 bHavePropagationDelay =
true;
1042 std::uint16_t u16Code{};
1044 const char * pzReason{};
1046 switch(gainInfodBi.second)
1049 pzReason =
"missing location info";
1050 u16Code = DROP_CODE_GAINMANAGER_LOCATION;
1053 pzReason =
"missing profile info";
1054 u16Code = DROP_CODE_GAINMANAGER_ANTENNAPROFILE;
1057 pzReason =
"below the horizon";
1058 u16Code = DROP_CODE_GAINMANAGER_HORIZON;
1061 pzReason =
"unknown";
1066 std::chrono::duration_cast<Microseconds>(Clock::now() - now),
1071 "PHYI %03hu FrameworkPHY::%s transmitter %hu, src %hu, dst %hu, drop %s",
1074 transmitter.getNEMId(),
1075 pktInfo.getSource(),
1076 pktInfo.getDestination(),
1089 std::chrono::duration_cast<Microseconds>(Clock::now() - now),
1090 DROP_CODE_PROPAGATIONMODEL);
1094 "PHYI %03hu FrameworkPHY::%s transmitter %hu, src %hu, dst %hu," 1095 " drop propagation model missing info",
1098 transmitter.getNEMId(),
1099 pktInfo.getSource(),
1100 pktInfo.getDestination());
1116 auto spectrumInfo = pSpectrumMonitor_->
update(now,
1129 bool bTreatAsInBand{};
1134 resultingFrequencySegments,
1135 bTreatAsInBand) = spectrumInfo;
1139 if(!resultingFrequencySegments.empty())
1142 std::chrono::duration_cast<Microseconds>(Clock::now() - now));
1147 "PHYI %03hu FrameworkPHY::%s src %hu, dst %hu," 1151 pktInfo.getSource(),
1152 pktInfo.getDestination());
1156 ++*pTimeSyncThresholdRewrite_;
1163 resultingFrequencySegments),
1167 dReceiverSensitivitydBm_)});
1173 std::chrono::duration_cast<Microseconds>(Clock::now() - now),
1174 DROP_CODE_RX_SENSITIVITY);
1178 "PHYI %03hu FrameworkPHY::%s src %hu, dst %hu," 1179 " drop below receiver sensitivity",
1182 pktInfo.getSource(),
1183 pktInfo.getDestination());
1193 std::chrono::duration_cast<Microseconds>(Clock::now() - now),
1198 "PHYI %03hu FrameworkPHY::%s src %hu, dst %hu," 1199 " drop one or more frequencies not in frequency of interest list",
1202 pktInfo.getSource(),
1203 pktInfo.getDestination());
1209 std::chrono::duration_cast<Microseconds>(Clock::now() - now),
1210 DROP_CODE_OUT_OF_BAND);
1214 "PHYI %03hu FrameworkPHY::%s src %hu, dst %hu," 1215 " drop out of band",
1218 pktInfo.getSource(),
1219 pktInfo.getDestination());
1227 std::chrono::duration_cast<Microseconds>(Clock::now() - now),
1228 DROP_CODE_SPECTRUM_CLAMP);
1232 "PHYI %03hu FrameworkPHY::%s src %hu, dst %hu," 1233 " drop spectrum out of bound %s",
1236 pktInfo.getSource(),
1237 pktInfo.getDestination(),
1245 std::chrono::duration_cast<Microseconds>(Clock::now() - now),
1246 DROP_CODE_OUT_OF_BAND);
1250 "PHYI %03hu FrameworkPHY::%s src %hu, dst %hu," 1251 " drop out of band",
1254 pktInfo.getSource(),
1255 pktInfo.getDestination());
1265 "PHYI %03hu FrameworkPHY::%s event id: %hu",
1275 gainManager_.
update(antennaProfile.getAntennaProfiles());
1276 eventTablePublisher_.
update(antennaProfile.getAntennaProfiles());
1281 "PHYI %03hu FrameworkPHY::%s antenna profile event: ",
1291 locationManager_.
update(locationEvent.getLocations());
1292 eventTablePublisher_.
update(locationEvent.getLocations());
1297 "PHYI %03hu FrameworkPHY::%s location event: ",
1306 pPropagationModelAlgorithm_->update(pathlossEvent.getPathlosses());
1307 eventTablePublisher_.
update(pathlossEvent.getPathlosses());
1312 "PHYI %03hu FrameworkPHY::%s pathloss event: ",
std::set< NEMId > OTATransmitters
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 attachEvent(NEMId nemId, const Event &event)
The Registrar interface provides access to all of the emulator registrars.
The Transmitter Control Message is sent to the emulator physical layer to specify the NEM Id of the s...
void configure(const ConfigurationUpdate &update) override
virtual ConfigurationRegistrar & configurationRegistrar()=0
An antenna profile event is used to set the antenna profile selection and pointing information for on...
std::pair< double, GainStatus > determineGain(NEMId transmitterId, const LocationInfo &locationPairInfo, const std::pair< double, bool > &optionalRxFixedGaindBi, const std::pair< double, bool > &optionalTxFixedGaindBi) const
static OTATransmitterControlMessage * create(const Serialization &serialization)
#define LOGGER_VERBOSE_LOGGING(logger, level, fmt, args...)
Holds transmitter id and power level.
void update(const Events::Locations &locations)
virtual StatisticRegistrar & statisticRegistrar()=0
A pathloss event is used to set the pathloss from one or more transmitting NEMs to a receiving NEM...
void processOutbound(const UpstreamPacket &pkt, Microseconds delay, size_t dropCode={})
Interface used to create a PHY layer plugin implementation.
std::list< const ControlMessage * > ControlMessages
void processUpstreamPacket(const CommonPHYHeader &hdr, UpstreamPacket &pkt, const ControlMessages &msgs) override
void update(NEMId nemId, std::uint64_t u64Frequency, double dReceivePower, const TimePoint &rxTime)
Antenna Profile Control Message is sent to the emulator physical layer to update antenna profile sele...
SpectrumServiceException is thrown when an exception occurs during spectrum service processing...
void processEvent(const EventId &eventId, const Serialization &serialization) override
void update(const Events::Locations &locations)
void sendDownstreamPacket(const CommonPHYHeader &hdr, DownstreamPacket &pkt, const ControlMessages &msgs=DownstreamTransport::empty)
A location event is usd to set the position, orientation and velocity information for one or more NEM...
virtual EventRegistrar & eventRegistrar()=0
The Frequency of Interest Control Message is sent to the emulator physical layer to specify receive f...
void registerStatistics(StatisticRegistrar &statisticRegistrar)
Store source, destination, creation time and priority information for a packet.
static FrequencyControlMessage * create(std::uint64_t u64BandwidthHz, const FrequencySegments &frequencySegments)
std::uint64_t getBandwidthHz() const
void processConfiguration(const ConfigurationUpdate &update) override
void initialize(Registrar ®istrar) override
std::set< std::uint64_t > FrequencySet
const char * what() const
The Frequency Control Message is sent to the emulator physical layer to specify the frequency segment...
TimePoint getTimeStamp() const
#define LOGGER_VERBOSE_LOGGING_FN_VARGS(logger, level, fn, fmt, args...)
std::vector< std::string > StatisticTableLabels
const PacketInfo & getPacketInfo() const
void registerStatistics(StatisticRegistrar ®istrar)
Specialized packet the allows downstream processing to add layer specific headers as the packet trave...
std::tuple< TimePoint, Microseconds, Microseconds, FrequencySegments, bool > update(const TimePoint &now, const TimePoint &txTime, const Microseconds &propagationDelay, const FrequencySegments &segments, std::uint64_t u64SegmentBandwidthHz, const std::vector< double > &rxPowersMilliWatt, bool bInBand, const std::vector< NEMId > &transmitters)
void processDownstreamPacket(DownstreamPacket &pkt, const ControlMessages &msgs) override
const RegistrationId REGISTERED_EMANE_PHY_FRAMEWORK
std::chrono::microseconds Microseconds
std::chrono::duration< double > DoubleSeconds
std::pair< LocationInfo, bool > getLocationInfo(NEMId remoteNEMId)
void initialize(const FrequencySet &foi, std::uint64_t u64BandwidthHz, double dReceiverSensitivityMilliWatt, NoiseMode mode, const Microseconds &binSize, const Microseconds &maxOffset, const Microseconds &maxPropagation, const Microseconds &maxDuration, const Microseconds &timeSyncThreshold, bool bMaxClamp)
void processUpstreamPacket_i(const TimePoint &now, const CommonPHYHeader &hdr, UpstreamPacket &pkt, const ControlMessages &msgs)
void processDownstreamControl(const ControlMessages &msgs) override
std::list< FrequencySegment > FrequencySegments
std::vector< ConfigurationNameAnyValues > ConfigurationUpdate
void update(const Events::AntennaProfiles &antennaProfiles)
double DB_TO_MILLIWATT(double ddB)
static ReceivePropertiesControlMessage * create(const TimePoint &txTime, const Microseconds &propagation, const Microseconds &span, double dReceiverSensitivitydBm)
virtual void registerEvent(EventId eventId)=0
Time Stamp Control Message is sent to the emulator physical layer to specify the time that should be ...
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={})
Clock::time_point TimePoint
std::list< Transmitter > Transmitters
const double THERMAL_NOISE_DB
void sendUpstreamPacket(UpstreamPacket &pkt, const ControlMessages &msgs=empty)
#define LOGGER_STANDARD_LOGGING(logger, level, fmt, args...)
#define LOGGER_STANDARD_LOGGING_FN_VARGS(logger, level, fn, fmt, args...)
FrameworkPHY(NEMId id, PlatformServiceProvider *pPlatformService, SpectrumMonitor *pSpectrumMonitor)
virtual void sendEvent(NEMId nemId, const Event &event)=0
std::list< AntennaProfile > AntennaProfiles
void processInbound(const UpstreamPacket &pkt)
void registerStatistics(StatisticRegistrar ®istrar)