mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:00:06 +00:00
165 lines
4.1 KiB
C++
165 lines
4.1 KiB
C++
#include <scwx/wsr88d/rda/message_header.hpp>
|
|
|
|
#include <istream>
|
|
#include <string>
|
|
|
|
#include <boost/log/trivial.hpp>
|
|
|
|
#ifdef WIN32
|
|
# include <WinSock2.h>
|
|
#else
|
|
# include <arpa/inet.h>
|
|
#endif
|
|
|
|
namespace scwx
|
|
{
|
|
namespace wsr88d
|
|
{
|
|
namespace rda
|
|
{
|
|
|
|
static const std::string logPrefix_ = "[scwx::wsr88d::rda::message_header] ";
|
|
|
|
class MessageHeaderImpl
|
|
{
|
|
public:
|
|
explicit MessageHeaderImpl() :
|
|
messageSize_(),
|
|
rdaRedundantChannel_(),
|
|
messageType_(),
|
|
idSequenceNumber_(),
|
|
julianDate_(),
|
|
millisecondsOfDay_(),
|
|
numberOfMessageSegments_(),
|
|
messageSegmentNumber_() {};
|
|
~MessageHeaderImpl() = default;
|
|
|
|
uint16_t messageSize_;
|
|
uint8_t rdaRedundantChannel_;
|
|
uint8_t messageType_;
|
|
uint16_t idSequenceNumber_;
|
|
uint16_t julianDate_;
|
|
uint32_t millisecondsOfDay_;
|
|
uint16_t numberOfMessageSegments_;
|
|
uint16_t messageSegmentNumber_;
|
|
};
|
|
|
|
MessageHeader::MessageHeader() : p(std::make_unique<MessageHeaderImpl>()) {}
|
|
MessageHeader::~MessageHeader() = default;
|
|
|
|
MessageHeader::MessageHeader(MessageHeader&&) noexcept = default;
|
|
MessageHeader& MessageHeader::operator=(MessageHeader&&) noexcept = default;
|
|
|
|
uint16_t MessageHeader::message_size() const
|
|
{
|
|
return p->messageSize_;
|
|
}
|
|
|
|
uint8_t MessageHeader::rda_redundant_channel() const
|
|
{
|
|
return p->rdaRedundantChannel_;
|
|
}
|
|
|
|
uint8_t MessageHeader::message_type() const
|
|
{
|
|
return p->messageType_;
|
|
}
|
|
|
|
uint16_t MessageHeader::id_sequence_number() const
|
|
{
|
|
return p->idSequenceNumber_;
|
|
}
|
|
|
|
uint16_t MessageHeader::julian_date() const
|
|
{
|
|
return p->julianDate_;
|
|
}
|
|
|
|
uint32_t MessageHeader::milliseconds_of_day() const
|
|
{
|
|
return p->millisecondsOfDay_;
|
|
}
|
|
|
|
uint16_t MessageHeader::number_of_message_segments() const
|
|
{
|
|
return p->numberOfMessageSegments_;
|
|
}
|
|
|
|
uint16_t MessageHeader::message_segment_number() const
|
|
{
|
|
return p->messageSegmentNumber_;
|
|
}
|
|
|
|
void MessageHeader::set_message_size(uint16_t messageSize)
|
|
{
|
|
p->messageSize_ = messageSize;
|
|
}
|
|
|
|
bool MessageHeader::Parse(std::istream& is)
|
|
{
|
|
bool headerValid = true;
|
|
|
|
is.read(reinterpret_cast<char*>(&p->messageSize_), 2);
|
|
is.read(reinterpret_cast<char*>(&p->rdaRedundantChannel_), 1);
|
|
is.read(reinterpret_cast<char*>(&p->messageType_), 1);
|
|
is.read(reinterpret_cast<char*>(&p->idSequenceNumber_), 2);
|
|
is.read(reinterpret_cast<char*>(&p->julianDate_), 2);
|
|
is.read(reinterpret_cast<char*>(&p->millisecondsOfDay_), 4);
|
|
is.read(reinterpret_cast<char*>(&p->numberOfMessageSegments_), 2);
|
|
is.read(reinterpret_cast<char*>(&p->messageSegmentNumber_), 2);
|
|
|
|
p->messageSize_ = ntohs(p->messageSize_);
|
|
p->idSequenceNumber_ = ntohs(p->idSequenceNumber_);
|
|
p->julianDate_ = ntohs(p->julianDate_);
|
|
p->millisecondsOfDay_ = ntohl(p->millisecondsOfDay_);
|
|
p->numberOfMessageSegments_ = ntohs(p->numberOfMessageSegments_);
|
|
p->messageSegmentNumber_ = ntohs(p->messageSegmentNumber_);
|
|
|
|
if (is.eof())
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file";
|
|
headerValid = false;
|
|
}
|
|
else
|
|
{
|
|
if (p->messageSize_ < 9)
|
|
{
|
|
BOOST_LOG_TRIVIAL(warning)
|
|
<< logPrefix_ << "Invalid message size: " << p->messageSize_;
|
|
headerValid = false;
|
|
}
|
|
if (p->julianDate_ < 1)
|
|
{
|
|
BOOST_LOG_TRIVIAL(warning)
|
|
<< logPrefix_ << "Invalid date: " << p->julianDate_;
|
|
headerValid = false;
|
|
}
|
|
if (p->millisecondsOfDay_ > 86'399'999u)
|
|
{
|
|
BOOST_LOG_TRIVIAL(warning)
|
|
<< logPrefix_ << "Invalid milliseconds: " << p->millisecondsOfDay_;
|
|
headerValid = false;
|
|
}
|
|
if (p->messageSize_ < 65534 &&
|
|
p->messageSegmentNumber_ > p->numberOfMessageSegments_)
|
|
{
|
|
BOOST_LOG_TRIVIAL(warning)
|
|
<< logPrefix_ << "Invalid segment = " << p->messageSegmentNumber_
|
|
<< "/" << p->numberOfMessageSegments_;
|
|
headerValid = false;
|
|
}
|
|
}
|
|
|
|
if (headerValid)
|
|
{
|
|
BOOST_LOG_TRIVIAL(trace)
|
|
<< logPrefix_
|
|
<< "Message type: " << static_cast<unsigned>(p->messageType_);
|
|
}
|
|
|
|
return headerValid;
|
|
}
|
|
|
|
} // namespace rda
|
|
} // namespace wsr88d
|
|
} // namespace scwx
|