mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 21:30:05 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			332 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			332 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <scwx/wsr88d/rda/rda_status_data.hpp>
 | |
| #include <scwx/util/logger.hpp>
 | |
| 
 | |
| namespace scwx::wsr88d::rda
 | |
| {
 | |
| 
 | |
| static const std::string logPrefix_ = "scwx::wsr88d::rda::rda_status_data";
 | |
| static const auto        logger_    = util::Logger::Create(logPrefix_);
 | |
| 
 | |
| class RdaStatusData::Impl
 | |
| {
 | |
| public:
 | |
|    explicit Impl() = default;
 | |
|    ~Impl()         = default;
 | |
| 
 | |
|    Impl(const Impl&)             = delete;
 | |
|    Impl& operator=(const Impl&)  = delete;
 | |
|    Impl(const Impl&&)            = delete;
 | |
|    Impl& operator=(const Impl&&) = delete;
 | |
| 
 | |
|    std::uint16_t rdaStatus_ {0};
 | |
|    std::uint16_t operabilityStatus_ {0};
 | |
|    std::uint16_t controlStatus_ {0};
 | |
|    std::uint16_t auxiliaryPowerGeneratorState_ {0};
 | |
|    std::uint16_t averageTransmitterPower_ {0};
 | |
|    std::int16_t  horizontalReflectivityCalibrationCorrection_ {0};
 | |
|    std::uint16_t dataTransmissionEnabled_ {0};
 | |
|    std::uint16_t volumeCoveragePatternNumber_ {0};
 | |
|    std::uint16_t rdaControlAuthorization_ {0};
 | |
|    std::uint16_t rdaBuildNumber_ {0};
 | |
|    std::uint16_t operationalMode_ {0};
 | |
|    std::uint16_t superResolutionStatus_ {0};
 | |
|    std::uint16_t clutterMitigationDecisionStatus_ {0};
 | |
|    std::uint16_t rdaScanAndDataFlags_ {0};
 | |
|    std::uint16_t rdaAlarmSummary_ {0};
 | |
|    std::uint16_t commandAcknowledgement_ {0};
 | |
|    std::uint16_t channelControlStatus_ {0};
 | |
|    std::uint16_t spotBlankingStatus_ {0};
 | |
|    std::uint16_t bypassMapGenerationDate_ {0};
 | |
|    std::uint16_t bypassMapGenerationTime_ {0};
 | |
|    std::uint16_t clutterFilterMapGenerationDate_ {0};
 | |
|    std::uint16_t clutterFilterMapGenerationTime_ {0};
 | |
|    std::int16_t  verticalReflectivityCalibrationCorrection_ {0};
 | |
|    std::uint16_t transitionPowerSourceStatus_ {0};
 | |
|    std::uint16_t rmsControlStatus_ {0};
 | |
|    std::uint16_t performanceCheckStatus_ {0};
 | |
| 
 | |
|    // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | |
|    std::array<std::uint16_t, 14> alarmCodes_ {0};
 | |
| 
 | |
|    std::uint16_t signalProcessingOptions_ {0};
 | |
|    std::uint16_t downloadedPatternNumber_ {0};
 | |
|    std::uint16_t statusVersion_ {0};
 | |
| };
 | |
| 
 | |
| RdaStatusData::RdaStatusData() : Level2Message(), p(std::make_unique<Impl>()) {}
 | |
| RdaStatusData::~RdaStatusData() = default;
 | |
| 
 | |
| RdaStatusData::RdaStatusData(RdaStatusData&&) noexcept            = default;
 | |
| RdaStatusData& RdaStatusData::operator=(RdaStatusData&&) noexcept = default;
 | |
| 
 | |
| std::uint16_t RdaStatusData::rda_status() const
 | |
| {
 | |
|    return p->rdaStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::operability_status() const
 | |
| {
 | |
|    return p->operabilityStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::control_status() const
 | |
| {
 | |
|    return p->controlStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::auxiliary_power_generator_state() const
 | |
| {
 | |
|    return p->auxiliaryPowerGeneratorState_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::average_transmitter_power() const
 | |
| {
 | |
|    return p->averageTransmitterPower_;
 | |
| }
 | |
| 
 | |
| float RdaStatusData::horizontal_reflectivity_calibration_correction() const
 | |
| {
 | |
|    constexpr float kScale_ = 0.01f;
 | |
|    return static_cast<float>(p->horizontalReflectivityCalibrationCorrection_) *
 | |
|           kScale_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::data_transmission_enabled() const
 | |
| {
 | |
|    return p->dataTransmissionEnabled_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::volume_coverage_pattern_number() const
 | |
| {
 | |
|    return p->volumeCoveragePatternNumber_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::rda_control_authorization() const
 | |
| {
 | |
|    return p->rdaControlAuthorization_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::rda_build_number() const
 | |
| {
 | |
|    return p->rdaBuildNumber_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::operational_mode() const
 | |
| {
 | |
|    return p->operationalMode_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::super_resolution_status() const
 | |
| {
 | |
|    return p->superResolutionStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::clutter_mitigation_decision_status() const
 | |
| {
 | |
|    return p->clutterMitigationDecisionStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::rda_scan_and_data_flags() const
 | |
| {
 | |
|    return p->rdaScanAndDataFlags_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::rda_alarm_summary() const
 | |
| {
 | |
|    return p->rdaAlarmSummary_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::command_acknowledgement() const
 | |
| {
 | |
|    return p->commandAcknowledgement_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::channel_control_status() const
 | |
| {
 | |
|    return p->channelControlStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::spot_blanking_status() const
 | |
| {
 | |
|    return p->spotBlankingStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::bypass_map_generation_date() const
 | |
| {
 | |
|    return p->bypassMapGenerationDate_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::bypass_map_generation_time() const
 | |
| {
 | |
|    return p->bypassMapGenerationTime_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::clutter_filter_map_generation_date() const
 | |
| {
 | |
|    return p->clutterFilterMapGenerationDate_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::clutter_filter_map_generation_time() const
 | |
| {
 | |
|    return p->clutterFilterMapGenerationTime_;
 | |
| }
 | |
| 
 | |
| float RdaStatusData::vertical_reflectivity_calibration_correction() const
 | |
| {
 | |
|    constexpr float kScale_ = 0.01f;
 | |
|    return static_cast<float>(p->verticalReflectivityCalibrationCorrection_) *
 | |
|           kScale_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::transition_power_source_status() const
 | |
| {
 | |
|    return p->transitionPowerSourceStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::rms_control_status() const
 | |
| {
 | |
|    return p->rmsControlStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::performance_check_status() const
 | |
| {
 | |
|    return p->performanceCheckStatus_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::alarm_codes(unsigned i) const
 | |
| {
 | |
|    return p->alarmCodes_.at(i);
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::signal_processing_options() const
 | |
| {
 | |
|    return p->signalProcessingOptions_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::downloaded_pattern_number() const
 | |
| {
 | |
|    return p->downloadedPatternNumber_;
 | |
| }
 | |
| 
 | |
| std::uint16_t RdaStatusData::status_version() const
 | |
| {
 | |
|    return p->statusVersion_;
 | |
| }
 | |
| 
 | |
| bool RdaStatusData::Parse(std::istream& is)
 | |
| {
 | |
|    logger_->trace("Parsing RDA Status Data (Message Type 2)");
 | |
| 
 | |
|    bool   messageValid = true;
 | |
|    size_t bytesRead    = 0;
 | |
| 
 | |
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers): Readability
 | |
|    is.read(reinterpret_cast<char*>(&p->rdaStatus_), 2);                    // 1
 | |
|    is.read(reinterpret_cast<char*>(&p->operabilityStatus_), 2);            // 2
 | |
|    is.read(reinterpret_cast<char*>(&p->controlStatus_), 2);                // 3
 | |
|    is.read(reinterpret_cast<char*>(&p->auxiliaryPowerGeneratorState_), 2); // 4
 | |
|    is.read(reinterpret_cast<char*>(&p->averageTransmitterPower_), 2);      // 5
 | |
|    is.read(
 | |
|       reinterpret_cast<char*>(&p->horizontalReflectivityCalibrationCorrection_),
 | |
|       2);                                                                 // 6
 | |
|    is.read(reinterpret_cast<char*>(&p->dataTransmissionEnabled_), 2);     // 7
 | |
|    is.read(reinterpret_cast<char*>(&p->volumeCoveragePatternNumber_), 2); // 8
 | |
|    is.read(reinterpret_cast<char*>(&p->rdaControlAuthorization_), 2);     // 9
 | |
|    is.read(reinterpret_cast<char*>(&p->rdaBuildNumber_), 2);              // 10
 | |
|    is.read(reinterpret_cast<char*>(&p->operationalMode_), 2);             // 11
 | |
|    is.read(reinterpret_cast<char*>(&p->superResolutionStatus_), 2);       // 12
 | |
|    is.read(reinterpret_cast<char*>(&p->clutterMitigationDecisionStatus_),
 | |
|            2);                                                        // 13
 | |
|    is.read(reinterpret_cast<char*>(&p->rdaScanAndDataFlags_), 2);     // 14
 | |
|    is.read(reinterpret_cast<char*>(&p->rdaAlarmSummary_), 2);         // 15
 | |
|    is.read(reinterpret_cast<char*>(&p->commandAcknowledgement_), 2);  // 16
 | |
|    is.read(reinterpret_cast<char*>(&p->channelControlStatus_), 2);    // 17
 | |
|    is.read(reinterpret_cast<char*>(&p->spotBlankingStatus_), 2);      // 18
 | |
|    is.read(reinterpret_cast<char*>(&p->bypassMapGenerationDate_), 2); // 19
 | |
|    is.read(reinterpret_cast<char*>(&p->bypassMapGenerationTime_), 2); // 20
 | |
|    is.read(reinterpret_cast<char*>(&p->clutterFilterMapGenerationDate_),
 | |
|            2); // 21
 | |
|    is.read(reinterpret_cast<char*>(&p->clutterFilterMapGenerationTime_),
 | |
|            2); // 22
 | |
|    is.read(
 | |
|       reinterpret_cast<char*>(&p->verticalReflectivityCalibrationCorrection_),
 | |
|       2);                                                                 // 23
 | |
|    is.read(reinterpret_cast<char*>(&p->transitionPowerSourceStatus_), 2); // 24
 | |
|    is.read(reinterpret_cast<char*>(&p->rmsControlStatus_), 2);            // 25
 | |
|    is.read(reinterpret_cast<char*>(&p->performanceCheckStatus_), 2);      // 26
 | |
|    is.read(reinterpret_cast<char*>(&p->alarmCodes_),
 | |
|            static_cast<std::streamsize>(p->alarmCodes_.size() * 2)); // 27-40
 | |
|    bytesRead += 80;
 | |
| 
 | |
|    p->rdaStatus_                    = ntohs(p->rdaStatus_);
 | |
|    p->operabilityStatus_            = ntohs(p->operabilityStatus_);
 | |
|    p->controlStatus_                = ntohs(p->controlStatus_);
 | |
|    p->auxiliaryPowerGeneratorState_ = ntohs(p->auxiliaryPowerGeneratorState_);
 | |
|    p->averageTransmitterPower_      = ntohs(p->averageTransmitterPower_);
 | |
|    p->horizontalReflectivityCalibrationCorrection_ = static_cast<std::int16_t>(
 | |
|       ntohs(p->horizontalReflectivityCalibrationCorrection_));
 | |
|    p->dataTransmissionEnabled_     = ntohs(p->dataTransmissionEnabled_);
 | |
|    p->volumeCoveragePatternNumber_ = ntohs(p->volumeCoveragePatternNumber_);
 | |
|    p->rdaControlAuthorization_     = ntohs(p->rdaControlAuthorization_);
 | |
|    p->rdaBuildNumber_              = ntohs(p->rdaBuildNumber_);
 | |
|    p->operationalMode_             = ntohs(p->operationalMode_);
 | |
|    p->superResolutionStatus_       = ntohs(p->superResolutionStatus_);
 | |
|    p->clutterMitigationDecisionStatus_ =
 | |
|       ntohs(p->clutterMitigationDecisionStatus_);
 | |
|    p->rdaScanAndDataFlags_     = ntohs(p->rdaScanAndDataFlags_);
 | |
|    p->rdaAlarmSummary_         = ntohs(p->rdaAlarmSummary_);
 | |
|    p->commandAcknowledgement_  = ntohs(p->commandAcknowledgement_);
 | |
|    p->channelControlStatus_    = ntohs(p->channelControlStatus_);
 | |
|    p->spotBlankingStatus_      = ntohs(p->spotBlankingStatus_);
 | |
|    p->bypassMapGenerationDate_ = ntohs(p->bypassMapGenerationDate_);
 | |
|    p->bypassMapGenerationTime_ = ntohs(p->bypassMapGenerationTime_);
 | |
|    p->clutterFilterMapGenerationDate_ =
 | |
|       ntohs(p->clutterFilterMapGenerationDate_);
 | |
|    p->clutterFilterMapGenerationTime_ =
 | |
|       ntohs(p->clutterFilterMapGenerationTime_);
 | |
|    p->verticalReflectivityCalibrationCorrection_ = static_cast<std::int16_t>(
 | |
|       ntohs(p->verticalReflectivityCalibrationCorrection_));
 | |
|    p->transitionPowerSourceStatus_ = ntohs(p->transitionPowerSourceStatus_);
 | |
|    p->rmsControlStatus_            = ntohs(p->rmsControlStatus_);
 | |
|    p->performanceCheckStatus_      = ntohs(p->performanceCheckStatus_);
 | |
|    SwapArray(p->alarmCodes_);
 | |
| 
 | |
|    // RDA Build 18.0 increased the size of the message from 80 to 120 bytes
 | |
|    if (static_cast<std::size_t>(header().message_size()) * 2 >
 | |
|        Level2MessageHeader::SIZE + 80)
 | |
|    {
 | |
|       is.read(reinterpret_cast<char*>(&p->signalProcessingOptions_), 2); // 41
 | |
|       is.seekg(34, std::ios_base::cur); // 42-58
 | |
|       is.read(reinterpret_cast<char*>(&p->downloadedPatternNumber_), 2); // 59
 | |
|       is.read(reinterpret_cast<char*>(&p->statusVersion_), 2);           // 60
 | |
|       bytesRead += 40;
 | |
| 
 | |
|       p->signalProcessingOptions_ = ntohs(p->signalProcessingOptions_);
 | |
|       p->statusVersion_           = ntohs(p->statusVersion_);
 | |
|    }
 | |
| 
 | |
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | |
| 
 | |
|    if (!ValidateMessage(is, bytesRead))
 | |
|    {
 | |
|       messageValid = false;
 | |
|    }
 | |
| 
 | |
|    return messageValid;
 | |
| }
 | |
| 
 | |
| std::shared_ptr<RdaStatusData>
 | |
| RdaStatusData::Create(Level2MessageHeader&& header, std::istream& is)
 | |
| {
 | |
|    std::shared_ptr<RdaStatusData> message = std::make_shared<RdaStatusData>();
 | |
|    message->set_header(std::move(header));
 | |
| 
 | |
|    if (!message->Parse(is))
 | |
|    {
 | |
|       message.reset();
 | |
|    }
 | |
| 
 | |
|    return message;
 | |
| }
 | |
| 
 | |
| } // namespace scwx::wsr88d::rda
 | 
