Commit 80067a9c authored by 王思远's avatar 王思远

UTC:2025-11-21 2:21:44 :

parent 1605712e
......@@ -18,19 +18,193 @@
#include <MessageFrame.h>
constexpr ::std::size_t MTU = 1024;
template<typename MessageType>
using MessagePtr = ::std::unique_ptr<MessageType, void (*)(MessageType *)>;
#define releaseMessage(MessageType) \
[](MessageType *message) -> void { \
if (message != nullptr) { \
ASN_STRUCT_FREE(asn_DEF_##MessageType, message); \
} \
}
/**
* @brief Print data.
*/
::std::ostream &operator<<(::std::ostream &stream, const MessageFrame &message)
{
auto flags = stream.flags();
auto fill = stream.fill();
auto width = stream.width();
stream << "MessageFrame{";
::std::unique_ptr<char[]> buffer;
::std::size_t bufferSize = 1024;
while (true) {
buffer = ::std::unique_ptr<char[]>(new char[bufferSize]);
::asn_enc_rval_t encodeResult = asn_encode_to_buffer(
nullptr, ATS_NONSTANDARD_PLAINTEXT, &asn_DEF_MessageFrame,
reinterpret_cast<const void *>(&message), buffer.get(), bufferSize);
if (encodeResult.encoded < 0) {
stream << "ENCODE_ERROR";
} else if (encodeResult.encoded <= bufferSize) {
stream.write(buffer.get(), encodeResult.encoded);
break;
} else {
bufferSize *= 2;
}
}
stream << "}";
stream.flags(flags);
stream.fill(fill);
stream.width(width);
return stream;
}
/**
* @brief Make BSM message.
*
* @return Fake message made.
*/
MessagePtr<MessageFrame> makeBSMMessage()
{
MessagePtr<MessageFrame> ret(
reinterpret_cast<MessageFrame *>(::calloc(1, sizeof(MessageFrame))),
releaseMessage(MessageFrame));
ret->present = MessageFrame_PR::MessageFrame_PR_bsmFrame;
::asn_dec_rval_t result = ::asn_decode(
nullptr, ATS_RANDOM, &::asn_DEF_BasicSafetyMessage,
reinterpret_cast<void **>(&ret->choice.bsmFrame), nullptr, 0);
if (result.code != RC_OK) {
::std::cerr << "Failed to generate BSM message." << ::std::endl;
return MessagePtr<MessageFrame>(nullptr, releaseMessage(MessageFrame));
}
return ret;
}
/**
* @brief Make map message.
*
* @return Fake message made.
*/
MessagePtr<MessageFrame> makeMapMessage()
{
MessagePtr<MessageFrame> ret(
reinterpret_cast<MessageFrame *>(::calloc(1, sizeof(MessageFrame))),
releaseMessage(MessageFrame));
ret->present = MessageFrame_PR::MessageFrame_PR_mapFrame;
::asn_dec_rval_t result = ::asn_decode(
nullptr, ATS_RANDOM, &::asn_DEF_MapData,
reinterpret_cast<void **>(&ret->choice.mapFrame), nullptr, 0);
if (result.code != RC_OK) {
::std::cerr << "Failed to generate Map message." << ::std::endl;
return MessagePtr<MessageFrame>(nullptr, releaseMessage(MessageFrame));
}
return ret;
}
/**
* @brief Make spat message.
*
* @return Fake message made.
*/
MessagePtr<MessageFrame> makeSPATMessage()
{
MessagePtr<MessageFrame> ret(
reinterpret_cast<MessageFrame *>(::calloc(1, sizeof(MessageFrame))),
releaseMessage(MessageFrame));
ret->present = MessageFrame_PR::MessageFrame_PR_spatFrame;
::asn_dec_rval_t result = ::asn_decode(
nullptr, ATS_RANDOM, &::asn_DEF_SPAT,
reinterpret_cast<void **>(&ret->choice.spatFrame), nullptr, 0);
if (result.code != RC_OK) {
::std::cerr << "Failed to generate SPAT message." << ::std::endl;
return MessagePtr<MessageFrame>(nullptr, releaseMessage(MessageFrame));
}
return ret;
}
/**
* @brief Read data.
*
* @param[in] fd File descriptor to read.
*/
void readData(int fd) {}
void readData(int fd)
{
// Receive data.
char buffer[MTU];
::ssize_t sizeRead = ::recv(fd, buffer, sizeof(buffer), 0);
if (sizeRead < 0) {
int err = errno;
::std::cerr << "Failed to receive data: " << ::strerror(err);
return;
}
// Decode data.
MessageFrame *message = nullptr;
::asn_dec_rval_t result = ::asn_decode(
nullptr, ATS_UNALIGNED_CANONICAL_PER, &::asn_DEF_MessageFrame,
reinterpret_cast<void **>(&message), buffer, sizeRead);
if (result.code != RC_OK) {
::std::cerr << "Decode error." << ::std::endl;
return;
}
MessagePtr<MessageFrame> autoRelease(message, releaseMessage(MessageFrame));
// Print data.
::std::cout << ::std::chrono::duration_cast<::std::chrono::seconds>(
::std::chrono::system_clock::now().time_since_epoch())
.count()
<< " Data received: " << *message << ::std::endl;
}
/**
* @brief Write data.
*
* @param[in] fd File descriptor to write.
*/
void writeData(int fd) {}
void writeData(int fd)
{
MessagePtr<MessageFrame> messages[] {makeBSMMessage(), makeMapMessage(),
makeSPATMessage()};
for (auto &message : messages) {
if (message == nullptr) {
continue;
}
char buffer[MTU];
::asn_enc_rval_t encodeResult = asn_encode_to_buffer(
nullptr, ATS_UNALIGNED_CANONICAL_PER, &asn_DEF_MessageFrame,
reinterpret_cast<void *>(message.get()), buffer, sizeof(buffer));
if (encodeResult.encoded > 0) {
ssize_t sizeSent = ::send(fd, buffer, encodeResult.encoded, 0);
if (sizeSent <= 0) {
::std::cout
<< ::std::chrono::duration_cast<::std::chrono::seconds>(
::std::chrono::system_clock::now()
.time_since_epoch())
.count()
<< " Data sent: " << *message << ::std::endl;
} else {
int err = errno;
::std::cerr << "Failed to send data: " << ::strerror(err);
return;
}
} else {
::std::cerr << "Encode error." << ::std::endl;
}
}
}
/**
* @brief Entery.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment